// FICHIER : Loi_ortho2D_C_entrainee.cc // CLASSE : Loi_ortho2D_C_entrainee // 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 "Loi_ortho2D_C_entrainee.h" #include "NevezTenseur.h" #include "MathUtil.h" #include "Util.h" #include "Enum_TypeQuelconque.h" #include "TypeQuelconqueParticulier.h" #include "TenseurQ2gene.h" #include "MathUtil.h" #include "MathUtil2.h" #include "CharUtil.h" #include "Coordonnee2.h" // ========== fonctions pour la classe de sauvegarde des résultats ========= // constructeur par défaut Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee(const int type_transport): O_B(NULL), O_H(NULL),Op_H(2,2),Op_H_t(2,2),eps_loc_HH(NULL),sig_loc_HH(NULL) ,para_loi(NULL) { }; // constructeur de copie Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee(const SaveResulLoi_ortho2D_C_entrainee& sav): O_B(NULL), O_H(NULL),Op_H(2,2),Op_H_t(2,2),eps_loc_HH(NULL),sig_loc_HH(NULL) ,para_loi(NULL) { // partie repère d'orthotropie 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); }; // destructeur Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::~SaveResulLoi_ortho2D_C_entrainee() { // partie repère d'orthotropie 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; }; // affectation Loi_comp_abstraite::SaveResul & Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::operator = ( const Loi_comp_abstraite::SaveResul & a) { Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee& sav = *((Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee*) &a); eps33=sav.eps33;eps33_t=sav.eps33_t; // partie repère d'orthotropie 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; 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 Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Lecture_base_info(ifstream& ent,const int cas) { string nom; ent >> nom ; #ifdef MISE_AU_POINT if (nom != "S_Ortho_2D_C") { cout << "\nErreur : on attendait le mot cle: S_Ortho_2D_C " << " et on a lue "<> 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; ent >> nom >> test; if (test == 0) { if (eps_loc_HH != NULL) {delete eps_loc_HH;eps_loc_HH=NULL;} if (sig_loc_HH != NULL) {delete sig_loc_HH;sig_loc_HH=NULL;} if (para_loi != NULL) {delete para_loi;para_loi=NULL;} } else // sinon cas où on a des données additionnelles { if (eps_loc_HH == NULL) eps_loc_HH = NevezTenseurHH(2); ent >> nom ; eps_loc_HH->Lecture(ent); if (sig_loc_HH == NULL) sig_loc_HH = NevezTenseurHH(2); ent >> nom ; sig_loc_HH->Lecture(ent); if (para_loi == NULL) para_loi = new Vecteur (7); 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;} if (sig_loc_HH != NULL) {delete sig_loc_HH;sig_loc_HH=NULL;} if (para_loi != NULL) {delete para_loi;para_loi=NULL;} } else // sinon cas où on a des données additionnelles { if (eps_loc_HH == NULL) eps_loc_HH = NevezTenseurHH(2); ent >> nom ; eps_loc_HH->Lecture(ent); if (sig_loc_HH == NULL) sig_loc_HH = NevezTenseurHH(2); ent >> nom ; sig_loc_HH->Lecture(ent); if (para_loi == NULL) para_loi = new Vecteur(7); ent >> nom >> *para_loi; }; break; } default: cout << "\n cas non considere !!: cas= " << cas << "\n Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::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 Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Ecriture_base_info(ofstream& sort,const int cas ) { sort << "\n S_Ortho_2D_C "; // 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 << " addi: 1 " << "\n eps_loc_HH: "; eps_loc_HH->Ecriture(sort); sort << "\n sig_loc_HH: "; sig_loc_HH->Ecriture(sort); sort << "\n para_loi: " << *para_loi << " "; } else { sort << " addi: 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: 1 "<< "\n eps_loc_HH: " ; eps_loc_HH->Ecriture(sort); sort << "\n sig_loc_HH: " ; sig_loc_HH->Ecriture(sort); sort << "\n para_loi: " << *para_loi << " "; } else { sort << "\n addi: 0 ";}; break; } default: cout << "\n cas non considere !!: cas= " << cas << "\n Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Ecriture_base_info(..."; Sortie(1); }; }; // mise à jour des informations transitoires void Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::TdtversT() { Op_H_t = Op_H; eps33_t=eps33; }; void Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::TversTdt() { Op_H = Op_H_t; eps33=eps33_t; }; // affichage à l'écran des infos void Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Affiche() const { cout << "\n SaveResulLoi_ortho2D_C_entrainee: " ; if (O_B != NULL) {cout << "\n O_B= "; O_B->Affiche(); }; if (O_H != NULL) {cout << "\n O_H= "; O_H->Affiche(); }; cout << "\n Op_H= ";Op_H.Affiche(); // les tenseurs intermédiaires if (eps_loc_HH != NULL) { cout << "\n eps_loc_HH= "; eps_loc_HH->Ecriture(cout); }; if (sig_loc_HH != NULL) { cout << "\n sig_loc_HH= "; sig_loc_HH->Ecriture(cout); }; // paramètre variables éventuelles de la loi if (para_loi != NULL) { cout << "\n para_loi: "; for (int i=1; i< 8;i++) cout << " coef("< dans un plan #ifdef MISE_AU_POINT if ((beta.Nb_colonne() != 2) || (beta.Nb_ligne() != 2)) { cout << "\nErreur : la dimension devrait etre 2 pour la matrice de changement de base = beta!" << " alors n_colonne= " << beta.Nb_colonne() << " et nb_ligne= " << beta.Nb_ligne() << " \n SaveResulLoi_ortho2D_C_entrainee::ChBase_des_grandeurs(... "; Sortie(1); }; if ((gamma.Nb_colonne() != 2) || (gamma.Nb_ligne() != 2)) { cout << "\nErreur : la dimension devrait etre 2 pour la matrice de changement de base = gamma!" << " alors n_colonne= " << gamma.Nb_colonne() << " et nb_ligne= " << gamma.Nb_ligne() << " \n SaveResulLoi_ortho2D_C_entrainee::ChBase_des_grandeurs(... "; Sortie(1); }; #endif if (O_B != NULL) {for (int i=1;i<3;i++) { CoordonneeB Ap_B(2); // 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<3;i++) { CoordonneeH Ap_H(2); // 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<3;i++) { CoordonneeH Ap_H(2); // 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);}; }; // 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* Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee ::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'orthotropie if (bloc.Nom(1) == "repere_anisotropie_") {// ensuite on vérifie le nom de l'identificateur Loi_ortho2D_C_entrainee* loiOrtho = (Loi_ortho2D_C_entrainee*) loi; // dimensionnement des bases d'orthotropie // . elles ont la dimension de l'espace: donc soit 2 soit 3 // . on utilise seulement les deux premiers vecteurs int dim = ParaGlob::Dimension(); if (loiOrtho->Type_transport() == 0) {O_H = new BaseH(dim,2); sig_loc_HH = NevezTenseurHH(2); } else {O_B = new BaseB(dim,2); eps_loc_HH = NevezTenseurHH(2); }; // récupération du repère if (bloc.Nom(2) == loiOrtho->NomRepere()) {// c'est le bon, récupération des 2 premiers vecteurs if (O_B != NULL) {for (int i=1;i<3;i++) O_B->CoordoB(i).Change_val(tab_coor(i)); }; if (O_H != NULL) {for (int i=1;i<3;i++) O_H->CoordoH(i).Change_val(tab_coor(i)); }; }; }; // return this; }; // initialise les informations de travail concernant le pas de temps en cours void Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Init_debut_calcul() { }; // ========== fin des fonctions pour la classe de sauvegarde des résultats ========= Loi_ortho2D_C_entrainee::Loi_ortho2D_C_entrainee () : // Constructeur par defaut Loi_comp_abstraite(ORTHOELA2D_C,CAT_MECANIQUE,2) ,E1(-ConstMath::trespetit),E2(-ConstMath::trespetit),E3(-ConstMath::trespetit) ,nu12(-ConstMath::trespetit),nu13(-ConstMath::trespetit),nu23(-ConstMath::trespetit) ,G12(-ConstMath::trespetit) ,fct_para(7),cas_calcul(0),type_transport(0) ,verification_convexite(1),sortie_post(0) ,nom_repere("") ,inv_loi(2,2),Op_B(2,2),d_Op_B(2,2),d_Op_H(2,2),pO_B(2,2),pO_H(2,2) ,beta_inv(2,2),beta(2,2),gamma(2,2),beta_transpose(2,2),gamma_transpose(2,2) ,alpha_H(2,2) ,I_x_I_HHHH(),I_xbarre_I_HHHH(),I_x_eps_HHHH(),Ixbarre_eps_HHHH() {for (int i=1;i< 8;i++) fct_para(i) = NULL; null_fct_para=1; // pour l'instant pas de fonction }; // Contructeur fonction de tous les paramètres constants de la loi Loi_ortho2D_C_entrainee::Loi_ortho2D_C_entrainee(const double& EE1,const double& EE2,const double& EE3 ,const double& nunu12,const double& nunu13,const double& nunu23 ,const double& GG12 ,const string& nom_rep): Loi_comp_abstraite(ORTHOELA2D_C,CAT_THERMO_MECANIQUE,2) ,E1(EE1),E2(EE2),E3(EE3),nu12(nunu12),nu13(nunu13),nu23(nunu23) ,G12(GG12) ,fct_para(7),cas_calcul(0),type_transport(0) ,verification_convexite(1),sortie_post(0) ,nom_repere(nom_rep) ,inv_loi(2,2),Op_B(2,2),d_Op_B(2,2),d_Op_H(2,2),pO_B(2,2),pO_H(2,2) ,beta_inv(2,2),beta(2,2),gamma(2,2),beta_transpose(2,2),gamma_transpose(2,2) ,alpha_H(2,2) ,I_x_I_HHHH(),I_xbarre_I_HHHH(),I_x_eps_HHHH(),Ixbarre_eps_HHHH() {for (int i=1;i< 8;i++) fct_para(i) = NULL; null_fct_para=1; // pour l'instant pas de fonction }; // Constructeur de copie Loi_ortho2D_C_entrainee::Loi_ortho2D_C_entrainee (const Loi_ortho2D_C_entrainee& loi) : Loi_comp_abstraite(loi) ,E1(loi.E1),E2(loi.E2),E3(loi.E3),nu12(loi.nu12),nu13(loi.nu13),nu23(loi.nu23) ,G12(loi.G12) ,fct_para(loi.fct_para),cas_calcul(loi.cas_calcul) ,inv_loi(loi.inv_loi),Op_B(2,2),d_Op_B(2,2),d_Op_H(2,2),pO_B(2,2),pO_H(2,2) ,beta_inv(2,2),beta(2,2),gamma(2,2),beta_transpose(2,2),gamma_transpose(2,2) ,alpha_H(2,2) ,type_transport(loi.type_transport) ,verification_convexite(loi.verification_convexite),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() {// on regarde s'il s'agit d'une courbe locale ou d'une courbe globale for (int i=1;i< 8;i++) {if (fct_para(i) != NULL) {null_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_ortho2D_C_entrainee::~Loi_ortho2D_C_entrainee () // Destructeur { for (int i=1;i< 8;i++) {if (fct_para(i) != NULL) if (fct_para(i)->NomFonction() == "_") delete fct_para(i); }; }; // Lecture des donnees de la classe sur fichier void Loi_ortho2D_C_entrainee::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D ,LesFonctions_nD& lesFonctionsnD) { // on lit les coefficients dans l'ordre string nom_class_methode("Loi_ortho2D_C_entrainee::LectureDonneesParticulieres"); double val_defaut=0.; double min = 0.; double max = -1; // max < min => la condition n'est pas prise en compte // pour faire une boucle de lecture on constitue un tableau de mots clés Tableau tab_mot_cle(7); tab_mot_cle(1) = "E1";tab_mot_cle(2) = "E2";tab_mot_cle(3) = "E3"; tab_mot_cle(4) = "nu12";tab_mot_cle(5) = "nu13";tab_mot_cle(6) = "nu23"; tab_mot_cle(7) = "G12"; // puis un tableau pour les valeurs Tableau < double * > coef(7); coef(1) = &E1; coef(2) = & E2;coef(3) = &E3; coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23; coef(7) = & G12; // on boucle sur les 7 coefficients for (int i=1;i< 8;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 if (i<4) // dans le cas des Ei, il faut qu'ils soient tous non nulles // sinon on ne peut pas calculer inv_loi { min = ConstMath::unpeupetit; max = ConstMath::grand; } else {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("**erreur en lecture** "+mot_cle1); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; } 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("**erreur en lecture** "+mot_cle2); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; null_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 != 7) entreePrinc->NouvelleDonnee(); // on se positionne sur un nouvel enreg }; }; // fin de la boucle for (int i=1;i< 7;i++) // lecture du repère d'orthotropie 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("**erreur en lecture** "+mot_cle); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // --- 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("** erreur5 des parametres de reglage de la loi de comportement de Loi_ortho2D_C_entrainee **"); 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 Loi_ortho2D_C_entrainee **"); 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 Loi_ortho2D_C_entrainee: "<< 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); } // 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;};} // cas de la vérification de la convexité else if (nom == "verification_convexite_") {*(entreePrinc->entree) >> verification_convexite; } // 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 Loi_ortho2D_C_entrainee::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); // dans le cas particulier où il n'y a pas de fonction nD on peut calculer inv_loi if (null_fct_para) {// on vérifie la convexité if (verification_convexite) Verif_convexite(); // on commence par remplir la matrice inv_loi(1,1) = 1./E1;inv_loi(2,2) = 1./E2; inv_loi(1,2) = inv_loi(2,1) = -nu12/E1; inv_loi = inv_loi.Inverse(); // on inverse la matrice }; }; // affichage de la loi void Loi_ortho2D_C_entrainee::Affiche() const { // pour faire une boucle on constitue un tableau de mots clés Tableau tab_mot_cle(7); tab_mot_cle(1) = "E1";tab_mot_cle(2) = "E2";tab_mot_cle(3) = "E3"; tab_mot_cle(4) = "nu12";tab_mot_cle(5) = "nu13";tab_mot_cle(6) = "nu23"; tab_mot_cle(7) = "G12"; // puis un tableau pour les valeurs Tableau < const double * > coef(7); coef(1) = &E1; coef(2) = & E2;coef(3) = &E3; coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23; coef(7) = & G12; // on boucle sur les 7 coefficients cout << "\n loi de comportement orthotrope elastique 2D CP "; for (int i=1;i< 8;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; // indicateur de cas de calcul if (cas_calcul != 0) { if (cas_calcul == 1) {cout << "\n calcul uniquement deviatorique ";} else if (cas_calcul == 2) {cout << " calcul uniquement spherique ";} else {cout << " cas de calcul mal defini !! ";}; }; // affichage du type de transport cout << " type_transport: " << type_transport; // niveau d'affichage cout << " niveau_affichage_local: "; Affiche_niveau_affichage(); cout << " verification_convexite: "<< verification_convexite; cout << " sortie_post: "<< sortie_post; cout << endl; // appel de la classe mère Loi_comp_abstraite::Affiche_don_classe_abstraite(); }; // affichage et definition interactive des commandes particulières à chaques lois void Loi_ortho2D_C_entrainee::Info_commande_LoisDeComp(UtilLecture& entreePrinc) {ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier cout << "\n definition standart (rep o) ou exemples exhaustifs (rep n'importe quoi) ? "; string rep = "_"; // procédure de lecture avec prise en charge d'un retour chariot rep = lect_return_defaut(true,"o"); // pour faire une boucle on constitue un tableau de mots clés Tableau tab_mot_cle(7); tab_mot_cle(1) = "E1";tab_mot_cle(2) = "E2";tab_mot_cle(3) = "E3"; tab_mot_cle(4) = "nu12";tab_mot_cle(5) = "nu13";tab_mot_cle(6) = "nu23"; tab_mot_cle(7) = "G12"; // puis un tableau pour les valeurs Tableau < double * > coef(7); coef(1) = &E1; coef(2) = & E2;coef(3) = &E3; coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23; coef(7) = & G12; E1=100000; E2= 50000;E3= 20000; nu12= 0.2; nu13 = 0.3; nu23 = 0.1; G12 = 20000; sort << "\n# ....... loi de comportement orthotrope elastique 2D contrainte plane........" << "\n# 7 parametres materiau: 3 modules, 3 coef de Poisson, 1 module de cisaillement " << "\n# et un nom de repere associe "; for (int i=1;i< 8;i++) {string mot_cle1=tab_mot_cle(i)+"= "; string mot_cle2=tab_mot_cle(i)+"_fonction_nD:"; sort << mot_cle1 << setprecision(6) << *coef(i) << " "; }; sort << "\n nom_repere_associe_ repere1 "; sort << endl; // 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# " <<"\n# Supposons que l'on veuille que E2 soit une fonction nD on ecrira: " <<"\n# soit a: " <<"\n# E2= E2_fonction_nD: un_nom_de_fonction_existant " <<"\n# soit b: " <<"\n# E2= E2_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# E2= E2_fonction_nD: f1_temperature " <<"\n# fi_temperature doit alors avoir ete definie dans les fonctions nD" <<"\n# " <<"\n# exemple d'un cas b: " <<"\n# E2= E2_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 E2 par E1, ou" <<"\n# nu12 ou nu13 ou n23 ou G12 " <<"\n# " <<"\n# 2) 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# " <<"\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 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 par exemple, dans ce cas l'affichage est fonction uniquement de n " << "\n# " << "\n# ex: permet_affichage_ 5 " << "\n# " <<"\n# " <<"\n# 4) 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# 4) Par defaut, on verifie la convexite du potentiel (cf. theorie) " <<"\n# mais le calcul ne s'arrete pas si le potentiel n'est pas convexe," <<"\n# il y a seulement un message d'erreur" <<"\n# " <<"\n# on peut supprimer cette verification a l'aide du mote cle " <<"\n# verification_convexite_ " <<"\n# suivi de 0 ou 1 (val par defaut) suivant que l'on ne veut pas de verification " <<"\n# ou le contraire " <<"\n# " << "\n# 5) --------------- 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# - le tenseur des deformation exprime dans le repere d'anisotropie " << "\n# - les parametres d'orthotropie entrainee: interessant s'ils varient " << "\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# ex: sortie_post_ 1 " << "\n# " <<"\n# " ; }; // appel de la classe mère Loi_comp_abstraite::Info_commande_don_LoisDeComp(entreePrinc); }; // test si la loi est complete int Loi_ortho2D_C_entrainee::TestComplet() { int ret = LoiAbstraiteGeneral::TestComplet(); // pour faire une boucle on constitue un tableau de mots clés Tableau tab_mot_cle(7); tab_mot_cle(1) = "E1";tab_mot_cle(2) = "E2";tab_mot_cle(3) = "E3"; tab_mot_cle(4) = "nu12";tab_mot_cle(5) = "nu13";tab_mot_cle(6) = "nu23"; tab_mot_cle(7) = "G12"; // puis un tableau pour les valeurs Tableau < double * > coef(7); coef(1) = &E1; coef(2) = & E2;coef(3) = &E3; coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23; coef(7) = & G12; for (int i=1;i< 8;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 Loi_ortho2D_C_entrainee"; 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 Loi_ortho2D_C_entrainee"; ret = 0; }; // info globale disponible actuellement if (!ret) { cout << "\n loi ortho elastique incomplete : "; Affiche(); }; // retour return ret; }; // 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 Loi_ortho2D_C_entrainee::Grandeur_particuliere (bool ,List_io& liTQ,Loi_comp_abstraite::SaveResul * saveDon,list& decal) const { // ici on est en 2D 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()) { // -----cas de la déformation d'épaisseur à t case DEF_EPAISSEUR: {SaveResulLoi_ortho2D_C_entrainee & save_resul = *((SaveResulLoi_ortho2D_C_entrainee*) saveDon);Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier tyTQ(1+(*idecal)) = save_resul.eps33; break; }; case REPERE_D_ANISOTROPIE: // a) ----- cas du repère d'anisotropie { SaveResulLoi_ortho2D_C_entrainee & save_resul = *((SaveResulLoi_ortho2D_C_entrainee*) saveDon); Tab_Grandeur_BaseH& tyTQ= *((Tab_Grandeur_BaseH*) (*itq).Grandeur_pointee()); // pour simplifier tyTQ(1+(*idecal))=save_resul.Op_H; //////----- debug //cout << "\n debug Loi_ortho2D_C_entrainee::Grandeur_particuliere(.. " // << "\n save_resul.Op_H: "<< save_resul.Op_H << "\n "; //Signature_pti_encours(cout); // //////----- fin debug (*idecal)++; break; } case EPS_TRANSPORTEE_ANISO: // ----- cas de la déformation transportée dans le repère d'orthotropie { SaveResulLoi_ortho2D_C_entrainee & save_resul = *((SaveResulLoi_ortho2D_C_entrainee*) saveDon); Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier if (sortie_post) {tyTQ(1+(*idecal))= *(save_resul.eps_loc_HH);} else {tyTQ(1+(*idecal)).Inita(0.);}; (*idecal)++; break; } case SIGMA_DANS_ANISO: // ----- cas de la contrainte calculée dans le repère d'orthotropie { SaveResulLoi_ortho2D_C_entrainee & save_resul = *((SaveResulLoi_ortho2D_C_entrainee*) saveDon); Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier if (sortie_post) {tyTQ(1+(*idecal))= *(save_resul.sig_loc_HH);} else {tyTQ(1+(*idecal)).Inita(0.);}; (*idecal)++; break; } case PARA_ORTHO: // ----- cas des paramètres d'orthotropie { SaveResulLoi_ortho2D_C_entrainee & save_resul = *((SaveResulLoi_ortho2D_C_entrainee*) saveDon); Tab_Grandeur_Vecteur& tyTQ= *((Tab_Grandeur_Vecteur*) (*itq).Grandeur_pointee()); // pour simplifier if (sortie_post) {tyTQ(1+(*idecal))= *(save_resul.para_loi);} else {tyTQ(1+(*idecal)).Zero();}; (*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 Loi_ortho2D_C_entrainee::ListeGrandeurs_particulieres(bool absolue,List_io& liTQ) const { // pour le stockage Tableau tab_double(1); Tab_Grandeur_scalaire_double grand_courant(tab_double); // $$$ cas du repère local d'orthotropie int dim_espace = ParaGlob::Dimension(); {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,2); Tab_Grandeur_BaseH grand5(v_rep,1); // def d'une grandeur courante TypeQuelconque typQ6(REPERE_D_ANISOTROPIE,EPS11,grand5); liTQ.push_back(typQ6); }; }; // -----cas de la déformation d'épaisseur à t uniquement //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == DEF_EPAISSEUR) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(DEF_EPAISSEUR,EPS11,grand_courant); liTQ.push_back(typQ1); }; }; // ---- la suite dépend de l'indicateur : sortie_post if (sortie_post) { // $$$ cas de la déformation transportée dans le repère d'orthotropie {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(2); // 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'orthotropie {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(2); // 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(7); // les 7 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 }; //----- 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 Loi_ortho2D_C_entrainee::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 != "ORTHOELA2D_C") {cout <<"\n *** erreur en lecture du type de la loi de comportement, on attendait" << " la chaine de caracteres: ORTHOELA2D_C et on a lu " << nom <<" !!! on ne peut pas continuer " << "\n Loi_ortho2D_C_entrainee::Lecture_base_info_loi(.. " << flush; Sortie(1); }; // pour faire une boucle on constitue un tableau de mots clés Tableau tab_mot_cle(7); tab_mot_cle(1) = "E1";tab_mot_cle(2) = "E2";tab_mot_cle(3) = "E3"; tab_mot_cle(4) = "nu12";tab_mot_cle(5) = "nu13";tab_mot_cle(6) = "nu23"; tab_mot_cle(7) = "G12"; // puis un tableau pour les valeurs Tableau < double * > coef(7); coef(1) = &E1; coef(2) = & E2; coef(3) = &E3; coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23; coef(7) = & G12; // cela va permettre de choisir entre une valeur fixe et une fonction nD for (int i=1;i< 8;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)); } else // cas d'une valeur fixe {(*coef(i)) = ChangeReel(nom);}; }; // lecture du repère associé ent >> nom >> nom_repere; // indicateur pour les calculs partielles ent >> nom >> cas_calcul ; // le type de transport ent >> nom >> type_transport; // le niveau d'affichage Lecture_permet_affichage(ent,cas,lesFonctionsnD); // sortie_post ent >> nom >> sortie_post; }; // appel de la classe mère Loi_comp_abstraite::Lecture_don_base_info(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD); }; // cas donne le niveau de sauvegarde // = 1 : on sauvegarde tout // = 2 : on sauvegarde uniquement les données variables (supposées comme telles) void Loi_ortho2D_C_entrainee::Ecriture_base_info_loi(ofstream& sort,const int cas) { if (cas == 1) { sort << " ORTHOELA2D_C " ; // pour faire une boucle on constitue un tableau de mots clés Tableau tab_mot_cle(7); tab_mot_cle(1) = "E1";tab_mot_cle(2) = "E2";tab_mot_cle(3) = "E3"; tab_mot_cle(4) = "nu12";tab_mot_cle(5) = "nu13";tab_mot_cle(6) = "nu23"; tab_mot_cle(7) = "G12"; // puis un tableau pour les valeurs Tableau < double * > coef(7); coef(1) = &E1; coef(2) = & E2; coef(3) = &E3; coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23; coef(7) = & G12; // on boucle sur les 7 coefficients sort << "\n loi de comportement orthotrope elastique 2D contrainte plane"; for (int i=1;i< 8;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 << " "; if (fct_para(i)->NomFonction() != "_") sort << fct_para(i)->NomFonction(); else fct_para(i)->Affiche(); sort << "\n"; }; }; // 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 ";}; }; // affichage du type de transport sort << " type_transport: " << type_transport; // niveau d'affichage Affiche_niveau_affichage(sort,cas); sort << " verification_convexite: "<< verification_convexite; sort << " sortie_post: "<Valeur(temperature_tdt); }; */ cout << "\n *** attention, methode non implante: " << "\n Loi_ortho2D_C_entrainee::Module_young_equivalent(..."; Sortie(1); }; // récupération d'un module de compressibilité équivalent à la loi pour un chargement nul // il s'agit ici de la relation -pression = sigma_trace/3. = module de compressibilité * I_eps double Loi_ortho2D_C_entrainee::Module_compressibilite_equivalent(Enum_dure temps,const Deformation & def,SaveResul * ) {/* if (!thermo_dependant) { return E/(3.*(1.-2.*nu));} else { temperature_tdt = def.DonneeInterpoleeScalaire(TEMP,temps); return E_temperature->Valeur(temperature_tdt)/(3.*(1.-2.*nu)); }; */ cout << "\n *** attention, methode non implante: " << "\n Loi_ortho2D_C_entrainee::Module_compressibilite_equivalent(..."; Sortie(1); }; // ========== codage des METHODES VIRTUELLES protegees:================ // virtual void 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) = 0; // calcul des contraintes a t+dt void Loi_ortho2D_C_entrainee::Calcul_SigmaHH (TenseurHH& sigHH_t,TenseurBB& ,DdlElement & tab_ddl ,TenseurBB & ,TenseurHH & ,BaseB& ,BaseH& ,TenseurBB& epsBB_ ,TenseurBB& ,TenseurBB& gijBB_ ,TenseurHH & gijHH_,Tableau & d_gijBB_,double& ,double& ,TenseurHH & sigHH_,EnergieMeca & energ,const EnergieMeca & ,double& module_compressibilite,double& module_cisaillement ,const Met_abstraite::Expli_t_tdt& ex) { #ifdef MISE_AU_POINT if (epsBB_.Dimension() != 2) { cout << "\nErreur : la dimension devrait etre 2 !\n"; cout << " Loi_ortho2D_C_entrainee::Calcul_SigmaHH\n"; Sortie(1); }; #endif bool affichage = (Permet_affichage() > 5); #ifdef MISE_AU_POINT if (affichage) {cout << "\n --- loi de comportement orthotrope entrainee --- "; }; #endif const Tenseur2BB & epsBB = *((Tenseur2BB*) &epsBB_); // passage en dim 2 const Tenseur2HH & gijHH = *((Tenseur2HH*) &gijHH_); // " " " " const Tenseur2BB & gijBB = *((Tenseur2BB*) &gijBB_); // " " " " Tenseur2HH & sigHH = *((Tenseur2HH*) &sigHH_); // " " " " Tenseur2BH epsBH = epsBB * gijHH; // deformation en mixte int dim = ParaGlob::Dimension(); // pour les affichages de vecteurs // récup du conteneur spécifique SaveResulLoi_ortho2D_C_entrainee & save_resul = *((SaveResulLoi_ortho2D_C_entrainee*) saveResul); // on commence par calculer le repère d'orthotropie 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(2); 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 << " Loi_ortho2D_C_entrainee::Calcul_SigmaHH\n"; Sortie(1); }; #endif BaseH& O_H = (*save_resul.O_H); // coordonnées en absolu de la base d'orthotropie // calcul des coordonnées alpha_a^{.i} = O_H(a) * g^i à t= 0 for (int a = 1;a < 3; a++) {CoordonneeH& inter = alpha_H.CoordoH(a); for (int i=1;i < 3;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<3;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) { TenseurBB* eps_p_BB = NevezTenseurBB(epsBB); cout <<"\n eps_p_BB: "; eps_p_BB->Ecriture(cout); delete eps_p_BB; }; #endif // c-a-d les coordonnées dans le dual de O'_i // il faut passer en 2 fois contravariant Tenseur2BB eps_p_BB(epsBB); //cout <<"\n eps_p_BB: "; eps_p_BB.Ecriture(cout); // il faut passer en 2 fois contravariant // on utilise l'opérateur d'affectation, car le résultat doit-être symétrique, or // les multiplications intermédiaires vont générer un tenseur systématiquement non symétrique Tenseur2HH eps_p_HH = gijHH * eps_p_BB * gijHH; eps_p_HH.ChBase(gamma); // res = (gamma * res) * gamma.Transpose(); #ifdef MISE_AU_POINT if (affichage) { cout <<"\n eps_p_HH: "; eps_p_HH.Ecriture(cout); TenseurHH* toto = NevezTenseurHH(eps_p_HH); toto->ChBase(beta_transpose); cout << "\n retour dans la base g^i de eps^{ij} :";toto->Ecriture(cout); TenseurBB* titi = NevezTenseurBB(gijBB * (*toto) * gijBB); cout << "\n def eps_ij :";titi->Ecriture(cout); delete toto; delete titi; }; #endif double untiers = 1./3.; // dans le cas de fonctions nD récupération des valeurs if (!null_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(7); coef(1) = &E1; coef(2) = & E2;coef(3) = &E3; coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23; coef(7) = & G12; // 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< 8;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 << " Loi_ortho2D_C_entrainee::Calcul_SigmaHH\n"; Sortie(1); }; #endif */ // on récupère le premier élément du tableau uniquement (*coef(i)) = tab_val(1); }; }; }; // puis fabrication de la matrice inv_loi {// on commence par remplir la matrice inv_loi(1,1) = 1./E1;inv_loi(2,2) = 1./E2; inv_loi(1,2) = inv_loi(2,1) = -nu12/E1; inv_loi = inv_loi.Inverse(); // on inverse la matrice }; // on vérifie éventuellement la convexité if (verification_convexite) Verif_convexite(); // calcul des contraintes dans le repère O_p Vecteur eps_ii(2);Vecteur sig_ii(2); for (int i=1; i<3;i++) eps_ii(i) = eps_p_HH(i,i); sig_ii = inv_loi * eps_ii; // Tenseur2HH sig_HH; for (int i=1; i<3;i++) {sigHH.Coor(i,i) = sig_ii(i); }; sigHH.Coor(1,2) = 2.* G12 * eps_p_HH(1,2); // 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(2); save_resul.sig_loc_HH = NevezTenseurHH(2); save_resul.para_loi = new Vecteur (7); }; (*save_resul.eps_loc_HH) = eps_p_HH; (*save_resul.sig_loc_HH) = sigHH; // paramètres de la loi (*save_resul.para_loi)(1) = E1; (*save_resul.para_loi)(2) = E2; (*save_resul.para_loi)(3) = E3; (*save_resul.para_loi)(4) = nu12; (*save_resul.para_loi)(5) = nu13; (*save_resul.para_loi)(6) = nu23; (*save_resul.para_loi)(7) = G12; }; // calcul des contraintes dans le repère g_i // l'inverse de gamma c'est beta transposée sigHH.ChBase(beta_transpose); // beta_inv = beta.Inverse(); // sig_BB.ChBase(beta_inv); // passage dans la bonne variance Tenseur2BH sigBH = gijBB * sigHH ; 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 { double trace_sig = sigBH.Trace(); sigBH -= (untiers * trace_sig) * IdBH2; sigHH -= (untiers * trace_sig) * gijHH; break; } case 2: // calcul de la partie sphérique seule { double trace_sig = sigBH.Trace(); sigBH = (untiers * trace_sig) * IdBH2; sigHH = (untiers * trace_sig) * gijHH; break; } default: { cout << "\n erreur l'indicateur cas_calcul= " << cas_calcul << " n'a pas une valeur correcte !! " << "\n Loi_ortho2D_C_entrainee::Calcul_SigmaHH (.... "; Sortie(1); } }; #ifdef MISE_AU_POINT if (affichage) { cout << "\n epsBB="< ConstMath::petit) {module_compressibilite = untiers * sigBH.Trace() / (log_var_vol);} else // si la variation de volume est trop faible on passe par la moyenne // des compressibilités dans les 2 directions d'orthotropie (cf. théorie) {double unsurKs1 = 1./E1 - nu12/E1 -nu13/E1; double unsurKs2 = -nu12/E1+1./E2-nu23/E2; double unsurKs3 = -nu13/E1-nu23/E2+1./E3; module_compressibilite = untiers * untiers * (1./unsurKs1+1./unsurKs2+1./unsurKs3); }; } 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 var_vol="<<((*(ex.jacobien_tdt))/(*(ex.jacobien_0))*var_epai) << " log_var_vol= " << log_var_vol << " sigBH.Trace()= " << sigBH.Trace() << " module_compressibilite= " << module_compressibilite << flush ; if (Permet_affichage() > 5) cout << "\n cas_calcul= " << cas_calcul; }; #endif // pour la partie cisaillement on garde la forme associée à la loi if ((cas_calcul == 0) || (cas_calcul == 1)) {module_cisaillement = 2. * (G12);} 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 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,Tableau & d_sigHH // ,EnergieMeca & energ,const EnergieMeca & energ_t,double& module_compressibilite,double& module_cisaillement // ,const Met_abstraite::Impli& ex); void Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt (TenseurHH& ,TenseurBB& ,DdlElement & tab_ddl ,BaseB& ,TenseurBB & ,TenseurHH & ,BaseB& ,Tableau & ,BaseH& ,Tableau & ,TenseurBB & epsBB_tdt,Tableau & d_epsBB ,TenseurBB & delta_epsBB,TenseurBB & gijBB_tdt,TenseurHH & gijHH_tdt ,Tableau & d_gijBB_tdt ,Tableau & d_gijHH_tdt,double& ,double& ,Vecteur& ,TenseurHH& sigHH_tdt,Tableau & d_sigHH ,EnergieMeca & energ,const EnergieMeca & ,double& module_compressibilite,double& module_cisaillement ,const Met_abstraite::Impli& ex) { #ifdef MISE_AU_POINT if (epsBB_tdt.Dimension() != 2) { cout << "\nErreur : la dimension devrait etre 2 !\n"; cout << " Loi_ortho2D_C_entrainee::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 << " Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt\n"; Sortie(1); }; #endif bool affichage = (Permet_affichage() > 5); #ifdef MISE_AU_POINT if (affichage) {cout << "\n --- loi de comportement orthotrope entrainee --- "; }; #endif const Tenseur2BB & epsBB = *((Tenseur2BB*) &epsBB_tdt); // passage en dim 2 const Tenseur2HH & gijHH = *((Tenseur2HH*) &gijHH_tdt); // " " " " Tenseur2HH & sigHH = *((Tenseur2HH*) &sigHH_tdt); // " " " " const Tenseur2BB & gijBB = *((Tenseur2BB*) &gijBB_tdt); // " " " " Tenseur2BH epsBH = epsBB * gijHH; // deformation en mixte Tenseur2HH epsHH = gijHH * epsBH; // en deuxfois contra int dim = ParaGlob::Dimension(); // pour les affichages de vecteurs // récup du conteneur spécifique SaveResulLoi_ortho2D_C_entrainee & save_resul = *((SaveResulLoi_ortho2D_C_entrainee*) saveResul); // on commence par calculer le repère d'orthotropie 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(2); 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 << " Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt\n"; Sortie(1); }; #endif BaseH& O_H = (*save_resul.O_H); // coordonnées en absolu de la base d'orthotropie // calcul des coordonnées alpha_a^{.i} = O_H(a) * g^i à t= 0 for (int a = 1;a < 3; a++) {CoordonneeH& inter = alpha_H.CoordoH(a); for (int i=1;i < 3;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<3;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); // pour simplifier 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) {// Tenseur2BB eps_p_BB(epsBB); cout <<"\n eps_p_BB en g^i: "; epsBB.Ecriture(cout); Tenseur2BB tiutiu; epsBB.BaseAbsolue(tiutiu,*(ex.giH_tdt)); cout << "\n eps en absolu :";tiutiu.Ecriture(cout); }; #endif // il faut passer en 2 fois contravariant Tenseur2HH 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: "; eps_p_HH.Ecriture(cout); TenseurHH* toto = NevezTenseurHH(eps_p_HH); toto->ChBase(beta_transpose); cout << "\n retour dans la base g^i de eps^{ij} :";toto->Ecriture(cout); TenseurBB* titi = NevezTenseurBB(gijBB * (*toto) * gijBB); cout << "\n def eps_ij :";titi->Ecriture(cout); delete toto; delete titi; }; #endif double untiers = 1./3.; // dans le cas de fonctions nD récupération des valeurs if (!null_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(7); coef(1) = &E1; coef(2) = & E2;coef(3) = &E3; coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23; coef(7) = & G12; // 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<8;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 << " Loi_ortho2D_C_entrainee::Calcul_DsigmaHH\n"; Sortie(1); }; #endif */ // on récupère le premier élément du tableau uniquement (*coef(i)) = tab_val(1); }; }; }; // puis fabrication de la matrice inv_loi {// on commence par remplir la matrice inv_loi(1,1) = 1./E1;inv_loi(2,2) = 1./E2; inv_loi(1,2) = inv_loi(2,1) = -nu12/E1; inv_loi = inv_loi.Inverse(); // on inverse la matrice }; // on vérifie éventuellement la convexité if (verification_convexite) Verif_convexite(); // calcul des contraintes dans le repère O_p Vecteur eps_ii(2);Vecteur sig_ii(2); for (int i=1; i<3;i++) eps_ii(i) = eps_p_HH(i,i); sig_ii = inv_loi * eps_ii; for (int i=1; i<3;i++) {sigHH.Coor(i,i) = sig_ii(i); }; sigHH.Coor(1,2) = 2.* G12 * eps_p_HH(1,2); // 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(2); save_resul.sig_loc_HH = NevezTenseurHH(2); save_resul.para_loi = new Vecteur (7); }; (*save_resul.eps_loc_HH) = eps_p_HH; (*save_resul.sig_loc_HH) = sigHH; // paramètres de la loi (*save_resul.para_loi)(1) = E1; (*save_resul.para_loi)(2) = E2; (*save_resul.para_loi)(3) = E3; (*save_resul.para_loi)(4) = nu12; (*save_resul.para_loi)(5) = nu13; (*save_resul.para_loi)(6) = nu23; (*save_resul.para_loi)(7) = G12; }; // calcul des contraintes dans le repère g_i // l'inverse de gamma c'est beta transposée sigHH.ChBase(beta_transpose); #ifdef MISE_AU_POINT if (affichage) {cout << "\n sig_ijHH complet :";sigHH.Ecriture(cout); Tenseur2HH tutu; sigHH.BaseAbsolue(tutu,*(ex.giB_tdt)); cout << "\n sig en absolu :";tutu.Ecriture(cout); }; #endif // passage dans la bonne variance Tenseur2BH sigBH = gijBB * sigHH ; 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 { double trace_sig = sigBH.Trace(); sigBH -= (untiers * trace_sig) * IdBH2; sigHH -= (untiers * trace_sig) * gijHH; break; } case 2: // calcul de la partie sphérique seule { double trace_sig = sigBH.Trace(); sigBH = (untiers * trace_sig) * IdBH2; sigHH = (untiers * trace_sig) * gijHH; break; } default: { cout << "\n erreur l'indicateur cas_calcul= " << cas_calcul << " n'a pas une valeur correcte !! " << "\n Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt (.... "; Sortie(1); } }; #ifdef MISE_AU_POINT if (affichage) { cout << "\n epsBB="< ConstMath::petit) { module_compressibilite = untiers * sigBH.Trace() / (log_var_vol); // module_compressibilite = untiers * sigBH.Trace() / // (1.- 1./((*(ex.jacobien_tdt))/(*(ex.jacobien_0))*var_epai)); } else // si la variation de volume est trop faible on passe par la moyenne // des compressibilités dans les 3 directions d'orthotropie (cf. théorie) {double unsurKs1 = 1./E1 - nu12/E1 -nu13/E1; double unsurKs2 = -nu12/E1+1./E2-nu23/E2; double unsurKs3 = -nu13/E1-nu23/E2+1./E3; module_compressibilite = untiers * untiers * (1./unsurKs1+1./unsurKs2+1./unsurKs3); }; } 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 eps33= " << save_resul.eps33 << " var_epai= " << var_epai << " var_surf= " << var_surf << "\n var_vol="<<((*(ex.jacobien_tdt))/(*(ex.jacobien_0))*var_epai) << " log_var_vol= " << log_var_vol << " sigBH.Trace()= " << sigBH.Trace() << " module_compressibilite= " << module_compressibilite << flush ; }; #endif // pour la partie cisaillement on garde la forme associée à la loi // on prend la moyenne des 3 if ((cas_calcul == 0) || (cas_calcul == 1)) {module_cisaillement = 2. * (G12);} 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 Tenseur2BH d_sigBH; Tenseur2HH d_sig_HH; Tenseur2HH d_epsHH;Mat_pleine mat_d_epsHH(2,2); Vecteur d_eps_ii(2);Vecteur d_sig_ii(2); Mat_pleine d_beta(2,2);Mat_pleine d_beta_inv(2,2); Mat_pleine d_beta_transpose(2,2); Mat_pleine d_gamma(2,2); Mat_pleine mat_d_eps_p_HH(2,2); // on récupère la matrice des composantes de déformation dans O_p_a Mat_pleine mat_epsHH(2,2);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 () Tenseur2HH & dsigHH = *((Tenseur2HH*) (d_sigHH(i))); // passage en dim 2 const Tenseur2HH & dgijHH = *((Tenseur2HH*)(d_gijHH_tdt(i))) ; // pour simplifier l'ecriture const Tenseur2BB & dgijBB = *((Tenseur2BB*)(d_gijBB_tdt(i))) ; // pour simplifier l'ecriture const Tenseur2BB & depsBB = *((Tenseur2BB *) (d_epsBB(i))); // " //Tableau * d_giB_tdt BaseB & d_giB = (*ex.d_giB_tdt)(i); BaseH & d_giH = (*ex.d_giH_tdt)(i); // pour chacun des ddl on calcul les tenseurs derivees Tenseur2BH depsBH = epsBB * dgijHH + depsBB * gijHH ; //cout <<"\n depsBH: "; depsBH.Ecriture(cout); /* // calcul des variations du repère O'_i // en fait il s'agit des variations des beta_a^{.j} 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<3;a++) { // calcul des variations du vecteur non normé CoordonneeH d_pO_H_i(3); d_pO_H_i.Zero(); // on a: Op_H(a) non normé = alpha_a^{.k} * \hat \vec g_k // d'où : d_Op_H(a) non normé = alpha_a^{.k} * d(\hat \vec g_k) for (int k=1; k<3;k++) {const CoordonneeB& d_giB_k = d_giB(k); // on change la variance car, celle-ci en fait dépend de la base // et non de gi_B, mais ici on utilise la base sous forme d'un scalaire // O_H(a)(k) et la variance est donnée par d_inter... CoordonneeH d_inter(3); d_inter.ConstructionAPartirDe_B(d_giB_k); d_pO_H_i += O_H(a)(k) * d_inter; }; // calcul de la variation du vecteur unitaire connaissant la variation du // vecteur non unitaire et la norme // d_Op_H.CoordoH(a) = Util::VarUnVect_coorH(pO_B.CoordoB(a),d_pO_H_i,tab_norme(a)); }; } else // transport de type covariant { // on calcule les coordonnées de la base O' dans la base duale BaseB& O_B = (*save_resul.O_B); // pour simplifier for (int iloc=1; iloc<3;iloc++) { // tout d'abord la base non normalisée CoordonneeH& d_pO_H_i = d_Op_H.CoordoH(iloc); d_pO_H_i.Zero(); for (int k=1; k<3;k++) {CoordonneeH d_giH_k = d_giH(k); d_pO_H_i += O_B(i)(k) * d_giH_k; }; // calcul de la variation du vecteur unitaire connaissant la variation du // vecteur non unitaire et la norme CoordonneeH interH = Util::VarUnVect_coorH(pO_H.CoordoH(iloc),d_pO_H_i,tab_norme(iloc)); }; // maintenant on calcule la base d_Op_B correspondante for (int i=1; i<3;i++) d_Op_B.CoordoB(i) = d_Op_H.CoordoH(i) * gijBB + Op_H.CoordoH(i) * dgijBB; }; */ // 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<3;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<3;l++) for (int m =1;m<3;m++) inter += alpha_H_a(l) * alpha_H_a(m) * dgijBB(l,m); for (int i=1; i<3;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(); //cout << "\n gamma: ";gamma.Affiche(); // d_gamma = (gamma * d_beta_transpose); d_gamma = - gamma * d_beta_transpose * gamma; #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 Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt (.... "<< endl; Sortie(1); }; // calcul des coordonnées de la variation de déformation dans le repère O'_i // -- 1) en coordonnees contravariantes tout d'abord variations dans g_i // epsHH = gijHH * epsBB * gijHH dans g_i d_epsHH = dgijHH * epsBB * gijHH + gijHH * depsBB * gijHH + gijHH * epsBB * dgijHH; //cout <<"\n d_epsHH: "; d_epsHH.Ecriture(cout); // -- maintenant on s'occupe du changement de base // les beta et gamma sont des matrices et non des tenseurs ... on transforme localement // en matrice d_epsHH.Matrice_composante(mat_d_epsHH); // -- calcul final de la variation de déformation dans le repère O'_i // rappel du changement de base : res = (gamma * res) * gamma.Transpose(); //cout << "\n d_gamma: ";d_gamma.Affiche(); mat_d_eps_p_HH = (d_gamma * mat_epsHH * gamma_transpose) + (gamma * mat_d_epsHH * gamma_transpose) + gamma * mat_epsHH * d_gamma.Transpose(); //cout << "\n mat_d_eps_p_HH: ";mat_d_eps_p_HH.Affiche(); // -- 2) calcul de la variation des contraintes dans le repère O_p for (int i=1; i<3;i++) d_eps_ii(i) = mat_d_eps_p_HH(i,i); // les def de la diagonale d_sig_ii = inv_loi * d_eps_ii; // les contraintes en ii for (int i=1; i<3;i++) {dsigHH.Coor(i,i) = d_sig_ii(i); // affectation des contraintes en ii }; // puis les contraintes en cisaillement dsigHH.Coor(1,2) = 2.* G12 * mat_d_eps_p_HH(1,2); //cout <<"\n dsigHH en O_p : "; dsigHH.Ecriture(cout); // -- 3) calcul de la variation des contraintes dans le repère g_i // c'est l'opération inverse et beta_transpose joue le rôle de gamma dans l'autre sens sigHH.Var_tenseur_dans_nouvelle_base(beta_transpose,dsigHH,d_beta_transpose); //cout <<"\n dsigHH en gi : "; dsigHH.Ecriture(cout); double untiers = 1./3.; 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 {// passage en mixte pour le calcul de la trace d_sigBH = dgijBB * sigHH + gijBB * dsigHH; double d_trace_sig = d_sigBH.Trace(); d_sigBH -= (untiers * d_trace_sig) * IdBH2; // passage en deux fois contravariant dsigHH = dgijHH * sigBH + gijHH * d_sigBH; break; } case 2: // calcul de la partie sphérique seule {// passage en mixte pour le calcul de la trace d_sigBH = dgijBB * sigHH + gijBB * dsigHH; double d_trace_sig = d_sigBH.Trace(); d_sigBH = (untiers * d_trace_sig) * IdBH2; // passage en deux fois contravariant dsigHH = dgijHH * sigBH + gijHH * d_sigBH; break; } default: break;//l'erreur a déjà été traitée dans le calcul de la contrainte }; ////----------------- debug // if ((i==2) || (i==5)) // {cout << "\n dsighh("< 5); #ifdef MISE_AU_POINT if (affichage) {cout << "\n --- loi de comportement orthotrope entrainee --- "; }; #endif const Tenseur2HH & gijHH = *((Tenseur2HH*) ex.gijHH_tdt); // " " " " const Tenseur2BB & gijBB = *((Tenseur2BB*) ex.gijBB_tdt); // " " " " const Tenseur2BB & epsBB = *((Tenseur2BB*) &epsBB_tdt); // passage en dim 2 Tenseur2HH & sigHH = *((Tenseur2HH*) &sigHH_tdt); // " " " " Tenseur2HHHH& d_sigma_deps = *((Tenseur2HHHH*) &d_sigma_deps_); Tenseur2BH epsBH = epsBB * gijHH; // deformation en mixte Tenseur2HH epsHH(gijHH * epsBH); // en deuxfois contra int dim = ParaGlob::Dimension(); // pour les affichages de vecteurs // récup du conteneur spécifique SaveResulLoi_ortho2D_C_entrainee & save_resul = *((SaveResulLoi_ortho2D_C_entrainee*) saveResul); // on commence par calculer le repère d'orthotropie 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(2); 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 << " Loi_ortho2D_C_entrainee::Calcul_dsigma_deps\n"; Sortie(1); }; #endif BaseH& O_H = (*save_resul.O_H); // coordonnées en absolu de la base d'orthotropie // calcul des coordonnées alpha_a^{.i} = O_H(a) * g^i à t= 0 for (int a = 1;a < 3; a++) {CoordonneeH& inter = alpha_H.CoordoH(a); for (int i=1;i < 3;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) {// Tenseur2BB eps_p_BB(epsBB); cout <<"\n eps_p_BB en g^i: "; epsBB.Ecriture(cout); Tenseur2BB tiutiu; epsBB.BaseAbsolue(tiutiu,*(ex.giH_tdt)); cout << "\n eps en absolu :";tiutiu.Ecriture(cout); }; #endif // il faut passer en 2 fois contravariant Tenseur2HH 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: "; eps_p_HH.Ecriture(cout); TenseurHH* toto = NevezTenseurHH(eps_p_HH); toto->ChBase(beta_transpose); cout << "\n retour dans la base g^i de eps^{ij} :";toto->Ecriture(cout); TenseurBB* titi = NevezTenseurBB(gijBB * (*toto) * gijBB); cout << "\n def eps_ij :";titi->Ecriture(cout); delete toto; delete titi; }; #endif double untiers = 1./3.; // dans le cas de fonctions nD récupération des valeurs if (!null_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(7); coef(1) = &E1; coef(2) = & E2;coef(3) = &E3; coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23; coef(7) = & G12; // 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<8;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 << " Loi_ortho2D_C_entrainee::Calcul_SigmaHH\n"; Sortie(1); }; #endif */ // on récupère le premier élément du tableau uniquement (*coef(i)) = tab_val(1); }; }; }; // puis fabrication de la matrice inv_loi {// on commence par remplir la matrice inv_loi(1,1) = 1./E1;inv_loi(2,2) = 1./E2; inv_loi(1,2) = inv_loi(2,1) = -nu12/E1; inv_loi = inv_loi.Inverse(); // on inverse la matrice }; // on vérifie éventuellement la convexité if (verification_convexite) Verif_convexite(); // calcul des contraintes dans le repère O_p Vecteur eps_ii(2);Vecteur sig_ii(2); for (int i=1; i<3;i++) eps_ii(i) = eps_p_HH(i,i); sig_ii = inv_loi * eps_ii; for (int i=1; i<3;i++) {sigHH.Coor(i,i) = sig_ii(i); }; sigHH.Coor(1,2) = 2.* G12 * eps_p_HH(1,2); #ifdef MISE_AU_POINT if (affichage) {cout << "\n sig_abHH :";sigHH.Ecriture(cout); }; #endif Tenseur2HH sig_ab_HH(sigHH); // 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(2); save_resul.sig_loc_HH = NevezTenseurHH(2); save_resul.para_loi = new Vecteur (7); }; (*save_resul.eps_loc_HH) = eps_p_HH; (*save_resul.sig_loc_HH) = sig_ab_HH; // paramètres de la loi (*save_resul.para_loi)(1) = E1; (*save_resul.para_loi)(2) = E2; (*save_resul.para_loi)(3) = E3; (*save_resul.para_loi)(4) = nu12; (*save_resul.para_loi)(5) = nu13; (*save_resul.para_loi)(6) = nu23; (*save_resul.para_loi)(7) = G12; }; // calcul des contraintes dans le repère g_i // l'inverse de gamma c'est beta transposée sigHH.ChBase(beta_transpose); #ifdef MISE_AU_POINT if (affichage) {cout << "\n sig_ijHH complet :";sigHH.Ecriture(cout); Tenseur2HH tutu; sigHH.BaseAbsolue(tutu,*(ex.giB_tdt)); cout << "\n sig en absolu :";tutu.Ecriture(cout); }; #endif // passage dans la variance mixte Tenseur2BH sigBH = gijBB * sigHH ; 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 { double trace_sig = sigBH.Trace(); sigBH -= (untiers * trace_sig) * IdBH2; sigHH -= (untiers * trace_sig) * gijHH; break; } case 2: // calcul de la partie sphérique seule { double trace_sig = sigBH.Trace(); sigBH = (untiers * trace_sig) * IdBH2; sigHH = (untiers * trace_sig) * gijHH; break; } default: { cout << "\n erreur l'indicateur cas_calcul= " << cas_calcul << " n'a pas une valeur correcte !! " << "\n Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt (.... "; Sortie(1); } }; #ifdef MISE_AU_POINT if (affichage) { cout << "\n epsBB="< ConstMath::petit) {module_compressibilite = untiers * sigBH.Trace() / (log_var_vol);} else // si la variation de volume est trop faible on passe par la moyenne // des compressibilités dans les 3 directions d'orthotropie (cf. théorie) {double unsurKs1 = 1./E1 - nu12/E1 -nu13/E1; double unsurKs2 = -nu12/E1+1./E2-nu23/E2; double unsurKs3 = -nu13/E1-nu23/E2+1./E3; module_compressibilite = untiers * untiers * (1./unsurKs1+1./unsurKs2+1./unsurKs3); }; } 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 var_vol="<<((*(ex.jacobien_tdt))/(*(ex.jacobien_0))*var_epai) << " log_var_vol= " << log_var_vol << " sigBH.Trace()= " << sigBH.Trace() << " module_compressibilite= " << module_compressibilite << flush ; if (Permet_affichage() > 5) cout << "\n cas_calcul= " << cas_calcul; }; #endif // pour la partie cisaillement on garde la forme associée à la loi // on prend la moyenne des 3 if ((cas_calcul == 0) || (cas_calcul == 1)) {module_cisaillement = 2. * (G12);} else // en purement sphérique, le module est supposé nul {module_cisaillement = 0.; }; // ----- calcul de l'opérateur tangent ----------- // calcul des variations de sigma / eps dans le repère transporté Tenseur2HHBB var_sig_ab_cd_HHBB; for (int i=1; i<3;i++) for (int j=1; j<3;j++) var_sig_ab_cd_HHBB.Change(i,i,j,j,inv_loi(i,j)); var_sig_ab_cd_HHBB.Change(1,2,1,2,G12); // du coup = (1,2,2,1) = (2,1,1,2) = (2,1,2,1) #ifdef MISE_AU_POINT if (affichage) {cout << "\n var_sig_ab_cd_HHBB= "; var_sig_ab_cd_HHBB.Affiche_bidim(cout); }; #endif // 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(2,2); Tableau2 d_beta_transpose_HH(2,2); 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<3;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<3;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))*Tenseur2HH::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<3;a++) { CoordonneeH alpha_H_a = alpha_H(a); //Tenseur2HH toto(Tenseur2HH::Prod_tensoriel(alpha_H_a,alpha_H_a)); //cout << "\n Prod_tensoriel(alpha_H_a,alpha_H_a)= "; //toto.Ecriture(cout); //Tenseur2HH titi; //for (int j=1;j<3;j++) // for (int i=1;i<3;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<3;i++) {d_beta_num = d_beta_HH(a,i) && epsBB; cout << "\n delta_beta("<