// FICHIER : Projection_anisotrope_3D.cp // CLASSE : Projection_anisotrope_3D // This file is part of the Herezh++ application. // // The finite element software Herezh++ is dedicated to the field // of mechanics for large transformations of solid structures. // It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600) // INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) . // // Herezh++ is distributed under GPL 3 license ou ultérieure. // // Copyright (C) 1997-2022 Université Bretagne Sud (France) // AUTHOR : Gérard Rio // E-MAIL : gerardrio56@free.fr // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, // or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // For more information, please consult: . //#include "Debug.h" # include using namespace std; //introduces namespace std #include #include #include "Sortie.h" #include "TypeConsTens.h" #include "ConstMath.h" #include "LesLoisDeComp.h" #include "Projection_anisotrope_3D.h" #include "NevezTenseur.h" #include "MathUtil.h" #include "Util.h" #include "Enum_TypeQuelconque.h" #include "TypeQuelconqueParticulier.h" #include "TenseurQ3gene.h" #include "NevezTenseurQ.h" #include "MathUtil.h" #include "MathUtil2.h" #include "CharUtil.h" // ========== fonctions pour la classe de sauvegarde des résultats ========= // constructeur par défaut à ne pas utiliser Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D::SaveResulProjection_anisotrope_3D(): O_B(NULL), O_H(NULL),Op_H(3,3),Op_H_t(3,3),eps_loc_HH(NULL),sig_loc_HH(NULL) ,para_loi(NULL) { // non on ne fait pas de définition par défaut // if (type_transport == 0) // {O_H = new BaseH(); sig_loc_HH = NevezTenseurHH(3); } // else // {O_B = new BaseB(); eps_loc_HH = NevezTenseurHH(3); }; cout << "\n erreur, le constructeur par defaut ne doit pas etre utilise !" << "\n Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D::SaveResulProjection_anisotrope_3D()"; cout << "\n Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D::SaveResulProjection_anisotrope_3D()"; Sortie(1); }; // le constructeur courant Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D::SaveResulProjection_anisotrope_3D (SaveResul* l_des_SaveResul,TenseurHH* l_siHH ,TenseurHH* l_siHH_t ,EnergieMeca l_energ_,EnergieMeca l_energ_t_ ,bool avec_ponderation): O_B(NULL), O_H(NULL),Op_H(3,3),Op_H_t(3,3),eps_loc_HH(NULL),sig_loc_HH(NULL) ,para_loi(NULL) ,SaveResul_interne(NULL) ,l_sigoHH(),l_sigoHH_t(),l_energ(l_energ_),l_energ_t(l_energ_t_) ,f_ponder(1.),f_ponder_t(1.) { SaveResul * nevez_save_result=NULL; if (l_des_SaveResul != NULL) nevez_save_result = l_des_SaveResul->Nevez_SaveResul(); SaveResul_interne = nevez_save_result; TenseurHH * interHH=NULL; // dans le cas où le tenseur passé en paramètre est non null on s'en sert if (l_siHH_t != NULL) {interHH=NevezTenseurHH(*l_siHH_t);}; l_sigoHH= 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 (l_siHH_t != NULL) {interHH_t =NevezTenseurHH(*l_siHH_t);}; l_sigoHH_t=interHH_t; }; // constructeur de copie Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D ::SaveResulProjection_anisotrope_3D(const SaveResulProjection_anisotrope_3D& sav): O_B(NULL), O_H(NULL),Op_H(3,3),Op_H_t(3,3),eps_loc_HH(NULL),sig_loc_HH(NULL) ,para_loi(NULL) ,SaveResul_interne(NULL) ,l_sigoHH(NULL),l_sigoHH_t(NULL) ,l_energ(sav.l_energ),l_energ_t(sav.l_energ_t) ,f_ponder(sav.f_ponder),f_ponder_t(sav.f_ponder_t) { // partie repère d'anisotropie if (sav.O_B != NULL) O_B = new BaseB(*sav.O_B); if (sav.O_H != NULL) O_H = new BaseH(*sav.O_H); if (sav.eps_loc_HH != NULL) eps_loc_HH = NevezTenseurHH(*sav.eps_loc_HH); if (sav.sig_loc_HH != NULL) sig_loc_HH = NevezTenseurHH(*sav.sig_loc_HH); if (sav.para_loi != NULL) para_loi = new Vecteur (*sav.para_loi); // loi interne if (sav.SaveResul_interne != NULL) SaveResul_interne = sav.SaveResul_interne->Nevez_SaveResul(); // dans le cas où le tenseur passé en paramètre est non null on s'en sert if (sav.l_sigoHH != NULL) {l_sigoHH=NevezTenseurHH(*(sav.l_sigoHH));}; // idem interHH, dans le cas où le tenseur passé en paramètre est non null on s'en sert if (sav.l_sigoHH_t != NULL) {l_sigoHH_t =NevezTenseurHH(*(sav.l_sigoHH_t));}; // pour les pondérations }; // destructeur Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D::~SaveResulProjection_anisotrope_3D() { // partie repère d'anisotropie if (O_B != NULL) delete O_B; if (O_H != NULL) delete O_H; if (eps_loc_HH != NULL) delete eps_loc_HH; if (sig_loc_HH != NULL) delete sig_loc_HH; if (para_loi != NULL) delete para_loi; // loi interne if (SaveResul_interne != NULL) delete SaveResul_interne; if(l_sigoHH != NULL) delete l_sigoHH; if(l_sigoHH_t != NULL) delete l_sigoHH_t; }; // affectation Loi_comp_abstraite::SaveResul & Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D::operator = ( const Loi_comp_abstraite::SaveResul & a) { Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D& sav = *((Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D*) &a); // partie repère d'anisotropie if (sav.O_B != NULL) {if (O_B == NULL) {O_B = new BaseB(*sav.O_B);} else {*O_B = *sav.O_B;}; } else // sinon cas NULL {if (O_B != NULL) {delete O_B;O_B=NULL;}} ; if (sav.O_H != NULL) {if (O_H == NULL) {O_H = new BaseH(*sav.O_H);} else {*O_H = *sav.O_H;}; } else // sinon cas NULL {if (O_H != NULL) {delete O_H;O_H=NULL;}} ; if (sav.eps_loc_HH != NULL) {if (eps_loc_HH == NULL) {eps_loc_HH = NevezTenseurHH(*sav.eps_loc_HH);} else {*eps_loc_HH = *sav.eps_loc_HH;}; } else // sinon cas NULL {if (eps_loc_HH != NULL) {delete eps_loc_HH;eps_loc_HH=NULL;}} ; if (sav.sig_loc_HH != NULL) {if (sig_loc_HH == NULL) {sig_loc_HH = NevezTenseurHH(*sav.sig_loc_HH);} else {*sig_loc_HH = *sav.sig_loc_HH;}; } else // sinon cas NULL {if (sig_loc_HH != NULL) {delete sig_loc_HH; sig_loc_HH= NULL;}; } ; if (sav.para_loi != NULL) {if (para_loi == NULL) para_loi = new Vecteur (*sav.para_loi); else {*para_loi = *sav.para_loi; }; } else // sinon cas NULL {if (para_loi != NULL) {delete para_loi;para_loi=NULL;}} ; // et la base Op_H = sav.Op_H; Op_H_t = sav.Op_H_t; // loi interne if (SaveResul_interne != NULL) {if (sav.SaveResul_interne == NULL) {delete SaveResul_interne;SaveResul_interne=NULL;} else // on considère que les deux sont de même type {*SaveResul_interne = *(sav.SaveResul_interne);}; } else {if (sav.SaveResul_interne != NULL) { SaveResul_interne = sav.SaveResul_interne->Nevez_SaveResul(); }; // sinon il n'y a rien à faire car les deux sont nulles }; if (l_sigoHH != NULL) {if (sav.l_sigoHH == NULL) {delete l_sigoHH;l_sigoHH=NULL;} else // on considère que les deux sont de même type {*l_sigoHH = *(sav.l_sigoHH);}; } else {if (sav.l_sigoHH != NULL) { *l_sigoHH = *(sav.l_sigoHH); }; // sinon il n'y a rien à faire car les deux sont nulles }; if (l_sigoHH_t != NULL) {if (sav.l_sigoHH_t == NULL) {delete l_sigoHH_t;l_sigoHH_t=NULL;} else // on considère que les deux sont de même type {*l_sigoHH_t = *(sav.l_sigoHH_t);}; } else {if (sav.l_sigoHH_t != NULL) { *l_sigoHH_t = *(sav.l_sigoHH_t); }; // sinon il n'y a rien à faire car les deux sont nulles }; // // pour les autres conteneurs internes, affectation directe, car a priori pas de pb l_energ = sav.l_energ; l_energ_t = sav.l_energ_t; f_ponder = sav.f_ponder; return *this; }; //------- lecture écriture dans base info ------- // cas donne le niveau de la récupération // = 1 : on récupère tout // = 2 : on récupère uniquement les données variables (supposées comme telles) void Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D::Lecture_base_info(ifstream& ent,const int cas) { string nom; ent >> nom ; #ifdef MISE_AU_POINT if (nom != "S_Proj_aniso_3D") { cout << "\nErreur : on attendait le mot cle: S_Proj_aniso_3D " << " et on a lue "<> toto >> f_ponder; f_ponder_t = f_ponder; // données de la loi bool avec_save_result = false; ent >> toto >> avec_save_result; if (avec_save_result) { if(SaveResul_interne != NULL) {SaveResul_interne->Lecture_base_info(ent,cas);} else { cout << "\n *** erreur en lecture des infos specifiques a la loi de comportement interne " << " il n'y a pas de conteneur definit ! on ne peut pas continuer " << "\n Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D::Lecture_base_info(..." << flush; Sortie(1); }; }; // lecture de la contrainte sauvegardée ent >> toto; // le mot clé (l_sigoHH_t)->Lecture(ent); // lecture du tenseur *l_sigoHH = *l_sigoHH_t; // lecture des énergies ent >> l_energ_t;l_energ =l_energ_t; // puis on lit que ce qui est à 0 et à t, ce qui est à tdt est considéré une zone de travail switch (cas) { case 1 : { // la base initiale if (O_B != NULL) { ent >> nom >> *O_B;} else if (O_H != NULL) { ent >> nom >> *O_H;} // la base convectée ent >> nom >> Op_H_t ; Op_H = Op_H_t; // les stockages conditionnels int test; // -- // cas d'eps_loc ent >> nom >> test; if (test == 0) { if (eps_loc_HH != NULL) {delete eps_loc_HH;eps_loc_HH=NULL;} } else // sinon cas où on a des données additionnelles { if (eps_loc_HH == NULL) eps_loc_HH = NevezTenseurHH(3); eps_loc_HH->Lecture(ent); }; // -- // cas de sig_loc ent >> nom >> test; if (test == 0) { if (sig_loc_HH != NULL) {delete sig_loc_HH;sig_loc_HH=NULL;} } else // sinon cas où on a des données additionnelles { if (sig_loc_HH == NULL) sig_loc_HH = NevezTenseurHH(3); sig_loc_HH->Lecture(ent); }; // -- // cas des para loi ent >> nom >> test; if (test == 0) { if (para_loi != NULL) {delete para_loi;para_loi=NULL;} } else // sinon cas où on a des données additionnelles { if (para_loi == NULL) para_loi = new Vecteur (6); ent >> *para_loi; }; break; } case 2 : { // la base convectée ent >> nom >> Op_H_t ; // les stockages conditionnels int test; ent >> nom >> test; if (test == 0) { if (eps_loc_HH != NULL) {delete eps_loc_HH;eps_loc_HH=NULL;} } else // sinon cas où on a des données additionnelles { if (eps_loc_HH == NULL) eps_loc_HH = NevezTenseurHH(3); eps_loc_HH->Lecture(ent); }; ent >> nom >> test; if (test == 0) { if (sig_loc_HH != NULL) {delete sig_loc_HH;sig_loc_HH=NULL;} } else // sinon cas où on a des données additionnelles { if (sig_loc_HH == NULL) sig_loc_HH = NevezTenseurHH(3); sig_loc_HH->Lecture(ent); }; ent >> nom >> test; if (test == 0) { if (para_loi != NULL) {delete para_loi;para_loi=NULL;} } else // sinon cas où on a des données additionnelles { if (para_loi == NULL) para_loi = new Vecteur(6); ent >> *para_loi; }; break; } default: cout << "\n cas non considere !!: cas= " << cas << "\n Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D::Ecriture_base_info(..."; Sortie(1); }; }; // cas donne le niveau de sauvegarde // = 1 : on sauvegarde tout // = 2 : on sauvegarde uniquement les données variables //(supposées comme telles) void Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D::Ecriture_base_info(ofstream& sort,const int cas ) { sort << "\n S_Proj_aniso_3D "; // tout d'abord ce qui varie tout le temps // pondération ? sort << " Pond= "<< f_ponder_t << " "; // on regarde s'il y a un save_result local sort << " avec_save_result "<< (SaveResul_interne != NULL)<<" "; if (SaveResul_interne != NULL) SaveResul_interne->Ecriture_base_info(sort, cas); // écriture de la contrainte sauvegardée sort << " sig_intHH "; (l_sigoHH)->Ecriture(sort); // écriture des énergies sort << l_energ; // puis on ne sauvegarde que ce qui est à 0 et à t, ce qui est à tdt est considéré une zone de travail switch (cas) { case 1 : { // la base initiale if (O_B != NULL) { sort << " O_B: "<< *O_B;} else if (O_H != NULL) { sort << " O_H: "<< *O_H;} // la base convectée sort << " Op_H_t: "<< Op_H_t << " "; // les stockages conditionnels if (eps_loc_HH != NULL) { sort << "\n addi_eps_loc: 1 "; eps_loc_HH->Ecriture(sort); } else { sort << " addi_eps_loc: 0 ";}; if (sig_loc_HH != NULL) { sort << "\n addi_sig_loc: 1 " ; sig_loc_HH->Ecriture(sort); } else { sort << " addi_sig_loc: 0 ";}; if (para_loi != NULL) { sort << " addi_para_loi: 1 "; sort << *para_loi << " "; } else { sort << " addi_para_loi: 0 ";}; break; } case 2 : { // la base convectée sort << " Op_H_t: "<< Op_H_t << " "; // les stockages conditionnels if (eps_loc_HH != NULL) { sort << "\n addi_eps_loc: 1 "; eps_loc_HH->Ecriture(sort); } else { sort << " addi_eps_loc: 0 ";}; if (sig_loc_HH != NULL) { sort << "\n addi_sig_loc: 1 " ; sig_loc_HH->Ecriture(sort); } else { sort << " addi_sig_loc: 0 ";}; if (para_loi != NULL) { sort << " addi_para_loi: 1 "; sort << *para_loi << " "; } else { sort << " addi_para_loi: 0 ";}; break; } default: cout << "\n cas non considere !!: cas= " << cas << "\n Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D::Ecriture_base_info(..."; Sortie(1); }; }; // mise à jour des informations transitoires void Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D::TdtversT() { Op_H_t = Op_H; f_ponder_t = f_ponder; (*l_sigoHH_t) = (*l_sigoHH); l_energ_t = l_energ; if (SaveResul_interne != NULL) SaveResul_interne->TdtversT(); }; void Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D::TversTdt() { Op_H = Op_H_t; f_ponder = f_ponder_t; (*l_sigoHH) = (*l_sigoHH_t); l_energ = l_energ_t; if (SaveResul_interne != NULL) SaveResul_interne->TversTdt(); }; // affichage à l'écran des infos void Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D::Affiche() const { cout << "\n SaveResulProjection_anisotrope_3D: " ; cout << "\n SaveResul_loi_interne: "; if (SaveResul_interne != NULL) SaveResul_interne->Affiche(); cout << "\n l_sigoHH: "; l_sigoHH->Ecriture(cout); cout << "\n l_sigoHH_t: "; l_sigoHH_t->Ecriture(cout); cout << "\n l_energ: " << l_energ; cout << "\n l_energ_t: " << l_energ_t; cout << "\n f_ponder: " << f_ponder; cout << "\n f_ponder_t: " << f_ponder_t; // la partie base d'anisotropie // la base initiale if (O_B != NULL) { cout << " O_B: "<< *O_B;} else if (O_H != NULL) { cout << " O_H: "<< *O_H;} // la base convectée cout << " Op_H_t: "<< Op_H_t << " "; // les stockages conditionnels if (eps_loc_HH != NULL) { cout << " addi: 1 " << "\n eps_loc_HH: "; eps_loc_HH->Ecriture(cout); cout << "\n sig_loc_HH: "; sig_loc_HH->Ecriture(cout); cout << "\n para_loi: " << *para_loi << " "; } else { cout << " addi: 0 ";}; // la base convectée cout << " Op_H_t: "<< Op_H_t << " "; // les stockages conditionnels if (eps_loc_HH != NULL) { cout << "\n addi: 1 "<< "\n eps_loc_HH: " ; eps_loc_HH->Ecriture(cout); cout << "\n sig_loc_HH: " ; sig_loc_HH->Ecriture(cout); cout << "\n para_loi: " << *para_loi << " "; } else { cout << "\n addi: 0 ";}; cout << "\n .. fin SaveResulProjection_anisotrope_3D ... "; }; //changement de base de toutes les grandeurs internes tensorielles stockées // b(i,j) represente les coordonnees de la nouvelle base naturelle gpB dans l'ancienne gB // gpB(i) = beta(i,j) * gB(j), i indice de ligne, j indice de colonne // gpH(i) = gamma(i,j) * gH(j) void Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D::ChBase_des_grandeurs(const Mat_pleine& beta,const Mat_pleine& gamma) { // on ne s'intéresse qu'aux grandeurs tensorielles // il faut que l'on exprime le repère d'anisotropie dans le nouveau repère if (O_B != NULL) {for (int i=1;i<4;i++) { CoordonneeB Ap_B(3); // inter MathUtil2::ChBase(O_B->CoordoB(i),beta,Ap_B); O_B->CoordoB(i)=Ap_B; } }; if (O_H != NULL) {for (int i=1;i<4;i++) { CoordonneeH Ap_H(3); // inter MathUtil2::ChBase(O_H->CoordoH(i),gamma,Ap_H); O_H->CoordoH(i)=Ap_H; } }; // les autres grandeurs sont issues du calcul // normalement elles sont calculées en même temps que les contraintes // mais on les change de repère néanmoins, au cas on on ferait une sortie // d'info sans calcul (c'est pénalisant pour le cas avec calcul, mais cela // évite peut-être des pb potentiels ??) // Op_H est toujours calculé {for (int i=1;i<4;i++) { CoordonneeH Ap_H(3); // inter MathUtil2::ChBase(Op_H_t.CoordoH(i),gamma,Ap_H); Op_H_t.CoordoH(i)=Ap_H; } }; // cas des grandeurs locales si elles sont sauvegardées if (eps_loc_HH != NULL) { eps_loc_HH->ChBase(gamma);}; if (sig_loc_HH != NULL) { sig_loc_HH->ChBase(gamma);}; // partie relative à la loi interne if (SaveResul_interne != NULL) SaveResul_interne->ChBase_des_grandeurs(beta,gamma); // les tenseurs l_sigoHH->ChBase(gamma); l_sigoHH_t->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* Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D ::Complete_SaveResul(const BlocGen & bloc, const Tableau & tab_coor ,const Loi_comp_abstraite* loi) {// on regarde s'il s'agit d'un repère d'anisotropie if (bloc.Nom(1) == "repere_anisotropie_") {// ensuite on vérifie le nom de l'identificateur Projection_anisotrope_3D* loiOrtho = (Projection_anisotrope_3D*) loi; // dimensionnement des bases if (loiOrtho->Type_transport() == 0) {O_H = new BaseH(); sig_loc_HH = NevezTenseurHH(3); } else {O_B = new BaseB(); eps_loc_HH = NevezTenseurHH(3); }; // // on crée sig et eps loc, les deux pour éviter des pb de sortie par la suite // sig_loc_HH = NevezTenseurHH(3); // eps_loc_HH = NevezTenseurHH(3); // récupération du repère if (bloc.Nom(2) == loiOrtho->NomRepere()) {// c'est le bon, récupération du repère if (O_B != NULL) {for (int i=1;i<4;i++) O_B->CoordoB(i).Change_val(tab_coor(i)); }; if (O_H != NULL) {for (int i=1;i<4;i++) O_H->CoordoH(i).Change_val(tab_coor(i)); }; }; }; // puis idem pour la loi interne // on transmet au conteneur 3D interne const Projection_anisotrope_3D * loi_CPtt = (const Projection_anisotrope_3D*) loi; // loi_CPtt : est un nom quelconque if (SaveResul_interne != NULL) SaveResul_interne->Complete_SaveResul(bloc,tab_coor, loi_CPtt->loi_interne); return this; }; // initialise les informations de travail concernant le pas de temps en cours void Projection_anisotrope_3D::SaveResulProjection_anisotrope_3D::Init_debut_calcul() { }; // ========== fin des fonctions pour la classe de sauvegarde des résultats ========= Projection_anisotrope_3D::Projection_anisotrope_3D () : // Constructeur par defaut Loi_comp_abstraite(PROJECTION_ANISOTROPE_3D,CAT_MECANIQUE,3) ,hij(3,3),fct_para(6),cas_calcul(0),type_transport(0) ,A1(ConstMath::tresgrand),A2(ConstMath::tresgrand),A3(ConstMath::tresgrand) ,B12(ConstMath::tresgrand),B13(ConstMath::tresgrand),B23(ConstMath::tresgrand) ,ratio_inf_module_compressibilite(0.01) ,sortie_post(0) ,nom_repere("") ,inv_loi(3,3),Op_B(3,3),d_Op_B(3,3),d_Op_H(3,3),pO_B(3,3),pO_H(3,3) ,beta_inv(3,3),beta(3,3),gamma(3,3),beta_transpose(3,3),gamma_transpose(3,3) ,alpha_H(3,3) ,I_x_I_HHHH(),I_xbarre_I_HHHH(),I_x_eps_HHHH(),Ixbarre_eps_HHHH() ,dsig_ijkl_HHHH() // loi interne ,loi_interne(NULL) ,completude_calcul(CONTRAINTE_ET_TANGENT),d_sigma_deps_inter(NULL),d_sig_deps_3D_HHHH() ,ponderation_nD_quelconque(NULL) ,d_sigRef_HH() // -- grandeurs de travail ,H_HHBB() // un conteneur d'un point d'intégration courant ,ptintmeca(3) {// def de hij B12=ConstMath::tresgrand;B13=ConstMath::tresgrand;B23=ConstMath::tresgrand; hij(1,1) = &A1;hij(2,2) = &A2;hij(3,3) = &A3; hij(1,2) = &B12;hij(1,3) = &B13;hij(2,3) = &B23; hij(2,1) = &B12;hij(3,1) = &B13;hij(3,2) = &B23; // init fnD for (int i=1;i<=6;i++) fct_para(i) = NULL; Bll_fct_para=1; // pour l'instant pas de fonction // on ajoute les invariants au pt integ courant ptintmeca.Change_statut_Invariants_contrainte (true); }; // Constructeur de copie Projection_anisotrope_3D::Projection_anisotrope_3D (const Projection_anisotrope_3D& loi) : Loi_comp_abstraite(loi) ,hij(3,3),fct_para(loi.fct_para),cas_calcul(loi.cas_calcul) ,A1(loi.A1),A2(loi.A2),A3(loi.A3) ,ratio_inf_module_compressibilite(loi.ratio_inf_module_compressibilite) ,inv_loi(loi.inv_loi),Op_B(3,3),d_Op_B(3,3),d_Op_H(3,3),pO_B(3,3),pO_H(3,3) ,beta_inv(3,3),beta(3,3),gamma(3,3),beta_transpose(3,3),gamma_transpose(3,3) ,alpha_H(3,3) ,type_transport(loi.type_transport) ,sortie_post(loi.sortie_post) ,nom_repere(loi.nom_repere) ,I_x_I_HHHH(),I_xbarre_I_HHHH(),I_x_eps_HHHH(),Ixbarre_eps_HHHH() ,dsig_ijkl_HHHH() // loi interne ,completude_calcul(loi.completude_calcul),d_sigma_deps_inter(NULL) ,d_sig_deps_3D_HHHH(loi.d_sig_deps_3D_HHHH) ,ponderation_nD_quelconque(NULL) ,d_sigRef_HH() // grandeurs de travail ,H_HHBB(loi.H_HHBB) // un conteneur d'un point d'intégration courant ,ptintmeca(loi.ptintmeca) {// def de hij B12=loi.B12;B13=loi.B13;B23=loi.B23; hij(1,1) = &A1;hij(2,2) = &A2;hij(3,3) = &A3; hij(1,2) = &B12;hij(1,3) = &B13;hij(2,3) = &B23; hij(2,1) = &B12;hij(3,1) = &B13;hij(3,2) = &B23; // init fnD // on regarde s'il s'agit d'une courbe locale ou d'une courbe globale for (int i=1;i<=6;i++) {if (fct_para(i) != NULL) {Bll_fct_para=0; // dans tous les cas on indique qu'il y a des fonctions if (fct_para(i)->NomFonction() == "_") {// comme il s'agit d'une fonction locale on la redéfinie (sinon pb lors du destructeur de loi) string non_fonction("_"); fct_para(i) = Fonction_nD::New_Fonction_nD(*fct_para(i)); }; }; }; // loi interne if (loi.loi_interne != NULL) loi_interne = loi.loi_interne->Nouvelle_loi_identique(); // pondération éventuelle if (loi.ponderation_nD_quelconque != NULL) ponderation_nD_quelconque = new Ponderation_TypeQuelconque(*(loi.ponderation_nD_quelconque)); if (loi.d_sigma_deps_inter != NULL) d_sigma_deps_inter = NevezTenseurHHHH(*loi.d_sigma_deps_inter); }; Projection_anisotrope_3D::~Projection_anisotrope_3D () // Destructeur { for (int i=1;i<=6;i++) {if (fct_para(i) != NULL) if (fct_para(i)->NomFonction() == "_") delete fct_para(i); }; // loi interne if (loi_interne != NULL) delete loi_interne; if (d_sigma_deps_inter != NULL) delete d_sigma_deps_inter; if (d_sigRef_HH.Taille() != 0) { int taille = d_sigRef_HH.Taille(); for (int i=1; i<= taille; i++) if (d_sigRef_HH(i) != NULL) delete d_sigRef_HH(i); }; // pondération nD quelconques if (ponderation_nD_quelconque != NULL) delete ponderation_nD_quelconque; }; // def d'une instance de données spécifiques, et initialisation // valable une fois que la loi interne est définie Projection_anisotrope_3D::SaveResul * Projection_anisotrope_3D::New_et_Initialise() { // petite vérif if (loi_interne == NULL) {cout << "\n *** erreur la loi interne n'est pas definie, on ne peut pas " << " creer le conteneur au pti associe !"<< flush; Sortie(1); }; // on crée les éléments nécessaires SaveResul * nevez_save_result = loi_interne->New_et_Initialise(); // 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 * l_sigoHH = NevezTenseurHH(dim,0.); TenseurHH * l_sigoHH_t = NevezTenseurHH(dim,0.); EnergieMeca l_energ_inter,l_energ_t_inter; bool avec_ponderation = (ponderation_nD_quelconque!=NULL); // on ramène la bonne instance Projection_anisotrope_3D::SaveResul * retour = new SaveResulProjection_anisotrope_3D (nevez_save_result,l_sigoHH,l_sigoHH_t ,l_energ_inter,l_energ_t_inter ,avec_ponderation); // on supprime les grandeurs locales qui ont été crées par des new delete nevez_save_result;delete l_sigoHH; delete l_sigoHH_t; // retour return retour; }; // Lecture des donnees de la classe sur fichier void Projection_anisotrope_3D::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D ,LesFonctions_nD& lesFonctionsnD) { // on lit les coefficients dans l'ordre string nom_class_methode("Projection_anisotrope_3D::LectureDonneesParticulieres"); double val_defaut=0.; double min = 0.; double max = -1; // max < min => la condition n'est pas prise en compte string nom_pour_erreur("**erreur en lecture** Projection_anisotrope_3D:"); // -- lecture du type de projection // on lit le nom du type de projection {string nom_proj; string mot_cle("TYPE_PROJ_ANISO_"); bool lec = entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle,nom_proj); if (!lec ) { entreePrinc->MessageBuffer(nom_pour_erreur+" mot cle "+mot_cle); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; if ( Type_Enum_proj_aniso_existe(nom_proj)) { type_projection = Id_Nom_proj_aniso(nom_proj); } else { entreePrinc->MessageBuffer(nom_pour_erreur+" type de projection inexistant: "+mot_cle); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; // --- suivant le type de projection on lit les paramètres ad hoc --- entreePrinc->NouvelleDonnee(); // on se positionne sur un nouvel enreg switch (type_projection) {case PROJ_ORTHO: {// pour faire une boucle de lecture on constitue un tableau de mots clés Tableau tab_mot_cle(6); tab_mot_cle(1) = "A1";tab_mot_cle(2) = "A2";tab_mot_cle(3) = "A3"; tab_mot_cle(4) = "B12";tab_mot_cle(5) = "B13";tab_mot_cle(6) = "B23"; // puis un tableau pour les valeurs Tableau < double * > coef(6); coef(1) = &A1; coef(2) = & A2; coef(3) = &A3; coef(4) = & B12; coef(5) = & B13; coef(6) = & B23; // on boucle sur les 6 coefficients for (int i=1;i < 7;i++) {string mot_cle1=tab_mot_cle(i)+"="; string mot_cle2=tab_mot_cle(i)+"_fonction_nD:"; if(strstr(entreePrinc->tablcar,mot_cle2.c_str())==0) {// lecture du paramètre min = 0.; max = -1; // max < min => la condition n'est pas prise en compte if (!entreePrinc->Lecture_un_parametre_double(val_defaut,nom_class_methode ,min,max,mot_cle1, *coef(i) )) { entreePrinc->MessageBuffer(nom_pour_erreur+" mot cle : "+mot_cle1); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; ////----- debug --- //cout << "\n debug Projection_anisotrope_3D::LectureDonneesParticulieres " // << " mot cle : "+mot_cle1 << " = "<< *coef(i) // << ", i= "<< i // << flush; ////--- fin debug --- // //----- debug --- // cout << "\n debug Projection_anisotrope_3D::LectureDonneesParticulieres "; // this->Affiche(); // //--- fin debug --- } else // on lit une fonction {// on passe le mot clé générique bool lec = entreePrinc->Lecture_et_verif_mot_cle(nom_class_methode,mot_cle1); // on lit le nom de la fonction string nom_fonct; lec = lec && entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle2,nom_fonct); if (!lec ) { entreePrinc->MessageBuffer(nom_pour_erreur+mot_cle2); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; Bll_fct_para=0; // on indique qu'il y a des fonctions // maintenant on définit la fonction if (lesFonctionsnD.Existe(nom_fonct)) {fct_para(i) = lesFonctionsnD.Trouve(nom_fonct); } else {// sinon il faut la lire maintenant string non("_"); fct_para(i) = Fonction_nD::New_Fonction_nD(non, Id_Nom_Fonction_nD(nom_fonct)); // lecture de la courbe fct_para(i)->LectDonnParticulieres_Fonction_nD (non,entreePrinc); // maintenant on vérifie que la fonction est utilisable if (fct_para(i)->NbComposante() != 1 ) { cout << "\n erreur en lecture, la fonction " << nom_fonct << " est une fonction vectorielle a " << fct_para(i)->NbComposante() << " composante alors qu'elle devrait etre scalaire ! " << " elle n'est donc pas utilisable !! "; string message("\n**erreur08** \n"+nom_class_methode+"(..."); entreePrinc->MessageBuffer(message); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; if (i != 6) entreePrinc->NouvelleDonnee(); // on se positionne sur un nouvel enreg }; }; // fin de la boucle for (int i=1;i < 7;i++) } break; default: cout << "\n *** le type de projection: " << Nom_proj_aniso(type_projection) << " n'est pas encore implemente, se plaindre !! " << flush; entreePrinc->MessageBuffer("**erreur en lecture** Projection_anisotrope_3D "); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); break; }; // --- lecture du repère d'anisotropie entraîné, associé --- string mot_cle("nom_repere_associe_"); entreePrinc->NouvelleDonnee(); // on se positionne sur un nouvel enreg bool lec = entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle,nom_repere); if (!lec ) { entreePrinc->MessageBuffer(nom_pour_erreur+mot_cle); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // --- lecture de la loi associée --- {// lecture du nom de la loi string st2; entreePrinc->NouvelleDonnee(); // on se positionne sur un nouvel enreg *(entreePrinc->entree) >> st2; // definition de la loi LoiAbstraiteGeneral * pt = LesLoisDeComp::Def_loi(st2); // enregistrement de la loi loi_interne = ((Loi_comp_abstraite*)pt); // lecture des informations particulières propres à la loi entreePrinc->NouvelleDonnee(); // prepa du flot de lecture pt->LectureDonneesParticulieres(entreePrinc,lesCourbes1D,lesFonctionsnD); // si la loi est thermo dépendante on indique que la loi projection l'est aussi if (((Loi_comp_abstraite*)pt)->ThermoDependante()) this->thermo_dependant = true; // on lit le mot cle "fin_loi_interne" string mot_cle("fin_loi_interne"); if (entreePrinc->Lecture_et_verif_mot_cle(nom_class_methode,mot_cle)) entreePrinc->NouvelleDonnee(); // on se positionne sur un nouvel enreg }; // --- lecture éventuelle des paramètres de réglage ---- cas_calcul = 0; // par défaut if(strstr(entreePrinc->tablcar,"avec_parametres_de_reglage_")!=0) {string nom; entreePrinc->NouvelleDonnee(); // on se positionne sur un nouvel enreg // on lit tant que l'on ne rencontre pas la ligne contenant "fin_parametres_reglage_" // ou un nouveau mot clé global auquel cas il y a pb !! MotCle motCle; // ref aux mots cle while (strstr(entreePrinc->tablcar,"fin_parametres_reglage_")==0) { // si on a un mot clé global dans la ligne courante c-a-d dans tablcar --> erreur if ( motCle.SimotCle(entreePrinc->tablcar)) { cout << "\n erreur de lecture des parametre de reglage : on n'a pas trouve le mot cle " << " fin_parametres_reglage_ et par contre la ligne courante contient un mot cle global "; entreePrinc->MessageBuffer(nom_pour_erreur); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // lecture d'un mot clé *(entreePrinc->entree) >> nom; if ((entreePrinc->entree)->rdstate() == 0) {} // lecture normale #ifdef ENLINUX else if ((entreePrinc->entree)->fail()) // on a atteind la fin de la ligne et on appelle un nouvel enregistrement { entreePrinc->NouvelleDonnee(); // lecture d'un nouvelle enregistrement *(entreePrinc->entree) >>nom; } #else else if ((entreePrinc->entree)->eof()) // la lecture est bonne mais on a atteind la fin de la ligne { if(nom != "fin_parametres_reglage_") {entreePrinc->NouvelleDonnee(); *(entreePrinc->entree) >> nom;}; } #endif else // cas d'une erreur de lecture { cout << "\n erreur de lecture inconnue "; entreePrinc->MessageBuffer("** erreur4 des parametres de reglage de la loi de comportement de Projection_anisotrope_3D **"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // type de transport if (nom == "type_transport_") { // lecture du type *(entreePrinc->entree) >> type_transport; if ((type_transport!=0)&&(type_transport!=1)) { cout << "\n le type de transport lue pour la loi de Projection_anisotrope_3D: "<< type_transport << " n'est pas acceptable (uniquement 0 ou 1), on utilise le type par defaut (0)" << " qui correspond a un transport de type contravariant "; type_transport = 0; }; } // forcer un affichage particulier pour les méthodes else if (nom == "permet_affichage_") {Lecture_permet_affichage(entreePrinc,lesFonctionsnD); } // lecture du ratio mini du module de compressibilité else if (nom == "ratio_inf_module_compressibilite_") {*(entreePrinc->entree) >> ratio_inf_module_compressibilite; } // on regarde si le calcul est éventuellement uniquement déviatorique else if (nom == "seule_deviatorique") {if (cas_calcul == 2) {cas_calcul=0;} else {cas_calcul = 1;};} // idem pour la partie sphérique else if (nom == "seule_spherique") {if (cas_calcul == 1) {cas_calcul=0;} else {cas_calcul = 2;};} // forcer un stockage pour des sorties else if (nom == "sortie_post_") {*(entreePrinc->entree) >> sortie_post; } // sinon ce n'est pas un mot clé connu, on le signale else if (nom != "fin_parametres_reglage_") { cout << "\n erreur en lecture d'un parametre, le mot cle est inconnu " << " on a lu : " << nom << endl; if (ParaGlob::NiveauImpression()>3) cout << "\n Projection_anisotrope_3D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } }; //-- fin du while }; //-- fin de la lecture des paramètres de réglage // --- appel au niveau de la classe mère --- Loi_comp_abstraite::Lecture_type_deformation_et_niveau_commentaire (*entreePrinc,lesFonctionsnD); { string mot_cle("fin_loi_projection_anisotrope"); if (entreePrinc->Lecture_et_verif_mot_cle(nom_class_methode,mot_cle)) entreePrinc->NouvelleDonnee(); // on se positionne sur un nouvel enreg }; // //----- debug --- // cout << "\n debug Projection_anisotrope_3D::LectureDonneesParticulieres "; // this->Affiche(); // //--- fin debug --- }; // affichage de la loi void Projection_anisotrope_3D::Affiche() const { cout << "\n ....... loi de comportement Projection anisotrope 3D ........"; // pour faire une boucle on constitue un tableau de mots clés Tableau tab_mot_cle(6); tab_mot_cle(1) = "A1";tab_mot_cle(2) = "A2";tab_mot_cle(3) = "A3"; tab_mot_cle(4) = "B12";tab_mot_cle(5) = "B13";tab_mot_cle(6) = "B23"; // puis un tableau pour les valeurs Tableau < const double * > coef(6); coef(1) = &A1; coef(2) = & A2; coef(3) = &A3; coef(4) = & B12; coef(5) = & B13; coef(6) = & B23; // on boucle sur les 6 coefficients for (int i=1;i<=6;i++) {string mot_cle1=tab_mot_cle(i)+"= "; string mot_cle2=tab_mot_cle(i)+"_fonction_nD:"; cout << mot_cle1 ; if (fct_para(i) == NULL) cout << *coef(i) << " "; else {cout << mot_cle2 << " "; if (fct_para(i)->NomFonction() != "_") cout << fct_para(i)->NomFonction(); else fct_para(i)->Affiche(); cout << "\n"; }; }; // le nom du repère associé cout << "\n nom_repere_associe " << nom_repere; cout << "\n ratio_inf_module_compressibilite_ "< tab_mot_cle(6); tab_mot_cle(1) = "A1";tab_mot_cle(2) = "A2";tab_mot_cle(3) = "A3"; tab_mot_cle(4) = "B12";tab_mot_cle(5) = "B13";tab_mot_cle(6) = "B23"; // puis un tableau pour les valeurs Tableau < double * > coef(6); coef(1) = &A1; coef(2) = & A2; coef(3) = &A3; coef(4) = & B12; coef(5) = & B13; coef(6) = & B23; A1= 1.; A2= 2.; A3= 3.; B12= 1.; B13 = 1.; B23 = 1.; sort << "\n# ....... loi de comportement Projection anisotrope 3D ........" << "\n# on commence par indiquer le type de projection, par exemple: " << "\n# TYPE_PROJ_ANISO_ PROJ_ORTHO " << "\n# On definit ensuite les informations necessaires pour calculer" << "\n# la projection. Par exemple pour PROJ_ORTHO " << "\n# on definit les 6 coefficients diagonaux du tenseur H exprimee " << "\n# dans le repere d'anisotropie " << "\n# A1= 1. A2= 2. A3= 3. B12= 1. B13= 1. B23= 1. " << "\n# ensuite on definit le repere d'anisotropie ex: " << "\n# nom_repere_associe_ repere1 " << "\n# puis le nom de la loi 3D interne associee" << "\n# ISOELAS " << "\n# 200000 0.3 " << "\n# fin_loi_interne # --- fin def loi interne" << "\n# fin_loi_projection_anisotrope # mot cle de fin de declaration " << "\n# " ; // cas avec plus d'information if ((rep != "o") && (rep != "O" ) && (rep != "0") ) { // cas d'une loi thermo dépendante sort << "\n# .... infos complementaires ...." <<"\n# 1) Pour chaque parametre materiau, individuellement, il est possible " <<"\n# d'utiliser une fonction nD a la place d'une valeur numerique. " <<"\n# La fonction nD peut alors dependre de toutes les grandeurs disponibles " <<"\n# localement, en particulier la position, les donnees imposees par l'utilisateur " <<"\n# par exe: une temperature, ou tout ddl obtenu directement ou par interpolation " <<"\n# suivant sa disponibilite, sachant que l'on regarde d'abord si la grandeur est " <<"\n# directement disponible au point d'integration, sinon on regarde si elle est " <<"\n# disponible par interpolation. " <<"\n# Par exemple pour PROJ_ORTHO: " <<"\n# supposons que l'on veuille que A3 soit une fonction nD on ecrira: " <<"\n# soit a: " <<"\n# A3= A3_fonction_nD: un_nom_de_fonction_existant " <<"\n# soit b: " <<"\n# A3= A3_fonction_nD: un_nom_de_type_de_fonction_existant " <<"\n# suivit sur la ligne suivante de la definition specifique de la fonction " <<"\n# " <<"\n# exemple d'un cas a: " <<"\n# A3= A3_fonction_nD: f1_temperature " <<"\n# fi_temperature doit alors avoir ete definie dans les fonctions nD" <<"\n# " <<"\n# exemple d'un cas b: " <<"\n# A3= A3_fonction_nD: FONCTION_EXPRESSION_LITTERALE_nD " <<"\n# deb_list_var_ TEMP fin_list_var_ " <<"\n# fct= (100726-101325)/50*TEMP + 101325 " <<"\n# fin_parametres_fonction_expression_litterale_ " <<"\n# " <<"\n# Remarques: " <<"\n# a) apres chaque definition d'une fonction nD on change de ligne " <<"\n# b) pour les autres coefficients, on remplace A3 par A1, ou A2, ou" <<"\n# B12 ou B13 ou B23 " <<"\n# " <<"\n# =====================================================================" <<"\n# Apres avoir defini les parametres de la loi, il est possible de preciser et/ou modifier" <<"\n# le fonctionnement de la loi via des parametres de reglage qui sont encapsules entre les 2 mots" <<"\n# clef: avec_parametres_de_reglage_ et fin_parametres_reglage_" <<"\n# le premier se situe sur la fin de la ligne definissant les para de la loi, le second doit" <<"\n# se situer sur une ligne seule" <<"\n# L'ordre d'apparition des parametres n'a pas d'importance, ni le fait qu'ils soient sur une" <<"\n# ou plusieurs lignes. la liste des parametres de reglage disponible et leurs significations sont" <<"\n# les suivantes: " << "\n# 2)-------------- type de transport de la base d'orthotropie initiale ---------- " <<"\n# Par defaut, la base initiale d'orthotropie est transportee dans l'etat courant " <<"\n# via une methode de type transport contravariant (cf. doc) " <<"\n# Il est possible d'indiquer un transport de type covariant. Pour ce faire " <<"\n# on utilise le mot cle: type_transport_ suivi de 0 ou 1 " <<"\n# 0 : pour un transport de type contravariant (valeur par defaut) " <<"\n# 1 : pour un transport de type covariant " <<"\n# d'une maniere generale, les parametres de reglage relatifs" <<"\n# au repere d'anisotropie et a son evolution, sont indiques entre" <<"\n# le mot cle: avec_parametres_de_reglage_ qui doit se trouver " <<"\n# sur une ligne seule, apres la definition de la loi interne, " <<"\n# et le mot cle: fin_parametres_reglage_ qui doit etre sur une seule ligne" <<"\n# " <<"\n# exemple de declaration: " << "\n# fin_loi_interne # --- fin def loi interne" << "\n# avec_parametres_de_reglage_ " << "\n# sortie_post_ 1 " << "\n# type_transport_ 0 " << "\n# fin_parametres_reglage_ " <<"\n# " <<"\n# 3)" << "\n# -------------- affichage des erreurs et des warning ---------- " << "\n# - l'affichage normale est fonction du parametre global d'affichage gerer" << "\n# par le niveau d'affichage. Cependant pour des raisons par exemple de mise au point," << "\n# il est possible de permettre l'affichage local a un niveau particulier " << "\n# (mot cle : permet_affichage_ suivi d'un nombre entier) en plus de l'affichage normal. " << "\n# l'affichage s'effectuera donc en fonction de l'affichage normale et de l'affichage particulier." << "\n# Le fonctionnement de l'affichage particulier suit les mêmes règles que l'affichage globale" << "\n# soit permet_affichage_ est nulle (cas par defaut), dans ce cas l'affichage est fonction du niveau global" << "\n# soit permet_affichage_ vaut n , (!= 0), dans ce cas l'affichage est fonction uniquement de n " << "\n# " << "\n# ex: permet_affichage_ 5 " << "\n# ce mot cle ainsi que le type de deformation (cf. doc) doit etre le dernier " << "\n# enregistrement de la loi avant le mot cle fin_loi_projection_anisotrope " << "\n# Remarque: la loi interne peut egalement avoir un permet_affichage_ independant " << "\n# il doit etre indique juste avant le mot cle: fin_loi_interne " << "\n# exemple de declaration avec deux niveaux differents: " << "\n# " << "\n# ISOELAS " << "\n# 200000 0.3 " << "\n# permet_affichage_ 5 # = le niveau utilise pour la loi elastique" << "\n# fin_loi_interne # --- fin def loi interne" << "\n# permet_affichage_ 3 # = le niveau utilise pour la loi de projection" << "\n# fin_loi_projection_anisotrope # mot cle de fin de declaration " << "\n# " << "\n# Remarque: de maniere equivalente, il est possible de mettre " << "\n# le mot permet_affichage_ dans la liste des parametres de reglage de la loi " <<"\n# cf. exemple plus bas " <<"\n# " <<"\n# " << "\n# 4) --------------- calcul spherique, deviatorique ou total -------" <<"\n# Il est possible de calculer que la partie spherique du tenseur de contrainte " <<"\n# ou que la partie deviatorique " <<"\n# Pour ce faire on indique a la suite des autres parametres:" <<"\n# soit le mot clef : seule_deviatorique " <<"\n# soit le mot clef : seule_spherique " <<"\n# " <<"\n# " <<"\n# " <<"\n# " << "\n# 5) --------------- calcul compressibilite -------" <<"\n# La compressibilite est calculee a partir de la variation de volume constatee" <<"\n# et de la trace du tenseur des contraintes. Lorsque la variation est trop faible " <<"\n# c'est la compressibilite initiale qui est utilisee. Lorsque la compressibilite" <<"\n# est inferieure a 1/100 de la compressibilite initiale, on considere que le calcul" <<"\n# de cette compressibilite n'est pas correcte, et on utilise la compressibilite initiale." <<"\n# Le coefficient 1/100 est arbitraire, on peut le changer avec le mot cle: " <<"\n# ratio_inf_module_compressibilite_ " <<"\n# ce qui permet de moduler la borne inferieure de la compressibilite" <<"\n# " << "\n# 6) --------------- acces en sortie a des grandeurs intermediaires de calcul -------" << "\n# A chaque resolution, il est possible de stocker: " << "\n# - le tenseur des contraintes exprime dans le repere d'anisotropie " << "\n# - les parametres de la projection: interessant s'ils varient " << "\n# par exemple pour: TYPE_PROJ_ANISO_ PROJ_ORTHO " << "\n# on aura acces aux 6 parametres A1 A2 A3 B12 B13 B23 dans cet ordre" << "\n# " << "\n# le mot cle est sortie_post_ , par defaut il vaut 0, dans ce cas aucun indicateur n'est stoke" << "\n# s'il est different de 0, on peut acceder aux grandeurs " << "\n# seules les grandeurs en cours sont disponibles, il n'y a pas de stockage sur plusieurs increment " << "\n# " <<"\n# exemple de declaration: " << "\n# fin_loi_interne # --- fin def loi interne" << "\n# avec_parametres_de_reglage_ " << "\n# sortie_post_ 1 " << "\n# type_transport_ 0 " << "\n# permet_affichage_ 3 " << "\n# fin_parametres_reglage_ " << "\n# " <<"\n# " ; }; // appel de la classe mère Loi_comp_abstraite::Info_commande_don_LoisDeComp(entreePrinc); }; // test si la loi est complete int Projection_anisotrope_3D::TestComplet() { int ret = LoiAbstraiteGeneral::TestComplet(); // pour faire une boucle on constitue un tableau de mots clés Tableau tab_mot_cle(6); tab_mot_cle(1) = "A1";tab_mot_cle(2) = "A2";tab_mot_cle(3) = "A3"; tab_mot_cle(4) = "B12";tab_mot_cle(5) = "B13";tab_mot_cle(6) = "B23"; // puis un tableau pour les valeurs Tableau < double * > coef(6); coef(1) = &A1; coef(2) = & A2; coef(3) = &A3; coef(4) = & B12; coef(5) = & B13; coef(6) = & B23; for (int i=1;i<=6;i++) if ((*coef(i) == -ConstMath::trespetit) && (fct_para(i) == NULL)) {string mot_cle1=tab_mot_cle(i)+"= "; cout << mot_cle1 << " n'est pas defini \n " ; ret = 0; }; // test du cas de calcul if ((cas_calcul < 0) || (cas_calcul > 2)) { cout << "\n l'indicateur de calcul cas_calcul= " << cas_calcul << " n'est pas correcte " << "\n ceci pour la Projection_anisotrope_3D"; ret = 0; }; // le nom du repère associé if (nom_repere.length() == 0) { cout << "\n le nom du repere assoce n'est pas defini " << "\n ceci pour la Projection_anisotrope_3D"; ret = 0; }; // info globale disponible actuellement if (!ret) { cout << "\n loi Projection_anisotrope_3D incomplete : "; Affiche(); }; // retour return ret; }; // 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 Projection_anisotrope_3D::Activation_donnees(Tableau& tabnoeud,bool dilatation,LesPtIntegMecaInterne& lesPtMecaInt) { // activation pour la loi projetée loi_interne->Activ_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 Projection_anisotrope_3D::Grandeur_particuliere (bool ,List_io& liTQ,Loi_comp_abstraite::SaveResul * saveDon,list& decal) const { // ici on est en 3D et les grandeurs sont par principe en locale, donc la variable absolue ne sert pas // on passe en revue la liste List_io::iterator itq,itqfin=liTQ.end(); list::iterator idecal=decal.begin(); for (itq=liTQ.begin();itq!=itqfin;itq++,idecal++) {TypeQuelconque& tipParticu = (*itq); // pour simplifier if (tipParticu.EnuTypeQuelconque().Nom_vide()) // veut dire que c'est un enum pur switch (tipParticu.EnuTypeQuelconque().EnumTQ()) { case REPERE_D_ANISOTROPIE: // a) ----- cas du repère d'anisotropie { SaveResulProjection_anisotrope_3D & save_resul = *((SaveResulProjection_anisotrope_3D*) saveDon); Tab_Grandeur_BaseH& tyTQ= *((Tab_Grandeur_BaseH*) (*itq).Grandeur_pointee()); // pour simplifier tyTQ(1+(*idecal))=save_resul.Op_H; (*idecal)++; break; } case EPS_TRANSPORTEE_ANISO: // ----- cas de la déformation transportée dans le repère d'anisotropie { SaveResulProjection_anisotrope_3D & save_resul = *((SaveResulProjection_anisotrope_3D*) saveDon); Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier tyTQ(1+(*idecal))= *(save_resul.eps_loc_HH); (*idecal)++; break; } case SIGMA_DANS_ANISO: // ----- cas de la contrainte calculée dans le repère d'anisotropie { SaveResulProjection_anisotrope_3D & save_resul = *((SaveResulProjection_anisotrope_3D*) saveDon); Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier tyTQ(1+(*idecal))= *(save_resul.sig_loc_HH); (*idecal)++; break; } case PARA_ORTHO: // ----- cas des paramètres de la projection { SaveResulProjection_anisotrope_3D & save_resul = *((SaveResulProjection_anisotrope_3D*) saveDon); Tab_Grandeur_Vecteur& tyTQ= *((Tab_Grandeur_Vecteur*) (*itq).Grandeur_pointee()); // pour simplifier tyTQ(1+(*idecal))= *(save_resul.para_loi); (*idecal)++; break; } default: ;// on ne fait rien }; }; }; // récupération et création de la liste de tous les grandeurs particulières // ces grandeurs sont ajoutées à la liste passées en paramètres // absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière void Projection_anisotrope_3D::ListeGrandeurs_particulieres(bool absolue,List_io& liTQ) const { // $$$ cas du repère local d'anisotropie int dim_espace = 3; {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == REPERE_D_ANISOTROPIE) { Tab_Grandeur_BaseH& tyTQ= *((Tab_Grandeur_BaseH*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {Grandeur_BaseH v_rep(dim_espace,3); Tab_Grandeur_BaseH grand5(v_rep,1); // def d'une grandeur courante TypeQuelconque typQ6(REPERE_D_ANISOTROPIE,EPS11,grand5); liTQ.push_back(typQ6); }; }; // ---- la suite dépend de l'indicateur : sortie_post if (sortie_post) { // $$$ cas de la déformation transportée dans le repère d'anisotropie {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == EPS_TRANSPORTEE_ANISO) {Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TenseurHH* tens = NevezTenseurHH(3); // un tenseur typique Tab_Grandeur_TenseurHH eps_loc_HH(*tens,1); // def d'un type quelconque représentatif TypeQuelconque typQ(EPS_TRANSPORTEE_ANISO,EPS11,eps_loc_HH); liTQ.push_back(typQ); delete tens; // car on n'en a plus besoin }; }; // $$$ cas de la contrainte calculée dans le repère d'anisotropie {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == SIGMA_DANS_ANISO) {Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TenseurHH* tens = NevezTenseurHH(3); // un tenseur typique Tab_Grandeur_TenseurHH eps_loc_HH(*tens,1); // def d'un type quelconque représentatif TypeQuelconque typQ(SIGMA_DANS_ANISO,SIG11,eps_loc_HH); liTQ.push_back(typQ); delete tens; // car on n'en a plus besoin }; }; // $$$ cas des paramètres de la loi de comportement {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == PARA_ORTHO) {Tab_Grandeur_Vecteur& tyTQ= *((Tab_Grandeur_Vecteur*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {Vecteur tens(6); // les 6 paramètres Tab_Grandeur_Vecteur gr_vec_para(tens,1); // def d'un type quelconque représentatif TypeQuelconque typQ(PARA_ORTHO,EPS11,gr_vec_para); liTQ.push_back(typQ); }; }; }; // fin du cas ou sortie_post est actif, c-a-d que l'on veut des infos sur les indicateurs // de résolution }; // 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 Projection_anisotrope_3D::Comportement_3D_CP_DP_1D() { // si la loi interne n'est pas nulle, on ramène le cas de la loi if (loi_interne != NULL) {return (loi_interne->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 Projection_anisotrope_3D::Lecture_base_info_loi (ifstream& ent,const int cas,LesReferences& lesRef ,LesCourbes1D& lesCourbes1D ,LesFonctions_nD& lesFonctionsnD) { string toto,nom; if (cas == 1) { ent >> nom ; if (nom != "PROJECTION_ANISOTROPE_3D") {cout <<"\n *** erreur en lecture du type de la loi de comportement, on attendait" << " la chaine de caracteres: PROJECTION_ANISOTROPE_3D et on a lu " << nom <<" !!! on ne peut pas continuer " << "\n Projection_anisotrope_3D::Lecture_base_info_loi(.. " << flush; Sortie(1); }; // lecture du type de projection ent >> toto >> nom; type_projection = Id_Nom_proj_aniso(nom); bool existe_fctnD=false; // pour la gestion des grandeurs locales éventuelles // pour faire une boucle on constitue un tableau de mots clés Tableau tab_mot_cle(6); tab_mot_cle(1) = "A1";tab_mot_cle(2) = "A2";tab_mot_cle(3) = "A3"; tab_mot_cle(4) = "B12";tab_mot_cle(5) = "B13";tab_mot_cle(6) = "B23"; // puis un tableau pour les valeurs Tableau < double * > coef(6); coef(1) = &A1; coef(2) = & A2; coef(3) = &A3; coef(4) = & B12; coef(5) = & B13; coef(6) = & B23; // cela va permettre de choisir entre une valeur fixe et une fonction nD for (int i=1;i<7;i++) { ent >> toto >> nom; string mot_cle2=tab_mot_cle(i)+"_fonction_nD:"; if (nom == mot_cle2) // cas d'une fonction nD {fct_para(i) = lesFonctionsnD.Lecture_pour_base_info(ent,cas,fct_para(i)); existe_fctnD = true; } else // cas d'une valeur fixe {(*coef(i)) = ChangeReel(nom);}; }; // lecture du repère associé ent >> nom >> nom_repere; // indicateur pour les calculs partielles string type_de_calcul; ent >> nom >> type_de_calcul ; if (type_de_calcul == "seul_deviatorique") {cas_calcul=1;} else if (type_de_calcul == "seul_spherique") {cas_calcul=2;} else {cas_calcul=0;} // ratio sur la compressibilité ent >> nom >> ratio_inf_module_compressibilite; // le type de transport ent >> nom >> type_transport; // le niveau d'affichage Lecture_permet_affichage(ent,cas,lesFonctionsnD); // sortie_post ent >> nom >> sortie_post; // pondération éventuelle int avec_nD=0; ent >> toto >> nom >> avec_nD; if (nom != "fct_nD") {cout <<"\n *** erreur en lecture du type de ponderation, on attendait" << " la chaine de caracteres: fct_nD et on a lu " << nom <<" !!! on ne peut pas continuer " << "\n Projection_anisotrope_3D::Lecture_base_info_loi(.. " << flush; Sortie(1); }; if (avec_nD == 1 ) {existe_fctnD=true; if (ponderation_nD_quelconque != NULL) {ponderation_nD_quelconque->Lecture_base_info(ent, cas, lesFonctionsnD); } else { ponderation_nD_quelconque = new Ponderation_TypeQuelconque(); ponderation_nD_quelconque->Lecture_base_info(ent, cas, lesFonctionsnD); }; } else {if (ponderation_nD_quelconque != NULL) {delete ponderation_nD_quelconque; ponderation_nD_quelconque=NULL; }; }; // la loi de comportement string nom_completude_calcul; ent >> toto >> nom >> nom_completude_calcul ; // lecture du nom de la loi et du type d'action if (nom_completude_calcul == "CONTRAINTE_ET_TANGENT") { completude_calcul = CONTRAINTE_ET_TANGENT;} else if (nom_completude_calcul == "CONTRAINTE_UNIQUEMENT") { completude_calcul=CONTRAINTE_UNIQUEMENT;} else if (nom_completude_calcul == "TANGENT_UNIQUEMENT") { completude_calcul = TANGENT_UNIQUEMENT;} else { cout << "\n *** erreur en lecture du type d'action a faire avec la loi, on a lue " << nom_completude_calcul << " au lieu d'un des noms suivants CONTRAINTE_ET_TANGENT CONTRAINTE_UNIQUEMENT TANGENT_UNIQUEMENT " << "\n Projection_anisotrope_3D::Lecture_base_info_loi(.. " << flush; Sortie(1); }; // definition de la loi if (loi_interne != NULL) delete loi_interne; LoiAbstraiteGeneral * pt = LesLoisDeComp::Def_loi(nom); // lecture des informations propres à la loi pt->Lecture_base_info_loi(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD); // récup de la loi loi_interne = (Loi_comp_abstraite*) pt; // s'il y a pondération avec des grandeurs locales, on va vérifier que ces grandeurs // sont dispo et on va préparer l'accès à ces grandeurs if (existe_fctnD) Verif_et_preparation_acces_grandeurs_locale(); } else {// lecture des informations propres à la loi loi_interne->Lecture_base_info_loi(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD); }; // appel de la classe mère Loi_comp_abstraite::Lecture_don_base_info(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD); }; // cas donne le niveau de sauvegarde // = 1 : on sauvegarde tout // = 2 : on sauvegarde uniquement les données variables (supposées comme telles) void Projection_anisotrope_3D::Ecriture_base_info_loi(ofstream& sort,const int cas) { if (cas == 1) { sort << " PROJECTION_ANISOTROPE_3D " ; // on indique le type de projection sort << "\n TYPE_PROJ_ANISO_ "<< Nom_proj_aniso(type_projection) << "\n" ; // pour faire une boucle on constitue un tableau de mots clés Tableau tab_mot_cle(6); tab_mot_cle(1) = "A1";tab_mot_cle(2) = "A2";tab_mot_cle(3) = "A3"; tab_mot_cle(4) = "B12";tab_mot_cle(5) = "B13";tab_mot_cle(6) = "B23"; // puis un tableau pour les valeurs Tableau < const double * > coef(6); coef(1) = &A1; coef(2) = & A2; coef(3) = &A3; coef(4) = & B12; coef(5) = & B13; coef(6) = & B23; // on boucle sur les 6 coefficients for (int i=1;i<7;i++) {string mot_cle1=tab_mot_cle(i)+"= "; string mot_cle2=tab_mot_cle(i)+"_fonction_nD:"; sort << mot_cle1 ; if (fct_para(i) == NULL) sort << *coef(i) << " "; else {sort << mot_cle2 << " "; LesFonctions_nD::Ecriture_pour_base_info(sort, cas,fct_para(i)); }; }; // le nom du repère associé sort << "\n nom_repere_associe_ "<< nom_repere; // indicateur de cas de calcul if (cas_calcul != 0) { if (cas_calcul == 1) {sort << "\n seul_deviatorique ";} else if (cas_calcul == 2) {sort << " seul_spherique ";} else {sort << " cas_de_calcul_mal_defini ";}; }; // ratio sur la compressibilité sort << "\n ratio_inf_module_compressibilite_ "<< ratio_inf_module_compressibilite; // affichage du type de transport sort << " type_transport: " << type_transport; // niveau d'affichage Affiche_niveau_affichage(sort,cas); sort << " sortie_post: "<Ecriture_base_info(sort,cas,sans_courbe); } else {sort << " ponderation: fct_nD 0 ";}; // la loi de comportement sort << "\n loi_interne: " << loi_interne->Nom_comport() << " "; switch (completude_calcul) {case CONTRAINTE_ET_TANGENT: sort << " CONTRAINTE_ET_TANGENT "; break; case CONTRAINTE_UNIQUEMENT: sort << " CONTRAINTE_UNIQUEMENT "; break; case TANGENT_UNIQUEMENT: sort << " TANGENT_UNIQUEMENT "; break; }; loi_interne->Ecriture_base_info_loi(sort,cas); sort << endl; } else {// on demande à la loi loi_interne->Ecriture_base_info_loi(sort,cas); }; // appel de la classe mère Loi_comp_abstraite::Ecriture_don_base_info(sort,cas); }; // calcul d'un module d'young équivalent à la loi pour un chargement nul double Projection_anisotrope_3D::Module_young_equivalent(Enum_dure temps,const Deformation & def,SaveResul * ) { cout << "\n *** methode non encore implante " << " Projection_anisotrope_3D::Module_young_equivalent(Enum_dure temps,const Deformation & def,SaveResul * ) " << endl; Sortie(1); return 0.; // taire le compilo /*if (!thermo_dependant) { return E;} else { temperature_tdt = def.DonneeInterpoleeScalaire(TEMP,temps); return E_temperature->Valeur(temperature_tdt); }; */ }; // récupération d'un module de compressibilité équivalent à la loi pour un chargement nul double Projection_anisotrope_3D::Module_compressibilite_equivalent(Enum_dure temps,const Deformation & def,SaveResul * av) { if (!Bll_fct_para) {cout << "\n **** petit probleme: dans le cas de fonction nd decrivant les parametres de projection " << " pour l'instant le calcul du module de compressibilite equivalent n'est pas possible " << "\n Projection_anisotrope_3D::Module_compressibilite_equivalent(... " << flush; Sortie(1); return 0.; } else { // récup du conteneur spécifique SaveResulProjection_anisotrope_3D & save_resul = *((SaveResulProjection_anisotrope_3D*) av); double compress_inter = loi_interne->Module_compressibilite_equivalent(temps, def, save_resul.SaveResul_interne); double coeff = (*hij(1,1)) + (*hij(2,2)) + (*hij(3,3)); double module_compressibilite = 1./3. * coeff * compress_inter; return module_compressibilite; }; }; // ========== codage des METHODES VIRTUELLES protegees:================ void Projection_anisotrope_3D::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 & energ_t ,double& module_compressibilite,double& module_cisaillement ,const Met_abstraite::Expli_t_tdt& ex) { #ifdef MISE_AU_POINT if (epsBB_.Dimension() != 3) { cout << "\nErreur : la dimension devrait etre 3 !\n"; cout << " Projection_anisotrope_3D::Calcul_SigmaHH\n"; Sortie(1); }; #endif bool affichage = (Permet_affichage() > 3); #ifdef MISE_AU_POINT if (affichage) {cout << "\n --- loi Projection_anisotrope_3D Calcul_SigmaHH --- "; Signature_pti_encours(cout); }; #endif const Tenseur3BB & epsBB = *((Tenseur3BB*) &epsBB_); // passage en dim 3 const Tenseur3HH & gijHH = *((Tenseur3HH*) &gijHH_); // " " " " const Tenseur3BB & gijBB = *((Tenseur3BB*) &gijBB_); // " " " " Tenseur3HH & sigHH = *((Tenseur3HH*) &sigHH_); // " " " " Tenseur3BH epsBH = epsBB * gijHH; // deformation en mixte // récup du conteneur spécifique SaveResulProjection_anisotrope_3D & save_resul = *((SaveResulProjection_anisotrope_3D*) saveResul); // --- on commence par calculer le repère d'anisotropie transporté // Op_H_i sont les coordonnées contravariantes de la nouvelle base // donc par rapport à g_i, BaseH& Op_H = save_resul.Op_H; Tableau tab_norme(3); if (type_transport == 0) // transport de type contravariant { // on calcule les coordonnées de la base O' dans la base naturelle #ifdef MISE_AU_POINT if (save_resul.O_H == NULL) {cout << "\n *** erreur, le repere d'anisotropie n'est pas defini " <<"on ne peut pas continuer " << flush ; cout << " Projection_anisotrope_3D::Calcul_SigmaHH\n"; Sortie(1); }; #endif BaseH& O_H = (*save_resul.O_H); // coordonnées en absolu de la base d'anisotropie // calcul des coordonnées alpha_a^{.i} = O_H(a) * g^i à t= 0 for (int a = 1;a < 4; a++) {CoordonneeH& inter = alpha_H.CoordoH(a); for (int i=1;i < 4;i++) inter(i)= O_H(a).ScalHH((*ex.giH_0)(i)); }; // calcule des beta_a^{.i} tel que O'_a = beta_a^{.i} \hat{g}_i donc au temps t+dt for (int a=1; a<4;a++) { // tout d'abord la base non normalisée // Op_H(a) non normé a les mêmes coordonnées alpha_a^{.j} // mais exprimés dans le repère actuel \hat \vec g_j CoordonneeH& Op_H_a = Op_H.CoordoH(a); Op_H_a = alpha_H(a); // calcul de la norme du vecteur Op_H_a double norme = sqrt(Op_H_a * gijBB * Op_H_a); tab_norme(a) = norme; // coordonnées finales Op_H_a /= norme; #ifdef MISE_AU_POINT if (affichage) {cout << "\n Op_H("< gp_i = beta_i^j * g_j // calcul des coordonnées de la déformation dans le repère O'_i #ifdef MISE_AU_POINT if (affichage) { Tenseur3BB eps_p_BB(epsBB); cout <<"\n eps_p_BB: "; eps_p_BB.Ecriture(cout); }; #endif double untiers = 1./3.; // dans le cas de fonctions nD récupération des valeurs if (!Bll_fct_para) // Tableau fct_para; // fonction nD éventuelle d'évolution des paramètres {// un tableau de travail pour les valeurs sous forme indicée Tableau < double * > coef(6); coef(1) = &A1; coef(2) = & A2; coef(3) = &A3; coef(4) = & B12; coef(5) = & B13; coef(6) = & B23; // opération de transmission de la métrique const Met_abstraite::Impli* ex_impli = NULL; const Met_abstraite::Expli_t_tdt* ex_expli_tdt = &ex; const Met_abstraite::Umat_cont* ex_expli = NULL; // on passe en revue les fonctions nD for (int i=1;i<7;i++) {if (fct_para(i) != NULL) { Fonction_nD* pt_fonct = fct_para(i); // pour simplifier // on utilise la méthode générique de loi abstraite Tableau & tab_val = Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee (pt_fonct,1 // une seule valeur attendue en retour ,ex_impli,ex_expli_tdt,ex_expli ,NULL ,NULL ,NULL ); /* // 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 = pt_fonct->Li_enu_etendu_scalaire(); List_io & li_quelc = pt_fonct->Li_equi_Quel_evolue(); bool absolue = true; // on se place systématiquement en absolu // on va utiliser la méhode Valeur_multi_interpoler_ou_calculer // pour les grandeurs strictement scalaire Tableau val_ddl_enum(Valeur_multi_interpoler_ou_calculer (absolue,TEMPS_tdt,li_enu_scal,ex_impli,ex_expli_tdt,ex_expli,NULL) ); // 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_expli,NULL); // calcul de la valeur et retour dans tab_ret Tableau & tab_val = pt_fonct->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 au parametre materiau " << i << " doit calculer un scalaire or le tableau de retour est de taille " << tab_val.Taille() << " ce n'est pas normal !\n"; cout << " Projection_anisotrope_3D::Calcul_SigmaHH\n"; Sortie(1); }; #endif */ // on récupère le premier élément du tableau uniquement (*coef(i)) = tab_val(1); }; }; }; // --- on calcule le tenseur de contrainte de référence Tenseur3HH sig_ref_HH; // def et init double compress_inter=0.; double cisaill_inter=0; // init { // passage des informations spécifique à la loi liste_des_SaveResul loi_interne->IndiqueSaveResult(save_resul.SaveResul_interne); loi_interne->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca loi_interne->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours // calcul de la contrainte résultante, if (completude_calcul != TANGENT_UNIQUEMENT) { loi_interne->Calcul_SigmaHH(*(save_resul.l_sigoHH_t),DepsBB,tab_ddl,gijBB_t,gijHH_t,giB,gi_H ,epsBB_,delta_epsBB,gijBB_,gijHH_,d_gijBB_,jacobien_0,jacobien ,*(save_resul.l_sigoHH),save_resul.l_energ,save_resul.l_energ_t ,compress_inter,cisaill_inter,ex); if ((ponderation_nD_quelconque != NULL) && (save_resul.f_ponder != 1.)) { double coef = save_resul.f_ponder; compress_inter *= coef; cisaill_inter *= coef; energ = save_resul.l_energ * coef; // update des énergies totales sig_ref_HH = coef*(*(save_resul.l_sigoHH)); // on coefficiente la contrainte } else {energ = save_resul.l_energ; // update des énergies totales sig_ref_HH = (*(save_resul.l_sigoHH)); // récup de la contrainte }; }; }; // --- on calcule la projection du tenseur de contrainte dans le repère de travail { sigHH.Inita(0.); for (int i=1;i<4;i++) for (int j=i;j<4;j++) {for (int k=1;k<4;k++) for (int l=1;l<4;l++) for (int a=1;a<4;a++)for (int b=1;b<4;b++) sigHH.Coor(i,j) += (*hij(a,b)) * beta(a,i) * beta(b,j) * gamma(a,k) * gamma(b,l) * sig_ref_HH(k,l); }; }; // dans le cas où on veut une sortie des grandeurs on sauvegarde if (sortie_post) { if (save_resul.eps_loc_HH == NULL) {save_resul.eps_loc_HH = NevezTenseurHH(3);}; if (save_resul.sig_loc_HH == NULL) {save_resul.sig_loc_HH = NevezTenseurHH(3);}; if (save_resul.para_loi == NULL ) {save_resul.para_loi = new Vecteur (6);}; // calcul des coordonnées de la déformation dans le repère O'^i // c-a-d les coordonnées dans le dual de O'_i Tenseur3BB eps_p_BB(epsBB); //cout <<"\n eps_p_BB: "; eps_p_BB.Ecriture(cout); // il faut passer en 2 fois contravariant (*save_resul.sig_loc_HH) = gijHH * eps_p_BB * gijHH; save_resul.sig_loc_HH->ChBase(gamma); // res = (gamma * res) * gamma.Transpose(); // idem pour les contraintes (*save_resul.sig_loc_HH) = sigHH; save_resul.sig_loc_HH->ChBase(gamma); // paramètres de la loi (*save_resul.para_loi)(1) = A1; (*save_resul.para_loi)(2) = A2; (*save_resul.para_loi)(3) = A3; (*save_resul.para_loi)(4) = B12; (*save_resul.para_loi)(5) = B13; (*save_resul.para_loi)(6) = B23; }; // passage dans la bonne variance Tenseur3BH sigBH = gijBB * sigHH ; double trace_sig = sigBH.Trace(); switch (cas_calcul) { case 0: // calcul normal (tous les termes) { // on ne fait rien de spécial break; } case 1: // calcul de la partie déviatorique seule { sigBH -= (untiers * trace_sig) * IdBH3; sigHH -= (untiers * trace_sig) * gijHH; break; } case 2: // calcul de la partie sphérique seule { sigBH = (untiers * trace_sig) * IdBH3; sigHH = (untiers * trace_sig) * gijHH; break; } default: { cout << "\n erreur l'indicateur cas_calcul= " << cas_calcul << " n'a pas une valeur correcte !! " << "\n Projection_anisotrope_3D::Calcul_SigmaHH (.... "; Sortie(1); } }; //----------------- debug // const Tenseur3BB & gijBB = *((Tenseur3BB*) &gijBB_tdt); // passage en dim 3 //cout << "\n epsBB="< ConstMath::petit) {module_courant = untiers * sigBH.Trace() / (log_var_vol);}; // maintenant on va essayer de faire un choix if (module_courant >= module_compressibilite_initial * ratio_inf_module_compressibilite) { module_compressibilite = module_courant;} else // cas où le module n'est pas recevable (a priori) {module_compressibilite = module_compressibilite_initial; }; // if (log_var_vol > ConstMath::petit) // {module_compressibilite = untiers * sigBH.Trace() / (log_var_vol);} // else // si la variation de volume est trop faible on passe par un cas particulier // // celui d'une variation purement volumique (cf. théorie) // {//K_{s} = \frac{1}{3} {g"}_{ab}~\left (\lambda(a,b) ~{g"}^{ab}\right ) K_{(ref)s} // // avec {g"}_{ab} et {g"}^{ab} les composantes de la métriques dans O' // // dans le cas ou la def est null // // le repère initial est orthonormé d'où un calcul très simple // double coeff = (*hij(1,1)) + (*hij(2,2)) + (*hij(3,3)); // module_compressibilite = untiers * coeff * compress_inter; // }; } else // dans le cas d'une loi purement déviatorique, le module de compressibilité = 0 (approximativement) {module_compressibilite = 0.;}; // pour la partie cisaillement if ((cas_calcul == 0) || (cas_calcul == 1)) {// on commence par calculer l'intensité du déviateur des déformations Tenseur3BH eps_barre_BH(epsBH); // init double I_eps = epsBH.Trace(); eps_barre_BH -= (untiers * I_eps) * IdBH3; double II_eps = eps_barre_BH.II(); if (II_eps > ConstMath::petit) {Tenseur3BH sig_barre_BH(sigBH); sig_barre_BH -= (untiers * trace_sig) * IdBH3; module_cisaillement = sig_barre_BH.II()/II_eps; } else // sinon c'est le cas à déformation nulle {module_cisaillement = 0.5*untiers * (B12+B13+B23) *cisaill_inter; }; } else // en purement sphérique, le module est supposé nul {module_cisaillement = 0.; }; } LibereTenseur(); }; // calcul des contraintes a t+dt et de ses variations void Projection_anisotrope_3D::Calcul_DsigmaHH_tdt (TenseurHH & sigHH_t,TenseurBB& DepsBB,DdlElement & tab_ddl ,BaseB& giB_t,TenseurBB & gijBB_t,TenseurHH & gijHH_t ,BaseB& giB_tdt,Tableau & d_giB_tdt,BaseH& giH_tdt,Tableau & d_giH_tdt ,TenseurBB & epsBB_tdt,Tableau & d_epsBB ,TenseurBB & delta_epsBB,TenseurBB & gijBB_tdt,TenseurHH & gijHH_tdt ,Tableau & d_gijBB_tdt ,Tableau & d_gijHH_tdt,double& jacobien_0,double& jacobien ,Vecteur& d_jacobien_tdt,TenseurHH& sigHH_tdt,Tableau & d_sigHH ,EnergieMeca & energ,const EnergieMeca & energ_t,double& module_compressibilite ,double& module_cisaillement ,const Met_abstraite::Impli& ex) { #ifdef MISE_AU_POINT if (epsBB_tdt.Dimension() != 3) { cout << "\nErreur : la dimension devrait etre 3 !\n"; cout << " Projection_anisotrope_3D::Calcul_DsigmaHH_tdt\n"; Sortie(1); }; if (tab_ddl.NbDdl() != d_gijBB_tdt.Taille()) { cout << "\nErreur : le nb de ddl est != de la taille de d_gijBB_tdt !\n"; cout << " Projection_anisotrope_3D::Calcul_DsigmaHH_tdt\n"; Sortie(1); }; #endif bool affichage = (Permet_affichage() > 3); #ifdef MISE_AU_POINT if (affichage) {cout << "\n --- loi Projection_anisotrope_3D Calcul_DsigmaHH_tdt --- "; Signature_pti_encours(cout); }; #endif const Tenseur3BB & epsBB = *((Tenseur3BB*) &epsBB_tdt); // passage en dim 3 const Tenseur3HH & gijHH = *((Tenseur3HH*) &gijHH_tdt); // " " " " Tenseur3HH & sigHH = *((Tenseur3HH*) &sigHH_tdt); // " " " " const Tenseur3BB & gijBB = *((Tenseur3BB*) &gijBB_tdt); // " " " " Tenseur3BH epsBH = epsBB * gijHH; // deformation en mixte Tenseur3HH epsHH = gijHH * epsBH; // en deuxfois contra int dim_tens = sigHH_tdt.Dimension(); // ici 3, mais on laisse le cas général TenseurHH* zeroHH = (NevezTenseurHH(dim_tens,0.)); // récup du conteneur spécifique SaveResulProjection_anisotrope_3D & save_resul = *((SaveResulProjection_anisotrope_3D*) saveResul); // on commence par calculer le repère d'anisotropie transporté // Op_H_i sont les coordonnées contravariantes de la nouvelle base // donc par rapport à g_i, BaseH& Op_H = save_resul.Op_H; Tableau tab_norme(3); if (type_transport == 0) // transport de type contravariant { // on calcule les coordonnées de la base O' dans la base naturelle #ifdef MISE_AU_POINT if (save_resul.O_H == NULL) {cout << "\n *** erreur, le repere d'anisotropie n'est pas defini " <<"on ne peut pas continuer " << flush ; cout << " Projection_anisotrope_3D::Calcul_DsigmaHH_tdt\n"; Sortie(1); }; #endif BaseH& O_H = (*save_resul.O_H); // coordonnées en absolu de la base d'anisotropie // calcul des coordonnées alpha_a^{.i} = O_H(a) * g^i à t= 0 for (int a = 1;a < 4; a++) {CoordonneeH& inter = alpha_H.CoordoH(a); for (int i=1;i < 4;i++) inter(i)= O_H(a).ScalHH((*ex.giH_0)(i)); #ifdef MISE_AU_POINT if (affichage) {cout << "\n O_H("< gp_i = beta_i^j * g_j // calcul des coordonnées de la déformation dans le repère O'_i #ifdef MISE_AU_POINT if (affichage) { Tenseur3BB eps_p_BB(epsBB); cout <<"\n eps_p_BB: "; eps_p_BB.Ecriture(cout); Tenseur3BB tiutiu; epsBB.BaseAbsolue(tiutiu,*(ex.giH_tdt)); cout << "\n eps en absolu :";tiutiu.Ecriture(cout); }; #endif // il faut passer en 2 fois contravariant Tenseur3HH eps_p_HH(epsHH); // init #ifdef MISE_AU_POINT if (affichage) {cout <<"\n eps_p_HH en g_i: "; eps_p_HH.Ecriture(cout); }; #endif eps_p_HH.ChBase(gamma); // res = (gamma * res) * gamma.Transpose(); #ifdef MISE_AU_POINT if (affichage) { cout <<"\n eps_p_HH en O_p: "; eps_p_HH.Ecriture(cout); cout <<"\n gijHH: "; gijHH.Ecriture(cout); Tenseur3HH toto(eps_p_HH); toto.ChBase(beta_transpose); cout << "\n retour dans la base g^i de eps^{ij} :";toto.Ecriture(cout); Tenseur3BB titi = gijBB * toto * gijBB; cout << "\n def eps_ij :";titi.Ecriture(cout); }; #endif double untiers = 1./3.; // dans le cas de fonctions nD récupération des valeurs if (!Bll_fct_para) // Tableau fct_para; // fonction nD éventuelle d'évolution des paramètres {// un tableau de travail pour les valeurs sous forme indicée Tableau < double * > coef(6); coef(1) = &A1; coef(2) = & A2; coef(3) = &A3; coef(4) = & B12; coef(5) = & B13; coef(6) = & B23; // opération de transmission de la métrique const Met_abstraite::Impli* ex_impli = &ex; const Met_abstraite::Expli_t_tdt* ex_expli_tdt = NULL; const Met_abstraite::Umat_cont* ex_expli = NULL; // on passe en revue les fonctions nD for (int i=1;i<7;i++) {if (fct_para(i) != NULL) { Fonction_nD* pt_fonct = fct_para(i); // pour simplifier // on utilise la méthode générique de loi abstraite Tableau & tab_val = Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee (pt_fonct,1 // une seule valeur attendue en retour ,ex_impli,ex_expli_tdt,ex_expli ,NULL ,NULL ,NULL ); /* // 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 = pt_fonct->Li_enu_etendu_scalaire(); List_io & li_quelc = pt_fonct->Li_equi_Quel_evolue(); bool absolue = true; // on se place systématiquement en absolu // on va utiliser la méhode Valeur_multi_interpoler_ou_calculer // pour les grandeurs strictement scalaire Tableau val_ddl_enum(Valeur_multi_interpoler_ou_calculer (absolue,TEMPS_tdt,li_enu_scal,ex_impli,ex_expli_tdt,ex_expli,NULL) ); // 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_expli,NULL); // calcul de la valeur et retour dans tab_ret Tableau & tab_val = pt_fonct->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 au parametre materiau " << i << " doit calculer un scalaire or le tableau de retour est de taille " << tab_val.Taille() << " ce n'est pas normal !\n"; cout << " Projection_anisotrope_3D::Calcul_SigmaHH\n"; Sortie(1); }; #endif */ // on récupère le premier élément du tableau uniquement (*coef(i)) = tab_val(1); }; }; }; // --- on calcule le tenseur de contrainte de référence et l'opérateur tangent ---- Tenseur3HH sig_ref_HH; // def et init double compress_inter=0.; double cisaill_inter=0; // init int taille = d_sigHH.Taille(); { // on vérifie que le tenseur de travail intermédiaire est correctement // dimensionné sinon on le modifie { if (d_sigRef_HH.Taille() == 0) { d_sigRef_HH.Change_taille(taille,NULL);} else if ( taille != d_sigRef_HH.Taille()) { int ancienne_taille = d_sigRef_HH.Taille(); d_sigRef_HH.Change_taille(taille); if (ancienne_taille < taille) for (int i=ancienne_taille+1;i<=taille;i++) d_sigRef_HH(i)=NULL; }; for (int i=1;i<=taille;i++) { // mise à zéro des tenseurs du tableau avec création si nécessaire if (d_sigRef_HH(i) == NULL) {d_sigRef_HH(i)=NevezTenseurHH(dim_tens,0.);} else if ( d_sigRef_HH(i)->Dimension() != dim_tens) { delete d_sigRef_HH(i); d_sigRef_HH(i)=NevezTenseurHH(dim_tens,0.);} else // mise à zéro simple *(d_sigRef_HH(i))= (*zeroHH); }; }; // passage des informations spécifique à la loi liste_des_SaveResul loi_interne->IndiqueSaveResult(save_resul.SaveResul_interne); loi_interne->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca loi_interne->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours // calcul de la contrainte résultante, loi_interne->Calcul_DsigmaHH_tdt(*(save_resul.l_sigoHH_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,*(save_resul.l_sigoHH),d_sigRef_HH ,save_resul.l_energ,save_resul.l_energ_t ,compress_inter,cisaill_inter ,ex); switch (completude_calcul) { case CONTRAINTE_ET_TANGENT: // cas normal {if ((ponderation_nD_quelconque != NULL) && (save_resul.f_ponder != 1.)) { double coef = save_resul.f_ponder; compress_inter *= coef; cisaill_inter *= coef; energ = save_resul.l_energ * coef; // update des énergies totales sig_ref_HH = coef*(*(save_resul.l_sigoHH)); // on coefficiente la contrainte // update de l'opérateur tangent for (int j=1;j<=taille;j++) (*d_sigRef_HH(j)) *= coef; } else {energ = save_resul.l_energ; // update des énergies totales sig_ref_HH = (*(save_resul.l_sigoHH)); // récup de la contrainte }; break; }; case CONTRAINTE_UNIQUEMENT: {if ((ponderation_nD_quelconque != NULL) && (save_resul.f_ponder != 1.)) { double coef = save_resul.f_ponder; compress_inter *= coef; cisaill_inter *= coef; energ = save_resul.l_energ * coef; // update des énergies totales sig_ref_HH = coef*(*(save_resul.l_sigoHH)); // on coefficiente la contrainte } else {energ = save_resul.l_energ; // update des énergies totales sig_ref_HH = (*(save_resul.l_sigoHH)); // récup de la contrainte }; break; }; case TANGENT_UNIQUEMENT: { // on remet à 0 l'énergie de ref car pas de prise en compte de la contrainte save_resul.l_energ.Inita(0.);energ = save_resul.l_energ; sig_ref_HH.Inita(0.);// on remet à 0 la contrainte de référence (*(save_resul.l_sigoHH)) = sig_ref_HH; // on ne tiens pas en compte du module de compressibilité ni de cisaillement module_compressibilite = module_cisaillement = 0.; if ((ponderation_nD_quelconque != NULL) && (save_resul.f_ponder != 1.)) { double coef = save_resul.f_ponder; // update de l'opérateur tangent for (int j=1;j<=taille;j++) (*d_sigRef_HH(j)) *= coef; }; // sinon rien, on utilisera l'opérateur tangent déjà calculé break; }; }; }; //----------------- debug #ifdef MISE_AU_POINT if (affichage) { const Tenseur3BB & gijBB = *((Tenseur3BB*) &gijBB_tdt); // passage en dim 3 cout << "\n epsBB="<ChBase(gamma); // res = (gamma * res) * gamma.Transpose(); // paramètres de la loi (*save_resul.para_loi)(1) = A1; (*save_resul.para_loi)(2) = A2; (*save_resul.para_loi)(3) = A3; (*save_resul.para_loi)(4) = B12; (*save_resul.para_loi)(5) = B13; (*save_resul.para_loi)(6) = B23; }; // passage dans la bonne variance Tenseur3BH sigBH = gijBB * sigHH ; double trace_sig = sigBH.Trace(); switch (cas_calcul) { case 0: // calcul normal (tous les termes) { // on ne fait rien de spécial break; } case 1: // calcul de la partie déviatorique seule { sigBH -= (untiers * trace_sig) * IdBH3; sigHH -= (untiers * trace_sig) * gijHH; break; } case 2: // calcul de la partie sphérique seule { sigBH = (untiers * trace_sig) * IdBH3; sigHH = (untiers * trace_sig) * gijHH; break; } default: { cout << "\n erreur l'indicateur cas_calcul= " << cas_calcul << " n'a pas une valeur correcte !! " << "\n Projection_anisotrope_3D::Calcul_DsigmaHH (.... "; Sortie(1); } }; #ifdef MISE_AU_POINT if (affichage) { Tenseur3HH toto; sigHH.BaseAbsolue(toto,giB_tdt); cout << "\n sighh= en absolue ";toto.Ecriture(cout); }; #endif // traitement des énergies { // on commence par calculer l'incrément de l'énergie de référence EnergieMeca delta_ener = save_resul.l_energ - save_resul.l_energ_t; // on calcule le rapport des incréments linéarisés des énergies globales double puiss_deltat = sigHH && delta_epsBB; double puiss_ref_deltat = (*(save_resul.l_sigoHH)) && delta_epsBB; double r = puiss_deltat / (puiss_ref_deltat + ConstMath::trespetit); delta_ener *= r ; // l'incrément dilaté energ = energ_t + delta_ener; // l'énergie finale }; // -- calcul des modules { // on n'utilise plus la forme linéaire, mais à la place la variation relative de volume // constaté, au sens d'une mesure logarithmique, sauf dans le cas où cette variation est trop petite // calcul de la valeur de la variation relative de volume en log double log_var_vol = log((*(ex.jacobien_tdt))/(*(ex.jacobien_0))); // pour le module de compressibilité, choix entre les différents cas if ((cas_calcul == 0) || (cas_calcul == 2)) {// calcul du module initiale : cas particulier // celui d'une variation purement volumique (cf. théorie) //K_{s} = \frac{1}{3} {g"}_{ab}~\left (\lambda(a,b) ~{g"}^{ab}\right ) K_{(ref)s} // avec {g"}_{ab} et {g"}^{ab} les composantes de la métriques dans O' // dans le cas ou la def est null // le repère initial est orthonormé d'où un calcul très simple double coeff = (*hij(1,1)) + (*hij(2,2)) + (*hij(3,3)); double module_compressibilite_initial = untiers * coeff * compress_inter; double module_courant=module_compressibilite_initial; // init if (log_var_vol > ConstMath::petit) {module_courant = untiers * sigBH.Trace() / (log_var_vol);}; // maintenant on va essayer de faire un choix if (module_courant >= module_compressibilite_initial * ratio_inf_module_compressibilite) { module_compressibilite = module_courant;} else // cas où le module n'est pas recevable (a priori) {module_compressibilite = module_compressibilite_initial; }; // if (log_var_vol > ConstMath::petit) // {module_compressibilite = untiers * sigBH.Trace() / (log_var_vol);} // else // si la variation de volume est trop faible on passe par un cas particulier // // celui d'une variation purement volumique (cf. théorie) // {//K_{s} = \frac{1}{3} {g"}_{ab}~\left (\lambda(a,b) ~{g"}^{ab}\right ) K_{(ref)s} // // avec {g"}_{ab} et {g"}^{ab} les composantes de la métriques dans O' // // dans le cas ou la def est null // // le repère initial est orthonormé d'où un calcul très simple // double coeff = (*hij(1,1)) + (*hij(2,2)) + (*hij(3,3)); // module_compressibilite = untiers * coeff * compress_inter; // }; } else // dans le cas d'une loi purement déviatorique, le module de compressibilité = 0 (approximativement) {module_compressibilite = 0.;}; // pour la partie cisaillement if ((cas_calcul == 0) || (cas_calcul == 1)) {// on commence par calculer l'intensité du déviateur des déformations Tenseur3BH eps_barre_BH(epsBH); // init double I_eps = epsBH.Trace(); eps_barre_BH -= (untiers * I_eps) * IdBH3; double II_eps = eps_barre_BH.II(); if (II_eps > ConstMath::petit) {Tenseur3BH sig_barre_BH(sigBH); sig_barre_BH -= (untiers * trace_sig) * IdBH3; double II_sig = sig_barre_BH.II(); module_cisaillement = II_sig /II_eps; } else // sinon c'est le cas à déformation nulle {module_cisaillement = 0.5*untiers * (B12+B13+B23) *cisaill_inter; }; } else // en purement sphérique, le module est supposé nul {module_cisaillement = 0.; }; }; // cas le la variation du tenseur des contraintes int nbddl = d_gijBB_tdt.Taille(); // des tenseurs de travail Tenseur3BH d_sigBH; Tenseur3HH d_sig_HH; Tenseur3HH d_epsHH;Mat_pleine mat_d_epsHH(3,3); Vecteur d_eps_ii(3);Vecteur d_sig_ii(3); Mat_pleine d_beta(3,3);Mat_pleine d_beta_inv(3,3); Mat_pleine d_beta_transpose(3,3); Mat_pleine d_gamma(3,3); Mat_pleine mat_d_eps_p_HH(3,3); // on récupère la matrice des composantes de déformation dans O_p_a Mat_pleine mat_epsHH(3,3);epsHH.Matrice_composante(mat_epsHH); //cout << "\n mat_epsHH: ";mat_epsHH.Affiche(); for (int i = 1; i<= nbddl; i++) { // on fait uniquement une égalité d'adresse et de ne pas utiliser // le constructeur d'ou la profusion d'* et de () Tenseur3HH & dsigHH = *((Tenseur3HH*) (d_sigHH(i))); // passage en dim 3 const Tenseur3HH & dgijHH = *((Tenseur3HH*)(d_gijHH_tdt(i))) ; // pour simplifier l'ecriture const Tenseur3BB & dgijBB = *((Tenseur3BB*)(d_gijBB_tdt(i))) ; // pour simplifier l'ecriture // const Tenseur3BB & depsBB = *((Tenseur3BB *) (d_epsBB(i))); // " Tenseur3HH & dsig_ref_HH = *((Tenseur3HH*) (d_sigRef_HH(i))); // passage en dim 3 //Tableau * d_giB_tdt // BaseB & d_giB = (*ex.d_giB_tdt)(i); // BaseH & d_giH = (*ex.d_giH_tdt)(i); // on calcul la variation de matrice de passage de la base g_i vers la base O'_a // O'_a = beta_a^{.i} * g_i if (type_transport == 0) // transport de type contravariant {for (int a=1; a<4;a++) {const CoordonneeH& alpha_H_a = alpha_H.CoordoH(a); // on calcul d'abord le produit alpha_a^l * alpha_a^m * d_g_ij(l,m) double inter = 0.; for (int l =1;l<4;l++) for (int m =1;m<4;m++) inter += alpha_H_a(l) * alpha_H_a(m) * dgijBB(l,m); for (int i=1; i<4;i++) {double & d_beta_ai = d_beta(a,i); // pour simplifier // ajout des termes or boucle d_beta_ai *= - 0.5 * alpha_H_a(i) * inter / PUISSN(tab_norme(a), 3); }; }; // on calcule ensuite la variation de gamma d_beta_transpose = d_beta.Transpose(); d_gamma = - gamma * d_beta_transpose * gamma; // on calcule maintenant la variation de gamma for (int b=1;b<4;b++) for (int j=1;j<4;j++) {for (int a=1;a<4;a++) for (int i=1;i<4;i++) d_gamma(b,j) -= (gamma(a,j) * gamma(b,i)) * d_beta(a,i); }; #ifdef MISE_AU_POINT if (affichage) {cout << "\n d_beta: ";d_beta.Affiche(); cout << "\n d_beta_transpose: ";d_beta_transpose.Affiche(); cout << "\n d_gamma: ";d_gamma.Affiche(); d_gamma = -d_gamma; cout << "\n d_gamma: ";d_gamma.Affiche(); }; #endif } else {cout << "\n **** cas en attente " << "\n Projection_anisotrope_3D::Calcul_DsigmaHH_tdt (.... "<< endl; Sortie(1); }; // -- 3) calcul de la variation des contraintes dans le repère g_i // ici on utilise directement la relation de calcul de contrainte { dsigHH.Inita(0.); //cout << "\n *** debug Projection_anisotrope_3D::Calcul_DsigmaHH_tdt "; for (int i=1;i<4;i++) for (int j=i;j<4;j++) // on boucle à partir de j==i jusqu'à 3 inclus -> on ne calcul que la moitié du tenseur {double inter = 0.; for (int k=1;k<4;k++) for (int l=1;l<4;l++) for (int a=1;a<4;a++)for (int b=1;b<4;b++) inter += (*hij(a,b)) *( (d_beta(a,i) * beta(b,j) * gamma(a,k) * gamma(b,l)* sig_ref_HH(k,l)) +(beta(a,i) * d_beta(b,j) * gamma(a,k) * gamma(b,l)* sig_ref_HH(k,l)) +(beta(a,i) * beta(b,j) * d_gamma(a,k) * gamma(b,l)* sig_ref_HH(k,l)) +(beta(a,i) * beta(b,j) * gamma(a,k) * d_gamma(b,l)* sig_ref_HH(k,l)) +(beta(a,i) * beta(b,j) * gamma(a,k) * gamma(b,l)* dsig_ref_HH(k,l)) ) ; dsigHH.Coor(i,j) = inter; //if (i != j) // cout << "\n dsigHH.Coor("< 3); #ifdef MISE_AU_POINT if (affichage) {cout << "\n --- loi de comportement Projection anisotrope 3D Calcul_dsigma_deps --- "; Signature_pti_encours(cout); }; #endif const Tenseur3HH & gijHH = *((Tenseur3HH*) ex.gijHH_tdt); // " " " " const Tenseur3BB & gijBB = *((Tenseur3BB*) ex.gijBB_tdt); // " " " " const Tenseur3BB & epsBB = *((Tenseur3BB*) &epsBB_tdt); // passage en dim 3 Tenseur3HH & sigHH = *((Tenseur3HH*) &sigHH_tdt); // " " " " Tenseur3HHHH& d_sigma_deps = *((Tenseur3HHHH*) &d_sigma_deps_); Tenseur3BH epsBH = epsBB * gijHH; // deformation en mixte Tenseur3HH epsHH = gijHH * epsBH; // en deuxfois contra // int dim_tens = sigHH_tdt.Dimension(); // ici 3, mais on laisse le cas général // TenseurHH* zeroHH = (NevezTenseurHH(dim_tens,0.)); // récup du conteneur spécifique SaveResulProjection_anisotrope_3D & save_resul = *((SaveResulProjection_anisotrope_3D*) saveResul); // on commence par calculer le repère d'anisotropie transporté // Op_H_i sont les coordonnées contravariantes de la nouvelle base // donc par rapport à g_i, BaseH& Op_H = save_resul.Op_H; Tableau tab_norme(3); if (type_transport == 0) // transport de type contravariant { // on calcule les coordonnées de la base O' dans la base naturelle #ifdef MISE_AU_POINT if (save_resul.O_H == NULL) {cout << "\n *** erreur, le repere d'anisotropie n'est pas defini " <<"on ne peut pas continuer " << flush ; cout << " Projection_anisotrope_3D::Calcul_dsigma_deps\n"; Sortie(1); }; #endif BaseH& O_H = (*save_resul.O_H); // coordonnées en absolu de la base d'anisotropie // calcul des coordonnées alpha_a^{.i} = O_H(a) * g^i à t= 0 for (int a = 1;a < 4; a++) {CoordonneeH& inter = alpha_H.CoordoH(a); for (int i=1;i < 4;i++) inter(i)= O_H(a).ScalHH((*ex.giH_0)(i)); #ifdef MISE_AU_POINT if (affichage) {cout << "\n O_H("< gp_i = beta_i^j * g_j // calcul des coordonnées de la déformation dans le repère O'_i #ifdef MISE_AU_POINT if (affichage) {// Tenseur3BB eps_p_BB(epsBB); cout <<"\n eps_p_BB en g^i: "; epsBB.Ecriture(cout); Tenseur3BB tiutiu; epsBB.BaseAbsolue(tiutiu,*(ex.giH_tdt)); cout << "\n eps en absolu :";tiutiu.Ecriture(cout); }; #endif // il faut passer en 2 fois contravariant Tenseur3HH eps_p_HH(epsHH); // init #ifdef MISE_AU_POINT if (affichage) {cout <<"\n eps_p_HH en g_i: "; eps_p_HH.Ecriture(cout); }; #endif eps_p_HH.ChBase(gamma); // res = (gamma * res) * gamma.Transpose(); #ifdef MISE_AU_POINT if (affichage) {cout <<"\n eps_p_HH en O_p: "; eps_p_HH.Ecriture(cout); cout <<"\n gijHH: "; gijHH.Ecriture(cout); Tenseur3HH toto(eps_p_HH); toto.ChBase(beta_transpose); cout << "\n retour dans la base g^i de eps^{ij} :";toto.Ecriture(cout); Tenseur3BB titi(gijBB * toto * gijBB); cout << "\n def eps_ij :";titi.Ecriture(cout); }; #endif double untiers = 1./3.; // dans le cas de fonctions nD récupération des valeurs if (!Bll_fct_para) //rappel: Tableau fct_para; // fonction nD éventuelle d'évolution des paramètres {// un tableau de travail pour les valeurs sous forme indicée Tableau < double * > coef(6); coef(1) = &A1; coef(2) = & A2; coef(3) = &A3; coef(4) = & B12; coef(5) = & B13; coef(6) = & B23; // opération de transmission de la métrique const Met_abstraite::Impli* ex_impli = NULL; const Met_abstraite::Expli_t_tdt* ex_expli_tdt = NULL; const Met_abstraite::Umat_cont* ex_expli = &ex; // on passe en revue les fonctions nD for (int i=1;i<7;i++) {if (fct_para(i) != NULL) { Fonction_nD* pt_fonct = fct_para(i); // pour simplifier // on utilise la méthode générique de loi abstraite Tableau & tab_val = Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee (pt_fonct,1 // une seule valeur attendue en retour ,ex_impli,ex_expli_tdt,ex_expli ,NULL ,NULL ,NULL ); /* // 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 = pt_fonct->Li_enu_etendu_scalaire(); List_io & li_quelc = pt_fonct->Li_equi_Quel_evolue(); bool absolue = true; // on se place systématiquement en absolu // on va utiliser la méhode Valeur_multi_interpoler_ou_calculer // pour les grandeurs strictement scalaire Tableau val_ddl_enum(Valeur_multi_interpoler_ou_calculer (absolue,TEMPS_tdt,li_enu_scal,ex_impli,ex_expli_tdt,ex_expli,NULL) ); // 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_expli,NULL); // calcul de la valeur et retour dans tab_ret Tableau & tab_val = pt_fonct->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 au parametre materiau " << i << " doit calculer un scalaire or le tableau de retour est de taille " << tab_val.Taille() << " ce n'est pas normal !\n"; cout << " Projection_anisotrope_3D::Calcul_SigmaHH\n"; Sortie(1); }; #endif */ // on récupère le premier élément du tableau uniquement (*coef(i)) = tab_val(1); }; }; }; // --- on calcule le tenseur de contrainte de référence et l'opérateur tangent ---- Tenseur3HH sig_ref_HH; // def et init double compress_inter=0.; double cisaill_inter=0; // init { (save_resul.l_sigoHH)->Inita(0.); // passage des informations spécifique à la loi liste_des_SaveResul loi_interne->IndiqueSaveResult(save_resul.SaveResul_interne); loi_interne->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca loi_interne->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours // calcul de la contrainte résultante, d_sig_deps_3D_HHHH.Inita(0.); // peut-être inutile *** loi_interne->Calcul_dsigma_deps(en_base_orthonormee,*(save_resul.l_sigoHH_t),DepsBB ,epsBB_tdt,delta_epsBB,jacobien_0,jacobien ,*(save_resul.l_sigoHH),d_sig_deps_3D_HHHH ,save_resul.l_energ,save_resul.l_energ_t ,compress_inter,cisaill_inter ,ex); switch (completude_calcul) { case CONTRAINTE_ET_TANGENT: // cas normal {if ((ponderation_nD_quelconque != NULL) && (save_resul.f_ponder != 1.)) { double coef = save_resul.f_ponder; compress_inter *= coef; cisaill_inter *= coef; energ = save_resul.l_energ * coef; // update des énergies totales sig_ref_HH = coef*(*(save_resul.l_sigoHH)); // on coefficiente la contrainte // update de l'opérateur tangent d_sig_deps_3D_HHHH *= coef; } else {energ = save_resul.l_energ; // update des énergies totales sig_ref_HH = (*(save_resul.l_sigoHH)); // récup de la contrainte }; break; }; case CONTRAINTE_UNIQUEMENT: {if ((ponderation_nD_quelconque != NULL) && (save_resul.f_ponder != 1.)) { double coef = save_resul.f_ponder; compress_inter *= coef; cisaill_inter *= coef; energ = save_resul.l_energ * coef; // update des énergies totales sig_ref_HH = coef*(*(save_resul.l_sigoHH)); // on coefficiente la contrainte } else {energ = save_resul.l_energ; // update des énergies totales sig_ref_HH = (*(save_resul.l_sigoHH)); // récup de la contrainte }; break; }; case TANGENT_UNIQUEMENT: { // on remet à 0 l'énergie de ref car pas de prise en compte de la contrainte save_resul.l_energ.Inita(0.);energ = save_resul.l_energ; sig_ref_HH.Inita(0.);// on remet à 0 la contrainte de référence (*(save_resul.l_sigoHH)) = sig_ref_HH; // on ne tiens pas en compte du module de compressibilité ni de cisaillement module_compressibilite = module_cisaillement = 0.; if ((ponderation_nD_quelconque != NULL) && (save_resul.f_ponder != 1.)) { double coef = save_resul.f_ponder; // update de l'opérateur tangent d_sig_deps_3D_HHHH *= coef; }; // sinon rien, on utilisera l'opérateur tangent déjà calculé break; }; }; }; #ifdef MISE_AU_POINT if (affichage) {cout << "\n sig_refHH :";sig_ref_HH.Ecriture(cout); }; if (affichage) { cout << "\n epsBB="< 4) { Tenseur3HH toto; sigHH.BaseAbsolue(toto,(*ex.giB_tdt)); cout << "\n sighh= en absolue ";toto.Ecriture(cout); }; #endif // traitement des énergies { // on commence par calculer l'incrément de l'énergie de référence EnergieMeca delta_ener = save_resul.l_energ - save_resul.l_energ_t; // on calcule le rapport des incréments linéarisés des énergies globales double puiss_deltat = sigHH && delta_epsBB; double puiss_ref_deltat = (*(save_resul.l_sigoHH)) && delta_epsBB; double r = puiss_deltat / (puiss_ref_deltat + ConstMath::trespetit); delta_ener *= r ; // l'incrément dilaté energ = energ_t + delta_ener; // l'énergie finale }; // -- calcul des modules { // on n'utilise plus la forme linéaire, mais à la place la variation relative de volume // constaté, au sens d'une mesure logarithmique, sauf dans le cas où cette variation est trop petite // calcul de la valeur de la variation relative de volume en log double log_var_vol = log((*(ex.jacobien_tdt))/(*(ex.jacobien_0))); // pour le module de compressibilité, choix entre les différents cas if ((cas_calcul == 0) || (cas_calcul == 2)) {// calcul du module initiale : cas particulier // celui d'une variation purement volumique (cf. théorie) //K_{s} = \frac{1}{3} {g"}_{ab}~\left (\lambda(a,b) ~{g"}^{ab}\right ) K_{(ref)s} // avec {g"}_{ab} et {g"}^{ab} les composantes de la métriques dans O' // dans le cas ou la def est null // le repère initial est orthonormé d'où un calcul très simple double coeff = (*hij(1,1)) + (*hij(2,2)) + (*hij(3,3)); double module_compressibilite_initial = untiers * coeff * compress_inter; double module_courant=module_compressibilite_initial; // init if (log_var_vol > ConstMath::petit) {module_courant = untiers * sigBH.Trace() / (log_var_vol);}; // maintenant on va essayer de faire un choix if (module_courant >= module_compressibilite_initial * ratio_inf_module_compressibilite) { module_compressibilite = module_courant;} else // cas où le module n'est pas recevable (a priori) {module_compressibilite = module_compressibilite_initial; }; // if (log_var_vol > 0.01 ) //ConstMath::petit) // {module_compressibilite = untiers * sigBH.Trace() / (log_var_vol);} // else // si la variation de volume est trop faible on passe par un cas particulier // // celui d'une variation purement volumique (cf. théorie) // {//K_{s} = \frac{1}{3} {g"}_{ab}~\left (\lambda(a,b) ~{g"}^{ab}\right ) K_{(ref)s} // // avec {g"}_{ab} et {g"}^{ab} les composantes de la métriques dans O' // // dans le cas ou la def est null // // le repère initial est orthonormé d'où un calcul très simple // double coeff = (*hij(1,1)) + (*hij(2,2)) + (*hij(3,3)); // module_compressibilite = untiers * coeff * compress_inter; // }; #ifdef MISE_AU_POINT if (Permet_affichage() > 4) cout << "\n module_compressibilite= " << module_compressibilite << ", module_loi_interne= " << compress_inter << " hij(1,1)= "<< (*hij(1,1)) << " ,hij(2,2)= "<< (*hij(2,2)) << " ,hij(3,3)= "<< (*hij(3,3)) << " ,log_var_vol= "<< log_var_vol << " ,sigBH.Trace()= "<< sigBH.Trace() << flush; if (Permet_affichage() > 5) cout << "\n cas_calcul= " << cas_calcul; #endif } else // dans le cas d'une loi purement déviatorique, le module de compressibilité = 0 (approximativement) {module_compressibilite = 0.; #ifdef MISE_AU_POINT if (Permet_affichage() > 4) cout << "\n module_compressibilite= " << module_compressibilite; if (Permet_affichage() > 5) cout << "\n cas_calcul= " << cas_calcul; #endif }; // pour la partie cisaillement if ((cas_calcul == 0) || (cas_calcul == 1)) {// on commence par calculer l'intensité du déviateur des déformations Tenseur3BH eps_barre_BH(epsBH); // init double I_eps = epsBH.Trace(); eps_barre_BH -= (untiers * I_eps) * IdBH3; double II_eps = eps_barre_BH.II(); if (II_eps > ConstMath::petit) {Tenseur3BH sig_barre_BH(sigBH); sig_barre_BH -= (untiers * trace_sig) * IdBH3; module_cisaillement = sig_barre_BH.II()/II_eps; } else // sinon c'est le cas à déformation nulle {module_cisaillement = 0.5*untiers * (B12+B13+B23) *cisaill_inter; }; } else // en purement sphérique, le module est supposé nul {module_cisaillement = 0.; }; }; // ----- calcul de l'opérateur tangent ----------- // cas de la variation des beta_a^{.i} par rapport aux eps_kl // on va les stocker dans un tableau d_beta(a,i) de tenseur HH Tableau2 d_beta_HH(3,3); Tableau2 d_beta_transpose_HH(3,3); if (type_transport == 0) // transport de type contravariant { // on calcule les coordonnées de la base O' dans la base naturelle // BaseH& O_H = (*save_resul.O_H); // pour simplifier for (int a=1;a<4;a++) {// calcul de la norme du vecteur O'_a CoordonneeH alpha_H_a = alpha_H(a); double n_O_a = tab_norme(a); for (int i=1;i<4;i++) {d_beta_transpose_HH(i,a) = d_beta_HH(a,i) = -(alpha_H_a(i) /(n_O_a*n_O_a*n_O_a))*Tenseur3HH::Prod_tensoriel(alpha_H_a,alpha_H_a); }; }; }; // fin du transport 0 //**** à faire le second transport // vérif d_beta OK /* {// vérif en différence finie de d_beta for (int a=1;a<4;a++) { CoordonneeH alpha_H_a = alpha_H(a); //Tenseur3HH toto(Tenseur3HH::Prod_tensoriel(alpha_H_a,alpha_H_a)); //cout << "\n Prod_tensoriel(alpha_H_a,alpha_H_a)= "; //toto.Ecriture(cout); //Tenseur3HH titi; //for (int j=1;j<4;j++) // for (int i=1;i<4;i++) // titi.Coor(i,j) = alpha_H_a(i) * alpha_H_a(j); //cout << "\n Prod_tensoriel(alpha_H_a,alpha_H_a) numerique = "; //titi.Ecriture(cout); // calcul de la norme du vecteur O'_a double d_beta_num=0.; double n_O_a = tab_norme(a); for (int i=1;i<4;i++) {d_beta_num = d_beta_HH(a,i) && epsBB; // avec les composantes double inter=0.; for (int k=1;k<4;k++) for (int l=1;l<4;l++) inter += d_beta_HH(a,i)(k,l) * epsBB(k,l); cout << "\n delta_beta("< d_gamma_HH(3,3); for (int b=1;b<4;b++) for (int j=1;j<4;j++) {for (int a=1;a<4;a++) for (int i=1;i<4;i++) d_gamma_HH(b,j) -= (gamma(a,j) * gamma(b,i)) * d_beta_HH(a,i); }; // vérification numérique de d_gamma // a priori ok /* // on a \hat{\vec g}_j = {\gamma}_{.j}^{b}~\hat{\vec O'}_b {Mat_pleine gamma_0(3,3); Mat_pleine O_p_0_ij(3,3);Mat_pleine O_p_tdt_ij(3,3); for (int a=1;a<4;a++) {CoordonneeH alpha_H_a = alpha_H(a); const Tenseur3BB & gijBB_0 = *((Tenseur3BB*) ex.gijBB_0); CoordonneeB alpha_B_a = alpha_H_a * gijBB_0; double d_gamma_num=0.; double n_O_a = tab_norme(a); for (int i=1;i<4;i++) {d_gamma_num = d_gamma_HH(a,i) && epsBB; cout << "\n delta_gamma("<6) {cout << "\n"; e=1;} }; }; #endif // on passe au tenseur de retour //**** pour voir d_sigma_deps.TransfertDunTenseurGeneral(dsig_ijkl_HHHH.Symetrise1et2_3et4()); //d_sigma_deps.TransfertDunTenseurGeneral(dsig_ijkl_HHHH); #ifdef MISE_AU_POINT if (affichage) { cout << "\n au final: d_sigma_depsHHHH= "; d_sigma_deps.Affiche_bidim(cout); }; #endif /* //$$$$$$$$ vérif ************ { cout << "\n $$$$$$$$ vérifs intermédiaires ************ "; TenseurQ3geneHHHH dsig_ijkl_HHHH; {for (int i=1;i<4;i++) for (int j=1;j<4;j++) for (int k=1;k<4;k++) for (int l=1;l<4;l++) { double inter= 0.; for (int a=1;a<4;a++) for (int b=1;b<4;b++) for (int m=1;m<4;m++) for (int n=1;n<4;n++) inter += (*hij(a,b)) * ( + beta(a,i) * beta(b,j) * gamma(a,k) * gamma(b,l)* d_sig_deps_3D_HHHH(m,n,k,l) ); dsig_ijkl_HHHH.Change(i,j,k,l,inter); }; }; { cout << "\n avant transfert de gene en symetrique: d_sigma_depsHHHH= "; int e=1; for (int i=1;i<4;i++) for (int j=1;j<4;j++) for (int k=1;k<4;k++)for (int l=1;l<4;l++,e++) { cout << "("<6) {cout << "\n"; e=1;} }; }; // on passe au tenseur de retour Tenseur3HHHH inter_HHHH; inter_HHHH.TransfertDunTenseurGeneral(dsig_ijkl_HHHH.Symetrise1et2_3et4()); //d_sigma_deps.TransfertDunTenseurGeneral(dsig_ijkl_HHHH); if (affichage) { cout << "\n au final: d_sigma_depsHHHH= "; inter_HHHH.Affiche_bidim(cout); }; // vérif en accroissement fini / aux eps en cours Tenseur3HH delta_sig_num_HH = inter_HHHH && epsBB; cout << "\n delta_sig_num_HH "; delta_sig_num_HH.Ecriture(cout); cout << "\n sig_HH "; sigHH.Ecriture(cout); {TenseurQ3geneHHHH toto; for (int m=1;m<4;m++) for (int n=1;n<4;n++) {for (int i=1;i<4;i++) for (int j=i;j<4;j++) {double inter = 0.; for (int k=1;k<4;k++) for (int l=1;l<4;l++) for (int a=1;a<4;a++)for (int b=1;b<4;b++) inter += (*hij(a,b)) * ( ( d_beta_HH(a,i)(m,n) * beta(b,j) * gamma(a,m) * gamma(b,n) +beta(a,i) * d_beta_HH(b,j)(m,n) * gamma(a,m) * gamma(b,n) +beta(a,i) * beta(b,j) * d_gamma_HH(a,m)(m,n) * gamma(b,n) +beta(a,i) * beta(b,j) * gamma(a,m) * d_gamma_HH(b,n)(m,n) )* sig_ref_HH(k,l) + beta(a,i) * beta(b,j) * gamma(a,k) * gamma(b,l) * d_sig_deps_3D_HHHH(k,l,m,n) ); toto.Change(i,j,m,n,inter); }; }; cout << "\n autre calcul toto= "; int e=1; for (int i=1;i<4;i++) for (int j=1;j<4;j++) for (int k=1;k<4;k++)for (int l=1;l<4;l++,e++) { cout << "("<6) {cout << "\n"; e=1;} }; // on passe au tenseur de retour // --- pour voir d_sigma_deps.TransfertDunTenseurGeneral(toto.Symetrise1et2_3et4()); { cout << "\n au final à partir de toto: d_sigma_depsHHHH= "; d_sigma_deps.Affiche_bidim(cout); }; // vérif en accroissement fini / aux eps en cours Tenseur3HH delta_sig_num_HH = toto && epsBB; cout << "\n autre_delta_sig_num_HH "; delta_sig_num_HH.Ecriture(cout); cout << "\n sig_HH "; sigHH.Ecriture(cout); }; } //$$$$$$$$ fin vérif ************ */ //cout << "\n d_sigma_deps= "; //d_sigma_deps.Affiche_bidim(cout); // // d_sigma_deps = Tenseur3HHHH::Var_tenseur_dans_nouvelle_base // (beta,var_sig_ab_kl_HHHH,d_beta_HH,sigHH); // //cout << "\n (2) d_sigma_deps= "; //d_sigma_deps.Affiche_bidim(cout); // Sortie(1); LibereTenseur(); LibereTenseurQ(); }; // fonction interne utilisée par les classes dérivées de Loi_comp_abstraite // pour répercuter les modifications de la température // ici utiliser pour modifier la température des lois élémentaires // l'Enum_dure: indique quel est la température courante : 0 t ou tdt void Projection_anisotrope_3D::RepercuteChangeTemperature(Enum_dure temps) { loi_interne->temperature_0 = this->temperature_0; loi_interne->temperature_t = this->temperature_t; loi_interne->temperature_tdt = this->temperature_tdt; loi_interne->dilatation=dilatation; // on répercute également les déformations thermiques, qui ne sont utilisées // telles quelles que pour certaines lois: ex: loi hyper-élastique if (dilatation) {// a- dimensionnement des tenseurs intermédiaires int dim_tens = epsBB_therm->Dimension(); // -- cas de la déformation if (loi_interne->epsBB_therm == NULL) { loi_interne->epsBB_therm = NevezTenseurBB(dim_tens);} else if (loi_interne->epsBB_therm->Dimension() != dim_tens) { delete loi_interne->epsBB_therm;loi_interne->epsBB_therm = NevezTenseurBB(dim_tens);}; // -- cas de la vitesse de déformation if (loi_interne->DepsBB_therm == NULL) { loi_interne->DepsBB_therm = NevezTenseurBB(dim_tens);} else if (loi_interne->DepsBB_therm->Dimension() != dim_tens) { delete loi_interne->DepsBB_therm;loi_interne->DepsBB_totale = NevezTenseurBB(dim_tens);}; // b- affectation des tenseurs (*loi_interne->epsBB_therm)=(*epsBB_therm); (*loi_interne->DepsBB_therm)=(*DepsBB_therm); }; // on répercute sur les lois internes loi_interne->RepercuteChangeTemperature(temps); Loi_comp_abstraite * loi_ili = loi_interne; // pour le débug switch (temps) { case TEMPS_0: {loi_interne->temperature = &loi_interne->temperature_0; break;} case TEMPS_t: {loi_interne->temperature = &loi_interne->temperature_t; break;} case TEMPS_tdt: {loi_interne->temperature = &loi_interne->temperature_tdt; break;} default: { cout << "\n erreur, cas de temps non prevu !! " << "\n Projection_anisotrope_3D::RepercuteChangeTemperature(..."; Sortie(1); }; }; #ifdef MISE_AU_POINT if (Permet_affichage() > 7) { cout << "\n init temperatures:\n " << " loi_ili->temperature_0= " << loi_ili->temperature_0 << " loi_ili->temperature_t= " << loi_ili->temperature_t << " loi_ili->temperature_tdt= " << loi_ili->temperature_tdt << " loi_ili->temperature= " << *(loi_ili->temperature) << " \n Projection_anisotrope_3D::RepercuteChangeTemperature(.." << endl; }; #endif }; // fonction surchargée dans les classes dérivée si besoin est void Projection_anisotrope_3D::CalculGrandeurTravail (const PtIntegMecaInterne& ptintmeca ,const Deformation & def,Enum_dure temps,const ThermoDonnee& dTP ,const Met_abstraite::Impli* ex_impli ,const Met_abstraite::Expli_t_tdt* ex_expli_tdt ,const Met_abstraite::Umat_cont* ex_umat ,const List_io* exclure_dd_etend ,const List_io* exclure_Q) { // récup et enregistrement dans les variables spécifiques au point calculé SaveResulProjection_anisotrope_3D & save_resul = *((SaveResulProjection_anisotrope_3D*) saveResul); // ******* prise en compte de la pondération: pour l'instant pas effective if (ponderation_nD_quelconque != NULL) { // dans le cas où il y a une dépendance à des grandeurs locales Ponderation_TypeQuelconque& pondnD = *ponderation_nD_quelconque; list list_save; // liste inter if (save_resul.SaveResul_interne != NULL) list_save.push_back(save_resul.SaveResul_interne); // on utilise la méthode générique de loi abstraite Tableau & tab_val = Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee (pondnD.C_proport(),1 // une seule valeur attendue en retour ,ex_impli,ex_expli_tdt,ex_umat ,exclure_dd_etend ,exclure_Q ,&(list_save) ); save_resul.f_ponder = tab_val(1); // on sauvegarde }; // répercution sur la classe dérivée si besoin est {// passage des informations spécifique loi_interne->IndiqueSaveResult(save_resul.SaveResul_interne); loi_interne->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca loi_interne->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours loi_interne->CalculGrandeurTravail(ptintmeca,def,temps,dTP ,ex_impli,ex_expli_tdt,ex_umat,exclure_dd_etend,exclure_Q); }; }; // vérification et préparation de l'acces aux grandeurs locales void Projection_anisotrope_3D::Verif_et_preparation_acces_grandeurs_locale() {// 1) on demande aux lois de prendre en compte éventuellement les grandeurs locales nécessaires list listEnuQuelc; // def de la liste des grandeurs quelconque // ---récup des grandeurs quelconques nécessaires // tout d'abord au niveau de la pondération if (ponderation_nD_quelconque != NULL) {const Tableau & tab_enu_quelc = ponderation_nD_quelconque->C_proport()->Tab_enu_quelconque(); int tail = tab_enu_quelc.Taille(); if (tail) {for (int i = 1; i<= tail; i++) listEnuQuelc.push_back(tab_enu_quelc(i)); }; }; // puis au niveau des fonctions paramètres si elles existent for (int i=1;i<7;i++) {if (fct_para(i) != NULL) {// les grandeurs patentées quelconques const Tableau & ti_grandeur = fct_para(i)->Tab_enu_quelconque(); {int taille = ti_grandeur.Taille(); for (int j=1;j<=taille;j++) listEnuQuelc.push_back(ti_grandeur(j)); }; // les énum étendues const Tableau & tab_enu = fct_para(i)->Tab_enu_etendu(); {int taille = tab_enu.Taille(); for (int j=1;j<=taille;j++) {EnumTypeQuelconque enQ = Ddl_enum_etendu ::Equivalent_en_grandeur_quelconque(tab_enu(j)); if (enQ != RIEN_TYPEQUELCONQUE) {listEnuQuelc.push_back(enQ);} else { cout << "\n erreur, la grandeur " << tab_enu(j).NomGenerique() << " n'a pas d'equivalent en type quelconque " << " !! on ne peut pas continuer " << "\n Projection_anisotrope_3D::Verif_et_preparation_acces_grandeurs_locale(..."; Sortie(1); }; }; }; }; }; // nettoyage de la liste listEnuQuelc.sort(); listEnuQuelc.unique(); // -- on vérifie que la loi interne produira la grandeur quelconque // ou this list ::iterator jj,jjfin=listEnuQuelc.end(); for (jj=listEnuQuelc.begin();jj != jjfin; jj++) {bool existe = false; // par défaut pb {if (loi_interne->Existe_stockage_grandeurs_quelconques((*jj))) {existe = true; loi_interne->Activation_stockage_grandeurs_quelconques(listEnuQuelc); }; if (this->Existe_stockage_grandeurs_quelconques((*jj))) {existe = true; this->Activation_stockage_grandeurs_quelconques(listEnuQuelc); }; }; if (!existe) { cout << "\n *** erreur d'utilisation de grandeur locale " << " la grandeur "<