// FICHIER : Hysteresis1D.cc // CLASSE : Hysteresis1D // 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 "CharUtil.h" #include "Hysteresis1D.h" #include "Enum_TypeQuelconque.h" #include "TypeQuelconqueParticulier.h" // ========== fonctions pour la classe de sauvegarde des résultats ========= // constructeur par défaut Hysteresis1D::SaveResulHysteresis1D::SaveResulHysteresis1D() : sigma_barre_BH_t(),sigma_barre_BH_tdt(),sigma_barre_BH_R() ,fonction_aide_t(0.),fonction_aide_tdt(0.),wprime_t(1.),wprime_tdt(1.) ,modif(0),sigma_barre_BH_R_t_a_tdt(),nb_coincidence(0) ,ip2(),indic_coin(),fct_aide_t_a_tdt(),fct_aide() ,indicateurs_resolution(),indicateurs_resolution_t() {// la première valeur de la fonction d'aide est l'infini fct_aide.push_front(ConstMath::tresgrand);sigma_barre_BH_R.push_front(Tenseur1BH()); }; // constructeur de copie Hysteresis1D::SaveResulHysteresis1D::SaveResulHysteresis1D(const SaveResulHysteresis1D& 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) ,fonction_aide_t(sav.fonction_aide_t),fonction_aide_tdt(sav.fonction_aide_tdt) ,wprime_t(sav.wprime_t),wprime_tdt(sav.wprime_tdt) ,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) ,ip2(),indic_coin(sav.indic_coin),fct_aide(sav.fct_aide) ,indicateurs_resolution(sav.indicateurs_resolution),indicateurs_resolution_t(sav.indicateurs_resolution_t) { if (fct_aide.size() >= 2) // pointage de ip2 {ip2= fct_aide.end(); ip2--;ip2--; }; }; // affectation Loi_comp_abstraite::SaveResul & Hysteresis1D::SaveResulHysteresis1D::operator = ( const Loi_comp_abstraite::SaveResul & a) { Hysteresis1D::SaveResulHysteresis1D& sav = *((Hysteresis1D::SaveResulHysteresis1D*) &a); // recopie de toutes les grandeurs 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; fct_aide = sav.fct_aide; wprime_t = sav.wprime_t; wprime_tdt = sav.wprime_tdt; 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; indic_coin = sav.indic_coin; 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 Hysteresis1D::SaveResulHysteresis1D::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 >> fonction_aide_t; fonction_aide_tdt=fonction_aide_t; ent >> toto >> wprime_t; wprime_tdt=wprime_t; ent >> toto; // ---- lecture fonction d'aide #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: debut_List_IO= " << "\n Hysteresis1D::SaveResulHysteresis1D::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--; } 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: debut_List_IO= " << "\n Hysteresis1D::SaveResulHysteresis1D::Lecture_base_info (... "; Sortie(1); } #endif ent >> toto >> taille; // lecture de la taille Tenseur1BH elem; // on vide la liste actuelle sigma_barre_BH_R.clear(); for (int j=1;j<=taille;j++) // puis on lit { ent >> elem; // lecture sigma_barre_BH_R.push_back(elem); // enregistrement } //re-initialisation des variables de travail 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 Hysteresis1D::SaveResulHysteresis1D::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 << " fct_aide_t " << fonction_aide_t; sort << " wprime_t " << wprime_t; // les listes: fonction d'aide et point d'inversion sort << " 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 << " "; } sort << " list_pt_inver " << "taille= " << sigma_barre_BH_R.size() << " "; 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 << " "; } }; // mise à jour des informations transitoires void Hysteresis1D::SaveResulHysteresis1D::TdtversT() { // partie générale sigma_barre_BH_t = sigma_barre_BH_tdt;fonction_aide_t=fonction_aide_tdt; wprime_t = wprime_tdt; // partie spécifique 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 2 pt de ref, sauf si l'on revient // sur la courbe de première charge, et que l'on a fait une symétrie trac -> comp par exemple // dans ce cas on ne supprime qu'un point: en clair il faut toujours qu'il reste un point List_io ::iterator itens;List_io ::iterator ifct; for (int i=1;i<=nb_coincidence;i++) { itens = sigma_barre_BH_R.begin(); if (itens != sigma_barre_BH_R.end()) sigma_barre_BH_R.erase(itens); ifct = fct_aide.begin(); if (ifct != fct_aide.end()) fct_aide.erase(ifct); // on dépile que si c'est une coincidence secondaire ou, dans le cas d'une coincidence avec // la première charge, on dépile que si il reste 2 pt d'inversion (cas tout traction ou // tout compression if ((wprime_tdt != 1.) || ((wprime_tdt == 1.)&&(sigma_barre_BH_R.size()!=1))) {itens = sigma_barre_BH_R.begin(); if (itens != sigma_barre_BH_R.end()) sigma_barre_BH_R.erase(itens); ifct = fct_aide.begin(); if (ifct != fct_aide.end()) fct_aide.erase(ifct); }; }; break; } case 2: // cas où l'on a une ou plusieurs inversions { 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_ref_new = fct_aide_t_a_tdt.size(); // récup du nombre de nouveau pt // on ajoute les différents points d'inversions List_io ::iterator iitens = sigma_barre_BH_R_t_a_tdt.begin(); List_io ::iterator iifct = fct_aide_t_a_tdt.begin(); for (int ii=1;ii<=nb_ref_new;ii++,iitens++,iifct++) { sigma_barre_BH_R.push_front(*iitens); // ----- débug (a virer ) ------ // // on vérifie que le niveau de la fonction d'aide est acceptable // if (*iifct > *fct_aide.begin()) // {cout << "\n erreur 3 " << endl;Sortie(1);} // ----- fin débug (a virer ) ------ 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) { // on itère sur indic_coin pour savoir si l'ordre des inversions et coincidence List_io ::iterator iindic,iindic_fin = indic_coin.end(); // on ajoute les différents points d'inversions List_io ::iterator iitens = sigma_barre_BH_R_t_a_tdt.begin(); List_io ::iterator iifct = fct_aide_t_a_tdt.begin(); // a chaque coincidence il faut supprimer 2 pt de ref List_io ::iterator itens;List_io ::iterator ifct; for (iindic= indic_coin.begin();iindic != iindic_fin;iindic++) { if (*iindic ) // cas d'une coincidence {itens = sigma_barre_BH_R.begin(); if (itens != sigma_barre_BH_R.end()) sigma_barre_BH_R.erase(itens); ifct = fct_aide.begin(); if (ifct != fct_aide.end()) fct_aide.erase(ifct); // on dépile que si c'est une coincidence secondaire ou, dans le cas d'une coincidence avec // la première charge, on dépile que si il reste 2 pt d'inversion (cas tout traction ou // tout compression if ((wprime_tdt != 1.) || ((wprime_tdt == 1.)&&(sigma_barre_BH_R.size()!=1))) {itens = sigma_barre_BH_R.begin(); if (itens != sigma_barre_BH_R.end()) sigma_barre_BH_R.erase(itens); ifct = fct_aide.begin(); if (ifct != fct_aide.end()) fct_aide.erase(ifct); } } else {// cas d'une inversion sigma_barre_BH_R.push_front(*iitens); // ----- débug (a virer ) ------ // // on vérifie que le niveau de la fonction d'aide est acceptable // if (*iifct > *fct_aide.begin()) // {cout << "\n erreur 4 " << endl;Sortie(1);} // ----- fin débug (a virer ) ------ fct_aide.push_front(*iifct); iitens++;iifct++; // incrémentation pour la fois suivante } } // mise à jour d'ip2 if ( fct_aide_t_a_tdt.size() > 1) { ip2 = fct_aide.end(); ip2--;ip2--;} break; } default: cout << "\n erreur dans la mise a jour des informations transitoire: modif= " << modif << "\n Hysteresis1D::SaveResulHysteresis1D::TversTdt() "; Sortie(1); } // 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 Hysteresis1D::SaveResulHysteresis1D::TversTdt() { // partie générale sigma_barre_BH_tdt = sigma_barre_BH_t;fonction_aide_tdt=fonction_aide_t; wprime_tdt=wprime_t; //re-initialisation des variables de travail Init_debut_calcul(); }; // affichage à l'écran des infos void Hysteresis1D::SaveResulHysteresis1D::Affiche() const { cout << "\n SaveResulHysteresis1D: " ; cout << "\n sigma_barre_BH_t= " << sigma_barre_BH_t << " sigma_barre_BH_tdt= " << sigma_barre_BH_tdt << " fonction_aide_t= " << fonction_aide_t << " fonction_aide_tdt= " << fonction_aide_tdt << " wprime_t= " << wprime_t << " wprime_tdt= " << wprime_tdt ; cout << "\n list sigma_barre_BH_R_t_a_tdt: " << sigma_barre_BH_R_t_a_tdt; cout << "\n nb_coincidence= " << nb_coincidence; cout << "\n list fct_aide_t_a_tdt: " << fct_aide_t_a_tdt; cout << "\n list indic_coin: " << indic_coin; cout << "\n list sigma_barre_BH_R: " << sigma_barre_BH_R; cout << "\n list fct_aide: " << fct_aide << " "; }; //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 Hysteresis1D::SaveResulHysteresis1D::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); // 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(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); }; }; // initialise les informations de travail concernant le pas de temps en cours void Hysteresis1D::SaveResulHysteresis1D::Init_debut_calcul() { //initialisation des variables de travail modif = 0; nb_coincidence=0; indic_coin.clear(); sigma_barre_BH_R_t_a_tdt.clear(); fct_aide_t_a_tdt.clear(); }; // ========== fin des fonctions pour la classe de sauvegarde des résultats ========= Hysteresis1D::Hysteresis1D () : // Constructeur par defaut Loi_comp_abstraite(HYSTERESIS_1D,CAT_MECANIQUE,1),xnp(ConstMath::tresgrand) ,xmu(ConstMath::tresgrand),Qzero(ConstMath::tresgrand) ,xnp_temperature(NULL),Qzero_temperature(NULL),xmu_temperature(NULL) ,tolerance_residu(1.e-3),tolerance_residu_rel(1.e-5),nb_boucle_maxi(100),nb_sous_increment(4) ,maxi_delta_var_sig_sur_iter_pour_Newton(-1) ,tolerance_coincidence() ,sigma_t_barre_tdt(),sigma_i_barre_BH(),sigma_barre_BH_R() ,delta_sigma_barre_BH_Rat(),delta_sigma_barre_BH_Ratdt() ,delta_sigma_barre_tdt_BH(),residuBH(),delta_barre_epsBH(),delta_barre_alpha_epsBH(),wprime() ,residu(1),derResidu(1,1),alg_zero(),alg_edp() ,rdelta_sigma_barre_BH_Ratdt(),rdelta_sigma_barre_tdt_BH() ,cas_kutta(5),erreurAbsolue(1.e-3),erreurRelative(1.e-5) ,sig_point(1),sigma_pointBH(),sigma_tauBH(),sigma_tau(1),delta_sigma_barre_R_a_tauBH() ,type_resolution_equa_constitutive(1),nbMaxiAppel(120) ,betaphideltasigHB(),deuxmudeltaepsHB(),nb_maxInvCoinSurUnPas(4) // ---- affichage ,sortie_post(0) {// 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_sous_increment); tolerance_coincidence = tolerance_residu; // idem avec kutta alg_edp.Modif_nbMaxiAppel(nbMaxiAppel); }; // Constructeur de copie Hysteresis1D::Hysteresis1D (const Hysteresis1D& loi) : Loi_comp_abstraite(loi),xnp(loi.xnp),xmu(loi.xmu),Qzero(loi.Qzero) ,xnp_temperature(loi.xnp_temperature),Qzero_temperature(loi.xnp_temperature) ,xmu_temperature(loi.xnp_temperature) ,tolerance_residu(loi.tolerance_residu),tolerance_residu_rel(loi.tolerance_residu_rel) ,nb_boucle_maxi(loi.nb_boucle_maxi) ,nb_sous_increment(loi.nb_sous_increment) ,maxi_delta_var_sig_sur_iter_pour_Newton(loi.maxi_delta_var_sig_sur_iter_pour_Newton) ,tolerance_coincidence(loi.tolerance_coincidence) ,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) ,delta_sigma_barre_BH_Rat(loi.delta_sigma_barre_BH_Rat) ,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_barre_epsBH(loi.delta_barre_epsBH) ,delta_barre_alpha_epsBH(loi.delta_barre_alpha_epsBH),wprime(loi.wprime) ,residu(1),derResidu(1,1),alg_zero(),alg_edp() ,rdelta_sigma_barre_BH_Ratdt(),rdelta_sigma_barre_tdt_BH() ,cas_kutta(loi.cas_kutta),erreurAbsolue(loi.erreurAbsolue),erreurRelative(loi.erreurRelative) ,sig_point(1),sigma_pointBH(),sigma_tauBH(),sigma_tau(1),delta_sigma_barre_R_a_tauBH() ,type_resolution_equa_constitutive(loi.type_resolution_equa_constitutive) ,nbMaxiAppel(loi.nbMaxiAppel),betaphideltasigHB(),deuxmudeltaepsHB() ,nb_maxInvCoinSurUnPas(loi.nb_maxInvCoinSurUnPas) // ---- affichage ,sortie_post(loi.sortie_post) {// 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_sous_increment); // 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));; }; Hysteresis1D::~Hysteresis1D () // 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; }; // Lecture des donnees de la classe sur fichier void Hysteresis1D::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D ,LesFonctions_nD& lesFonctionsnD) { // ---- lecture du paramètre de prager string nom; *(entreePrinc->entree) >> nom; if(nom != "np=") { cout << "\n erreur en lecture du parametre de prager " << " on attendait la chaine : np= "; cout << "\n Hysteresis1D::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 "; entreePrinc->MessageBuffer("**erreur2 Hysteresis1D::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 Hysteresis1D::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= "; cout << "\n Hysteresis1D::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 Hysteresis1D::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= "; cout << "\n Hysteresis1D::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;}; // // --- 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) // { entreePrinc->NouvelleDonnee(); // if(strstr(entreePrinc->tablcar,"type_de_resolution_")!=0) // {*(entreePrinc->entree) >> nom; // if (nom != "type_de_resolution_") // { cout << "\n erreur en lecture du type de resolution, on attendait la chaine: type_de_resolution_ " // << " et on a lu : " << nom // << "\n Hysteresis1D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; // throw (UtilLecture::ErrNouvelleDonnee(-1)); // Sortie(1); // } // else // {*(entreePrinc->entree) >> type_resolution_equa_constitutive; // }; // }; // if(strstr(entreePrinc->tablcar,"nb_iteration_maxi_")!=0) // {*(entreePrinc->entree) >> nom; // if (nom != "nb_iteration_maxi_") // { cout << "\n erreur en lecture du nombre d'iteration maxi, on attendait la chaine: nb_iteration_maxi_ " // << " et on a lu : " << nom // << "\n Hysteresis1D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; // throw (UtilLecture::ErrNouvelleDonnee(-1)); // Sortie(1); // } // else // {*(entreePrinc->entree) >> nb_boucle_maxi; // alg_zero.Modif_iter_max(nb_boucle_maxi); // }; // }; // if(strstr(entreePrinc->tablcar,"nb_dichotomie_maxi_")!=0) // {*(entreePrinc->entree) >> nom; // if (nom != "nb_dichotomie_maxi_") // { cout << "\n erreur en lecture du nombre de dichotomies maxi, on attendait la chaine: nb_dichotomie_ " // << " et on a lu : " << nom // << "\n Hysteresis1D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; // throw (UtilLecture::ErrNouvelleDonnee(-1)); // Sortie(1); // } // else // {*(entreePrinc->entree) >> nb_sous_increment; // alg_zero.Modif_nbMaxiIncre(nb_sous_increment); // }; // }; // if(strstr(entreePrinc->tablcar,"tolerance_residu_")!=0) // {*(entreePrinc->entree) >> nom; // if (nom != "tolerance_residu_") // { cout << "\n erreur en lecture de la tolerance absolue sur le residu, on attendait la chaine: tolerance_residu_ " // << " et on a lu : " << nom // << "\n Hysteresis1D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; // throw (UtilLecture::ErrNouvelleDonnee(-1)); // Sortie(1); // } // else // {*(entreePrinc->entree) >> tolerance_residu; // alg_zero.Modif_prec_res_abs(tolerance_residu); // }; // }; // if(strstr(entreePrinc->tablcar,"tolerance_residu_rel_")!=0) // {*(entreePrinc->entree) >> nom; // if (nom != "tolerance_residu_rel_") // { cout << "\n erreur en lecture de la tolerance relative sur le residu, on attendait la chaine:" // << " tolerance_residu_rel_ " // << " et on a lu : " << nom // << "\n Hysteresis1D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; // throw (UtilLecture::ErrNouvelleDonnee(-1)); // Sortie(1); // } // else // {*(entreePrinc->entree) >> tolerance_residu_rel; // alg_zero.Modif_prec_res_rel(tolerance_residu_rel); // }; // }; // if(strstr(entreePrinc->tablcar,"cas_kutta_")!=0) // {*(entreePrinc->entree) >> nom; // if (nom != "cas_kutta_") // { cout << "\n erreur en lecture du cas de Runge Kutta, on attendait la chaine: cas_kutta_ " // << " et on a lu : " << nom // << "\n Hysteresis1D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; // throw (UtilLecture::ErrNouvelleDonnee(-1)); // Sortie(1); // } // else // {*(entreePrinc->entree) >> cas_kutta; // }; // }; // if(strstr(entreePrinc->tablcar,"erreurAbsolue_")!=0) // {*(entreePrinc->entree) >> nom; // if (nom != "erreurAbsolue_") // { cout << "\n erreur en lecture de l'erreur absolu pour Runge Kutta, on attendait la chaine: erreurAbsolue_ " // << " et on a lu : " << nom // << "\n Hysteresis1D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; // throw (UtilLecture::ErrNouvelleDonnee(-1)); // Sortie(1); // } // else // {*(entreePrinc->entree) >> erreurAbsolue; // }; // }; // if(strstr(entreePrinc->tablcar,"erreurRelative_")!=0) // {*(entreePrinc->entree) >> nom; // if (nom != "erreurRelative_") // { cout << "\n erreur en lecture de l'erreur relative pour Runge Kutta, on attendait la chaine: erreurRelative_ " // << " et on a lu : " << nom // << "\n Hysteresis1D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; // throw (UtilLecture::ErrNouvelleDonnee(-1)); // Sortie(1); // } // else // {*(entreePrinc->entree) >> erreurRelative; // }; // }; // if(strstr(entreePrinc->tablcar,"nbMaxiAppel_")!=0) // {*(entreePrinc->entree) >> nom; // if (nom != "nbMaxiAppel_") // { cout << "\n erreur en lecture du nombre maxi d'appel de la derivee pour Runge Kutta, on attendait la chaine: nbMaxiAppel_ " // << " et on a lu : " << nom // << "\n Hysteresis1D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; // throw (UtilLecture::ErrNouvelleDonnee(-1)); // Sortie(1); // } // else // {*(entreePrinc->entree) >> nbMaxiAppel; // alg_edp.Modif_nbMaxiAppel(nbMaxiAppel); // }; // }; // if(strstr(entreePrinc->tablcar,"tolerance_coincidence_")!=0) // {*(entreePrinc->entree) >> nom; // if (nom != "tolerance_coincidence_") // { cout << "\n erreur en lecture de la tolerance sur les coincidences, on attendait la chaine: tolerance_coincidence_ " // << " et on a lu : " << nom // << "\n Hysteresis3D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; // throw (UtilLecture::ErrNouvelleDonnee(-1)); // Sortie(1); // } // else // {*(entreePrinc->entree) >> tolerance_coincidence; // }; // }; // if(strstr(entreePrinc->tablcar,"nb_maxInvCoinSurUnPas_")!=0) // {*(entreePrinc->entree) >> nom; // if (nom != "nb_maxInvCoinSurUnPas_") // { cout << "\n erreur en lecture sur le nombre maxi d'inversion sur le pas, on attendait la chaine:" // << "\n nb_maxInvCoinSurUnPas_ et on a lu : " << nom // << "\n Hysteresis1D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; // throw (UtilLecture::ErrNouvelleDonnee(-1)); // Sortie(1); // } // else // {*(entreePrinc->entree) >> nb_maxInvCoinSurUnPas; // }; // }; // }; //-- fin de la lecture des paramètres de réglage // --- 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); }; } // 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_sous_increment; alg_zero.Modif_nbMaxiIncre(nb_sous_increment); } // 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; } // nombre maxi d'inversion sur le pas else if (nom == "nb_maxInvCoinSurUnPas_") {*(entreePrinc->entree) >> nb_maxInvCoinSurUnPas; } // 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 (Permet_affichage() > 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 // 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 Hysteresis1D::Affiche() const { cout << " \n loi_de_comportement d'hysteresis1D " ; if ( xnp_temperature != NULL) { cout << " np thermo dependant " << " courbe np=f(T): " << xnp_temperature->NomCourbe() <<" ";} else { cout << " np= " << xnp ;}; if ( Qzero_temperature != NULL) { cout << " Qzero thermo dependant " << " courbe np=f(T): " << Qzero_temperature->NomCourbe() <<" ";} else { cout << " Qzero= " << Qzero ;}; if ( xmu_temperature != NULL) { cout << " xmu thermo dependant " << " courbe xmu=f(T): " << xmu_temperature->NomCourbe() <<" ";} else { cout << " mu= " << xmu ;}; if (type_resolution_equa_constitutive == 1) { cout << " \n type de resolution: linearisation, nbmax iteration= " << nb_boucle_maxi << " nbmax_dichotonmie= " << nb_sous_increment << " 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 { cout << " \n type de resolution: Runge_Kutta " << cas_kutta << " erreurAbsolue " << erreurAbsolue << " erreurRelative= " << erreurRelative ; }; cout << " tolerance_coincidence= " << tolerance_coincidence << " nb_maxInvCoinSurUnPas= " << nb_maxInvCoinSurUnPas; // 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 Hysteresis1D::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 sort << "\n#-------------------------------------------------------------------" << "\n# ....... loi_de_comportement d'hysteresis 1D ........ |" << "\n# para de prager(>=0) : mu : limite de plasticite |" << "\n#-------------------------------------------------------------------" << "\n np= " << setprecision(6) << xnp << " mu= " << setprecision(6) << xmu << " Qzero= "<< setprecision(6) << Qzero ; if ((rep != "o") && (rep != "O" ) && (rep != "0") ) { sort << "\n#-----------------------------------" << "\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= xmu_temperature_ courbe4 " << "\n# Qzero= Qzero_temperature_ 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= xmu_temperature_ courbe4 " << "\n# Qzero= Qzero_temperature_ courbe3 " << "\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 on indique " << "\n# le mot cle: avec_parametres_de_reglage_ " << "\n# ensuite sur la ligne qui suit on peut indiquer en respectant l'ordre d'apparition: " << "\n# le type de resolution: par linearisation(1) (valeur par defaut) ou integration directe via Runge_Kutta(2)" << "\n# le nombre d'iteration (pour (1)), le nombre de dichotomie(pour (1)), " << "\n# la tolerance abolue et relative sur le residu(pour (1))" << "\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# le type de Runge_kutta (pour (2)): 3 pour une methode imbriquee 2-3, 4 pour 3-4, 5 pour 4-5, " << "\n# l'erreur absolue sur la contrainte finale(pour (2)), l'erreur relative sur la contrainte finale(pour (2)) " << "\n# le nombre maxi d'appel de la fonction derivee (sigma_point) (pour (2)) " << "\n# la tolerance sur la detection des coincidences," << "\n# NB: tous les parametres n'ont pas a etre presents, il en faut seulement 1 au minimum " << "\n# \n Exemple de declaration pour une resolution de l'equation linearisee: " << "\n#-------------------------------------------------------------------------" << "\n# ....... loi_de_comportement d'hysteresis 1D ........ |" << "\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_ " << " nb_iteration_maxi_ 20 nb_dichotomie_maxi_ 20 tolerance_residu_ 1.e-3 tolerance_residu_rel_ 1.e-5 " << " tolerance_coincidence_ 1.e-3 " << "\n# \n Exemple de declaration pour une resolution avec une methode de Runge_Kutta: " << "\n#-------------------------------------------------------------------------" << "\n# ....... loi_de_comportement d'hysteresis 1D ........ |" << "\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_ " << " type_de_resolution_ 2 " << " cas_kutta_ 5 erreurAbsolue_ 1.e-3 erreurRelative_ 1.e-5 nbMaxiAppel_ 100" << " tolerance_coincidence_ 1.e-3 nb_maxInvCoinSurUnPas_ 20 " << "\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# "; }; sort << endl; // appel de la classe mère Loi_comp_abstraite::Info_commande_don_LoisDeComp(entreePrinc); }; // test si la loi est complete int Hysteresis1D::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) && (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) && (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 Hysteresis1D::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 Hysteresis1D::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 { SaveResulHysteresis1D & save_resul = *((SaveResulHysteresis1D*) 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 SIGMA_REF: // c) ----- cas de la contrainte de référence actuelle { SaveResulHysteresis1D & save_resul = *((SaveResulHysteresis1D*) 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; } // e) ----- Q_sigma actuel de R à T case Q_SIG_HYST_R_A_T: { SaveResulHysteresis1D & save_resul = *((SaveResulHysteresis1D*) 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; } // i) ----- Q_delta_sig d'hystérésis case Q_DELTA_SIG_HYST: { SaveResulHysteresis1D & save_resul = *((SaveResulHysteresis1D*) 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: { SaveResulHysteresis1D & save_resul = *((SaveResulHysteresis1D*) 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: { SaveResulHysteresis1D & save_resul = *((SaveResulHysteresis1D*) 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: { SaveResulHysteresis1D & save_resul = *((SaveResulHysteresis1D*) 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: { SaveResulHysteresis1D & save_resul = *((SaveResulHysteresis1D*) 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: { SaveResulHysteresis1D & save_resul = *((SaveResulHysteresis1D*) 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: { SaveResulHysteresis1D & save_resul = *((SaveResulHysteresis1D*) 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 Hysteresis1D::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); }; }; // 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 }; }; // 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); }; }; // 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:================ // calcul des contraintes void Hysteresis1D::Calcul_SigmaHH (TenseurHH & sigHH_t,TenseurBB& ,DdlElement & tab_ddl, TenseurBB & ,TenseurHH & ,BaseB& ,BaseH& ,TenseurBB& epsBB_, TenseurBB& delta_epsBB_,TenseurBB & gijBB_, TenseurHH & gijHH_,Tableau & d_gijBB_,double& ,double& , TenseurHH & sigHH_ ,EnergieMeca & energ,const EnergieMeca & energ_t,double& module_compressibilite,double& module_cisaillement ,const Met_abstraite::Expli_t_tdt& ) { #ifdef MISE_AU_POINT if (epsBB_.Dimension() != 1) { cout << "\nErreur : la dimension devrait etre 3 !\n"; cout << " Hysteresis1D::Calcul_SigmaHH\n"; Sortie(1); }; if (tab_ddl.NbDdl() != d_gijBB_.Taille()) { cout << "\nErreur : le nb de ddl est != de la taille de d_gijBB_ !\n"; cout << " Hysteresis1D::Calcul_SigmaHH\n"; Sortie(1); }; #endif const Tenseur1BB & epsBB = *((Tenseur1BB*) &epsBB_); // passage en dim 1 const Tenseur1BB & delta_epsBB = *((Tenseur1BB*) &delta_epsBB_); // passage en dim 1 const Tenseur1HH & gijHH = *((Tenseur1HH*) &gijHH_); // " " " " const Tenseur1BB & gijBB = *((Tenseur1BB*) &gijBB_); // " " " " Tenseur1HH & sigHH = *((Tenseur1HH*) &sigHH_); // " " " " Tenseur1HH & sigHH_i = *((Tenseur1HH*) &sigHH_t); // " " " " SaveResulHysteresis1D & save_resul = *((SaveResulHysteresis1D*) saveResul); // initialisation des variables de travail save_resul.Init_debut_calcul(); // initialisation éventuelle des variables thermo-dépendantes Init_thermo_dependance(); // === 1 == calcul de l'avancement temporel sur 1 pas, Avancement_temporel(delta_epsBB,gijHH,save_resul,sigHH); LibereTenseur(); }; // calcul des contraintes a t+dt et de ses variations void Hysteresis1D::Calcul_DsigmaHH_tdt (TenseurHH & sigHH_t,TenseurBB& ,DdlElement & tab_ddl ,BaseB& ,TenseurBB & ,TenseurHH & , BaseB& ,Tableau & ,BaseH& ,Tableau & , TenseurBB & epsBB_tdt,Tableau & d_epsBB,TenseurBB & delta_epsBB_, TenseurBB & gijBB_tdt ,TenseurHH & gijHH_tdt, Tableau & d_gijBB_tdt, Tableau & d_gijHH_tdt,double& ,double& , Vecteur& ,TenseurHH& sigHH_tdt,Tableau & d_sigHH ,EnergieMeca & energ,const EnergieMeca & energ_t,double& module_compressibilite,double& module_cisaillement ,const Met_abstraite::Impli& ) { #ifdef MISE_AU_POINT if (epsBB_tdt.Dimension() != 1) { cout << "\nErreur : la dimension devrait etre 1 !\n"; cout << " Hysteresis1D::Calcul_DsigmaHH_tdt\n"; Sortie(1); }; if (tab_ddl.NbDdl() != d_gijBB_tdt.Taille()) { cout << "\nErreur : le nb de ddl est != de la taille de d_gijBB_tdt !\n"; cout << " Hysteresis1D::Calcul_DsigmaHH_tdt\n"; Sortie(1); }; #endif const Tenseur1BB & epsBB = *((Tenseur1BB*) &epsBB_tdt); // passage en dim 1 const Tenseur1BB & delta_epsBB = *((Tenseur1BB*) &delta_epsBB_); // passage en dim 1 const Tenseur1HH & gijHH = *((Tenseur1HH*) &gijHH_tdt); // " " " " const Tenseur1BB & gijBB = *((Tenseur1BB*) &gijBB_tdt); // " " " " Tenseur1HH & sigHH = *((Tenseur1HH*) &sigHH_tdt); // " " " " Tenseur1HH & sigHH_i = *((Tenseur1HH*) &sigHH_t); // " " " " SaveResulHysteresis1D & save_resul = *((SaveResulHysteresis1D*) saveResul); // initialisation des variables de travail save_resul.Init_debut_calcul(); // initialisation éventuelle des variables thermo-dépendantes Init_thermo_dependance(); // === 1 == calcul de l'avancement temporel sur 1 pas, Avancement_temporel(delta_epsBB,gijHH,save_resul,sigHH); // ==== 2 === calcul de l'opérateur tangent ============= TenseurQ1geneBHBH T_BHBH; Dsig_depsilon(T_BHBH); // ==== 3 === calcul de la variation de contrainte / au ddl // nombre de ddl pour la variation du tenseur des contraintes int nbddl = d_gijBB_tdt.Taille(); Tenseur1BH depsBH_dll; for (int i = 1; i<= nbddl; i++) { // on fait uniquement une égalité d'adresse de manière à ne pas utiliser // le constructeur d'ou la profusion d'* et de () Tenseur1HH & dsigHH = *((Tenseur1HH*) (d_sigHH(i))); // passage en dim 1 const Tenseur1BB & d_gijBB = *((Tenseur1BB*)(d_gijBB_tdt(i))); // passage en dim 1 const Tenseur1HH & dgijHH = *((Tenseur1HH*)(d_gijHH_tdt(i))) ; // pour simplifier l'ecriture const Tenseur1BB & depsBB = *((Tenseur1BB *) (d_epsBB(i))); // " depsBH_dll = (depsBB * gijHH + epsBB * dgijHH ); dsigHH = gijHH * (T_BHBH && depsBH_dll) + dgijHH * sigma_t_barre_tdt ; }; LibereTenseur(); }; //----- 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 Hysteresis1D::Lecture_base_info_loi(ifstream& ent,const int cas,LesReferences& lesRef,LesCourbes1D& lesCourbes1D ,LesFonctions_nD& lesFonctionsnD) { string toto; 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); }; // 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 >> tolerance_coincidence; ent >> nom >> type_resolution_equa_constitutive >> nom >> cas_kutta >> nom >> erreurAbsolue >> nom >> erreurRelative; ent >> nom >> nb_maxInvCoinSurUnPas; // 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 Hysteresis1D::Ecriture_base_info_loi(ofstream& sort,const int cas) { if (cas == 1) { sort << " HYSTERESIS_1D "; sort << " param_prager_(np) "; if (xnp_temperature == NULL) { sort << false << " " << xnp << " ";} 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 << " ";} 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 << " ";} else { sort << true << " fonction_xmu_temperature "; LesCourbes1D::Ecriture_pour_base_info(sort,cas,xmu_temperature); }; 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 << " tolerance_coincidence " << tolerance_coincidence; sort << "\n type_resolution_equa_constitutive " << type_resolution_equa_constitutive << " cas_kutta " << cas_kutta << " erreurAbsolue " << erreurAbsolue << " erreurRelative " << erreurRelative << " "; sort << " nb_maxInvCoinSurUnPas " << nb_maxInvCoinSurUnPas ; // 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); };