// FICHIER : LoiDesMelangesEnSigma.cp // CLASSE : LoiDesMelangesEnSigma // 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 "TypeQuelconqueParticulier.h" #include "TypeConsTens.h" #include "NevezTenseurQ.h" #include "CharUtil.h" #include "LoiDesMelangesEnSigma.h" //==================== cas de la class de sauvegarde SaveResul =================== // constructeur par défaut à ne pas utiliser LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma() : liste_des_SaveResul() ,l_sigoHH(),l_sigoHH_t(),l_energ(),l_energ_t() ,J_sigoHH(),J_sigoHH_t(),proportion(1.),proportion_t(1.),type_evolution_proportion(0) ,deja_actif_sur_iter1(false),deja_actif_sur_iter2(false) { cout << "\n erreur, le constructeur par defaut ne doit pas etre utilise !" << "\n LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma()"; Sortie(1); }; // le constructeur courant LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma (list & l_des_SaveResul ,list & l_siHH,list & l_siHH_t ,list & J_siHH,list & J_siHH_t ,list & l_energ_,list & l_energ_t_ ,int type_evol_proportion): liste_des_SaveResul() ,l_sigoHH(),l_sigoHH_t(),l_energ(l_energ_),l_energ_t(l_energ_t_) ,J_sigoHH(),J_sigoHH_t(),proportion(1.),proportion_t(1.) ,type_evolution_proportion(type_evol_proportion) ,deja_actif_sur_iter1(false),deja_actif_sur_iter2(false) { list ::const_iterator ili,ilifin=l_des_SaveResul.end(); list ::const_iterator isig,isig_t,jsig,jsig_t; for (ili=l_des_SaveResul.begin(),isig = l_siHH.begin(),isig_t = l_siHH_t.begin() ,jsig = J_siHH.begin(),jsig_t = J_siHH_t.begin(); ili!=ilifin;ili++,isig++,isig_t++,jsig++,jsig_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); TenseurHH * jnterHH=NULL; // dans le cas où le tenseur passé en paramètre est non null on s'en sert if ((*jsig) != NULL) {jnterHH=NevezTenseurHH(*(*jsig));}; J_sigoHH.push_back(jnterHH); TenseurHH * jnterHH_t=NULL; // idem interHH, dans le cas où le tenseur passé en paramètre est non null on s'en sert if ((*jsig_t) != NULL) {jnterHH_t =NevezTenseurHH(*(*jsig_t));}; J_sigoHH_t.push_back(jnterHH_t); }; //---debug //cout << "\n constructeur: taille_l_energ= " << l_energ.size() << " taille_l_energ_t= " << l_energ_t.size()<< endl; //---fin debug }; // constructeur de copie LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma (const LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma& sav ): liste_des_SaveResul() ,l_sigoHH(),l_sigoHH_t(),J_sigoHH(),J_sigoHH_t() ,l_energ(sav.l_energ),l_energ_t(sav.l_energ_t) ,proportion(sav.proportion),proportion_t(sav.proportion_t) ,type_evolution_proportion(sav.type_evolution_proportion) ,deja_actif_sur_iter1(sav.deja_actif_sur_iter1),deja_actif_sur_iter2(sav.deja_actif_sur_iter2) { list ::const_iterator ili,ilifin=sav.liste_des_SaveResul.end(); list ::const_iterator isig,isig_t,jsig,jsig_t; for (ili=sav.liste_des_SaveResul.begin(),isig = sav.l_sigoHH.begin(),isig_t = sav.l_sigoHH_t.begin() ,jsig = sav.J_sigoHH.begin(),jsig_t = sav.J_sigoHH_t.begin(); ili!=ilifin;ili++,isig++,isig_t++,jsig++,jsig_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); TenseurHH * jnterHH=NULL; // dans le cas où le tenseur passé en paramètre est non null on s'en sert if ((*jsig) != NULL) {jnterHH=NevezTenseurHH(*(*jsig));}; J_sigoHH.push_back(jnterHH); TenseurHH * jnterHH_t=NULL; // idem interHH, dans le cas où le tenseur passé en paramètre est non null on s'en sert if ((*jsig_t) != NULL) {jnterHH_t =NevezTenseurHH(*(*jsig_t));}; J_sigoHH_t.push_back(jnterHH_t); }; //---debug //cout << "\n constructeur_copie: taille_l_energ= " << l_energ.size() << " taille_l_energ_t= " << l_energ_t.size()<< endl; //this->Affiche(); cout << "\n" << endl; //---fin debug }; // destructeur LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::~SaveResul_LoiDesMelangesEnSigma() { list ::iterator ili,ilifin=liste_des_SaveResul.end(); list ::iterator isig,isig_t,jsig,jsig_t; for (ili=liste_des_SaveResul.begin(),isig = l_sigoHH.begin(),isig_t = l_sigoHH_t.begin() ,jsig = J_sigoHH.begin(),jsig_t = J_sigoHH_t.begin(); ili!=ilifin;ili++,isig++,isig_t++,jsig++,jsig_t++) {if ((*ili) != NULL) delete (*ili); //liste_des_SaveResul.erase(ili); if((*isig) != NULL) delete (*isig); if((*isig_t) != NULL) delete (*isig_t); if((*jsig) != NULL) delete (*jsig); if((*jsig_t) != NULL) delete (*jsig_t); }; }; // affectation Loi_comp_abstraite::SaveResul & LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::operator = ( const Loi_comp_abstraite::SaveResul & a) { LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma& sav = *((LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma*) &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(); list ::const_iterator kisig = sav.J_sigoHH.begin(); list ::const_iterator kisig_t = sav.J_sigoHH_t.begin(); if (liste_des_SaveResul.size() != sav.liste_des_SaveResul.size()) {// 1) on vide la liste list ::iterator jli,jlifin=liste_des_SaveResul.end(); list ::iterator jsig = l_sigoHH.begin(); list ::iterator jsig_t = l_sigoHH_t.begin(); list ::iterator ksig = J_sigoHH.begin(); list ::iterator ksig_t = J_sigoHH_t.begin(); // on supprime les grandeurs pointées for (jli=liste_des_SaveResul.begin();jli!=jlifin; jli++,jsig++,jsig_t++,ksig++,ksig_t++) {if ((*jli) != NULL) delete (*jli); //liste_des_SaveResul.erase(ili); if((*jsig) != NULL) delete (*jsig); if((*jsig_t) != NULL) delete (*jsig_t); if((*ksig) != NULL) delete (*ksig); if((*ksig_t) != NULL) delete (*ksig_t); }; // on vide les listes liste_des_SaveResul.clear();l_sigoHH.clear();l_sigoHH_t.clear(); J_sigoHH.clear();J_sigoHH_t.clear(); // 2) on recrée à la bonne taille for (ili=sav.liste_des_SaveResul.begin(); ili!=ilifin;ili++,isig++,isig_t++,kisig++,kisig_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); // idem pour kisig if ((*kisig) != NULL) {interHH_t =NevezTenseurHH(*(*kisig));}; J_sigoHH.push_back(interHH_t); // idem pour kisig_t if ((*kisig_t) != NULL) {interHH_t =NevezTenseurHH(*(*kisig_t));}; J_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(); list ::iterator ksig=J_sigoHH.begin(); list ::iterator ksig_t=J_sigoHH_t.begin(); for (ili=sav.liste_des_SaveResul.begin(); ili!=ilifin;ili++,isig++,isig_t++,kisig++,kisig_t++ ,jli++,jsig++,jsig_t++,ksig++,ksig_t++) { (*(*jli))=(*(*ili)); (*(*isig))=(*(*jsig));(*(*isig_t))=(*(*jsig_t)); (*(*ksig))=(*(*kisig));(*(*ksig_t))=(*(*kisig_t)); }; }; // puis les grandeurs qui ne posent pas de pb proportion = sav.proportion; proportion_t = sav.proportion_t; type_evolution_proportion = sav.type_evolution_proportion; l_energ = sav.l_energ; l_energ_t = sav.l_energ_t; deja_actif_sur_iter1 = sav.deja_actif_sur_iter1; deja_actif_sur_iter2 = sav.deja_actif_sur_iter2; 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 LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::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_LoiMeSig") { cout << "\n erreur en lecture du conteneur pour la loi additive" << " \n LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::Lecture_base_info(.."; Sortie(1); }; #endif // la proportion ent >> toto >> proportion_t ; //proportion = proportion_t; if (cas == 1) ent >> toto >> type_evolution_proportion; // le type d'évolution ent >> toto >> deja_actif_sur_iter1 >> deja_actif_sur_iter2; // lecture du nombre de loi int nb_loi; ent >> 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 LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::Lecture_base_info(.."; Sortie(1); }; #endif // on itère sur ces grandeurs list ::iterator ili,ilifin=liste_des_SaveResul.end(); list ::iterator isig_t,jsig_t; list ::iterator ienerg_t=l_energ_t.begin(); for (ili=liste_des_SaveResul.begin(),isig_t = l_sigoHH_t.begin(),jsig_t = J_sigoHH_t.begin(); ili!=ilifin;ili++,isig_t++,ienerg_t++) { // 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 de la contrainte sauvegardée (*jsig_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 LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::Ecriture_base_info (ofstream& sort,const int cas) { // ici la majorité des 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_LoiMeSig "; // la proportion sort << " prop= " << proportion_t << " "; if (cas == 1) sort << " type_evol_prop= " << type_evolution_proportion << " "; // deja_actif_sur_iter sort << " deja_actif_sur_iter= "<::iterator ili,ilifin=liste_des_SaveResul.end(); list ::iterator isig_t,jsig_t; list ::iterator ienerg_t=l_energ_t.begin(); for (ili=liste_des_SaveResul.begin(),isig_t = l_sigoHH_t.begin(),jsig_t = J_sigoHH_t.begin(); ili!=ilifin;ili++,isig_t++,ienerg_t++) { // données de chaque loi if ((*ili) != NULL) (*ili)->Ecriture_base_info(sort,cas);sort << " "; // la contrainte sauvegardée est celle stable uniquement (*isig_t)->Ecriture(sort); sort << " " ;// écriture du tenseur // la contrainte sauvegardée est celle stable uniquement (*jsig_t)->Ecriture(sort); // écriture du tenseur sort << " " << (*ienerg_t); // écriture des énergies }; }; // mise à jour des informations transitoires en définitif s'il y a convergence // par exemple (pour la plasticité par exemple) void LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::TdtversT() { list ::iterator ili,ilifin=liste_des_SaveResul.end(); list ::iterator isig_t,isig,jsig_t,jsig; list ::iterator ienerg,ienerg_t; for (ili=liste_des_SaveResul.begin(),isig_t = l_sigoHH_t.begin(),isig = l_sigoHH.begin() ,jsig_t = J_sigoHH_t.begin(),jsig = J_sigoHH.begin() ,ienerg=l_energ.begin(),ienerg_t=l_energ_t.begin(); ili!=ilifin;ili++,isig_t++,isig++,jsig_t++,jsig++,ienerg++,ienerg_t++) {if ((*ili) != NULL) (*ili)->TdtversT(); (*(*isig_t)) = (*(*isig));(*(*jsig_t)) = (*(*jsig)); (*ienerg_t)=(*ienerg); }; // la proportion proportion_t = proportion; //non, ce n'est pas la bonne solution dans le cas général proportion = 1.; // on démarre à priori sur la première loi // cas où la proportion démarrre à 1 et ne fait que diminuer sur chaque incrément // pour le premier incrément, la proportion est initialisée à la valeur par défaut if (type_evolution_proportion == 2) proportion = 1.; // deja_actif_sur_iter: pour l'instant on remet à false car // c'est présumé travailler uniquement sur un incrément deja_actif_sur_iter1 = deja_actif_sur_iter2 = false; }; void LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::TversTdt() { list ::iterator ili,ilifin=liste_des_SaveResul.end(); list ::iterator isig_t,isig,jsig_t,jsig; list ::iterator ienerg,ienerg_t; for (ili=liste_des_SaveResul.begin(),isig_t = l_sigoHH_t.begin(),isig = l_sigoHH.begin() ,jsig_t = J_sigoHH_t.begin(),jsig = J_sigoHH.begin() ,ienerg=l_energ.begin(),ienerg_t=l_energ_t.begin(); ili!=ilifin;ili++,isig_t++,isig++,jsig_t++,jsig++,ienerg++,ienerg_t++) {if ((*ili) != NULL) (*ili)->TversTdt(); (*(*isig)) = (*(*isig_t));(*(*jsig)) = (*(*jsig_t)); (*ienerg)=(*ienerg_t); }; // la proportion proportion = proportion_t; // cas où la proportion démarrre à 1 et ne fait que diminuer sur chaque incrément // pour le premier incrément, la proportion est initialisée à la valeur par défaut if (type_evolution_proportion == 2) proportion = 1.; // deja_actif_sur_iter: pour l'instant on remet à false car // c'est présumé travailler uniquement sur un incrément deja_actif_sur_iter1 = deja_actif_sur_iter2 = false; }; // affichage à l'écran des infos void LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::Affiche() const { cout << "\n SaveResul_LoiDesMelangesEnSigma: " ; 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 jsig,jsigfin=J_sigoHH.end(); list ::const_iterator jsig_t,jsig_tfin=J_sigoHH_t.end(); list ::const_iterator ienerg,ienergfin = l_energ.end(); list ::const_iterator ienerg_t,ienerg_tfin = l_energ_t.end(); cout << "\n liste_des_SaveResul: "; for (ili=liste_des_SaveResul.begin();ili!=ilifin;ili++) {if ((*ili) != NULL) { cout << "\n "; (*ili)->Affiche();};}; 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 J_sigoHH: "; for (jsig = J_sigoHH.begin();jsig!=jsigfin;jsig++) { (*jsig)->Ecriture(cout);}; cout << "\n J_sigoHH_t: "; for (jsig_t = J_sigoHH_t.begin();jsig_t!=jsig_tfin;jsig_t++) { (*jsig_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 proportion= " << proportion << " proportion_t= " << proportion_t << " "; cout << "\n deja_actif_sur_iter(1 et 2)= " << deja_actif_sur_iter1 <<" "<::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); }; { List_io ::iterator lit(J_sigoHH.begin()), lend(J_sigoHH.end()); for(;lit!=lend;++lit) // ici les bornes ne changent pas (*lit)->ChBase(gamma); }; { List_io ::iterator lit(J_sigoHH_t.begin()), lend(J_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* LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma ::Complete_SaveResul(const BlocGen & bloc, const Tableau & tab_coor ,const Loi_comp_abstraite* loi) {// on transmet au conteneur 3D interne const LoiDesMelangesEnSigma * loi_CP = (const LoiDesMelangesEnSigma*) loi; // récup des conteneurs relatifs à chaque loi list ::iterator ia = liste_des_SaveResul.begin(); // traitement de la première loi (*ia)->Complete_SaveResul(bloc,tab_coor,loi_CP->lois_internes1); // traitement de la seconde loi ia++; (*ia)->Complete_SaveResul(bloc,tab_coor,loi_CP->lois_internes2); return this; }; // ---- récupération d'information: spécifique à certaine classe dérivée double LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::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_LoiDesMelangesEnSigma::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 ============ LoiDesMelangesEnSigma::LoiDesMelangesEnSigma () : // Constructeur par defaut Loi_comp_abstraite(LOI_DES_MELANGES_EN_SIGMA,RIEN_CATEGORIE_LOI_COMP,0) ,lois_internes1(NULL),lois_internes2(NULL) ,calcule_si_prop_non_nulle(),d_sigtotalHH() ,type_grandeur(NU_DDL),proportion(1.),d_sigma_deps_inter(NULL) ,type_melange(1),valeur_aux_noeuds(true),c_proport(NULL),aA(1.) ,niveauF_grandeurND(NULL),niveauF_grandeurConsultable(NULL) ,niveauF_ddlEtendu(NULL),niveauF_temps(NULL) {}; // Constructeur de copie LoiDesMelangesEnSigma::LoiDesMelangesEnSigma (const LoiDesMelangesEnSigma& loi) : Loi_comp_abstraite(loi),type_grandeur(loi.type_grandeur),proportion(loi.proportion) ,lois_internes1(NULL),lois_internes2(NULL),calcule_si_prop_non_nulle(loi.calcule_si_prop_non_nulle) ,d_sigma_deps_inter(NULL),d_sigtotalHH() ,type_melange(loi.type_melange),valeur_aux_noeuds(loi.valeur_aux_noeuds) ,c_proport(loi.c_proport),aA(loi.aA) ,niveauF_grandeurND(loi.niveauF_grandeurND) ,niveauF_grandeurConsultable(NULL) ,niveauF_ddlEtendu(NULL),niveauF_temps(NULL) { lois_internes1 = loi.lois_internes1->Nouvelle_loi_identique(); lois_internes2 = loi.lois_internes2->Nouvelle_loi_identique(); // on regarde s'il s'agit d'une courbe locale ou d'une courbe globale if (c_proport != NULL) if (c_proport->NomCourbe() == "_") {// comme il s'agit d'une courbe locale on la redéfinie (sinon pb lors du destructeur de loi) string non_courbe("_"); c_proport = Courbe1D::New_Courbe1D(*loi.c_proport); }; // traitement des pondérations if (loi.niveauF_grandeurND != NULL) if (loi.niveauF_grandeurND->NomFonction() == "_") niveauF_grandeurND = Fonction_nD::New_Fonction_nD(*(loi.niveauF_grandeurND)); if (loi.niveauF_ddlEtendu != NULL) niveauF_ddlEtendu = new Ponderation(*(loi.niveauF_ddlEtendu)); if (loi.niveauF_temps != NULL) niveauF_temps = new Ponderation_temps(*(loi.niveauF_temps));; if (loi.niveauF_grandeurConsultable != NULL) niveauF_grandeurConsultable = new Ponderation_Consultable(*(loi.niveauF_grandeurConsultable)); }; LoiDesMelangesEnSigma::~LoiDesMelangesEnSigma () // Destructeur { if (lois_internes1 != NULL) delete lois_internes1; if (lois_internes2 != NULL) delete lois_internes2; if (d_sigma_deps_inter != NULL) delete d_sigma_deps_inter; if (d_sigtotalHH.Taille() != 0) { int taille = d_sigtotalHH.Taille(); for (int i=1; i<= taille; i++) if (d_sigtotalHH(i) != NULL) delete d_sigtotalHH(i); }; if (c_proport != NULL) if (c_proport->NomCourbe() == "_") delete c_proport; // cas des pondérations if (niveauF_grandeurND != NULL) if (niveauF_grandeurND->NomFonction() == "_") delete niveauF_grandeurND; if (niveauF_ddlEtendu != NULL) delete niveauF_ddlEtendu; if (niveauF_temps != NULL) delete niveauF_temps; if (niveauF_grandeurConsultable != NULL) delete niveauF_grandeurConsultable; }; // def d'une instance de données spécifiques, et initialisation // valable une fois que les différentes lois internes sont définit LoiDesMelangesEnSigma::SaveResul * LoiDesMelangesEnSigma::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 J_sigoHH,J_sigoHH_t; // gestion des contraintes pour chaque loi list l_energ,l_energ_t; // idem pour les énergies list ::iterator isig,isig_t; // on balaie les deux lois { SaveResul * nevez_save_result=NULL; if (lois_internes1 != NULL) nevez_save_result = lois_internes1->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); TenseurHH * jnterHH = NevezTenseurHH(dim,0.);J_sigoHH.push_back(jnterHH); TenseurHH * jnterHH_t = NevezTenseurHH(dim,0.);J_sigoHH_t.push_back(jnterHH_t); // on définit les conteneurs pour les énergies l_energ.push_back(EnergieMeca());l_energ_t.push_back(EnergieMeca()); } { SaveResul * nevez_save_result=NULL; if (lois_internes2 != NULL) nevez_save_result = lois_internes2->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); TenseurHH * jnterHH = NevezTenseurHH(dim,0.);J_sigoHH.push_back(jnterHH); TenseurHH * jnterHH_t = NevezTenseurHH(dim,0.);J_sigoHH_t.push_back(jnterHH_t); // on définit les conteneurs pour les énergies l_energ.push_back(EnergieMeca());l_energ_t.push_back(EnergieMeca()); } // on regarde le type de progressivité de la proportion éventuelle int type_evol_proportion = 0; // init par défaut if (calcule_si_prop_non_nulle.Taille() == 2) {if ((calcule_si_prop_non_nulle(1) == 2) || (calcule_si_prop_non_nulle(2) == 2)) type_evol_proportion = 1; else if ((calcule_si_prop_non_nulle(1) == 3) || (calcule_si_prop_non_nulle(2) == 3)) type_evol_proportion = 2; }; // on ramène la bonne instance LoiDesMelangesEnSigma::SaveResul * retour = new SaveResul_LoiDesMelangesEnSigma (liste_des_SaveResul,l_sigoHH,l_sigoHH_t ,J_sigoHH,J_sigoHH_t,l_energ,l_energ_t,type_evol_proportion); // 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(); list ::iterator jsib = J_sigoHH.begin(); list ::iterator jsib_t = J_sigoHH_t.begin(); for (ils=liste_des_SaveResul.begin();ils!=ilsfin;ils++,isib++,isib_t++,jsib++,jsib_t++) { if ((*ils) != NULL) delete (*ils); if ((*isib) != NULL) delete (*isib); if ((*isib_t) != NULL) delete (*isib_t); if ((*jsib) != NULL) delete (*jsib); if ((*jsib_t) != NULL) delete (*jsib_t); }; // retour return retour; }; // Lecture des donnees de la classe sur fichier void LoiDesMelangesEnSigma::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D ,LesFonctions_nD& lesFonctionsnD) { // lecture jusque l'on trouve le mot clé signalant la fin de la liste des loi élémentaires bool premier_lecture = true; // on lit tout d'abord la grandeur qui servira a établir la proportion entre la première loi et la // seconde string nom; *(entreePrinc->entree) >> nom; bool passer_une_ligne = true; // choix entre grandeur_proportion= et les_grandeurs_de_controle_= if ((nom != "grandeur_proportion=") && (nom != "les_grandeurs_de_controle_=")) { cout << "\n erreur en lecture de la loi des melanges en sigma," << " on attendait le mot cle grandeur_proportion= " << " et un identificateur de grandeur, ou les_grandeurs_de_controle_= " << " alors que l'on a lue: " << nom; entreePrinc->MessageBuffer("**erreur1 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; if (nom == "grandeur_proportion=") { *(entreePrinc->entree) >> type_grandeur; // lecture du type enumere de la grandeur // on regarde s'il faut lire le type de mélange if (strstr(entreePrinc->tablcar,"type_melange=")!=NULL) { *(entreePrinc->entree) >> nom; if (nom != "type_melange=") { cout << "\n erreur en lecture de la loi des melanges en sigma, on attendait le mot cle type_melange=" << " alors que l'on a lue " << nom; entreePrinc->MessageBuffer("**erreur11 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; *(entreePrinc->entree) >> type_melange; if ((type_melange!= 1) && (type_melange != 2)) { cout << "\n erreur en lecture du type de melange , il doit etre egale a 1 ou 2 alors que l'on a lu " << type_melange; entreePrinc->MessageBuffer("**erreur12 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; } else { type_melange = 1.;}; // on regarde s'il faut lire l'indicateur "valeur_aux_noeuds" if (strstr(entreePrinc->tablcar,"valeur_aux_noeuds=")!=NULL) { *(entreePrinc->entree) >> nom; if (nom != "valeur_aux_noeuds=") { cout << "\n erreur en lecture de la loi des melanges en sigma," << " on attendait le mot cle valeur_aux_noeuds=" << " alors que l'on a lue " << nom; entreePrinc->MessageBuffer("**erreur13 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; *(entreePrinc->entree) >> valeur_aux_noeuds; } else { valeur_aux_noeuds = 1;}; // **** pour l'instant on ne considère que des grandeurs ddl aux noeuds, mais cela peut-être étendu sans pb if (valeur_aux_noeuds && (!type_grandeur.Nom_vide())) { cout << "\n erreur en lecture de la loi des melanges en sigma, dans le cas d'une proportion en fonction" << " de grandeur aux noeuds pour l'instant seul les ddl de base sont autorises " ; entreePrinc->MessageBuffer("**erreur14 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // --- on regarde le cas d'une somme étendue aA=1.; //par défaut if (strstr(entreePrinc->tablcar,"somme_pondere_etendue_")!=NULL) {string nom; *(entreePrinc->entree) >> nom; // lecture d'un identificateur if(nom != "somme_pondere_etendue_") { cout << "\n erreur en lecture du mot cle somme_pondere_etendue_ " << " on attendait la chaine : somme_pondere_etendue_ et on a lue " << nom; entreePrinc->MessageBuffer("**erreur15 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; entreePrinc->NouvelleDonnee(); // on passe une ligne *(entreePrinc->entree) >> nom; // lecture de aA if(nom != "A=") { cout << "\n erreur en lecture du mot cle A= " << " on attendait la chaine : A= et on a lue " << nom; entreePrinc->MessageBuffer("**erreur16 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; *(entreePrinc->entree) >> aA; }; // --- on regarde s'il y a une fonction d'interface if (strstr(entreePrinc->tablcar,"avec_fonction_proportion_")!=NULL) {string nom; *(entreePrinc->entree) >> nom; // lecture d'un identificateur if(nom != "avec_fonction_proportion_") { cout << "\n erreur en lecture du mot cle avec_fonction_proportion_ " << " on attendait la chaine : avec_fonction_proportion_ et on a lue " << nom; entreePrinc->MessageBuffer("**erreur17 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; entreePrinc->NouvelleDonnee(); // on passe une ligne *(entreePrinc->entree) >> nom; // lecture du mot cle if(nom != "fonction_prop=") { cout << "\n erreur en lecture du mot cle fonction_prop= " << " on attendait la chaine : fonction_prop= et on a lue " << nom; entreePrinc->MessageBuffer("**erreur18 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; *(entreePrinc->entree) >> nom; // 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(nom)) { c_proport = lesCourbes1D.Trouve(nom); } else { // sinon il faut la lire maintenant string non_courbe("_"); c_proport = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str())); // lecture de la courbe c_proport->LectDonnParticulieres_courbes (non_courbe,entreePrinc); }; }; } else if (nom == "les_grandeurs_de_controle_=") { Ponderation ponder; // un élément courant // on initialise string mot_cle, st1,st2; string nom_class_methode="LoiDesMelangesEnSigma::LectureDonneesParticulieres (."; List_io < Ddl_enum_etendu > listddlenum; List_io listbool; // on lit les grandeurs pour l'instant en string List_io list_id_grand; //liste de travail de toutes les grandeurs List_io list_id_grand_glob; //liste des grandeurs globales List_io list_id_ddl_etendu; //liste des ddl étendus int nb_grandeurs_globales = 0; // init while (st1 != "fin_grandeurs_") {*(entreePrinc->entree) >> st1 ; if (st1 == "fin_grandeurs_") break; // pas terrible mais c'est ce qui me vient à l'idée ! // on vérifie que le mot clé lu est exploitable string minus = Minuscules(st1); // la forme minuscules if ((st1=="TEMPS") || (Ddl_enum_etendu::VerifExistence(st1)) || EstUneGrandeurGlobale(minus) ) {list_id_grand.push_back(st1); if (EstUneGrandeurGlobale(minus)) // si c'est une grandeur globale on cumule le compteur nb_grandeurs_globales++; } else { cout << "\n erreur en lecture, le type de grandeur lu" << st1 << " n'est pas acceptable " << "\n LoiDesMelangesEnSigma::LectureDonneesParticulieres (..."; entreePrinc->MessageBuffer("**erreur05**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on rempli les listes spécifiques if (Ddl_enum_etendu::VerifExistence(st1)) list_id_ddl_etendu.push_back(st1); if (EstUneGrandeurGlobale(minus)) list_id_grand_glob.push_back(st1); }; // --- maintenant on va lire les fonctions entreePrinc->NouvelleDonnee(); // prepa du flot de lecture mot_cle="deb_fonct_="; // le début des fonctions entreePrinc->Lecture_et_verif_mot_cle(nom_class_methode,mot_cle); List_io ::iterator ili,ilifin = list_id_grand.end(); List_io li_courbe_globale; // inter List_io val_aux_noeuds; // inter int nb_GGlob=0;int nb_enum_etendu = 0; // compteur pour le dimensionnement // premier passage on crée les fonctions for (ili=list_id_grand.begin();ili != ilifin;ili++) {string minus = Minuscules(*ili); // la forme minuscules if ((*ili)=="TEMPS") // cas de la fonction du temps { // lecture de la loi d'évolution val_aux_noeuds.push_back(false); // sert à rien, mais permet // de garder le même ordre de rangement que list_id_grand if (niveauF_temps == NULL) niveauF_temps = new Ponderation_temps; // lecture de la pondération niveauF_temps->LectureDonneesPonderation(entreePrinc, lesCourbes1D); } else if (EstUneGrandeurGlobale(minus)) { val_aux_noeuds.push_back(false); // sert à rien, mais permet nb_GGlob++; // de garder le même ordre de rangement que list_id_grand // pour le premier élément de la liste on lit la fonction // pour les autres, on ne fait rien (la fct est déjà lue) if (nb_GGlob == 1) {// création de la pondération si nécessaire string nom_fonction; // lecture du nom de la fonction nD *(entreePrinc->entree) >> nom_fonction; // on regarde si la fonction existe, si oui on récupère la référence if (lesFonctionsnD.Existe(nom_fonction)) { niveauF_grandeurND = lesFonctionsnD.Trouve(nom_fonction); } else { // sinon il faut la lire maintenant string non_fonction("_"); niveauF_grandeurND = Fonction_nD::New_Fonction_nD(non_fonction,Id_Nom_Fonction_nD (non_fonction.c_str())); // lecture de la fonction niveauF_grandeurND->LectDonnParticulieres_Fonction_nD (non_fonction,entreePrinc); }; }; } else if (Ddl_enum_etendu::VerifExistence(*ili)) { nb_enum_etendu++; // pour le premier élément de la liste on lit la pondération // pour les autres, on ne fait rien (la pondération est déjà lue) if (nb_enum_etendu == 1) { if (niveauF_ddlEtendu==NULL) // on le crée niveauF_ddlEtendu = new Ponderation; // lecture niveauF_ddlEtendu->LectureDonneesPonderation (list_id_ddl_etendu,entreePrinc,lesCourbes1D); }; }; }; // on passe le mot clé de fin mot_cle="fin_fonct_"; // la fin des fonctions entreePrinc->Lecture_et_verif_mot_cle(nom_class_methode,mot_cle); // *** à changer en fonction de l'utilisation // deuxième passage on met à jour les conteneurs // niveauF_grandeurND->type_grandeur_GGlob.Change_taille(nb_GGlob); // niveauF_grandeurND->c_proport.Change_taille(nb_GGlob); entreePrinc->NouvelleDonnee(); // prepa du flot de lecture passer_une_ligne = false; // on regarde s'il faut lire le type de mélange if (strstr(entreePrinc->tablcar,"type_melange=")!=NULL) { *(entreePrinc->entree) >> nom; if (nom != "type_melange=") { cout << "\n erreur en lecture de la loi des melanges en sigma, on attendait le mot cle type_melange=" << " alors que l'on a lue " << nom; entreePrinc->MessageBuffer("**erreur11 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; *(entreePrinc->entree) >> type_melange; if ((type_melange!= 1) && (type_melange != 2)) { cout << "\n erreur en lecture du type de melange , il doit etre egale a 1 ou 2 alors que l'on a lu " << type_melange; entreePrinc->MessageBuffer("**erreur12 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; entreePrinc->NouvelleDonnee(); // prepa du flot de lecture // on ajoute 2 au type de mélange car ce sera l'indicateur qui permettra de savoir si on est // dans la mise en donnée historique ou la nouvelle mise en donnée type_melange += 2; } else { type_melange = 3;}; }; // maintenant lecture des 2 lois if (passer_une_ligne) entreePrinc->NouvelleDonnee(); calcule_si_prop_non_nulle.Change_taille(0); // init au cas où int dim_lois=0; int nb_loi = 0;Enum_categorie_loi_comp categ=RIEN_CATEGORIE_LOI_COMP; while (strstr(entreePrinc->tablcar,"fin_liste_lois_elementaires")==NULL) { // lecture du nom de la loi string st2,nom3; *(entreePrinc->entree) >> st2; // on regarde si on est dans le cas d'une proportion exclusive (cf. info_commande_LoisDeComp) if ( (strstr(entreePrinc->tablcar,"calcule_si_prop_non_nulle_")!=NULL) || (strstr(entreePrinc->tablcar,"demarre_a_prop_non_nulle_puis_strictement_decroissante_")!=NULL) || (strstr(entreePrinc->tablcar,"demarre_a_prop_non_nulle_puis_strictement_decroissante_sur_chaque_incre_")!=NULL)) { *(entreePrinc->entree) >> nom3; if (calcule_si_prop_non_nulle.Taille() == 0) calcule_si_prop_non_nulle.Change_taille(2,0); if(nom3 == "calcule_si_prop_non_nulle_") {calcule_si_prop_non_nulle(nb_loi+1)=1;} else if(nom3 == "demarre_a_prop_non_nulle_puis_strictement_decroissante_") // sinon cas demarre_a_prop_non_nulle_puis_strictement_decroissante_ {calcule_si_prop_non_nulle(nb_loi+1)=2;} else if(nom3 == "demarre_a_prop_non_nulle_puis_strictement_decroissante_sur_chaque_incre_") // sinon cas idem prec mais // sur chaque incrément {calcule_si_prop_non_nulle(nb_loi+1)=3;} else { cout << "\n erreur en lecture des lois constitutives elementaire d'une loi LoiDesMelangesEnSigma" << "\n le mot cle lue: " << nom3 << " devrait etre soit calcule_si_prop_non_nulle_ ou soit demarre_a_prop_non_nulle_puis_strictement_decroissante_ "; entreePrinc->MessageBuffer("**erreur LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; // definition de la loi LoiAbstraiteGeneral * pt = LesLoisDeComp::Def_loi(st2); if (nb_loi==0) // la première fois que l'on passe ici le nombre de loi = 0 {lois_internes1 = (Loi_comp_abstraite*) LesLoisDeComp::Def_loi(st2); pt = lois_internes1;} else {lois_internes2 = (Loi_comp_abstraite*) LesLoisDeComp::Def_loi(st2); pt = lois_internes2;} // --- 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 dim = dim_lois;categorie_loi_comp = categ; if (!GroupeMecanique(categorie_loi_comp)) { cout << "\n erreur1 en lecture des lois constitutives elementaire d'une loi LoiDesMelangesEnSigma" << "\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 LoiDesMelangesEnSigma::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 LoiDesMelangesEnSigma" << "\n la loi lue: " << pt->Nom_comport() << " n'a pas la meme dimension que la premier loi lue"; entreePrinc->MessageBuffer("**erreur2 lecture LoiDesMelangesEnSigma"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } if (!GroupeMecanique(pt->Id_categorie())) { cout << "\n erreur en lecture des lois constitutives elementaire d'une loi LoiDesMelangesEnSigma" << "\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 LoiDesMelangesEnSigma::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; nb_loi++; if (nb_loi > 2 ) { cout << "\n erreur en lecture de la loi des melanges en sigma," << " vous avez defini plus de deux lois internes !"; entreePrinc->MessageBuffer("**erreur3 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; // vérification que l'on a bien lu deux lois if (nb_loi != 2 ) { cout << "\n erreur en lecture de la loi des melanges en sigma," << " vous n'avez pas defini deux lois internes !"; entreePrinc->MessageBuffer("**erreur4 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // 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); }; // affichage de la loi void LoiDesMelangesEnSigma::Affiche() const { cout << "\n ....... loi de comportement LoiDesMelangesEnSigma ........"; cout << "\n type de melange: "<NomCourbe() <<" ";}; cout << " \n "; } else // deuxième mise en donnée { cout << "niveauF_grandeurND" << " "; if (niveauF_grandeurND->NomFonction() != "_") { cout << niveauF_grandeurND->NomFonction();} else { niveauF_grandeurND->Affiche();}; if (niveauF_ddlEtendu!= NULL) niveauF_ddlEtendu->Affiche(); if (niveauF_temps!= NULL) niveauF_temps->Affiche(); }; if (calcule_si_prop_non_nulle.Taille() == 2) { cout << " calcule_si_prop_non_nulle1= " << calcule_si_prop_non_nulle(1) << " calcule_si_prop_non_nulle2= " << calcule_si_prop_non_nulle(2) << " \n"; }; cout << "\n -- partie relative aux lois internes: "; lois_internes1->Affiche(); lois_internes2->Affiche(); cout << "\n ....... fin de la loi de comportement LoiDesMelangesEnSigma ........"; }; // affichage et definition interactive des commandes particulières à chaques lois void LoiDesMelangesEnSigma::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 LoiDesMelangesEnSigma ........" << "\n# deux types de mises en donnees sont proposees " << "\n# "; if (rep == "o") {//--------- cas de la première mise en donnée (historique) ------- { sort << "\n# " << "\n# $$$ === premier type possible de mise en donnees ===$$$ " << "\n# " << "\n# sur la premiere ligne on indique successivement : " << "\n# a) obligatoirement: le type de grandeur (mot cle: grandeur_proportion= ) qui regle la proportion entre " << "\n# les deux lois, on peut utiliser n'importe quelle grandeur definie (mais qui doit exister par ailleurs) " << "\n# aux noeuds par exemple, cf. documentation " << "\n# b) optionnellement: le type de melange (mot cle: type_melange= ) (1 ou 2) cf. expli qui suit " << "\n# c) optionnellement: si la proportion provient des noeuds ou du pt d'integ directement " << "\n# (mot cle: valeur_aux_noeuds= ) (1 ou 0) la valeur par defaut est 1 (en fait tout nb diff de 0), " << "\n# dans le cas de 0, pour l'instant les cas implantes sont relatif a PROP_CRISTA, def_duale_mises, " << "\n# Spherique_eps, def_duale_mises_maxi, Spherique_sig" << "\n# --> ex: grandeur_proportion= PROP_CRISTA type_melange= 2 valeur_aux_noeuds= 0 " << "\n# d) optionnellement: l'extension a une somme ponderee etendue mot cle: somme_pondere_etendue_ " << "\n# si oui, on passe une ligne et sur la ligne suivante on a le mot cle A= " << "\n# suivit du coeff multiplicatif de la somme ponderee (cf explication qui suit) " << "\n# " << "\n# e) optionnellement: une fonction permettant le calcul de la proportion en fonction de la grandeur" << "\n# qui regle la proportion mot cle: avec_fonction_proportion_ " << "\n# dans ce cas, on passe une ligne et la fonction est decrite avec le mot cle: fonction_prop= " << "\n# suivit du nom de la fonction (si elle existe deja) ou de la definition de la fonction " << "\n# " << "\n# f) puis on passe une ligne pour decrire les 2 lois individuelles" << "\n# " << "\n# ---- explications complementaires ------ " << "\n# en fait il y a deux type de loi des melanges possible: " << "\n# soit : sigma = grandeur * sigma(loi1) + (1.-grandeur) * sigma(loi2) , ce qui est le type 1 (par defaut) " << "\n# soit : delta sigma = grandeur * delta sigma(loi1) + (1.-grandeur) * delta sigma(loi2) , ce qui est le type 2" << "\n# en tenant compte que les contraintes sont cumulees dans le type 2. " << "\n# le type 1 est par defaut, mais on peut indiquer le type 2 apres le mot cle type_melange= " << "\n# puis il faut donner le nom de chaque loi (2 maxi) suivi des parametres sur les lignes suivantes" << "\n# " << "\n# Dans le cas d'une somme ponderee etendue, la contrainte est calculee suivant la formule suivante: " << "\n# sigma = A*(grandeur * sigma(loi1) + (1-grandeur) * sigma(loi2)) " << "\n# ou : delta sigma = A*(grandeur * delta sigma(loi1) + (1-grandeur) * delta sigma(loi2)) " << "\n# ainsi A peut etre different de 1, par exemple si A=2, on peut tendre vers la somme non ponderee des deux lois " << "\n# " << "\n# ------------ cas d'une proportion exclusive --------------- " << "\n# g) optionnellement: apres chaque loi, on peut indiquer le mot cle: calcule_si_prop_non_nulle_ " << "\n# cela indique que la loi n'est calculee que si son coefficient est non nul, " << "\n# bien noter que dans ce cas il n'y a pas accumulation de l'historique du comportement " << "\n# donc c'est une option qui est raisonnable que pour une loi non incrementale" << "\n# dans le cas contraire, il faut avoir conscience de ce que l'on impose" << "\n# " << "\n# ----- exemple de deux lois elastiques -----" << "\n# " << "\n grandeur_proportion= PROP_CRISTA type_melange= 2 valeur_aux_noeuds= 1 "; // 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 LoiDesMelangesEnSigma" << endl; sort << "\n# " << "\n# ------ exemple d'une somme etendue avec fonction d'interface (partie avant les lois) ------" << "\n# " << "\n# grandeur_proportion= def_equivalente type_melange= 1 valeur_aux_noeuds= 0 somme_pondere_etendue_ " << "\n# A= 2. avec_fonction_proportion_ " << "\n# fonction_prop= courbe1 " << "\n# ..... " << "\n# "; }; //--------- cas de la deuxième mise en donnée ------- { sort << "\n# " << "\n# $$$ === second type possible de mise en donnees ===$$$ " << "\n# " << "\n# ce second type permet d'utiliser un plus large choix de fonctions de ponderation, par contre" << "\n# son utilisation est peut-etre un peu plus complexe (?) " << "\n# Plus precisemment, la ponderation peut-etre un assemblage multiplicatif de: " << "\n# - une fonction nD de grandeurs globales (ex: precision d'equilibre globale, num d'iteration, etc.)" << "\n# - avec le produit d'un ensemble de courbes 1D , chacune fonction d'un ddl etendu. Ici c'est le cas " << "\n# identique au premier type de mise en donnees" << "\n# - avec le produit d'une courbe 1D fonction du temps" << "\n# " << "\n# sur la premiere ligne on indique successivement : " << "\n# a) le mot cle: les_grandeurs_de_controle_= " << "\n# b) ensuite on donne la liste des grandeurs que l'on va utiliser, ces grandeurs peuvent etre" << "\n# - le temps (mot cle: TEMPS ) " << "\n# - un ddl primaire (ex: U1 ou X1 au noeud) ou secondaire (SIG11 ou EPS11 au pti)" << "\n# - un ddl etendue " << "\n# - une grandeur globale" << "\n# l'ensemble des grandeurs doit se terminer par le mot cle : fin_grandeurs_" << "\n# c) ensuite sur la ligne suivante: on donne la liste des fonctions que l'on va utiliser " << "\n# - mot cle deb_fonct_= " << "\n# la liste doit suivre le meme ordre que celui des grandeurs, cependant " << "\n# 1) dans le cas des grandeurs globales (sauf le temps), il y a une seule fonction pour toutes les grandeurs" << "\n# c'est donc la place de la premiere grandeur globale qui est consideree " << "\n# IMPORTANT: les grandeurs globales qui vont etre utilisees sont celles indiquees dans la definition" << "\n# de la fonction nD, aussi dans la def de la proportion, il suffit d'indiquer une seule grandeur " << "\n# globale pour ensuite definir une fonction nD. Par contre dans la definition de la fonction nD " << "\n# on peut introduire d'autres grandeurs, en particulier des grandeurs non locales. " << "\n# La fonction nD permet donc d'introduire tout type de grandeur, elle fait donc" << "\n# double emploi avec les autres courbes. Cependant on laisse les autres courbes " << "\n# pour des raisons historiques et pour des cas simples, on l'utilisation d'une courbe " << "\n# peut-etre plus explicite qu'une fonction nD. " << "\n# 2) pour les ddl et ddl etendue il faut indiquer apres chaque fonction d'un ddl s'il s'agit " << "\n# a) d'une grandeur au pti avec le mot cle AuPti_ " << "\n# b) d'une grandeur au noeud avec le mot cle AuxNoeuds_ " << "\n# l'ensemble de la liste des fonctions doit se terminer par le mot cle: fin_fonct_ " << "\n# e) puis sur la ligne suivante, optionnellement: " << "\n# le type de melange (mot cle: type_melange= ) (1 ou 2) " << "\n# l'explication est identique au cas de la premiere mise en donnees " << "\n# " << "\n# f) puis on passe une ligne pour decrire les 2 lois individuelles" << "\n# On peut comme dans le cas de la premiere mise en donnee, utiliser" << "\n# une proportion exclusive, la syntaxe est identique au cas de la premiere " << "\n# mise en donnee " << "\n# " << "\n# ----- exemple de deux lois elastiques -----" << "\n# " << "\n# les_grandeurs_de_controle_= TEMPS \\ " << "\n# compteur_increment_charge_algo_global\\ " << "\n# compteur_iteration_algo_global\\ " << "\n# def_equivalente X1 \\ " << "\n# fin_grandeurs_ " << "\n# deb_fonct_= f_temps fonction1 \\ " << "\n# f_const AuPti_ \\ " << "\n# f_const AuxNoeuds_ \\ " << "\n# fin_fonct_ "; // 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 LoiDesMelangesEnSigma" << endl; sort << "\n# "; sort << "\n#a la suite du mot cle qui definit une loi interne on peut choisir entre 4 " << "types de fonctionnement. Pour simplifier et expliciter la presentation," << " on suppose que la premiere loi est une simple loi de Hooke. Les 4 types" << " de fonctionnement sont alors les suivants:" << "\n# ISOELAS -> aucune particularite ," << "\n# ISOELAS calcule_si_prop_non_nulle_ -> le mot cle est utilise" << " pour indiquer que la loi ne doit-être calculee que si la proportion" << " la concernant (c-a-c alpha pour la première loi, et (1.-alpha) pour " << " la seconde loi) est non nulle. Si elle est nulle, la loi n'est pas calculee." << "\n# ISOELAS demarre_a_prop_non_nulle_puis_strictement_decroissante_} " << " -> le fonctionnement est semblable au cas precedent avec en plus la " << " particularite supplementaire suivante: on interdit a la proportion d'augmenter." << " Ainsi, si entre deux appels consecutifs de la loi de comportement, la valeur d'alpha" << " tente d'augmente au travers d'un calcul via une fonction de ponderation," << " c'est la valeur la plus faible qui est retenue, et ceci tout au long du calcul. " << " Ce comportement tres particulier, est construit en particulier pour être utilise" << " via une fonction de ponderation qui depend de la precision de l'equilibre globale." << " On force ainsi l'evolution d'alpha a etre strictement decroissante a mesure " << " que la precision augmente." << "\n# ISOELAS demarre_a_prop_non_nulle_puis_strictement_decroissante_sur_chaque_incre_" << " -> le fonctionnement est un peu semblable au cas precedent mais avec la particularite" << " supplementaire suivante: l'evolution est strictement decroissante sur un increment." << " Par contre au debut de chaque increment, on initialise la valeur d'alpha" << " via les fonctions de proportion." << endl; }; } else // cas simplifié, on ne donne que les exemples {//--------- cas de la première mise en donnée (historique) ------- { sort << "\n# " << "\n# $$$ === premier type possible de mise en donnees ===$$$ " << "\n# " << "\n# ----- exemple de deux lois elastiques -----" << "\n# " << "\n grandeur_proportion= PROP_CRISTA type_melange= 2 valeur_aux_noeuds= 1 "; // 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 LoiDesMelangesEnSigma" << endl; }; //--------- cas de la deuxième mise en donnée ------- { sort << "\n# " << "\n# $$$ === second type possible de mise en donnees ===$$$ " << "\n# " << "\n# ----- exemple de deux lois elastiques -----" << "\n# " << "\n# les_grandeurs_de_controle_= TEMPS \\ " << "\n# compteur_increment_charge_algo_global\\ " << "\n# compteur_iteration_algo_global\\ " << "\n# def_equivalente X1 \\ " << "\n# fin_grandeurs_ " << "\n# deb_fonct_= f_temps fonction1 \\ " << "\n# f_const AuPti_ \\ " << "\n# f_const AuxNoeuds_ \\ " << "\n# fin_fonct_ "; // 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 LoiDesMelangesEnSigma" << endl; }; } }; // test si la loi est complete int LoiDesMelangesEnSigma::TestComplet() { int ret = LoiAbstraiteGeneral::TestComplet(); ret *=lois_internes1->TestComplet(); ret *=lois_internes2->TestComplet(); // puis les proportions if (type_melange < 3) // mise en donnée historique { // courbe d'interface if ( c_proport != NULL) c_proport->Complet_courbe(); } else // deuxième mise en donnée { //if (niveauF_grandeurND != NULL) // niveauF_grandeurND->Verif_complet(); if (niveauF_ddlEtendu!= NULL) niveauF_ddlEtendu->Verif_complet(); if (niveauF_temps!= NULL) niveauF_temps->Verif_complet(); }; return ret; }; // calcul d'un module d'young équivalent à la loi, ceci pour un // chargement nul double LoiDesMelangesEnSigma::Module_young_equivalent(Enum_dure temps,const Deformation & def ,SaveResul * saveResul_ex) { double E=0.; // on récupère les infos de chaque loi SaveResul_LoiDesMelangesEnSigma & save_resul = *((SaveResul_LoiDesMelangesEnSigma*) saveResul_ex); list ::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois // on utilise les proportions sauvegardées qui peuvent éventuellement ne pas avoir été déjà calculées // dans ce cas la proportion = 1 E +=save_resul.proportion * lois_internes1->Module_young_equivalent(temps,def,*isave); isave++; E +=(1.-save_resul.proportion) * lois_internes2->Module_young_equivalent(temps,def,*isave); 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 LoiDesMelangesEnSigma::Module_compressibilite_equivalent(Enum_dure temps,const Deformation & def ,SaveResul * saveResul_ex) { double module_compressibilite=0.; // on récupère les infos de chaque loi SaveResul_LoiDesMelangesEnSigma & save_resul = *((SaveResul_LoiDesMelangesEnSigma*) saveResul_ex); list ::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois // on utilise les proportions sauvegardées qui peuvent éventuellement ne pas avoir été déjà calculées // dans ce cas la proportion = 1 module_compressibilite +=save_resul.proportion * lois_internes1->Module_compressibilite_equivalent(temps,def,*isave); isave++; module_compressibilite +=(1.-save_resul.proportion) * lois_internes2->Module_compressibilite_equivalent(temps,def,*isave); 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 LoiDesMelangesEnSigma::Activation_donnees(Tableau& tabnoeud,bool dilatation,LesPtIntegMecaInterne& lesPtMecaInt) { if (type_melange < 3) // cas de la loi historique { // dans le cas d'une proportion venant des noeuds par interpolation // on active les ddl correspondant à la grandeur qui règle la proportion if (valeur_aux_noeuds) { 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(type_grandeur.Enum())) {tabnoeud(i)->Met_en_service(type_grandeur.Enum());} else // { cout << "\n erreur: la grandeur " << Nom_ddl(type_grandeur) << " n'existe pas " { cout << "\n erreur: la grandeur " << type_grandeur << " n'existe pas " << " il n'est pas possible d'utiliser une loi des melanges avec cette grandeur " << " il manque sans doute des donnees !!! " << "\n LoiDesMelangesEnSigma::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 des melanges ne peut pas s'utiliser ici telle quelle ***" << " demander une modification ! "; cout << "\n LoiDesMelangesEnSigma::Activation_donnees(.. " << endl; Sortie(1); }; // cas normal switch (type_grandeur.Position()-NbEnum_ddl()) {case 77: case 78: case 87: case 88: // cas de "def_duale_mises", cas de "Spherique_eps", cas de "def_duale_mises_maxi" {// il faut que l'on active le calcul des invariants de déformations int nbpti = lesPtMecaInt.NbPti(); for (int i= 1;i<= nbpti;i++) lesPtMecaInt(i).Change_statut_Invariants_deformation (true); break; } case 81: // cas de "Spherique_sig" {// il faut que l'on active le calcul des invariants des contraintes int nbpti = lesPtMecaInt.NbPti(); for (int i= 1;i<= nbpti;i++) lesPtMecaInt(i).Change_statut_Invariants_contrainte (true); break; } default: cout << "\n erreur, le type de proportion " << type_grandeur << " n'est pas disponible " << " pour l'instant au point d'integration ! " << "\n LoiDesMelangesEnSigma::Activation_donnees(.... "; Sortie(1); break; }; }; } else // cas type_melange = 3 ou 4: -> fonctions complexes {if (niveauF_ddlEtendu != NULL) niveauF_ddlEtendu->Activation_donnees(tabnoeud, dilatation, lesPtMecaInt); }; // appel des lois élémentaires lois_internes1->Activation_donnees(tabnoeud,dilatation,lesPtMecaInt); lois_internes2->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 LoiDesMelangesEnSigma::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_LoiDesMelangesEnSigma & save_resul = *((SaveResul_LoiDesMelangesEnSigma*) saveDon); 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(); SaveResul_LoiDesMelangesEnSigma & save_resul = *((SaveResul_LoiDesMelangesEnSigma*) saveDon); // 1) -----cas des contraintes individuelles à chaque loi à t et courantes if ((enuTQ) == CONTRAINTE_INDIVIDUELLE_A_CHAQUE_LOI_A_T_SANS_PROPORTION) { Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier // on boucle sur les lois list ::iterator isig_t; // première loi isig_t = save_resul.l_sigoHH_t.begin(); // 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 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)++; // seconde loi isig_t++; 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)++; }; // 2) -----cas des contraintes individuelles à chaque loi à t uniquement 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 ::iterator jsig_t; // première loi jsig_t = save_resul.J_sigoHH_t.begin(); // 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 TenseurHH* sigHH = (*(jsig_t)); // pour simplifier if (Dabs(sigHH->Dimension()) != dim) {tyTQ(1+(*idecal)).Affectation_trans_dimension((*sigHH) * aA*save_resul.proportion_t,true); } else // cas même dimension {tyTQ(1+(*idecal)) = (*(*(jsig_t))) * aA*save_resul.proportion_t; }; (*idecal)++; //debug //cout << "\n (*(*(jsig_t))) * save_resul.proportion_t= "; //((*(*(jsig_t))) * save_resul.proportion_t).Ecriture(cout); //cout << "\n debug LoiDesMelangesEnSigma::Grandeur_particuliere" << endl; //findebug // seconde loi jsig_t++; sigHH = (*(jsig_t)); // pour simplifier if (Dabs(sigHH->Dimension()) != dim) {tyTQ(1+(*idecal)).Affectation_trans_dimension((*sigHH) * aA*(1.-save_resul.proportion_t),true); } else // cas même dimension {tyTQ(1+(*idecal)) = (*(*(jsig_t))) * aA*(1.-save_resul.proportion_t); }; (*idecal)++; //debug //cout << "\n (*(*(jsig_t))) * save_resul.proportion_t= "; //((*(*(jsig_t))) * save_resul.proportion_t).Ecriture(cout); //cout << "\n debug LoiDesMelangesEnSigma::Grandeur_particuliere" << endl; //findebug }; // 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 ::iterator ienerg_t; ienerg_t = save_resul.l_energ_t.begin(); tyTQ(1+(*idecal)) = (*ienerg_t).EnergieElastique(); (*idecal)++; 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 ::iterator ienerg_t; ienerg_t = save_resul.l_energ_t.begin(); tyTQ(1+(*idecal)) = (*ienerg_t).DissipationPlastique(); (*idecal)++; 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 ::iterator ienerg_t; ienerg_t = save_resul.l_energ_t.begin(); tyTQ(1+(*idecal)) = (*ienerg_t).DissipationVisqueuse(); (*idecal)++; ienerg_t++; tyTQ(1+(*idecal)) = (*ienerg_t).DissipationVisqueuse(); (*idecal)++; }; // 6) -----cas de la proportion relative entre les deux lois if (enuTQ == PROPORTION_LOI_MELANGE) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier tyTQ(1+(*idecal)) = save_resul.proportion_t; (*idecal)++; // *(tyTQ.ConteneurDouble()) = save_resul.proportion_t; }; }; }; // puis appel des lois élémentaires list ::iterator ill = save_resul.liste_des_SaveResul.begin(); lois_internes1->Grandeur_particuliere(absolue,liTQ,*ill,decal); ill++; lois_internes2->Grandeur_particuliere(absolue,liTQ,*ill,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 LoiDesMelangesEnSigma::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 int nb_loi = 2; // pour être identique pour la loi additive !! lois_internes1->ListeGrandeurs_particulieres(absolue,liTQ); lois_internes2->ListeGrandeurs_particulieres(absolue,liTQ); // ... maintenant on s'occupe des grandeurs de la loi additive elle même, // 1) -----cas des contraintes individuelles à chaque loi à t et courantes // 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_SANS_PROPORTION) { 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_SANS_PROPORTION,SIG11,gtHH); liTQ.push_back(typQ); delete tens; // car on n'en a plus besoin }; }; // 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 la proportion relative entre les deux lois //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée {//on commence par définir une grandeur_scalaire_double Tableau tab_1(1); Tab_Grandeur_scalaire_double gtab(tab_1); List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == PROPORTION_LOI_MELANGE) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) { TypeQuelconque typQ1(PROPORTION_LOI_MELANGE,SIG11,gtab); 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 LoiDesMelangesEnSigma::Comportement_3D_CP_DP_1D() { // si la première lois internes n'est pas nulle, on ramène le cas de la première loi if (lois_internes1 != NULL) {return lois_internes1->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 LoiDesMelangesEnSigma::Lecture_base_info_loi(ifstream& ent,const int cas,LesReferences& lesRef,LesCourbes1D& lesCourbes1D ,LesFonctions_nD& lesFonctionsnD) { if (cas == 1) { string st1; string nom; ent >> st1 >> nom >> type_melange ; if (st1 != "LOI_DES_MELANGES_EN_SIGMA") { cout << "\n erreur en lecture de la loi : LOI_DES_MELANGES_EN_SIGMA," << " on attendait le mot cle : LOI_DES_MELANGES_EN_SIGMA " << "\n LoiDesMelangesEnSigma::Lecture_base_info_loi(..."; Sortie(1); }; if (type_melange < 3) // cas de la mise en données historique {ent >> nom >> type_grandeur >> nom >> valeur_aux_noeuds >> nom; // extension éventuelle ent >> st1 >> aA; // courbe d'interface éventuelle bool test = false; ent >> test; if (!test) { if (c_proport != NULL) {if (c_proport->NomCourbe() == "_") delete c_proport; c_proport = NULL;}; } else { ent >> nom; c_proport = lesCourbes1D.Lecture_pour_base_info(ent,cas,c_proport); }; } else // cas de la deuxième mise en données { // les grandeurs globales ent >> nom; if (nom == "avec_Ponderation_nD") { niveauF_grandeurND = lesFonctionsnD.Lecture_pour_base_info(ent,cas,niveauF_grandeurND);}; // les pondérations avec les ddl ent >> nom; if (nom == "avec_Ponderation_ddl") {if (niveauF_ddlEtendu==NULL) niveauF_ddlEtendu = new Ponderation; niveauF_ddlEtendu->Lecture_base_info(ent,cas, lesCourbes1D); } else { if (niveauF_ddlEtendu!=NULL) delete niveauF_ddlEtendu; }; // la pondération temps ent >> nom; if (nom == "avec_Ponderation_temps") {if (niveauF_temps==NULL) niveauF_temps = new Ponderation_temps; niveauF_temps->Lecture_base_info(ent,cas, lesCourbes1D); } else { if (niveauF_temps!=NULL) delete niveauF_temps; }; }; // ensuite normalement il n'y a pas de pb de lecture puisque c'est écrit automatiquement // on supprime les lois actuellement présentent par sécurité if (lois_internes1 != NULL) delete lois_internes1; if (lois_internes2 != NULL) delete lois_internes2; // lecture de la gestion conditionnel si prop non nulle ent >> nom; if (nom == "sans_test_proportion_non_nulle") { calcule_si_prop_non_nulle.Change_taille(0);} else { calcule_si_prop_non_nulle.Change_taille(2); ent >> nom >> calcule_si_prop_non_nulle(1) >> nom >> calcule_si_prop_non_nulle(2); }; // --partie_relative_aux_lois_internes: ent >> nom; // on lit les deux lois ent >> nom >> st1; lois_internes1 = (Loi_comp_abstraite *) LesLoisDeComp::Def_loi(st1); lois_internes1->Lecture_base_info_loi(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD); ent >> nom >> st1; lois_internes2 = (Loi_comp_abstraite *) LesLoisDeComp::Def_loi(st1); lois_internes2->Lecture_base_info_loi(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD); } else { // on boucle directement sur les lois déjà définis string nom; ent >> nom; // lois_1--> lois_internes1->Lecture_base_info_loi(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD); ent >> nom; // lois_2--> lois_internes2->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 LoiDesMelangesEnSigma::Ecriture_base_info_loi(ofstream& sort,const int cas) { if (cas == 1) { sort << "\n LOI_DES_MELANGES_EN_SIGMA " << "\n type_de_melange: "<Ecriture_base_info(sort,cas); } else {sort << " sans_Ponderation_ddl ";}; if (niveauF_temps!= NULL) {sort << " avec_Ponderation_temps "; niveauF_temps->Ecriture_base_info(sort,cas); } else {sort << " sans_Ponderation_temps ";}; }; // gestion conditionnel si prop non nulle if (calcule_si_prop_non_nulle.Taille() != 2) { sort << "\n sans_test_proportion_non_nulle \n ";} else { sort << "\n AVEC_test_proportion_non_nulle "; sort << "\n calcule_si_prop_non_nulle1= " << calcule_si_prop_non_nulle(1) << " calcule_si_prop_non_nulle2= " << calcule_si_prop_non_nulle(2) << " "; }; sort << "\n --partie_relative_aux_lois_internes: "; sort << "\n lois_1---> " << lois_internes1->Nom_comport() << " "; lois_internes1->Ecriture_base_info_loi(sort,cas); sort << "\n lois_2---> " << lois_internes2->Nom_comport() << " "; lois_internes2->Ecriture_base_info_loi(sort,cas); } else { sort << "\n lois_1--> "; lois_internes1->Ecriture_base_info_loi(sort,cas); sort << "\n lois_2--> "; lois_internes2->Ecriture_base_info_loi(sort,cas); }; }; // ========== codage des METHODES VIRTUELLES protegees:================ // calcul des contraintes a t+dt void LoiDesMelangesEnSigma::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(); // on utilise des pointeurs pour utiliser delete à la fin TenseurHH * sigtotalHH = (NevezTenseurHH(dim_tens,0.)); TenseurHH * zeroHH = (NevezTenseurHH(dim_tens,0.)); TenseurHH * deltaSigHH = (NevezTenseurHH(dim_tens,0.)); // pour la variation de contraintes SaveResul_LoiDesMelangesEnSigma & save_resul = *((SaveResul_LoiDesMelangesEnSigma*) saveResul); module_compressibilite=module_cisaillement=0.; // init energ.Inita(0.); // initialisation des énergies mises en jeux // on balaie l'ensemble des lois list ::iterator isig,isig_t,jsig,jsig_t; int ili; list ::iterator ienerg,ienerg_t; list ::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois Loi_comp_abstraite * pt=NULL; // on récupère la valeur de la proportion enregistrée, qui a donc été calculée dans les grandeurs de // travail proportion = save_resul.proportion; bool premier_passage = true; for (ili=1,isig_t = save_resul.l_sigoHH_t.begin(),isig = save_resul.l_sigoHH.begin() ,jsig_t = save_resul.J_sigoHH_t.begin(),jsig = save_resul.J_sigoHH.begin() ,ienerg = save_resul.l_energ.begin(),ienerg_t = save_resul.l_energ_t.begin(); ili<=2;ili++,isig_t++,isig++,jsig_t++,jsig++,isave++,ienerg++,ienerg_t++) { // 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.);}; if ((*jsig)->Dimension()!=sigHH_t.Dimension()) { delete (*jsig); (*jsig)=NevezTenseurHH(sigHH_t.Dimension(),0.);}; if ((*jsig_t)->Dimension()!=sigHH_t.Dimension()) { delete (*jsig_t); (*jsig_t)=NevezTenseurHH(sigHH_t.Dimension(),0.);}; // initialisation du tenseurs contrainte sigHH = (*zeroHH); // calcul de la contrainte résultante, if (ili==1) {pt=lois_internes1;} else {pt=lois_internes2;}; double compress_inter=0.; double cisaill_inter=0; // init // passage des informations spécifique à la loi liste_des_SaveResul pt->IndiqueSaveResult(*isave); pt->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca pt->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours // prise en compte éventuel d'un calcul conditionel au cas d'une proportion non nulle bool traitement = true; // par défaut if (calcule_si_prop_non_nulle.Taille() == 2) {if (calcule_si_prop_non_nulle(ili) == 1) {if (premier_passage && ( proportion == 0.)) {traitement = false;} else if ((!premier_passage) && ( proportion == 1.)) {traitement = false;}; } else if ((calcule_si_prop_non_nulle(ili) == 2)||(calcule_si_prop_non_nulle(ili) == 3)) { if ((premier_passage)&& (!save_resul.deja_actif_sur_iter1)) // première loi et pas encore actif { if ( proportion == 0. ) // on désactive et on signale pour la suite {traitement = false;save_resul.deja_actif_sur_iter1=true;}; }; if ((!premier_passage)&& (!save_resul.deja_actif_sur_iter2)) // seconde loi et pas encore actif { if ( proportion == 1. ) // on ne traite pas {traitement = false;} else // sinon le traitement commence {save_resul.deja_actif_sur_iter2=true;}; }; } }; //--- debug // cout << "\n debug LoiDesMelangesEnSigma::Calcul_SigmaHH traitement= " // << traitement ; // if (premier_passage) {cout << " P1 " << endl;} else {cout << " P2 " << endl;} // if (!premier_passage && traitement) // {cout << "\n debug LoiDesMelangesEnSigma::Calcul_SigmaHH traitement= enclanche " // << calcule_si_prop_non_nulle(1) << " " << calcule_si_prop_non_nulle(2) // << endl; // }; //--- fin debug if (traitement) { pt->Calcul_SigmaHH((*(*isig_t)),DepsBB,tab_ddl,gijBB_t,gijHH_t,giB,gi_H,epsBB_,delta_epsBB, gijBB_,gijHH_,d_gijBB_,jacobien_0,jacobien,sigHH ,(*ienerg),(*ienerg_t),compress_inter,cisaill_inter,ex); // on commence par sauvegarder la contrainte partielle avant application de la proportion (*(*isig))=sigHH; // on sauvegarde la contrainte partielle totale // def du facteur multiplicatif du à la proportion double facteur_multiplicatif = aA * proportion; ////--- debug // cout << "\n debug LoiDesMelangesEnSigma::Calcul_SigmaHH facteur_multiplicatif= " // << facteur_multiplicatif << endl; ////--- fin debug #ifdef MISE_AU_POINT if (Permet_affichage() > 3) cout << "\n LoiDesMelangesEnSigma::Calcul_SigmaHH "; #endif if (premier_passage) { premier_passage = false;} else {facteur_multiplicatif = aA*(1.-proportion);}; // traitement if ((type_melange == 1)||(type_melange == 3)) { sigHH *= facteur_multiplicatif; (*(*jsig))=sigHH; // on sauvegarde la contrainte partielle proportionalisée (*sigtotalHH) += sigHH; // on ajoute la contrainte au total #ifdef MISE_AU_POINT if (Permet_affichage() > 3) {if (premier_passage) {cout << "\n 1ere loi:";} else {cout << "\n 2ieme loi: ";}; cout << " facteur_multiplicatif= " << facteur_multiplicatif << ", sigHH_tdt avec ponderation "; sigHH.Ecriture(cout); }; #endif } else // cas == 2 { (*deltaSigHH) = sigHH - (*(*isig_t)); (*deltaSigHH) *= facteur_multiplicatif; (*(*jsig))=(*(*jsig_t)) + (*deltaSigHH); // on sauvegarde la contrainte partielle proportionalisée (*sigtotalHH) += (*(*jsig)); // cumule }; energ += (*ienerg) * facteur_multiplicatif; // update des énergies module_compressibilite += compress_inter * facteur_multiplicatif; module_cisaillement += cisaill_inter * facteur_multiplicatif; } else { if (premier_passage) { premier_passage = false;}; (*(*isig))=(*zeroHH); (*(*jsig))=(*zeroHH); (*ienerg).Inita(0.); }; // fin du traitement conditionnel }; // fin de la boucle sur les deux lois // recopie du résultat sigHH = (*sigtotalHH); delete sigtotalHH; delete zeroHH;delete deltaSigHH; LibereTenseur(); }; // calcul des contraintes a t+dt et de ses variations void LoiDesMelangesEnSigma::Calcul_DsigmaHH_tdt (TenseurHH& sigHH_t,TenseurBB& DepsBB,DdlElement & tab_ddl ,BaseB& giB_t,TenseurBB & gijBB_t,TenseurHH & gijHH_t, BaseB& giB_tdt,Tableau & d_giB_tdt,BaseH& giH_tdt,Tableau & d_giH_tdt, TenseurBB & epsBB_tdt,Tableau & d_epsBB, TenseurBB & delta_epsBB,TenseurBB & gijBB_tdt,TenseurHH & gijHH_tdt, Tableau & d_gijBB_tdt, Tableau & d_gijHH_tdt,double& jacobien_0,double& jacobien, Vecteur& d_jacobien_tdt,TenseurHH& sigHH_tdt,Tableau & d_sigHH ,EnergieMeca & energ,const EnergieMeca & ,double& module_compressibilite,double& module_cisaillement ,const Met_abstraite::Impli& ex) { // on commence par créer un tenseur contrainte qui totalisera toutes les contraintes // le tenseurs est initialisé à 0. // on utilise des pointeurs pour utiliser delete à la fin int dim_tens = sigHH_tdt.Dimension(); TenseurHH * sigtotalHH = (NevezTenseurHH(dim_tens,0.)); TenseurHH * zeroHH = (NevezTenseurHH(dim_tens,0.)); TenseurHH * deltaSigHH = (NevezTenseurHH(dim_tens,0.)); // pour la variation de contraintes SaveResul_LoiDesMelangesEnSigma & save_resul = *((SaveResul_LoiDesMelangesEnSigma*) saveResul); module_compressibilite=module_cisaillement=0.; // init //---debug //ofstream fichier("toto", ios::app); //save_resul.Ecriture_base_info(fichier,1); // calcul de la contrainte résultante //list ::iterator ili=save_resul.liste_des_SaveResul.begin(); //(*ili)->Ecriture_base_info(fichier,1); //ili++; //(*ili)->Ecriture_base_info(fichier,1); //save_resul.Ecriture_base_info(fichier,1); // calcul de la contrainte résultante ////fichier.close(); ////---fin debug energ.Inita(0.); // initialisation des énergies mises en jeux // on vérifie que le tableau de travail intermédiaire statique est correctement // dimensionné sinon on le modifie int taille = d_sigHH.Taille(); if (d_sigtotalHH.Taille() == 0) { d_sigtotalHH.Change_taille(taille,NULL);} // for (int i=1;i<=taille;i++) d_sigtotalHH)(i)=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 bool premier_passage = true; list ::iterator isig_t = save_resul.l_sigoHH_t.begin(); list ::iterator isig = save_resul.l_sigoHH.begin(); list ::iterator jsig_t = save_resul.J_sigoHH_t.begin(); list ::iterator jsig = save_resul.J_sigoHH.begin(); list ::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois list ::iterator ienerg = save_resul.l_energ.begin(); list ::iterator ienerg_t = save_resul.l_energ_t.begin(); Loi_comp_abstraite * pt=NULL; // on récupère la valeur de la proportion enregistrée, qui a donc été calculée dans les grandeurs de // travail proportion = save_resul.proportion; //try { for (int ili=1;ili<=2;ili++,isig_t++,isig++,jsig_t++,jsig++,isave++,ienerg++,ienerg_t++) { // 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.);}; if ((*jsig)->Dimension()!=sigHH_t.Dimension()) { delete (*jsig); (*jsig)=NevezTenseurHH(sigHH_t.Dimension(),0.);}; if ((*jsig_t)->Dimension()!=sigHH_t.Dimension()) { delete (*jsig_t); (*jsig_t)=NevezTenseurHH(sigHH_t.Dimension(),0.);}; // calcul de la contrainte résultante, if (ili==1) {pt=lois_internes1;} else {pt=lois_internes2;}; double compress_inter=0.; double cisaill_inter=0; // init // passage des informations spécifique à la loi liste_des_SaveResul pt->IndiqueSaveResult(*isave); pt->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca pt->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours ////---debug //cout << "\n isave melange = " << ( (*isave) == NULL ) << endl; ////ofstream fichier("toto"); //(*isave)->Ecriture_base_info(fichier,1); // calcul de la contrainte résultante //fichier.close(); //---fin debug // prise en compte éventuel d'un calcul conditionel au cas d'une proportion non nulle bool traitement = true; // par défaut if (calcule_si_prop_non_nulle.Taille() == 2) {if (calcule_si_prop_non_nulle(ili) == 1) {if (premier_passage && ( proportion == 0.)) {traitement = false;} else if ((!premier_passage) && ( proportion == 1.)) {traitement = false;}; } else if ((calcule_si_prop_non_nulle(ili) == 2)||(calcule_si_prop_non_nulle(ili) == 3)) { if ((premier_passage)&& (!save_resul.deja_actif_sur_iter1)) // première loi et pas encore actif { if ( proportion == 0. ) // on désactive et on signale pour la suite {traitement = false;save_resul.deja_actif_sur_iter1=true;}; }; if ((!premier_passage)&& (!save_resul.deja_actif_sur_iter2)) // seconde loi et pas encore actif { if ( proportion == 1. ) // on ne traite pas {traitement = false;} else // sinon le traitement commence {save_resul.deja_actif_sur_iter2=true;}; }; } }; //--- debug // if (proportion == 0.) // cout << "\n premier_passage= " << premier_passage << ", traitement= " << traitement << endl; //--- fin debug if (traitement) { pt->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); // on sauvegarde la contrainte partielle totale (*(*isig))=sigHH_tdt; #ifdef MISE_AU_POINT if (Permet_affichage() > 3) cout << "\n LoiDesMelangesEnSigma::Calcul_DsigmaHH_tdt "; #endif // def du facteur multiplicatif du à la proportion double facteur_multiplicatif = aA * proportion; if (premier_passage) { premier_passage = false;} else {facteur_multiplicatif = aA*(1.-proportion);}; // traitement if ((type_melange == 1)||(type_melange == 3)) { sigHH_tdt *= facteur_multiplicatif; (*(*jsig))=sigHH_tdt; // on sauvegarde la contrainte partielle proportionalisée (*sigtotalHH) += sigHH_tdt; // on ajoute la contrainte au total #ifdef MISE_AU_POINT if (Permet_affichage() > 3) {if (premier_passage) {cout << "\n 1ere loi:";} else {cout << "\n 2ieme loi: ";}; cout << " facteur_multiplicatif= " << facteur_multiplicatif << ", sigHH_tdt avec ponderation "; sigHH_tdt.Ecriture(cout); }; #endif } else // cas == 2 { (*deltaSigHH) = sigHH_tdt - (*(*isig_t)); (*deltaSigHH) *= facteur_multiplicatif; (*(*jsig))=(*(*jsig_t)) + (*deltaSigHH); // on sauvegarde la contrainte partielle proportionalisée (*sigtotalHH) += (*(*jsig)); // cumule }; energ += (*ienerg) * facteur_multiplicatif; // update des énergies module_compressibilite += compress_inter * facteur_multiplicatif; module_cisaillement += cisaill_inter * facteur_multiplicatif; // récup de l'opérateur tangent for (int j=1;j<=taille;j++) (*d_sigHH(j))*= facteur_multiplicatif; #ifdef MISE_AU_POINT if (Permet_affichage() > 4) for (int j = 1; j<= taille; j++) { cout << "\n d_sigHH("<Ecriture(cout); }; #endif for (int j=1;j<=taille;j++) { (*d_SigtotalHH(j)) += (*d_sigHH(j)); // cumul *d_sigHH(j) = (*zeroHH); // et on initialise pour le prochain coup } } else { if (premier_passage) { premier_passage = false;}; (*(*isig))=(*zeroHH); (*(*jsig))=(*zeroHH); (*ienerg).Inita(0.); }; // fin du traitement conditionnel }; // fin de la boucle sur les deux lois // } //catch ( ... ) // { this->Affiche(); // Sortie(1); // }; // recopie du résultat sigHH_tdt = (*sigtotalHH); for (int k=1;k<=taille;k++) (*d_sigHH(k)) = (*d_SigtotalHH(k)); delete sigtotalHH; delete zeroHH;delete deltaSigHH; LibereTenseur(); //---debug //fichier.close(); //---fin debug }; // 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 LoiDesMelangesEnSigma::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.)); TenseurHH * deltaSigHH = (NevezTenseurHH(dim_tens,0.)); // pour la variation de contraintes SaveResul_LoiDesMelangesEnSigma & save_resul = *((SaveResul_LoiDesMelangesEnSigma*) 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);}; // maintenant on balaie l'ensemble des lois bool premier_passage = true; list ::iterator isig,isig_t,jsig,jsig_t;int ili; list ::iterator ienerg,ienerg_t; list ::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois Loi_comp_abstraite * pt=NULL; // on récupère la valeur de la proportion enregistrée, qui a donc été calculée dans les grandeurs de // travail proportion = save_resul.proportion; for (ili=1,isig_t = save_resul.l_sigoHH_t.begin(),isig = save_resul.l_sigoHH.begin() ,jsig_t = save_resul.l_sigoHH_t.begin(),jsig = save_resul.l_sigoHH.begin() ,ienerg = save_resul.l_energ.begin(),ienerg_t = save_resul.l_energ_t.begin(); ili<=2;ili++,isig_t++,isig++,jsig_t++,jsig++,isave++,ienerg++,ienerg_t++) { // 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.);}; if ((*jsig)->Dimension()!=sigHH_t.Dimension()) { delete (*jsig); (*jsig)=NevezTenseurHH(sigHH_t.Dimension(),0.);}; if ((*jsig_t)->Dimension()!=sigHH_t.Dimension()) { delete (*jsig_t); (*jsig_t)=NevezTenseurHH(sigHH_t.Dimension(),0.);}; // calcul de la contrainte résultante, if (ili==1) {pt=lois_internes1;} else {pt=lois_internes2;}; double compress_inter=0.; double cisaill_inter=0; // init // passage des informations spécifique à la loi liste_des_SaveResul pt->IndiqueSaveResult(*isave); pt->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca pt->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours // initialisation du comportement tangent d_sigma_deps_inter->Inita(0.); // prise en compte éventuel d'un calcul conditionel au cas d'une proportion non nulle bool traitement = true; // par défaut if (calcule_si_prop_non_nulle.Taille() == 2) {if (calcule_si_prop_non_nulle(ili) == 1) {if (premier_passage && ( proportion == 0.)) {traitement = false;} else if ((!premier_passage) && ( proportion == 1.)) {traitement = false;}; } else if ((calcule_si_prop_non_nulle(ili) == 2)||(calcule_si_prop_non_nulle(ili) == 3)) { if ((premier_passage)&& (!save_resul.deja_actif_sur_iter1)) // première loi et pas encore actif { if ( proportion == 0. ) // on désactive et on signale pour la suite {traitement = false;save_resul.deja_actif_sur_iter1=true;}; }; if ((!premier_passage)&& (!save_resul.deja_actif_sur_iter2)) // seconde loi et pas encore actif { if ( proportion == 1. ) // on ne traite pas {traitement = false;} else // sinon le traitement commence {save_resul.deja_actif_sur_iter2=true;}; }; } }; if (traitement) { // calcul de la contrainte résultante pt->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); // on sauvegarde la contrainte partielle totale (*(*isig))=sigHH_tdt; #ifdef MISE_AU_POINT if (Permet_affichage() > 3) cout << "\n LoiDesMelangesEnSigma::Calcul_dsigma_deps "; #endif // def du facteur multiplicatif du à la proportion double facteur_multiplicatif = aA * proportion; if (premier_passage) { premier_passage = false;} else {facteur_multiplicatif = aA*(1.-proportion);}; // traitement if ((type_melange == 1)||(type_melange == 3)) { sigHH_tdt *= facteur_multiplicatif; (*(*jsig))=sigHH_tdt; // on sauvegarde la contrainte partielle proportionalisée (*sigtotalHH) += sigHH_tdt; // on ajoute la contrainte au total #ifdef MISE_AU_POINT if (Permet_affichage() > 3) {if (premier_passage) {cout << "\n 1ere loi:";} else {cout << "\n 2ieme loi: ";}; cout << " facteur_multiplicatif= " << facteur_multiplicatif << ", sigHH_tdt avec ponderation "; sigHH_tdt.Ecriture(cout); }; #endif } else // cas == 2 { (*deltaSigHH) = sigHH_tdt - (*(*isig_t)); (*deltaSigHH) *= facteur_multiplicatif; (*(*jsig))=(*(*jsig_t)) + (*deltaSigHH); // on sauvegarde la contrainte partielle proportionalisée (*sigtotalHH) += (*(*jsig)); // cumule }; energ += (*ienerg) * facteur_multiplicatif; // update des énergies module_compressibilite += compress_inter * facteur_multiplicatif; module_cisaillement += cisaill_inter * facteur_multiplicatif; (*d_sigma_deps_inter) *= facteur_multiplicatif; // module tangent #ifdef MISE_AU_POINT if (Permet_affichage() > 4) { cout << "\n d_sigma_deps_inter: "; d_sigma_deps_inter->Ecriture(cout); }; #endif // récup de l'opérateur tangent d_sigma_deps += *d_sigma_deps_inter; } else { if (premier_passage) { premier_passage = false;}; (*(*isig))=(*zeroHH); (*(*jsig))=(*zeroHH); (*ienerg).Inita(0.); }; // fin du traitement conditionnel }; // fin de la boucle sur les deux lois // recopie du résultat sigHH_tdt = (*sigtotalHH); delete sigtotalHH; delete zeroHH;delete deltaSigHH; LibereTenseur();LibereTenseurQ(); }; // fonction surchargée dans les classes dérivée si besoin est void LoiDesMelangesEnSigma::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 ) { // calcul de la proportion double proportion_locale; // variable locale de travail pour être indépendant de la variable de la classe if (type_melange < 3) // cas de la loi historique { if (valeur_aux_noeuds) // pour l'instant que des ddl patentés ! // cas d'une proportion provenant d'une interpolation aux noeuds { double grand = def.DonneeInterpoleeScalaire(type_grandeur.Enum(),temps); if (c_proport != NULL) { proportion_locale = c_proport->Valeur(grand);} else { proportion_locale = grand;}; } 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 (type_grandeur.Nom_vide()) {switch (type_grandeur.Enum()) { case PROP_CRISTA: { const double* taux_crita = dTP.TauxCrista(); if (taux_crita != NULL) { if (c_proport != NULL) { proportion_locale = c_proport->Valeur(*taux_crita);} else { proportion_locale = *taux_crita;}; } 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 LoiDesMelangesEnSigma::CalculGrandeurTravail(.... "; }; break; } default: // cout << "\n erreur, le type de proportion " << Nom_ddl(type_grandeur) << " n'est pas disponible " cout << "\n erreur, le type de proportion " << type_grandeur << " n'est pas disponible " << " pour l'instant au point d'integration ! " << "\n LoiDesMelangesEnSigma::CalculGrandeurTravail(.... "; Sortie(1); }; } else {// cas d'un vrai ddl étendue switch (type_grandeur.Position()-NbEnum_ddl()) {case 87: // cas de "def_equivalente" {const double def_equivalente = ptintmeca.Deformation_equi_const()(1); // recup de la def equi if (c_proport != NULL) { proportion_locale = c_proport->Valeur(def_equivalente);} else { proportion_locale = def_equivalente;}; // là mécanquement c'est débile mais techniquement c'est correcte 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 if (c_proport != NULL) { proportion_locale = c_proport->Valeur(def_duale_mises_maxi);} else { proportion_locale = def_duale_mises_maxi;}; // là mécanquement c'est débile mais techniquement c'est correcte break; } case 77: // cas de "def_duale_mises" {const double def_duale_mises = ptintmeca.Deformation_equi_const()(2); // recup de la def equi if (c_proport != NULL) { proportion_locale = c_proport->Valeur(def_duale_mises);} else { proportion_locale = def_duale_mises;}; // là mécanquement c'est débile mais techniquement c'est correcte break; } // {const Vecteur & epsInvar = ptintmeca.EpsInvar_const(); // recup des invariants // double def_duale_mises = sqrt(2./3. * epsInvar(2)); // // if (c_proport != NULL) // { proportion = c_proport->Valeur(def_duale_mises);} // else // { proportion = def_duale_mises;}; // là mécanquement c'est débile mais techniquement c'est correcte // break; // } case 78: // cas de "Spherique_eps" {const Vecteur & epsInvar = ptintmeca.EpsInvar_const(); // recup des invariants double spherique_eps = epsInvar(1); // cout << " Ieps=" << spherique_eps; if (c_proport != NULL) { proportion_locale = c_proport->Valeur(spherique_eps);} else { proportion_locale = spherique_eps;}; // là mécaniquement c'est débile mais techniquement c'est correcte break; } case 81: // cas de "Spherique_sig" {const Vecteur & sigInvar = ptintmeca.SigInvar_const(); // recup des invariants double spherique_sig = sigInvar(1); if (c_proport != NULL) { proportion_locale = c_proport->Valeur(spherique_sig);} else { proportion_locale = spherique_sig;}; // là mécaniquement c'est débile mais techniquement c'est correcte break; } default: cout << "\n erreur, le type de proportion " << type_grandeur << " n'est pas disponible " << " pour l'instant au point d'integration ! " << "\n LoiDesMelangesEnSigma::CalculGrandeurTravail(.... "; Sortie(1); break; } } }; } else // cas type_melange = 3 ou 4: -> fonctions complexes { // le résultat de la proportion est le produit de toutes les proportions // on initialise donc à 1 proportion_locale = 1.; if (niveauF_grandeurND != NULL) { // il faut calculer la fonction nD SaveResul_LoiDesMelangesEnSigma & save_resul = *((SaveResul_LoiDesMelangesEnSigma*) saveResul); // on utilise la méthode générique de loi abstraite Tableau & tab_val = Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee (niveauF_grandeurND,1 // une seule valeur attendue en retour ,ex_impli,ex_expli_tdt,ex_umat ,exclure_dd_etend ,exclure_Q ,&save_resul.liste_des_SaveResul ); /* // ici on utilise les variables connues aux pti, ou calculées à partir de // on commence par récupérer les conteneurs des grandeurs à fournir List_io & li_enu_scal = niveauF_grandeurND->Li_enu_etendu_scalaire(); List_io & li_quelc = niveauF_grandeurND->Li_equi_Quel_evolue(); bool absolue = true; // on se place systématiquement en absolu SaveResul_LoiDesMelangesEnSigma & save_resul = *((SaveResul_LoiDesMelangesEnSigma*) saveResul); // on va exclure certaines grandeurs de l'appel de Valeur_multi_interpoler_ou_calculer(..) // on va utiliser la méhode Valeur_multi_interpoler_ou_calculer // pour les grandeurs strictement scalaire List_io exclure_Q; // init de la liste à exclure {List_io ::iterator it,itfin = li_quelc.end(); map < EnumTypeQuelconque , TypeQuelconque, std::less < EnumTypeQuelconque> >::const_iterator imap; for (it = li_quelc.begin(); it != itfin; it++) {bool valeur_recuperer = false; // pour savoir s'il y a eu récupération EnumTypeQuelconque enu=(*it).EnuTypeQuelconque().EnumTQ(); // on boucle sur les lois pour récupérer les types quelconques Loi_comp_abstraite * pt=NULL; // pour couvrir l'ensemble des lois list ::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois for (int iloi = 1;iloi<3;iloi++,isave++) { if (iloi==1) {pt=lois_internes1;} else {pt=lois_internes2;}; // récupération des type quelconque sous forme d'un arbre pour faciliter la recherche const map < EnumTypeQuelconque , TypeQuelconque, std::less < EnumTypeQuelconque> >* map_quelcon = (*isave)->Map_type_quelconque(); if (map_quelcon != NULL) // sinon il n'y a pas de map {imap = map_quelcon->find(enu); if (imap != map_quelcon->end()) { // on a trouvé la grandeur switch (Type_de_grandeur_associee(enu)) { case SCALAIRE_DOUBLE: { const Grandeur_scalaire_double& tyTQ= *((Grandeur_scalaire_double*) (*imap).second.Const_Grandeur_pointee()); // on renseigne l'argument (*(*it).Grandeur_pointee()) = tyTQ; valeur_recuperer = true; break; } case SCALAIRE_ENTIER: { const Grandeur_scalaire_entier& tyTQ= *((Grandeur_scalaire_entier*) (*imap).second.Const_Grandeur_pointee()); // on renseigne l'argument (*(*it).Grandeur_pointee()) = tyTQ; valeur_recuperer = true; break; } default: {cout << "\n erreur fatale dans l'utilisation de la grandeur locale," << NomTypeQuelconque(enu) << " necessaire pour le calcul de la ponderation " << " cette grandeur n'est pas un scalaire, pour l'instant " << " on ne sait pas comment l'utiliser !! " << "\n LoiDesMelangesEnSigma::CalculGrandeurTravail(... "; Sortie(1); }; break; }; // on sort de la boucle break; }; }; }; // si la grandeur a été récupérée, on l'exclue de la liste à transmettre // à la méthode Valeurs_Tensorielles_interpoler_ou_calculer if (valeur_recuperer) exclure_Q.push_back(enu); }; }; // maintenant on appel les méthodes génériques Tableau val_ddl_enum(Valeur_multi_interpoler_ou_calculer (absolue,TEMPS_tdt,li_enu_scal,ex_impli,ex_expli_tdt,ex_umat,exclure_dd_etend) ); // on fait de même pour les grandeurs tensorielles // on utilise la méthode Valeurs_Tensorielles_interpoler_ou_calculer // pour les Coordonnees et Tenseur Valeurs_Tensorielles_interpoler_ou_calculer (absolue,TEMPS_tdt,li_quelc,ex_impli,ex_expli_tdt,ex_umat,&exclure_Q); // calcul de la valeur et retour dans tab_val Tableau & tab_val = niveauF_grandeurND->Valeur_FnD_Evoluee(&val_ddl_enum,&li_enu_scal,&li_quelc,NULL,NULL); #ifdef MISE_AU_POINT if (tab_val.Taille() != 1) { cout << "\nErreur : la fonction nD relative a la ponderation nD " << " doit calculer un scalaire or le tableau de retour est de taille " << tab_val.Taille() << " ce n'est pas normal !\n"; cout << " LoiDesMelangesEnSigma::CalculGrandeurTravail(..\n"; Sortie(1); }; #endif */ proportion_locale *= tab_val(1); // mise à jour de la proportion }; if (niveauF_temps != NULL) // cas d'une dépendance au temps proportion_locale *= niveauF_temps->CalculPonder(); // avec une dépendance via éventuellement des ddl étendu if (niveauF_ddlEtendu != NULL) proportion_locale *= niveauF_ddlEtendu->CalculPonderMultiplicatif(ptintmeca, def, temps, dTP); }; // --- arrivée ici on a une proposition de proportion = proportion_locale #ifdef MISE_AU_POINT if (Permet_affichage() > 5) { cout << "\n loi melange: proportion avant limitation "<< proportion_locale; } #endif // on traite les extrémums !!: a conserver absolument, car sert dans les tests avec le tableau: calcule_si_prop_non_nulle if (proportion_locale < 0.) proportion_locale = 0; if (proportion_locale > 1.) proportion_locale = 1.; #ifdef MISE_AU_POINT if (Permet_affichage() > 4) { cout << "\n proportion apres limitation "<< proportion_locale; } #endif // if ( (proportion < -0.02) || (proportion > 1.02)) // { cout << "\n attention, la proportion entre les deux lois est hors de [-0.02,1.02], proportion = " // << proportion << " "; // cout << "\n LoiDesMelangesEnSigma::CalculGrandeurTravail(.."; // }; // calcul de l'enregistrement dans les variables spécifiques au point calculé SaveResul_LoiDesMelangesEnSigma & save_res = *((SaveResul_LoiDesMelangesEnSigma*) saveResul); // auparavant: traitement particulier d'une proportion toujours progressive // if (calcule_si_prop_non_nulle.Taille() == 2) // {if ((calcule_si_prop_non_nulle(1) == 2) || (calcule_si_prop_non_nulle(2) == 2) // || ((calcule_si_prop_non_nulle(1) == 3) || (calcule_si_prop_non_nulle(2) == 3)) // ) if ((save_res.type_evolution_proportion == 1) || (save_res.type_evolution_proportion == 2)) // ici il s'agit d'une évolution absolue sur tout le calcul = tous les incréments { if (proportion_locale > save_res.proportion ) proportion_locale = save_res.proportion; // la proportion a augmenté, on garde la plus petite } // }; // suite normale save_res.proportion = proportion_locale; // répercution sur les classes dérivées si besoin est list ::iterator isave=save_res.liste_des_SaveResul.begin(); // pour les saveResul des lois Loi_comp_abstraite * pt=NULL; for (int ili=1;ili<=2;ili++,isave++) { if (ili==1) {pt=lois_internes1;} else {pt=lois_internes2;}; // passage des informations spécifique à la loi liste_des_SaveResul pt->IndiqueSaveResult(*isave); pt->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca pt->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours pt->CalculGrandeurTravail(ptintmeca,def,temps,dTP,ex_impli ,ex_expli_tdt,ex_umat,exclure_dd_etend,exclure_Q); }; }; // 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 LoiDesMelangesEnSigma::RepercuteChangeTemperature(Enum_dure temps) { lois_internes1->temperature_0 = this->temperature_0; lois_internes1->temperature_t = this->temperature_t; lois_internes1->temperature_tdt = this->temperature_tdt; lois_internes1->dilatation=dilatation; lois_internes2->temperature_0 = this->temperature_0; lois_internes2->temperature_t = this->temperature_t; lois_internes2->temperature_tdt = this->temperature_tdt; lois_internes2->dilatation=dilatation; if (dilatation) {// a- dimensionnement des tenseurs intermédiaires int dim_tens = epsBB_therm->Dimension(); // -- cas de la déformation if (lois_internes1->epsBB_therm == NULL) { lois_internes1->epsBB_therm = NevezTenseurBB(dim_tens);} else if (lois_internes1->epsBB_therm->Dimension() != dim_tens) { delete lois_internes1->epsBB_therm;lois_internes1->epsBB_therm = NevezTenseurBB(dim_tens);}; if (lois_internes2->epsBB_therm == NULL) { lois_internes2->epsBB_therm = NevezTenseurBB(dim_tens);} else if (lois_internes2->epsBB_therm->Dimension() != dim_tens) { delete lois_internes2->epsBB_therm;lois_internes2->epsBB_therm = NevezTenseurBB(dim_tens);}; // -- cas de la vitesse de déformation if (lois_internes1->DepsBB_therm == NULL) { lois_internes1->DepsBB_therm = NevezTenseurBB(dim_tens);} else if (lois_internes1->DepsBB_therm->Dimension() != dim_tens) { delete lois_internes1->DepsBB_therm;lois_internes1->DepsBB_totale = NevezTenseurBB(dim_tens);}; if (lois_internes2->DepsBB_therm == NULL) { lois_internes2->DepsBB_therm = NevezTenseurBB(dim_tens);} else if (lois_internes2->DepsBB_therm->Dimension() != dim_tens) { delete lois_internes2->DepsBB_therm;lois_internes2->DepsBB_totale = NevezTenseurBB(dim_tens);}; // b- affectation des tenseurs (*lois_internes1->epsBB_therm)=(*epsBB_therm); (*lois_internes1->DepsBB_therm)=(*DepsBB_therm); (*lois_internes2->epsBB_therm)=(*epsBB_therm); (*lois_internes2->DepsBB_therm)=(*DepsBB_therm); }; lois_internes1->RepercuteChangeTemperature(temps); lois_internes2->RepercuteChangeTemperature(temps); switch (temps) { case TEMPS_0: {lois_internes1->temperature = &lois_internes1->temperature_0; lois_internes2->temperature = &lois_internes2->temperature_0; break; } case TEMPS_t: {lois_internes1->temperature = &lois_internes1->temperature_t; lois_internes2->temperature = &lois_internes2->temperature_t; break; } case TEMPS_tdt: {lois_internes1->temperature = &lois_internes1->temperature_tdt; lois_internes2->temperature = &lois_internes2->temperature_tdt; break; } default: { cout << "\n erreur, cas de temps non prevu !! " << "\n LoiDesMelangesEnSigma::RepercuteChangeTemperature(..."; Sortie(1); }; }; #ifdef MISE_AU_POINT if (Permet_affichage() > 7) { cout << "\n init temperatures:\n " << " lois_internes1->temperature_0= " << lois_internes1->temperature_0 << " lois_internes1->temperature_t= " << lois_internes1->temperature_t << " lois_internes1->temperature_tdt= " << lois_internes1->temperature_tdt << " lois_internes1->temperature= " << *(lois_internes1->temperature) << " lois_internes2->temperature_0= " << lois_internes2->temperature_0 << " lois_internes2->temperature_t= " << lois_internes2->temperature_t << " lois_internes2->temperature_tdt= " << lois_internes2->temperature_tdt << " lois_internes2->temperature= " << *(lois_internes2->temperature) << " \n LoiDesMelangesEnSigma::RepercuteChangeTemperature(.." << endl; }; #endif };