// FICHIER : LoiCritere.cp // CLASSE : LoiCritere // 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-2021 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 "LesLoisDeComp.h" # include using namespace std; //introduces namespace std #include #include #include "Sortie.h" #include "TypeConsTens.h" #include "TypeQuelconqueParticulier.h" #include "NevezTenseurQ.h" #include "LoiCritere.h" #include "LoiContraintesPlanesDouble.h" #include "LoiContraintesPlanes.h" #include "Util.h" #include "CharUtil.h" //==================== cas de la class de sauvegarde SaveResul =================== // constructeur par défaut à ne pas utiliser LoiCritere::SaveResul_LoiCritere::SaveResul_LoiCritere() : liste_des_SaveResul() ,l_sigoHH(),l_sigoHH_t(),l_energ(),l_energ_t(),f_ponder(),f_ponder_t() ,V_P_sig(NULL),V_P_sig_t(NULL),save_result_1DCP2(NULL) ,eps_pli(),eps_pli_t(),niveau_declenchement_critere(-ConstMath::petit) ,le_type_critere(AUCUN_CRITERE) ,cas_cal_plis(0),cas_cal_plis_t(0) ,map_type_quelconque() { cout << "\n erreur, le constructeur par defaut ne doit pas etre utilise !" << "\n LoiCritere::SaveResul_LoiCritere::SaveResul_LoiCritere()"; cout << "\n LoiCritere::SaveResul_LoiCritere::SaveResul_LoiCritere()"; Sortie(1); }; // le constructeur courant LoiCritere::SaveResul_LoiCritere::SaveResul_LoiCritere (list & l_des_SaveResul,list & l_siHH ,list & l_siHH_t ,list & l_energ_,list & l_energ_t_ ,bool avec_ponderation,Enum_Critere_Loi type_crite): liste_des_SaveResul() ,l_sigoHH(),l_sigoHH_t(),l_energ(l_energ_),l_energ_t(l_energ_t_) ,f_ponder(),f_ponder_t(),V_P_sig(NULL),V_P_sig_t(NULL),save_result_1DCP2(NULL) ,eps_pli(),eps_pli_t(),niveau_declenchement_critere(-ConstMath::petit) ,le_type_critere(type_crite) ,cas_cal_plis(0),cas_cal_plis_t(0) ,map_type_quelconque() { list ::const_iterator ili,ilifin=l_des_SaveResul.end(); list ::const_iterator isig,isig_t; for (ili=l_des_SaveResul.begin(),isig = l_siHH.begin(),isig_t = l_siHH_t.begin(); ili!=ilifin;ili++,isig++,isig_t++) { SaveResul * nevez_save_result=NULL; if ((*ili) != NULL) nevez_save_result = (*ili)->Nevez_SaveResul(); liste_des_SaveResul.push_back(nevez_save_result); TenseurHH * interHH=NULL; // dans le cas où le tenseur passé en paramètre est non null on s'en sert if ((*isig) != NULL) {interHH=NevezTenseurHH(*(*isig));}; l_sigoHH.push_back(interHH); TenseurHH * interHH_t=NULL; // idem interHH, dans le cas où le tenseur passé en paramètre est non null on s'en sert if ((*isig_t) != NULL) {interHH_t =NevezTenseurHH(*(*isig_t));}; l_sigoHH_t.push_back(interHH_t); if (avec_ponderation) // on fait de la place {f_ponder.push_back(1.);f_ponder_t.push_back(1.);}; }; }; // constructeur de copie LoiCritere::SaveResul_LoiCritere::SaveResul_LoiCritere (const LoiCritere::SaveResul_LoiCritere& sav ): liste_des_SaveResul() ,l_sigoHH(),l_sigoHH_t() ,l_energ(sav.l_energ),l_energ_t(sav.l_energ_t) ,f_ponder(sav.f_ponder),f_ponder_t(sav.f_ponder_t),V_P_sig(NULL),V_P_sig_t(NULL) ,save_result_1DCP2(NULL) ,eps_pli(sav.eps_pli),eps_pli_t(sav.eps_pli_t) ,niveau_declenchement_critere(sav.niveau_declenchement_critere) ,le_type_critere(sav.le_type_critere) ,cas_cal_plis(sav.cas_cal_plis),cas_cal_plis_t(sav.cas_cal_plis_t) ,map_type_quelconque(sav.map_type_quelconque) { list ::const_iterator ili,ilifin=sav.liste_des_SaveResul.end(); list ::const_iterator isig,isig_t; for (ili=sav.liste_des_SaveResul.begin(),isig = sav.l_sigoHH.begin(),isig_t = sav.l_sigoHH_t.begin(); ili!=ilifin;ili++,isig++,isig_t++) { SaveResul * nevez_save_result = NULL; if ((*ili) != NULL) nevez_save_result = (*ili)->Nevez_SaveResul(); liste_des_SaveResul.push_back(nevez_save_result); TenseurHH * interHH=NULL; // dans le cas où le tenseur passé en paramètre est non null on s'en sert if ((*isig) != NULL) {interHH=NevezTenseurHH(*(*isig));}; l_sigoHH.push_back(interHH); TenseurHH * interHH_t=NULL; // idem interHH, dans le cas où le tenseur passé en paramètre est non null on s'en sert if ((*isig_t) != NULL) {interHH_t =NevezTenseurHH(*(*isig_t));}; l_sigoHH_t.push_back(interHH_t); }; // les vecteurs propres éventuelles if (sav.V_P_sig != NULL) V_P_sig = new Tableau < Coordonnee >(*(sav.V_P_sig)); if (sav.V_P_sig_t != NULL) V_P_sig_t = new Tableau < Coordonnee >(*(sav.V_P_sig_t)); // le pointeur de travail pour les plis if (sav.save_result_1DCP2 != NULL) { SaveResul * inter = sav.save_result_1DCP2->Nevez_SaveResul(); save_result_1DCP2 = ((LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble*) inter); }; }; // destructeur LoiCritere::SaveResul_LoiCritere::~SaveResul_LoiCritere() { list ::iterator ili,ilifin=liste_des_SaveResul.end(); list ::iterator isig,isig_t; for (ili=liste_des_SaveResul.begin(),isig = l_sigoHH.begin(),isig_t = l_sigoHH_t.begin(); ili!=ilifin;ili++,isig++,isig_t++) {if ((*ili) != NULL) delete (*ili); //liste_des_SaveResul.erase(ili); if((*isig) != NULL) delete (*isig); if((*isig_t) != NULL) delete (*isig_t); }; // car des vecteurs propres de contrainte if (V_P_sig != NULL) delete V_P_sig; if (V_P_sig_t != NULL) delete V_P_sig_t; if (save_result_1DCP2 != NULL) delete save_result_1DCP2; }; // affectation Loi_comp_abstraite::SaveResul & LoiCritere::SaveResul_LoiCritere::operator = ( const Loi_comp_abstraite::SaveResul & a) { LoiCritere::SaveResul_LoiCritere& sav = *((LoiCritere::SaveResul_LoiCritere*) &a); // on regarde si les listes sont de même tailles, si oui on considère qu'elle sont des conteneurs identiques // sinon on les crée list ::const_iterator ili,ilifin=sav.liste_des_SaveResul.end(); list ::const_iterator isig = sav.l_sigoHH.begin(); list ::const_iterator isig_t = sav.l_sigoHH_t.begin(); if (liste_des_SaveResul.size() != sav.liste_des_SaveResul.size()) {// 1) on vide la liste: tout d'abord les grandeurs pointées sont supprimées list ::iterator jli,jlifin=liste_des_SaveResul.end(); list ::iterator jsig = l_sigoHH.begin(); list ::iterator jsig_t = l_sigoHH_t.begin(); for (jli=liste_des_SaveResul.begin();jli!=jlifin;jli++,jsig++,jsig_t++) {if ((*jli) != NULL) delete (*jli); //liste_des_SaveResul.erase(ili); if((*jsig) != NULL) delete (*jsig); if((*jsig_t) != NULL) delete (*jsig_t); }; // on vide les listes liste_des_SaveResul.clear();l_sigoHH.clear();l_sigoHH_t.clear(); // 2) on recrée à la bonne taille for (ili=sav.liste_des_SaveResul.begin(),isig = sav.l_sigoHH.begin(),isig_t = sav.l_sigoHH_t.begin(); ili!=ilifin;ili++,isig++,isig_t++) { SaveResul * nevez_save_result = NULL; if ((*ili) != NULL) nevez_save_result = (*ili)->Nevez_SaveResul(); liste_des_SaveResul.push_back(nevez_save_result); TenseurHH * interHH=NULL; // dans le cas où le tenseur passé en paramètre est non null on s'en sert if ((*isig) != NULL) {interHH=NevezTenseurHH(*(*isig));}; l_sigoHH.push_back(interHH); TenseurHH * interHH_t=NULL; // idem interHH, dans le cas où le tenseur passé en paramètre est non null on s'en sert if ((*isig_t) != NULL) {interHH_t =NevezTenseurHH(*(*isig_t));}; l_sigoHH_t.push_back(interHH_t); }; } else // sinon on affecte les conteneurs { list ::iterator jli=liste_des_SaveResul.begin(); list ::iterator jsig=l_sigoHH.begin(); list ::iterator jsig_t=l_sigoHH_t.begin(); for (ili=sav.liste_des_SaveResul.begin(),isig = sav.l_sigoHH.begin(),isig_t = sav.l_sigoHH_t.begin(); ili!=ilifin;ili++,isig++,isig_t++,jli++,jsig++,jsig_t++) { (*(*jli))=(*(*ili)); (*(*jsig))=(*(*isig));(*(*jsig_t))=(*(*isig_t));}; }; // les vecteurs propres éventuelles if (sav.V_P_sig != NULL) { if (V_P_sig == NULL) { V_P_sig = new Tableau < Coordonnee >(*(sav.V_P_sig));} else {*V_P_sig = *(sav.V_P_sig);}; } else // les vecteurs sont nulles donc on supprime { if (V_P_sig != NULL) {delete V_P_sig; V_P_sig=NULL;}; }; if (sav.V_P_sig_t != NULL) { if (V_P_sig_t == NULL) { V_P_sig_t = new Tableau < Coordonnee >(*(sav.V_P_sig_t));} else {*V_P_sig_t = *(sav.V_P_sig_t);}; } else // les vecteurs sont nulles donc on supprime {if (V_P_sig_t != NULL) {delete V_P_sig_t; V_P_sig_t=NULL;}; }; // le pointeur de travail pour les plis if (sav.save_result_1DCP2 != NULL) {if (save_result_1DCP2 == NULL) { SaveResul * inter = sav.save_result_1DCP2->Nevez_SaveResul(); save_result_1DCP2 = ((LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble*) inter); } else // sinon on peut affecter directement { *save_result_1DCP2 = *((Loi_comp_abstraite::SaveResul *) sav.save_result_1DCP2); }; } else { if (save_result_1DCP2 != NULL) {delete save_result_1DCP2;save_result_1DCP2=NULL;}; }; // // pour les autres conteneurs internes, affectation directe, car a priori pas de pb l_energ = sav.l_energ; l_energ_t = sav.l_energ_t; f_ponder = sav.f_ponder; eps_pli = sav.eps_pli; eps_pli_t = sav.eps_pli_t; // le niveau de déclenchement niveau_declenchement_critere = sav.niveau_declenchement_critere; le_type_critere = sav.le_type_critere; cas_cal_plis = sav.cas_cal_plis; cas_cal_plis_t = sav.cas_cal_plis_t; map_type_quelconque = sav.map_type_quelconque; 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 LoiCritere::SaveResul_LoiCritere::Lecture_base_info (ifstream& ent,const int cas) { // ici toutes les données sont toujours a priori variables // ou en tout cas pour les méthodes appelées, elles sont gérées par le paramètre: cas string toto; ent >> toto; #ifdef MISE_AU_POINT if (toto != "S_R_LoiCrit") { cout << "\n erreur en lecture du conteneur pour la loi critere" << " \n LoiCritere::SaveResul_LoiCritere::Lecture_base_info(.."; Sortie(1); } #endif // niveau du critère ent >> toto >> niveau_declenchement_critere; ent >> toto >> le_type_critere; // indicateur concernant le calcul des directions de plis ent >> toto >> cas_cal_plis_t; cas_cal_plis = cas_cal_plis_t; // on regarde s'il s'agit d'une lecture avec fonction de pondération ou non bool avec_ponderation=false; ent >> toto >> avec_ponderation; // lecture du nombre de loi int nb_loi; ent >> toto >> nb_loi; // Dans le cas où le nombre de loi n'est pas identique au cas actuel // cela signifie que l'instance est mal déclaré -> pb on arrête // sinon on lit uniquement #ifdef MISE_AU_POINT if (nb_loi != liste_des_SaveResul.size()) { cout << "\n erreur en lecture du conteneur pour la loi critere, cas des infos specifiques a chaque loi" << "\n le nombre de loi definit est different de celui lu donc il y a un pb d'initialisation" << " \n LoiCritere::SaveResul_LoiCritere::Lecture_base_info(.."; Sortie(1); }; #endif // on vérifie que la taille de f_ponder_t est correcte, sinon on redimentionne if (avec_ponderation) {if (f_ponder_t.size() != nb_loi) {// on efface les listes list ::iterator ieefin=f_ponder.end(); list ::iterator ieedeb=f_ponder.begin(); f_ponder.erase(ieedeb,ieefin); f_ponder.insert(ieedeb,nb_loi,1.); ieefin=f_ponder_t.end(); ieedeb=f_ponder_t.begin(); f_ponder_t.erase(ieedeb,ieefin); // on les définit la place f_ponder_t.insert(ieedeb,nb_loi,1.); }; }; // on itère sur ces grandeurs list ::iterator ili,ilifin=liste_des_SaveResul.end(); list ::iterator isig_t; list ::iterator ienerg_t=l_energ_t.begin(); string nom_num_loi;int num_loi; list ::iterator ifo; if (avec_ponderation) ifo = f_ponder_t.begin(); for (ili=liste_des_SaveResul.begin(),isig_t = l_sigoHH_t.begin(); ili!=ilifin;ili++,isig_t++,ienerg_t++) { ent >> nom_num_loi>>num_loi; if (avec_ponderation) { ent >> (*ifo); ifo++;}; // données de chaque loi if((*ili) != NULL) (*ili)->Lecture_base_info(ent,cas); // lecture de la contrainte sauvegardée (*isig_t)->Lecture(ent); // lecture du tenseur // lecture des énergies ent >> (*ienerg_t); }; // cas des directions des vecteurs propres int test; ent >> toto >> test; if (test) { // cas de l'existence de vecteurs propres if (V_P_sig_t == NULL) V_P_sig_t = new Tableau ; if (V_P_sig == NULL) V_P_sig = new Tableau ; ent >> (*V_P_sig_t); (*V_P_sig)=(*V_P_sig_t); } else { // cas où il n'y a pas de vecteurs propres en sauvegarde if (V_P_sig_t != NULL) {delete V_P_sig_t; V_P_sig_t=NULL;}; if (V_P_sig != NULL) { delete V_P_sig; V_P_sig=NULL;}; }; // cas des plis ent >> toto >> eps_pli_t; eps_pli=eps_pli_t; }; // cas donne le niveau de sauvegarde // = 1 : on sauvegarde tout // = 2 : on sauvegarde uniquement les données variables (supposées comme telles) void LoiCritere::SaveResul_LoiCritere::Ecriture_base_info (ofstream& sort,const int cas) { // ici toutes les données sont toujours a priori variables // ou en tout cas pour les méthodes appelées, elles sont gérées par le paramètre: cas sort << "\n S_R_LoiCrit "; // niveau du critère sort << "\n niv_declenche_= " << niveau_declenchement_critere ; sort << "\n type_de_critere= " << le_type_critere; // indicateur concernant le calcul des directions de plis sort << " cas_cal_plis= "<< cas_cal_plis_t ; // pondération ? bool avec_ponderation = (f_ponder_t.size() != 0); sort << " Pond= "<< avec_ponderation << " "; // on sort le nombre de grandeur à sauvegarde sort << "nbS= "<< liste_des_SaveResul.size(); // on itère sur ces grandeurs list ::iterator ili,ilifin=liste_des_SaveResul.end(); list ::iterator isig_t; int nb_loi=1; list ::iterator ienerg_t=l_energ_t.begin(); list ::iterator ifo; if (avec_ponderation) ifo=f_ponder_t.begin(); for (ili=liste_des_SaveResul.begin(),isig_t = l_sigoHH_t.begin();ili!=ilifin; ili++,isig_t++,nb_loi++,ienerg_t++) { // données de chaque loi sort << "\n --loi_nb " << nb_loi << " "; // les pondérations éventuelles if (avec_ponderation) { sort << " " << (*ifo) << " "; ifo++; }; if ((*ili) != NULL) (*ili)->Ecriture_base_info(sort,cas);sort << " "; // la contrainte sauvegardée est celle stable uniquement (*isig_t)->Ecriture(sort); // écriture du tenseur sort << " " << (*ienerg_t); }; // cas des directions des vecteurs propres if (V_P_sig_t == NULL) {sort << " V_P_sig= 0 ";} else {sort << " V_P_sig= 1 "<< (*V_P_sig_t)<<" ";}; // cas des plis sort << "\n eps_pli= " << eps_pli_t; }; // mise à jour des informations transitoires en définitif s'il y a convergence // par exemple (pour la plasticité par exemple) void LoiCritere::SaveResul_LoiCritere::TdtversT() {list ::iterator ili,ilifin=liste_des_SaveResul.end(); list ::iterator isig_t,isig; list ::iterator ienerg,ienerg_t; bool avec_ponderation = (f_ponder_t.size() != 0); list ::iterator ifo,ifo_t; if (avec_ponderation) {ifo=f_ponder.begin();ifo_t=f_ponder_t.begin();}; for (ili=liste_des_SaveResul.begin(),isig_t = l_sigoHH_t.begin(),isig = l_sigoHH.begin() ,ienerg=l_energ.begin(),ienerg_t=l_energ_t.begin(); ili!=ilifin;ili++,isig_t++,isig++,ienerg++,ienerg_t++) {// dans le cas d'un critère plis, on a utiliser un conteneur intermédiaire: // il faut mettre à jour le conteneur 3D à minima avec les résultats du calcul 1D // *** pour l'instant il n'y a rien de fait donc cela signifie, que le save_result de la loi 3D // correspond à celui du comportement sans plis. // ça c'est ok s'il n'y a finalement pas de plis, mais pas du tout ok, s'il y a des plis // avec une loi incrémental de type hystérésis, c'est catastrophique !! //$$$$$$$$$$$$$$$$ il faut changer $$$$$$$$$$$$$$$$$$ if ((*ili) != NULL) (*ili)->TdtversT(); (*(*isig_t)) = (*(*isig)); (*ienerg_t)=(*ienerg); if (avec_ponderation) {(*ifo_t) = (*ifo); ifo++; ifo_t++; }; }; // cas des directions des vecteurs propres if (V_P_sig != NULL) { // cas de l'existence de vecteurs propres if (V_P_sig_t == NULL) V_P_sig_t = new Tableau ; (*V_P_sig_t)=(*V_P_sig); } else { // cas où il n'y a pas de vecteurs propres en sauvegarde if (V_P_sig_t != NULL) {delete V_P_sig_t; V_P_sig_t=NULL;}; }; // cas des plis eps_pli_t = eps_pli; cas_cal_plis_t = cas_cal_plis; // mise à jour de la liste des grandeurs quelconques internes Mise_a_jour_map_type_quelconque(); }; void LoiCritere::SaveResul_LoiCritere::TversTdt() {list ::iterator ili,ilifin=liste_des_SaveResul.end(); list ::iterator isig_t,isig; list ::iterator ienerg,ienerg_t; bool avec_ponderation = (f_ponder_t.size() != 0); list ::iterator ifo,ifo_t; if (avec_ponderation) {ifo=f_ponder.begin();ifo_t=f_ponder_t.begin();}; for (ili=liste_des_SaveResul.begin(),isig_t = l_sigoHH_t.begin(),isig = l_sigoHH.begin() ,ienerg=l_energ.begin(),ienerg_t=l_energ_t.begin(); ili!=ilifin;ili++,isig_t++,isig++,ienerg++,ienerg_t++) { if ((*ili) != NULL) (*ili)->TversTdt(); (*(*isig)) = (*(*isig_t)); (*ienerg)=(*ienerg_t); if (avec_ponderation) {(*ifo) = (*ifo_t); ifo++; ifo_t++; }; }; // cas des directions des vecteurs propres if (V_P_sig_t != NULL) { // cas de l'existence de vecteurs propres if (V_P_sig == NULL) V_P_sig = new Tableau ; (*V_P_sig)=(*V_P_sig_t); } else { // cas où il n'y a pas de vecteurs propres en sauvegarde if (V_P_sig != NULL) {delete V_P_sig; V_P_sig=NULL;}; }; // cas des plis eps_pli = eps_pli_t; cas_cal_plis = cas_cal_plis_t; // mise à jour de la liste des grandeurs quelconques internes Mise_a_jour_map_type_quelconque(); }; // affichage à l'écran des infos void LoiCritere::SaveResul_LoiCritere::Affiche() const { cout << "\n SaveResul_LoiCritere: " ; list ::const_iterator ili,ilifin=liste_des_SaveResul.end(); list ::const_iterator isig,isigfin=l_sigoHH.end(); list ::const_iterator isig_t,isig_tfin=l_sigoHH_t.end(); list ::const_iterator ienerg,ienergfin = l_energ.end(); list ::const_iterator ienerg_t,ienerg_tfin = l_energ_t.end(); list ::const_iterator i_ponder, i_ponderfin = f_ponder.end(); list ::const_iterator i_ponder_t,i_ponder_tfin = f_ponder_t.end(); cout << "\n -- partie relative aux lois internes: "; cout << "\n liste_des_SaveResul: "; int i=1; for (ili=liste_des_SaveResul.begin();ili!=ilifin;ili++,i++) {cout << "\n loi nb: " << i <<" "; if ((*ili) != NULL) { (*ili)->Affiche();}; }; cout << "\n -- partie specifique loi critere: "; cout << "\n l_sigoHH: "; for (isig = l_sigoHH.begin();isig!=isigfin;isig++) { (*isig)->Ecriture(cout);}; cout << "\n l_sigoHH_t: "; for (isig_t = l_sigoHH_t.begin();isig_t!=isig_tfin;isig_t++) { (*isig_t)->Ecriture(cout);}; cout << "\n l_energ: "; for (ienerg = l_energ.begin();ienerg!=ienergfin;ienerg++) { cout << (*ienerg);}; cout << "\n l_energ_t: "; for (ienerg_t = l_energ_t.begin();ienerg_t!=ienerg_tfin;ienerg_t++) { cout << (*ienerg_t);}; cout << "\n f_ponder: "; for (i_ponder = f_ponder.begin();i_ponder!=i_ponderfin;i_ponder++) { cout << " " << (*i_ponder);}; cout << "\n f_ponder_t: "; for (i_ponder_t = f_ponder_t.begin();i_ponder_t!=i_ponder_tfin;i_ponder_t++) { cout << " " << (*i_ponder_t);}; // cas d'existence et sauvegarde de vecteurs propres de contrainte if (V_P_sig != NULL) cout << "\n V_P_sig= " << (*V_P_sig)<<" "; // cas du pointeur 1D de plis if (save_result_1DCP2 != NULL) {cout << "\n conteneur1D_pour plis: "; save_result_1DCP2->Affiche(); }; // cas des plis cout << "\n eps_pli= " << eps_pli_t; // déclenchement du critère cout << "\n niveau_declenchement_critere= "<::iterator lit(liste_des_SaveResul.begin()), lend(liste_des_SaveResul.end()); for(;lit!=lend;++lit) // ici les bornes ne changent pas if ((*lit) != NULL) // s'il y a un conteneur non nul (*lit)->ChBase_des_grandeurs(beta,gamma); }; { List_io ::iterator lit(l_sigoHH.begin()), lend(l_sigoHH.end()); for(;lit!=lend;++lit) // ici les bornes ne changent pas (*lit)->ChBase(gamma); }; { List_io ::iterator lit(l_sigoHH_t.begin()), lend(l_sigoHH_t.end()); for(;lit!=lend;++lit) // ici les bornes ne changent pas (*lit)->ChBase(gamma); }; // les vecteurs donnant les directions principales sont exprimés dans la base orthonormee // ils ne sont pas concernés par cette méthode ! }; // procedure permettant de completer éventuellement les données particulières // de la loi stockées // au niveau du point d'intégration par exemple: exemple: un repère d'anisotropie // completer est appelé apres sa creation avec les donnees du bloc transmis // peut etre appeler plusieurs fois Loi_comp_abstraite::SaveResul* LoiCritere::SaveResul_LoiCritere ::Complete_SaveResul(const BlocGen & bloc, const Tableau & tab_coor ,const Loi_comp_abstraite* loi) {// on transmet au conteneur 3D interne const LoiCritere * loi_CP = (const LoiCritere*) loi; // récup de la liste de loi list ::const_iterator ili,ilifin=loi_CP->lois_internes.end(); // récup des infos pour chaque loi list ::iterator ia=liste_des_SaveResul.begin(); for (ili = loi_CP->lois_internes.begin(); ili != ilifin; ili++,ia++) {// on intervient que si le conteneur n'est pas vide if ((*ia)!= NULL) (*ia)->Complete_SaveResul(bloc,tab_coor,(*ili)); }; return this; }; // ---- récupération d'information: spécifique à certaine classe dérivée double LoiCritere::SaveResul_LoiCritere::Deformation_plastique() { cout << "\n pour l'instant cette option n'est pas implante dans le cas d'une loi" << "\n additive en contrainte" << "\n double Loi_comp_abstraite::SaveResul_LoiCritere::Deformation_plastique()"; Sortie(1); return 0.; // pour taire le warning, mais on ne passe jamais là }; // mise à jour de la liste des grandeurs quelconques internes void LoiCritere::SaveResul_LoiCritere::Mise_a_jour_map_type_quelconque() { map < EnumTypeQuelconque , TypeQuelconque, std::less < EnumTypeQuelconque> >::iterator il ,ilfin=map_type_quelconque.end(); int dim_espace = ParaGlob::Dimension(); for (il=map_type_quelconque.begin();il != ilfin;il++) {EnumTypeQuelconque enu = (*il).first; switch (enu) {// -----cas de la direction de pli éventuelle case DIRECTION_PLI: { Tab_Grandeur_Coordonnee& gr= *((Tab_Grandeur_Coordonnee*) map_type_quelconque[DIRECTION_PLI].Grandeur_pointee()); // pour simplifier switch (le_type_critere) { case PLISSEMENT_MEMBRANE: {// tout d'abord on regarde s'il y des vecteurs propres if (((cas_cal_plis == 2)|| (cas_cal_plis == 3)) && (V_P_sig != NULL)) // cas où il y a des vecteurs propres, la direction des plis est le premier vecteur, + éventuellement // le deuxième s'il y a deux plis { gr(1) = eps_pli(1) * (*V_P_sig)(1); gr(2) = eps_pli(2) * (*V_P_sig)(2); } else // sinon cela veut dire qu'il n'y a pas de pli, on sort un vecteur nul {Coordonnee coor(dim_espace); // un type coordonnee typique gr(1) = coor; gr(2) = coor; }; break; } case PLISSEMENT_BIEL: {// tout d'abord on regarde s'il y des vecteurs propres if (V_P_sig != NULL) // cas où il y a des vecteurs propres, la direction des plis est le premier vecteur, + éventuellement // le deuxième s'il y a deux plis {gr(1) = eps_pli(1) * (*V_P_sig)(1); Coordonnee coor(dim_espace); gr(2) = coor; } else // sinon cela veut dire qu'il n'y a pas de pli, on sort un vecteur nul {Coordonnee coor(dim_espace); // un type coordonnee typique gr(1) = coor; gr(2) = coor; }; break; } default : cout << "\nErreur : valeur non prise en compte du type de critere defini= " << le_type_critere << " !\n"; cout << "\n LoiCritere::SaveResul_LoiCritere::Mise_a_jour_map_type_quelconque(..."; Sortie(1); }; break; } case INDIC_CAL_PLIS: { Grandeur_scalaire_entier& gr= *((Grandeur_scalaire_entier*) map_type_quelconque[DIRECTION_PLI].Grandeur_pointee()); // pour simplifier switch (le_type_critere) { case PLISSEMENT_MEMBRANE: case PLISSEMENT_BIEL: // pour les biels on ne sait pas encore !! {*(gr.ConteneurEntier()) = cas_cal_plis; break; } default : cout << "\nErreur : valeur non prise en compte du type de critere defini= " << le_type_critere << " !\n"; cout << "\n LoiCritere::SaveResul_LoiCritere::Mise_a_jour_map_type_quelconque(..."; Sortie(1); }; break; } default:; // on ne fait rien sinon }; }; }; //==================== fin du cas de la class de sauvegarde SaveResul ============ LoiCritere::LoiCritere () : // Constructeur par defaut Loi_comp_abstraite(LOI_CRITERE,RIEN_CATEGORIE_LOI_COMP,0) ,type_critere(AUCUN_CRITERE),lois_internes() ,list_completude_calcul(),d_sigma_deps_inter(NULL),d_sig_deps_3D_HHHH() ,avec_ponderation(false),list_ponderation(),fonc_ponder(),type_calcul(1) ,d_sigtotalHH() ,ordre_criteres() // -- pour PLISSEMENT_MEMBRANE ,loi_2DCP_de_3D(NULL),loi_1DCP2_de_3D(NULL),niveau_declenchement_critere(-ConstMath::petit) ,avecNiveauSigmaI_mini_pour_plis(false) ,niveauF_fct_nD(NULL),niveauF_grandeurConsultable(NULL) ,niveauF_ddlEtendu(NULL),niveauF_temps(NULL) ,choix_calcul_epaisseur_si_relachement_complet(1),recalcul_dir_plis(NULL) // -- pour RUPTURE_SIGMA_PRINC et RUPTURE_EPS_PRINC ,loi_2DCP_pour_rupture(NULL),loi_1DCP2_pour_rupture(NULL) // -- grandeurs de travail // un conteneur d'un point d'intégration courant ,ptintmeca(3) // métriques ,giB_0_1D(3,1),giH_0_1D(3,1),giB_t_1D(3,1),giH_t_1D(3,1),giB_tdt_1D(3,1),giH_tdt_1D(3,1) ,gijBB_0_1D(),gijHH_0_1D(),gijBB_t_1D(),gijHH_t_1D(),gijBB_tdt_1D(),gijHH_tdt_1D() ,gradVmoyBB_t_1D_P(NULL),gradVmoyBB_t_1D() ,gradVmoyBB_tdt_1D_P(NULL),gradVmoyBB_tdt_1D() ,gradVBB_tdt_1D_P(NULL),gradVBB_tdt_1D() ,jacobien_tdt_1D(0.),jacobien_t_1D(0.),jacobien_0_1D(0.),d_jacobien_tdt_1D() ,d_giB_tdt_1D(),d_giH_tdt_1D(),d_gijBB_tdt_1D_P(NULL),d_gijBB_tdt_1D() ,d2_gijBB_tdt_1D_P(NULL),d2_gijBB_tdt_1D() ,d_gijHH_tdt_1D_P(NULL),d_gijHH_tdt_1D() ,d_gradVmoyBB_t_1D_P(NULL),d_gradVmoyBB_t_1D() ,d_gradVmoyBB_tdt_1D_P(NULL),d_gradVmoyBB_tdt_1D() ,d_gradVBB_t_1D_P(NULL),d_gradVBB_t_1D() ,d_gradVBB_tdt_1D_P(NULL),d_gradVBB_tdt_1D() ,sig_HH_t_1D(),sig_HH_1D(),Deps_BB_1D(),eps_BB_1D(),delta_eps_BB_1D() ,d_eps_BB_1D_P(),d_eps_BB_1D(),d_sig_HH_1D_P(NULL),d_sig_HH_1D() ,d_sigma_deps_1D_P(NULL),d_sigma_deps_1D() ,eps_BB_2D_t(),delta_eps_BB_2D(),eps_HH_2D_t() ,ViB(ParaGlob::Dimension(),ParaGlob::Dimension()),ViH(ParaGlob::Dimension(),ParaGlob::Dimension()) // puis les grandeurs hors métriques ,sig_HH_t_3D(),sig_HH_3D(),Deps_BB_3D(),eps_BB_3D(),delta_eps_BB_3D() // paramètres ,choix_methode_cal_plis_memb(1) { // conteneurs des métriques // a priori seules les grandeurs principales sont affecté expli_1D = new Met_abstraite::Expli_t_tdt // constructeur normal (&giB_0_1D,&giH_0_1D,&giB_t_1D,&giH_t_1D,&giB_tdt_1D,&giH_tdt_1D ,&gijBB_0_1D,&gijHH_0_1D,&gijBB_t_1D,&gijHH_t_1D ,&gijBB_tdt_1D,&gijHH_tdt_1D ,gradVmoyBB_t_1D_P,gradVmoyBB_tdt_1D_P,gradVBB_tdt_1D_P // pas affecté par défaut ,&d_gijBB_tdt_1D_P,&jacobien_tdt_1D,&jacobien_t_1D,&jacobien_0_1D); impli_1D = new Met_abstraite::Impli // constructeur normal (&giB_0_1D,&giH_0_1D,&giB_t_1D,&giH_t_1D,&giB_tdt_1D,&d_giB_tdt_1D,&giH_tdt_1D,&d_giH_tdt_1D ,&gijBB_0_1D,&gijHH_0_1D,&gijBB_t_1D,&gijHH_t_1D,&gijBB_tdt_1D,&gijHH_tdt_1D ,gradVmoyBB_t_1D_P,gradVmoyBB_tdt_1D_P,gradVBB_tdt_1D_P // pas affecté par défaut ,&d_gijBB_tdt_1D_P ,d2_gijBB_tdt_1D_P // pas affecté par défaut ,&d_gijHH_tdt_1D_P ,&jacobien_tdt_1D,&jacobien_t_1D,&jacobien_0_1D,&d_jacobien_tdt_1D ,d_gradVmoyBB_t_1D_P,d_gradVmoyBB_tdt_1D_P // pas affecté par défaut ,d_gradVBB_t_1D_P,d_gradVBB_tdt_1D_P); // pas affecté par défaut umat_cont_1D = new Met_abstraite::Umat_cont // constructeur normal (&giB_0_1D,&giH_0_1D,&giB_t_1D,&giH_t_1D,&giB_tdt_1D,&giH_tdt_1D ,&gijBB_0_1D,&gijHH_0_1D,&gijBB_t_1D,&gijHH_t_1D ,&gijBB_tdt_1D,&gijHH_tdt_1D ,gradVmoyBB_t_1D_P,gradVmoyBB_tdt_1D_P,gradVBB_tdt_1D_P // pas affecté par défaut ,&jacobien_tdt_1D,&jacobien_t_1D,&jacobien_0_1D); // on ajoute les invariants au pt integ courant ptintmeca.Change_statut_Invariants_contrainte (true); d_sigma_deps_1D_P = & d_sigma_deps_1D; }; // Constructeur de copie LoiCritere::LoiCritere (const LoiCritere& loi) : Loi_comp_abstraite(loi),lois_internes() ,type_critere(loi.type_critere),list_completude_calcul(),d_sigma_deps_inter(NULL) ,d_sig_deps_3D_HHHH(loi.d_sig_deps_3D_HHHH) ,avec_ponderation(loi.avec_ponderation),list_ponderation(loi.list_ponderation) ,fonc_ponder(loi.fonc_ponder),type_calcul(loi.type_calcul),d_sigtotalHH() ,ordre_criteres(loi.ordre_criteres) // -- pour PLISSEMENT_MEMBRANE ,loi_2DCP_de_3D(NULL),loi_1DCP2_de_3D(NULL) ,niveau_declenchement_critere(loi.niveau_declenchement_critere) ,avecNiveauSigmaI_mini_pour_plis(loi.avecNiveauSigmaI_mini_pour_plis) ,niveauF_fct_nD(NULL),niveauF_grandeurConsultable(NULL) ,niveauF_ddlEtendu(NULL),niveauF_temps(loi.niveauF_temps) ,choix_calcul_epaisseur_si_relachement_complet(loi.choix_calcul_epaisseur_si_relachement_complet) ,recalcul_dir_plis(NULL) // -- pour RUPTURE_SIGMA_PRINC et RUPTURE_EPS_PRINC ,loi_2DCP_pour_rupture(NULL),loi_1DCP2_pour_rupture(NULL) // un conteneur d'un point d'intégration courant ,ptintmeca(loi.ptintmeca) // métriques ,giB_0_1D(1),giH_0_1D(1),giB_t_1D(1),giH_t_1D(1),giB_tdt_1D(1),giH_tdt_1D(1) ,gijBB_0_1D(),gijHH_0_1D(),gijBB_t_1D(),gijHH_t_1D(),gijBB_tdt_1D(),gijHH_tdt_1D() ,gradVmoyBB_t_1D_P(NULL),gradVmoyBB_t_1D() ,gradVmoyBB_tdt_1D_P(NULL),gradVmoyBB_tdt_1D() ,gradVBB_tdt_1D_P(NULL),gradVBB_tdt_1D() ,jacobien_tdt_1D(0.),jacobien_t_1D(0.),jacobien_0_1D(0.),d_jacobien_tdt_1D() ,d_giB_tdt_1D(),d_giH_tdt_1D(),d_gijBB_tdt_1D_P(NULL),d_gijBB_tdt_1D() ,d2_gijBB_tdt_1D_P(NULL),d2_gijBB_tdt_1D() ,d_gijHH_tdt_1D_P(NULL),d_gijHH_tdt_1D() ,d_gradVmoyBB_t_1D_P(NULL),d_gradVmoyBB_t_1D() ,d_gradVmoyBB_tdt_1D_P(NULL),d_gradVmoyBB_tdt_1D() ,d_gradVBB_t_1D_P(NULL),d_gradVBB_t_1D() ,d_gradVBB_tdt_1D_P(NULL),d_gradVBB_tdt_1D() ,sig_HH_t_1D(),sig_HH_1D(),Deps_BB_1D(),eps_BB_1D(),delta_eps_BB_1D() ,d_eps_BB_1D_P(),d_eps_BB_1D(),d_sig_HH_1D_P(NULL),d_sig_HH_1D() ,d_sigma_deps_1D_P(NULL),d_sigma_deps_1D() ,eps_BB_2D_t(),delta_eps_BB_2D(),eps_HH_2D_t() ,ViB(ParaGlob::Dimension(),ParaGlob::Dimension()),ViH(ParaGlob::Dimension(),ParaGlob::Dimension()) // puis les grandeurs hors métriques, pour les tableaux de pointeurs, c'est uniquement du dimensionnement ,sig_HH_t_3D(loi.sig_HH_t_3D),sig_HH_3D(loi.sig_HH_3D),Deps_BB_3D(loi.Deps_BB_3D) ,eps_BB_3D(loi.eps_BB_3D),delta_eps_BB_3D(loi.delta_eps_BB_3D) // paramètres ,choix_methode_cal_plis_memb(loi.choix_methode_cal_plis_memb) { list ::const_iterator ili,ilifin=loi.lois_internes.end(); list ::const_iterator ic; for (ili=loi.lois_internes.begin(),ic=loi.list_completude_calcul.begin();ili!=ilifin;ili++,ic++) { Loi_comp_abstraite * nouvelle_loi = (*ili)->Nouvelle_loi_identique(); lois_internes.push_back(nouvelle_loi); list_completude_calcul.push_back(*ic); }; Loi_comp_abstraite * loi_inter = *(lois_internes.begin()); // pour simplifier switch (type_critere) { case PLISSEMENT_MEMBRANE: {// -- pour PLISSEMENT_MEMBRANE loi_2DCP_de_3D = (LoiContraintesPlanes*) loi_inter; // on construit une loi interne en contraintes planes double qui servira de support bool calcul_en_3D_via_direction_quelconque=false; // init if (choix_methode_cal_plis_memb == 2) calcul_en_3D_via_direction_quelconque = true; loi_1DCP2_de_3D = new LoiContraintesPlanesDouble(*loi_2DCP_de_3D,calcul_en_3D_via_direction_quelconque); // cas des fonctions éventuelles pour le niveau de détection // -- cas de niveauF_temps // on regarde s'il s'agit d'une courbe locale ou d'une courbe globale if (niveauF_temps != NULL) if (niveauF_temps->NomCourbe() == "_") {// comme il s'agit d'une courbe locale on la redéfinie (sinon pb lors du destructeur de loi) string non_courbe("_"); niveauF_temps = Courbe1D::New_Courbe1D(*loi.niveauF_temps); }; // -- pour les pondérations à base de ddl étendue et pour les grandeurs globale // tout est déjà fait dans les constructeurs de copie des class // Ponderation_GGlobal et Ponderation // --- pilotage recalcul des directions des plis // on regarde s'il s'agit d'une fonction locale ou d'une fonction globale if (recalcul_dir_plis != NULL) if (recalcul_dir_plis->NomFonction() == "_") {// comme il s'agit d'une fonction locale on la redéfinie // (sinon pb lors du destructeur de loi) string non_courbe("_"); recalcul_dir_plis = Fonction_nD::New_Fonction_nD(*loi.recalcul_dir_plis); }; break; } case RUPTURE_SIGMA_PRINC: case RUPTURE_EPS_PRINC: {loi_2DCP_pour_rupture = new LoiContraintesPlanes(*(loi.loi_2DCP_pour_rupture)); loi_1DCP2_pour_rupture = new LoiContraintesPlanesDouble(*(loi.loi_1DCP2_pour_rupture)); break; } default : cout << "\nErreur : valeur incorrecte du type de critere defini= " << Nom_Critere_Loi(type_critere) << " !\n"; cout << "\n LoiCritere::LoiCritere (const LoiCritere& loi)"; Sortie(1); }; // association des pointeurs de grandeurs si nécessaire if (loi.gradVmoyBB_t_1D_P != NULL) {gradVmoyBB_t_1D_P = &gradVmoyBB_t_1D;}; if (loi.gradVmoyBB_tdt_1D_P != NULL) {gradVmoyBB_tdt_1D_P = &gradVmoyBB_tdt_1D;}; if (loi.gradVBB_tdt_1D_P != NULL) {gradVBB_tdt_1D_P = &gradVBB_tdt_1D;}; // def des tableaux de pointeurs pour les conteneurs de métriques // -- cas des tableaux de pointeurs, ils ont déjà la bonne dimension int ta_d_gijBB_tdt_1D = loi.d_gijBB_tdt_1D.Taille(); for (int i=1;i<= ta_d_gijBB_tdt_1D;i++) d_gijBB_tdt_1D_P(i) = &(d_gijBB_tdt_1D(i)); if (loi.d2_gijBB_tdt_1D_P!= NULL) { int tai_d2_gijBB_tdt_1D = d2_gijBB_tdt_1D.Taille1(); d2_gijBB_tdt_1D_P = new Tableau2 (tai_d2_gijBB_tdt_1D); int taj_d2_gijBB_tdt_1D = d2_gijBB_tdt_1D.Taille2(); for (int i=1;i<= tai_d2_gijBB_tdt_1D;i++) for (int j=1;j<= taj_d2_gijBB_tdt_1D;j++) (*d2_gijBB_tdt_1D_P)(i,j) = &(d2_gijBB_tdt_1D(i,j)); }; int ta_d_gijHH_tdt_1D = d_gijHH_tdt_1D.Taille(); for (int i=1;i<= ta_d_gijHH_tdt_1D;i++) d_gijHH_tdt_1D_P(i) = &(d_gijHH_tdt_1D(i)); if (loi.d_gradVmoyBB_t_1D_P != NULL) { int ta_d_gradVmoyBB_t_1D = d_gradVmoyBB_t_1D.Taille(); d_gradVmoyBB_t_1D_P = new Tableau (ta_d_gradVmoyBB_t_1D); for (int i=1;i<= ta_d_gradVmoyBB_t_1D;i++) (*d_gradVmoyBB_t_1D_P)(i) = &(d_gradVmoyBB_t_1D(i)); }; if (loi.d_gradVmoyBB_tdt_1D_P != NULL) { int ta_d_gradVmoyBB_tdt_1D = d_gradVmoyBB_tdt_1D.Taille(); d_gradVmoyBB_tdt_1D_P = new Tableau (ta_d_gradVmoyBB_tdt_1D); for (int i=1;i<= ta_d_gradVmoyBB_tdt_1D;i++) (*d_gradVmoyBB_tdt_1D_P)(i) = &(d_gradVmoyBB_tdt_1D(i)); }; if (loi.d_gradVBB_t_1D_P != NULL) { int ta_d_gradVBB_t_1D = d_gradVBB_t_1D.Taille(); d_gradVBB_t_1D_P = new Tableau (ta_d_gradVBB_t_1D); for (int i=1;i<= ta_d_gradVBB_t_1D;i++) (*d_gradVBB_t_1D_P)(i) = &(d_gradVBB_t_1D(i)); }; if (loi.d_gradVBB_tdt_1D_P != NULL) { int ta_d_gradVBB_tdt_1D = d_gradVBB_tdt_1D.Taille(); d_gradVBB_tdt_1D_P = new Tableau (ta_d_gradVBB_tdt_1D); for (int i=1;i<= ta_d_gradVBB_tdt_1D;i++) (*d_gradVBB_tdt_1D_P)(i) = &(d_gradVBB_tdt_1D(i)); }; // conteneurs des métriques // a priori seules les grandeurs principales sont affecté expli_1D = new Met_abstraite::Expli_t_tdt // constructeur normal (&giB_0_1D,&giH_0_1D,&giB_t_1D,&giH_t_1D,&giB_tdt_1D,&giH_tdt_1D ,&gijBB_0_1D,&gijHH_0_1D,&gijBB_t_1D,&gijHH_t_1D ,&gijBB_tdt_1D,&gijHH_tdt_1D ,gradVmoyBB_t_1D_P,gradVmoyBB_tdt_1D_P,gradVBB_tdt_1D_P // pas affecté par défaut ,&d_gijBB_tdt_1D_P,&jacobien_tdt_1D,&jacobien_t_1D,&jacobien_0_1D); impli_1D = new Met_abstraite::Impli // constructeur normal (&giB_0_1D,&giH_0_1D,&giB_t_1D,&giH_t_1D,&giB_tdt_1D,&d_giB_tdt_1D,&giH_tdt_1D,&d_giH_tdt_1D ,&gijBB_0_1D,&gijHH_0_1D,&gijBB_t_1D,&gijHH_t_1D,&gijBB_tdt_1D,&gijHH_tdt_1D ,gradVmoyBB_t_1D_P,gradVmoyBB_tdt_1D_P,gradVBB_tdt_1D_P // pas affecté par défaut ,&d_gijBB_tdt_1D_P ,d2_gijBB_tdt_1D_P // pas affecté par défaut ,&d_gijHH_tdt_1D_P ,&jacobien_tdt_1D,&jacobien_t_1D,&jacobien_0_1D,&d_jacobien_tdt_1D ,d_gradVmoyBB_t_1D_P,d_gradVmoyBB_tdt_1D_P // pas affecté par défaut ,d_gradVBB_t_1D_P,d_gradVBB_tdt_1D_P); // pas affecté par défaut umat_cont_1D = new Met_abstraite::Umat_cont // constructeur normal (&giB_0_1D,&giH_0_1D,&giB_t_1D,&giH_t_1D,&giB_tdt_1D,&giH_tdt_1D ,&gijBB_0_1D,&gijHH_0_1D,&gijBB_t_1D,&gijHH_t_1D ,&gijBB_tdt_1D,&gijHH_tdt_1D ,gradVmoyBB_t_1D_P,gradVmoyBB_tdt_1D_P,gradVBB_tdt_1D_P // pas affecté par défaut ,&jacobien_tdt_1D,&jacobien_t_1D,&jacobien_0_1D); // puis les tableaux de pointeurs de grandeurs hors métriques int ta_d_eps_BB_1D = d_eps_BB_1D.Taille(); for (int i=1;i<= ta_d_eps_BB_1D;i++) d_eps_BB_1D_P(i) = &(d_eps_BB_1D(i)); int ta_d_sig_HH_1D = d_sig_HH_1D.Taille(); for (int i=1;i<= ta_d_sig_HH_1D;i++) d_sig_HH_1D_P(i) = &(d_sig_HH_1D(i)); d_sigma_deps_1D_P = & d_sigma_deps_1D; // traitement des pondérations if (loi.niveauF_fct_nD != NULL) niveauF_fct_nD = new Ponderation_TypeQuelconque(*(loi.niveauF_fct_nD)); if (loi.niveauF_ddlEtendu != NULL) niveauF_ddlEtendu = new Ponderation(*(loi.niveauF_ddlEtendu)); if (loi.niveauF_temps != NULL) {if (loi.niveauF_temps->NomCourbe() == "_") niveauF_temps = Courbe1D::New_Courbe1D(*(loi.niveauF_temps));; }; if (loi.niveauF_grandeurConsultable != NULL) niveauF_grandeurConsultable = new Ponderation_Consultable(*(loi.niveauF_grandeurConsultable)); }; LoiCritere::~LoiCritere () // Destructeur { list ::iterator ili,ilifin=lois_internes.end(); for (ili=lois_internes.begin();ili!=ilifin;ili++) { lois_internes.erase(ili); }; if (d_sigma_deps_inter != NULL) delete d_sigma_deps_inter; if (d_sigtotalHH.Taille() != 0) { int taille = d_sigtotalHH.Taille(); for (int i=1; i<= taille; i++) if (d_sigtotalHH(i) != NULL) delete d_sigtotalHH(i); }; // -- pour les plis if (loi_1DCP2_de_3D != NULL) delete loi_1DCP2_de_3D; // on regarde s'il s'agit d'une fonction locale ou d'une fonction globale if (recalcul_dir_plis != NULL) if (recalcul_dir_plis->NomFonction() == "_") delete recalcul_dir_plis; // -- pour RUPTURE_SIGMA_PRINC et RUPTURE_EPS_PRINC if (loi_2DCP_pour_rupture != NULL) delete loi_2DCP_pour_rupture; if (loi_1DCP2_pour_rupture != NULL) delete loi_1DCP2_pour_rupture; // les conteneurs de pointeurs: delete expli_1D;delete impli_1D; delete umat_cont_1D; // pour les grandeurs de base, pas de new, donc pas de delete // pour les tableaux de pointeurs, idem s'ils ne sont pas addressé par un pointeur // sinon il faut détruire le tableau if (d2_gijBB_tdt_1D_P!= NULL) delete d2_gijBB_tdt_1D_P; if (d_gradVmoyBB_t_1D_P!= NULL) delete d_gradVmoyBB_t_1D_P; if (d_gradVmoyBB_tdt_1D_P!= NULL) delete d_gradVmoyBB_tdt_1D_P; if (d_gradVBB_t_1D_P!= NULL) delete d_gradVBB_t_1D_P; if (d_gradVBB_tdt_1D_P!= NULL) delete d_gradVBB_tdt_1D_P; // cas des pondérations if (niveauF_fct_nD != NULL) delete niveauF_fct_nD; if (niveauF_ddlEtendu != NULL) delete niveauF_ddlEtendu; if (niveauF_temps != NULL) {if (niveauF_temps->NomCourbe() == "_") // comme il s'agit d'une courbe locale on doit la détruire localement delete niveauF_temps; }; }; // def d'une instance de données spécifiques, et initialisation // valable une fois que les différentes lois internes sont définit LoiCritere::SaveResul * LoiCritere::LoiCritere::New_et_Initialise() { // on crée les différentes listes list liste_des_SaveResul; // data pour chaque loi list l_sigoHH,l_sigoHH_t; // gestion des contraintes pour chaque loi list l_energ,l_energ_t; // idem pour les énergies // le traitement est différent suivant les types de critères Loi_comp_abstraite * loi_inter = *(lois_internes.begin()); // pour simplifier switch (type_critere) { case PLISSEMENT_MEMBRANE: { // -- pour PLISSEMENT_MEMBRANE // ici seule la première loi est utilisée et il s'agit forcément d'une loi de contrainte plane // on définit un conteneur de CP double qui contient lui-même un conteneur de CP ce qui permettra // de passer de l'un à l'autre sans pb SaveResul * nevez_save_result=NULL; // si on utilise la V2 plis, il faut en avertir la loi 1D nevez_save_result = loi_1DCP2_de_3D->New_et_Initialise(); liste_des_SaveResul.push_back(nevez_save_result); break; } case PLISSEMENT_BIEL: { // -- pour plissement 1D // ici seule la première loi est utilisée et il s'agit forcément d'une loi 1D SaveResul * nevez_save_result=loi_inter->New_et_Initialise(); liste_des_SaveResul.push_back(nevez_save_result); break; } case RUPTURE_SIGMA_PRINC: case RUPTURE_EPS_PRINC: {// pour l'instant on ne fait rien break; } default : cout << "\nErreur : valeur incorrecte du type de critere defini= " << Nom_Critere_Loi(type_critere) << " !\n"; cout << "\n LoiCritere::LoiCritere::New_et_Initialise()"; Sortie(1); }; // pour le reste on balaie l'ensemble des lois list ::iterator ili,ilifin=lois_internes.end(); list ::iterator isig,isig_t; for (ili=lois_internes.begin();ili!=ilifin;ili++) { // pour l'instant on définit des pointeurs de tenseurs qui ont la dimension de la loi, // ensuite au moment de l'utilisation on les initialisera correctement si besoin TenseurHH * interHH = NevezTenseurHH(dim,0.);l_sigoHH.push_back(interHH); TenseurHH * interHH_t = NevezTenseurHH(dim,0.);l_sigoHH_t.push_back(interHH_t); // on définit les conteneurs pour les énergies l_energ.push_back(EnergieMeca());l_energ_t.push_back(EnergieMeca()); }; // on ramène la bonne instance LoiCritere::SaveResul * retour = new SaveResul_LoiCritere(liste_des_SaveResul,l_sigoHH,l_sigoHH_t ,l_energ,l_energ_t,avec_ponderation,type_critere); // on supprime les grandeurs locales qui ont été crées par des new list ::iterator ils, ilsfin= liste_des_SaveResul.end(); list ::iterator isib = l_sigoHH.begin(); list ::iterator isib_t = l_sigoHH_t.begin(); for (ils=liste_des_SaveResul.begin();ils!=ilsfin;ils++,isib++,isib_t++) { if ((*ils) != NULL) delete (*ils); if ((*isib) != NULL) delete (*isib); if ((*isib_t) != NULL) delete (*isib_t); }; // insertion éventuelle de conteneurs de grandeurs quelconque Insertion_conteneur_dans_save_result(retour); // retour return retour; }; // Lecture des lois de comportement void LoiCritere::LectureDonneesParticulieres(UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D ,LesFonctions_nD& lesFonctionsnD) { // on commence par lire le type de critère qui devra être considéré // pour l'instant on suppose qu'il n'y a qu'un seul critère actif string nom_class_methode("LoiCritere::LectureDonneesParticulieres"); string mot_cle("TYPE_DE_CRITERE_"); entreePrinc->Lecture_et_verif_mot_cle(nom_class_methode,mot_cle); // lecture du critère *(entreePrinc->entree) >> type_critere; // on regarde si on compte utiliser une fonction de contrôle du niveau // d'apparition des plis bool passerUneLigne = false; if (strstr(entreePrinc->tablcar,"avecNiveauSigmaI_mini_pour_plis_")!=NULL) { // lecture du mot clé string st2; *(entreePrinc->entree) >> st2; // vérification if (st2 != "avecNiveauSigmaI_mini_pour_plis_") { cout << "\n erreur en lecture, on aurait du lire le mot cle avecNiveauSigmaI_mini_pour_plis_" << " alors qu'on a lu " << st2; cout << "\n LoiCritere::LectureDonneesParticulieres(..."; entreePrinc->MessageBuffer("**erreur01**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on enregistre avecNiveauSigmaI_mini_pour_plis = true; passerUneLigne = true; } else // sinon on n'a pas de fonction de contrôle {avecNiveauSigmaI_mini_pour_plis = false;}; // passage éventuel de ligne // if (passerUneLigne) entreePrinc->NouvelleDonnee(); // prepa du flot de lecture // lecture jusque l'on trouve le mot clé signalant la fin de la liste des loi élémentaires bool premier_lecture = true; int dim_lois=0; Enum_categorie_loi_comp categ=RIEN_CATEGORIE_LOI_COMP; while (strstr(entreePrinc->tablcar,"fin_loi_interne")==NULL) { // dans le cas de l'existence de fonction de niveau, on lit les infos bool use_temps=false; if (avecNiveauSigmaI_mini_pour_plis) { Ponderation ponder; // un élément courant // on doit commencer par lire les grandeurs des fonctions de niveau mot_cle="les_grandeurs_de_controle_=";string st1,st2; entreePrinc->Lecture_et_verif_mot_cle(nom_class_methode,mot_cle); // entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle,st2); int compteur = 1; // pour éviter une boucle infinie List_io < Ddl_enum_etendu > listddlenum; List_io listbool; // on lit les grandeurs pour l'instant en string List_io list_id_grand; //liste de travail List_io list_id_grand_glob; //liste des grandeurs globales int nb_grandeurs_globales = 0; // init while (st1 != "fin_grandeurs_") {*(entreePrinc->entree) >> st1 ; if (st1 == "fin_grandeurs_") break; // pas terrible mais c'est ce qui me vient à l'idée ! // on vérifie que le mot clé lu est exploitable string minus = Minuscules(st1); // la forme minuscules if ((st1=="TEMPS") || (Ddl_enum_etendu::VerifExistence(st1)) || EstUneGrandeurGlobale(minus) ) {list_id_grand.push_back(st1); if (EstUneGrandeurGlobale(minus)) // si c'est une grandeur globale on cumule le compteur {nb_grandeurs_globales++; list_id_grand_glob.push_back(st1); }; } else { cout << "\n erreur en lecture, le type de grandeur lu" << st1 << " n'est pas acceptable " << "\n LoiCritere::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur05**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; // --- maintenant on va lire les fonctions entreePrinc->NouvelleDonnee(); // prepa du flot de lecture mot_cle="deb_fonct_="; // le début des fonctions entreePrinc->Lecture_et_verif_mot_cle(nom_class_methode,mot_cle); List_io ::iterator ili,ilifin = list_id_grand.end(); List_io li_courbe_globale; // inter List_io val_aux_noeuds; // inter int nb_GGlob=0;int nb_enum_etendu = 0; // compteur pour le dimensionnement // premier passage on crée les fonctions for (ili=list_id_grand.begin();ili != ilifin;ili++) {string minus = Minuscules(*ili); // la forme minuscules if ((*ili)=="TEMPS") // cas de la fonction du temps { // lecture de la loi d'évolution *(entreePrinc->entree) >> st1; val_aux_noeuds.push_back(false); // sert à rien, mais permet // de garder le même ordre de rangement que list_id_grand // on regarde si la courbe existe, si oui on récupère la référence if (lesCourbes1D.Existe(st1)) { niveauF_temps = lesCourbes1D.Trouve(st1); } else { // sinon il faut la lire maintenant string non_courbe("_"); niveauF_temps = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (st1.c_str())); // lecture de la courbe niveauF_temps->LectDonnParticulieres_courbes (non_courbe,entreePrinc); }; } else if (EstUneGrandeurGlobale(minus)) { val_aux_noeuds.push_back(false); // sert à rien, mais permet nb_GGlob++; // de garder le même ordre de rangement que list_id_grand // pour le premier élément de la liste on lit la fonction // pour les autres, on ne fait rien (la fct est déjà lue) if (nb_GGlob == 1) {// création de la pondération si nécessaire if (niveauF_fct_nD == NULL) niveauF_fct_nD = new Ponderation_TypeQuelconque; // on lit la fonction niveauF_fct_nD->LecturePonderation (list_id_grand_glob,entreePrinc,lesFonctionsnD); }; } else if (Ddl_enum_etendu::VerifExistence(*ili)) { nb_enum_etendu++; if (niveauF_ddlEtendu==NULL) // on le crée niveauF_ddlEtendu = new Ponderation; // on lit la courbe *(entreePrinc->entree) >> st1; Courbe1D* inter=NULL; // on regarde si la courbe existe, si oui on récupère la référence if (lesCourbes1D.Existe(st1)) { inter = lesCourbes1D.Trouve(st1); } else { // sinon il faut la lire maintenant string non_courbe("_"); inter = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (st1.c_str())); // lecture de la courbe inter->LectDonnParticulieres_courbes (non_courbe,entreePrinc); }; li_courbe_globale.push_back(inter); // et il faut lire en plus le fait que ce soit au noeud // ou au pti *(entreePrinc->entree) >> st2; if (st2 == "AuxNoeuds_") {val_aux_noeuds.push_back(true);} else if (st2 == "AuPti_") {val_aux_noeuds.push_back(false);} else { cout << "\n erreur en lecture, de positionnement de la grandeur: " << (*ili) << " qui doit etre AuxNoeuds_ ou AuPti_ " << " et on a lu" << st2 << " qui n'est pas acceptable " << "\n" << nom_class_methode<<"(..."; entreePrinc->MessageBuffer("**erreur06**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; }; // on passe le mot clé de fin mot_cle="fin_fonct_"; // la fin des fonctions entreePrinc->Lecture_et_verif_mot_cle(nom_class_methode,mot_cle); // *** à changer en fonction de l'utilisation // deuxième passage on met à jour les conteneurs // niveauF_fct_nD->type_grandeur_GGlob.Change_taille(nb_GGlob); // niveauF_fct_nD->c_proport.Change_taille(nb_GGlob); // on intervient sur les ddlEtendu que s'il en existe if (niveauF_ddlEtendu != NULL) { niveauF_ddlEtendu->Type_grandeur().Change_taille(nb_enum_etendu); niveauF_ddlEtendu->Valeur_aux_noeuds().Change_taille(nb_enum_etendu); niveauF_ddlEtendu->C_proport().Change_taille(nb_enum_etendu); }; List_io ::iterator i_courbe=li_courbe_globale.begin(); // inter List_io ::iterator i_val= val_aux_noeuds.begin(); // inter // re_init des numéros nb_enum_etendu = 1; // compteur pour le dimensionnement for (ili=list_id_grand.begin();ili != ilifin;ili++,i_courbe++, i_val++) { if ((*ili)=="TEMPS") // cas de la fonction du temps { // on passe car l'affectation a déjà été faite } else if (EstUneGrandeurGlobale((*ili))) { // on passe car l'affectation a déjà été faite } else if (Ddl_enum_etendu::VerifExistence(*ili)) {(niveauF_ddlEtendu->Type_grandeur())(nb_enum_etendu)= Ddl_enum_etendu(*ili); (niveauF_ddlEtendu->Valeur_aux_noeuds())(nb_enum_etendu)=(*i_val); (niveauF_ddlEtendu->C_proport())(nb_enum_etendu)=(*i_courbe); nb_enum_etendu++; }; }; entreePrinc->NouvelleDonnee(); // prepa du flot de lecture }; // --- lecture de la loi individuelle --------- // lecture du nom de la loi string st2; *(entreePrinc->entree) >> st2; // --- définition de list_completude_calcul, // on regarde si éventuellement on utilise seulement une partie de la loi string toto; if(strstr(entreePrinc->tablcar,"sigma_seulement_")!=0) { *(entreePrinc->entree) >> toto; // on passe la chaine de caractere // on vérifie que le mot clé est bien positionné if (toto != "sigma_seulement_") { cout << "\n erreur en lecture, on aurait du lire le mot cle sigma_seulement_" << " alors qu'on a lu " << toto; cout << "\n LoiCritere::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur2**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on enregistre list_completude_calcul.push_back(CONTRAINTE_UNIQUEMENT); } else if(strstr(entreePrinc->tablcar,"tangent_seulement_")!=0) { *(entreePrinc->entree) >> toto; // on passe la chaine de caractere // on vérifie que le mot clé est bien positionné if (toto != "tangent_seulement_") { cout << "\n erreur en lecture, on aurait du lire le mot cle tangent_seulement_" << " alors qu'on a lu " << toto; cout << "\n LoiCritere::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur3**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on enregistre list_completude_calcul.push_back(TANGENT_UNIQUEMENT); } else // cas par défaut { list_completude_calcul.push_back(CONTRAINTE_ET_TANGENT); }; // --- definition de la loi LoiAbstraiteGeneral * pt = LesLoisDeComp::Def_loi(st2); // enregistrement de la loi lois_internes.push_back((Loi_comp_abstraite*)pt); // lecture des informations particulières propres à la loi entreePrinc->NouvelleDonnee(); // prepa du flot de lecture pt->LectureDonneesParticulieres (entreePrinc,lesCourbes1D,lesFonctionsnD); // dans le cas de la première loi on enregistre la dimension // on s'occupe de la catégorie et de la dimension de la loi, après la lecture des informations particulières // pour le cas où ce serait une loi critere, car dans ce dernier cas, c'est après la lecture que l'on peut // définir la catégorie dans le cas de la première loi on enregistre la dimension if (premier_lecture) { premier_lecture=false; dim_lois=pt->Dimension_loi();categ = pt->Id_categorie(); // on met à jour la dimension et la catégorie dim = dim_lois; categorie_loi_comp = categ; if (!GroupeMecanique(categorie_loi_comp)) { cout << "\n erreur1 en lecture des lois constitutives elementaire d'une loi LoiCritere" << "\n la loi lue: " << pt->Nom_comport() << " n'est pas une loi mecanique, elle fait partie " << " de la categorie: "<< Nom_categorie_loi_comp(categorie_loi_comp); entreePrinc->MessageBuffer("**erreur LoiCritere::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; } else // sinon on vérifie que les lois ont la bonne dimension et la bonne catégorie { if (pt->Dimension_loi() != dim_lois) { cout << "\n erreur en lecture des lois constitutives elementaire d'une loi LoiCritere" << "\n la loi lue: " << pt->Nom_comport() << " n'a pas la meme dimension que la premier loi lue"; entreePrinc->MessageBuffer("lecture LoiCritere"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } if (!GroupeMecanique(pt->Id_categorie())) { cout << "\n erreur en lecture des lois constitutives elementaire d'une loi LoiCritere" << "\n la loi lue: " << pt->Nom_comport() << " n'est pas une loi mecanique, elle fait partie " << " de la categorie: "<< Nom_categorie_loi_comp(categorie_loi_comp); entreePrinc->MessageBuffer("**erreur2 LoiCritere::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on enregistre la catégorie la plus complète categorie_loi_comp = Categorie_loi_comp_la_plus_complete(categorie_loi_comp,pt->Id_categorie()); }; // si la loi est thermo dépendante on indique que la loi critère l'est aussi if (((Loi_comp_abstraite*)pt)->ThermoDependante()) this->thermo_dependant = true; }; // préparation lecture éventuelle de paramètres additionnels entreePrinc->NouvelleDonnee(); // vérification en fonction du type de critère switch (type_critere) { case PLISSEMENT_MEMBRANE: {// on vérifie qu'il n'y a qu'une seule loi élémentaire if (lois_internes.size() != 1) { cout << "\n erreur : dans le cas d'un critere " << Nom_Critere_Loi(type_critere) << " une seule loi interne est autorise alors qu'ici il y a " << lois_internes.size() << " loi(s) definie(s), revoir les donnees d'entree "; cout << "\n LoiCritere::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur3**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on vérifie qu'il s'agit d'une loi de 2D contraintes planes venant du 3D Loi_comp_abstraite * loi = *(lois_internes.begin()); // pour simplifier if (!(loi->Contraintes_planes_de_3D())) { cout << "\n erreur : dans le cas d'un critere " << Nom_Critere_Loi(type_critere) << " la loi de comportement ne provient pas d'une loi 3D, on ne peut pas l'utiliser ! "; cout << "\n LoiCritere::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur4**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } else // sinon on définit la loi 2D contraintes planes support, puis la 1D {loi_2DCP_de_3D = (LoiContraintesPlanes*) loi; // on construit une loi interne en contraintes planes double qui servira de support bool calcul_en_3D_via_direction_quelconque=false; // init if (choix_methode_cal_plis_memb == 2) calcul_en_3D_via_direction_quelconque = true; loi_1DCP2_de_3D = new LoiContraintesPlanesDouble(*loi_2DCP_de_3D,calcul_en_3D_via_direction_quelconque); // on regarde s'il faut lire des paramètres particuliers à la loi contraintes planes double string toto; if(strstr(entreePrinc->tablcar,"parametres_controle_pour_contraintes_planes_double_")!=0) { *(entreePrinc->entree) >> toto; // on passe la chaine de caractere // on vérifie que le mot clé est bien positionné if (toto != "parametres_controle_pour_contraintes_planes_double_") { cout << "\n erreur en lecture, on aurait du lire le mot cle parametres_controle_pour_contraintes_planes_double_" << " alors qu'on a lu " << toto; cout << "\n LoiCritere::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur41**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; entreePrinc->NouvelleDonnee(); // on passe le mot clé // on appelle la méthode loi_1DCP2_de_3D->LectureParametres_controles(entreePrinc,lesCourbes1D,lesFonctionsnD); // lecture du mot clé de fin des paramètres de controle *(entreePrinc->entree) >> toto; // on passe la chaine de caractere // on vérifie que le mot clé est bien positionné if (toto != "fin_parametres_controle_pour_contraintes_planes_double_") { cout << "\n erreur en lecture, on aurait du lire le mot cle fin_parametres_controle_pour_contraintes_planes_double_" << " alors qu'on a lu " << toto; cout << "\n LoiCritere::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur42**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; // on dimensionne éventuellement if (d_sigma_deps_inter == NULL) d_sigma_deps_inter = NevezTenseurHHHH(22); }; // on met à jour l'indicateur calcul_en_3D_via_direction_quelconque_ de la loi 1D bool calcul_en_3D_via_direction_quelconque=false; // init if (choix_methode_cal_plis_memb == 2) calcul_en_3D_via_direction_quelconque = true; loi_1DCP2_de_3D->Change_calcul_en_3D_via_direction_quelconque (calcul_en_3D_via_direction_quelconque); break; } case PLISSEMENT_BIEL: {// on vérifie qu'il n'y a qu'une seule loi élémentaire if (lois_internes.size() != 1) { cout << "\n erreur : dans le cas d'un critere " << Nom_Critere_Loi(type_critere) << " une seule loi interne est autorise alors qu'ici il y a " << lois_internes.size() << " loi(s) definie(s), revoir les donnees d'entree "; cout << "\n LoiCritere::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur3**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on vérifie qu'il s'agit d'une loi de 1D Loi_comp_abstraite * loi = *(lois_internes.begin()); // pour simplifier if ((loi->Dimension_loi() != 1) && (loi->Dimension_loi() != 4)) { cout << "\n erreur : dans le cas d'un critere " << Nom_Critere_Loi(type_critere) << " la loi de comportement doit etre de type 1D, on ne peut pas l'utiliser ! "; cout << "\n LoiCritere::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur4**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on dimensionne éventuellement if (d_sigma_deps_inter == NULL) d_sigma_deps_inter = NevezTenseurHHHH(11); break; } case RUPTURE_SIGMA_PRINC: case RUPTURE_EPS_PRINC: {// on vérifie qu'il n'y a qu'une seule loi élémentaire if (lois_internes.size() != 1) { cout << "\n erreur : dans le cas d'un critere " << Nom_Critere_Loi(type_critere) << " une seule loi interne est autorise alors qu'ici il y a " << lois_internes.size() << " loi(s) definie(s), revoir les donnees d'entree "; cout << "\n LoiCritere::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur3**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // pour l'instant seule les lois 3D sont autorisées Loi_comp_abstraite * loi = *(lois_internes.begin()); // pour simplifier if (Comp_3D_CP_DP_1D(loi->Id_comport()) != COMP_3D) { cout << "\n erreur : dans le cas d'un critere " << Nom_Critere_Loi(type_critere) << " la loi de comportement n'est pas une loi 3D, on ne peut pas l'utiliser ! "; cout << "\n LoiCritere::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur5**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on définit les lois supports en contraintes planes loi_2DCP_pour_rupture = (LoiContraintesPlanes*) loi; // on construit une loi interne en contraintes planes double qui servira de support bool calcul_en_3D_via_direction_quelconque=false; // init if (choix_methode_cal_plis_memb == 2) calcul_en_3D_via_direction_quelconque = true; loi_1DCP2_de_3D = new LoiContraintesPlanesDouble(*loi_2DCP_de_3D,calcul_en_3D_via_direction_quelconque); break; } default : cout << "\nErreur : valeur incorrecte du type de critere defini= " << Nom_Critere_Loi(type_critere) << " !\n"; cout << "\n LoiCritere::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur4**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // prepa du flot de lecture pour d'autre loi éventuellement et // lecture éventuelle du mot clé de fin de la loi if((strstr(entreePrinc->tablcar,"fin_loi_critere")==0) && (strstr(entreePrinc->tablcar,"avec_parametres_controle_pour_loi_critere_")==0) ) entreePrinc->NouvelleDonnee(); // --- lecture éventuelle des paramètres de réglage ---- if(strstr(entreePrinc->tablcar,"avec_parametres_controle_pour_loi_critere_")!=0) {string nom; entreePrinc->NouvelleDonnee(); // on se positionne sur un nouvel enreg // on lit tant que l'on ne rencontre pas la ligne contenant "fin_parametres_controle_pour_loi_critere_" // ou un nouveau mot clé global auquel cas il y a pb !! MotCle motCle; // ref aux mots cle while (strstr(entreePrinc->tablcar,"fin_parametres_controle_pour_loi_critere_")==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 : on n'a pas trouve le mot cle " << " fin_parametres_controle_pour_loi_critere_ et par contre la ligne courante contient un mot cle global "; entreePrinc->MessageBuffer("** erreur5 des parametres de reglage de la loi de comportement de LoiCritere::LectureDonneesParticulieres( **"); 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_controle_pour_loi_critere_") {entreePrinc->NouvelleDonnee(); *(entreePrinc->entree) >> nom;}; } #endif else // cas d'une erreur de lecture { cout << "\n erreur de lecture inconnue "; entreePrinc->MessageBuffer("** erreur4 des parametres de reglage de la loi de comportement de LoiCritere::LectureDonneesParticulieres( **"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // forcer un affichage particulier pour les méthodes if (nom == "permet_affichage_") { Lecture_permet_affichage(entreePrinc,lesFonctionsnD); } // choix entre la première ou deuxième méthode pour le calcul des plis en membrane else if (nom == "choix_methode_cal_plis_memb_") { *(entreePrinc->entree) >> choix_methode_cal_plis_memb; // on met à jour l'indicateur calcul_en_3D_via_direction_quelconque_ de la loi 1D bool calcul_en_3D_via_direction_quelconque=false; // init if (choix_methode_cal_plis_memb == 2) calcul_en_3D_via_direction_quelconque = true; loi_1DCP2_de_3D->Change_calcul_en_3D_via_direction_quelconque (calcul_en_3D_via_direction_quelconque); } // traitement des épaisseurs si relachement_complet else if (nom == "choix_calcul_epaisseur_si_relachement_complet_") { *(entreePrinc->entree) >> choix_calcul_epaisseur_si_relachement_complet; } //paramètres de controle du recalcul de la direction des plis // utilisation d'une fonction nD else if (nom == "recalcul_dir_plis_") { // --- lecture du nom de la fonction nD mot_cle="recalcul_dir_plis_"; string nom_fonct; // init *(entreePrinc->entree) >> nom_fonct; // maintenant on définit la fonction if (lesFonctionsnD.Existe(nom_fonct)) {recalcul_dir_plis = lesFonctionsnD.Trouve(nom_fonct); } else {// sinon il faut la lire maintenant string non("_"); recalcul_dir_plis = Fonction_nD::New_Fonction_nD(non, Id_Nom_Fonction_nD(nom_fonct)); // lecture de la courbe recalcul_dir_plis->LectDonnParticulieres_Fonction_nD (non,entreePrinc); // maintenant on vérifie que la fonction est utilisable if (recalcul_dir_plis->NbComposante() != 1 ) { cout << "\n erreur en lecture, la fonction " << nom_fonct << " est une fonction vectorielle a " << recalcul_dir_plis->NbComposante() << " composante alors qu'elle devrait etre scalaire ! " << " elle n'est donc pas utilisable !! "; string message("\n**erreur** \n"+nom_class_methode+"(..."); entreePrinc->MessageBuffer(message); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; } // // niveau du critère // if (nom == "niv_declenche_") // {*(entreePrinc->entree) >> niveau_declenchement_critere; // } // sinon ce n'est pas un mot clé connu, on le signale else if (nom != "fin_parametres_controle_pour_loi_critere_") { cout << "\n erreur en lecture d'un parametre, le mot cle est inconnu " << " on a lu : " << nom << endl; if (ParaGlob::NiveauImpression()>3) cout << "\n LoiCritere::LectureDonneesParticulieres((UtilLecture * entreePrinc) " << endl ; throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } }; //-- fin du while }; //-- fin de la lecture des paramètres de réglage // préparation de la lecture entreePrinc->NouvelleDonnee(); if(strstr(entreePrinc->tablcar,"fin_loi_critere")!=0) entreePrinc->NouvelleDonnee(); // appel au niveau de la classe mère Loi_comp_abstraite::Lecture_type_deformation_et_niveau_commentaire (*entreePrinc,lesFonctionsnD,false); }; // affichage de la loi void LoiCritere::Affiche() const { cout << "\n ....... loi de comportement LOI_CRITERE ........"; cout << "\n type de critere: " << type_critere; cout << "\n type_calcul_additif " ; if (type_calcul) {cout << " sur les contraintes ";} else { cout << " sur les increments de contraintes ";}; if (avec_ponderation) {cout << " avec ponderation " ;} else {cout << " sans ponderation ";}; list ::const_iterator ili,ilifin=lois_internes.end(); list ::const_iterator ic,icfin=list_completude_calcul.end(); list ::const_iterator ipon; if (avec_ponderation) ipon = list_ponderation.begin(); for (ili=lois_internes.begin(),ic=list_completude_calcul.begin();ili!=ilifin;ili++,ic++) {if (avec_ponderation) { cout << "\n avec fonctions de ponderation des grandeurs: "; const Ponderation& ponder = (*ipon); // pour simplifier int taille = (ponder.Const_Type_grandeur()).Taille(); for (int i=1;i<=taille;i++) {cout << (ponder.Const_Type_grandeur())(i) << " "; if ((ponder.Const_Valeur_aux_noeuds())(i)) {cout << "AuxNoeuds ";} else {cout << "AuPti ";}; }; // les courbes cout << "\n les courbes: "; for (int i=1;i<=taille;i++) {cout << (ponder.Const_C_proport())(i)->NomCourbe() <<" ";}; ipon++; }; // affichage de la loi (*ili)->Affiche(); // affichage du type d'utilisation de la loi switch (*ic) {case CONTRAINTE_ET_TANGENT: cout << "\n utilisation complete de la loi (contraintes et comportement tangent)"; break; case CONTRAINTE_UNIQUEMENT: cout << "\n utilisation uniquement des contraintes calculees par cette loi"; break; case TANGENT_UNIQUEMENT: cout << "\n utilisation uniquement de l'operateur tangent calcules par cette loi"; break; // le type énuméré ne contenant que ces valeurs, on ne peut pas avoir d'autres cas }; }; // niveau d'affichage Affiche_niveau_affichage(); // affichage switch (type_critere) { case PLISSEMENT_MEMBRANE: {//affichage de la loi CP2 cout << "\n loi 1D CP2: "; loi_1DCP2_de_3D->Affiche(); // choix entre la première ou deuxième méthode pour le calcul des plis en membrane cout << "\n choix_methode_cal_plis_memb= " << choix_methode_cal_plis_memb; // cas de recalcul_dir_plis cout << "\n recalcul_dir_plis= "; if (recalcul_dir_plis == NULL) {cout << " 0 ";} else {if (recalcul_dir_plis->NomFonction() != "_") cout << recalcul_dir_plis->NomFonction(); else recalcul_dir_plis->Affiche(); cout << "\n"; }; break; } case PLISSEMENT_BIEL: { break; } case RUPTURE_SIGMA_PRINC: case RUPTURE_EPS_PRINC: { break; } default : break; // déjà vue }; cout << "\n ....... fin de la loi de comportement LOI_CRITERE ........"; }; // affichage et definition interactive des commandes particulières à chaques lois void LoiCritere::Info_commande_LoisDeComp(UtilLecture& entreePrinc) { ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier cout << "\n definition standart pour critere plis (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"); sort << "\n# ....... loi de comportement avec critere(s) ........" << "\n# on commence par indiquer le type de critere, par exemple: " << "\n# TYPE_DE_CRITERE_ PLISSEMENT_MEMBRANE " << "\n# il faut donner le nom d'une (ou plusieurs, cela depend du critere) loi(s) " << "\n# suivi des parametres sur les lignes suivantes" << "\n# puis terminer avec le mot cle: fin_loi_interne " << "\n# puis def eventuel des grandeurs associees au(x) critere(s) sur les lignes suivantes" << "\n# puis terminer avec le mot cle: fin_loi_critere " << "\n# " << "\n# exemple avec une loi elastique et un critere de plissement "; // definition de la loi sort << "\n# TYPE_DE_CRITERE_ PLISSEMENT_MEMBRANE "; string internom("LOI_CONTRAINTES_PLANES"); LoiAbstraiteGeneral * pt = LesLoisDeComp::Def_loi(internom); sort << "\n# LOI_CONTRAINTES_PLANES # loi de contrainte plane "; pt->Info_commande_LoisDeComp(entreePrinc); sort << "\n fin_loi_critere # ----- fin de LOI_CRITERE" << endl; // cas particulier if ((rep != "o") && (rep != "O" ) && (rep != "0") ) { sort << "\n# ....... cas particulier 1) ........" << "\n# il est possible de ne retenir de la loi que les contraintes, ou que le comportement tangent " << "\n# ceci peut-etre utile dans le cas d'un comportement tangent singulier par exemple " << "\n# pour cela on indique apres le nom de la loi, un des mots cles suivant: " << "\n# sigma_seulement_ tangent_seulement_ "; sort << "\n# ....... cas particulier 2) ........" << "\n# --- cas d'un critere de plissement sur des membrannes --- " << "\n# la loi de comportement doit etre de type contrainte plane, " << "\n# qui utilise une loi 3D. Cette loi 3D est utilisee directement par " << "\n# le critere (cf. doc). " << "\n# Seule une seule loi est autorisee " << "\n# " << "\n# --- exemple de declaration pour une loi elastique --- " << "\n# " << "\n# " << "\n# toto LOI_CRITERE " << "\n# TYPE_DE_CRITERE_ PLISSEMENT_MEMBRANE " << "\n# LOI_CONTRAINTES_PLANES " << "\n# NEWTON_LOCAL avec_parametres_de_reglage_ " << "\n# nb_iteration_maxi_ 20 " << "\n# nb_dichotomie_maxi_ 20 " << "\n# tolerance_residu_ 1.e-3 " << "\n# fin_parametres_reglage_Algo_Newton_ " << "\n# " << "\n# ISOELAS " << "\n# 200000 0.3 " << "\n# fin_loi_contrainte_plane # --- fin de la loi de contrainte plane " << "\n# fin_loi_interne # --- fin des lois internes" << "\n# fin_loi_critere # --- fin de la loi critere " << "\n\n \n "; sort << "\n# ....... cas particulier 3) ........" << "\n# --- cas d'un critere de plissement sur des elements 1D type biel (sans flexion) --- " << "\n# la loi de comportement doit etre de type 1D quelconque " << "\n# Seule une seule loi est autorisee " << "\n# " << "\n# --- exemple de declaration pour une loi elastique --- " << "\n# " << "\n# " << "\n# toto LOI_CRITERE " << "\n# TYPE_DE_CRITERE_ PLISSEMENT_BIEL " << "\n# ISOELAS1D " << "\n# 200000 0.3 " << "\n# fin_loi_interne # --- fin des lois internes" << "\n# fin_loi_critere # --- fin de la loi critere " << "\n\n \n " << "\n# -------------- parametres particuliers pour les plis ------ " << "\n# il est possible d'indiquer les parametres particuliers qui controles " << "\n# la loi de comportement doublement planes, pour cela apres la declaration " << "\n# de la loi de contrainte plane, on indique : " << "\n# parametres_controle_pour_contraintes_planes_double_ " << "\n# - puis les parametres specifique de pilotage des contraintes planes double" << "\n# cf. la loi " << "\n# - pui le mot cle " << "\n# fin_parametres_controle_pour_contraintes_planes_double_" << "\n# " << "\n# Exemple de declaration: " << "\n# " << "\n# toto LOI_CRITERE " << "\n# TYPE_DE_CRITERE_ PLISSEMENT_MEMBRANE " << "\n# LOI_CONTRAINTES_PLANES " << "\n# NEWTON_LOCAL avec_parametres_de_reglage_ " << "\n# nb_iteration_maxi_ 20 " << "\n# nb_dichotomie_maxi_ 20 " << "\n# tolerance_residu_ 1.e-3 " << "\n# fin_parametres_reglage_Algo_Newton_ " << "\n# " << "\n# ISOELAS " << "\n# 200000 0.3 " << "\n# fin_loi_contrainte_plane # --- fin de la loi de contrainte plane " << "\n# fin_loi_interne # --- fin des lois internes" << "\n# parametres_controle_pour_contraintes_planes_double_" << "\n# NEWTON_LOCAL avec_parametres_de_reglage_" << "\n# nb_iteration_maxi_ 20 " << "\n# nb_dichotomie_maxi_ 20 " << "\n# tolerance_residu_ 5.e-3 " << "\n# tolerance_residu_rel_ 1.e-4 " << "\n# mini_hsurh0_ 1.e-4 " << "\n# mini_bsurb0_ 1.e-4 " << "\n# maxi_hsurh0_ 1.2 " << "\n# maxi_bsurb0_ 1.2 " << "\n# sortie_post_ 1 " << "\n# permet_affichage_ 3 " << "\n# choix_methode_cal_plis_memb_ 1 " << "\n# fin_parametres_reglage_Algo_Newton_ " << "\n# fin_parametres_controle_pour_contraintes_planes_double_" << "\n# " << "\n# -------------- parametres de controle ------ " << "\n# parametres a mettre en dernier entre les deux mots clefs: " << "\n# avec_parametres_controle_pour_loi_critere_ et fin_parametres_controle_pour_loi_critere_" << "\n# " << "\n# 1) controle de l'affichage: " << "\n# - l'affichage normale est fonction du parametre global d'affichage gerer " << "\n# par le niveau d'affichage cependant il est possible de permettre l'affichage " << "\n# a un niveau particulier (mot cle : permet_affichage_ suivi d'un nombre entier) " << "\n# l'affichage s'effectuera donc en fonction de l'affichage normale et de l'affichage " << "\n# 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), " << "\n# 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 " << "\n# uniquement de n " << "\n# " << "\n# ex: permet_affichage_ 5 " << "\n# " << "\n# 2) gestion eventuelle du recalcul des directions des plis " << "\n# - par defaut la direction des plis est recalculee a chaque iteration " << "\n# il est possible de changer ce comportement a l'aide de la definition d'une fonction nD " << "\n# qui doit renvoyer une valeur qui est transformee en entier: " << "\n# si == 0 on utilise la valeur stockee actuelle (== celle de l'iter precedente), " << "\n# si aucun calcul de direction n'a ete effectue, un premier calcul est fait " << "\n# si == 1 on recalcule les directions des plis, " << "\n# si == 2 on recalcule les directions des plis uniquement pour la zone " << "\n# non completement relachee a t, pour cette derniere on maintient le relachement, " << "\n# si == -1 on utilise la valeur stockee a t (celle precedente qui a convergee), " << "\n# si aucun calcul de direction n'a ete effectue, un premier calcul est fait " << "\n# si == -2 idem -1 , sauf que s'il n'y a pas de direction existante, on ne recalcule pas une " << "\n# nouvelle direction, on continue avec un calcul sans plis " << "\n# --> cela signifie que la zone de plis est totalement figee / au precedent incr" << "\n# si == -3 idem 0 , sauf que s'il n'y a pas de direction existante, on ne recalcule pas une " << "\n# nouvelle direction, on continue avec un calcul sans plis " << "\n# --> cela signifie que la zone de plis est totalement figee / a la precedente iter" << "\n# " << "\n# Pour cela on utilise le mot cle: recalcul_dir_plis_ suivi du nom de la fonction " << "\n# (ou eventuellement en declarant directement la fonction localement, " << "\n# et alors on passe une ligne apres la definition) " << "\n# " << "\n# exemple de mise en donnees: " << "\n# " << "\n# recalcul_dir_plis_ f_recalcul_pli " << "\n# " << "\n# dans cet exemple f_recalcul_pli est le nom d'une fonction qui doit avoir ete definie " << "\n# " << "\n# 3) une nouvelle methode de calcul des plis sur membrane est disponible " << "\n# le choix de la methode s'effectue via le mot cle : choix_methode_cal_plis_memb_ " << "\n# valeur par defaut: 1, nouvelle methode : 2 " << "\n# exemple de mise en donnees: " << "\n# choix_methode_cal_plis_memb_ 2 " << "\n# .... " << "\n# fin_loi_critere # --- fin de la loi critere " << "\n\n \n " << "\n# " << "\n# " << "\n\n \n "; // sort << "\n# ....... cas particulier 4) ........" // << "\n# Dans le cas d'un critere de membrane, il est possible de ponderer chaque terme de la somme de contrainte. La contrainte finale sera alors: " // << "\n# sigma = f1*sigma1+ f2*sigma2 + ..." // << "\n# Les facteurs de ponderation, sont des fonctions de grandeurs disponibles pendant le calcul: i.e.: deformation equivalente, " // << "\n# temperature, etc. " // << "\n# Pour ce faire, on indique sur la premiere ligne (apres la ligne contenant le mot cle LOI_CRITERE) le mot cle: " // << "\n# avec_fonction_de_ponderation_ suivit optionnellement (sur la meme ligne)" // << "\n# du type de calcul (mot cle: type_calcul= ) (1 ou 2) cf. expli si dessous, puis on passe a la ligne suivante " // << "\n# et on definit successivement chaque lois de la maniere suivante: " // << "\n# avant le mot cle definissant la loi , on indique le mot cle les_grandeur_ponderation= suivit de m (m < 11 maxi) couples " // << "\n# (un nomDeGrandeur A_k suivi de l'une des deux chaines: AuxNoeuds_ ou AuPti_ , indiquant ou est definit la grandeur) " // << "\n# L'ensemble des couples est terminer par le mot cle fin_grandeur_ponderation_ " // << "\n# On peut utiliser n'importe quelle grandeur definie (mais qui doit exister par ailleurs) " // << "\n# aux noeuds ou au point d'integration, cf. documentation " // << "\n# ensuite sur la ligne suivante on definit la fonction de ponderation f, qui est produit de fonction 1D g(A_k) :" // << "\n# f = Produit_{k=1}^m [ g_k(A_k)] " // << "\n# On doit donc definir m fonction 1D, d'où un mot cle: deb_fonct_ponder= " // << "\n# les noms de fonctions deja definies, ou alors la definition directe de la fonction (apres la def directe d'une" // << "\n# fonction, on passe a la ligne suivante pour continuer)" // << "\n# et enfin le mot cle: fin_fonct_ponder_ puis sur la ligne suivante: le nom de la loi" // << "\n# optionnellement, apres le nom de la loi, on peut indiquer (cf. expli si dessus) un des deux mots cle suivant: " // << "\n# sigma_seulement_ ou tangent_seulement_ " // << "\n# ensuite suivent les informations specifiques a la loi" // << "\n# sur la derniere ligne on doit indiquer le mot cle: fin_liste_lois_elementaires " // << "\n# " // << "\n# NB: option type_calcul= : en fait il y a deux type de loi possibles: " // << "\n# soit : sigma = somme_{i=1}^n ( f_i * sigma(loi_i)) , ce qui est le type 1 (par defaut) " // << "\n# soit : delta sigma = somme_{i=1}^n (f_i * delta sigma(loi_i)) , ce qui est le type 2" // << "\n# en tenant compte que les contraintes sont cumulees dans le type 2. " // << "\n# " // << "\n# exemple d'un somme ponderee de deux lois elastique, chacune ponderee de fonctions dependantes " // << "\n# de la vitesse de deformation equivalente et de la temperature, " // << "\n# " // << "\n# metal LOI_CRITERE " // << "\n# avec_fonction_de_ponderation_ " // << "\n# les_grandeur_ponderation= def_equivalente AuPti_ TEMP AuxNoeuds_ fin_grandeur_ponderation_ " // << "\n# deb_fonct_ponder= nom_fonc_1 nom_fonc_2 fin_fonct_ponder_ " // << "\n# ISOELAS " // << "\n# 210000 0.3 " // << "\n# les_grandeur_ponderation= def_equivalente AuPti_ TEMP AuxNoeuds_ fin_grandeur_ponderation_ " // << "\n# deb_fonct_ponder= nom_fonc_3 nom_fonc_4 fin_fonct_ponder_ " // << "\n# ISOELAS " // << "\n# 300 0.1 " // << "\n# fin_liste_lois_elementaires " // << "\n# " << endl; }; }; // test si la loi est complete int LoiCritere::TestComplet() {int ret = LoiAbstraiteGeneral::TestComplet(); list ::const_iterator ili,ilifin=lois_internes.end(); for (ili=lois_internes.begin();ili!=ilifin;ili++) ret *=(*ili)->TestComplet(); switch (type_critere) { case PLISSEMENT_MEMBRANE: {// on vérifie que les lois supports sont définies if ((loi_2DCP_de_3D == NULL) || (loi_1DCP2_de_3D == NULL)) { cout << "\n erreur : dans le cas d'un critere " << Nom_Critere_Loi(type_critere) << " le lois internes supports ne sont pas definies ... la loi n'est pas exploitable "; cout << "\n LoiCritere::TestComplet()"; ret = 0; } break; } case PLISSEMENT_BIEL: {// rien n'a vérifier break; } case RUPTURE_SIGMA_PRINC: case RUPTURE_EPS_PRINC: {// on vérifie que les lois supports sont définies if ((loi_2DCP_pour_rupture == NULL) || (loi_1DCP2_pour_rupture == NULL)) { cout << "\n erreur : dans le cas d'un critere " << Nom_Critere_Loi(type_critere) << " le lois internes supports ne sont pas definies ... la loi n'est pas exploitable "; cout << "\n LoiCritere::TestComplet()"; ret = 0; } break; } default : cout << "\nErreur : valeur incorrecte du type de critere defini= " << Nom_Critere_Loi(type_critere) << " !\n"; cout << "\n LoiCritere::TestComplet()"; ret = 0; }; return ret; }; // calcul d'un module d'young équivalent à la loi, ceci pour un // chargement nul double LoiCritere::Module_young_equivalent(Enum_dure temps,const Deformation & def ,SaveResul * saveResul_ex) { double E=0.; list ::const_iterator ili,ilifin=lois_internes.end(); list ::const_iterator ic,icfin=list_completude_calcul.end(); // récup des infos spécifiques SaveResul_LoiCritere & save_resul = *((SaveResul_LoiCritere*) saveResul_ex); list ::iterator lisave = save_resul.liste_des_SaveResul.begin(); // cas éventuelle des fonctions de pondération list ::iterator ipfonc; if (avec_ponderation) ipfonc = fonc_ponder.begin(); for (ili=lois_internes.begin(),ic=list_completude_calcul.begin();ili!=ilifin;ili++,ic++,lisave++) {if (*ic != TANGENT_UNIQUEMENT) {if ((avec_ponderation)&&((*ipfonc) != 1.)) {E +=(*ili)->Module_young_equivalent(temps,def,*lisave) * (*ipfonc);} else {E +=(*ili)->Module_young_equivalent(temps,def,*lisave);}; }; if (avec_ponderation) // on incrémente si on a de la pondération ipfonc++; }; //cout << "\n E= " << E; return E; }; // récupération d'un module de compressibilité équivalent à la loi, ceci pour un chargement nul // il s'agit ici de la relation -pression = sigma_trace/3. = module de compressibilité * I_eps double LoiCritere::Module_compressibilite_equivalent(Enum_dure temps,const Deformation & def,SaveResul * saveResul_ex) { double module_compressibilite=0.; list ::const_iterator ili,ilifin=lois_internes.end(); list ::const_iterator ic,icfin=list_completude_calcul.end(); // récup des infos spécifiques SaveResul_LoiCritere & save_resul = *((SaveResul_LoiCritere*) saveResul_ex); list ::iterator lisave = save_resul.liste_des_SaveResul.begin(); // cas éventuelle des fonctions de pondération list ::iterator ipfonc; if (avec_ponderation) ipfonc = fonc_ponder.begin(); for (ili=lois_internes.begin(),ic=list_completude_calcul.begin();ili!=ilifin;ili++,ic++,lisave++) {if (*ic != TANGENT_UNIQUEMENT) {if ((avec_ponderation)&&((*ipfonc) != 1.)) {module_compressibilite +=(*ili)->Module_compressibilite_equivalent(temps,def,*lisave) * (*ipfonc);} else {module_compressibilite +=(*ili)->Module_compressibilite_equivalent(temps,def,*lisave);}; }; if (avec_ponderation) // on incrémente si on a de la pondération ipfonc++; }; return module_compressibilite; }; // activation des données des noeuds et/ou elements nécessaires au fonctionnement de la loi // exemple: mise en service des ddl de température aux noeuds // ici la grandeur qui sert de proportion entre la première loi et la seconde void LoiCritere::Activation_donnees(Tableau& tabnoeud,bool dilatation,LesPtIntegMecaInterne& lesPtMecaInt) { if (avec_ponderation) { // on passe en revue les grandeurs servant au calcul des fonctions de proportion list ::iterator il,ilfin=list_ponderation.end(); for (il=list_ponderation.begin();il != ilfin;il++) { Ponderation& ponder = (*il); // pour simplifier int taille = ponder.Type_grandeur().Taille(); for (int i=1;i<= taille; i++) { // dans le cas de fonction de pondération venant des noeuds par interpolation // on active les ddl correspondant à la grandeur qui règle la proportion if (ponder.Valeur_aux_noeuds()(i)) {int nbnoeud = tabnoeud.Taille(); for (int i=1;i<=nbnoeud;i++) { // on vérifie que la variable type_grandeur existe sinon erreur if (tabnoeud(i)->Existe_ici(ponder.Type_grandeur()(i).Enum())) {tabnoeud(i)->Met_en_service(ponder.Type_grandeur()(i).Enum());} else { cout << "\n erreur: la grandeur " << ponder.Type_grandeur()(i) << " n'existe pas " << " il n'est pas possible d'utiliser une loi critere ponderee avec cette grandeur " << " il manque sans doute des donnees aux noeuds !!! " << "\n LoiCritere::Activation_donnees(..."; Sortie(1); }; }; } else { // cas d'un vrai ddl étendue // on commence par regarder si les pt meca int existent if ( ((LesPtIntegMecaInterne*) &lesPtMecaInt) == NULL) { cout << "\n *** erreur la loi critere ponderee ne peut pas s'utiliser ici telle quelle ***" << " demander une modification ! "; cout << "\n LoiCritere::Activation_donnees(.. " << endl; Sortie(1); }; // cas normal switch (ponder.Type_grandeur()(i).Position()-NbEnum_ddl()) {case 77: case 78: case 87: case 88: case 89: // cas de "def_duale_mises", cas de "Spherique_eps", cas de "def_duale_mises_maxi" {// et vitesse_def_equi// il faut que l'on active le calcul des invariants de déformations int nbpti = lesPtMecaInt.NbPti(); for (int i= 1;i<= nbpti;i++) lesPtMecaInt(i).Change_statut_Invariants_deformation (true); break; } case 81: // cas de "Spherique_sig" {// il faut que l'on active le calcul des invariants des contraintes int nbpti = lesPtMecaInt.NbPti(); for (int i= 1;i<= nbpti;i++) lesPtMecaInt(i).Change_statut_Invariants_contrainte (true); break; } default: cout << "\n erreur, le type de proportion " << ponder.Type_grandeur()(i) << " n'est pas disponible " << " pour l'instant au point d'integration ! " << "\n LoiCritere::Activation_donnees(.... "; break; }; }; }; }; }; // ---maintenant appel des lois élémentaires list ::const_iterator ili,ilifin=lois_internes.end(); for (ili=lois_internes.begin();ili!=ilifin;ili++) (*ili)->Activation_donnees(tabnoeud,dilatation,lesPtMecaInt); // appel de la méthode de la classe mère Loi_comp_abstraite::Activ_donnees(tabnoeud,dilatation,lesPtMecaInt); }; // 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 LoiCritere::Grandeur_particuliere (bool absolue, List_io& liTQ,Loi_comp_abstraite::SaveResul * saveDon,list& decal) const { // tout d'abord on récupère le conteneur SaveResul_LoiCritere & save_resul = *((SaveResul_LoiCritere*) saveDon); int dim = ParaGlob::Dimension(); list ::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois list ::const_iterator ili,ilifin=lois_internes.end(); // maintenant on s'occupe des grandeurs de la loi critere elle même, List_io::iterator itq,itqfin=liTQ.end(); list::iterator idecal=decal.begin(); int dim_espace = ParaGlob::Dimension(); 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 { EnumTypeQuelconque enuTQ = tipParticu.EnuTypeQuelconque().EnumTQ(); // -----cas de la direction de pli éventuelle if (enuTQ == DIRECTION_PLI) { Tab_Grandeur_Coordonnee& gr= *((Tab_Grandeur_Coordonnee*) (*itq).Grandeur_pointee()); // pour simplifier switch (type_critere) { case PLISSEMENT_MEMBRANE: {// tout d'abord on regarde s'il y des vecteurs propres // if (((save_resul.cas_cal_plis == 1)|| (save_resul.cas_cal_plis == 2)|| (save_resul.cas_cal_plis == 3)) if (((save_resul.cas_cal_plis == 2)|| (save_resul.cas_cal_plis == 3)) && (save_resul.V_P_sig != NULL)) // cas où il y a des vecteurs propres, la direction des plis est le premier vecteur, + éventuellement // le deuxième s'il y a deux plis { gr(1) = save_resul.eps_pli(1) * (*save_resul.V_P_sig)(1); gr(2) = save_resul.eps_pli(2) * (*save_resul.V_P_sig)(2); } else // sinon cela veut dire qu'il n'y a pas de pli, on sort un vecteur nul {Coordonnee coor(dim_espace); // un type coordonnee typique gr(1) = coor; gr(2) = coor; }; break; } case PLISSEMENT_BIEL: {// tout d'abord on regarde s'il y des vecteurs propres if (save_resul.V_P_sig != NULL) // cas où il y a des vecteurs propres, la direction des plis est le premier vecteur, + éventuellement // le deuxième s'il y a deux plis {gr(1) = save_resul.eps_pli(1) * (*save_resul.V_P_sig)(1); Coordonnee coor(dim_espace); gr(2) = coor; } else // sinon cela veut dire qu'il n'y a pas de pli, on sort un vecteur nul {Coordonnee coor(dim_espace); // un type coordonnee typique gr(1) = coor; gr(2) = coor; }; break; } default : cout << "\nErreur : valeur incorrecte du type de critere defini= " << Nom_Critere_Loi(type_critere) << " !\n"; cout << "\n LoiCritere::Grandeur_particuliere(..."; Sortie(1); }; }; if (enuTQ == DIRECTION_PLI_NORMEE) // ici il s'agit uniquement des vecteurs normés { Tab_Grandeur_Coordonnee& gr= *((Tab_Grandeur_Coordonnee*) (*itq).Grandeur_pointee()); // pour simplifier switch (type_critere) { case PLISSEMENT_MEMBRANE: // {if (((save_resul.cas_cal_plis == 1)|| (save_resul.cas_cal_plis == 2)|| (save_resul.cas_cal_plis == 3)) {if (( (save_resul.cas_cal_plis == 2)|| (save_resul.cas_cal_plis == 3)) && (save_resul.V_P_sig != NULL)) // cas où il y a des plis correctement calculés // on regarde s'il y des vecteurs propres: normalement il devrait en avoir // if (save_resul.V_P_sig != NULL) // cas où il y a des vecteurs propres, la direction des plis est le premier vecteur, + éventuellement // le deuxième s'il y a deux plis { gr(1) = (*save_resul.V_P_sig)(1); gr(2) = (*save_resul.V_P_sig)(2); } else // sinon cela veut dire qu'il n'y a pas de pli, on sort un vecteur nul // ou que l'on n'a pas pu les calculer {Coordonnee coor(dim_espace); // un type coordonnee typique gr(1) = coor; gr(2) = coor; }; break; } case PLISSEMENT_BIEL: {// tout d'abord on regarde s'il y des vecteurs propres if (save_resul.V_P_sig != NULL) // cas où il y a des vecteurs propres, la direction des plis est le premier vecteur, + éventuellement // le deuxième s'il y a deux plis {gr(1) = (*save_resul.V_P_sig)(1); Coordonnee coor(dim_espace); gr(2) = coor; } else // sinon cela veut dire qu'il n'y a pas de pli, on sort un vecteur nul {Coordonnee coor(dim_espace); // un type coordonnee typique gr(1) = coor; gr(2) = coor; }; break; } default : cout << "\nErreur : valeur incorrecte du type de critere defini= " << Nom_Critere_Loi(type_critere) << " !\n"; cout << "\n LoiCritere::Grandeur_particuliere(..."; Sortie(1); }; }; if (enuTQ == INDIC_CAL_PLIS) // ici il s'agit d'un scalaire { Grandeur_scalaire_entier& gr= *((Grandeur_scalaire_entier*) (*itq).Grandeur_pointee()); // pour simplifier switch (type_critere) { case PLISSEMENT_MEMBRANE: case PLISSEMENT_BIEL: // pour les biels on ne sait pas encore !! {*(gr.ConteneurEntier()) = save_resul.cas_cal_plis; break; } default : // on annule car l'info ne correspond a priori à rien // donc a priori pas de calcul effectué *(gr.ConteneurEntier()) = 0; }; }; //-------- la suite est identique aux lois additives, devra être modifié sans doute --------- // 2) -----cas des contraintes individuelles à chaque loi à t if (enuTQ == CONTRAINTE_INDIVIDUELLE_A_CHAQUE_LOI_A_T) { Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier // on boucle sur les lois list ::const_iterator ili,ilifin=lois_internes.end(); list ::iterator isig_t; for (ili=lois_internes.begin(),isig_t = save_resul.l_sigoHH_t.begin(); ili!=ilifin;ili++,isig_t++) {// dans le cas des plis, la loi principale est 2D ou 1D alors que // le conteneur est un tenseur d'ordre 3, on transfert en fonction TenseurHH* sigHH = (*(isig_t)); // pour simplifier if (Dabs(sigHH->Dimension()) != dim) {tyTQ(1+(*idecal)).Affectation_trans_dimension(*sigHH,true); } else // cas ordre 3 {tyTQ(1+(*idecal)) = *(*(isig_t)); }; // puis on décale (*idecal)++; }; }; // 3) -----cas de l'énergie élastique individuelles à chaque loi à t if (enuTQ == ENERGIE_ELASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier // on boucle sur les lois list ::const_iterator ili,ilifin=lois_internes.end(); list ::iterator ienerg_t; for (ili=lois_internes.begin(),ienerg_t = save_resul.l_energ_t.begin(); ili!=ilifin;ili++,ienerg_t++) { tyTQ(1+(*idecal)) = (*ienerg_t).EnergieElastique(); (*idecal)++; }; }; // 4) -----cas de l'énergie plastique individuelles à chaque loi à t if (enuTQ == ENERGIE_PLASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier // on boucle sur les lois list ::const_iterator ili,ilifin=lois_internes.end(); list ::iterator ienerg_t; for (ili=lois_internes.begin(),ienerg_t = save_resul.l_energ_t.begin(); ili!=ilifin;ili++,ienerg_t++) { tyTQ(1+(*idecal)) = (*ienerg_t).DissipationPlastique(); (*idecal)++; }; }; // 5) -----cas de l'énergie visqueuse individuelles à chaque loi à t if (enuTQ == ENERGIE_VISQUEUSE_INDIVIDUELLE_A_CHAQUE_LOI_A_T) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier // on boucle sur les lois list ::const_iterator ili,ilifin=lois_internes.end(); list ::iterator ienerg_t; for (ili=lois_internes.begin(),ienerg_t = save_resul.l_energ_t.begin(); ili!=ilifin;ili++,ienerg_t++) { tyTQ(1+(*idecal)) = (*ienerg_t).DissipationVisqueuse(); (*idecal)++; }; }; // 6) -----cas de fonction de ponderation des lois if(avec_ponderation) if (enuTQ == FONC_PONDERATION) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier // on boucle sur les lois list ::const_iterator ipfonc, ipfonc_fin = fonc_ponder.end(); list ::const_iterator ifo = save_resul.f_ponder_t.begin(); for (ipfonc=fonc_ponder.begin();ipfonc != ipfonc_fin;ipfonc++,ifo++) { tyTQ(1+(*idecal)) = (*ifo); (*idecal)++; }; }; }; }; // puis appel des lois élémentaires générales for (ili=lois_internes.begin();ili!=ilifin;ili++,isave++) (*ili)->Grandeur_particuliere(absolue,liTQ,*isave,decal); // puis on examine le cas des différents critères et on récupère les infos internes associées switch (type_critere) { case PLISSEMENT_MEMBRANE: // {// on récupère les infos pour la loi 1D, dans le cas où il y a des plis // si pas de plis, la loi loi_1DCP2_de_3D n'a pas été sollicité, dans ce cas on ne sort rien if (save_resul.V_P_sig != NULL) loi_1DCP2_de_3D->Grandeur_particuliere(absolue,liTQ,*(save_resul.liste_des_SaveResul.begin()),decal); break; } case PLISSEMENT_BIEL: {// ici il n'y a rien pour l'instant à récupérer break; } case RUPTURE_SIGMA_PRINC: case RUPTURE_EPS_PRINC: {cout << "\nwarning : pour l'instant rien il n'y a rien de prevu en sortie " << " de specifique pour les criteres: RUPTURE_SIGMA_PRINC et RUPTURE_EPS_PRINC, a completer !!!\n"; cout << "\n LoiCritere::Grandeur_particuliere(..."; Sortie(1); break; } default : cout << "\nErreur : valeur incorrecte du type de critere defini= " << Nom_Critere_Loi(type_critere) << " !\n"; cout << "\n LoiCritere::Grandeur_particuliere(..."; Sortie(1); }; }; // récupération 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 LoiCritere::ListeGrandeurs_particulieres(bool absolue,List_io& liTQ) const { // tout d'abord on passe en revue les grandeurs des lois associées // ** au niveau de l'exécution ce sera l'inverse de cette ordre: on s'occupera d'abord de this puis les lois internes // ** mais a priori cela n'a pas d'importance // appel des lois élémentaires list ::const_iterator ili,ilifin=lois_internes.end(); int nb_loi = lois_internes.size(); for (ili=lois_internes.begin();ili!=ilifin;ili++) (*ili)->ListeGrandeurs_particulieres(absolue,liTQ); // on examine le cas des différents critères et on récupère les infos internes associées switch (type_critere) { case PLISSEMENT_MEMBRANE: // {// la partie loi 2D CP a déjà été traité, car il s'agit de la première loi interne loi_1DCP2_de_3D->ListeGrandeurs_particulieres(absolue,liTQ); break; } case PLISSEMENT_BIEL: {// ici il n'y a rien pour l'instant à récupérer break; } case RUPTURE_SIGMA_PRINC: case RUPTURE_EPS_PRINC: {// la partie loi 2D CP a déjà été traité, car il s'agit de la première loi interne loi_1DCP2_pour_rupture->ListeGrandeurs_particulieres(absolue,liTQ); break; } default : cout << "\nErreur : valeur incorrecte du type de critere defini= " << Nom_Critere_Loi(type_critere) << " !\n"; cout << "\n LoiCritere::ListeGrandeurs_particulieres(..."; Sortie(1); }; // maintenant on s'occupe des grandeurs de la loi critère elle même, int dim_espace = ParaGlob::Dimension(); switch (type_critere) { case PLISSEMENT_MEMBRANE: // { // -----cas de la direction de pli éventuelle Coordonnee coor(dim_espace); // un type coordonnee typique Tab_Grandeur_Coordonnee grand5(coor,2); // deux plis maxi // la direction des plis dont l'intensité = la norme des vecteurs // sous forme d'un vecteur, exprimée aux pti TypeQuelconque typQ(DIRECTION_PLI,SIG11,grand5);liTQ.push_back(typQ); // idem mais avec des vecteurs normés TypeQuelconque typQN(DIRECTION_PLI_NORMEE,SIG11,grand5);liTQ.push_back(typQN); // L'indicateur de calcul de plis Grandeur_scalaire_entier gscal; TypeQuelconque typGI(INDIC_CAL_PLIS,SIG11,gscal);liTQ.push_back(typGI); break; } case PLISSEMENT_BIEL: { // -----cas de la direction de pli éventuelle Coordonnee coor(dim_espace); // un type coordonnee typique Tab_Grandeur_Coordonnee grand5(coor,2); // ne seule direction de pli // **** mais pour l'instant j'en mets 2 de manière à être cohérent avec les membranes // sinon pb en sortie des grandeurs // la direction des plis, sous forme d'un vecteur, exprimée aux pti TypeQuelconque typQ(DIRECTION_PLI,SIG11,grand5);liTQ.push_back(typQ); // idem mais avec des vecteurs normés TypeQuelconque typQN(DIRECTION_PLI_NORMEE,SIG11,grand5);liTQ.push_back(typQN); break; } default : break; // rien car on a déjà traité ce cas }; //-------- la suite est identique aux lois additives, devra être modifié sans doute --------- // 2) -----cas des contraintes individuelles à chaque loi à t uniquement {// ici il s'agit du tenseur des contraintes du pas précédent ou du pas actuel //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == CONTRAINTE_INDIVIDUELLE_A_CHAQUE_LOI_A_T) { Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+nb_loi; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TenseurHH* tens = NevezTenseurHH(ParaGlob::Dimension()); // un tenseur typique // en fait on utilise systématiquement un tenseur d'ordre le + élevé, car c'est le conteneur le plus générique // et Tab_Grandeur_TenseurHH ne supporte que des tenseurs du même ordre donc s'il y a un tenseur élevé // interne il faut que tous les tenseurs soient du même ordre Tab_Grandeur_TenseurHH gtHH(*tens,nb_loi); // def d'un type quelconque représentatif TypeQuelconque typQ(CONTRAINTE_INDIVIDUELLE_A_CHAQUE_LOI_A_T,SIG11,gtHH); liTQ.push_back(typQ); delete tens; // car on n'en a plus besoin }; }; // pour toutes les énergies Tableau tab_double(nb_loi); Tab_Grandeur_scalaire_double grand_courant(tab_double); // 3) -----cas de l'énergie élastique individuelles à chaque loi à t uniquement //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == ENERGIE_ELASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+nb_loi; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(ENERGIE_ELASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; // 4) -----cas de l'énergie plastique individuelles à chaque loi à t uniquement //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == ENERGIE_PLASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+nb_loi; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) { TypeQuelconque typQ1(ENERGIE_PLASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; // 5) -----cas de l'énergie visqueuse individuelles à chaque loi à t uniquement //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == ENERGIE_VISQUEUSE_INDIVIDUELLE_A_CHAQUE_LOI_A_T) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+nb_loi; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) { TypeQuelconque typQ1(ENERGIE_VISQUEUSE_INDIVIDUELLE_A_CHAQUE_LOI_A_T,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; // 6) -----cas de fonction de ponderation des lois {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == FONC_PONDERATION) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+nb_loi; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(FONC_PONDERATION,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; }; // indique le type Enum_comp_3D_CP_DP_1D correspondant à une loi de comportement // la fonction est simple dans le cas d'une loi basique, par contre dans le cas // d'une loi combinée, la réponse dépend des lois internes donc c'est redéfini // dans les classes dérivées Enum_comp_3D_CP_DP_1D LoiCritere::Comportement_3D_CP_DP_1D() { // si la liste des lois internes n'est pas nulle, on ramène le cas de la première loi if (lois_internes.size() != 0) {return (*(lois_internes.begin()))->Comportement_3D_CP_DP_1D();} else // sinon on ramène le cas non défini {return RIEN_COMP_3D_CP_DP_1D;}; }; //----- 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 LoiCritere::Lecture_base_info_loi(ifstream& ent,const int cas,LesReferences& lesRef,LesCourbes1D& lesCourbes1D ,LesFonctions_nD& lesFonctionsnD) { if (cas == 1) { string st1,st2,nom_completude_calcul; int nb_loi; ent >> st1 >> nb_loi >> st1 >> type_calcul >> st1 >> avec_ponderation >> st2; // on supprime la liste de loi actuellement présente par sécurité list ::iterator ilifin=lois_internes.end(); list ::iterator ilideb=lois_internes.begin(); lois_internes.erase(ilideb,ilifin); // idem pour list_completude_calcul list ::iterator icfin=list_completude_calcul.end(); list ::iterator icdeb=list_completude_calcul.begin(); list_completude_calcul.erase(icdeb,icfin); // idem pour la liste list_ponderation list ::iterator iefin=list_ponderation.end(); list ::iterator iedeb=list_ponderation.begin(); list_ponderation.erase(iedeb,iefin); // idem pour la liste fonc_ponder list ::iterator ieefin=fonc_ponder.end(); list ::iterator ieedeb=fonc_ponder.begin(); fonc_ponder.erase(ieedeb,ieefin); // on boucle sur le nombre de loi for (int i=1;i<= nb_loi; i++) { if (avec_ponderation) {ent >> st1;int taille; ent >> taille; Ponderation ponder; // inter ponder.Type_grandeur().Change_taille(taille); ponder.Valeur_aux_noeuds().Change_taille(taille); ponder.C_proport().Change_taille(taille); for (int i=1;i<=taille;i++) ent >> ponder.Type_grandeur()(i) >> ponder.Valeur_aux_noeuds()(i); // les courbes ent >> st1; for (int i=1;i<=taille;i++) ponder.C_proport()(i) = lesCourbes1D.Lecture_pour_base_info(ent,cas,ponder.C_proport()(i)); // enreg list_ponderation.push_back(ponder); fonc_ponder.push_back(1.); // préparation de la place }; //------ maintenant les lois ent >> st1 >> nom_completude_calcul ; // lecture du nom de la loi et du type d'action if (nom_completude_calcul == "CONTRAINTE_ET_TANGENT") { list_completude_calcul.push_back(CONTRAINTE_ET_TANGENT);} else if (nom_completude_calcul == "CONTRAINTE_UNIQUEMENT") { list_completude_calcul.push_back(CONTRAINTE_UNIQUEMENT);} else if (nom_completude_calcul == "TANGENT_UNIQUEMENT") { list_completude_calcul.push_back(TANGENT_UNIQUEMENT);} else { cout << "\n *** erreur en lecture du type d'action a faire avec la loi, on a lue " << nom_completude_calcul << " au lieu d'un des noms suivants CONTRAINTE_ET_TANGENT CONTRAINTE_UNIQUEMENT TANGENT_UNIQUEMENT "; cout << "\n LoiCritere::Lecture_base_info_loi(..."; Sortie(1); }; // definition de la loi LoiAbstraiteGeneral * pt = LesLoisDeComp::Def_loi(st1); lois_internes.push_back((Loi_comp_abstraite*) pt); // enregistrement de la loi // lecture des informations propres à la loi pt->Lecture_base_info_loi(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD); }; // les autres paramètres string toto; ent >> toto; // entête // le niveau d'affichage Lecture_permet_affichage(ent,cas,lesFonctionsnD); // choix de la methode pour le calcul de plis ent >> st1 >> choix_methode_cal_plis_memb; // cas de recalcul_dir_plis {int choix; ent >> st1 >> choix; if (choix) recalcul_dir_plis = lesFonctionsnD.Lecture_pour_base_info(ent,cas,recalcul_dir_plis); } } else { // on boucle directement sur les lois déjà définis list ::iterator ili,ilifin=lois_internes.end(); for (ili=lois_internes.begin();ili!=ilifin;ili++) (*ili)->Lecture_base_info_loi(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 LoiCritere::Ecriture_base_info_loi(ofstream& sort,const int cas) { if (cas == 1) { sort << "\n LOI_CRITERE " << lois_internes.size() << " "; sort << "\n type_calcul_additif " << type_calcul; sort << " avec_ponderation "; if (avec_ponderation) {sort << 1 ;} else {sort << 0;}; sort <<" ,_les_lois: "; list ::const_iterator ili,ilifin=lois_internes.end(); list ::const_iterator ic,icfin=list_completude_calcul.end(); list ::const_iterator ipon; if (avec_ponderation) ipon = list_ponderation.begin(); for (ili=lois_internes.begin(),ic=list_completude_calcul.begin();ili!=ilifin;ili++,ic++) { if (avec_ponderation) { sort << "\n avec_fonctions_de_ponderation_des_grandeurs: "; const Ponderation& ponder = (*ipon); // pour simplifier int taille = (ponder.Const_Type_grandeur()).Taille(); sort << taille << " "; for (int i=1;i<=taille;i++) {sort << ponder.Const_Type_grandeur()(i) << " " << ponder.Const_Valeur_aux_noeuds()(i) << " ";}; // les courbes sort << "\n les_courbes: "; for (int i=1;i<=taille;i++) { LesCourbes1D::Ecriture_pour_base_info(sort,cas,ponder.Const_C_proport()(i));}; ipon++; }; sort << "\n " << (*ili)->Nom_comport() << " "; switch (*ic) {case CONTRAINTE_ET_TANGENT: sort << " CONTRAINTE_ET_TANGENT "; break; case CONTRAINTE_UNIQUEMENT: sort << " CONTRAINTE_UNIQUEMENT "; break; case TANGENT_UNIQUEMENT: sort << " TANGENT_UNIQUEMENT "; break; }; (*ili)->Ecriture_base_info_loi(sort,cas); }; // affichage autres paramètre sort << "\n autres-parametres_loi_critere:--> "; // niveau d'affichage Affiche_niveau_affichage(sort,cas); // choix de la méthode pour le calcul de plis sort << "\n choix_methode_cal_plis_memb= " << choix_methode_cal_plis_memb; // cas de recalcul_dir_plis sort << "\n recalcul_dir_plis= "; if (recalcul_dir_plis == NULL) {sort << " 0 ";} else {sort << " 1 "; LesFonctions_nD::Ecriture_pour_base_info(sort,cas,recalcul_dir_plis); }; } else { list ::const_iterator ili,ilifin=lois_internes.end(); for (ili=lois_internes.begin();ili!=ilifin;ili++) (*ili)->Ecriture_base_info_loi(sort,cas); }; }; // activation du stockage de grandeurs quelconques qui pourront ensuite être récupéré // via le conteneur SaveResul, si la grandeur n'existe pas ici, aucune action void LoiCritere::Activation_stockage_grandeurs_quelconques(list & listEnuQuelc) { // def du conteneur de grandeurs quelconques, initialisée à 0 Grandeur_scalaire_double grand_courant(0.); // récup de la liste de stockage list & listlocale = ListQuelc_mis_en_acces_localement(); // on parcours la liste des grandeurs à activer // et on remplit la liste locale list ::iterator il, ilfin = listEnuQuelc.end(); for (il = listEnuQuelc.begin();il != ilfin; il++) // for (EnumTypeQuelconque enu : listEnuQuelc) // on ne remplit que s'il s'agit d'une grandeur qui peut-être accessible {switch (*il) {case DIRECTION_PLI : case INDIC_CAL_PLIS: listlocale.push_back(*(il)); break; default: ; // pour les autres cas on ne fait rien }; }; // on supprime les doublons localement listlocale.sort(); // on ordonne la liste listlocale.unique(); // suppression des doublons }; // insertion des conteneurs ad hoc concernant le stockage de grandeurs quelconques // passée en paramètre, dans le save result: ces conteneurs doivent être valides // c-a-d faire partie de listdeTouslesQuelc_dispo_localement void LoiCritere::Insertion_conteneur_dans_save_result(SaveResul * sr) { // récup de la liste de stockage list & listlocale = ListQuelc_mis_en_acces_localement(); // on spécialise saveresult SaveResul_LoiCritere & save_resul = *((SaveResul_LoiCritere*) sr); // -- autre stockage éventuel en fonction des grandeurs quelconques demandées par d'autres lois // on va regarder s'il faut activer ou non, pour le cas // de la récupération de grandeur quelconque au moment de l'utilisation de la loi List_io ::iterator jk,jkfin = listlocale.end(); int dim_espace = ParaGlob::Dimension(); for (jk=listlocale.begin();jk != jkfin;jk++) {EnumTypeQuelconque enu = *jk; switch (enu) {case DIRECTION_PLI: { // on crée le conteneur ad hoc pour le passage d'info // def d'un conteneur de grandeurs quelconques, initialisée à 0 Coordonnee coor(dim_espace); // un type coordonnee typique Tab_Grandeur_Coordonnee grand5(coor,2); // deux plis maxi // la direction des plis dont l'intensité = la norme des vecteurs // sous forme d'un vecteur, exprimée aux pti TypeQuelconque typQ(DIRECTION_PLI,SIG11,grand5); save_resul.map_type_quelconque[enu]=(typQ); break; } case INDIC_CAL_PLIS : { // on crée le conteneur ad hoc pour le passage d'info // def d'un conteneur de grandeurs quelconques, initialisée à 0 Grandeur_scalaire_entier grand_courant(0); TypeQuelconque typQ1(enu,SIG11,grand_courant); save_resul.map_type_quelconque[enu]=(typQ1); break; } default: cout << "\n *** erreur on demande l'acces a : " << NomTypeQuelconque(enu) << " or celui-ci n'est pas dispo pour la loi "; this->Affiche(); cout << " revoir la mise en donnees ! " << endl; Sortie(1); }; }; }; // ========== codage des METHODES VIRTUELLES protegees:================ // calcul des contraintes a t+dt void LoiCritere::Calcul_SigmaHH (TenseurHH& sigHH_t,TenseurBB& DepsBB,DdlElement & tab_ddl, TenseurBB & gijBB_t,TenseurHH & gijHH_t,BaseB& giB,BaseH& gi_H, TenseurBB & epsBB_, TenseurBB & delta_epsBB, TenseurBB & gijBB_,TenseurHH & gijHH_,Tableau & d_gijBB_, double& jacobien_0,double& jacobien,TenseurHH & sigHH ,EnergieMeca & energ,const EnergieMeca & ,double& module_compressibilite,double& module_cisaillement ,const Met_abstraite::Expli_t_tdt& ex) { // on commence par créer un tenseur contrainte qui totalisera toutes les contraintes int dim_tens = sigHH.Dimension(); TenseurHH* sigtotalHH = (NevezTenseurHH(dim_tens,0.)); TenseurHH* zeroHH = (NevezTenseurHH(dim_tens,0.)); SaveResul_LoiCritere & save_resul = *((SaveResul_LoiCritere*) saveResul); module_compressibilite=module_cisaillement=0.; // init energ.Inita(0.); // initialisation des énergies mises en jeux // on balaie l'ensemble des lois list ::iterator ili,ilifin=lois_internes.end(); list ::const_iterator ic,icfin=list_completude_calcul.end(); // cas éventuelle des fonctions de pondération list ::iterator ipfonc; if (avec_ponderation) ipfonc = fonc_ponder.begin(); list ::iterator isig,isig_t; list ::iterator ienerg,ienerg_t; list ::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois for (ili=lois_internes.begin(),isig_t = save_resul.l_sigoHH_t.begin(),isig = save_resul.l_sigoHH.begin() ,ienerg = save_resul.l_energ.begin(),ienerg_t = save_resul.l_energ_t.begin(),ic=list_completude_calcul.begin(); ili!=ilifin;ili++,isig_t++,isig++,isave++,ienerg++,ienerg_t++,ic++) { // dimensionnement si nécessaire if ((*isig)->Dimension()!=sigHH_t.Dimension()) { delete (*isig); (*isig)=NevezTenseurHH(sigHH_t.Dimension(),0.);}; if ((*isig_t)->Dimension()!=sigHH_t.Dimension()) { delete (*isig_t); (*isig_t)=NevezTenseurHH(sigHH_t.Dimension(),0.);}; // initialisation du tenseurs contrainte pour le prochain calcul de la contrainte (*(*isig)) = *zeroHH; double compress_inter=0.; double cisaill_inter=0; // init // passage des informations spécifique à la loi liste_des_SaveResul (*ili)->IndiqueSaveResult(*isave); (*ili)->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca (*ili)->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours // -- première phase: préparation de calcul pour l'application d'un critère const Met_abstraite::Expli_t_tdt* ex_expli= (Met_abstraite::Expli_t_tdt*) &ex; const Met_abstraite::Impli* ex_impli =NULL; const Met_abstraite::Umat_cont* ex_umat = NULL; int retour_pre_critere = Pre_Critere (DepsBB,epsBB_,delta_epsBB,jacobien_0,jacobien ,ex_expli,ex_impli,ex_umat); // calcul de la contrainte résultante, if (*ic != TANGENT_UNIQUEMENT) { (*ili)->Calcul_SigmaHH((*(*isig_t)),DepsBB,tab_ddl,gijBB_t,gijHH_t,giB,gi_H,epsBB_,delta_epsBB, gijBB_,gijHH_,d_gijBB_,jacobien_0,jacobien,(*(*isig)) ,(*ienerg),(*ienerg_t),compress_inter,cisaill_inter,ex); //if (compress_inter == 0. ) // {cout << "\n debug: LoiCritere::Calcul_SigmaHH:... " // << " compress= "<< compress_inter ; // TenseurHH* ptHH = NevezTenseurHH((*(*isig))); // (*(*isig)).BaseAbsolue(*ptHH,giB); // cout << "\n sigHH= en giB "; (*(*isig)).Ecriture(cout); // cout << "\n sigma en absolu: "; // ptHH->Ecriture(cout); // cout << "\n module_compressibilite= "<Calcul_SigmaHH((*(*isig_t)),DepsBB,tab_ddl,gijBB_t,gijHH_t,giB,gi_H,epsBB_,delta_epsBB, // gijBB_,gijHH_,d_gijBB_,jacobien_0,jacobien,(*(*isig)) // ,(*ienerg),(*ienerg_t),compress_inter,cisaill_inter,ex); // } // if ((ParaGlob::NiveauImpression() > 8) || (Permet_affichage() > 5)) // cout << "\n test1: LoiCritere::Calcul_SigmaHH:... " << flush; #ifdef MISE_AU_POINT // sortie éventuelle d'infos if (Permet_affichage() > 5) { cout << "\nLoiCritere::Calcul_SigmaHH: avant critere "; cout << "\n ele= "<< (ptintmeca_en_cours->Nb_ele()) << ", nbpti= "<< (ptintmeca_en_cours->Nb_pti()); //if (sigHH.MaxiComposante() > 20.) TenseurBB* ptBB = NevezTenseurBB(epsBB_); epsBB_.BaseAbsolue(*ptBB,(gi_H)); cout << "\n eps en absolu: "; ptBB->Ecriture(cout); delta_epsBB.BaseAbsolue(*ptBB,gi_H); cout << "\n delta eps en absolu: "; ptBB->Ecriture(cout); TenseurHH* ptHH = NevezTenseurHH((*(*isig))); (*(*isig)).BaseAbsolue(*ptHH,giB); cout << "\n base giB(1) "<< giB(1) << "\n base giB(2) "<< giB(2); cout << "\n sigHH= en giB "; (*(*isig)).Ecriture(cout); cout << "\n sigma en absolu: "; ptHH->Ecriture(cout); delete ptBB; delete ptHH; }; #endif // -- on applique le critère ce qui peut changer ou pas les résultats précédents bool implicit = false;bool en_base_absolu = false; Met_abstraite::Umat_cont umat_transfert; // une umat inter ex.Recup_Umat_cont(umat_transfert); //if ((ptintmeca_en_cours->Nb_ele() == 100) && (ptintmeca_en_cours->Nb_pti() == 1)) // cout << "\n debug: LoiCritere::Calcul_SigmaHH:... " << flush; int retour_critere = Critere (en_base_absolu, (*(*isig_t)),DepsBB,epsBB_,delta_epsBB,jacobien_0,jacobien ,(*(*isig)),*d_sigma_deps_inter ,(*ienerg),(*ienerg_t),compress_inter,cisaill_inter,implicit,umat_transfert ); // if ((ParaGlob::NiveauImpression() > 8) || (Permet_affichage() > 5)) //if (compress_inter == 0. ) // {cout << "\n debug: LoiCritere::Calcul_SigmaHH:... " // << " compress= "<< compress_inter ; // TenseurHH* ptHH = NevezTenseurHH((*(*isig))); // (*(*isig)).BaseAbsolue(*ptHH,giB); // cout << "\n sigHH= en giB "; (*(*isig)).Ecriture(cout); // cout << "\n sigma en absolu: "; // ptHH->Ecriture(cout); // cout << "\n module_compressibilite= "< 5) { cout << "\nLoiCritere::Calcul_SigmaHH: apres l'application du critere: "; TenseurHH* ptHH = NevezTenseurHH((*(*isig))); (*(*isig)).BaseAbsolue(*ptHH,giB); cout << "\n sigHH= en giB "; (*(*isig)).Ecriture(cout); cout << "\n sigma en absolu: "; ptHH->Ecriture(cout); cout << "\n module_compressibilite= "<MaxiComposante() > 20.) // cout << "\n debug LoiCritere::Calcul_SigmaHH " // << "(ptHH->MaxiComposante() > 20.) !! "; ////------ debug delete ptHH; }; #endif switch (retour_critere) {case 0: // cas d'un pb if (Permet_affichage() > 4) cout << "\n pb dans l'application du critere, on continue sans tenir compte du critere "; if (Permet_affichage() > 5) {cout << "\n **>> il y a eu un pb que l'on n'a pas pu resoudre, rien n'a ete modifie "; if (ptintmeca_en_cours != NULL) ptintmeca_en_cours->Signature(); cout << "\n retour_critere= "<< retour_critere ; }; break; case 1: break; // le critère n'a rien changé case 2: if (Permet_affichage() > 5) {cout << "\n **>> l'application du critere conduit a une contrainte nulle "; if (ptintmeca_en_cours != NULL) ptintmeca_en_cours->Signature(); //cout << "\n retour_critere= "<< retour_critere ; } break; // l'application du critère -> tout nul case 3: break; // il y a eu des modification default: cout << "\n *** cas non prevu ! " << "\n LoiCritere::Calcul_SigmaHH (.." << endl; Sortie(2); break; }; // --- traitement en fonction du type de calcul // if (retour_critere != 2) // ==1 signifie que tout est nul, dans ce cas ce n'est pas la peine d'ajouter // transitoirement on va mettre une petite raideur // if (retour_critere == 2) // { compress_inter /= 1000.; // cisaill_inter /= 1000.; // }; {if ((avec_ponderation)&&((*ipfonc) != 1.)) {module_compressibilite += (*ipfonc)*compress_inter; module_cisaillement += (*ipfonc)*cisaill_inter; energ += (*ienerg) * (*ipfonc); // update des énergies totales (*sigtotalHH) += (*ipfonc)*(*(*isig)); // on ajoute la contrainte au total } else {module_compressibilite += compress_inter; module_cisaillement += cisaill_inter; energ += (*ienerg); // update des énergies totales (*sigtotalHH) += (*(*isig)); // on ajoute la contrainte au total }; }; if (avec_ponderation) // on incrémente si on a de la pondération ipfonc++; }; }; // recopie du résultat sigHH = (*sigtotalHH); delete sigtotalHH; delete zeroHH; LibereTenseur(); }; // calcul des contraintes a t+dt et de ses variations void LoiCritere::Calcul_DsigmaHH_tdt(TenseurHH& sigHH_t,TenseurBB& DepsBB,DdlElement & tab_ddl ,BaseB& giB_t,TenseurBB & gijBB_t,TenseurHH & gijHH_t ,BaseB& giB_tdt,Tableau & d_giB_tdt,BaseH& giH_tdt,Tableau & d_giH_tdt ,TenseurBB & epsBB_tdt,Tableau & d_epsBB ,TenseurBB & delta_epsBB,TenseurBB & gijBB_tdt,TenseurHH & gijHH_tdt ,Tableau & d_gijBB_tdt ,Tableau & d_gijHH_tdt,double& jacobien_0,double& jacobien ,Vecteur& d_jacobien_tdt,TenseurHH& sigHH_tdt,Tableau & d_sigHH ,EnergieMeca & energ,const EnergieMeca & ,double& module_compressibilite,double& module_cisaillement ,const Met_abstraite::Impli& ex ) { // on commence par créer un tenseur contrainte qui totalisera toutes les contraintes // le tenseurs est initialisé à 0. int dim_tens = sigHH_tdt.Dimension(); TenseurHH* sigtotalHH = (NevezTenseurHH(dim_tens,0.)); TenseurHH* zeroHH = (NevezTenseurHH(dim_tens,0.)); SaveResul_LoiCritere & save_resul = *((SaveResul_LoiCritere*) saveResul); module_compressibilite=module_cisaillement=0.; // init energ.Inita(0.); // initialisation des énergies mises en jeux // on vérifie que le tableau de travail intermédiaire statique est correctement // dimensionné sinon on le modifie int taille = d_sigHH.Taille(); if (d_sigtotalHH.Taille() == 0) { d_sigtotalHH.Change_taille(taille,NULL);} else if ( taille != d_sigtotalHH.Taille()) { int ancienne_taille = d_sigtotalHH.Taille(); d_sigtotalHH.Change_taille(taille); if (ancienne_taille < taille) for (int i=ancienne_taille+1;i<=taille;i++) d_sigtotalHH(i)=NULL; }; for (int i=1;i<=taille;i++) { // mise à zéro des tenseurs du tableau avec création si nécessaire if (d_sigtotalHH(i) == NULL) {d_sigtotalHH(i)=NevezTenseurHH(dim_tens,0.);} else if ( d_sigtotalHH(i)->Dimension() != dim_tens) { delete d_sigtotalHH(i); d_sigtotalHH(i)=NevezTenseurHH(dim_tens,0.);} else // mise à zéro simple *(d_sigtotalHH(i))= (*zeroHH); }; // première mise à zéro de d_sigHH for (int j1=1;j1<=taille;j1++) *d_sigHH(j1) = (*zeroHH); Tableau & d_SigtotalHH = d_sigtotalHH; // pour simplifier l'acces // maintenant on balaie l'ensemble des lois list ::iterator ili,ilifin=lois_internes.end(); list ::const_iterator icfin=list_completude_calcul.end(); list ::const_iterator ic = list_completude_calcul.begin(); // cas éventuelle des fonctions de pondération list ::iterator ipfonc; if (avec_ponderation) ipfonc = fonc_ponder.begin(); list ::iterator isig = save_resul.l_sigoHH.begin(); list ::iterator isig_t = save_resul.l_sigoHH_t.begin(); list ::iterator ienerg = save_resul.l_energ.begin(); list ::iterator ienerg_t = save_resul.l_energ_t.begin(); list ::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois for (ili=lois_internes.begin();ili!=ilifin;ili++,isig_t++,isig++,isave++,ienerg++,ienerg_t++,ic++) { // initialisation du tenseurs contrainte à chaque début de boucle sigHH_tdt = (*zeroHH); // dimensionnement si nécessaire if ((*isig)->Dimension()!=sigHH_t.Dimension()) { delete (*isig); (*isig)=NevezTenseurHH(sigHH_t.Dimension(),0.);}; if ((*isig_t)->Dimension()!=sigHH_t.Dimension()) { delete (*isig_t); (*isig_t)=NevezTenseurHH(sigHH_t.Dimension(),0.);}; double compress_inter=0.; double cisaill_inter=0; // init // passage des informations spécifique à la loi liste_des_SaveResul (*ili)->IndiqueSaveResult(*isave); (*ili)->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca (*ili)->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours // -- première phase: préparation de calcul pour l'application d'un critère const Met_abstraite::Expli_t_tdt* ex_expli= NULL; const Met_abstraite::Impli* ex_impli = (Met_abstraite::Impli*) &ex; const Met_abstraite::Umat_cont* ex_umat = NULL; int retour_pre_critere = Pre_Critere (DepsBB,epsBB_tdt,delta_epsBB,jacobien_0,jacobien ,ex_expli,ex_impli,ex_umat); // -- calcul initial de la contrainte résultante, pour l'instant sans tenir compte de critère (*ili)->Calcul_DsigmaHH_tdt((*(*isig_t)),DepsBB,tab_ddl,giB_t,gijBB_t,gijHH_t,giB_tdt ,d_giB_tdt,giH_tdt,d_giH_tdt,epsBB_tdt,d_epsBB,delta_epsBB ,gijBB_tdt,gijHH_tdt,d_gijBB_tdt,d_gijHH_tdt,jacobien_0 ,jacobien,d_jacobien_tdt,sigHH_tdt,d_sigHH,(*ienerg) ,(*ienerg_t),compress_inter,cisaill_inter,ex); #ifdef MISE_AU_POINT // sortie éventuelle d'infos if (Permet_affichage() > 5) { cout << "\nLoiCritere::Calcul_DSigmaHH_tdt: avant critere "; //if (sigHH.MaxiComposante() > 20.) TenseurBB* ptBB = NevezTenseurBB(epsBB_tdt); epsBB_tdt.BaseAbsolue(*ptBB,(giH_tdt)); cout << "\n eps en absolu: "; ptBB->Ecriture(cout); delta_epsBB.BaseAbsolue(*ptBB,giH_tdt); cout << "\n delta eps en absolu: "; ptBB->Ecriture(cout); TenseurHH* ptHH = NevezTenseurHH(sigHH_tdt); sigHH_tdt.BaseAbsolue(*ptHH,giB_tdt); cout << "\n base giB(1) "<< giB_tdt(1) << "\n base giB(2) "<< giB_tdt(2); cout << "\n sigHH= en giB "; sigHH_tdt.Ecriture(cout); cout << "\n sigma en absolu: "; ptHH->Ecriture(cout); delete ptBB; delete ptHH; if (Permet_affichage() > 6) {int nbddl = d_gijBB_tdt.Taille(); cout << "\n operateur tangent avant critere: " ; for (int i = 1; i<= nbddl; i++) {cout << "\n i= "<< i; (*d_sigHH(i)).Ecriture(cout); }; }; }; #endif // -- on applique le critère ce qui peut changer ou pas les résultats précédents bool implicit = true;bool en_base_absolu = false; Met_abstraite::Umat_cont umat_transfert; // une umat inter ex.Recup_Umat_cont(umat_transfert); int retour_critere = Critere (en_base_absolu, (*(*isig_t)),DepsBB,epsBB_tdt,delta_epsBB ,jacobien_0,jacobien,sigHH_tdt,*d_sigma_deps_inter ,(*ienerg),(*ienerg_t),compress_inter,cisaill_inter,implicit ,umat_transfert); #ifdef MISE_AU_POINT // sortie éventuelle d'infos après l'application du critère if (Permet_affichage() > 5) { cout << "\nLoiCritere::Calcul_DSigmaHH_tdt: apres l'application du critere: "; TenseurHH* ptHH = NevezTenseurHH(sigHH_tdt); sigHH_tdt.BaseAbsolue(*ptHH,giB_tdt); cout << "\n sigHH= en giB "; sigHH_tdt.Ecriture(cout); cout << "\n sigma en absolu: "; ptHH->Ecriture(cout); ////------ debug // if (ptHH->MaxiComposante() > 100.) // cout << "\n debug LoiCritere::Calcul_SigmaHH " // << "(ptHH->MaxiComposante() > 100.) !! "; ////------ debug delete ptHH; }; #endif switch (retour_critere) {case 0: // cas d'un pb if (Permet_affichage() > 4) cout << "\n pb dans l'application du critere, on continue sans tenir compte du critere "; if (Permet_affichage() > 5) {cout << "\n **>> il y a eu un pb que l'on n'a pas pu resoudre, rien n'a ete modifie "; if (ptintmeca_en_cours != NULL) ptintmeca_en_cours->Signature(); cout << "\n retour_critere= "<< retour_critere ; }; break; case 1: break; // le critère n'a rien changé case 2: if (Permet_affichage() > 5) {//cout << "\n retour_critere= "<< retour_critere ; cout << "\n **>> l'application du critere conduit a une contrainte et un operateur" << " tangent nul "; if (ptintmeca_en_cours != NULL) ptintmeca_en_cours->Signature(); } break; // l'application du critère -> tout nul case 3: // il y a eu des modification on va recalculer l'opérateur tangent / au ddl { int nbddl = d_gijBB_tdt.Taille(); for (int i = 1; i<= nbddl; i++) (*d_sigHH(i)) = (*d_sigma_deps_inter) && (*(d_epsBB(i))); if (Permet_affichage() > 6) {cout << "\n **>> retour_critere= "<< retour_critere << " recalcul de l'operateur tangent: " ; for (int i = 1; i<= nbddl; i++) {cout << "\n i= "<< i; (*d_sigHH(i)).Ecriture(cout); }; }; break; } default: cout << "\n *** cas non prevu ! " << "\n LoiCritere::Calcul_DsigmaHH_tdt (.." << endl; Sortie(2); break; }; // application d'un critère // 0 : il y a eu un pb que l'on n'a pas peu résoudre, rien n'a été modifié // 1 : le critère n'a rien modifié // 2 : l'application du critère conduit à une contrainte et un opérateur tangent nul // 3 : les données d'entrée ont été modifiées: contraintes, opérateur tangent, module, énergies // --- traitement en fonction du type de calcul // if (retour_critere != 2) // ==2 signifie que tout est nul, dans ce cas ce n'est pas la peine d'ajouter // non on ne peut pas faire cela car cela conduit à une structure complètement instable // transitoirement on va mettre une petite raideur // if (retour_critere == 2) // { compress_inter /= 1000.; // cisaill_inter /= 1000.; // }; switch (*ic) { case CONTRAINTE_ET_TANGENT: // cas normal {if ((avec_ponderation)&&((*ipfonc) != 1.)) {module_compressibilite += (*ipfonc) * compress_inter; module_cisaillement += (*ipfonc) * cisaill_inter; energ += (*ienerg) * (*ipfonc); // update des énergies totales (*sigtotalHH) += (*ipfonc) * (sigHH_tdt); // on ajoute la contrainte au total (*(*isig)) = sigHH_tdt; // on sauvegarde la contrainte partielle // récup de l'opérateur tangent for (int j=1;j<=taille;j++) { (*d_SigtotalHH(j)) += (*ipfonc) * (*d_sigHH(j)); *d_sigHH(j) = (*zeroHH); }; } else {energ += (*ienerg); // update des énergies module_compressibilite += compress_inter; module_cisaillement += cisaill_inter; (*sigtotalHH) += sigHH_tdt; // récup du tenseur et on ajoute la contrainte au total (*(*isig))=sigHH_tdt; // on sauvegarde la contrainte partielle // récup de l'opérateur tangent for (int j=1;j<=taille;j++) { (*d_SigtotalHH(j)) += (*d_sigHH(j)); *d_sigHH(j) = (*zeroHH); }; }; break; } case CONTRAINTE_UNIQUEMENT: {if ((avec_ponderation)&&((*ipfonc) != 1.)) {module_compressibilite += (*ipfonc) * compress_inter; module_cisaillement += (*ipfonc) * cisaill_inter; energ += (*ienerg) * (*ipfonc); // update des énergies totales (*sigtotalHH) += (*ipfonc) * (sigHH_tdt); // on ajoute la contrainte au total (*(*isig)) = sigHH_tdt; // on sauvegarde la contrainte partielle // récup de l'opérateur tangent for (int j=1;j<=taille;j++) { *d_sigHH(j) = (*zeroHH);}; } else {energ += (*ienerg); // update des énergies module_compressibilite += compress_inter; module_cisaillement += cisaill_inter; (*sigtotalHH) += sigHH_tdt; // récup du tenseur et on ajoute la contrainte au total (*(*isig))=sigHH_tdt; // on sauvegarde la contrainte partielle // mise à zéro de l'opérateur tangent pour la suite for (int j=1;j<=taille;j++) { *d_sigHH(j) = (*zeroHH);}; }; break; } case TANGENT_UNIQUEMENT: {(*ienerg).Inita(0.); // on remet à 0 l'énergie partielle car pas de prise en compte de la contrainte (*(*isig))=(*zeroHH); // on remet à 0 la contrainte partielle if ((avec_ponderation)&&((*ipfonc) != 1.)) {// récup de l'opérateur tangent for (int j=1;j<=taille;j++) { (*d_SigtotalHH(j)) += (*ipfonc) * (*d_sigHH(j)); *d_sigHH(j) = (*zeroHH); }; } else // on ne tiens pas en compte du module de compressibilité ni de cisaillement // récup de l'opérateur tangent {for (int j=1;j<=taille;j++) { (*d_SigtotalHH(j)) += (*d_sigHH(j)); *d_sigHH(j) = (*zeroHH);}; }; break; } }; if (avec_ponderation) // on incrémente si on a de la pondération ipfonc++; }; // fin de la boucle sur les lois // recopie du résultat sigHH_tdt = (*sigtotalHH); for (int k=1;k<=taille;k++) (*d_sigHH(k)) = (*d_SigtotalHH(k)); delete sigtotalHH; delete zeroHH; LibereTenseur(); }; // calcul des contraintes et ses variations par rapport aux déformations a t+dt // en_base_orthonormee: le tenseur de contrainte en entrée est en orthonormee // le tenseur de déformation et son incrémentsont également en orthonormees // si = false: les bases transmises sont utilisées // ex: contient les éléments de métrique relativement au paramétrage matériel = X_(0)^a void LoiCritere::Calcul_dsigma_deps (bool en_base_orthonormee, TenseurHH & sigHH_t,TenseurBB& DepsBB ,TenseurBB & epsBB_tdt,TenseurBB & delta_epsBB,double& jacobien_0,double& jacobien ,TenseurHH& sigHH_tdt,TenseurHHHH& d_sigma_deps ,EnergieMeca & energ,const EnergieMeca & ,double& module_compressibilite,double& module_cisaillement ,const Met_abstraite::Umat_cont& ex) { // on commence par créer un tenseur contrainte qui totalisera toutes les contraintes // le tenseurs est initialisé à 0. int dim_tens = sigHH_tdt.Dimension(); TenseurHH* sigtotalHH = (NevezTenseurHH(dim_tens,0.)); TenseurHH* zeroHH = (NevezTenseurHH(dim_tens,0.)); SaveResul_LoiCritere & save_resul = *((SaveResul_LoiCritere*) saveResul); module_compressibilite=module_cisaillement=0.; // init energ.Inita(0.); // initialisation des énergies mises en jeux // redimentionnement éventuel pour le comportement tangent if (d_sigma_deps_inter != NULL) { if (d_sigma_deps_inter->Dimension() != d_sigma_deps.Dimension()) { delete d_sigma_deps_inter; d_sigma_deps_inter = NevezTenseurHHHH(d_sigma_deps);} } else {d_sigma_deps_inter = NevezTenseurHHHH(d_sigma_deps);}; // if ((ParaGlob::NiveauImpression() > 8) || (Permet_affichage() > 5)) // {cout << "\n debug: LoiCritere::Calcul_dsigma_deps (... " // << " d_sigma_deps_inter: dimension = " << d_sigma_deps_inter->Dimension() // << flush; // }; // idem pour le comportement tangent d_sigma_deps.Inita(0.); // maintenant on balaie l'ensemble des lois list ::iterator ili,ilifin=lois_internes.end(); list ::const_iterator ic,icfin=list_completude_calcul.end(); // cas éventuelle des fonctions de pondération list ::iterator ipfonc; if (avec_ponderation) ipfonc = fonc_ponder.begin(); list ::iterator isig,isig_t; list ::iterator ienerg,ienerg_t; list ::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois for (ili=lois_internes.begin(),isig_t = save_resul.l_sigoHH_t.begin(),isig = save_resul.l_sigoHH.begin() ,ienerg = save_resul.l_energ.begin(),ienerg_t = save_resul.l_energ_t.begin(),ic=list_completude_calcul.begin(); ili!=ilifin;ili++,isig_t++,isig++,isave++,ienerg++,ienerg_t++,ic++) { // initialisation du tenseurs contrainte à chaque début de boucle sigHH_tdt = (*zeroHH); // initialisation du comportement tangent d_sigma_deps_inter->Inita(0.); // dimensionnement si nécessaire if ((*isig)->Dimension()!=sigHH_t.Dimension()) { delete (*isig); (*isig)=NevezTenseurHH(sigHH_t.Dimension(),0.);}; if ((*isig_t)->Dimension()!=sigHH_t.Dimension()) { delete (*isig_t); (*isig_t)=NevezTenseurHH(sigHH_t.Dimension(),0.);}; double compress_inter=0.; double cisaill_inter=0; // init // passage des informations spécifique à la loi liste_des_SaveResul (*ili)->IndiqueSaveResult(*isave); (*ili)->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca (*ili)->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours // -- première phase: préparation de calcul pour l'application d'un critère const Met_abstraite::Expli_t_tdt* ex_expli= NULL; const Met_abstraite::Impli* ex_impli = NULL; const Met_abstraite::Umat_cont* ex_umat = (Met_abstraite::Umat_cont*) &ex; int retour_pre_critere = Pre_Critere (DepsBB,epsBB_tdt,delta_epsBB,jacobien_0,jacobien ,ex_expli,ex_impli,ex_umat); bool implicit = true; // -- prédiction : calcul de la contrainte résultante // on passe en paramètre delta_eps_BB_2D à la place de delta_epsBB // cet incrément peut avoir été modifié par la méthode Pre_Critere (*ili)->Calcul_dsigma_deps (en_base_orthonormee, (*(*isig_t)),DepsBB,epsBB_tdt,delta_eps_BB_2D,jacobien_0,jacobien ,sigHH_tdt,*d_sigma_deps_inter ,(*ienerg),(*ienerg_t),compress_inter,cisaill_inter,ex); #ifdef MISE_AU_POINT // sortie éventuelle d'infos if (Permet_affichage() > 5) { cout << "\nLoiCritere::Calcul_dsigma_deps: avant critere "; //if (sigHH.MaxiComposante() > 20.) TenseurBB* ptBB = NevezTenseurBB(epsBB_tdt); epsBB_tdt.BaseAbsolue(*ptBB,*(ex.giH_tdt)); cout << "\n eps en absolu: "; ptBB->Ecriture(cout); delta_epsBB.BaseAbsolue(*ptBB,*(ex.giH_tdt)); cout << "\n delta eps en absolu: "; ptBB->Ecriture(cout); TenseurHH* ptHH = NevezTenseurHH(sigHH_tdt); sigHH_tdt.BaseAbsolue(*ptHH,*(ex.giB_tdt)); cout << "\n base giB(1) "<< (*(ex.giB_tdt))(1) << "\n base giB(2) "<< (*(ex.giB_tdt))(2); cout << "\n sigHH= en giB "; sigHH_tdt.Ecriture(cout); cout << "\n sigma en absolu: "; ptHH->Ecriture(cout); delete ptBB; delete ptHH; }; #endif // -- on applique le critère ce qui peut changer ou pas les résultats précédents int retour_critere = Critere (en_base_orthonormee, (*(*isig_t)),DepsBB,epsBB_tdt,delta_epsBB,jacobien_0,jacobien ,sigHH_tdt,*d_sigma_deps_inter ,(*ienerg),(*ienerg_t),compress_inter,cisaill_inter,implicit,ex); #ifdef MISE_AU_POINT // sortie éventuelle d'infos après l'application du critère if (Permet_affichage() > 5) { cout << "\nLoiCritere::Calcul_dsigma_deps: apres l'application du critere: "; TenseurHH* ptHH = NevezTenseurHH(sigHH_tdt); sigHH_tdt.BaseAbsolue(*ptHH,*(ex.giB_tdt)); cout << "\n sigHH= en giB "; sigHH_tdt.Ecriture(cout); cout << "\n sigma en absolu: "; ptHH->Ecriture(cout); ////------ debug // if (ptHH->MaxiComposante() > 100.) // cout << "\n debug LoiCritere::Calcul_SigmaHH " // << "(ptHH->MaxiComposante() > 100.) !! "; ////------ debug delete ptHH; }; #endif switch (retour_critere) {case 0: // cas d'un pb if (Permet_affichage() > 4) cout << "\n pb dans l'application du critere, on continue sans tenir compte du critere "; if (Permet_affichage() > 5) {cout << "\n **>> il y a eu un pb que l'on n'a pas pu resoudre, rien n'a ete modifie "; if (ptintmeca_en_cours != NULL) ptintmeca_en_cours->Signature(); cout << "\n retour_critere= "<< retour_critere ; }; break; case 1: break; // le critère n'a rien changé case 2: if (Permet_affichage() > 5) {//cout << "\n retour_critere= "<< retour_critere ; cout << "\n **>> l'application du critere conduit a une contrainte et un operateur" << " tangent nul "; if (ptintmeca_en_cours != NULL) ptintmeca_en_cours->Signature(); } break; // l'application du critère -> tout nul case 3: break; // il y a eu des modification default: cout << "\n *** cas non prevu ! " << "\n LoiCritere::Calcul_DsigmaHH_tdt (.." << endl; Sortie(2); break; }; // --- traitement en fonction du type de calcul if (retour_critere != 1) // ==1 signifie que tout est nul, dans ce cas ce n'est pas la peine d'ajouter switch (*ic) { case CONTRAINTE_ET_TANGENT: // cas normal {if ((avec_ponderation)&&((*ipfonc) != 1.)) {module_compressibilite += (*ipfonc) * compress_inter; module_cisaillement += (*ipfonc) * cisaill_inter; energ += (*ienerg) * (*ipfonc); // update des énergies totales (*sigtotalHH) += (*ipfonc) * (sigHH_tdt); // on ajoute la contrainte au total (*(*isig)) = sigHH_tdt; // on sauvegarde la contrainte partielle // récup de l'opérateur tangent d_sigma_deps += *d_sigma_deps_inter * (*ipfonc) ; } else {energ += (*ienerg); // update des énergies module_compressibilite += compress_inter; module_cisaillement += cisaill_inter; (*sigtotalHH) += sigHH_tdt; // récup du tenseur et on ajoute la contrainte au total (*(*isig))=sigHH_tdt; // on sauvegarde la contrainte partielle // récup de l'opérateur tangent d_sigma_deps += *d_sigma_deps_inter; }; break; } case CONTRAINTE_UNIQUEMENT: {if ((avec_ponderation)&&((*ipfonc) != 1.)) {module_compressibilite += (*ipfonc) * compress_inter; module_cisaillement += (*ipfonc) * cisaill_inter; energ += (*ienerg) * (*ipfonc); // update des énergies totales (*sigtotalHH) += (*ipfonc) * (sigHH_tdt); // on ajoute la contrainte au total (*(*isig)) = sigHH_tdt; // on sauvegarde la contrainte partielle // on ne récupère pas l'opérateur tangent } else {energ += (*ienerg); // update des énergies module_compressibilite += compress_inter; module_cisaillement += cisaill_inter; (*sigtotalHH) += sigHH_tdt; // récup du tenseur et on ajoute la contrainte au total (*(*isig))=sigHH_tdt; // on sauvegarde la contrainte partielle // on ne récupère pas l'opérateur tangent }; break; } case TANGENT_UNIQUEMENT: {(*ienerg).Inita(0.); // on remet à 0 l'énergie partielle car pas de prise en compte de la contrainte (*(*isig))=(*zeroHH); // on remet à 0 la contrainte partielle if ((avec_ponderation)&&((*ipfonc) != 1.)) {// récup de l'opérateur tangent d_sigma_deps += *d_sigma_deps_inter * (*ipfonc) ; } else // on ne tiens pas en compte du module de compressibilité ni de cisaillement // récup de l'opérateur tangent {d_sigma_deps += *d_sigma_deps_inter;}; break; } }; if (avec_ponderation) // on incrémente si on a de la pondération ipfonc++; }; // recopie du résultat sigHH_tdt = (*sigtotalHH); delete sigtotalHH; delete zeroHH; LibereTenseur();LibereTenseurQ(); }; // application d'un critère // 0 : il y a eu un pb que l'on n'a pas peu résoudre, rien n'a été modifié // 1 : le critère n'a rien modifié // 2 : l'application du critère conduit à une contrainte et un opérateur tangent nul // 3 : les données d'entrée ont été modifiées: contraintes, opérateur tangent, module, énergies int LoiCritere::Critere(bool en_base_orthonormee,TenseurHH & sigHH_t,TenseurBB& DepsBB ,TenseurBB & epsBB_tdt,TenseurBB & delta_epsBB,double& jacobien_0,double& jacobien ,TenseurHH& sigHH,TenseurHHHH& d_sigma_deps_inter ,EnergieMeca & energ,const EnergieMeca & energ_t,double& module_compressibilite,double& module_cisaillement ,bool implicit,const Met_abstraite::Umat_cont& ex) { int retour_critere = 1; // init par défaut du retour // if ((ParaGlob::NiveauImpression() > 8) || (Permet_affichage() > 5)) // cout << "\n test1: LoiCritere::Critere(... " << flush; switch (type_critere) { case PLISSEMENT_MEMBRANE: { int retour_plis_membrane = Critere_plis_membrane(en_base_orthonormee,sigHH_t,DepsBB ,epsBB_tdt,delta_epsBB,jacobien_0,jacobien,sigHH,d_sigma_deps_inter ,energ,energ_t,module_compressibilite,module_cisaillement,implicit,ex ); switch( retour_plis_membrane) { // = -1 : pas de calcul de valeur propre possible en contrainte // = 1 : pas de plis (pas de calcul de nouvelle direction ) // = -2 : pas de calcul de valeur propre de déformation // = -3 : plis dans les deux sens, mais pas de calcul de direction propre valide // = 2 : plis dans les deux sens, calcul des directions de plis // = -4 : pas de calcul de vecteurs propres possible pour les contraintes // = 3 : plis dans une seule directions, calcul ok case -2: case -1: case -4: retour_critere = 0; break; // -3 c'est quand même ok case -3: case 2: retour_critere = 2; break; default: retour_critere = retour_plis_membrane; break; }; break; } case PLISSEMENT_BIEL: { int retour_plis_biel = Critere_plis_biel(en_base_orthonormee,sigHH_t,DepsBB ,epsBB_tdt,delta_epsBB,jacobien_0,jacobien,sigHH,d_sigma_deps_inter ,energ,energ_t,module_compressibilite,module_cisaillement,implicit,ex ); switch( retour_plis_biel) { case -2: case -1: retour_critere = 0; break; default: retour_critere = retour_plis_biel; break; }; break; } case RUPTURE_SIGMA_PRINC: case RUPTURE_EPS_PRINC: { break; } default : cout << "\nErreur : valeur incorrecte du type de critere defini= " << Nom_Critere_Loi(type_critere) << " !\n"; cout << "\n LoiCritere::Critere(..."; Sortie(1); }; // retour return retour_critere; }; // préparation à l'appel du comportement //Par exemple dans le cas d'un critère pli (plutôt seconde méthode), l'incrément de déformation // dépend de la situation précédente: avec pli ou pas int LoiCritere::Pre_Critere (const TenseurBB& DepsBB,TenseurBB & epsBB_tdt,TenseurBB & delta_epsBB,double& jacobien_0,double& jacobien,const Met_abstraite::Expli_t_tdt* ex_expli,const Met_abstraite::Impli* ex_impli,const Met_abstraite::Umat_cont* ex_umat ) { int retour_pre_critere = 1; // init par défaut du retour if (choix_methode_cal_plis_memb == 2) switch (type_critere) { case PLISSEMENT_MEMBRANE: { Pre_Critere_plis_membrane(epsBB_tdt,delta_epsBB,ex_expli,ex_impli,ex_umat); break; } // case PLISSEMENT_BIEL: // break default : cout << "\nErreur : valeur incorrecte du type de critere defini= " << Nom_Critere_Loi(type_critere) << " !\n"; cout << "\n LoiCritere::Pre_Critere(..."; Sortie(1); }; // retour return retour_pre_critere; };