// FICHIER : LoiAdditiveEnSigma.cp // CLASSE : LoiAdditiveEnSigma // This file is part of the Herezh++ application. // // The finite element software Herezh++ is dedicated to the field // of mechanics for large transformations of solid structures. // It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600) // INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) . // // Herezh++ is distributed under GPL 3 license ou ultérieure. // // Copyright (C) 1997-2022 Université Bretagne Sud (France) // AUTHOR : Gérard Rio // E-MAIL : gerardrio56@free.fr // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, // or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // For more information, please consult: . //#include "Debug.h" #include "LesLoisDeComp.h" # include using namespace std; //introduces namespace std #include #include #include "Sortie.h" #include "TypeConsTens.h" #include "TypeQuelconqueParticulier.h" #include "NevezTenseurQ.h" #include "CharUtil.h" #include "LoiAdditiveEnSigma.h" //==================== cas de la class de sauvegarde SaveResul =================== // constructeur par défaut à ne pas utiliser LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma() : liste_des_SaveResul() ,l_sigoHH(),l_sigoHH_t(),l_energ(),l_energ_t(),f_ponder(),f_ponder_t() { cout << "\n erreur, le constructeur par defaut ne doit pas etre utilise !" << "\n LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma()"; cout << "\n LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma()"; Sortie(1); }; // le constructeur courant LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma (list & l_des_SaveResul,list & l_siHH ,list & l_siHH_t ,list & l_energ_,list & l_energ_t_ ,bool avec_ponderation): liste_des_SaveResul() ,l_sigoHH(),l_sigoHH_t(),l_energ(l_energ_),l_energ_t(l_energ_t_) ,f_ponder(),f_ponder_t() { 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.);}; //---debug //cout << "\n constructeurcourant LoiAdditiveEnSigma : taille_l_energ= " << l_energ.size() << " taille_l_energ_t= " << l_energ_t.size()<< endl; //this->Affiche(); cout << "\n" << endl; //---fin debug }; //---debug //ofstream fichier("toto", ios::app); //fichier << "\n un saveresult de loi additive : constructeur courant "; //this->Ecriture_base_info(fichier,1); //---fin debug }; // constructeur de copie LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma (const LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma& 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) { 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); //---debug //ofstream fichier("toto", ios::app); //fichier << "\n un constructeur de copie "; //fichier << "\n ------ save result interne : "; //if (nevez_save_result != NULL) nevez_save_result->Ecriture_base_info(fichier,1); //fichier << endl; //---fin debug 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); }; //---debug //ofstream fichier("toto", ios::app); //fichier << "\n un saveresult de loi additive : constructeur de copie "; //fichier << "\n ------ le saveresult passé en paramètre : "; //LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma* savons = ( LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma*) &sav ; //savons->Ecriture_base_info(fichier,1); // //fichier << "\n ------- le saveresult this : "; //this->Ecriture_base_info(fichier,1); //---fin debug }; // destructeur LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma::~SaveResul_LoiAdditiveEnSigma() { 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); }; }; // affectation Loi_comp_abstraite::SaveResul & LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma::operator = ( const Loi_comp_abstraite::SaveResul & a) { LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma& sav = *((LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma*) &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++) { if ((*ili) != NULL) // cas où il y a effectivement un conteneur non nul dans sav // normalement les tailles sont déjà bonnes (*(*jli))=(*(*ili)); // on peut directement affecter // pour les autres conteneurs, ils doivent toujours exister (*(*jsig))=(*(*isig));(*(*jsig_t))=(*(*isig_t)); }; }; // // 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; 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 LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma::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_LoiAdSig") { cout << "\n erreur en lecture du conteneur pour la loi additive" << " \n LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma::Lecture_base_info(.."; Sortie(1); } #endif // 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 additive, 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 LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma::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) {f_ponder.resize(nb_loi); f_ponder_t.resize(nb_loi); }; }; // 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); }; // on met les grandeurs de t vers tdt TversTdt(); }; // cas donne le niveau de sauvegarde // = 1 : on sauvegarde tout // = 2 : on sauvegarde uniquement les données variables (supposées comme telles) void LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma::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_LoiAdSig "; 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); }; }; // mise à jour des informations transitoires en définitif s'il y a convergence // par exemple (pour la plasticité par exemple) void LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma::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++) {if ((*ili) != NULL) (*ili)->TdtversT(); (*(*isig_t)) = (*(*isig)); (*ienerg_t)=(*ienerg); if (avec_ponderation) {(*ifo_t) = (*ifo); ifo++; ifo_t++; }; }; }; void LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma::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++; }; }; }; // affichage à l'écran des infos void LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma::Affiche() const { cout << "\n SaveResul_LoiAdditiveEnSigma: " ; 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 additive: "; 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);}; cout << "\n .. fin SaveResul_LoiAdditiveEnSigma:.. \n" ; }; //changement de base de toutes les grandeurs internes tensorielles stockées // beta(i,j) represente les coordonnees de la nouvelle base naturelle gpB dans l'ancienne gB // gpB(i) = beta(i,j) * gB(j), i indice de ligne, j indice de colonne // gpH(i) = gamma(i,j) * gH(j) void LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma::ChBase_des_grandeurs(const Mat_pleine& beta,const Mat_pleine& gamma) { // on ne s'intéresse qu'aux grandeurs tensorielles // encapsulage pour utiliser deux fois les mêmes itérators { List_io ::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); }; }; // 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* LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma ::Complete_SaveResul(const BlocGen & bloc, const Tableau & tab_coor ,const Loi_comp_abstraite* loi) {// on transmet au conteneur 3D interne const LoiAdditiveEnSigma * loi_CPtt = (const LoiAdditiveEnSigma*) loi; // loi_CPtt : est un nom quelconque // récup de la liste de loi list ::const_iterator ili,ilifin=loi_CPtt->lois_internes.end(); // récup des infos pour chaque loi list ::iterator ia=liste_des_SaveResul.begin(); for (ili = loi_CPtt->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 LoiAdditiveEnSigma::SaveResul_LoiAdditiveEnSigma::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_LoiAdditiveEnSigma::Deformation_plastique()"; Sortie(1); return 0.; // pour taire le warning, mais on ne passe jamais là }; //==================== fin du cas de la class de sauvegarde SaveResul ============ LoiAdditiveEnSigma::LoiAdditiveEnSigma () : // Constructeur par defaut Loi_comp_abstraite(LOI_ADDITIVE_EN_SIGMA,RIEN_CATEGORIE_LOI_COMP,0),lois_internes() ,list_completude_calcul(),d_sigma_deps_inter(NULL) ,d_sigma_deps_pourCalcul_DsigmaHH_via_eps_tdt(NULL) ,avec_ponderation(false),list_ponderation() ,list_ponderation_nD_quelconque() ,d_sigtotalHH() ,type_calcul(1),tangent_ddl_via_eps(0) {}; // Constructeur de copie LoiAdditiveEnSigma::LoiAdditiveEnSigma (const LoiAdditiveEnSigma& loi) : Loi_comp_abstraite(loi),lois_internes(),list_completude_calcul() ,d_sigma_deps_inter(NULL),d_sigma_deps_pourCalcul_DsigmaHH_via_eps_tdt(NULL) ,avec_ponderation(loi.avec_ponderation),list_ponderation(loi.list_ponderation) ,d_sigtotalHH() ,list_ponderation_nD_quelconque() ,type_calcul(loi.type_calcul),tangent_ddl_via_eps(loi.tangent_ddl_via_eps) { list ::const_iterator ili,ilifin=loi.lois_internes.end(); list ::const_iterator ic,icfin=loi.list_completude_calcul.end(); 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); }; // pondération nD quelconques -> création de pondérations identiques list ::const_iterator it,itfin = loi.list_ponderation_nD_quelconque.end(); if (!(loi.list_ponderation_nD_quelconque.empty())) {for (it = loi.list_ponderation_nD_quelconque.begin(); it != itfin; it++) if (*it != NULL) { Ponderation_TypeQuelconque* pt = new Ponderation_TypeQuelconque(*(*it)); list_ponderation_nD_quelconque.push_back(pt); } else list_ponderation_nD_quelconque.push_back(NULL); }; }; LoiAdditiveEnSigma::~LoiAdditiveEnSigma () // 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_sigma_deps_pourCalcul_DsigmaHH_via_eps_tdt != NULL) delete d_sigma_deps_pourCalcul_DsigmaHH_via_eps_tdt; 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); }; // pondération nD quelconques list ::iterator it,itfin = list_ponderation_nD_quelconque.end(); if (list_ponderation_nD_quelconque.size() != 0) {for (it = list_ponderation_nD_quelconque.begin(); it != itfin; it++) if (*it != NULL) delete *it; }; }; // def d'une instance de données spécifiques, et initialisation // valable une fois que les différentes lois internes sont définit LoiAdditiveEnSigma::SaveResul * LoiAdditiveEnSigma::LoiAdditiveEnSigma::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 // 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++) { SaveResul * nevez_save_result=NULL; if ((*ili) != NULL) nevez_save_result = (*ili)->New_et_Initialise(); liste_des_SaveResul.push_back(nevez_save_result); // 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 LoiAdditiveEnSigma::SaveResul * retour = new SaveResul_LoiAdditiveEnSigma(liste_des_SaveResul,l_sigoHH,l_sigoHH_t ,l_energ,l_energ_t,avec_ponderation); // 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); }; // retour return retour; }; // Lecture des lois de comportement void LoiAdditiveEnSigma::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D ,LesFonctions_nD& lesFonctionsnD) { // tout d'abord on regarde si on utilise ou pas des fonctions de pondération bool passerUneLigne = false; if (strstr(entreePrinc->tablcar,"avec_fonction_de_ponderation_")!=NULL) { // lecture du mot clé string st2; *(entreePrinc->entree) >> st2; // vérification if (st2 != "avec_fonction_de_ponderation_") { cout << "\n erreur en lecture, on aurait du lire le mot cle avec_fonction_de_ponderation_" << " alors qu'on a lu " << st2; cout << "\n LoiAdditiveEnSigma::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur01**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on enregistre avec_ponderation = true; passerUneLigne = true; } else // sinon on n'a pas de fonction de pondération {avec_ponderation = false;}; // maintenant on regarde si le type de calcul est spécifié if (strstr(entreePrinc->tablcar,"type_calcul=")!=NULL) { // lecture du mot clé string st2; *(entreePrinc->entree) >> st2 >> type_calcul; // vérification if (st2 != "type_calcul=") { cout << "\n erreur en lecture, on aurait du lire le mot cle type_calcul=" << " alors qu'on a lu " << st2; cout << "\n LoiAdditiveEnSigma::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur02**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on enregistre if ((type_calcul != 1) && (type_calcul != 2)) { cout << "\n erreur en lecture, on aurait du lire type_calcul= 1 ou 2" << " alors qu'on a lu " << type_calcul; cout << "\n LoiAdditiveEnSigma::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur03**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; passerUneLigne = true; } else // sinon valeur par défaut {type_calcul = 1;}; // maintenant on regarde si tangent_ddl_via_eps est spécifié if (strstr(entreePrinc->tablcar,"tangent_ddl_via_eps=")!=NULL) { // lecture du mot clé string st2; *(entreePrinc->entree) >> st2 >> tangent_ddl_via_eps; // vérification if (st2 != "tangent_ddl_via_eps=") { cout << "\n erreur en lecture, on aurait du lire le mot cle tangent_ddl_via_eps=" << " alors qu'on a lu " << st2; cout << "\n LoiAdditiveEnSigma::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur10**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on enregistre if ((tangent_ddl_via_eps != 1) && (tangent_ddl_via_eps != 0)) { cout << "\n erreur en lecture, on aurait du lire tangent_ddl_via_eps= 1 ou 0" << " alors qu'on a lu " << tangent_ddl_via_eps; cout << "\n LoiAdditiveEnSigma::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur010**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; passerUneLigne = true; } else // sinon valeur par défaut {tangent_ddl_via_eps = 0;}; // on passe à la ligne éventuellement, s'il y a des fonctions de pondération et/ou un type de calcul spécifié if (passerUneLigne) entreePrinc->NouvelleDonnee(); // lecture jusque l'on trouve le mot clé signalant la fin de la liste des loi élémentaires bool trouve_ponder_grandeur_locale = false; // pour la gestion de list_ponderation_nD_quelconque bool premier_lecture = true; int dim_lois=0; Enum_categorie_loi_comp categ=RIEN_CATEGORIE_LOI_COMP; string st1,st2; while (strstr(entreePrinc->tablcar,"fin_liste_lois_elementaires")==NULL) { // dans le cas de l'existence de fonction de pondération, on lit les infos if (avec_ponderation) { Ponderation ponder; // un élément courant // on doit commencer par lire les grandeurs des fonctions de pondération *(entreePrinc->entree) >> st1; if ((st1 != "les_grandeur_ponderation=") && (st1 != "avec_ponder_grandeur_locale_")) { cout << "\n erreur en lecture, on aurait du lire le mot cle les_grandeur_ponderation=" << " ou le mot cle avec_ponder_grandeur_locale_ " << " alors qu'on a lu " << st1; cout << "\n LoiAdditiveEnSigma::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur04**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // 1) cas de l'utilisation de courbes 1D if (st1 == "les_grandeur_ponderation=") {int compteur = 1; // pour éviter une boucle infinie Ddl_enum_etendu typecourant; // inter List_io < Ddl_enum_etendu > listddlenum; List_io listbool; while (st1 != "fin_grandeur_ponderation_") {*(entreePrinc->entree) >> st1 >> st2; if (st1 == "fin_grandeur_ponderation_") break; // pas terrible mais c'est ce qui me vient à l'idée ! // cas de la grandeur if (!(Ddl_enum_etendu::VerifExistence(st1))) { cout << "\n erreur en lecture, le type de grandeur lu" << st1 << " n'est pas acceptable " << "\n LoiAdditiveEnSigma::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur05**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } else {typecourant=Ddl_enum_etendu::RecupDdl_enum_etendu(st1);}; listddlenum.push_back(typecourant); // sauvegarde // cas du positionnement de la grandeur if (st2 == "AuxNoeuds_") {listbool.push_back(1);} else if (st2 == "AuPti_") {listbool.push_back(0);} else { cout << "\n erreur en lecture, de positionnement de la grandeur qui doit etre AuxNoeuds_ ou AuPti_ " << " et on a lu" << st2 << " qui n'est pas acceptable " << "\n LoiAdditiveEnSigma::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur06**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // vérif que l'on n'a pas dépasser le maxi autorisé if (compteur > 11) { cout << "\n erreur en lecture, on a lu plus de 11 types de grandeurs pour les fonctions de ponderations " << " il y a un probleme dans le fichier de donnee !! " << "\n valeurs actuellement lue: " << listddlenum; cout << "\n LoiAdditiveEnSigma::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur07**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } else {compteur++;}; }; // maintenant on peut définir le nombre de fonctions 1D int taille = listddlenum.size(); ponder.Type_grandeur().Change_taille(taille); ponder.Valeur_aux_noeuds().Change_taille(taille); ponder.C_proport().Change_taille(taille); // on transfert les Ddl_enum_etendu et les positionnements int i=1; List_io < Ddl_enum_etendu >::iterator il,ilfin=listddlenum.end(); List_io < bool >::iterator ip = listbool.begin(); for (il=listddlenum.begin();il != ilfin; il++,i++,ip++) {ponder.Type_grandeur()(i) = (*il); ponder.Valeur_aux_noeuds()(i) = (*ip); }; // maintenant la lecture des fonctions de pondération entreePrinc->NouvelleDonnee(); *(entreePrinc->entree) >> st1; // le mot clé if (st1 != "deb_fonct_ponder=") { cout << "\n erreur en lecture, on attendait le mot cle deb_fonct_ponder= et on a lu " << st1 << "\n LoiAdditiveEnSigma::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur08**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; for (int j=1;j<=taille;j++) { *(entreePrinc->entree) >> st2; // lecture de l'identificateur de la courbe // on regarde si la courbe existe, si oui on récupère la référence if (lesCourbes1D.Existe(st2)) { ponder.C_proport()(j) = lesCourbes1D.Trouve(st2);} else // sinon il faut la lire maintenant { string non_courbe("_"); ponder.C_proport()(j) = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (st2.c_str())); // lecture de la courbe ponder.C_proport()(j)->LectDonnParticulieres_courbes (non_courbe,entreePrinc); entreePrinc->NouvelleDonnee(); // préparation du flux }; }; *(entreePrinc->entree) >> st1; // le mot clé de la fin if (st1 != "fin_fonct_ponder_") { cout << "\n erreur en lecture, on attendait le mot cle fin_fonct_ponder_ et on a lu " << st1 << "\n LoiAdditiveEnSigma::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur09**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // enregistrement des infos list_ponderation.push_back(ponder); entreePrinc->NouvelleDonnee(); // prepa du flot de lecture pour la suite *(entreePrinc->entree) >> st1; // on lit le prochain mot clé }; // fin du cas de l'utilisation de courbes 1D // 2) cas de l'utilisation d'une fonction nD // cas où il existe une pondération additionnelle via des grandeurs // quelconque locales // mais en fait cela permet de définir une fonction nD qui // peut alors contenir toutes les grandeurs possibles: locales et globales if (st1 == "avec_ponder_grandeur_locale_") // if (strstr(entreePrinc->tablcar,"avec_ponder_grandeur_locale_")!=NULL) { Ponderation_TypeQuelconque ponderQuelc; // un élément courant entreePrinc->NouvelleDonnee(); // prepa du flot de lecture pour la suite // on doit commencer par lire les grandeurs des fonctions de niveau string mot_cle="les_grandeurs_="; string nom_class_methode("LoiAdditiveEnSigma::LectureDonneesParticulieres"); List_io list_id_grand; //liste de travail if (strstr(entreePrinc->tablcar,"les_grandeurs_=")!=NULL) // cas où il y a des grandeurs à lire {entreePrinc->Lecture_et_verif_mot_cle(nom_class_methode,mot_cle); int compteur = 1; // pour éviter une boucle infinie // on lit les grandeurs pour l'instant en string int nb_grandeurs_locales = 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 if (Existe_typeQuelconque(st1)) {list_id_grand.push_back(st1); nb_grandeurs_locales++; } else { cout << "\n erreur en lecture, le type de grandeur lu" << st1 << " n'est pas acceptable " << "\n "<MessageBuffer("**erreur05**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; }; // --- maintenant on va lire la fonction nD 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); // on crée le conteneur de pondération Ponderation_TypeQuelconque* ptnD = new Ponderation_TypeQuelconque; // lecture sur le flot d'entrée // si list_id_grand n'est pas vide, on vérifie que les grandeurs passées en paramètre // sont bien des variables de la fonction (locale ou globale) ptnD->LecturePonderation(list_id_grand,entreePrinc,lesFonctionsnD); trouve_ponder_grandeur_locale=true; // on valide l'existence au moins d'une fct nD // on ajoute dans la liste des fct nD list_ponderation_nD_quelconque.push_back(ptnD); // 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); entreePrinc->NouvelleDonnee(); // prepa du flot de lecture pour la suite *(entreePrinc->entree) >> st1; // on lit le prochain mot clé // cout << "\n debug lecture donnée loi additive en sigma " // << "\n st1= "<< st1 << flush; } else // sinon pour l'instant on rempli de pointeurs nulles {list_ponderation_nD_quelconque.push_back(NULL); }; } else // si on n'est pas avec ponderation il faut lire le nom de la loi {*(entreePrinc->entree) >> st1; } ; // --- lecture de la loi individuelle --------- // lecture du nom de la loi st2=st1; // c'est st1 qui contient le dernier nom lu // *(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 LoiAdditiveEnSigma::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 LoiAdditiveEnSigma::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 additive, 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 LoiAdditiveEnSigma" << "\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 LoiAdditiveEnSigma::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 LoiAdditiveEnSigma" << "\n la loi lue: " << pt->Nom_comport() << " n'a pas la meme dimension que la premier loi lue"; entreePrinc->MessageBuffer("lecture LoiAdditiveEnSigma"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } if (!GroupeMecanique(pt->Id_categorie())) { cout << "\n erreur en lecture des lois constitutives elementaire d'une loi LoiAdditiveEnSigma" << "\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 LoiAdditiveEnSigma::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 additive l'est aussi if (((Loi_comp_abstraite*)pt)->ThermoDependante()) this->thermo_dependant = true; }; // gestion de list_ponderation_nD_quelconque // dans le cas où aucune fct_nD n'a été trouvé, on vide la liste qui n'est remplie que de nul if (!trouve_ponder_grandeur_locale) list_ponderation_nD_quelconque.clear(); // au contraire s'il y a pondération avec des grandeurs locales, on va vérifier que ces grandeurs // sont dispo et on va préparer l'accès à ces grandeurs if (trouve_ponder_grandeur_locale) Verif_et_preparation_acces_grandeurs_locale(); // appel au niveau de la classe mère, avec preparation du flot de lecture Loi_comp_abstraite::Lecture_type_deformation_et_niveau_commentaire (*entreePrinc,lesFonctionsnD,true); // // prepa du flot de lecture pour d'autre loi éventuellement // entreePrinc->NouvelleDonnee(); }; // affichage de la loi void LoiAdditiveEnSigma::Affiche() const {cout << "\n ....... loi de comportement loiAdditiveEnSigma ........"; cout << "\n calcul additif "; if (type_calcul) {cout << " sur les contraintes ";} else { cout << " sur les increments de contraintes ";}; if (tangent_ddl_via_eps) cout << "\n utilisation du comportement tangent dsig/deps pour calculer le comportement tangent en ddl "; if (avec_ponderation) {cout << "\n avec ponderation " ;} else {cout << "\n 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 }; }; cout << "\n ....... fin de la loi de comportement loiAdditiveEnSigma ........"; }; // affichage et definition interactive des commandes particulières à chaques lois void LoiAdditiveEnSigma::Info_commande_LoisDeComp(UtilLecture& entreePrinc) { ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier cout << "\n definition standart (rep o) ou exemples exhaustifs (rep n'importe quoi) ? "; string rep = "_"; // procédure de lecture avec prise en charge d'un retour chariot rep = lect_return_defaut(true,"o"); sort << "\n# ....... loi de comportement loiAdditiveEnSigma ........" << "\n# il faut donner le nom de chaque loi suivi des parametres sur les lignes suivantes" << "\n# puis terminer avec le mot cle: fin_liste_lois_elementaires " << "\n# exemple de deux lois elastiques "; // definition de la loi string internom("ISOELAS"); LoiAbstraiteGeneral * pt = LesLoisDeComp::Def_loi(internom); sort << "\n ISOELAS # premiere loi isoelas 3D"; pt->Info_commande_LoisDeComp(entreePrinc); sort << "\n ISOELAS # seconde loi isoelas 3D"; pt->Info_commande_LoisDeComp(entreePrinc); sort << "\n fin_liste_lois_elementaires # ----- fin de loiAdditiveEnSigma" << 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_ " << "\n# exemple de deux lois elastiques "; sort << "\n# ISOELAS tangent_seulement_ # premiere loi isoelas 3D dont on retiens que le comportement tangent"; pt->Info_commande_LoisDeComp(entreePrinc); sort << "\n# ISOELAS tangent_seulement_ # seconde loi isoelas 3D dont on retiens que les contraintes "; pt->Info_commande_LoisDeComp(entreePrinc); sort << "\n# fin_liste_lois_elementaires # ----- fin de loiAdditiveEnSigma" << endl; sort << "\n\n \n "; sort << "\n# ....... cas particulier 2) ........" << "\n# 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_ADDITIVE_EN_SIGMA) 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_ADDITIVE_EN_SIGMA " << "\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# " << "\n# Cas particulier: a la suite du mot cle eventuel type_calcul= suivi de sa valeur " << "\n# on peut indiquer le mot cle tangent_ddl_via_eps= suivi de 1 ou 0 (valeur par defaut) " << "\n# une valeur de 1 indique que l'on souhaite calculer l'operateur tangent dsig/d_ddl " << "\n# via l'operation composee: dsig/deps * deps/d_ddl (ce qui n'est pas le cas par defaut)" << "\n# " << "\n# " << endl; }; }; // test si la loi est complete int LoiAdditiveEnSigma::TestComplet() {int ret = LoiAbstraiteGeneral::TestComplet(); list ::const_iterator ili,ilifin=lois_internes.end(); for (ili=lois_internes.begin();ili!=ilifin;ili++) { ret *=(*ili)->TestComplet(); } return ret; }; // calcul d'un module d'young équivalent à la loi, ceci pour un // chargement nul double LoiAdditiveEnSigma::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(); // on balaie les infos de chaque loi SaveResul_LoiAdditiveEnSigma & save_resul = *((SaveResul_LoiAdditiveEnSigma*) saveResul_ex); list ::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois // cas éventuelle des fonctions de pondération list ::iterator ipfonc; if (avec_ponderation) ipfonc = save_resul.f_ponder.begin(); for (ili=lois_internes.begin(),ic=list_completude_calcul.begin();ili!=ilifin;ili++,ic++,isave++) { if (*ic != TANGENT_UNIQUEMENT) {if ((avec_ponderation)&&((*ipfonc) != 1.)) {E +=(*ili)->Module_young_equivalent(temps,def,*isave) * (*ipfonc);} else {E +=(*ili)->Module_young_equivalent(temps,def,*isave);}; }; 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 LoiAdditiveEnSigma::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(); // on balaie les infos de chaque loi SaveResul_LoiAdditiveEnSigma & save_resul = *((SaveResul_LoiAdditiveEnSigma*) saveResul_ex); list ::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois // cas éventuelle des fonctions de pondération list ::iterator ipfonc; if (avec_ponderation) ipfonc = save_resul.f_ponder.begin(); for (ili=lois_internes.begin(),ic=list_completude_calcul.begin();ili!=ilifin;ili++,ic++) { if (*ic != TANGENT_UNIQUEMENT) {if ((avec_ponderation)&&((*ipfonc) != 1.)) {module_compressibilite +=(*ili)->Module_compressibilite_equivalent(temps,def,*isave) * (*ipfonc);} else {module_compressibilite +=(*ili)->Module_compressibilite_equivalent(temps,def,*isave);}; }; 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 LoiAdditiveEnSigma::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_enu=1;i_enu<= taille; i_enu++) { // 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_enu)) {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_enu).Enum())) {tabnoeud(i)->Met_en_service(ponder.Type_grandeur()(i_enu).Enum());} else { cout << "\n erreur: la grandeur " << ponder.Type_grandeur()(i) << " n'existe pas " << " il n'est pas possible d'utiliser une loi additive ponderee avec cette grandeur " << " il manque sans doute des donnees aux noeuds !!! " << "\n LoiAdditiveEnSigma::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 additive ponderee ne peut pas s'utiliser ici telle quelle ***" << " demander une modification ! "; cout << "\n LoiAdditiveEnSigma::Activation_donnees(.. " << endl; Sortie(1); }; // cas normal switch (ponder.Type_grandeur()(i_enu).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: { Enum_ddl enu = ponder.Type_grandeur()(i_enu).Enum(); // pour simplifier // si c'est EPS11, c'est ok, on n'a rien à faire car c'est directement dispo sinon les autres cas sont pb if (enu != EPS11) {cout << "\n erreur, le type de proportion " << ponder.Type_grandeur()(i_enu) << " n'est pas disponible " << " pour l'instant au point d'integration ! " << "\n LoiAdditiveEnSigma::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 LoiAdditiveEnSigma::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_LoiAdditiveEnSigma & save_resul = *((SaveResul_LoiAdditiveEnSigma*) saveDon); list ::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois list ::const_iterator ili,ilifin=lois_internes.end(); int dim = ParaGlob::Dimension(); // maintenant on s'occupe des grandeurs de la loi additive elle même, List_io::iterator itq,itqfin=liTQ.end(); list::iterator idecal=decal.begin(); for (itq=liTQ.begin();itq!=itqfin;itq++,idecal++) {TypeQuelconque& tipParticu = (*itq); // pour simplifier if (tipParticu.EnuTypeQuelconque().Nom_vide()) // veut dire que c'est un enum pur { EnumTypeQuelconque enuTQ = tipParticu.EnuTypeQuelconque().EnumTQ(); // 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; //--debug // cout << "\n taille " << save_resul.l_sigoHH_t.size() << endl; // for (ili=lois_internes.begin(),isig_t = save_resul.l_sigoHH_t.begin(); // ili!=ilifin;ili++,isig_t++) // (*(isig_t))->Ecriture(cout); // cout << endl; // Sortie(1); //--fin debug for (ili=lois_internes.begin(),isig_t = save_resul.l_sigoHH_t.begin(); ili!=ilifin;ili++,isig_t++) {TenseurHH* sigHH = (*(isig_t)); // pour simplifier if (Dabs(sigHH->Dimension()) != dim) {tyTQ(1+(*idecal)).Affectation_trans_dimension(*sigHH,true); } else // cas même dimension {tyTQ(1+(*idecal)) = *(*(isig_t)); }; (*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 = save_resul.f_ponder_t.end(); for (ipfonc=save_resul.f_ponder_t.begin();ipfonc != ipfonc_fin;ipfonc++) {tyTQ(1+(*idecal)) = (*ipfonc); (*idecal)++;}; }; }; }; // puis appel des lois élémentaires for (ili=lois_internes.begin();ili!=ilifin;ili++,isave++) (*ili)->Grandeur_particuliere(absolue,liTQ,*isave,decal); }; // 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 LoiAdditiveEnSigma::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); }; // maintenant on s'occupe des grandeurs de la loi additive elle même, // 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 LoiAdditiveEnSigma::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 LoiAdditiveEnSigma::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 >> tangent_ddl_via_eps >> st1 >> type_calcul >> st1 >> avec_ponderation >> st2; // on regarde s'il y a une pondération nD également bool avec_nD; // on vide la liste au cas où {if (!list_ponderation_nD_quelconque.empty()) {list ::iterator il, ilfin= list_ponderation_nD_quelconque.end(); // on commence par supprimer les grandeurs pointées for (il = list_ponderation_nD_quelconque.begin();il != ilfin; il++) if (*il != NULL) delete (*il); list_ponderation_nD_quelconque.clear(); // puis on vide }; }; ent >> st1 >> avec_nD; // lecture du fait qu'il y a ou non du nD // 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); // on boucle sur le nombre de loi for (int i=1;i<= nb_loi; i++) { string toto; ent >> toto >> toto ; // passage de "===>sous_loi nb " 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); // cas éventuel des fonctions nD if (avec_nD) {bool existe_fct; ent >> st1 >> existe_fct; if (existe_fct) // cas où il y a une fonction {Ponderation_TypeQuelconque* pt = new Ponderation_TypeQuelconque(); pt->Lecture_base_info(ent, cas, lesFonctionsnD); list_ponderation_nD_quelconque.push_back(pt); } else list_ponderation_nD_quelconque.push_back(NULL); }; }; //------ 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 lu " << nom_completude_calcul << " au lieu d'un des noms suivants CONTRAINTE_ET_TANGENT CONTRAINTE_UNIQUEMENT TANGENT_UNIQUEMENT "; cout << "\n LoiAdditiveEnSigma::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); }; // s'il y a pondération avec des grandeurs locales, on va vérifier que ces grandeurs // sont dispo et on va préparer l'accès à ces grandeurs if (!list_ponderation_nD_quelconque.empty()) Verif_et_preparation_acces_grandeurs_locale(); } 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 LoiAdditiveEnSigma::Ecriture_base_info_loi(ofstream& sort,const int cas) { if (cas == 1) { sort << "\n loiAdditiveEnSigma " << lois_internes.size() << " tangent_ddl_via_eps= "<< tangent_ddl_via_eps <<" "; sort << "\n type_calcul_additif " << type_calcul; sort << " avec_ponderation "; if (avec_ponderation) {sort << 1 ;} else {sort << 0;}; // on regarde s'il y a une pondération nD également bool avec_nD = false; if ( list_ponderation_nD_quelconque.empty()) {sort << " nD= 0 ";} else // cas avec nD {sort << " nD= 1 "; avec_nD = true; }; sort <<" ,_les_lois: "; list ::const_iterator ili,ilifin=lois_internes.end(); list ::const_iterator ic,icfin=list_completude_calcul.end(); list ::const_iterator ipon; list ::const_iterator ipon_nD; if ( avec_nD) ipon_nD= list_ponderation_nD_quelconque.begin(); if (avec_ponderation) ipon = list_ponderation.begin(); int compteur_loi = 1; // init for (ili=lois_internes.begin(),ic=list_completude_calcul.begin(); ili!=ilifin;ili++,ic++,compteur_loi++) {sort << "\n ===>sous_loi "<< compteur_loi << " "; 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++; // cas éventuel des fonctions nD if (avec_nD) {if (*ipon_nD != NULL) {bool sans_courbe = false; sort << " fct_nD 1 "; (*ipon_nD)->Ecriture_base_info(sort,cas,sans_courbe); } else {sort << " fct_nD 0 ";}; ipon_nD++; // on avance pour la loi suivante }; }; 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); }; } else { list ::const_iterator ili,ilifin=lois_internes.end(); for (ili=lois_internes.begin();ili!=ilifin;ili++) (*ili)->Ecriture_base_info_loi(sort,cas); }; }; // ========== codage des METHODES VIRTUELLES protegees:================ // calcul des contraintes a t+dt void LoiAdditiveEnSigma::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_LoiAdditiveEnSigma & save_resul = *((SaveResul_LoiAdditiveEnSigma*) 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 = save_resul.f_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 // 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); ////----- debug ////if (((*(*isig))(1,1) < 0.) && ((*ipfonc) != 0.)) // { cout << "\n debug LoiAdditiveEnSigma::Calcul_SigmaHH " // << " (*(*isig))(1,1)= "<<(*(*isig))(1,1)<< ", (*ipfonc)= "<< (*ipfonc) // << endl; // }; ////--- fin debug if ((avec_ponderation)&&((*ipfonc) != 1.)) { // double coef = (*ipfonc); // coef sans le local // if (avec_fctnD_quelc) coef *= (*ipfonc_nD); // + le local // switch(type_calcul) // choix en fonction du type // { case 1 : // cas où les proportions s'appliquent à la totalité // {module_compressibilite += coef*compress_inter; // module_cisaillement += coef*cisaill_inter; // energ += (*ienerg) * coef; // update des énergies totales // (*sigtotalHH) += coef*(*(*isig)); // on ajoute la contrainte au total // break; // } // case 2 : // cas où les proportions s'appliquent aux deltats // {module_compressibilite += coef*compress_inter; // module_cisaillement += coef*cisaill_inter; // energ += (*ienerg) * coef; // update des énergies totales // (*sigtotalHH) += (*(*isig_t)) + coef*((*(*isig))-(*(*isig_t))); // on ajoute la contrainte au total // break; // } double coef = (*ipfonc); // if (avec_fctnD_quelc) coef *= (*ipfonc_nD); module_compressibilite += coef*compress_inter; module_cisaillement += coef*cisaill_inter; energ += (*ienerg) * coef; // update des énergies totales (*sigtotalHH) += coef*(*(*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++; // if (avec_fctnD_quelc) ipfonc_nD++; }; }; }; //////----- debug //if (((*sigtotalHH)(1,1) < 0.) && (Dabs(*ipfonc) > ConstMath::petit)) // { cout << "\n **** erreur debug LoiAdditiveEnSigma::Calcul_SigmaHH " // << "(*sigtotalHH)(1,1)= " << (*sigtotalHH)(1,1) << " (*ipfonc)= "<< (*ipfonc); // }; // // { cout << "\n debug LoiAdditiveEnSigma::Calcul_SigmaHH " // << " (*sigtotalHH)(1,1)="<<(*sigtotalHH)(1,1) // << endl; // }; //////--- fin debug // recopie du résultat sigHH = (*sigtotalHH); delete sigtotalHH; delete zeroHH; LibereTenseur(); }; // calcul des contraintes a t+dt et de ses variations void LoiAdditiveEnSigma::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 & energ_t ,double& module_compressibilite,double& module_cisaillement ,const Met_abstraite::Impli& ex ) { // dans le cas très particulier ou on veut un opérateur tangent via dsig/deps on appelle // une routine particulière if (tangent_ddl_via_eps) {Calcul_DsigmaHH_via_eps_tdt (sigHH_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,energ,energ_t ,module_compressibilite,module_cisaillement,ex ); return; }; // 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_LoiAdditiveEnSigma & save_resul = *((SaveResul_LoiAdditiveEnSigma*) saveResul); ////---debug // //ofstream fichier("toto", ios::app); //this->Ecriture_base_info_loi(fichier,1); // calcul de la contrainte résultante // //cout << "\n nb loi= " << save_resul.liste_des_SaveResul.size() << endl; ////---fin debug 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 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 = save_resul.f_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 //---debug //cout << "\n isave = " << ( (*isave) == NULL ) << endl; //---fin debug // calcul de la contrainte résultante (*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); // --- traitement en fonction du type de calcul //cout << "\n ipfonc= " << (*ipfonc) << endl; ////------- debug ------ // { cout << "\n debug LoiAdditiveEnSigma: contrainte et variation d'une loi individuelle "; // cout << "\n contrainte "; sigHH_tdt.Ecriture(cout); // cout << "\n variation contrainte/ddl "; // for (int i=1;i<=taille;i++) // d_sigHH(i)->Ecriture(cout); // cout << " \n -- fin contrainte et variation d'une loi individuelle --- "<< endl ; // }; ////------- fin debug ------ switch (*ic) { case CONTRAINTE_ET_TANGENT: // cas normal {if ((avec_ponderation)&&((*ipfonc) != 1.)) {double coef = (*ipfonc); // if (avec_fctnD_quelc) coef *= (*ipfonc_nD); ////------- debug ------ // { cout << "\n debug LoiAdditiveEnSigma::Calcul_DsigmaHH_tdt "; // cout << "\n (*ipfonc)= "<< (*ipfonc) ; // cout << "(*ipfonc_nD)= " << (*ipfonc_nD) << endl ; // }; ////------- fin debug ------ module_compressibilite += coef * compress_inter; module_cisaillement += coef * cisaill_inter; energ += (*ienerg) * coef; // update des énergies totales (*sigtotalHH) += coef * (sigHH_tdt); // on ajoute la contrainte au total (*(*isig)) = sigHH_tdt; // on sauvegarde la contrainte partielle //cout << "\n ipfonc= " << (*ipfonc) << " "; // récup de l'opérateur tangent for (int j=1;j<=taille;j++) { (*d_SigtotalHH(j)) += coef * (*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.)) {double coef = (*ipfonc); // if (avec_fctnD_quelc) coef *= (*ipfonc_nD); module_compressibilite += coef * compress_inter; module_cisaillement += coef * cisaill_inter; energ += (*ienerg) * coef; // update des énergies totales (*sigtotalHH) += coef * (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.)) {double coef = (*ipfonc); // if (avec_fctnD_quelc) coef *= (*ipfonc_nD); // récup de l'opérateur tangent for (int j=1;j<=taille;j++) { (*d_SigtotalHH(j)) += coef * (*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++; // if (avec_fctnD_quelc) ipfonc_nD++; }; }; // 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 a t+dt et de ses variations void LoiAdditiveEnSigma::Calcul_DsigmaHH_via_eps_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 & energ_t ,double& module_compressibilite,double& module_cisaillement ,const Met_abstraite::Impli& ex ) { //il nous faut une Met_abstraite::Umat_cont Met_abstraite::Umat_cont umat; // def ex.Recup_Umat_cont(umat); // récup des grandeurs ad hoc d'Impli // redimentionnement éventuel pour le comportement tangent if (d_sigma_deps_pourCalcul_DsigmaHH_via_eps_tdt != NULL) { int dim_HHHH = d_sigma_deps_pourCalcul_DsigmaHH_via_eps_tdt->Dimension(); switch (Abs(sigHH_t.Dimension())) {case 3: if (dim_HHHH != 33) {delete d_sigma_deps_pourCalcul_DsigmaHH_via_eps_tdt; d_sigma_deps_pourCalcul_DsigmaHH_via_eps_tdt = NevezTenseurHHHH(33); }; break; case 2: if (dim_HHHH != 22) {delete d_sigma_deps_pourCalcul_DsigmaHH_via_eps_tdt; d_sigma_deps_pourCalcul_DsigmaHH_via_eps_tdt = NevezTenseurHHHH(22); }; break; case 1: if (dim_HHHH != 11) {delete d_sigma_deps_pourCalcul_DsigmaHH_via_eps_tdt; d_sigma_deps_pourCalcul_DsigmaHH_via_eps_tdt = NevezTenseurHHHH(11); }; break; default: cout << "\n *** dimensiont incorrecte !!! on arrete " << "\n LoiAdditiveEnSigma::Calcul_DsigmaHH_via_eps_tdt(..."; Sortie(1); }; } else { switch (Abs(sigHH_t.Dimension())) {case 3: d_sigma_deps_pourCalcul_DsigmaHH_via_eps_tdt = NevezTenseurHHHH(33); // on essaie avec un tenseur général, pas de symétrie prise en compte // d_sigma_deps_pourCalcul_DsigmaHH_via_eps_tdt = NevezTenseurHHHH(30); break; case 2: d_sigma_deps_pourCalcul_DsigmaHH_via_eps_tdt = NevezTenseurHHHH(22); break; case 1: d_sigma_deps_pourCalcul_DsigmaHH_via_eps_tdt = NevezTenseurHHHH(11); break; default: cout << "\n *** dimensiont incorrecte !!! on arrete " << "\n LoiAdditiveEnSigma::Calcul_DsigmaHH_via_eps_tdt(..."; Sortie(1); }; } // appel de Calcul_dsigma_deps bool en_base_orthonormee = false; // on est en curviligne Calcul_dsigma_deps (en_base_orthonormee,sigHH_t,DepsBB ,epsBB_tdt,delta_epsBB,jacobien_0,jacobien ,sigHH_tdt ,*d_sigma_deps_pourCalcul_DsigmaHH_via_eps_tdt ,energ,energ_t,module_compressibilite,module_cisaillement ,umat); // maintenant on peut calculer l'opérateur tangent / ddl int nbddl = d_gijBB_tdt.Taille(); for (int i = 1; i<= nbddl; i++) { *(d_sigHH(i)) = (*d_sigma_deps_pourCalcul_DsigmaHH_via_eps_tdt) && (*(d_epsBB(i))); }; // for (int i = 1; i<= nbddl; i++) // { Tenseur3HH & dsigHH = *((Tenseur3HH*) (d_sigHH(i))); // passage en dim 3 // const Tenseur3BB & depsBB = *((Tenseur3BB *) (d_epsBB(i))); // " // dsigHH = (*d_sigma_deps_pourCalcul_DsigmaHH_via_eps_tdt) && depsBB; // }; LibereTenseur();LibereTenseurQ(); }; // 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 LoiAdditiveEnSigma::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_LoiAdditiveEnSigma & save_resul = *((SaveResul_LoiAdditiveEnSigma*) 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);}; // 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 = save_resul.f_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 // calcul de la contrainte résultante //cout << "\n boucle 100000 pour debug LoiAdditiveEnSigma::Calcul_dsigma_deps "<Calcul_dsigma_deps (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,ex); // --- traitement en fonction du type de calcul switch (*ic) { case CONTRAINTE_ET_TANGENT: // cas normal {if ((avec_ponderation)&&((*ipfonc) != 1.)) {double coef = (*ipfonc); // if (avec_fctnD_quelc) coef *= (*ipfonc_nD); module_compressibilite += coef * compress_inter; module_cisaillement += coef * cisaill_inter; energ += (*ienerg) * coef; // update des énergies totales (*sigtotalHH) += coef * (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 * coef ; } 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.)) {double coef = (*ipfonc); // if (avec_fctnD_quelc) coef *= (*ipfonc_nD); module_compressibilite += coef * compress_inter; module_cisaillement += coef * cisaill_inter; energ += (*ienerg) * coef; // update des énergies totales (*sigtotalHH) += coef * (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.)) {double coef = (*ipfonc); // if (avec_fctnD_quelc) coef *= (*ipfonc_nD); // récup de l'opérateur tangent d_sigma_deps += *d_sigma_deps_inter * coef ; } 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++; // if (avec_fctnD_quelc) ipfonc_nD++; }; }; // recopie du résultat sigHH_tdt = (*sigtotalHH); delete sigtotalHH; delete zeroHH; LibereTenseur();LibereTenseurQ(); }; // fonction interne utilisée par les classes dérivées de Loi_comp_abstraite // pour répercuter les modifications de la température // ici utiliser pour modifier la température des lois élémentaires // l'Enum_dure: indique quel est la température courante : 0 t ou tdt void LoiAdditiveEnSigma::RepercuteChangeTemperature(Enum_dure temps) { list ::const_iterator ili,ilifin=lois_internes.end(); for (ili=lois_internes.begin();ili!=ilifin;ili++) {(*ili)->temperature_0 = this->temperature_0; (*ili)->temperature_t = this->temperature_t; (*ili)->temperature_tdt = this->temperature_tdt; (*ili)->dilatation=dilatation; // on répercute également les déformations thermiques, qui ne sont utilisées // telles quelles que pour certaines lois: ex: loi hyper-élastique if (dilatation) {// a- dimensionnement des tenseurs intermédiaires int dim_tens = epsBB_therm->Dimension(); // -- cas de la déformation if ((*ili)->epsBB_therm == NULL) { (*ili)->epsBB_therm = NevezTenseurBB(dim_tens);} else if ((*ili)->epsBB_therm->Dimension() != dim_tens) { delete (*ili)->epsBB_therm;(*ili)->epsBB_therm = NevezTenseurBB(dim_tens);}; // -- cas de la vitesse de déformation if ((*ili)->DepsBB_therm == NULL) { (*ili)->DepsBB_therm = NevezTenseurBB(dim_tens);} else if ((*ili)->DepsBB_therm->Dimension() != dim_tens) { delete (*ili)->DepsBB_therm;(*ili)->DepsBB_totale = NevezTenseurBB(dim_tens);}; // b- affectation des tenseurs (*(*ili)->epsBB_therm)=(*epsBB_therm); (*(*ili)->DepsBB_therm)=(*DepsBB_therm); }; // on répercute sur les lois internes (*ili)->RepercuteChangeTemperature(temps); Loi_comp_abstraite * loi_ili = (*ili); // pour le débug switch (temps) { case TEMPS_0: {(*ili)->temperature = &(*ili)->temperature_0; break;} case TEMPS_t: {(*ili)->temperature = &(*ili)->temperature_t; break;} case TEMPS_tdt: {(*ili)->temperature = &(*ili)->temperature_tdt; break;} default: { cout << "\n erreur, cas de temps non prevu !! " << "\n LoiAdditiveEnSigma::RepercuteChangeTemperature(..."; Sortie(1); }; }; #ifdef MISE_AU_POINT if (Permet_affichage() > 7) { cout << "\n init temperatures:\n " << " loi_ili->temperature_0= " << loi_ili->temperature_0 << " loi_ili->temperature_t= " << loi_ili->temperature_t << " loi_ili->temperature_tdt= " << loi_ili->temperature_tdt << " loi_ili->temperature= " << *(loi_ili->temperature) << " \n LoiAdditiveEnSigma::RepercuteChangeTemperature(.." << endl; }; #endif }; }; // fonction surchargée dans les classes dérivée si besoin est void LoiAdditiveEnSigma::CalculGrandeurTravail (const PtIntegMecaInterne& ptintmeca ,const Deformation & def,Enum_dure temps,const ThermoDonnee& dTP ,const Met_abstraite::Impli* ex_impli ,const Met_abstraite::Expli_t_tdt* ex_expli_tdt ,const Met_abstraite::Umat_cont* ex_umat ,const List_io* exclure_dd_etend ,const List_io* exclure_Q ) { // récup et enregistrement dans les variables spécifiques au point calculé SaveResul_LoiAdditiveEnSigma & save_resul = *((SaveResul_LoiAdditiveEnSigma*) saveResul); if (avec_ponderation) { // on passe en revue les grandeurs servant au calcul des fonctions de proportion {list ::iterator il,ilfin=list_ponderation.end(); list ::iterator ipfonc = save_resul.f_ponder.begin(); for (il=list_ponderation.begin();il != ilfin;il++,ipfonc++) { Ponderation& ponder = (*il); // pour simplifier (*ipfonc)=1.; // init int taille = ponder.Type_grandeur().Taille(); for (int i=1;i<= taille; i++) { // calcul des pondérations if (ponder.Valeur_aux_noeuds()(i)) // pour l'instant que des ddl patentés ! // cas d'une proportion provenant d'une interpolation aux noeuds { double grand = def.DonneeInterpoleeScalaire(ponder.Type_grandeur()(i).Enum(),temps); double fonc = ponder.C_proport()(i)->Valeur(grand); (*ipfonc) *= fonc; // on accumule multiplicativement } else // sinon il s'agit d'une grandeur directement accessible au point d'intégration // pour l'instant il n'y a pas de procédure générale de récupération, seulement des cas particuliers { // deux cas suivant que l'on a affaire à un ddl de base ou à un vrai ddl étendu if (ponder.Type_grandeur()(i).Nom_vide()) {Enum_ddl enu = ponder.Type_grandeur()(i).Enum(); // pour simplifier switch (enu) { case PROP_CRISTA: { const double* taux_crita = dTP.TauxCrista(); if (taux_crita != NULL) { double fonc = ponder.C_proport()(i)->Valeur(*taux_crita); (*ipfonc) *= fonc; // on accumule multiplicativement } else {cout << "\n erreur, le taux de cristalinite n'est pas disponible au point d'integration " << " il n'est pas possible de calculer la proportion pour la loi des melanges " << "\n LoiAdditiveEnSigma::CalculGrandeurTravail(.... "; }; break; } case EPS11: { double eps11 = (ptintmeca.EpsBB_const())(1,1); double fonc = ponder.C_proport()(i)->Valeur(eps11); (*ipfonc) *= fonc; // on accumule multiplicativement ////----- debug ////if ((spherique_sig < 0.) && (fonc != 0.)) // { cout << "\n debug LoiAdditiveEnSigma::CalculGrandeurTravail " // << " EPS11= "<Valeur(def_equivalente); (*ipfonc) *= fonc; // on accumule multiplicativement //cout << "\n defEqui= " << def_equivalente << " fonct= " << fonc << " "; break; } case 88: // cas de "def_duale_mises_maxi" {const double def_duale_mises_maxi = ptintmeca.Deformation_equi_const()(3); // recup de la def equi double fonc = ponder.C_proport()(i)->Valeur(def_duale_mises_maxi); (*ipfonc) *= fonc; // on accumule multiplicativement break; } case 89: // cas de "vitesse_def_equivalente" {const double delta_def_equivalente = ptintmeca.Deformation_equi_const()(4); // recup du delta def equi // recup de l'incrément de temps double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant(); double unSurDeltat=0; if (Abs(deltat) >= ConstMath::trespetit) {unSurDeltat = 1./deltat;} else // si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand { // un pas de temps doit être positif !! or certaine fois il peut y avoir des pb if (unSurDeltat < 0) { cout << "\n le pas de temps est négatif !! "; }; unSurDeltat = ConstMath::tresgrand; }; double vitesse_def_equi = delta_def_equivalente * unSurDeltat; double fonc = ponder.C_proport()(i)->Valeur(vitesse_def_equi); (*ipfonc) *= fonc; // on accumule multiplicativement //cout << "\n vit= " << vitesse_def_equi << " f= " << fonc << endl; break; } case 77: // cas de "def_duale_mises" {const double def_duale_mises = ptintmeca.Deformation_equi_const()(2); // recup de la def equi double fonc = ponder.C_proport()(i)->Valeur(def_duale_mises); (*ipfonc) *= fonc; // on accumule multiplicativement break; } case 78: // cas de "Spherique_eps" {const Vecteur & epsInvar = ptintmeca.EpsInvar_const(); // recup des invariants double spherique_eps = epsInvar(1); double fonc = ponder.C_proport()(i)->Valeur(spherique_eps); (*ipfonc) *= fonc; // on accumule multiplicativement break; } case 81: // cas de "Spherique_sig" {const Vecteur & sigInvar = ptintmeca.SigInvar_const(); // recup des invariants double spherique_sig = sigInvar(1); double fonc = ponder.C_proport()(i)->Valeur(spherique_sig); ////----- debug ////if ((spherique_sig < 0.) && (fonc != 0.)) // { cout << "\n debug LoiAdditiveEnSigma::CalculGrandeurTravail " // << " i="<< i << " spherique_sig= "<::iterator il,ilfin=list_ponderation_nD_quelconque.end(); // // on reparcourt les pondérations list ::iterator ipfonc = save_resul.f_ponder.begin(); for (il=list_ponderation_nD_quelconque.begin();il != ilfin;il++,ipfonc++) {//(*ipfonc)=1.; // init if (*il != NULL) {Ponderation_TypeQuelconque& pondnD = *(*il); // on utilise la méthode générique de loi abstraite Tableau & tab_val = Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee (pondnD.C_proport(),1 // une seule valeur attendue en retour ,ex_impli,ex_expli_tdt,ex_umat ,exclure_dd_etend ,exclure_Q ,&(save_resul.liste_des_SaveResul) ); (*ipfonc) *= tab_val(1); // on accumule multiplicativement ////------- debug ------ // { cout << "\n debug LoiAdditiveEnSigma::CalculGrandeurTravail "; // cout << "\n argument "<< pondnD.Tab_argument() ; // cout << "(*ipfonc_nD)= " << (*ipfonc) << endl ; // }; ////------- fin debug ------ }; }; }; }; // répercution sur les classes dérivées si besoin est list ::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois list ::const_iterator ili,ilifin=lois_internes.end(); for (ili=lois_internes.begin();ili!=ilifin;ili++,isave++) {// 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 (*ili)->CalculGrandeurTravail(ptintmeca,def,temps,dTP ,ex_impli,ex_expli_tdt,ex_umat,exclure_dd_etend,exclure_Q); }; }; // vérification et préparation de l'acces aux grandeurs locales void LoiAdditiveEnSigma::Verif_et_preparation_acces_grandeurs_locale() {// 1) on demande aux lois de prendre en compte éventuellement les grandeurs locales nécessaires list listEnuQuelc; // def de la liste des grandeurs quelconque // récup des grandeurs quelconques nécessaires if (!list_ponderation_nD_quelconque.empty()) { list ::iterator il,ilfin=list_ponderation_nD_quelconque.end(); for (il = list_ponderation_nD_quelconque.begin();il != ilfin;il++) if ((*il)!= NULL) {const Tableau & tab_enu_quelc = (*il)->C_proport()->Tab_enu_quelconque(); int tail = tab_enu_quelc.Taille(); if (tail) {for (int i = 1; i<= tail; i++) listEnuQuelc.push_back(tab_enu_quelc(i)); }; }; listEnuQuelc.sort(); listEnuQuelc.unique(); // 2) on vérifie qu'une des lois au moins produira la grandeur quelconque list ::iterator kk,kkfin=lois_internes.end(); list ::iterator jj,jjfin=listEnuQuelc.end(); for (jj=listEnuQuelc.begin();jj != jjfin; jj++) {bool existe = false; // par défaut pb for (kk=lois_internes.begin();kk != kkfin;kk++) {if(((*kk)->Existe_stockage_grandeurs_quelconques((*jj)))) existe = true; ////--- debug //cout << "\n debug LoiAdditiveEnSigma::Verif_et_preparation_acces_grandeurs_locale() "; //cout <<"\n nom_loi: "<< (*kk)->Nom_comport() <<", ce que l'on regarde: "<< NomTypeQuelconque(*jj) << ", existe= "<< existe << "\n "; //const list & liinter = (*kk)->ListdeTouslesQuelc_dispo_localement(); // //if (!(liinter.empty())) // {list ::const_iterator hh,hfin=liinter.end(); // for (hh=liinter.begin();hh!=hfin;hh++) // cout << NomTypeQuelconque(*hh) << " "; // }; // // ////--- fin debug // }; if (!existe) { cout << "\n *** erreur d'utilisation de grandeur locale " << " la grandeur "<Activation_stockage_grandeurs_quelconques(listEnuQuelc); (*kk)->Activation_stockage_grandeurs_quelconques(listEnuQuelc); // for (EnumTypeQuelconque enu : listEnuQuelc) // for (Loi_comp_abstraite * loii : lois_internes) // if(!(loii->Existe_stockage_grandeurs_quelconques(enu))) // { cout << "\n *** erreur d'utilisation de grandeur locale " // << " la grandeur "<