// FICHIER : Hysteresis3D.cc // CLASSE : Hysteresis3D // This file is part of the Herezh++ application. // // The finite element software Herezh++ is dedicated to the field // of mechanics for large transformations of solid structures. // It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600) // INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) . // // Herezh++ is distributed under GPL 3 license ou ultérieure. // // Copyright (C) 1997-2022 Université Bretagne Sud (France) // AUTHOR : Gérard Rio // E-MAIL : gerardrio56@free.fr // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, // or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // For more information, please consult: . //#include "Debug.h" # include using namespace std; //introduces namespace std #include #include #include "Sortie.h" #include "ConstMath.h" #include "MatLapack.h" #include "ExceptionsLoiComp.h" #include "MotCle.h" #include "CharUtil.h" #include "Hysteresis3D.h" #include "Enum_TypeQuelconque.h" #include "TypeQuelconqueParticulier.h" // $$$$$$$$$$$$$$$$$$$$$ a faire $$$$$$$$$$$$$$$$$ // a priori la sauvegarde de w_base n'est pas nécessaire car c'est un résultat // mais on ne sans sert pas comme test, et à l'aide des listes on peut savoir si l'on est sur // une première charge ou non, ce qui donne la valeur de w_base // ========== fonctions pour la classe de sauvegarde des résultats ========= // constructeur par défaut Hysteresis3D::SaveResulHysteresis3D::SaveResulHysteresis3D() : sigma_barre_BH_t(),sigma_barre_BH_tdt(),sigma_barre_BH_R() ,oc_BH_R(),oc_BH_t(),oc_BH_tdt(),fonction_aide_t(0.),fonction_aide_tdt(0.) ,wBase_t(1),wBase_tdt(1) ,def_equi_at(0.),def_equi_atdt(0.) ,ip2(),fct_aide_t_a_tdt(),fct_aide() ,modif(0),sigma_barre_BH_R_t_a_tdt(),nb_coincidence(0) ,oc_BH_t_a_tdt(),def_equi_t_a_tdt(),def_equi() ,sigma_barre_BH_R_atrans(),oc_BH_R_atrans() ,indicateurs_resolution(),indicateurs_resolution_t() // ,modif_sauve(0),sigma_barre_BH_R_sauve(),nb_ref_new_sauve(0) // ,nb_coincidence_sauve(0),oc_BH_R_sauve(),nb_centre_new_sauve(0) // ,def_equi_sauve() { // la première valeur de la déformation équivalente est 0 def_equi.push_front(0.); // la première valeur de la fonction d'aide est l'infini fct_aide.push_front(ConstMath::tresgrand); }; // constructeur de copie Hysteresis3D::SaveResulHysteresis3D::SaveResulHysteresis3D(const SaveResulHysteresis3D& sav): sigma_barre_BH_t(sav.sigma_barre_BH_t),sigma_barre_BH_tdt(sav.sigma_barre_BH_tdt) ,sigma_barre_BH_R(sav.sigma_barre_BH_R) ,oc_BH_R(sav.oc_BH_R),oc_BH_t(sav.oc_BH_t),oc_BH_tdt(sav.oc_BH_tdt) ,fonction_aide_t(sav.fonction_aide_t),fonction_aide_tdt(sav.fonction_aide_tdt) ,wBase_t(sav.wBase_t),wBase_tdt(sav.wBase_tdt) ,def_equi_at(sav.def_equi_at),def_equi_atdt(sav.def_equi_atdt) ,modif(sav.modif),sigma_barre_BH_R_t_a_tdt(sav.sigma_barre_BH_R_t_a_tdt) ,nb_coincidence(sav.nb_coincidence),oc_BH_t_a_tdt(sav.oc_BH_t_a_tdt) ,def_equi_t_a_tdt(sav.def_equi_t_a_tdt),def_equi(sav.def_equi) ,ip2(),fct_aide_t_a_tdt(sav.fct_aide_t_a_tdt),fct_aide(sav.fct_aide) ,sigma_barre_BH_R_atrans(sav.sigma_barre_BH_R_atrans),oc_BH_R_atrans(sav.oc_BH_R_atrans) ,indicateurs_resolution(sav.indicateurs_resolution),indicateurs_resolution_t(sav.indicateurs_resolution_t) // ,modif_sauve(sav.modif_sauve),sigma_barre_BH_R_sauve(sav.sigma_barre_BH_R_sauve) // ,nb_ref_new_sauve(sav.nb_ref_new_sauve),nb_coincidence_sauve(sav.nb_coincidence_sauve) // ,oc_BH_R_sauve(sav.oc_BH_R_sauve),nb_centre_new_sauve(sav.nb_centre_new_sauve) // ,def_equi_sauve(sav.def_equi_sauve) { if (fct_aide.size() >= 2) // pointage de ip2 {ip2= fct_aide.end(); ip2--;ip2--; } }; // affectation Loi_comp_abstraite::SaveResul & Hysteresis3D::SaveResulHysteresis3D::operator = ( const Loi_comp_abstraite::SaveResul & a) { Hysteresis3D::SaveResulHysteresis3D& sav = *((Hysteresis3D::SaveResulHysteresis3D*) &a); // recopie de toutes les grandeurs oc_BH_t = sav.oc_BH_t; oc_BH_tdt = sav.oc_BH_tdt; def_equi_at = sav.def_equi_at; def_equi_atdt = sav.def_equi_atdt; oc_BH_t_a_tdt = sav.oc_BH_t_a_tdt; def_equi_t_a_tdt = sav.def_equi_t_a_tdt; oc_BH_R = sav.oc_BH_R; def_equi = sav.def_equi; sigma_barre_BH_R_atrans = sav.sigma_barre_BH_R_atrans; oc_BH_R_atrans = sav.oc_BH_R_atrans; sigma_barre_BH_t = sav.sigma_barre_BH_t; sigma_barre_BH_tdt = sav.sigma_barre_BH_tdt; fonction_aide_t = sav.fonction_aide_t; fonction_aide_tdt = sav.fonction_aide_tdt; wBase_t = sav.wBase_t; wBase_tdt = sav.wBase_tdt; fct_aide = sav.fct_aide; if (fct_aide.size() >= 2) // pointage de ip2 {ip2= fct_aide.end(); ip2--;ip2--; }; modif = sav.modif; sigma_barre_BH_R_t_a_tdt = sav.sigma_barre_BH_R_t_a_tdt; nb_coincidence = sav.nb_coincidence; fct_aide_t_a_tdt = sav.fct_aide_t_a_tdt; sigma_barre_BH_R = sav.sigma_barre_BH_R; indicateurs_resolution = sav.indicateurs_resolution; indicateurs_resolution_t = sav.indicateurs_resolution_t; return *this; }; //------- lecture écriture dans base info ------- // cas donne le niveau de la récupération // = 1 : on récupère tout // = 2 : on récupère uniquement les données variables (supposées comme telles) void Hysteresis3D::SaveResulHysteresis3D::Lecture_base_info (ifstream& ent,const int ) { // ici toutes les données sont toujours a priori variables string toto; ent >> toto >> sigma_barre_BH_t ;sigma_barre_BH_tdt = sigma_barre_BH_t; ent >> toto >> oc_BH_t; oc_BH_tdt=oc_BH_t; ent >> toto >> wBase_t; wBase_tdt=wBase_t; ent >> toto >> def_equi_at >> def_equi_atdt; ent >> toto >> fonction_aide_t; fonction_aide_tdt=fonction_aide_t; // ---- lecture liste fonction d'aide ent >> toto; #ifdef MISE_AU_POINT if (toto != "list_fct_aide") { cout << "\n erreur dans la lecture de la list_io fonction d'aide, on ne trouve pas le mot cle: list_fct_aide " << " on a lu "<< toto << " avec auparavent: " << "\n fonction_aide_t= "<< fonction_aide_t << "\n def_equi_at= "<< def_equi_at << "\n def_equi_atdt= "<< def_equi_atdt << "\n wBase_t= "<< wBase_t << "\n Hysteresis3D::SaveResulHysteresis3D::Lecture_base_info (... "; Sortie(1); } #endif int taille;ent >> toto >> taille; // lecture de la taille double un_elem; // on vide la liste actuelle fct_aide.clear(); for (int i=1;i<=taille;i++) // puis on lit { ent >> un_elem; // lecture fct_aide.push_back(un_elem); // enregistrement } if (fct_aide.size() >= 2) // pointage de ip2 {ip2= fct_aide.end(); ip2--;ip2--; } // ---- lecture des centre de cercle ent >> toto; #ifdef MISE_AU_POINT if (toto != "list_oc_BH_R") { cout << "\n erreur dans la lecture de la list_io de centre, on ne trouve pas le mot cle: list_oc_BH_R " << "\n Hysteresis3D::SaveResulHysteresis3D::Lecture_base_info (... "; Sortie(1); } #endif ent >> toto >> taille; // lecture de la taille de la liste Tenseur3BH elem; // on vide la liste actuelle oc_BH_R.clear(); for (int i=1;i<=taille;i++) // puis on lit { ent >> elem; // lecture oc_BH_R.push_back(elem); // enregistrement } // initialisation pour le transport éventuel oc_BH_R_atrans= oc_BH_R; ent >> toto; // ---- lecture des points d'inversion #ifdef MISE_AU_POINT if (toto != "list_pt_inver") { cout << "\n erreur dans la lecture de la list_io: ref contrainte, on ne trouve pas le mot cle: list_pt_inver " << "\n Hysteresis3D::SaveResulHysteresis3D::Lecture_base_info (... "; Sortie(1); } #endif // on vide la listes actuelle et on lit sigma_barre_BH_R.clear(); ent >> toto >> taille; // lecture de la taille du nombre de point d'inversion for (int j=1;j<=taille;j++) // puis on lit { ent >> elem; // lecture sigma_barre_BH_R.push_back(elem); // enregistrement }; // initialisation pour le transport éventuel sigma_barre_BH_R_atrans = sigma_barre_BH_R; ent >> toto; // ---- lecture def équivalente #ifdef MISE_AU_POINT if (toto != "list_def_equi") { cout << "\n erreur dans la lecture de la list_io def equivalente, on ne trouve pas le mot cle: list_def_equi " << "\n Hysteresis3D::SaveResulHysteresis3D::Lecture_base_info (... "; Sortie(1); } #endif int taille_C;ent >> toto >> taille_C; // lecture de la taille double un_elem_eps; // on vide la liste actuelle def_equi.clear(); for (int i=1;i<=taille_C;i++) // puis on lit { ent >> un_elem_eps; // lecture def_equi.push_back(un_elem_eps); // enregistrement } //re-initialisation des variables de travail TversTdt(); // Init_debut_calcul(); }; // cas donne le niveau de sauvegarde // = 1 : on sauvegarde tout // = 2 : on sauvegarde uniquement les données variables //(supposées comme telles) void Hysteresis3D::SaveResulHysteresis3D::Ecriture_base_info(ofstream& sort,const int ) { // ici toutes les données sont toujours a priori variables sort << " sigma_barre_BH_t " << sigma_barre_BH_t; sort << "\n oc_BH_t " << oc_BH_t; sort << "\n wBase_t " << wBase_t; sort << "\n def_equi_at_et_tdt " << def_equi_at << " " << def_equi_atdt; sort << " fct_aide_t " << fonction_aide_t; // liste des fonctions d'aide {sort << "\n list_fct_aide " << "taille= " << fct_aide.size() << " "; List_io ::const_iterator iter_courant,iter_fin = fct_aide.end(); for (iter_courant=fct_aide.begin();iter_courant!=iter_fin;iter_courant++) { sort << setprecision(ParaGlob::NbdigdoCA()) << (*iter_courant) ; sort << " "; } } // listes: centre de cercle et point d'inversion sort << "\n list_oc_BH_R " << "taille= " << oc_BH_R.size() << " "; List_io ::const_iterator iter_courant,iter_fin = oc_BH_R.end(); for (iter_courant=oc_BH_R.begin();iter_courant!=iter_fin;iter_courant++) { sort << setprecision(ParaGlob::NbdigdoCA()) << (*iter_courant) ; sort << " "; }; int taille_sigma_barre_BH_R= sigma_barre_BH_R.size(); sort << "\n list_pt_inver " << "taille= " << taille_sigma_barre_BH_R << " "; List_io ::const_iterator jter_courant,jter_fin = sigma_barre_BH_R.end(); for (jter_courant=sigma_barre_BH_R.begin();jter_courant!=jter_fin;jter_courant++) { sort << setprecision(ParaGlob::NbdigdoCA()) << (*jter_courant) ; sort << " "; }; // les listes: def équivalente sort << " list_def_equi " << "taille= " << def_equi.size() << " "; List_io ::const_iterator kter_courant,kter_fin = def_equi.end(); for (kter_courant=def_equi.begin();kter_courant!=kter_fin;kter_courant++) { sort << setprecision(ParaGlob::NbdigdoCA()) << (*kter_courant) ; sort << " "; }; }; // mise à jour des informations transitoires void Hysteresis3D::SaveResulHysteresis3D::TdtversT() { // partie générale sigma_barre_BH_t = sigma_barre_BH_tdt;oc_BH_t=oc_BH_tdt; wBase_t = wBase_tdt; def_equi_at = def_equi_atdt; // def équivalente fonction_aide_t=fonction_aide_tdt; // partie spécifique // en fait ici on pourrait simplifier car le cas 3 est toujours valide -> supprime l'utilité // du paramètre modif !! // int maxi_ref_en_plus = 0; // indique le maximum de ref que l'on a mis en plus dans la liste //------- débug --------- // vérif de la cohérence des centres et références: les rayons associés doivent être de tailles // décroissantes // Verif_centre_reference(); //-------- fin débug ----------- // ------- mise en place des modifs ---------- // modif_sauve = modif ; // pour le retour t -> tdt éventuel // nb_coincidence_sauve = nb_coincidence; // idem switch (modif) { case 0: // rien ne change sur le pas en terme de coincidence et d'inversion { break; } case 1: // cas où l'on a une ou plusieurs coincidences { // a chaque coincidence il faut supprimer 1 pt de ref et un centre de cercle // sauf si l'on arrive au centre nul ou au point de référence null List_io ::iterator itens;List_io ::iterator ioc_i; for (int i=1;i<=nb_coincidence;i++) { itens = sigma_barre_BH_R.begin(); if (itens != sigma_barre_BH_R.end()) // si itens == sigma_barre_BH_R.end(), cela signifie {//sigma_barre_BH_R_sauve.push_back(*itens); // on sauve avant de détruire sigma_barre_BH_R.erase(itens); // que la référence est le tenseur nulle, on arrête de dépiler }; ioc_i = oc_BH_R.begin(); if (ioc_i != oc_BH_R.end()) // si ioc_i == oc_BH_R.end(), cela signifie que le centre de référence {//oc_BH_R_sauve.push_back(*ioc_i); // on sauve avant de détruire oc_BH_R.erase(ioc_i); // est le tenseur nulle }; // idem pour les def équivalentes List_io ::iterator idouble; idouble = def_equi.begin(); if (idouble != def_equi.end()) // si idouble == def_equi.end(), cela signifie que l'on est arrivé { //def_equi_sauve.push_back(*idouble); // on sauve avant de détruire def_equi.erase(idouble); // sur la branche fondamentale }; // idem pour la fonction d'aide List_io ::iterator ifct; ifct = fct_aide.begin(); if (ifct != fct_aide.end()) // si ifct == fct_aide.end(), cela signifie que l'on est arrivé { //fct_aide_sauve.push_back(*ifct); // on sauve avant de détruire fct_aide.erase(ifct); // sur la branche fondamentale }; }; break; } case 2: // cas où l'on a une ou plusieurs inversions { // on traite les centres différement des points d'inversions int nb_centre_new = oc_BH_t_a_tdt.size(); // récup du nombre de nouveaux centres // nb_centre_new_sauve = nb_centre_new; // on sauvegarde pour un retour t -> tdt éventuel // on ajoute les différents nouveaux centres, en tenant compte du fait que le premier rentrée est // le dernier dans la liste, d'où l'utilisation de reverse_iterator List_io ::reverse_iterator iifoi = oc_BH_t_a_tdt.rbegin(); for (int ii=1;ii<=nb_centre_new;ii++,iifoi++) oc_BH_R.push_front(*iifoi); // maintenant on traites les points d'inversions int nb_ref_new = sigma_barre_BH_R_t_a_tdt.size(); // récup du nombre de nouveaux pt // nb_ref_new_sauve = nb_ref_new; // on sauve pour le retour t -> tdt éventuel // on ajoute les différents points d'inversions List_io ::reverse_iterator iitens = sigma_barre_BH_R_t_a_tdt.rbegin(); for (int ii=1;ii<=nb_ref_new;ii++,iitens++) sigma_barre_BH_R.push_front(*iitens); // pour les def équivalentes List_io ::reverse_iterator iidouble = def_equi_t_a_tdt.rbegin(); for (int ij=1;ij<=nb_ref_new;ij++,iidouble++) def_equi.push_front(*iidouble); // cas de la fonction d'aide int nb_ref = fct_aide.size(); // récup du nombre de pt de ref actuel bool init_ip2 = false; if (nb_ref == 1) init_ip2=true; // pour gérer ip2 int nb_fct_new = fct_aide_t_a_tdt.size(); // récup du nombre de nouveau pt // on ajoute les différentes valeurs List_io ::iterator iifct = fct_aide_t_a_tdt.begin(); for (int ii=1;ii<=nb_ref_new;ii++,iitens++,iifct++) {fct_aide.push_front(*iifct); if (init_ip2) // uniquement pour mémoriser le W_a de la première charge { // cas où l'on doit initialiser ip2 (car ici le nombre de pt = 2) ip2 = fct_aide.begin(); init_ip2 = false; }; }; break; } case 3: // cas où l'on a une ou plusieurs coincidence(s) et inversion (s) { // les coïncidences sont forcéments au début puis on a les inversions qui sont // au nombre d'éléments sur la liste secondaire // a) on commence par traiter les coïncidences // a chaque coincidence il faut supprimer 1 pt de ref et un centre de cercle // sauf si l'on arrive au centre nul ou au point de référence null List_io ::iterator itens;List_io ::iterator ioc_i; for (int i=1;i<=nb_coincidence;i++) { itens = sigma_barre_BH_R.begin(); if (itens != sigma_barre_BH_R.end()) // si itens == sigma_barre_BH_R.end(), cela signifie {//sigma_barre_BH_R_sauve.push_back(*itens); // on sauve avant de détruire sigma_barre_BH_R.erase(itens); // que la référence est le tenseur nulle, on arrête de dépiler }; ioc_i = oc_BH_R.begin(); if (ioc_i != oc_BH_R.end()) // si ioc_i == oc_BH_R.end(), cela signifie que le centre de référence {//oc_BH_R_sauve.push_back(*ioc_i); // on sauve avant de détruire oc_BH_R.erase(ioc_i); // est le tenseur nulle }; // idem pour les def équivalentes List_io ::iterator idouble; idouble = def_equi.begin(); if (idouble != def_equi.end()) // si idouble == def_equi.end(), cela signifie que l'on est arrivé { //def_equi_sauve.push_back(*idouble); // on sauve avant de détruire def_equi.erase(idouble); // sur la branche fondamentale } // idem pour la fonction d'aide List_io ::iterator ifct; ifct = fct_aide.begin(); if (ifct != fct_aide.end()) // si ifct == fct_aide.end(), cela signifie que l'on est arrivé { //fct_aide_sauve.push_back(*ifct); // on sauve avant de détruire fct_aide.erase(ifct); // sur la branche fondamentale }; }; // b) maintenant on s'occupe des inversions // on traite les centres différemment des points d'inversions int nb_centre_new = oc_BH_t_a_tdt.size(); // récup du nombre de nouveaux centres // nb_centre_new_sauve = nb_centre_new; // on sauvegarde pour un retour t -> tdt éventuel // on ajoute les différents nouveaux centres List_io ::reverse_iterator iifoi = oc_BH_t_a_tdt.rbegin(); for (int ii=1;ii<=nb_centre_new;ii++,iifoi++) oc_BH_R.push_front(*iifoi); // maintenant on traites les points d'inversions int nb_ref_new = sigma_barre_BH_R_t_a_tdt.size(); // récup du nombre de nouveaux pt // nb_ref_new_sauve = nb_ref_new; // on sauve pour le retour t -> tdt éventuel // on ajoute les différents points d'inversions List_io ::reverse_iterator iitens = sigma_barre_BH_R_t_a_tdt.rbegin(); for (int ii=1;ii<=nb_ref_new;ii++,iitens++) sigma_barre_BH_R.push_front(*iitens); // pour les def équivalentes List_io ::reverse_iterator iidouble = def_equi_t_a_tdt.rbegin(); for (int ij=1;ij<=nb_ref_new;ij++,iidouble++) def_equi.push_front(*iidouble); // cas de la fonction d'aide int nb_ref = fct_aide.size(); // récup du nombre de pt de ref actuel bool init_ip2 = false; if (nb_ref == 1) init_ip2=true; // pour gérer ip2 int nb_fct_new = fct_aide_t_a_tdt.size(); // récup du nombre de nouveau pt // on ajoute les différentes valeurs List_io ::iterator iifct = fct_aide_t_a_tdt.begin(); for (int ii=1;ii<=nb_ref_new;ii++,iitens++,iifct++) {fct_aide.push_front(*iifct); if (init_ip2) // uniquement pour mémoriser le W_a de la première charge { // cas où l'on doit initialiser ip2 (car ici le nombre de pt = 2) ip2 = fct_aide.begin(); init_ip2 = false; }; }; break; } default: cout << "\n erreur dans la mise a jour des informations transitoire: modif= " << modif << "\n Hysteresis3D::SaveResulHysteresis3D::TversTdt() "; Sortie(1); } // --------------------- très important: traitement de finition -------------------------- // si les rayons résultants que l'on a ajoute sont à une distance inférieure à la précision de la coincidence // on les collapses !! // finalement on va traiter directement au niveau des coincidences pour l'instant !! // if (maxi_ref_en_plus != 0) // { // } //------- débug --------- // vérif de la cohérence des centres et références: les rayons associés doivent être de tailles // décroissantes // Verif_centre_reference(6); //-------- fin débug ----------- // on sauve les grandeurs transportables sigma_barre_BH_R_atrans = sigma_barre_BH_R; oc_BH_R_atrans= oc_BH_R; // on met à jour éventuellement les indicateurs de résolution if (indicateurs_resolution.Taille()) { indicateurs_resolution_t = indicateurs_resolution; // on met les indicateurs à 0 indicateurs_resolution.Change_taille(5,0.); }; //re-initialisation des variables de travail Init_debut_calcul(); }; void Hysteresis3D::SaveResulHysteresis3D::TversTdt() { // partie générale sigma_barre_BH_tdt = sigma_barre_BH_t;oc_BH_tdt=oc_BH_t; wBase_tdt=wBase_t; def_equi_atdt = def_equi_at; // def équivalente // on supprime le transport éventuel sigma_barre_BH_R = sigma_barre_BH_R_atrans; oc_BH_R = oc_BH_R_atrans; fonction_aide_tdt=fonction_aide_t; // en fait le tant que le pas n'est pas validé, les différentes listes ne sont pas changées // donc il n'y a pas à mettre en place une stratégie pour revenir en arrière // une fois que le pas est validé, effectivement on ne peut pas revenir en arrière, mais // c'est aussi vrai pour toutes les autres lois // ceci étant la suite serait une solution pour revenir en arrière // // maintenant on essaie de remettre les choses d'aplomb // switch (modif_sauve) // { case 0: // rien n'a changé sur le pas en terme de coincidence et d'inversion // { break; // donc rien n'a faire !! ouf // } // case 1: // cas où l'on a eu une ou plusieurs coincidences // { // ici il suffit de rajouter tous les tenseurs qui ont été supprimés // List_io ::iterator itens;List_io ::iterator ioc_i; // {List_io ::iterator itens_fin=sigma_barre_BH_R_sauve.end(); // for (itens = sigma_barre_BH_R_sauve.begin(); itens != itens_fin;itens++) // sigma_barre_BH_R.push_front(*itens); // }; // {List_io ::iterator itens_fin=oc_BH_R_sauve.end(); // for (itens = oc_BH_R_sauve.begin(); itens != itens_fin;itens++) // oc_BH_R.push_front(*itens); // }; // {List_io ::iterator idouble,idouble_fin= def_equi_sauve.end(); // for (idouble = def_equi_sauve.begin(); idouble != idouble_fin;idouble++) // def_equi.push_front(*idouble); // }; // // puis on supprime les sauvegardes histoire de ne pas rajouter une nouvelle fois // sigma_barre_BH_R.clear();oc_BH_R_sauve.clear();def_equi_sauve.clear(); // break; // } // case 2: // cas où l'on a eu une ou plusieurs inversions // { // pour les centres on en a rajouté nb_centre_new_sauve, on les supprimes // List_io ::iterator ioc_i; // for (int i=1; i<= nb_centre_new_sauve;i++) // { ioc_i = oc_BH_R.begin(); // oc_BH_R.erase(ioc_i); // }; // // maintenant on traites les points d'inversions, même chose que les centres on supprime // List_io ::iterator iitens; // for (int i=1; i<= nb_ref_new_sauve;i++) // { iitens = sigma_barre_BH_R.begin(); // sigma_barre_BH_R.erase(iitens); // }; // // pour les def équivalentes, même chose // List_io ::iterator iidouble; // for (int i=1; i<= nb_ref_new_sauve;i++) // { iidouble = def_equi.begin(); // def_equi.erase(iidouble); // }; // // on supprime les compteurs pour éviter une autre suppression future // nb_centre_new_sauve=0;nb_ref_new_sauve=0; // break; // } // case 3: // cas où l'on a eu une ou plusieurs coincidence(s) et inversion (s) // { // on traite dans l'ordre inverse du cas tdt -> t // // -- a) on s'occupe des inversions // // pour les centres on en a rajouté nb_centre_new_sauve, on les supprimes // {List_io ::iterator ioc_i; // for (int i=1; i<= nb_centre_new_sauve;i++) // { ioc_i = oc_BH_R.begin(); // oc_BH_R.erase(ioc_i); // }; // // maintenant on traites les points d'inversions, même chose que les centres on supprime // List_io ::iterator iitens; // for (int i=1; i<= nb_ref_new_sauve;i++) // { iitens = sigma_barre_BH_R.begin(); // sigma_barre_BH_R.erase(iitens); // }; // // pour les def équivalentes, même chose // List_io ::iterator iidouble; // for (int i=1; i<= nb_ref_new_sauve;i++) // { iidouble = def_equi.begin(); // def_equi.erase(iidouble); // }; // // on supprime les compteurs pour éviter une autre suppression future // nb_centre_new_sauve=0;nb_ref_new_sauve=0; // }; // // -- b) on s'occupe des coincidences // // ici il suffit de rajouter tous les tenseurs qui ont été supprimés // {List_io ::iterator itens;List_io ::iterator ioc_i; // {List_io ::iterator itens_fin=sigma_barre_BH_R_sauve.end(); // for (itens = sigma_barre_BH_R_sauve.begin(); itens != itens_fin;itens++) // sigma_barre_BH_R.push_front(*itens); // }; // {List_io ::iterator itens_fin=oc_BH_R_sauve.end(); // for (itens = oc_BH_R_sauve.begin(); itens != itens_fin;itens++) // oc_BH_R.push_front(*itens); // }; // {List_io ::iterator idouble,idouble_fin= def_equi_sauve.end(); // for (idouble = def_equi_sauve.begin(); idouble != idouble_fin;idouble++) // def_equi.push_front(*idouble); // }; // // puis on supprime les sauvegardes histoire de ne pas rajouter une nouvelle fois // sigma_barre_BH_R.clear();oc_BH_R_sauve.clear();def_equi_sauve.clear(); // }; // break; // } // default: // cout << "\n erreur dans la mise a jour des informations transitoire: modif= " << modif // << "\n Hysteresis3D::SaveResulHysteresis3D::TversTdt() "; // Sortie(1); // }; //re-initialisation des variables de travail Init_debut_calcul(); }; // affichage à l'écran des infos void Hysteresis3D::SaveResulHysteresis3D::Affiche() const { cout << "\n SaveResulHysteresis3D: " ; cout << "\n sigma_barre_BH_t= " << sigma_barre_BH_t << " sigma_barre_BH_tdt= " << sigma_barre_BH_tdt << " oc_BH_t= " << oc_BH_t << " oc_BH_tdt= " << oc_BH_tdt << " wBase_t= " << wBase_t << " wBase_tdt= " << wBase_tdt << " def_equi_at= " << def_equi_at << " def_equi_atdt= " << def_equi_atdt << " fonction_aide_t= " << fonction_aide_t << " fonction_aide_tdt= " << fonction_aide_tdt; cout << "\n -- info de travail en cours: "; cout << " modif= " << modif << "\n list sigma_barre_BH_R_t_a_tdt: " << sigma_barre_BH_R_t_a_tdt << "\n nb_coincidence= " << nb_coincidence << "\n list oc_BH_t_a_tdt: " << oc_BH_t_a_tdt << "\n list def_equi_t_a_tdt: " << def_equi_t_a_tdt; cout << "\n -- memorisation discrete de 0 a t: "; cout << "\n list sigma_barre_BH_R: " << sigma_barre_BH_R; cout << "\n list oc_BH_R: " << oc_BH_R; cout << "\n list def_equi: " << def_equi; cout << "\n list fct_aide: " << fct_aide << " "; cout << "\n .. fin SaveResulHysteresis3D ... "; }; //changement de base de toutes les grandeurs internes tensorielles stockées // beta(i,j) represente les coordonnees de la nouvelle base naturelle gpB dans l'ancienne gB // gpB(i) = beta(i,j) * gB(j), i indice de ligne, j indice de colonne // gpH(i) = gamma(i,j) * gH(j) void Hysteresis3D::SaveResulHysteresis3D::ChBase_des_grandeurs(const Mat_pleine& beta,const Mat_pleine& gamma) { // on ne s'intéresse qu'aux grandeurs tensorielles sigma_barre_BH_t.ChBase(beta,gamma); sigma_barre_BH_tdt.ChBase(beta,gamma); oc_BH_t.ChBase(beta,gamma); oc_BH_tdt.ChBase(beta,gamma); // encapsulage pour utiliser deux fois les mêmes itérators { List_io ::iterator lit(sigma_barre_BH_R_t_a_tdt.begin()), lend(sigma_barre_BH_R_t_a_tdt.end()); for(;lit!=lend;++lit) // ici les bornes ne changent pas (*lit).ChBase(beta,gamma); }; { List_io ::iterator lit(oc_BH_t_a_tdt.begin()), lend(oc_BH_t_a_tdt.end()); for(;lit!=lend;++lit) // ici les bornes ne changent pas (*lit).ChBase(beta,gamma); }; { List_io ::iterator lit(sigma_barre_BH_R.begin()), lend(sigma_barre_BH_R.end()); for(;lit!=lend;++lit) // ici les bornes ne changent pas (*lit).ChBase(beta,gamma); }; { List_io ::iterator lit(oc_BH_R.begin()), lend(oc_BH_R.end()); for(;lit!=lend;++lit) // ici les bornes ne changent pas (*lit).ChBase(beta,gamma); }; { List_io ::iterator lit(sigma_barre_BH_R_atrans.begin()), lend(sigma_barre_BH_R_atrans.end()); for(;lit!=lend;++lit) // ici les bornes ne changent pas (*lit).ChBase(beta,gamma); }; { List_io ::iterator lit(oc_BH_R_atrans.begin()), lend(oc_BH_R_atrans.end()); for(;lit!=lend;++lit) // ici les bornes ne changent pas (*lit).ChBase(beta,gamma); }; }; // initialise les informations de travail concernant le pas de temps en cours void Hysteresis3D::SaveResulHysteresis3D::Init_debut_calcul() { //initialisation des variables de travail modif = 0; nb_coincidence=0; sigma_barre_BH_R_t_a_tdt.clear();oc_BH_t_a_tdt.clear();def_equi_t_a_tdt.clear(); fct_aide_t_a_tdt.clear(); //---- debug // cout << "\n Hysteresis3D::SaveResulHysteresis3D::Init_debut_calcul() "<< endl; //---- fin debug }; ///----------***** fin de l'introduction de la fonction d'aide // ========== fin des fonctions pour la classe de sauvegarde des résultats ========= Hysteresis3D::Hysteresis3D () : // Constructeur par defaut Loi_comp_abstraite(HYSTERESIS_3D,CAT_MECANIQUE,3) // ---- para matériau ,xnp(ConstMath::tresgrand),xnp_temperature(NULL),xnp_lue(ConstMath::tresgrand) ,Qzero(ConstMath::tresgrand),Qzero_temperature(NULL),Qzero_lue(ConstMath::tresgrand) ,xmu(ConstMath::tresgrand),xmu_temperature(NULL),xmu_lue(ConstMath::tresgrand) // parmètres de phase éventuelles ,xnp_phase(NULL),Qzero_defEqui(NULL),xnp_defEqui(NULL),Qzero_phase(NULL),xmu_phase(NULL) ,avec_phaseDeltaSig(false),avec_phaseEps(NULL) ,avec_defEqui(false),avec_phase_paradefEqui(false),coef_paradefEqui(NULL) ,val_coef_paradefEqui(1.),mini_QepsilonBH(1.e-4) ,type_de_transport_memorisation(0) ,niveau_bascule_fct_aide(10.) //volontairement très grand => ne sert pas // --- réglage résolution de l'équation constitutive ,tolerance_coincidence(),mini_rayon(ConstMath::pasmalpetit) ,tolerance_centre(0.001) ,min_angle_trajet_neutre(0.008),possibilite_cosAlphaNegatif(true) // environ 90° - 0.5° ,mini_Qsig_pour_phase_sigma_Oi_tdt(1.5) // 1.5 MPa ,type_resolution_equa_constitutive(1) ,type_calcul_comportement_tangent(1),avecVarWprimeS(false) ,nb_maxInvCoinSurUnPas(4),force_phi_zero_si_negatif(0.) ,depassement_Q0(2.) // ---- réglage résolution avec linéarisation ,tolerance_residu(1.e-3),tolerance_residu_rel(1.e-5),nb_boucle_maxi(6),nb_dichotomie(4) ,maxi_delta_var_sig_sur_iter_pour_Newton(-1) // ---- réglage résolution avec Kutta ,cas_kutta(5),erreurAbsolue(1.e-3),erreurRelative(1.e-5),nbMaxiAppel(1000) // ---- affichage ,sortie_post(0) // ---- init variable de travail ,sigma_t_barre_tdt(),sigma_i_barre_BH(),sigma_barre_BH_R() ,def_equi_R(0.),def_i_equi(0.),def_equi_atdt(0.),defEqui_maxi(0.) ,delta_sigma_barre_BH_Rat(),delta_sigma_barre_BH_Ra_i(),delta_sigma_barre_BH_Ratdt() ,delta_sigma_barre_tdt_BH(),residuBH() ,delta_epsBH(),delta_barre_epsBH(),delta_barre_alpha_epsBH() ,wBase(1),wprime(1),wprime_point(0.),trajet_neutre(false),d_wprime(),d_wprime_point() ,residu(9),derResidu(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT) ,derResidu_adefConstant(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT) ,alg_zero(),alg_edp() ,rdelta_sigma_barre_BH_Ratdt(),rdelta_sigma_barre_tdt_BH() ,sig_point(9),sigma_pointBH(),sigma_tauBH(),sigma_tau(9) ,delta_sigma_barre_R_a_tauBH(),delta_sigma_barre_t_a_tauBH() ,betaphideltasigHB(),deuxmudeltaepsHB() ,sig_initiale(9),dersig_initiale(9),sig_finale(9),dersig_finale(9),estime_erreur(9) ,val_initiale(9),racine(9) ,der_at_racine(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT) ,centre_initial(true),aucun_pt_inversion(true) ,dRdsigMoinsun(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT) ,dRdeps(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT) ,MPC(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT) ,dsig_ojef_HHHH() ,matriceH(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT) ,matriceM(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT) ,matHmoinsun(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT) ,calcul_dResi_dsig(false) {// initialisation des paramètres de la résolution de newton alg_zero.Modif_prec_res_abs(tolerance_residu); alg_zero.Modif_prec_res_rel(tolerance_residu_rel); alg_zero.Modif_iter_max(nb_boucle_maxi); alg_zero.Modif_nbMaxiIncre(nb_dichotomie); tolerance_coincidence = tolerance_residu * 100; tolerance_centre = tolerance_coincidence; // idem avec kutta alg_edp.Modif_nbMaxiAppel(nbMaxiAppel); }; // Constructeur de copie Hysteresis3D::Hysteresis3D (const Hysteresis3D& loi) : Loi_comp_abstraite(loi) // ---- para matériau ,xnp(loi.xnp),xmu(loi.xmu),Qzero(loi.Qzero) ,xnp_lue(loi.xnp_lue),xmu_lue(loi.xmu_lue),Qzero_lue(loi.Qzero_lue) ,xnp_temperature(loi.xnp_temperature),Qzero_temperature(loi.Qzero_temperature) ,xmu_temperature(loi.xmu_temperature) // paramètres de phase éventuelles ,xnp_phase(loi.xnp_phase),Qzero_defEqui(loi.Qzero_defEqui) ,xnp_defEqui(loi.xnp_defEqui),Qzero_phase(loi.Qzero_phase),xmu_phase(loi.xmu_phase) ,avec_phaseDeltaSig(loi.avec_phaseDeltaSig),avec_phaseEps(loi.avec_phaseEps) ,avec_defEqui(loi.avec_defEqui) ,avec_phase_paradefEqui(loi.avec_phase_paradefEqui),coef_paradefEqui(loi.coef_paradefEqui) ,val_coef_paradefEqui(1.),mini_QepsilonBH(loi.mini_QepsilonBH) ,type_de_transport_memorisation(loi.type_de_transport_memorisation) ,niveau_bascule_fct_aide(loi.niveau_bascule_fct_aide) // --- réglage résolution de l'équation constitutive ,tolerance_coincidence(loi.tolerance_coincidence),mini_rayon(loi.mini_rayon) ,tolerance_centre(loi.tolerance_centre) ,min_angle_trajet_neutre(loi.min_angle_trajet_neutre) // environ 90° - 0.5° ,possibilite_cosAlphaNegatif(loi.possibilite_cosAlphaNegatif) ,mini_Qsig_pour_phase_sigma_Oi_tdt(loi.mini_Qsig_pour_phase_sigma_Oi_tdt) ,type_resolution_equa_constitutive(loi.type_resolution_equa_constitutive) ,type_calcul_comportement_tangent(loi.type_calcul_comportement_tangent),avecVarWprimeS(loi.avecVarWprimeS) ,nb_maxInvCoinSurUnPas(loi.nb_maxInvCoinSurUnPas),force_phi_zero_si_negatif(loi.force_phi_zero_si_negatif) ,depassement_Q0(loi.depassement_Q0) // ---- réglage résolution avec linéarisation ,tolerance_residu(loi.tolerance_residu),tolerance_residu_rel(loi.tolerance_residu_rel) ,nb_boucle_maxi(loi.nb_boucle_maxi),nb_dichotomie(loi.nb_dichotomie) ,maxi_delta_var_sig_sur_iter_pour_Newton(loi.maxi_delta_var_sig_sur_iter_pour_Newton) // ---- réglage résolution avec Kutta ,cas_kutta(loi.cas_kutta),erreurAbsolue(loi.erreurAbsolue),erreurRelative(loi.erreurRelative) ,nbMaxiAppel(loi.nbMaxiAppel) // ---- affichage ,sortie_post(loi.sortie_post) // ---- intit variable de travail ,sigma_t_barre_tdt(loi.sigma_t_barre_tdt),sigma_i_barre_BH(loi.sigma_i_barre_BH) ,sigma_barre_BH_R(loi.sigma_barre_BH_R) ,def_equi_R(loi.def_equi_R),def_i_equi(loi.def_i_equi),def_equi_atdt(loi.def_equi_atdt) ,defEqui_maxi(loi.defEqui_maxi) ,delta_sigma_barre_BH_Rat(loi.delta_sigma_barre_BH_Rat) ,delta_sigma_barre_BH_Ra_i(loi.delta_sigma_barre_BH_Ra_i) ,delta_sigma_barre_BH_Ratdt(loi.delta_sigma_barre_BH_Ratdt) ,delta_sigma_barre_tdt_BH(loi.delta_sigma_barre_tdt_BH) ,residuBH(loi.residuBH),delta_epsBH(loi.delta_epsBH) ,delta_barre_epsBH(loi.delta_barre_epsBH) ,delta_barre_alpha_epsBH(loi.delta_barre_alpha_epsBH) ,wBase(loi.wBase),wprime(loi.wprime),trajet_neutre(loi.trajet_neutre),wprime_point(loi.wprime_point) ,d_wprime(loi.d_wprime),d_wprime_point(loi.d_wprime_point) ,residu(9),derResidu(loi.derResidu),derResidu_adefConstant(loi.derResidu_adefConstant),alg_zero(),alg_edp() ,rdelta_sigma_barre_BH_Ratdt(),rdelta_sigma_barre_tdt_BH() ,centre_initial(true),aucun_pt_inversion(true) ,dRdsigMoinsun(loi.dRdsigMoinsun),dRdeps(loi.dRdeps),MPC(loi.MPC) ,dsig_ojef_HHHH() ,matriceH(loi.matriceH), matriceM(loi.matriceM),matHmoinsun(loi.matHmoinsun) ,calcul_dResi_dsig(false) ,sig_point(9),sigma_pointBH(),sigma_tauBH(),sigma_tau(9) ,delta_sigma_barre_R_a_tauBH(),delta_sigma_barre_t_a_tauBH() ,betaphideltasigHB(),deuxmudeltaepsHB() ,sig_initiale(9),dersig_initiale(9),sig_finale(9),dersig_finale(9),estime_erreur(9) ,val_initiale(9),racine(9) ,der_at_racine(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT) {// initialisation des paramètres de la résolution de newton alg_zero.Modif_prec_res_abs(tolerance_residu); alg_zero.Modif_prec_res_rel(tolerance_residu_rel); alg_zero.Modif_iter_max(nb_boucle_maxi); alg_zero.Modif_nbMaxiIncre(nb_dichotomie); // idem avec kutta alg_edp.Modif_nbMaxiAppel(nbMaxiAppel); // pour les pointeurs de courbes, on regarde s'il s'agit d'une courbe locale ou d'une courbe globale if (xnp_temperature != NULL) if (xnp_temperature->NomCourbe() == "_") xnp_temperature = Courbe1D::New_Courbe1D(*(loi.xnp_temperature)); if (Qzero_temperature != NULL) if (Qzero_temperature->NomCourbe() == "_") Qzero_temperature = Courbe1D::New_Courbe1D(*(loi.Qzero_temperature)); if (xmu_temperature != NULL) if (xmu_temperature->NomCourbe() == "_") xmu_temperature = Courbe1D::New_Courbe1D(*(loi.xmu_temperature)); // pour la phase if (xnp_phase != NULL) if (xnp_phase->NomCourbe() == "_") xnp_phase = Courbe1D::New_Courbe1D(*(loi.xnp_phase)); if (Qzero_phase != NULL) if (Qzero_phase->NomCourbe() == "_") Qzero_phase = Courbe1D::New_Courbe1D(*(loi.Qzero_phase)); if (xmu_phase != NULL) if (xmu_phase->NomCourbe() == "_") xmu_phase = Courbe1D::New_Courbe1D(*(loi.xmu_phase)); // pour la dépendance à la déformation équivalente if (xnp_defEqui != NULL) if (xnp_defEqui->NomCourbe() == "_") xnp_defEqui = Courbe1D::New_Courbe1D(*(loi.xnp_defEqui)); // pour la dépendance à la déformation équivalente if (Qzero_defEqui != NULL) if (Qzero_defEqui->NomCourbe() == "_") Qzero_defEqui = Courbe1D::New_Courbe1D(*(loi.Qzero_defEqui)); // pour la dépendance à la déformation totale if (coef_paradefEqui != NULL) if (coef_paradefEqui->NomCourbe() == "_") coef_paradefEqui = Courbe1D::New_Courbe1D(*(loi.coef_paradefEqui)); }; Hysteresis3D::~Hysteresis3D () // Destructeur { if (xnp_temperature != NULL) if (xnp_temperature->NomCourbe() == "_") delete xnp_temperature; if (Qzero_temperature != NULL) if (Qzero_temperature->NomCourbe() == "_") delete Qzero_temperature; if (xmu_temperature != NULL) if (xmu_temperature->NomCourbe() == "_") delete xmu_temperature; if (xnp_phase != NULL) if (xnp_phase->NomCourbe() == "_") delete xnp_phase; if (xnp_defEqui != NULL) if (xnp_defEqui->NomCourbe() == "_") delete xnp_defEqui; if (Qzero_defEqui != NULL) if (Qzero_defEqui->NomCourbe() == "_") delete Qzero_defEqui; if (Qzero_phase != NULL) if (Qzero_phase->NomCourbe() == "_") delete Qzero_phase; if (xmu_phase != NULL) if (xmu_phase->NomCourbe() == "_") delete xmu_phase; if (coef_paradefEqui != NULL) if (coef_paradefEqui->NomCourbe() == "_") delete coef_paradefEqui; }; // Lecture des donnees de la classe sur fichier void Hysteresis3D::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D ,LesFonctions_nD& lesFonctionsnD) { // ---- lecture du paramètre de prager ----- string nom; *(entreePrinc->entree) >> nom; // lecture d'un identificateur if(nom != "np=") { cout << "\n erreur en lecture du parametre de prager " << " on attendait la chaine : np= et on a lue " << nom; cout << "\n Hysteresis3D::LectureDonneesParticulieres " << "(UtilLecture * entreePrinc) " << endl ; throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on regarde si le paramètre de prager est thermo dépendant if(strstr(entreePrinc->tablcar,"np_thermo_dependant_")!=0) { thermo_dependant=true; *(entreePrinc->entree) >> nom; if (nom != "np_thermo_dependant_") { cout << "\n erreur en lecture de la thermodependance de np, on aurait du lire le mot cle np_thermo_dependant_" << " suivi du nom d'une courbe de charge ou de la courbe elle meme "<< endl; entreePrinc->MessageBuffer("**erreur2 Hysteresis3D::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } // lecture de la loi d'évolution du paramètre de prager en fonction de la température *(entreePrinc->entree) >> nom; // on regarde si la courbe existe, si oui on récupère la référence if (lesCourbes1D.Existe(nom)) { xnp_temperature = lesCourbes1D.Trouve(nom); } else { // sinon il faut la lire maintenant string non_courbe("_"); xnp_temperature = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str())); // lecture de la courbe xnp_temperature->LectDonnParticulieres_courbes (non_courbe,entreePrinc); } entreePrinc->NouvelleDonnee(); // prepa du flot de lecture } else // sinon on lit directement le paramètre de prager {*(entreePrinc->entree) >> xnp; if (xnp <= 0) {cout << "\n erreur en lecture du parametre de prager np= " << xnp << " il doit etre superieur a 0 ! "; cout << "\n Hysteresis3D::LectureDonneesParticulieres " << "(UtilLecture * entreePrinc) " << endl ; throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; // ---- lecture de mu : coefficient de lame ---- *(entreePrinc->entree) >> nom; if(nom != "mu=") { cout << "\n erreur en lecture du coefficient mu de lame " << " on attendait la chaine : mu= et on a lue " << nom; cout << "\n Hysteresis3D::LectureDonneesParticulieres " << "(UtilLecture * entreePrinc) " << endl ; throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } // on regarde si le coefficient de lame est thermo dépendant if(strstr(entreePrinc->tablcar,"mu_thermo_dependant_")!=0) { thermo_dependant=true; *(entreePrinc->entree) >> nom; if (nom != "mu_thermo_dependant_") { cout << "\n erreur en lecture de la thermodependance de mu, on aurait du lire le mot cle mu_thermo_dependant_" << " suivi du nom d'une courbe de charge ou de la courbe elle meme "; entreePrinc->MessageBuffer("**erreur3 Hysteresis3D::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } // lecture de la loi d'évolution du coefficient mu en fonction de la température *(entreePrinc->entree) >> nom; // on regarde si la courbe existe, si oui on récupère la référence if (lesCourbes1D.Existe(nom)) { xmu_temperature = lesCourbes1D.Trouve(nom); } else { // sinon il faut la lire maintenant string non_courbe("_"); xmu_temperature = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str())); // lecture de la courbe xmu_temperature->LectDonnParticulieres_courbes (non_courbe,entreePrinc); } entreePrinc->NouvelleDonnee(); // prepa du flot de lecture } else // sinon on lit directement le paramètre mu {*(entreePrinc->entree) >> xmu;}; // ---- lecture de la limite de plasticité infini ----- *(entreePrinc->entree) >> nom; if(nom != "Qzero=") { cout << "\n erreur en lecture du coefficient mu de lame " << " on attendait la chaine : Qzero= et on a lue " << nom; cout << "\n Hysteresis3D::LectureDonneesParticulieres " << "(UtilLecture * entreePrinc) " << endl ; throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } // on regarde si Qzero est thermo dépendant if(strstr(entreePrinc->tablcar,"Qzero_thermo_dependant_")!=0) { thermo_dependant=true; *(entreePrinc->entree) >> nom; if (nom != "Qzero_thermo_dependant_") { cout << "\n erreur en lecture de la thermodependance de Qzero, on aurait du lire le mot cle Qzero_thermo_dependant_" << " suivi du nom d'une courbe de charge ou de la courbe elle meme "; entreePrinc->MessageBuffer("**erreur4 Hysteresis3D::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } // lecture de la loi d'évolution du coefficient Qzero en fonction de la température *(entreePrinc->entree) >> nom; // on regarde si la courbe existe, si oui on récupère la référence if (lesCourbes1D.Existe(nom)) { Qzero_temperature = lesCourbes1D.Trouve(nom); } else { // sinon il faut la lire maintenant string non_courbe("_"); Qzero_temperature = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str())); // lecture de la courbe Qzero_temperature->LectDonnParticulieres_courbes (non_courbe,entreePrinc); } entreePrinc->NouvelleDonnee(); // prepa du flot de lecture } else // sinon on lit directement le paramètre Qzero {*(entreePrinc->entree) >> Qzero;}; // on garde en mémoire ce que l'on a lue xnp_lue=xnp; Qzero_lue=Qzero; xmu_lue=xmu; // --- lecture éventuelle d'une dépendance à la phase if ((strstr(entreePrinc->tablcar,"avec_phaseDeltaSig")!=NULL) || (strstr(entreePrinc->tablcar,"avec_phaseEps")!=NULL)) { string nom1,nom2; int drapeau=0; // une variable intermédiaire if (strstr(entreePrinc->tablcar,"avec_phaseDeltaSig")!=NULL) {drapeau=1;} else { drapeau=2; }; // on oriente le type de dépendance (contrainte ou def) // lecture des paramètres de phase entreePrinc->NouvelleDonnee(); // passage d'une ligne // cas de np if (strstr(entreePrinc->tablcar,"xnp_phase=")!=NULL) {drapeau +=10; // petite ope pour valider que l'on a bien lue qqchose *(entreePrinc->entree) >> nom; if (nom != "xnp_phase=") { cout << "\n erreur en lecture de la dependance a la phase de xnp, on aurait du lire" << " le mot cle xnp_phase=" << " suivi du nom d'une courbe de charge ou de la courbe elle meme "; entreePrinc->MessageBuffer("**erreur41 Hysteresis3D::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } // lecture de la loi d'évolution du coefficient xnp en fonction de la phase *(entreePrinc->entree) >> nom; // on regarde si la courbe existe, si oui on récupère la référence if (lesCourbes1D.Existe(nom)) { xnp_phase = lesCourbes1D.Trouve(nom); } else { // sinon il faut la lire maintenant string non_courbe("_"); xnp_phase = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str())); // lecture de la courbe xnp_phase->LectDonnParticulieres_courbes (non_courbe,entreePrinc); } entreePrinc->NouvelleDonnee(); // prepa du flot de lecture }; // cas de xmu if (strstr(entreePrinc->tablcar,"xmu_phase=")!=NULL) {drapeau +=10; // petite ope pour valider que l'on a bien lue qqchose *(entreePrinc->entree) >> nom; if (nom != "xmu_phase=") { cout << "\n erreur en lecture de la dependance a la phase de xmu, on aurait du lire" << " le mot cle xmu_phase=" << " suivi du nom d'une courbe de charge ou de la courbe elle meme "; entreePrinc->MessageBuffer("**erreur42 Hysteresis3D::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } // lecture de la loi d'évolution du coefficient xmu en fonction de la phase *(entreePrinc->entree) >> nom; // on regarde si la courbe existe, si oui on récupère la référence if (lesCourbes1D.Existe(nom)) { xmu_phase = lesCourbes1D.Trouve(nom); } else { // sinon il faut la lire maintenant string non_courbe("_"); xmu_phase = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str())); // lecture de la courbe xmu_phase->LectDonnParticulieres_courbes (non_courbe,entreePrinc); } entreePrinc->NouvelleDonnee(); // prepa du flot de lecture }; // cas de Qzero if (strstr(entreePrinc->tablcar,"Qzero_phase=")!=NULL) {drapeau +=10; // petite ope pour valider que l'on a bien lue qqchose *(entreePrinc->entree) >> nom; if (nom != "Qzero_phase=") { cout << "\n erreur en lecture de la dependance a la phase de Qzero, on aurait du lire" << " le mot cle Qzero_phase=" << " suivi du nom d'une courbe de charge ou de la courbe elle meme "; entreePrinc->MessageBuffer("**erreur43 Hysteresis3D::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } // lecture de la loi d'évolution du coefficient Qzero en fonction de la phase *(entreePrinc->entree) >> nom; // on regarde si la courbe existe, si oui on récupère la référence if (lesCourbes1D.Existe(nom)) { Qzero_phase = lesCourbes1D.Trouve(nom); } else { // sinon il faut la lire maintenant string non_courbe("_"); Qzero_phase = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str())); // lecture de la courbe Qzero_phase->LectDonnParticulieres_courbes (non_courbe,entreePrinc); } entreePrinc->NouvelleDonnee(); // prepa du flot de lecture }; // fin de la manip avec le drapeau // si drapeau > 10 cela veut dire qu'il y a eu au moins une validation // le reste de la division euclidienne = la valeur initiale if ((drapeau % 10) == 1) {avec_phaseDeltaSig = true; avec_phaseEps = false; } else if ((drapeau % 10) == 2) {avec_phaseDeltaSig = false; avec_phaseEps = true; } else // sinon, malgré la dépendance à la phase il n'y a aucun paramètre lue // donc on désactive {avec_phaseDeltaSig = false; avec_phaseEps = false; }; }; // --- lecture éventuelle d'une dépendance à la déformation équivalente if (strstr(entreePrinc->tablcar,"avec_defEquivalente")!=NULL) { string nom1,nom2; // lecture des de dépendance entreePrinc->NouvelleDonnee(); // passage d'une ligne // cas de np if (strstr(entreePrinc->tablcar,"xnp_defEqui=")!=NULL) {avec_defEqui=true; *(entreePrinc->entree) >> nom; if (nom != "xnp_defEqui=") { cout << "\n erreur en lecture de la dependance a la deformation equivalente de xnp, on aurait du lire" << " le mot cle xnp_defEqui=" << " suivi du nom d'une courbe de charge ou de la courbe elle meme "; entreePrinc->MessageBuffer("**erreur44 Hysteresis3D::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } // lecture de la loi d'évolution du coefficient xnp en fonction de def Equi *(entreePrinc->entree) >> nom; // on regarde si la courbe existe, si oui on récupère la référence if (lesCourbes1D.Existe(nom)) { xnp_defEqui = lesCourbes1D.Trouve(nom); } else { // sinon il faut la lire maintenant string non_courbe("_"); xnp_defEqui = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str())); // lecture de la courbe xnp_defEqui->LectDonnParticulieres_courbes (non_courbe,entreePrinc); } entreePrinc->NouvelleDonnee(); // prepa du flot de lecture } else { xnp_defEqui=NULL;}; // cas de Qzero if (strstr(entreePrinc->tablcar,"Qzero_defEqui=")!=NULL) {avec_defEqui=true; *(entreePrinc->entree) >> nom; if (nom != "Qzero_defEqui=") { cout << "\n erreur en lecture de la dependance a la deformation equivalente de Qzero, on aurait du lire" << " le mot cle Qzero_defEqui=" << " suivi du nom d'une courbe de charge ou de la courbe elle meme "; entreePrinc->MessageBuffer("**erreur44 Hysteresis3D::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } // lecture de la loi d'évolution du coefficient Qzero en fonction de def Equi *(entreePrinc->entree) >> nom; // on regarde si la courbe existe, si oui on récupère la référence if (lesCourbes1D.Existe(nom)) { Qzero_defEqui = lesCourbes1D.Trouve(nom); } else { // sinon il faut la lire maintenant string non_courbe("_"); Qzero_defEqui = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str())); // lecture de la courbe Qzero_defEqui->LectDonnParticulieres_courbes (non_courbe,entreePrinc); } entreePrinc->NouvelleDonnee(); // prepa du flot de lecture } else {Qzero_defEqui = NULL;} ; }; // --- lecture éventuelle d'une dépendance à la phase de la déformation if (strstr(entreePrinc->tablcar,"avec_phase_paradefEqui")!=NULL) { string nom1,nom2; // pour l'instant ne fonctionne qu'avec la dépendance conjointe à la def équivalente if (!avec_defEqui) { cout << "\n erreur la dependance a la phase de la deformation n'est licite que " << " conjointement avec la dependance la deformation equivalente de xnp qui n'est pas ici" << " activee on s'arrete donc !! "; entreePrinc->MessageBuffer("**erreur444 Hysteresis3D::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // lecture des de dépendance entreePrinc->NouvelleDonnee(); // passage d'une ligne // lecture de la fonction if (strstr(entreePrinc->tablcar,"coef_paradefEqui=")!=NULL) {avec_phase_paradefEqui=true; *(entreePrinc->entree) >> nom; if (nom != "coef_paradefEqui=") { cout << "\n erreur en lecture de la dependance a la phase de la deformation totale, " << " on aurait du lire le mot cle coef_paradefEqui=" << " suivi du nom d'une courbe de charge ou de la courbe elle meme "; entreePrinc->MessageBuffer("**erreur445 Hysteresis3D::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } // lecture de la loi d'évolution du paradefEqui en fonction de cos(3phi) de la déformation totale *(entreePrinc->entree) >> nom; // on regarde si la courbe existe, si oui on récupère la référence if (lesCourbes1D.Existe(nom)) { coef_paradefEqui = lesCourbes1D.Trouve(nom); } else { // sinon il faut la lire maintenant string non_courbe("_"); coef_paradefEqui = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str())); // lecture de la courbe coef_paradefEqui->LectDonnParticulieres_courbes (non_courbe,entreePrinc); } entreePrinc->NouvelleDonnee(); // prepa du flot de lecture } else { cout << "\n erreur en lecture de la dependance a la phase de la deformation totale, " << " on devrait avoir sur la ligne courante le mot cle coef_paradefEqui=" << " suivi du nom d'une courbe de charge ou de la courbe elle meme "; entreePrinc->MessageBuffer("**erreur446 Hysteresis3D::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; // --- lecture éventuelle des paramètres de réglage ---- // de l'algo de résolution de l'équation d'avancement temporel if(strstr(entreePrinc->tablcar,"avec_parametres_de_reglage_")!=0) {type_resolution_equa_constitutive = 0; // valeur voulant dire qu'il n'y a pas eu de lecture entreePrinc->NouvelleDonnee(); // on se positionne sur un nouvel enreg // on lit tant que l'on ne rencontre pas la ligne contenant "fin_parametres_reglage_Hysteresis_" // ou un nouveau mot clé global auquel cas il y a pb !! MotCle motCle; // ref aux mots cle while (strstr(entreePrinc->tablcar,"fin_parametres_reglage_Hysteresis_")==0) { // si on a un mot clé global dans la ligne courante c-a-d dans tablcar --> erreur if ( motCle.SimotCle(entreePrinc->tablcar)) { cout << "\n erreur de lecture des parametre de reglage d'hysteresis: on n'a pas trouve le mot cle " << " fin_parametres_reglage_Hysteresis_ et par contre la ligne courante contient un mot cle global "; entreePrinc->MessageBuffer("** erreur5 des parametres de reglage de la loi de comportement d'hyteresis**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // lecture d'un mot clé *(entreePrinc->entree) >> nom; if ((entreePrinc->entree)->rdstate() == 0) {} // lecture normale #ifdef ENLINUX else if ((entreePrinc->entree)->fail()) // on a atteind la fin de la ligne et on appelle un nouvel enregistrement { entreePrinc->NouvelleDonnee(); // lecture d'un nouvelle enregistrement *(entreePrinc->entree) >>nom; } #else else if ((entreePrinc->entree)->eof()) // la lecture est bonne mais on a atteind la fin de la ligne { if(nom != "fin_parametres_reglage_Hysteresis_") {entreePrinc->NouvelleDonnee(); *(entreePrinc->entree) >> nom;}; } #endif else // cas d'une erreur de lecture { cout << "\n erreur de lecture inconnue "; entreePrinc->MessageBuffer("** erreur5 des parametres de reglage de la loi de comportement d'hyteresis**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // cas du type de résolution if(nom == "type_de_resolution_") {*(entreePrinc->entree) >> type_resolution_equa_constitutive; if ((type_resolution_equa_constitutive < 1) || (type_resolution_equa_constitutive> 6)) // 6 valeur exploratoire { cout << "\n erreur en lecture du type de resolution, on attendait un nombre compris entre 1 et 6 " << " et on a lu : " << type_resolution_equa_constitutive << " ce cas n'est pas implante (cf. doc) " << "\n Hysteresis3D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; } // type de calcul de la matrice tangente else if (nom == "type_calcul_comportement_tangent_") {*(entreePrinc->entree) >> type_calcul_comportement_tangent; if ((type_calcul_comportement_tangent < 1) || (type_calcul_comportement_tangent> 2)) { cout << "\n erreur en lecture du type de calcul du comportement tangent," << " on attendait un nombre compris entre 1 et 2 " << " et on a lu : " << type_calcul_comportement_tangent << " ce cas n'est pas implante (cf. doc) " << "\n Hysteresis3D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; } // nombre d'itération maxi else if (nom == "nb_iteration_maxi_") {*(entreePrinc->entree) >> nb_boucle_maxi; alg_zero.Modif_iter_max(nb_boucle_maxi); } // nombre de dichotomie maxi else if (nom == "nb_dichotomie_maxi_") {*(entreePrinc->entree) >> nb_dichotomie; alg_zero.Modif_nbMaxiIncre(nb_dichotomie); } // tolérance absolue sur le résidu else if (nom == "tolerance_residu_") {*(entreePrinc->entree) >> tolerance_residu; alg_zero.Modif_prec_res_abs(tolerance_residu); } // tolérance relative sur le résidu else if (nom == "tolerance_residu_rel_") {*(entreePrinc->entree) >> tolerance_residu_rel; alg_zero.Modif_prec_res_rel(tolerance_residu_rel); } // le maxi de variation que l'on tolère d'une itération à l'autre else if (nom == "maxi_delta_var_sig_sur_iter_pour_Newton_") { *(entreePrinc->entree) >> maxi_delta_var_sig_sur_iter_pour_Newton; } // type d'algo de kutta else if (nom == "cas_kutta_") {*(entreePrinc->entree) >> cas_kutta; } // l'erreur absolue else if (nom == "erreurAbsolue_") {*(entreePrinc->entree) >> erreurAbsolue; } // l'erreur relative else if (nom == "erreurRelative_") {*(entreePrinc->entree) >> erreurRelative; } // le nombre d'appel maxi de la fonction f else if (nom == "nbMaxiAppel_") {*(entreePrinc->entree) >> nbMaxiAppel; alg_edp.Modif_nbMaxiAppel(nbMaxiAppel); } // tolérance sur la coïncidence else if (nom == "tolerance_coincidence_") {*(entreePrinc->entree) >> tolerance_coincidence; } // tolérance sur le calcul de centre else if (nom == "tolerance_centre_") {*(entreePrinc->entree) >> tolerance_centre; } // minimun du rayon else if (nom == "mini_rayon_") {*(entreePrinc->entree) >> mini_rayon; } // nombre maxi d'inversion sur le pas else if (nom == "nb_maxInvCoinSurUnPas_") {*(entreePrinc->entree) >> nb_maxInvCoinSurUnPas; } else if (nom == "force_phi_zero_si_negatif_") {*(entreePrinc->entree) >> force_phi_zero_si_negatif; } else if (nom == "depassement_Q0_") {*(entreePrinc->entree) >> depassement_Q0; } else if (nom == "type_de_transport_memorisation_") {*(entreePrinc->entree) >> type_de_transport_memorisation; } else if (nom == "niveau_bascule_fct_aide_") {*(entreePrinc->entree) >> niveau_bascule_fct_aide; } // l'angle mini pour les trajets neutre else if (nom == "min_angle_trajet_neutre_") {*(entreePrinc->entree) >> min_angle_trajet_neutre; if ((min_angle_trajet_neutre < 0.) || (min_angle_trajet_neutre > 1.)) { cout << "\n erreur en lecture sur le l'angle mini pour les trajets neutre, " << "\n il doit etre compris entre 0 et 1 on a lu : " << min_angle_trajet_neutre << "\n Hysteresis3D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; } // possibilité ou non d'accepter transitoirement un cosAlpha négatif else if (nom == "possibilite_cosAlphaNegatif_") {*(entreePrinc->entree) >> possibilite_cosAlphaNegatif; } else if (nom == "mini_Qsig_pour_phase_sigma_Oi_tdt_") {*(entreePrinc->entree) >> mini_Qsig_pour_phase_sigma_Oi_tdt; // if (mini_Qsig_pour_phase_sigma_Oi_tdt < 0.) // { cout << "\n erreur en lecture sur mini_Qsig_pour_phase_sigma_Oi_tdt, " // << "\n il doit etre positif on a lu : " << mini_Qsig_pour_phase_sigma_Oi_tdt // << "\n Hysteresis3D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; // throw (UtilLecture::ErrNouvelleDonnee(-1)); // Sortie(1); // }; } else if (nom == "mini_QepsilonBH_") {*(entreePrinc->entree) >> mini_QepsilonBH; // if (mini_QepsilonBH < 0.) // { cout << "\n erreur en lecture sur mini_QepsilonBH, " // << "\n il doit etre positif on a lu : " << mini_QepsilonBH // << "\n Hysteresis3D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; // throw (UtilLecture::ErrNouvelleDonnee(-1)); // Sortie(1); // }; } // prise en compte des variations de w' et w'point dans le calcul de l'évolution tangente else if (nom == "avecVarWprimeS_") {*(entreePrinc->entree) >> avecVarWprimeS; } // forcer un affichage particulier pour les méthodes else if (nom == "permet_affichage_") {Lecture_permet_affichage(entreePrinc,lesFonctionsnD); alg_edp.Change_niveau_affichage(Permet_affichage()); } // forcer un stockage des indicateurs de la résolution else if (nom == "sortie_post_") {*(entreePrinc->entree) >> sortie_post; } // sinon ce n'est pas un mot clé connu, on le signale else if(nom != "fin_parametres_reglage_Hysteresis_") { cout << "\n erreur en lecture d'un parametre, le mot cle est inconnu " << " on a lu : " << nom << endl; if (ParaGlob::NiveauImpression()>3) cout << "\n Hysteresis3D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } }; //-- fin du while }; //-- fin de la lecture des paramètres de réglage // traitement de certains paramètres non initialisés if (type_calcul_comportement_tangent == 0) { // == 0 signifie qu'il n'y a pas eu de lecture, on met donc les valeurs cohérentes par défaut if (type_resolution_equa_constitutive == 1) {type_calcul_comportement_tangent = 1;} else {type_calcul_comportement_tangent = 2;}; }; // le niveau d'affichage alg_zero.Modif_affichage(Permet_affichage()); // appel au niveau de la classe mère Loi_comp_abstraite::Lecture_type_deformation_et_niveau_commentaire (*entreePrinc,lesFonctionsnD); }; // affichage de la loi void Hysteresis3D::Affiche() const { cout << " \n loi_de_comportement d'hysteresis3D " ; if ( xnp_temperature != NULL) { cout << " np thermo dependant " << " courbe np=f(T): " << xnp_temperature->NomCourbe() <<" ";} else { cout << " np= " << xnp_lue ;}; if ( Qzero_temperature != NULL) { cout << " Qzero thermo dependant " << " courbe np=f(T): " << Qzero_temperature->NomCourbe() <<" ";} else { cout << " Qzero= " << Qzero_lue ;}; if ( xmu_temperature != NULL) { cout << " xmu thermo dependant " << " courbe xmu=f(T): " << xmu_temperature->NomCourbe() <<" ";} else { cout << " mu= " << xmu_lue ;}; // -- éventuellement dépendance à la phase if (avec_phaseDeltaSig || avec_phaseEps) {if (avec_phaseDeltaSig ) { cout << " \n dependance a la phase de Delta_R^t_sigma ";} else { cout << " \n dependance a la phase de la deformation ";}; if (xnp_phase != NULL) { cout << " np dependant de la phase " << " courbe np=f(3cos(phi)): " << xnp_phase->NomCourbe() <<" ";}; if (Qzero_phase != NULL) { cout << " Qzero dependant de la phase " << " courbe Qzero=f(3cos(phi)): " << Qzero_phase->NomCourbe() <<" ";}; if (xmu_phase != NULL) { cout << " xmu dependant de la phase " << " courbe xmu=f(3cos(phi)): " << xmu_phase->NomCourbe() <<" ";}; }; // -- éventuellement dépendance à la defEqui if (avec_defEqui) {if (xnp_defEqui != NULL) { cout << " np dependant de la deformation equivalente " << " courbe np=f(3cos(phi)): " << xnp_defEqui->NomCourbe() <<" ";}; if (Qzero_defEqui != NULL) { cout << " Qzero dependant de la deformation equivalente " << " courbe np=f(3cos(phi)): " << Qzero_defEqui->NomCourbe() <<" ";}; }; // -- éventuellement dépendance à la phase de la déformation totale if (avec_phase_paradefEqui) {if (coef_paradefEqui != NULL) { cout << " dependance a la phase de la deformation totale " << " courbe coef_paradefEqui=f(3cos(phi)): " << coef_paradefEqui->NomCourbe() <<" ";}; }; // --- paramètre de réglage cout << "\n type_resolution_equa_constitutive " << type_resolution_equa_constitutive << " type_calcul_comportement_tangent " << type_calcul_comportement_tangent; if (type_resolution_equa_constitutive == 1) { cout << " \n type de resolution: linearisation, nbmax iteration= " << nb_boucle_maxi << " nbmax_dichotonmie= " << nb_dichotomie << " tolerance_residu_absolue= " << tolerance_residu << " tolerance_residu_relative= " << tolerance_residu_rel << " maxi_delta_var_sig_sur_iter_pour_Newton= " << maxi_delta_var_sig_sur_iter_pour_Newton; } else //if ((type_resolution_equa_constitutive == 2) || (type_resolution_equa_constitutive == 3)) { cout << " \n type de resolution: Runge_Kutta " << cas_kutta << " erreurAbsolue " << erreurAbsolue << " erreurRelative= " << erreurRelative ; }; cout << " tolerance_coincidence= " << tolerance_coincidence << " mini_rayon " << mini_rayon << " tolerance_centre= " << tolerance_centre << " nb_maxInvCoinSurUnPas= " << nb_maxInvCoinSurUnPas << " min_angle_trajet_neutre= " << min_angle_trajet_neutre << " possibilite_cosAlphaNegatif= " << possibilite_cosAlphaNegatif << " mini_Qsig_pour_phase_sigma_Oi_tdt= " << mini_Qsig_pour_phase_sigma_Oi_tdt << " mini_QepsilonBH= " << mini_QepsilonBH << " force_phi_zero_si_negatif= " << force_phi_zero_si_negatif << " " << " depassement_Q0= " << depassement_Q0 << " type_de_transport_memorisation= "<< type_de_transport_memorisation << " niveau_bascule_fct_aide= "<< niveau_bascule_fct_aide; // niveau d'affichage Affiche_niveau_affichage(); cout << " sortie_post "<< sortie_post << " "; // appel de la classe mère Loi_comp_abstraite::Affiche_don_classe_abstraite(); }; // affichage et definition interactive des commandes particulières à chaques lois void Hysteresis3D::Info_commande_LoisDeComp(UtilLecture& entreePrinc) { ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier cout << "\n definition standart (rep o) ou exemples exhaustifs (rep n'importe quoi) ? "; string rep = "_"; // procédure de lecture avec prise en charge d'un retour chariot rep = lect_return_defaut(true,"o"); Qzero = 200.; xnp = 1.; xmu = 1000; // init à des exemples de valeurs if ((rep != "o") && (rep != "O" ) && (rep != "0") ) { sort << "\n#-------------------------------------------------------------------------" << "\n# ....... loi_de_comportement d'hysteresis 3D ........ |" << "\n# para de prager : mu : limite maxi de plasticite |" << "\n#-------------------------------------------------------------------------" << "\n np= " << setprecision(6) << xnp << " mu= " << setprecision(6) << xmu << " Qzero= "<< setprecision(6) << Qzero << "\n# il est possible de definir des parametres thermo-dependants (1 ou 2 ou 3 parametres)" << "\n# par exemple pour les trois parametres on ecrit: " << "\n#-----------------------------------" << "\n# np= np_thermo_dependant_ courbe1 " << "\n# mu= mu_thermo_dependant_ courbe4 " << "\n# Qzero= Qzero_thermo_dependant_ courbe3 " << "\n#-----------------------------------" << "\n# noter qu'apres la definition de chaque courbe, on change de ligne, d'une maniere inverse " << "\n# si la valeur du parametre est fixe, on poursuit sur la meme ligne. " << "\n# par exemple supposons np fixe, mu et Qzero thermo-dependant, on ecrit: " << "\n#-----------------------------------" << "\n# np= 2. mu= mu_thermo_dependant_ courbe4 " << "\n# Qzero= Qzero_thermo_dependant_ courbe3 " << "\n#-----------------------------------" << "\n# il est egalement possible de definir une dependance a la phase des parametres " << "\n# deux possibilites: soit une dependance a la phase du delta deviateur de contrainte " << "\n# entre le centre instantane et sa valeur a tdt" << "\n# soit une dependance a la phase a la phase de la deformation totale. " << "\n# Dans ce cas, a la suite du parametre Qzero on met le mot cle: avec_phaseDeltaSig ou avec_phaseDeltaSig" << "\n# puis sur la ligne qui suit on met les fonctions de controle de la dependance " << "\n# suit un exemple de declaration (il est possible d'ommettre une fonction " << "\n# mais il faut respecter l'ordre ). Comme pour toutes les courbes on peut soit mettre directement" << "\n# la courbe, soit mettre un nom de courbe. Ne pas oublier de passer a la ligne apres chaque courbe " << "\n# np= 1 mu= 4000 Qzero= 80 avec_phaseDeltaSig " << "\n# xnp_phase= courbe_xnp_phase " << "\n# xmu_phase= courbe_xmu_phase " << "\n# Qzero_phase= courbe_Qzero_phase " << "\n# " << "\n#-----------------------------------" << "\n# il est egalement possible de definir une dependance a la deformation equivalente (cf. doc)" << "\n# il s'agit ici d'une grandeur qui mesure une mesure de def equivalente a un trajet radial pur. " << "\n# Il s'agit :" << "\n# 1) d'une dependance du parametre de prager sous la forme suivante:" << "\n# xp = f(eps_equi * Q_deltaSigma_R_tdt * para) tel que para = (2*Qzero^2/(w'*mu). " << "\n# 2) d'une dependance de la saturation Qzero sous la forme suivante:" << "\n# Qzero = f(eps_equi) * Qzero " << "\n# Dans ce cas, a la suite du parametre Qzero (ou des parametres de phase et du type de transport ) " << "\n# on met le mot cle: avec_defEqui . " << "\n# puis sur la ligne qui suit on met la fonctions de controle de la dependance pour xnp et/ou pour Qzero. " << "\n# on peut mettre l'une ou l'autre ou les deux " << "\n# suit un exemple de declaration. Comme pour toutes les courbes on peut soit mettre directement" << "\n# la courbe, soit mettre un nom de courbe. Ne pas oublier de passer a la ligne apres chaque courbe " << "\n# np= 1 mu= 4000 Qzero= 80 avec_defEqui " << "\n# xnp_phase= courbe_xnp_defEqui Qzero_phase= courbe_Qzero_defEqui" << "\n# " << "\n#-----------------------------------" << "\n# il est egalement possible de definir une dependance a la phase de la deformation totale" << "\n# (cf. doc) pour para = (2*Qzero^2/(w'*mu) . Il s'agit d'une fonction multiplicatrice de para" << "\n# Cette dependance s'utilise donc conjointement avec la dependance a la deformation equivalente " << "\n# Dans le cas d'une dependance, a la suite de la dependance a la deformation equivalente " << "\n# on met le mot cle: avec_phase_paradefEqui . " << "\n# puis sur la ligne qui suit on met la fonctions de controle de la dependance. " << "\n# suit un exemple de declaration. Comme pour toutes les courbes on peut soit mettre directement" << "\n# la courbe, soit mettre un nom de courbe. Ne pas oublier de passer a la ligne apres chaque courbe " << "\n# np= 1 mu= 4000 Qzero= 80 avec_defEqui " << "\n# xnp_phase= courbe_xnp_defEqui " << "\n# avec_phase_paradefEqui " << "\n# coef_paradefEqui= courbe_coef_paradefEqui " << "\n# " << "\n#-----------------------------------" << "\n# il est egalement possible (mais pas obligatoire) de definir les parametres de reglage " << "\n# de la resolution. Dans ce cas, a la suite de la limite maxi de plasticite (si l'on est sans phase) " << "\n# ou sur la ligne qui suit le dernier parametre de phase on indique le mot cle: avec_parametres_de_reglage_ " << "\n# ensuite on defini (dans un ordre quelconque) les parametres que l'on souhaites " << "\n# chaque parametre est precede d'un mot cle, on a donc une succession de mot cle suivi d'une grandeur " << "\n# on peut avoir un ou plusieur couple parametre-grandeur sur chaque ligne " << "\n# par contre la derniere ligne doit comporter uniquement le mot cle: " << "\n# fin_parametres_reglage_Hysteresis_ " << "\n# les differents parametres sont: " << "\n# - le type de resolution: par linearisation(1) (valeur par defaut) ou integration directe via Runge_Kutta(2)" << "\n# s'il n'y a pas convergence avec (1) arret et generation d'une exception, avec 2, on bascule sur (1) et " << "\n# s'il n'y a pas de nouveau convergence on bascule sur un appel directe de kutta" << "\n# type (3) = idem que type (2) mais s'il n'y a pas convergence arret et genration d'une exception" << "\n# type (4) = idem que type (2) mais s'il n'y a pas convergence bascule sur la linearisation, et s'il n'y" << "\n# a pas convergence arret et generation d'une exception" << "\n# ex: type_de_resolution_ 2 " << "\n# - le nombre d'iteration (pour (1)) ex: nb_iteration_maxi_ 20 " << "\n# - le nombre de dichotomie(pour (1)) ex: nb_dichotomie_maxi_ 20 " << "\n# - la tolerance absolue sur le residu(pour (1)) ex: tolerance_residu_ 1.e-3 " << "\n# - la tolerance relative sur le residu(pour (1)) ex: tolerance_residu_rel_ 1.e-3 " << "\n# signifie que la precision sera tolerance_residu_ + ||sig_tdt|| * tolerance_residu_rel_" << "\n# la norme maximale du delta sigma qui est permise a chaque iteration de Newton " << "\n# par defaut = -1 , si on veut une autre valeur: exe: " << "\n# maxi_delta_var_sig_sur_iter_pour_Newton_ 2 # donc 2 MPa a chaque iter " << "\n# si on donne une valeur negative (val par defaut), il n'y a pas de limite " << "\n# " // << "\n# si la valeur est negative il s'agit d'une presicion relative: exe -1.e-3 " // << "\n# signifie que la precision sera max (0.001*||sig_tdt||,0.001) " << "\n# - le type de Runge_kutta (pour (2)): 3 pour une methode imbriquee 2-3, 4 pour 3-4, 5 pour 4-5, " << "\n# ex: cas_kutta_ 5 " << "\n# - l'erreur absolue sur la contrainte finale(pour (2)) ex: erreurAbsolue_ 1.e-3" << "\n# - l'erreur relative sur la contrainte finale(pour (2)) ex: erreurRelative_ 1.e-5" << "\n# - le nombre maxi d'appel de la fonction derivee (sigma_point) (pour (2)) ex: nbMaxiAppel_ 100" << "\n# " << "\n# - la tolerance sur la detection des coincidences ex: tolerance_coincidence_ 1.e-3" << "\n# si le nombre indique est negatif, cela signifie que la tolerance sera relative a la valeur " << "\n# de la norme de la contrainte de reference: exe -0.1 signifie que la tolerance sera " << "\n# max (0.1*||sig_R||,0.1) " << "\n# " << "\n# - la tolerance sur le calcul des hyper-centres de trajet neutre ex: tolerance_centre_ 1.e-3" << "\n# si le nombre indique est negatif, cela signifie que la tolerance sera relative a la valeur " << "\n# de la norme de la contrainte de reference: exe -0.1 signifie que la tolerance sera " << "\n# max (0.1*||sig_R||,0.1) " << "\n# " << "\n# -le mini en dessous duquel on considere delta_O_R et delta_R_Stdt nul ex: mini_rayon_ 1. e-8" << "\n# Meme comportement que pour mini_Qsig_pour_phase_sigma_Oi_tdt_, dans le cas ou mini_rayon est negatif" << "\n# ce parametre devient un parametre de regularisation " << "\n# " << "\n# -le maxi d'inversion ou de coincidence que l'on tolere sur un pas " << "\n# dans le cas ou ce maxi est un nombre negatif, on utilise sa valeur absolue et lorsque le maxi " << "\n# depasse ce nombre, on retient la valeur final de la contrainte, sinon cas normal: on genere une erreur " << "\n# ex nb_maxInvCoinSurUnPas_ -20" << "\n# " << "\n# - min_angle_trajet_neutre : indique le minimun du cos de l'angle en dessous duquel le trajet est neutre " << "\n# ex min_angle_trajet_neutre_ 0.008" << "\n# " << "\n# - possibilite_cosAlphaNegatif : indique si oui (diff de 0) on non (0) on accepte transitoirement une valeur " << "\n# de cosAlpha negative: ex: possibilite_cosAlphaNegatif_ 0 , si c'est non, c'est traite comme un cas neutre " << "\n# " << "\n#------------- mini_Qsig_pour_phase_sigma_Oi_tdt_ ------------------" << "\n# - mini_Qsig_pour_phase_sigma_Oi_tdt : indique le minimum de Qsig en dessous duquel on " << "\n# considere que la phase pour delta sigma de Oi a tdt, est nulle " << "\n# ex mini_Qsig_pour_phase_sigma_Oi_tdt_ 1.5 " << "\n# Dans le cas ou mini_Qsig_pour_phase_sigma_Oi_tdt_ est negatif, cela devient un parametre de regularisation " << "\n# Qsig est alors transforme en (Qsig-mini_Qsig_pour_phase_sigma_Oi_tdt) au niveau des divisions qui servent " << "\n# a calculer la phase. Dans ce cas l'angle de phase est toujours calculable, par contre pour les faibles " << "\n# valeur de Qsig, on peut avoir angle errone, mais ce n'est peut-etre pas un pb " << "\n# " << "\n#------------- mini_QepsilonBH_ ------------------" << "\n# - mini_QepsilonBH : indique le minimum de QepsilonBH en dessous duquel on " << "\n# considere que la phase pour la deformation totale, est nulle " << "\n# ex mini_QepsilonBH_ 1.e-4 " << "\n# Meme comportement que pour mini_Qsig_pour_phase_sigma_Oi_tdt_, dans le cas ou mini_QepsilonBH est negatif" << "\n# ce parametre devient un parametre de regularisation " << "\n# " << "\n#------------- force_phi_zero_si_negatif_ ------------------" << "\n# - au niveau de l'equation constitutive, phi doit-etre toujours positif, cependant pendant le processus " << "\n# de convergence il peut etre transitoirement negatif: on peut neanmoins forcer phi a etre toujours >= 0 " << "\n# avec le parametre : force_phi_zero_si_negatif_ " << "\n# Par defaut => force_phi_zero_si_negatif_ = 0. : on ne force pas la mise a 0" << "\n# si : force_phi_zero_si_negatif_ x , avec x diff de 0 : on force la mise a 0 " << "\n# si phi devient negatif et |phi| < x " << "\n#------------- type de transport ------------------" << "\n# - il est egalement possible de preciser un type de transport des grandeurs memorises " << "\n# (cf. doc) " << "\n# Dans ce cas, on met le mot cle: type_de_transport_memorisation_ suivi d'un entier signe 'i' " << "\n# i = 0 : transport historique en mixte (valeur par defaut pour l'instant) " << "\n# i = -1 : transport incremental ( a la fin de chaque increment) de maniere coherente avec " << "\n# la derivee de Jauman " << "\n#--------------- utilisation de la fonction d'aide -----------------" << "\n# " << "\n# - l'algorithme de gestion de la memorisation discrete s'effectue soit via le rayon des " << "\n# hypersphere representant les tenseurs OiSigma_tdt ceci pour de faibles rayons, " << "\n# soit via une fonction d'aide pour des rayons importants. Le passage entre ces deux modes " << "\n# de gestion s'effectue en fonction du parametre niveau_bascule_fct_aide_ qui est compris entre 0 et 1" << "\n# ex: niveau_bascule_fct_aide_ 0.5 # signifie que l'on bascule pour un rayon superieur a 50% " << "\n# # du rayon maxi " << "\n# " << "\n# " << "\n#-------------- limitation de l'intensite du deviateur ------------------" << "\n# " << "\n# - normalement l'intensite du deviateur des contraintes Qsig doit etre inferieure a la saturation Q_0 " << "\n# le parametre depassement_Q0 donne la valeur toleree de depassement, au-dessus de laquelle " << "\n# la contrainte n'est plus recevable " << "\n# ex: depassement_Q0_ 1.2 # signifie que l'on tolere 20% de deplacement" << "\n# " << "\n# " << "\n# -------------- calcul du comportement tangent ---------" << "\n# - Pour le type de resolution par linearisation, le comportement tangent est calcule par une methode coherente" << "\n# differente du cas de type de resolution par Kutta. Il est possible d'indiquer explicitement " << "\n# le type de calcul du comportement tangent: deux cas possibles, soit en utilisant l'equation linearise " << "\n# (cas = 1), soit en utilisant l'equation exacte sans linearisation (cas 2) " << "\n# Pour cela, par exemple apres la definition du cas de resolution , on indique le mot cle" << "\n# type_calcul_comportement_tangent_ suivi du cas : 1 ou 2 " << "\n# ex type_calcul_comportement_tangent_ 2" << "\n# Il est possible de tenir compte ou pas de la variation de l'angle de phase et de sa derivee danse le " << "\n# calcul du comportement tangent. Par defaut, il n'y a pas de prise en compte de ces variations. Pour " << "\n# en tenir compte il faut mettre le mot cle avecVarWprimeS_ suivi de 1 (0 etant la valeur par defaut) " << "\n# ex avecVarWprimeS_ 1" << "\n# " << "\n# -------------- affichage des erreurs et des warning ---------- " << "\n# - l'affichage normale est fonction du parametre global d'affichage gerer par le niveau d'affichage" << "\n# cependant pour des raisons par exemple de mise au point, il est possible de permettre l'affichage " << "\n# a un niveau particulier (mot cle : permet_affichage_ suivi d'un nombre entier) en plus de l'affichage normal. " << "\n# l'affichage s'effectuera donc en fonction de l'affichage normale et de l'affichage particulier." << "\n# Le fonctionnement de l'affichage particulier suit les mêmes règles que l'affichage globale" << "\n# soit permet_affichage_ est nulle (cas par defaut), dans ce cas l'affichage est fonction du niveau global" << "\n# soit permet_affichage_ vaut n par exemple, dans ce cas l'affichage est fonction uniquement de n " << "\n# " << "\n# ex: permet_affichage_ 5 " << "\n# --------------- acces aux indicateurs de la resolution par -------" << "\n# A chaque resolution, il est possible de stocker les indicateurs: nombre d'iteration, d'increment " << "\n# precision etc. les indicateurs sont renseignes en fonction du type de resolution " << "\n# le mot cle est sortie_post_ , par defaut il vaut 0, dans ce cas aucun indicateur n'est stoke" << "\n# s'il est different de 0, on peut acceder aux indicateurs en post-traitement" << "\n# seules les indicateurs en cours sont disponibles, il n'y a pas de stockage sur plusieurs increment " << "\n# " << "\n# ex: sortie_post_ 1 " << "\n# " << "\n# \n Exemple de declaration: sans la phase " << "\n#-------------------------------------------------------------------------" << "\n# ....... loi_de_comportement d'hysteresis 3D ........ |" << "\n# para de prager : mu : limite maxi de plasticite |" << "\n#-------------------------------------------------------------------------" << "\n# np= " << setprecision(6) << xnp << " mu= " << setprecision(6) << xmu << "\n# Qzero= "<< setprecision(6) << Qzero << " avec_parametres_de_reglage_ " << "\n# nb_iteration_maxi_ 20 nb_dichotomie_maxi_ 20 tolerance_residu_ 1.e-3 tolerance_residu_rel_ 1.e-5 " << "\n# tolerance_coincidence_ 1.e-3 mini_rayon_ 1. e-8 tolerance_centre_ 1. e-3 " << "\n# fin_parametres_reglage_Hysteresis_ " << "\n# " << "\n# \n Exemple de declaration pour une resolution avec une methode de Runge_Kutta: " << "\n#-------------------------------------------------------------------------" << "\n# ....... loi_de_comportement d'hysteresis 3D ........ |" << "\n# para de prager : mu : limite maxi de plasticite |" << "\n#-------------------------------------------------------------------------" << "\n# np= " << setprecision(6) << xnp << " mu= " << setprecision(6) << xmu << "\n# Qzero= "<< setprecision(6) << Qzero << " avec_parametres_de_reglage_ " << "\n# type_de_resolution_ 2 " << "\n# cas_kutta_ 5 erreurAbsolue_ 1.e-3 erreurRelative_ 1.e-5 nbMaxiAppel_ 100" << "\n# tolerance_coincidence_ 1.e-3 nb_maxInvCoinSurUnPas_ 20 min_angle_trajet_neutre_ 0.008" << "\n# possibilite_cosAlphaNegatif_ 0 mini_Qsig_pour_phase_sigma_Oi_tdt_ 1.5 " << "\n# fin_parametres_reglage_Hysteresis_ "; } else {sort << "\n# \n Exemple de declaration pour une resolution avec une methode de Runge_Kutta: " << "\n#-------------------------------------------------------------------------" << "\n# ....... loi_de_comportement d'hysteresis 3D ........ |" << "\n# para de prager : mu : limite maxi de plasticite |" << "\n#-------------------------------------------------------------------------" << "\n np= " << setprecision(6) << xnp << " mu= " << setprecision(6) << xmu << " Qzero= "<< setprecision(6) << Qzero << " avec_parametres_de_reglage_ " << "\n type_de_resolution_ 2 " << "\n cas_kutta_ 5 erreurAbsolue_ 1.e-3 erreurRelative_ 1.e-5 nbMaxiAppel_ 3000" << "\n tolerance_coincidence_ 1.e-3 nb_maxInvCoinSurUnPas_ 20 min_angle_trajet_neutre_ 0.008" << "\n possibilite_cosAlphaNegatif_ 0 mini_Qsig_pour_phase_sigma_Oi_tdt_ 1.5 " << "\n fin_parametres_reglage_Hysteresis_ "; }; sort << endl; // appel de la classe mère Loi_comp_abstraite::Info_commande_don_LoisDeComp(entreePrinc); }; // test si la loi est complete int Hysteresis3D::TestComplet() { int ret = LoiAbstraiteGeneral::TestComplet(); if ((xnp_temperature == NULL) && (xnp == ConstMath::tresgrand)) { cout << " \n le parametre de prager n'est pas défini pour la loi " << Nom_comp(id_comp) << '\n'; ret = 0; } if ((xmu_temperature == NULL) && (xmu == ConstMath::tresgrand)) { cout << " \n le parametre de lame mu n'est pas défini pour la loi " << Nom_comp(id_comp) << '\n'; ret = 0; } if ((Qzero_temperature == NULL) && (Qzero == ConstMath::tresgrand)) { cout << " \n la limite de plasticite n'est pas défini pour la loi " << Nom_comp(id_comp) << '\n'; ret = 0; } return ret; }; // calcul d'un module d'young équivalent à la loi, ceci pour un // chargement nul double Hysteresis3D::Module_young_equivalent(Enum_dure temps,const Deformation & ,SaveResul * ) { // par défaut on prend un mu de 0.3 et on utilise l'équivalent d'une loi élastique // mu = G = E/(2(1+nu)) -> E=2.6 * mu if (xmu_temperature != NULL) xmu = xmu_temperature->Valeur(*temperature); return (2.6 * xmu); }; // récupération des grandeurs particulière (hors ddl ) // correspondant à liTQ // absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière void Hysteresis3D::Grandeur_particuliere (bool ,List_io& liTQ,Loi_comp_abstraite::SaveResul * saveDon,list& decal) const { // ici on est en 3D et les grandeurs sont par principe en absolue, donc la variable absolue ne sert pas // on passe en revue la liste List_io::iterator itq,itqfin=liTQ.end(); list::iterator idecal=decal.begin(); for (itq=liTQ.begin();itq!=itqfin;itq++,idecal++) {TypeQuelconque& tipParticu = (*itq); // pour simplifier if (tipParticu.EnuTypeQuelconque().Nom_vide()) // veut dire que c'est un enum pur switch (tipParticu.EnuTypeQuelconque().EnumTQ()) { case NB_INVERSION: // a) ----- cas du nombre d'inversion actuelle { SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon); Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier tyTQ(1+(*idecal))=save_resul.sigma_barre_BH_R.size(); (*idecal)++; break; } case HYPER_CENTRE_HYSTERESIS: // b) ----- cas du centre du cercle actuelle de référence { SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon); Tab_Grandeur_TenseurBH& tyTQ= *((Tab_Grandeur_TenseurBH*) (*itq).Grandeur_pointee()); // pour simplifier if (save_resul.oc_BH_R.size() != 0) {tyTQ(1+(*idecal))= *(save_resul.oc_BH_R.begin());} else {tyTQ(1+(*idecal)).Inita(0.);} (*idecal)++; break; } case SIGMA_REF: // c) ----- cas de la contrainte de référence actuelle { SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon); Tab_Grandeur_TenseurBH& tyTQ= *((Tab_Grandeur_TenseurBH*) (*itq).Grandeur_pointee()); // pour simplifier if (save_resul.sigma_barre_BH_R.size() != 0) {tyTQ(1+(*idecal))= *(save_resul.sigma_barre_BH_R.begin());} else {tyTQ(1+(*idecal)).Inita(0.);}; (*idecal)++; break; } // d) ----- Q_sigma actuel de Oi à T case Q_SIG_HYST_Oi_A_R: { SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon); Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier Tenseur3BH delta__sigma_barre_BH_OiaR; // a priori le centre et la référence = 0: cas du début if (save_resul.sigma_barre_BH_R.size() != 0) delta__sigma_barre_BH_OiaR=(*(save_resul.sigma_barre_BH_R.begin())); if (save_resul.oc_BH_R.size() != 0) delta__sigma_barre_BH_OiaR -= *(save_resul.oc_BH_R.begin()); tyTQ(1+(*idecal)) = sqrt(delta__sigma_barre_BH_OiaR.II()); (*idecal)++; break; } // e) ----- Q_sigma actuel de R à T case Q_SIG_HYST_R_A_T: { SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon); Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier Tenseur3BH delta__sigma_barre_BH_Ratdt (save_resul.sigma_barre_BH_tdt); // a priori la ref = 0: cas du début if (save_resul.sigma_barre_BH_R.size() != 0) delta__sigma_barre_BH_Ratdt -= *(save_resul.sigma_barre_BH_R.begin()); tyTQ(1+(*idecal))=sqrt(delta__sigma_barre_BH_Ratdt.II()); (*idecal)++; break; } // f) ----- COS_ALPHA_HYSTERESIS actuel case COS_ALPHA_HYSTERESIS: { SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon); Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier // le plus simple est de recalculer double w__prime,w__prime_point; // grandeurs de retour bool trajet_neutre=false; Tenseur3BH delta__sigma_barre_BH_Ratdt (save_resul.sigma_barre_BH_tdt); // a priori la ref = 0: cas du début if (save_resul.sigma_barre_BH_R.size() != 0) delta__sigma_barre_BH_Ratdt -= *(save_resul.sigma_barre_BH_R.begin()); double Q__deltaSiRatdt = sqrt(delta__sigma_barre_BH_Ratdt.II()); Tenseur3BH delta__sigma_barre_BH_OiaR; // a priori le centre et la référence = 0: cas du début if (save_resul.sigma_barre_BH_R.size() != 0) delta__sigma_barre_BH_OiaR=(*(save_resul.sigma_barre_BH_R.begin())); if (save_resul.oc_BH_R.size() != 0) delta__sigma_barre_BH_OiaR -= *(save_resul.oc_BH_R.begin()); double Q__OiaR = sqrt(delta__sigma_barre_BH_OiaR.II()); Cal_wprime(Q__deltaSiRatdt,delta__sigma_barre_BH_Ratdt,Q__OiaR,delta__sigma_barre_BH_OiaR ,save_resul.wBase_tdt,ZeroBH3,w__prime,w__prime_point,trajet_neutre); tyTQ(1+(*idecal))=w__prime/save_resul.wBase_tdt; (*idecal)++; break; } // g) ----- cos_3phi actuel pour la contrainte totale d'hystérésis case COS3PHI_SIG_HYSTERESIS: { SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon); Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier double Qsig = sqrt(Dabs(save_resul.sigma_barre_BH_tdt.II())); double Qsig3 = Qsig * Qsig * Qsig; // if (Qsig > mini_Qsig_pour_phase_sigma_Oi_tdt ) { // on peut calculer un cos3phi pas débile double bIIIb = save_resul.sigma_barre_BH_tdt.III() / 3.; if (mini_Qsig_pour_phase_sigma_Oi_tdt > 0.) tyTQ(1+(*idecal)) = 3. * sqrt(6.) * bIIIb/ Qsig3; else tyTQ(1+(*idecal)) = 3. * sqrt(6.) * bIIIb/ (Qsig3-mini_Qsig_pour_phase_sigma_Oi_tdt); }; // else tyTQ=0.; // sinon on le met à 0 (*idecal)++; break; } // h) ----- cos_3phi actuel pour l'incrément de contrainte totale d'hystérésis case COS3PHI_DELTA_SIG_HYSTERESIS: { SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon); Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier Tenseur3BH delta__sigma_barre_BH_tatdt(save_resul.sigma_barre_BH_tdt-save_resul.sigma_barre_BH_t); double Qsig = sqrt(delta__sigma_barre_BH_tatdt.II()); double Qsig3 = Qsig * Qsig * Qsig; // if (Qsig > mini_Qsig_pour_phase_sigma_Oi_tdt ) { // on peut calculer un cos3phi pas débile double bIIIb = delta__sigma_barre_BH_tatdt.III() / 3.; if (mini_Qsig_pour_phase_sigma_Oi_tdt > 0.) tyTQ(1+(*idecal)) = 3. * sqrt(6.) * bIIIb/ Qsig3; else tyTQ(1+(*idecal)) = 3. * sqrt(6.) * bIIIb/ (Qsig3-mini_Qsig_pour_phase_sigma_Oi_tdt); } // else tyTQ=0.; // sinon on le met à 0 (*idecal)++; break; } // i) ----- Q_delta_sig d'hystérésis case Q_DELTA_SIG_HYST: { SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon); Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier Tenseur3BH delta__sigma_barre_BH_tatdt(save_resul.sigma_barre_BH_tdt-save_resul.sigma_barre_BH_t); tyTQ(1+(*idecal)) = sqrt(delta__sigma_barre_BH_tatdt.II()); (*idecal)++; break; } // ----- fonction d'aide case FCT_AIDE: { SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon); Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier tyTQ(1+(*idecal)) = save_resul.fonction_aide_tdt; (*idecal)++; break; } case NB_INCRE_TOTAL_RESIDU: { SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon); Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier if ((save_resul.indicateurs_resolution_t.Taille())) tyTQ(1+(*idecal)) = save_resul.indicateurs_resolution_t(1); else tyTQ(1+(*idecal)) = 0.; (*idecal)++; break; } case NB_ITER_TOTAL_RESIDU: { SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon); Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier if ((save_resul.indicateurs_resolution_t.Taille())) tyTQ(1+(*idecal)) = save_resul.indicateurs_resolution_t(2); else tyTQ(1+(*idecal)) = 0.; (*idecal)++; break; } case NB_APPEL_FCT: { SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon); Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier if ((save_resul.indicateurs_resolution_t.Taille())) tyTQ(1+(*idecal)) = save_resul.indicateurs_resolution_t(3); else tyTQ(1+(*idecal)) = 0.; (*idecal)++; break; } case NB_STEP: { SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon); Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier if ((save_resul.indicateurs_resolution_t.Taille())) tyTQ(1+(*idecal)) = save_resul.indicateurs_resolution_t(4); else tyTQ(1+(*idecal)) = 0.; (*idecal)++; break; } case ERREUR_RK: { SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon); Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier if ((save_resul.indicateurs_resolution_t.Taille())) tyTQ(1+(*idecal)) = save_resul.indicateurs_resolution_t(5); else tyTQ(1+(*idecal)) = 0.; (*idecal)++; break; } default: ;// on ne fait rien }; }; }; // récupération et création de la liste de tous les grandeurs particulières // ces grandeurs sont ajoutées à la liste passées en paramètres // absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière void Hysteresis3D::ListeGrandeurs_particulieres(bool absolue,List_io& liTQ) const {// ici on est en 3D et les grandeurs sont par principe en absolue, donc la variable absolue ne sert pas Tableau tab_1(1); Tab_Grandeur_scalaire_double grand_courant(tab_1); // def d'un type quelconque représentatif à chaque grandeur // a priori ces grandeurs sont défini aux points d'intégration identique à la contrainte par exemple // enu_ddl_type_pt est définit dans la loi Abtraite générale // on n'ajoute que si sortie_post est vraie, sinon aucune grandeur n'est sauvegardé, donc on ne peut // plus y accèder //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée // a) $$$ cas du nombre d'inversion actuelle {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == NB_INVERSION) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(NB_INVERSION,enu_ddl_type_pt,grand_courant); liTQ.push_back(typQ1); }; }; // b) $$$ cas du centre du cercle actuelle de référence {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == HYPER_CENTRE_HYSTERESIS) {Tab_Grandeur_TenseurBH& tyTQ= *((Tab_Grandeur_TenseurBH*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TenseurBH* tens = NevezTenseurBH(3); // un tenseur typique Tab_Grandeur_TenseurBH sigrefBH(*tens,1); // def d'un type quelconque représentatif TypeQuelconque typQ(HYPER_CENTRE_HYSTERESIS,SIG11,sigrefBH); liTQ.push_back(typQ); delete tens; // car on n'en a plus besoin }; }; // c) $$$ cas de la contrainte de référence actuelle {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == SIGMA_REF) {Tab_Grandeur_TenseurBH& tyTQ= *((Tab_Grandeur_TenseurBH*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TenseurBH* tens = NevezTenseurBH(3); // un tenseur typique Tab_Grandeur_TenseurBH sigrefBH(*tens,1); // def d'un type quelconque représentatif TypeQuelconque typQ(SIGMA_REF,SIG11,sigrefBH); liTQ.push_back(typQ); delete tens; // car on n'en a plus besoin }; }; // d) $$$ Q_sigma actuel de Oi à R {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == Q_SIG_HYST_Oi_A_R) {Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(Q_SIG_HYST_Oi_A_R,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; // e) $$$ Q_sigma actuel de R à T {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == Q_SIG_HYST_R_A_T) {Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(Q_SIG_HYST_R_A_T,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; // f) $$$ cos_alpha actuel {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == COS_ALPHA_HYSTERESIS) {Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(COS_ALPHA_HYSTERESIS,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; // g) ----- cos_3phi actuel pour la contrainte totale d'hystérésis {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == COS3PHI_SIG_HYSTERESIS) {Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(COS3PHI_SIG_HYSTERESIS,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; // h) ----- cos_3phi actuel pour l'incrément de contrainte totale d'hystérésis {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == COS3PHI_DELTA_SIG_HYSTERESIS) {Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(COS3PHI_DELTA_SIG_HYSTERESIS,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; // i) ----- Q_delta_sig d'hystérésis {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == Q_DELTA_SIG_HYST) {Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(Q_DELTA_SIG_HYST,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; // ----- fonction d'aide {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == FCT_AIDE) {Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(FCT_AIDE,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; // ---- la suite dépend de l'indicateur : sortie_post if (sortie_post) { // j) ----- NB_INCRE_TOTAL_RESIDU {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == NB_INCRE_TOTAL_RESIDU) {Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(NB_INCRE_TOTAL_RESIDU,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; // k) ----- NB_ITER_TOTAL_RESIDU {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == NB_ITER_TOTAL_RESIDU) {Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(NB_ITER_TOTAL_RESIDU,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; // l) ----- NB_APPEL_FCT {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == NB_APPEL_FCT) {Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(NB_APPEL_FCT,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; // m) ----- NB_STEP {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == NB_STEP) {Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(NB_STEP,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; // n) ----- ERREUR_RK {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == ERREUR_RK) {Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(ERREUR_RK,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; }; // fin du cas ou sortie_post est actif, c-a-d que l'on veut des infos sur les indicateurs // de résolution }; // ========== codage des METHODES VIRTUELLES protegees:================ //----- lecture écriture de restart ----- // cas donne le niveau de la récupération // = 1 : on récupère tout // = 2 : on récupère uniquement les données variables (supposées comme telles) void Hysteresis3D::Lecture_base_info_loi(ifstream& ent,const int cas,LesReferences& lesRef,LesCourbes1D& lesCourbes1D ,LesFonctions_nD& lesFonctionsnD) {if (cas == 1) { bool test;string nom; // param_prager_(np) ent >> nom >> test; if (!test) { ent >> xnp; if (xnp_temperature != NULL) {if (xnp_temperature->NomCourbe() == "_") delete xnp_temperature; xnp_temperature = NULL; }; } else { ent >> nom; xnp_temperature = lesCourbes1D.Lecture_pour_base_info(ent,cas,xnp_temperature); }; // limite_plasticite_(Q0) ent >> nom >> test; if (!test) { ent >> Qzero; if (Qzero_temperature != NULL) {if (Qzero_temperature->NomCourbe() == "_") delete Qzero_temperature; Qzero_temperature = NULL; }; } else { ent >> nom; Qzero_temperature = lesCourbes1D.Lecture_pour_base_info(ent,cas,Qzero_temperature); }; // param_lame_(mu) ent >> nom >> test; if (!test) { ent >> xmu; if (xmu_temperature != NULL) {if (xmu_temperature->NomCourbe() == "_") delete xmu_temperature; xmu_temperature = NULL; }; } else { ent >> nom; xmu_temperature = lesCourbes1D.Lecture_pour_base_info(ent,cas,xmu_temperature); }; // --- dépendance à la phase éventuelle ent >> nom; if (nom == "avec_phaseDeltaSig") {avec_phaseDeltaSig = true; avec_phaseEps = false; } else if (nom == "avec_phaseEps") {avec_phaseDeltaSig = false; avec_phaseEps = true; } else {avec_phaseDeltaSig = false; avec_phaseEps = false; }; if (avec_phaseDeltaSig || avec_phaseEps) {// param_prager_(np) ent >> nom >> test; if (!test) { if (xnp_phase != NULL) {if (xnp_phase->NomCourbe() == "_") delete xnp_phase; xnp_phase = NULL; }; } else { ent >> nom; xnp_phase = lesCourbes1D.Lecture_pour_base_info(ent,cas,xnp_phase); }; // xmu ent >> nom >> test; if (!test) { if (xmu_phase != NULL) {if (xmu_phase->NomCourbe() == "_") delete xmu_phase; xmu_phase = NULL; }; } else { ent >> nom; xmu_phase = lesCourbes1D.Lecture_pour_base_info(ent,cas,xmu_phase); }; // Qzero ent >> nom >> test; if (!test) { if (Qzero_phase != NULL) {if (Qzero_phase->NomCourbe() == "_") delete Qzero_phase; Qzero_phase = NULL; }; } else { ent >> nom; Qzero_phase = lesCourbes1D.Lecture_pour_base_info(ent,cas,Qzero_phase); }; }; // --- dépendance à la def Equi éventuelle ent >> nom; if (nom == "avec_defEqui") { // param_prager_(np) ent >> test >> nom; if ((!test) && (nom == "pas_de_fct_xnp_defEqui_")) { // pas de dépendance de xn à la defEqui if (xnp_defEqui != NULL) {if (xnp_defEqui->NomCourbe() == "_") delete xnp_defEqui; xnp_defEqui = NULL; }; } else if (test) { ent >> nom; if (nom == "fonction_xnp_defEqui") {xnp_defEqui = lesCourbes1D.Lecture_pour_base_info(ent,cas,xnp_defEqui);}; } else { cout << "\n erreur en lecture de xnp_defEqui, on attendait de lire la chaine: pas_de_fct_xnp_defEqui_ et on a lue " << nom << endl; Sortie(1); }; // dépendance de Qzero ent >> test >> nom; if ((!test) && (nom == "pas_de_fct_Qzero_defEqui_")) { // pas de dépendance de Qzero à la defEqui if (Qzero_defEqui != NULL) {if (Qzero_defEqui->NomCourbe() == "_") delete Qzero_defEqui; Qzero_defEqui = NULL; }; } else if (test) { ent >> nom; if (nom == "fonction_Qzero_defEqui") {Qzero_defEqui = lesCourbes1D.Lecture_pour_base_info(ent,cas,Qzero_defEqui);}; } else { cout << "\n erreur en lecture de Qzero_defEqui, on attendait de lire la chaine: pas_de_fct_Qzero_defEqui_ et on a lue " << nom << endl; Sortie(1); }; }; // --- dépendance à la phase de la déformation totale ent >> nom; if (nom == "avec_phase_paradefEqui") {ent >> nom >> test; // coef_paradefEqui if (!test) { if (coef_paradefEqui != NULL) {if (coef_paradefEqui->NomCourbe() == "_") delete coef_paradefEqui; coef_paradefEqui = NULL; }; } else { ent >> nom; coef_paradefEqui = lesCourbes1D.Lecture_pour_base_info(ent,cas,coef_paradefEqui); }; }; // les paramètres de réglage de l'algorithme ent >> nom >> tolerance_residu >> nom >> tolerance_residu_rel >> nom >> nb_boucle_maxi >> nom >> maxi_delta_var_sig_sur_iter_pour_Newton >> nom >> nb_dichotomie >> nom >> mini_rayon >> nom >> tolerance_coincidence >> nom >> tolerance_centre; ent >> nom >> type_resolution_equa_constitutive >> nom >> type_calcul_comportement_tangent >> nom >> avecVarWprimeS >> nom >> cas_kutta >> nom >> erreurAbsolue >> nom >> erreurRelative; ent >> nom >> nb_maxInvCoinSurUnPas >> nom >> min_angle_trajet_neutre >> nom >> possibilite_cosAlphaNegatif >> nom >> mini_Qsig_pour_phase_sigma_Oi_tdt >> nom >> mini_QepsilonBH >> nom >> force_phi_zero_si_negatif >> nom >> depassement_Q0 >> nom >> type_de_transport_memorisation >> nom >> niveau_bascule_fct_aide; // le niveau d'affichage Lecture_permet_affichage(ent,cas,lesFonctionsnD); ent >> nom >> sortie_post; }; // appel de la classe mère Loi_comp_abstraite::Lecture_don_base_info(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD); }; // cas donne le niveau de sauvegarde // = 1 : on sauvegarde tout // = 2 : on sauvegarde uniquement les données variables (supposées comme telles) void Hysteresis3D::Ecriture_base_info_loi(ofstream& sort,const int cas) { if (cas == 1) { sort << " HYSTERESIS_3D "; sort << " param_prager_(np) "; if (xnp_temperature == NULL) { sort << false << " " << xnp_lue << " ";} else { sort << true << " fonction_xnp_temperature "; LesCourbes1D::Ecriture_pour_base_info(sort,cas,xnp_temperature); }; sort << " limite_plasticite_(Q0) "; if (Qzero_temperature == NULL) { sort << false << " " << Qzero_lue << " ";} else { sort << true << " fonction_Qzero_temperature "; LesCourbes1D::Ecriture_pour_base_info(sort,cas,Qzero_temperature); }; sort << " param_lame_(mu) "; if (xmu_temperature == NULL) { sort << false << " " << xmu_lue << " ";} else { sort << true << " fonction_xmu_temperature "; LesCourbes1D::Ecriture_pour_base_info(sort,cas,xmu_temperature); }; // --- dépendance à la phase éventuelle if (avec_phaseDeltaSig || avec_phaseEps) {if (avec_phaseDeltaSig == 1) {sort << " avec_phaseDeltaSig ";} else {sort << " avec_phaseEps ";}; if (xnp_phase == NULL) { sort << false << " " ;} else { sort << true << " fonction_xnp_phase "; LesCourbes1D::Ecriture_pour_base_info(sort,cas,xnp_phase); }; if (xmu_phase == NULL) { sort << false << " " ;} else { sort << true << " fonction_xmu_phase "; LesCourbes1D::Ecriture_pour_base_info(sort,cas,xmu_phase); }; if (Qzero_phase == NULL) { sort << false << " " ;} else { sort << true << " fonction_Qzero_phase "; LesCourbes1D::Ecriture_pour_base_info(sort,cas,Qzero_phase); }; } else {sort << " sans_phase ";}; // --- dépendance à la def Equi éventuelle if (avec_defEqui) {sort << " avec_defEqui "; if (xnp_defEqui == NULL) { sort << false << " pas_de_fct_xnp_defEqui_ " ;} else { sort << true << " fonction_xnp_defEqui "; LesCourbes1D::Ecriture_pour_base_info(sort,cas,xnp_defEqui); }; if (Qzero_defEqui == NULL) { sort << false << " pas_de_fct_Qzero_defEqui_ " ;} else { sort << true << " fonction_Qzero_defEqui "; LesCourbes1D::Ecriture_pour_base_info(sort,cas,Qzero_defEqui); }; } else {sort << " sans_defEqui ";}; // --- dépendance à la phase de la déformation totale pour paradefEqui if (avec_phase_paradefEqui) {sort << " avec_phase_paradefEqui "; if (coef_paradefEqui == NULL) { sort << false << " " ;} else { sort << true << " fonction_coef_paradefEqui "; LesCourbes1D::Ecriture_pour_base_info(sort,cas,coef_paradefEqui); }; } else {sort << " sans_phaseEps ";}; // --- paramètre de réglage sort << "\n tolerance_algo_newton_equadiff:_absolue= " << tolerance_residu << " relative= "<< tolerance_residu_rel << " nb_boucle_maxi " << nb_boucle_maxi << " maxi_delta_var_sig_sur_iter_pour_Newton " << maxi_delta_var_sig_sur_iter_pour_Newton << " nb_dichotomie " << nb_dichotomie << " tolerance_coincidence " << tolerance_coincidence << " tolerance_centre " << tolerance_centre << " mini_rayon " << mini_rayon; sort << "\n type_resolution_equa_constitutive " << type_resolution_equa_constitutive << " type_calcul_comportement_tangent " << type_calcul_comportement_tangent << " avecVarWprimeS " << avecVarWprimeS << " cas_kutta " << cas_kutta << " erreurAbsolue " << erreurAbsolue << " erreurRelative " << erreurRelative << " "; sort << " nb_maxInvCoinSurUnPas " << nb_maxInvCoinSurUnPas << " min_angle_trajet_neutre " << min_angle_trajet_neutre << " possibilite_cosAlphaNegatif " << possibilite_cosAlphaNegatif << " mini_Qsig_pour_phase_sigma_Oi_tdt " << mini_Qsig_pour_phase_sigma_Oi_tdt << " mini_QepsilonBH " << mini_QepsilonBH << " force_phi_zero_si_negatif " << force_phi_zero_si_negatif << " depassement_Q0 " << depassement_Q0 << " type_de_transport_memorisation "<< type_de_transport_memorisation << " niveau_bascule_fct_aide "<< niveau_bascule_fct_aide; // niveau d'affichage Affiche_niveau_affichage(sort,cas); sort << " sortie_post " << sortie_post << " "; }; // appel de la classe mère Loi_comp_abstraite::Ecriture_don_base_info(sort,cas); }; // =============== fonction protegee ============ // --------------- méthodes internes ---------------: // 1) affinage d'un point de coincidence à l'aide des rayons // ramène true si le traitement est exactement terminé, sinon false, ce qui signifie qu'il // faut encore continuer à utiliser l'équation d'évolution // pt_sur_principal : indique si oui ou non le pointeur iatens pointe sur sa liste principale // oi_sur_principal : indique si oui ou non le pointeur iaOi pointe sur sa liste principale // iatens_princ et iaOi_princ: pointeurs sur les listes principales // force_coincidence : on force la coincidence à la position actuelle // le rayon peut-être modifié dans le cas particulier d'une coincidence à la précision près bool Hysteresis3D::Coincidence(bool bascule_fct_aide,double& unSur_wBaseCarre ,const Tenseur3HH & gijHH,const Tenseur3BB & gijBB ,SaveResulHysteresis3D & save_resul,double& W_a ,List_io ::iterator& iatens ,List_io ::iterator& iadef_equi ,List_io ::iterator& iafct ,bool& pt_sur_principal ,List_io ::iterator& iaOi,bool& oi_sur_principal ,List_io ::iterator& iatens_princ ,List_io ::iterator& iadef_equi_princ ,List_io ::iterator& iaOi_princ ,List_io ::iterator& iafct_princ ,const double& rayon_tdt,bool force_coincidence) { // tout d'abord on vérifie que l'on n'est pas exactement à un point de // coincidence à la précision près // -- modif 10 juillet 2014: // on calcul la grandeur cc qui est un des coef de l'équation du second degré permettant // de trouver la coïncidence (voir après) Tenseur3BH delta_sigma_oi_a_t_BH = sigma_i_barre_BH - oc_BH_R; // OB double cc = (delta_sigma_oi_a_t_BH && delta_sigma_oi_a_t_BH) - Q_OiaR * Q_OiaR; // cc=OB*OB - r^2 // si cc est positif, cela signifie qu'au pas précédent on n'a pas bien détecté une coincidence // ou que c'est un pb de zero // on considère alors que le point actuel est un point de coïncidence à la précision près et donc // on finit le traitement double tol_coincidence_reelle = tolerance_coincidence; if (tolerance_coincidence < 0) // si l'indication est négative , cela veut dire que l'on veut une grandeur relative tol_coincidence_reelle = MaX(-tolerance_coincidence * Q_OiaR,-tolerance_coincidence); // -- fin modif if ((Abs(rayon_tdt - Q_OiaR) <= tol_coincidence_reelle) || force_coincidence // || ((cc >= 0.) && (sqrt(Dabs(cc)) <= tol_coincidence_reelle)) ) // -- ajout 10 juillet 2014: || (cc >= 0.) ) // -- ajout 11 juillet 2014: on ne peut plus revenir sur les grandeurs à t // donc le mieux est de valider la coïncidence ce qui simplifiera la suite du traitement { // on est dans le cas où l'on a une coïncidence exacte à la précision "tolerance_coincidence" près // mais dans tous les cas on a rayon_tdt > Q_OiaR sinon on n'aurait pas de coïncidence // on signale qu'il y a une coincidence exacte (pour le retour de la méthode Coincidence) // gestion des pointeurs do {Gestion_pointeur_coincidence(unSur_wBaseCarre,save_resul,W_a ,iatens,iadef_equi,iafct,pt_sur_principal,iaOi,oi_sur_principal ,iatens_princ,iadef_equi_princ,iaOi_princ,iafct_princ); }// on traite le cas où des autres coincidences existent à la précision près while (Autre_coincidence_a_la_tolerance_pres(bascule_fct_aide,gijHH,gijBB ,pt_sur_principal,oi_sur_principal,iatens,iaOi)); return true; }; // --- sinon on continue mais le traitement ne sera pas fini !! // dans une première étape on tente de calculer plus précisemment le point d'inversion, // en supposant une approximation linéaire de l'évolution de sigma sur le pas de temps: bool bon_calcul = false; // permet de savoir si le calcul précis est correcte, // pour l'instant on dit que non au niveau de l'init // a-- calcul des coefficients de l'équation du second degré qui gère le point exact double aa = delta_sigma_barre_tdt_BH && delta_sigma_barre_tdt_BH; // BA*BA // aa doit être sup à 0, si ce n'est pas le cas du à des arrondis ou des pb de transport on le met à 0 if (aa < ConstMath::pasmalpetit) { aa = 0.; if (Permet_affichage() > 0) cout << "\n warning algo coincidence, dans la recherche des racines de l'equa 2 degre " << " on a sig_tdt : sig_tdt qui est negatif !! = " << aa <<" on le met a 0 mais ce n'est pas normal " << "\n Hysteresis3D::Coincidence(... "; }; // delta_sigma_oi_a_tdt_BH c'est OA double bb = 2. * (delta_sigma_oi_a_t_BH && delta_sigma_barre_tdt_BH); // OB*BA // bb *= 2. * bb; // 2 (OB*BA)^2 // double cc = (delta_sigma_oi_a_t_BH && delta_sigma_oi_a_t_BH) - Q_OiaR * Q_OiaR; // OB*OB - r^2 // #ifdef MISE_AU_POINT //**** le test qui suit ne sert plus compte tenu du choix fait plus haut sur cc // if(!aucun_pt_inversion) // if (cc > 0.) // signifie qu'au pas précédent on n'a pas bien détecté une coincidence // // ou que c'est un pb de zero // { // les 4 lignes qui suivent n'ont plus lieu d'être : -- modif 10 juillet 2014 //// if (Dabs(cc) <= tolerance_coincidence) //// { cc = 0.; //// } //// else // { if ( ((Permet_affichage()==0) && (ParaGlob::NiveauImpression() > 0)) || (Permet_affichage() > 0)) // cout << "\n erreur algo coincidence : 1 : cc positif ! " // << "\n Hysteresis3D::Coincidence(... " << endl; // if ( ((Permet_affichage()==0) && (ParaGlob::NiveauImpression() > 2)) || (Permet_affichage() > 2)) // { cout << "\n aa= " << aa << " bb= " << bb << " cc= " << cc;}; // if ( ((Permet_affichage()==0) && (ParaGlob::NiveauImpression() > 4)) || (Permet_affichage() > 4)) // { Affiche_debug(unSur_wBaseCarre,save_resul,iatens,iadef_equi,pt_sur_principal // ,iaOi,oi_sur_principal,iatens_princ,iadef_equi_princ,iaOi_princ); // }; // // on génère une exception // throw ErrNonConvergence_loiDeComportement(); //// Sortie(1); // }; // }; // //**** // #endif // b-- recherche de racine double racine1,racine2; int cas; alg_zero.SecondDegre(aa,bb,cc,racine1,racine2,cas); // --- traitement suivant les différents cas de la résolution de l'équation du second degré --- switch (cas) { case 1: // deux racines distinctes { // normalement les deux racines sont de signe opposé, seule la positive <=1 est recevable if (racine1*racine2 <=0.) {// on regarde si racine2 <= 1 ce qui est le cas normal if (racine2 <= 1.) // racine2 est la plus grande donc positive // cas normal, on valide la procédure { bon_calcul = true;} #ifdef MISE_AU_POINT else // sinon cela signifie que la méthode n'est pas bonne { if (Permet_affichage() > 0) cout << "\n warning algo coincidence, dans la recherche des racines de l'equa 2 degre " << " la seconde racine " << racine2 <<" est superieur a 1" << "\n Hysteresis3D::Coincidence(... "; } #endif } else { #ifdef MISE_AU_POINT // normalement aa >=0 donc avec cc <0 on ne doit pas avoir 2 racines du même signe if(!aucun_pt_inversion) // sauf dans le cas de la première charge { if (Permet_affichage() > 0) cout << "\n erreur algo coincidence, dans la recherche des racines de l'equa 2 degre " << " les deux racines sont du meme signe ??, a= " <0.) && (la_plus_grande<1.)) { racine2=la_plus_grande; bon_calcul = true;} else // sinon on test l'autre { double la_plus_petite = MiN(racine1,racine2); if ((la_plus_petite>0.) && (la_plus_petite<1.)) { racine2=la_plus_petite; bon_calcul = true;} // sinon rien tous les autres cas sont mauvais }; }; break; } case 2: // deux racines identiques { // normalement la racine doit être comprise entre 0 et 1, sinon non recevable if ((racine2>=0.) && (racine2 <= 1.)) // cas normal, on valide la procédure { bon_calcul = true;}; // tous les autres cas sont mauvais break; } case -3: // une racine simple { // normalement la racine doit être comprise entre 0 et 1, sinon non recevable if ((racine1>=0.) && (racine1 <= 1.)) // cas normal, on valide la procédure { bon_calcul = true; racine2=racine1; // pour la suite }; // tous les autres cas sont mauvais break; } // tous les autres cas sont mauvais donc la variable bon_calcul sera fausse // et on utilisera une autre procedure de calcul par la suite }; //-- fin du switch // --- fin du traitement suivant les différents cas de la résolution de l'équation du second degré --- if (!bon_calcul) // cas où la recherche fine avec la résolution de l'équat du second degré n'a pas marché { // on utilise une interpolation plus grossière à l'aide de la fonction de charge if (Permet_affichage() > 4) cout << "\n (algo hysteresis) on passe par l'interpolation lineaire de l'equation du second degre"; double delta_r2 = rayon_tdt - Q_OiaR; double delta_r1 = Q_OiaR - sqrt(delta_sigma_oi_a_t_BH.II()); racine2 = delta_r1 / (delta_r1 + delta_r2); // normalement racine2 est compris entre 0 et 1 if ( (racine2 < 0.) || (racine2 > 1.)) { if (Permet_affichage() > 0) cout << "\n erreur algo coincidence, dans la recherche de racine2 simplifiee" << "\n racine2= " << racine2 << " delta_r2= " << delta_r2 << " delta_r1= " << delta_r1 << " Q_OiaR= " << Q_OiaR << " -> divergence ! " << "\n Hysteresis3D::Coincidence(... " << endl; // on génère une exception throw ErrNonConvergence_loiDeComportement(); }; }; // c-- maintenant on traite les infos // comme racine2 appartient à [0,1], que OiR > Oisigma_t et que OiR < Oisigma_tdt, normalement on doit avoir // Oisigma_tdt > Oisigma_coinci // -- cas où à l'issue du calcul racines est très proche de 1 --- // dans ce cas on considère que la coïncidence est exacte if (sqrt(((1.-racine2)*delta_sigma_barre_tdt_BH).II()) <= tol_coincidence_reelle) { // on est dans le cas où l'on a une coïncidence exacte à la précision "tolerance_coincidence" près // mais dans tous les cas on a rayon_tdt > Q_OiaR sinon on n'aurait pas de coïncidence // on signale qu'il y a une coincidence exacte (pour le retour de la méthode Coincidence) // gestion des pointeurs do {Gestion_pointeur_coincidence(unSur_wBaseCarre,save_resul,W_a ,iatens,iadef_equi,iafct,pt_sur_principal,iaOi,oi_sur_principal ,iatens_princ,iadef_equi_princ,iaOi_princ,iafct_princ); }// on traite le cas où des autres coincidences existent à la précision près while (Autre_coincidence_a_la_tolerance_pres(bascule_fct_aide,gijHH,gijBB ,pt_sur_principal,oi_sur_principal,iatens,iaOi)); return true; }; // calcul de la valeur de sigma au point de coincidence, qui servira pour un nouveau calcul sigma_i_barre_BH += racine2 * delta_sigma_barre_tdt_BH; // donc à partir d'ici on considère que l'on va valider la coïncidence, il faut donc que // la contrainte au point de conïncidence corresponde "exactement" à celle correspondante au critère de // coïncidence, on va donc vérifier que "racine2" est correcte double nouveau_rayon_tdt = sqrt((sigma_i_barre_BH - oc_BH_R).II()); // Q_OiaR if ((Abs(nouveau_rayon_tdt - Q_OiaR) > tol_coincidence_reelle) ) if (Permet_affichage() > 4) { cout << "\n erreur2 algo coincidence, dans la recherche de racine2 " << "\n racine2= " << racine2 << " nouveau_rayon_tdt= " << nouveau_rayon_tdt << " Q_OiaR= " << Q_OiaR << " -> divergence ! " << "\n Hysteresis3D::Coincidence(... " << endl; // on génère une exception throw ErrNonConvergence_loiDeComportement(); }; // calcul du reste d'incrément de déformation qu'il faut utiliser pour la suite delta_barre_epsBH *= (1.-racine2); // (1.-racine2) est >= 0 // mise à jour des différents pointeurs Gestion_pointeur_coincidence(unSur_wBaseCarre,save_resul,W_a ,iatens,iadef_equi,iafct,pt_sur_principal,iaOi,oi_sur_principal ,iatens_princ,iadef_equi_princ,iaOi_princ,iafct_princ); // fin et retour, comme le calcul n'est pas fini on retourne false return false; }; // traitement des cas où des autres coincidences existent à la précision près // ramène true si effectivement il y a une nouvelle coincidence bool Hysteresis3D::Autre_coincidence_a_la_tolerance_pres(bool bascule_fct_aide ,const Tenseur3HH & gijHH,const Tenseur3BB & gijBB ,const bool& pt_sur_principal,const bool& oi_sur_principal ,List_io ::iterator& iatens ,List_io ::iterator& iaOi) { // choix entre gestion avec rayons ou avec fonction d'aide if (!bascule_fct_aide) {// on va calculer le nouveau rayon et voir s'il y a de nouveau coincidence ou pas // -- 1) sigma_barre_BH_R : initialisé sur la liste principal, mais ensuite peut évoluer sur liste secondaire if (aucun_pt_inversion) {sigma_barre_BH_R.Inita(0.);def_equi_R=0.;} else {sigma_barre_BH_R = *iatens; // la contrainte de référence }; delta_sigma_barre_BH_Rat = sigma_i_barre_BH - sigma_barre_BH_R; // -- 2) centre et rayon de la première surface de coïncidence if (centre_initial) {oc_BH_R.Inita(0.);} else {oc_BH_R = *iaOi;}; delta_sigma_barre_BH_OiaR = sigma_barre_BH_R-oc_BH_R; // le tenseur rayon // -- 3) calcul du rayon: la première fois le rayon est infini if (aucun_pt_inversion) {Q_OiaR = ConstMath::tresgrand;} else {Q_OiaR = sqrt(delta_sigma_barre_BH_OiaR.II());}; // calcul du rayon actuelle, avec le nouveau centre éventuelle Tenseur3BH delta_sigma_oi_a_tdt_BH = sigma_t_barre_tdt - oc_BH_R; // OA double nouveau_rayon_tdt = sqrt(delta_sigma_oi_a_tdt_BH.II()); // on test bool retour; if (nouveau_rayon_tdt < Q_OiaR) {retour = false;} // cas normal else {retour = true; }; // cas où il y a une nouvelle coincidence // une nouvelle coincidence est possible si l'ancien rayon de référence et le nouveau ont une // différence inférieure à la précision de la coincidence !! //--------débug- traçage #ifdef MISE_AU_POINT if ((Permet_affichage() == -77)&&retour) { cout << "\n nouvelle coïncidence: cas de points tres rapprochees " << endl ; }; #endif //----- fin débug return retour; } else // cas d'une gestion avec la fonction d'aide {// pour l'instant on ne fait rien, s'il y a plusieurs coïncidence à suivre // on passera plusieurs fois dans l'algo coïncidence return false; }; }; // 2) affinage d'un point de coincidence à l'aide de la fonction d'aide // ramène true si le traitement est exactement terminé, sinon false, ce qui signifie qu'il // faut encore continuer à utiliser l'équation d'évolution // premiere_charge : indique si c'est oui ou non une coincidence avec la première charge // pt_sur_principal : indique si oui ou non les pointeurs iafct et iatens pointent sur les listes // principales // iatens_princ et iafct_princ: pointeurs sur les listes principales bool Hysteresis3D::Coincidence(bool bascule_fct_aide,double& unSur_wBaseCarre ,const Tenseur3HH & gijHH,const Tenseur3BB & gijBB ,SaveResulHysteresis3D & save_resul,double& W_a ,List_io ::iterator& iatens ,List_io ::iterator& iadef_equi ,List_io ::iterator& iafct ,bool& pt_sur_principal ,List_io ::iterator& iaOi,bool& oi_sur_principal ,List_io ::iterator& iatens_princ ,List_io ::iterator& iadef_equi_princ ,double& position_coincidence ,List_io ::iterator& iaOi_princ ,List_io ::iterator& iafct_princ ,double& delta_W_a,bool force_coincidence) { // tout d'abord on vérifie que l'on n'est pas exactement à un point de // coincidence à la précision près double c = (W_a - delta_W_a) - *iafct; bool coin_exacte = false; // drapeau indiquant si l'on a une coincidence exacte ou pas // calcul de la précision double tol_coincidence_reelle = tolerance_coincidence; if (tolerance_coincidence < 0) // si l'indication est négative , cela veut dire que l'on veut une grandeur négative tol_coincidence_reelle = MaX(-tolerance_coincidence * W_a,-tolerance_coincidence); if ((Abs(W_a - *iafct) <= tol_coincidence_reelle) || force_coincidence || (c >= 0.) ) // on ne peut plus revenir sur les grandeurs à t // donc le mieux est de valider la coïncidence ce qui simplifiera la suite du traitement { // on est dans le cas où l'on a une coïncidence exacte à la précision "tolerance_coincidence" près // mais dans tous les cas on a rayon_tdt > Q_OiaR sinon on n'aurait pas de coïncidence // on signale qu'il y a une coincidence exacte (pour le retour de la méthode Coincidence) // gestion des pointeurs do { // on prend pour W_a la valeur au moment de la coïncidence ce qui permet d'éviter des approximations futures W_a = *iafct; Gestion_pointeur_coincidence(unSur_wBaseCarre,save_resul,W_a ,iatens,iadef_equi,iafct,pt_sur_principal,iaOi,oi_sur_principal ,iatens_princ,iadef_equi_princ,iaOi_princ,iafct_princ); }// on traite le cas où des autres coincidences existent à la précision près while (Autre_coincidence_a_la_tolerance_pres(bascule_fct_aide,gijHH,gijBB,pt_sur_principal ,oi_sur_principal,iatens,iaOi)); coin_exacte = true;position_coincidence=1.; return coin_exacte; }; // --- sinon on continue // recherche de racine double racine2; // // c doit-être négatif, à la limite nul // if (c >= 0.) // {// on détermine la proportion de déformation qu'il faut faire pour être exactement à la coïncidence // double W_t=W_a - delta_W_a; // racine2 = (W_a - *iafct) / delta_W_a; // } // else { // on utilise une interpolation assez grossière à l'aide de la fonction de charge // cout << "\n on passe par l'interpolation de la fonction d'aide"; double W_t=W_a - delta_W_a; racine2 = (*iafct - W_t) / delta_W_a; #ifdef MISE_AU_POINT // normalement racine2 est compris entre 0 et 1 if ( (racine2 < 0.) || (racine2 > 1.)) { cout << "\n erreur algo coincidence, dans la recherche de racine2 a l'aide de la fonction de charge " << " W_ref= " <<*iafct<<" W_t= " << W_t << " delta_W_a= " << delta_W_a << "\n Hysteresis1D::Coincidence(... "; Sortie(1); } #endif } // -- maintenant on traite les infos // comme racine2 appartient à [0,1], que OiR > Oisigma_t et que OiR < Oisigma_tdt, normalement on doit avoir // Oisigma_tdt > Oisigma_coinci // -- cas où à l'issue du calcul racines est très proche de 1 --- // dans ce cas on considère que la coïncidence est exacte if (sqrt(((1.-racine2)*delta_sigma_barre_tdt_BH).II()) <= tol_coincidence_reelle) { // on est dans le cas où l'on a une coïncidence exacte à la précision "tolerance_coincidence" près // mais dans tous les cas on a rayon_tdt > Q_OiaR sinon on n'aurait pas de coïncidence // on signale qu'il y a une coincidence exacte (pour le retour de la méthode Coincidence) // gestion des pointeurs do {// on prend pour W_a la valeur au moment de la coïncidence ce qui permet d'éviter des approximations futures W_a = *iafct; Gestion_pointeur_coincidence(unSur_wBaseCarre,save_resul,W_a ,iatens,iadef_equi,iafct,pt_sur_principal,iaOi,oi_sur_principal ,iatens_princ,iadef_equi_princ,iaOi_princ,iafct_princ); }// on traite le cas où des autres coincidences existent à la précision près while (Autre_coincidence_a_la_tolerance_pres(bascule_fct_aide,gijHH,gijBB ,pt_sur_principal,oi_sur_principal,iatens,iaOi)); coin_exacte = true;position_coincidence=1.; return coin_exacte; }; // -- sinon cela veut dire que la coïncidence n'est pas précise, au lieu de chercher à calculer // le tenseur sigma à l'aide d'une péréquation, on ne valide pas la coïncidence, par contre // on ramène la valeur de la proportion racine2 indiquant la position approximative de l'inversion exacte // // calcul de la valeur de sigma au point de coincidence, qui servira pour un nouveau calcul // sigma_i_barre_BH += racine2 * delta_sigma_barre_tdt_BH; // // // calcul du reste d'incrément de déformation qu'il faut utiliser pour la suite // delta_barre_epsBH *= (1.-racine2); // (1.-racine2) est >= 0 // // mise à jour des différents pointeurs // Gestion_pointeur_coincidence(unSur_wBaseCarre,save_resul // ,iatens,iadef_equi,iafct,pt_sur_principal,iaOi,oi_sur_principal // ,iatens_princ,iadef_equi_princ,iaOi_princ,iafct_princ); // // // fin et retour, comme le calcul n'est pas fini on retourne false coin_exacte = false;position_coincidence=racine2; return coin_exacte; }; // calcul de wprime en fonction de grandeurs supposées déjà calculées // --- méthode indépendante ----- // utilise : Q_OiaR, QdeltaSigmaRatdt, // delta_sigma_barre_BH_Ratdt, delta_sigma_barre_BH_OiaR // wBase // trajet_neutre: indique si oui ou non, on est dans un chargement neutre à la précision près void Hysteresis3D::Cal_wprime(const double& Q__deltaSiRatdt,const Tenseur3BH& delta__sig_barre_BH_Ratdt ,const double& Q__OiaR,const Tenseur3BH& delta__sig_barre_BH_OiaR ,const double& w__Base,Tenseur3BH& delta__sig_barre_BH_tatdt , double& w__prime, double& w__prime_point,bool& trajet_neut) const { // -- calculs relatifs aux angles de phases // ces calculs ne sont nécessaires que si l'on n'est pas sur une première charge if (w__Base!=1) {// si l'intensité du rayon est nulle, celui de seconde charge doit // être également nulle, on considére un alpha nulle donc un cos = 1 d'où w__prime = 2. if (Q__OiaR >= mini_rayon) // si mini_rayon est négatif (=> régularisation), l'expression est tjs vrai {// si l'intensité de l'accroissement du déviateur de contrainte est nulle, // on considére un alpha nulle donc un cos = 1 d'où w__prime = 2. if (Q__deltaSiRatdt >= mini_rayon) // idem test si dessus pour le cas où mini_rayon est négatif {// cas où on peut calculer l'angle // -- calcul de w__prime double unSurQ__OiaR ; //= 1./Q__OiaR; double unSurQ__deltaSiRatdt ;//= 1./Q__deltaSiRatdt; if (mini_rayon > 0.) // cas historique { unSurQ__OiaR = 1./Q__OiaR; unSurQ__deltaSiRatdt = 1./Q__deltaSiRatdt; } else // cas avec régularisation { unSurQ__OiaR = 1./(Q__OiaR-mini_rayon); unSurQ__deltaSiRatdt = 1./(Q__deltaSiRatdt-mini_rayon); }; double cos_alpha = - (delta__sig_barre_BH_Ratdt && delta__sig_barre_BH_OiaR) * unSurQ__OiaR * unSurQ__deltaSiRatdt; // if (Dabs(cos_alpha)<= ConstMath::pasmalpetit) if (Dabs(cos_alpha)<= min_angle_trajet_neutre) { // dans ce cas il s'agit d'un trajet neutre // le cos_alpha, sa dérivée, les w_prime et w_prime_point n'auront pas au final d'importance trajet_neut=true; w__prime=0.; w__prime_point=0.; } else if ((cos_alpha <= - min_angle_trajet_neutre) && (!possibilite_cosAlphaNegatif)) { // cas ou cos_alpha est négatif et que l'on veut traiter ce cas comme un cas neutre // le cos_alpha, sa dérivée, les w_prime et w_prime_point n'auront pas au final d'importance trajet_neut=true; w__prime=0.; w__prime_point=0.; } else { // chargement non neutre trajet_neut = false; w__prime = w__Base * cos_alpha; if ((w__prime <= 0) && (possibilite_cosAlphaNegatif)) { // dans le cas où cos_alpha est négatif et que l'on admet "transitoirement" que le cos_alpha puisse // être négatif, on lui change de signe (cf. les anciens commentaires qui suivent) // C1- il y a problème car cela signifie que cos_alpha est négatif donc que les cercles s'accroissent // C1- ceci peut être du à une erreur d'arrondi // C1- on considère alors que l'on est au cas limite de cos_alpha = 0` // C2-- non en fait ça peut-être tout-à-fait normale, juste avant une inversion on a un angle négatif et c'est normale // C2-- pour éviter d'avoir des pb le plus simple est de considérer la partie positive de l'angle // -- if (MaX(ParaGlob::NiveauImpression(),Permet_affichage()) >= 3) // -- cout << "\n attention, angle de phase negatif en hysteresis ! ,"; // << " on le met a 0"; // if (MaX(ParaGlob::NiveauImpression(),Permet_affichage()) >= 4) // cout << " Q__deltaSiRatdt= " << Q__deltaSiRatdt << " w__prime= " << w__prime; // w__prime = 2.;w__prime_point=0.; w__prime = - w__prime; double Rsig_point_scalaire_Rsig = delta__sig_barre_BH_tatdt && delta__sig_barre_BH_Ratdt; double ee = Rsig_point_scalaire_Rsig * unSurQ__deltaSiRatdt * unSurQ__deltaSiRatdt; double cos_alpha_point = - unSurQ__OiaR * unSurQ__deltaSiRatdt * (delta__sig_barre_BH_OiaR && (delta__sig_barre_BH_tatdt - ee * delta__sig_barre_BH_Ratdt )) ; w__prime_point = - w__Base * cos_alpha_point; } else {// -- calcul de w__prime_point double Rsig_point_scalaire_Rsig = delta__sig_barre_BH_tatdt && delta__sig_barre_BH_Ratdt; double ee = Rsig_point_scalaire_Rsig * unSurQ__deltaSiRatdt * unSurQ__deltaSiRatdt; double cos_alpha_point = - unSurQ__OiaR * unSurQ__deltaSiRatdt * (delta__sig_barre_BH_OiaR && (delta__sig_barre_BH_tatdt - ee * delta__sig_barre_BH_Ratdt )) ; w__prime_point = w__Base * cos_alpha_point; }; }; // fin du cas non neutre } // fin du cas où on peut calculer l'angle else // cas ou l'intensité de l'accroissement du déviateur de contrainte est nulle {w__prime = 2.;w__prime_point=0.;trajet_neut = false;}; // cas de cos(alpha)=1. } else // cas ou l'intensité du déviateur de référence est nulle {w__prime = 2.;w__prime_point=0.;trajet_neut = false;}; // cas de cos(alpha)=1. } else // cas d'une première charge {w__prime=1.;w__prime_point=0.;trajet_neut = false;}; }; // calcul de wprime et de sa variation par rapport aux coordonnées de delta sigma barre // en fonction de grandeurs supposées déjà calculées // utilise : Q_OiaR, QdeltaSigmaRatdt, // delta_sigma_barre_BH_Ratdt, delta_sigma_barre_BH_OiaR // wBase // trajet_neut: indique si oui ou non, on est dans un chargement neutre à la précision près // --- méthode indépendante ----- void Hysteresis3D::Cal_wprime_et_der(const double& Q__deltaSiRatdt,const Tenseur3BH& delta__sig_barre_BH_Ratdt ,const double& Q__OiaR,const Tenseur3BH& delta__sig_barre_BH_OiaR ,const double& w__Base,Tenseur3BH& delta__sig_barre_BH_tatdt ,double& w__prime, Tenseur3BH& d_w__prime ,double& w__prime_point,Tenseur3BH& d_w__prime_point,bool& trajet_neut) const { // -- calculs relatifs aux angles de phases static const double untiers=1./3.;static const double troisRacineDe6=3.*sqrt(6.); // ces calculs ne sont nécessaires que si l'on n'est pas sur une première charge d_w__prime.Inita(0.); // init pour tous les cas ou d_w__prime n'est pas calculée // cf les différents cas qui suivent d_w__prime_point.Inita(0.); // idem pour le w__prime_point if (w__Base!=1) {// si l'intensité du rayon est nulle, celui de seconde charge doit // être également nulle, on considére un alpha nulle donc un cos = 1 d'où w__prime = 2. // d'où des variations nulles if (Q__OiaR >= mini_rayon) // si mini_rayon est négatif (=> régularisation), l'expression est tjs vrai {// si l'intensité de l'accroissement du déviateur de contrainte est nulle, // on considére un alpha nulle donc un cos = 1 d'où w__prime = 2. if (Q__deltaSiRatdt >= mini_rayon) // idem test si dessus pour le cas où mini_rayon est négatif {// cas où on peut calculer l'angle double unSurQ__OiaR ;//= 1./Q__OiaR; double unSurQ__deltaSiRatdt;// = 1./Q__deltaSiRatdt; if (mini_rayon > 0.) // cas historique { unSurQ__OiaR = 1./Q__OiaR; unSurQ__deltaSiRatdt = 1./Q__deltaSiRatdt; } else // cas avec régularisation { unSurQ__OiaR = 1./(Q__OiaR-mini_rayon); unSurQ__deltaSiRatdt = 1./(Q__deltaSiRatdt-mini_rayon); } double x1 = delta__sig_barre_BH_Ratdt && delta__sig_barre_BH_OiaR; double cos_alpha = - x1* unSurQ__OiaR * unSurQ__deltaSiRatdt;; // if (Dabs(cos_alpha)<= ConstMath::pasmalpetit) if (Dabs(cos_alpha)<= min_angle_trajet_neutre) { // dans ce cas il s'agit d'un trajet neutre // le cos_alpha, sa dérivée, les w_prime et w_prime_point n'auront pas au final d'importance trajet_neut=true; w__prime=0.; w__prime_point=0.; } else if ((cos_alpha <= - min_angle_trajet_neutre) && (!possibilite_cosAlphaNegatif)) { // cas ou cos_alpha est négatif et que l'on veut traiter ce cas comme un cas neutre // le cos_alpha, sa dérivée, les w_prime et w_prime_point n'auront pas au final d'importance trajet_neut=true; w__prime=0.; w__prime_point=0.; } else { // chargement non neutre trajet_neut = false; w__prime = w__Base * cos_alpha; if ((w__prime <= 0) && (possibilite_cosAlphaNegatif)) { // dans le cas où cos_alpha est négatif et que l'on admet "transitoirement" que le cos_alpha puisse // être négatif, on lui change de signe (cf. les anciens commentaires qui suivent) // C1- il y a problème car cela signifie que cos_alpha est négatif donc que les cercles s'accroissent // C1- ceci peut être du à une erreur d'arrondi // C1- on considère alors que l'on est au cas limite de cos_alpha = 0` // C2-- non en fait ça peut-être tout-à-fait normale, juste avant une inversion on a un angle négatif et c'est normale // C2-- pour éviter d'avoir des pb le plus simple est de considérer la partie positive de l'angle // if (MaX(ParaGlob::NiveauImpression(),Permet_affichage()) >= 3) // cout << "\n attention, angle de phase negatif en hysteresis ! ,"; // << " on le met a 0"; // if (MaX(ParaGlob::NiveauImpression(),Permet_affichage()) >= 6) // cout << " Q__deltaSiRatdt= " << Q__deltaSiRatdt ; // w__prime = 2.;w__prime_point=0.; */ w__prime = - w__prime; // -- calcul de w__prime_point double a ;//= Q__deltaSiRatdt * Q__deltaSiRatdt; if (mini_rayon > 0.) // cas historique { a = Q__deltaSiRatdt * Q__deltaSiRatdt;} else // cas avec régularisation { a = Q__deltaSiRatdt * Q__deltaSiRatdt-mini_rayon;}; double b = delta__sig_barre_BH_tatdt && delta__sig_barre_BH_Ratdt; double ee = b/a; double C = delta__sig_barre_BH_OiaR && (delta__sig_barre_BH_tatdt - ee * delta__sig_barre_BH_Ratdt); double cos_alpha_point = (- unSurQ__OiaR * unSurQ__deltaSiRatdt) * C; w__prime_point = - w__Base * cos_alpha_point; // calcul de la variation de cos_alpha et donc de w__prime Tenseur3BH d_aSur2_BH(delta__sig_barre_BH_Ratdt); d_aSur2_BH.PermuteHautBas(); Tenseur3BH num_cos_BH(delta__sig_barre_BH_OiaR);num_cos_BH.PermuteHautBas(); d_w__prime = d_aSur2_BH * (cos_alpha * unSurQ__deltaSiRatdt * unSurQ__deltaSiRatdt*w__Base) + num_cos_BH * (unSurQ__deltaSiRatdt * unSurQ__OiaR*w__Base); // d_w__prime = d_a_BH; // d_w__prime *= (x1/(Q__deltaSiRatdt*Q__deltaSiRatdt)-1)/(Q__deltaSiRatdt*Q__OiaR); // calcul de la variation de cos_alpha_point Tenseur3BH d_b_BH(delta__sig_barre_BH_tatdt); d_b_BH.PermuteHautBas(); d_b_BH += d_aSur2_BH; double unSur_a2 = 1./(a*a); Tenseur3BH d_e_BH = d_b_BH / a - (2.* b*unSur_a2)*d_aSur2_BH; d_w__prime_point = (w__Base * unSurQ__OiaR) * ( (- unSurQ__deltaSiRatdt / a * C)*d_aSur2_BH + ((1.-ee)*unSurQ__deltaSiRatdt) * num_cos_BH + (-unSurQ__deltaSiRatdt * x1)* d_e_BH ); } else {// -- calcul de w__prime_point double a ;//= Q__deltaSiRatdt * Q__deltaSiRatdt; if (mini_rayon > 0.) // cas historique { a = Q__deltaSiRatdt * Q__deltaSiRatdt;} else // cas avec régularisation { a = Q__deltaSiRatdt * Q__deltaSiRatdt-mini_rayon;}; double b = delta__sig_barre_BH_tatdt && delta__sig_barre_BH_Ratdt; double ee = b/a; double C = delta__sig_barre_BH_OiaR && (delta__sig_barre_BH_tatdt - ee * delta__sig_barre_BH_Ratdt); double cos_alpha_point = (- unSurQ__OiaR * unSurQ__deltaSiRatdt) * C; w__prime_point = w__Base * cos_alpha_point; // calcul de la variation de cos_alpha et donc de w__prime Tenseur3BH d_aSur2_BH(delta__sig_barre_BH_Ratdt); d_aSur2_BH.PermuteHautBas(); Tenseur3BH num_cos_BH(delta__sig_barre_BH_OiaR);num_cos_BH.PermuteHautBas(); d_w__prime = d_aSur2_BH * (- cos_alpha * unSurQ__deltaSiRatdt * unSurQ__deltaSiRatdt*w__Base) - num_cos_BH * (unSurQ__deltaSiRatdt * unSurQ__OiaR*w__Base); // d_w__prime = d_a_BH; // d_w__prime *= (x1/(Q__deltaSiRatdt*Q__deltaSiRatdt)-1)/(Q__deltaSiRatdt*Q__OiaR); // calcul de la variation de cos_alpha_point Tenseur3BH d_b_BH(delta__sig_barre_BH_tatdt); d_b_BH.PermuteHautBas(); d_b_BH += d_aSur2_BH; double unSur_a2 = 1./(a*a); Tenseur3BH d_e_BH = d_b_BH / a - (2.*b*unSur_a2)*d_aSur2_BH; d_w__prime_point = (-w__Base * unSurQ__OiaR) * ( (- unSurQ__deltaSiRatdt / a * C)*d_aSur2_BH + ((1.-ee)*unSurQ__deltaSiRatdt) * num_cos_BH + (-unSurQ__deltaSiRatdt * x1)* d_e_BH ); }; }// fin du cas non neutre }// fin du cas où on peut calculer l'angle else // cas ou l'intensité de l'accroissement du déviateur de contrainte est nulle {w__prime = 2.;w__prime_point=0.;trajet_neut = false;}; // cas de cos(alpha)=1. } else // cas ou l'intensité du déviateur de référence est nulle {w__prime = 2.;w__prime_point=0.;trajet_neut = false;}; // cas de cos(alpha)=1. } else // cas d'une première charge {w__prime=1.;w__prime_point=0.;trajet_neut = false;}; }; // calcul du centre d'inversion avec les données actuelles // ramène un indicateur informant comment l'opération s'est passé et si elle est valide (= 0) int Hysteresis3D::CentreCercle(Tenseur3BH& sig0i_BH,const Tenseur3BH& oc_BH_R ,const Tenseur3BH & delta_sigma_barre_BH_OiaR ,const Tenseur3BH& delta_sigma_barre_BH_Rat) { // on part du principe que c'est le point à t qui est le point d'inversion // ceci a été déterminé par le fait que le rayon à tdt a été trouvé plus petit que celui a t double rayon_t = sqrt((delta_sigma_barre_BH_OiaR + delta_sigma_barre_BH_Rat).II()); double delta_rayon2 = (rayon_t*rayon_t - Q_OiaR*Q_OiaR); // ici ce n'est pas le vrai cos, mais le cos * les deux normes, mais le signe est le même double cos_alpha_a_t = (delta_sigma_barre_BH_OiaR && delta_sigma_barre_BH_Rat); // double gamma = 0.5 * (rayon_t*rayon_t - Q_OiaR*Q_OiaR) // / (delta_sigma_barre_BH_OiaR && delta_sigma_barre_BH_Rat); int retour = 0; // init du retour a priori // --- mise à jour précision éventuelle double tol_centre_reelle = tolerance_centre; if (tolerance_centre < 0) // si l'indication est négative , cela veut dire que l'on veut une grandeur relative tol_centre_reelle = MaX(-tolerance_centre * Q_OiaR,-tolerance_centre); // --- // en fait peut-être très proche de 0 du aux erreurs d'arrondi if (Dabs(delta_rayon2) < tol_centre_reelle) // à la tolérance près on a le même rayon, cela veut dire qu'à l'incrément précédent on était sur un trajet // neutre à la précision près, donc pas de nouveau centre à calculer {retour = 1;} else if (delta_rayon2 > 0.) // et donc sup aussi à tol_centre_reelle compte tenu du test plus haut // là il s'agit d'un comportement qui n'est pas normal, car normalement le nouveau rayon doit-être plus petit // que l'ancien donc on n'a pas de point d'inversion probant (ce serait plutôt une coïncidence mal déterminée) // il vaut mieux attendre un incrément de charge supérieure qui permettra d'avoir // un point d'inversion correctement déterminé {retour = 1;} // on signale que ce n'est pas la peine de calculer un nouveau centre else if (Dabs(cos_alpha_a_t) < min_angle_trajet_neutre) // maintenant il faut que le cos_alpha ne soit pas trop petit // si oui on était alors sur un trajet neutre qui s'ignorait, là encore le point d'inversion n'est pas probant // il vaut mieux attendre un incrément de charge supérieure qui permettra d'avoir // un point d'inversion correctement déterminé {retour = 1;} // on signale que ce n'est pas la peine de calculer un nouveau centre else if (cos_alpha_a_t > 0.) // et donc sup aussi à min_angle_trajet_neutre compte tenu du test plus haut // c'est pas non plus normal, cela veut dire que l'on se déplace vers l'extérieur de la sphére de ref // donc ce n'est pas un point d'inversion correct {retour = 1;} // on signale que ce n'est pas la peine de calculer un nouveau centre else // arrivée ici toutes les conditions sont bonnes pour calculer un point d'inversion correct {double gamma = 0.5 * delta_rayon2 / cos_alpha_a_t; sig0i_BH = oc_BH_R + gamma * delta_sigma_barre_BH_OiaR; }; // message d'info au cas où if (retour) if (Permet_affichage() > 5) { double cosalpha = (delta_sigma_barre_BH_OiaR && delta_sigma_barre_BH_Rat) /sqrt((delta_sigma_barre_BH_OiaR.II()*delta_sigma_barre_BH_Rat.II())); cout << "\n info concernant le calcul de centre, le centre ne peut-etre calcule ce qui n'est peut-etre pas normal !! " << "\n Hysteresis3D::CentreCercle(..." << " rayon_t= " << rayon_t << " Q_OiaR= " < 4) Affiche_debug(unSur_wBaseCarre,save_resul,iatens,iadef_equi,pt_sur_principal ,iaOi,oi_sur_principal,iatens_princ,iadef_equi_princ,iaOi_princ); // on génère une exception throw ErrNonConvergence_loiDeComportement(); }; // comme on est sur la liste secondaire, cela signifie qu'elle n'est pas vide en point d'inversion // donc on peut supprimer une contrainte d'inversion save_resul.sigma_barre_BH_R_t_a_tdt.erase(iatens); // normalement c'est le premier de la liste! save_resul.def_equi_t_a_tdt.erase(iadef_equi); // idem pour def_equi qui suit la même logique save_resul.fct_aide_t_a_tdt.erase(iafct); // idem pour la fonction d'aide // save_resul.nb_coincidence--; // on dépile également le nombre de coïncidence active if (save_resul.sigma_barre_BH_R_t_a_tdt.size()==0) {// il ne reste plus d'élément on revient sur la liste principal pt_sur_principal = true; iatens = iatens_princ; iadef_equi=iadef_equi_princ;iafct=iafct_princ; // on regarde si le pointeur est valide if (iatens != save_resul.sigma_barre_BH_R.end()) {aucun_pt_inversion = false;} else {aucun_pt_inversion = true;}; } else // cas où il reste des éléments sur les listes secondaires {iatens = save_resul.sigma_barre_BH_R_t_a_tdt.begin();aucun_pt_inversion = false; iadef_equi = save_resul.def_equi_t_a_tdt.begin(); iafct = save_resul.fct_aide_t_a_tdt.begin(); }; } else // cas où on pointe sur la liste principal, on se déplace dans la liste principal, { // sans éliminer d'élément : on update le pointage if (iatens != save_resul.sigma_barre_BH_R.end()) {iatens++;iadef_equi++;// idem pour def_equi et iafct qui suivent une même logique // mais il faut mettre à jour la fonction d'aide par rapport à la valeur // qu'elle avait au point d'inversion précédent sinon, c'est perdue W_a = *iafct; iafct++; // idem pour def_equi et iafct qui suivent une même logique // on regarde si le pointeur est valide if (iatens != save_resul.sigma_barre_BH_R.end()) {aucun_pt_inversion = false;} else {aucun_pt_inversion = true;}; save_resul.nb_coincidence++; // on acte la coïncidence // comme on est sur la liste principale, on met à jour les pointeurs de la liste principale iatens_princ = iatens;iadef_equi_princ=iadef_equi;iafct_princ = iafct; } else // sinon il y a un pb car comme c'est une coïncidence il devrait rester un pointeur valide {if (Permet_affichage() > 0) cout << "\n incoherence, il devrait rester un pointeur de valide sur la liste de pt de ref" << "\n Hysteresis3D::Gestion_pointeur_coincidence(..." << endl; if (Permet_affichage() > 4) Affiche_debug(unSur_wBaseCarre,save_resul,iatens,iadef_equi,pt_sur_principal ,iaOi,oi_sur_principal,iatens_princ,iadef_equi_princ,iaOi_princ); // cout << "\n tapper quelque chose "; // string toto; cin >> toto; // on génère une exception throw ErrNonConvergence_loiDeComportement(); }; }; // 2-- cas des centres : si on pointe sur la liste secondaire on retire le dernier élément if (!oi_sur_principal) { if (iaOi != save_resul.oc_BH_t_a_tdt.begin()) { if (Permet_affichage() > 0) cout << "\n incoherence, on devrait avoir ici le premier element de la liste secondaire des centres" << "\n Hysteresis3D::Gestion_pointeur_coïncidence(..."<< endl; if (Permet_affichage() > 4) Affiche_debug(unSur_wBaseCarre,save_resul,iatens,iadef_equi,pt_sur_principal ,iaOi,oi_sur_principal,iatens_princ,iadef_equi_princ,iaOi_princ); // on génère une exception throw ErrNonConvergence_loiDeComportement(); }; // on regarde si on peut supprimer un centre if (iaOi != save_resul.oc_BH_t_a_tdt.end()) // dans le cas où l'origine est 0, il n'y a rien de sauvegardé save_resul.oc_BH_t_a_tdt.erase(iaOi); // sinon normalement c'est le premier de la liste! if (save_resul.oc_BH_t_a_tdt.size()==0) {// il ne reste plus d'élément on revient sur la liste principal oi_sur_principal = true; iaOi = iaOi_princ; // on regarde de nouveau si le pointeur de centre est valide if ((iaOi != save_resul.oc_BH_R.end())) {centre_initial=false;} else {centre_initial=true;}; } else // cas où il reste des éléments sur les nouvelles listes {iaOi = save_resul.oc_BH_t_a_tdt.begin(); centre_initial = false; }; } else // cas où on pointe sur la liste principal, on se déplace dans la liste principal, { // sans éliminer d'élément : on update le pointage if (iaOi != save_resul.oc_BH_R.end()) // si la liste est vide, c-a-d le centre est le tenseur nulle iaOi++; // on n'avance pas // on regarde de nouveau si le pointeur de centre est valide if ((iaOi != save_resul.oc_BH_R.end())) {centre_initial=false;} else {centre_initial=true;}; // comme on est sur la liste principale, on met à jour les pointeurs de la liste principale iaOi_princ=iaOi; }; // 3-- traitement particulier dans le cas où on a rejoint la première charge if (aucun_pt_inversion) // cas où l'on est sur la courbe de première charge { wBase = 1; unSur_wBaseCarre = 1./(wBase*wBase); } else // on met à jour le centre du cercle de référence, en indiquant que l'on a rattrapé une courbe { wBase = 2; unSur_wBaseCarre = 1./(wBase*wBase); }; // gestion du paramètre "modif" de saveresult bool inversion = false; Gestion_para_Saveresult_Modif(pt_sur_principal,save_resul,inversion); //--------débug- traçage #ifdef MISE_AU_POINT if (Permet_affichage() == -77) { cout << "\ngestion de pointeur de coïncidence "; cout << " aucun_pt_inversion= " << aucun_pt_inversion << " save_resul.nb_coincidence= " << save_resul.nb_coincidence; cout << " \nsigR_sur_principal= " << pt_sur_principal << ", oi_sur_principal= " << oi_sur_principal << " save_resul.modif= " << save_resul.modif << " \n nb_Oi= "<