// FICHIER : LoiContraintesPlanesDouble.cp // CLASSE : LoiContraintesPlanesDouble // This file is part of the Herezh++ application. // // The finite element software Herezh++ is dedicated to the field // of mechanics for large transformations of solid structures. // It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600) // INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) . // // Herezh++ is distributed under GPL 3 license ou ultérieure. // // Copyright (C) 1997-2022 Université Bretagne Sud (France) // AUTHOR : Gérard Rio // E-MAIL : gerardrio56@free.fr // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, // or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // For more information, please consult: . //#include "Debug.h" #include "LesLoisDeComp.h" # include using namespace std; //introduces namespace std #include #include #include "Sortie.h" #include "TypeQuelconqueParticulier.h" #include "TypeConsTens.h" #include "NevezTenseurQ.h" #include "Util.h" #include "ExceptionsLoiComp.h" #include "MotCle.h" #include "MathUtil.h" #include "MathUtil2.h" #include "LoiContraintesPlanesDouble.h" // calcul des contraintes et ses variations par rapport aux déformations a t+dt // ceci dans le cas où l'axe de traction simple est quelconque // ici on suppose que: // - tous les calculs sont en dim 3 // - l'axe 3 est normal aux deux autres (ceci pour Vi et pour gi) // // ViB et ViH : correspond à la base de traction: les vecteurs sont identiques // par contre leurs composantes sont différentes car exprimés dans g^i et g_i // telle que \vec ViB(1) = \vec ViH(1) = l'axe de traction // La base Vi est supposée orthonormée // en_base_orthonormee: le tenseur de contrainte en entrée est en orthonormee // le tenseur de déformation et son incrémentsont également en orthonormees // si = false: les bases transmises sont utilisées // ex: contient les éléments de métrique relativement au paramétrage matériel = X_(0)^a !!** non pas tout le temps a revoir void LoiContraintesPlanesDouble::Calcul_dsigma_deps (bool en_base_orthonormee,const BaseB * ViB,const BaseH * ViH ,const TenseurHH & sigHH_t,const TenseurBB& DepsBB ,const TenseurBB & epsBB_tdt,const TenseurBB & delta_epsBB,double& jacobien_0,double& jacobien ,TenseurHH& sigHH_tdt,TenseurHHHH& d_sigma_deps ,EnergieMeca & energ,const EnergieMeca & ,double& module_compressibilite,double& module_cisaillement ,const Met_abstraite::Umat_cont& ex) { // récup du conteneur spécifique SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul); module_compressibilite=module_cisaillement=0.; // init energ.Inita(0.); // initialisation des énergies mises en jeux //récup de eps_mecaBB_t // 1) dans le repère gi Tenseur3BB& eps_mecaBB_t = *((Tenseur3BB*) (save_resul.eps_mecaBB_t)); Tenseur3BB& eps_mecaBB = *((Tenseur3BB*) (save_resul.eps_mecaBB)); // 2) dans le dernier repère V_a: a utiliser en sortie post, pas pour le calcul !! Tenseur3BB& eps_P_mecaBB_t = *((Tenseur3BB*) (save_resul.eps_P_mecaBB_t)); Tenseur3BB& eps_P_mecaBB = *((Tenseur3BB*) (save_resul.eps_P_mecaBB)); // on récupère la dimension de l'espace de travail qui doit-être de dimension 3 // ainsi que le nombre de vecteur: pour l'instant 3 #ifdef MISE_AU_POINT {if (Permet_affichage() > 5) cout << "\n LoiContraintesPlanesDouble::Calcul_dsigma_deps(..."; if ((ViB->Dimension() != 3) || (ViH->Dimension() != 3)) { cout << "\n***Erreur : la dimension de la base ViB = "<< ViB->Dimension() << " ou la dimension de la base ViH = " << ViH->Dimension() << " est different de 3, on ne peut pas continuer ! " << "\n LoiContraintesPlanesDouble::Calcul_dsigma_deps(..."; Sortie(1); }; if ((ViB->NbVecteur() != 3) || (ViH->NbVecteur() != 3)) { cout << "\n***Erreur : le nombre de vecteur de la base ViB = " << ViB->NbVecteur() << " ou le nombre de vecteur de la base ViH = " << ViH->NbVecteur() << " est different de 3, on ne peut pas continuer ! " << "\n LoiContraintesPlanesDouble::Calcul_dsigma_deps(..."; Sortie(1); }; // idem pour l'Umat: là on ne test que les vecteurs à 0, pour alléger le test if (ex.giB_0->Dimension() != 3) { cout << "\n***Erreur : la dimension de la base ex.giB_0 = " << ex.giB_0->Dimension() << " du conteneur Umat, est different de 3, on ne peut pas continuer ! " << "\n LoiContraintesPlanesDouble::Calcul_dsigma_deps(..."; Sortie(1); }; if (ex.giB_0->NbVecteur() != 3) { cout << "\n***Erreur : le nombre de vecteur de la base ex.giB_0 = " << ex.giB_0->NbVecteur() << " du conteneur Umat est different de 3, on ne peut pas continuer ! " << "\n LoiContraintesPlanesDouble::Calcul_dsigma_deps(..."; Sortie(1); }; } #endif // les coordonnées des vecteurs \vec V_e sont exprimées // dans la base de travail g_i finale on a donc // Vi_B(i) = {\beta'}_i^{.j} \hat{\vec g}_j = betaP(i,j) * giB_tdt(j) // i indice de ligne, j indice de colonne // \vec V_i = \vec V^i : les vecteurs sont égaux mais pas les composantes ! // 1 -- passage de la base \vec V_e à la base \hat{\vec g}_i // et \vec V^e à la base \hat{\vec g}^i // calcul des grandeurs gamma et beta: // \hat{\vec g}^i = \gamma^i_{~.e}~\vec V^e // \hat{\vec g}_i = \beta_i^{~.e}~\vec V_e // 2 -- passage de la base \hat{\vec g}_i à la base \vec V_e // et \hat{\vec g}^i à la base \vec V^e // // Vi_B(i) = {\beta'}_i^{.j} \hat{\vec g}_j // Vi_H(i) = {\gamma'}^i_{.j} \hat{\vec g}^j // gamma3D(i,e) = \gamma^i_{~.e} = \hat{\vec g}^i . \vec V_e // ce qui donne que [gamma3D(i,e)] = [{\beta'}_i^{.j}]^T for (int i=1;i<4;i++) // calcul de la matrice beta' for (int e=1;e<4;e++) // au lieu de passer par un produit scalaire on récupère {betaP_3D(i,e) = (*ViH)(i)(e); // directement les coordonnées gammaP_3D(i,e) = (*ViB)(i)(e); // " " }; // \beta_i^{~.e} = \hat{\vec g}_i . \vec V^e // c'est aussi l'inverse de la transposé de gamma3D // on choisit de calculer avec la formule gamma3D = betaP_3D.Transpose(); // ok beta3D = gammaP_3D.Transpose(); // betaP_3D.Inverse(); // gammaP_3D = beta3D.Transpose(); #ifdef MISE_AU_POINT if (Permet_affichage() > 6) {cout << "\n Vi_B(1)= "<<(*ViB)(1) << " Vi_B(2)= "<<(*ViB)(2) << " Vi_B(3)= "<<(*ViB)(3); cout << "\n Vi_H(1)= "<<(*ViH)(1) << " Vi_H(2)= "<<(*ViH)(2) << " Vi_H(3)= "<<(*ViH)(3); cout << "\n Vi_B(i) = {beta'}_i^{.j} hat{vec g}_j --> beta'= ";betaP_3D.Affiche(); cout << "\n Vi_H(i) = {gamma'}^i_{.j} hat{vec g}^j--> gamma'= ";gammaP_3D.Affiche(); cout << "\n hat{vec g}^i = gamma^i_{~.e}~vec V^e --> gamma= ";gamma3D.Affiche(); cout << "\n hat{vec g}_i = beta_i^{~.e}~vec V_e--> beta= ";beta3D.Affiche(); }; #endif // on alimente les pointeurs de tenseurs d'entrée de la cinématique epsBB_tdt_cin = ((Tenseur3BB*) &epsBB_tdt); // passage en dim 3 DepsBB_cin = ((Tenseur3BB*) &DepsBB); // passage en dim 3 delta_epsBB_cin = ((Tenseur3BB*) &delta_epsBB); // passage en dim 3 #ifdef MISE_AU_POINT if (Permet_affichage() > 6) {cout << "\n epsBB_tdt_cin "<< (*epsBB_tdt_cin) << "\n DepsBB_cin "<< (*DepsBB_cin) << "\n delta_epsBB_cin "<< (*delta_epsBB_cin) << flush; // en base orthonormee Tenseur3BB epsBB_tdt_cin_inter; epsBB_tdt_cin->BaseAbsolue(epsBB_tdt_cin_inter,(* ex.giH_tdt)); cout << "\n epsBB_tdt_cin= en absolue 3D : "< 6) {cout << "\n eps_mecaBB_t= "; eps_mecaBB_t.Ecriture(cout); cout << "\n eps_P_BB apres change base donc en V_a "<< eps_P_BB; }; #endif // on calcul la déformation cinématique dans la direction V_1 // \epsilon'_{11}(t+\Delta t) = \epsilon_{kl}(t+\Delta t) ~\gamma^k_{~.1} ~\gamma^l_{~.1} // idem pour l'accroissement de déformation et la vitesse de déformation eps_P_BB.Coor(1,1) = 0.; Deps_P_BB.Coor(1,1) = 0.; delta_eps_P_BB.Coor(1,1) = 0.; for (int k=1;k<4;k++) // calcul de la matrice gamma for (int l=1;l<4;l++) {eps_P_BB.Coor(1,1) += (*epsBB_tdt_cin)(k,l) * gamma3D(k,1) * gamma3D(l,1); Deps_P_BB.Coor(1,1) += (*DepsBB_cin)(k,l) * gamma3D(k,1) * gamma3D(l,1); delta_eps_P_BB.Coor(1,1) += (*delta_epsBB_cin)(k,l) * gamma3D(k,1) * gamma3D(l,1); }; #ifdef MISE_AU_POINT if (Permet_affichage() > 6) {cout << "\n eps_P_BB avec la cinematique "<< eps_P_BB; cout << "\n Deps_P_BB avec la cinematique "<< Deps_P_BB; cout << "\n delta_eps_P_BB avec la cinematique "<< delta_eps_P_BB << flush; }; #endif // on affecte les contraintes a t: en fait pour les lois incrémentales, les infos à t // sont déjà stocké, donc cela ne sert à rien, mais pour une loi élastique par exemple ce n'est pas le cas sig_HH_t_3D = sigHH_t; // concernant la métrique relative au repère de travail, on utilise celle passée en paramètre (*umat_cont_3D)= ex; // concernant le jacobien, le jacobien du conteneur est supposé être celui 1D sauve_jacobien1D_tdt = *(ex.jacobien_tdt); // --- pour les contraintes passage en 3D // bool plusZero = true; // --- pour la cinématique // passage des informations spécifique à la loi le_SaveResul lois_interne->IndiqueSaveResult(save_resul.le_SaveResul); lois_interne->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca lois_interne->IndiqueDef_en_cours(def_en_cours); // idem pour def en coursVhVg // la base de traction ViB_3D = ViB; ViH_3D = ViH; // calcul d'élements intermédiaires V1V1_BB = Tenseur3BB::Prod_tensoriel((*ViB_3D)(1),(*ViB_3D)(1)); #ifdef MISE_AU_POINT if (Permet_affichage() > 7) { cout << "\n V1V1_BB: "<< V1V1_BB; } #endif // pour (m,n) = (2,2); (3,3); (1,2), et pour (g,h) = (2,2); (3,3); et (1,2) // on va utiliser des matrices intermédiaires tels que: // in = 1 pour (2,2) , 2 pour (3,3) et 3 pour (1,2) for (int gh=1;gh<4;gh++) {//if (gh <3) {VhVg_BB(gh) = Tenseur3BB::Prod_tensoriel((*ViB_3D)(jnd(gh)),(*ViB_3D)(ind(gh)));} // else // donne des tenseurs non symétriques pour (1,2) -> on symétrise // {VhVg_BB(gh) = 0.5* Tenseur3BB::Prod_tensoriel((*ViB_3D)(ind(gh)),(*ViB_3D)(jnd(gh))) // + 0.5* Tenseur3BB::Prod_tensoriel((*ViB_3D)(jnd(gh)),(*ViB_3D)(ind(gh))); // } #ifdef MISE_AU_POINT if (Permet_affichage() > 7) { cout << "\n VhVg_BB("< save_resul.hsurh0 * save_resul.bsurb0 == 1; jacobien_t_3D = (*ex.jacobien_t) * save_resul.h_tsurh0 * save_resul.b_tsurb0; // choix entre calcul avec une boucle locale de Newton on non. // Dans le premier cas il nous faut la version d_sig/d_eps // au lieu de d_sig/d_ddl bool mauvaise_convergence = false; // init bool newtonlocal = false; switch (type_de_contrainte) {case NEWTON_LOCAL: // cas de la version d_sig/d_eps { newtonlocal=true; // pour la gestion du cas par défaut // initialisation du tenseur final de contrainte sig_HH_3D = sigHH_tdt; // c-a-d de la solution: peut-être pas nécessaire *** // passage des informations liées à la déformation de 1 vers 3, et variation de volume Tableau * toto = NULL; // pour dire que ce n'est pas attribué // on appel la procédure de résolution de sig33(..)=0 if ((sortie_post)&&(save_resul.indicateurs_resolution.Taille()!= 2)) // dimensionnement éventuelle de la sortie d'indicateurs save_resul.indicateurs_resolution.Change_taille(2); // ----- pour ce faire on appelle une méthode de recherche de zero // on initialise les inconnues à 0. On pourrait partir des def_P sauvegardés // mais si on change d'orientation dans la pratique la convergence est moins bonne ?? val_initiale_3D.Zero(); // = save_resul.def_P_t; // val_initiale_3D = save_resul.def_P_t; // on impose que les grandeurs soient dans les limites admises double& hsurh0 = save_resul.h_tsurh0;double& bsurb0 = save_resul.b_tsurb0; // init // la méthode va mettre à jour les variations bsurb0 et hsurh0 et le jacobien if (Calcul_et_Limitation2_h_b(hsurh0,eps_P_BB,bsurb0,jacobien_tdt_3D,jacobien_0_3D)) {if (Permet_affichage() > 3) cout << "\n pb limitation val initiales: LoiContraintesPlanesDouble::Calcul_dsigma_deps(... " << flush; }; //// ---- debut // // on vérifie que les anciennes transversales ne sont pas négatives // if ((val_initiale(1) < 0.) || (val_initiale(2) < 0.) ) // { cout << "\n debug LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt : " // << " initialement " // << "\n save_resul.b_tsurb0 = " << save_resul.b_tsurb0 // << ", save_resul.h_tsurh0 " << save_resul.h_tsurh0 << endl; // Sortie(1); // }; ////------ fin debug residu_3D.Zero(); // init du résultat à 0., mais c'est une grandeur de sortie donc cela ne sert à rien derResidu_3D.Initialise(0.); // init de la matrice dérivée à 0. try // on met le bloc sous surveillance { // résolution de l'équation constitutive d'avancement discrétisée en euler implicite int nb_incr_total,nb_iter_total; // variables intermédiaires d'indicateurs // dans le cas où on utilise une précision qui est pilotée { // opération de transmission de la métrique: encapsulé ici 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; if (fct_tolerance_residu != 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 = fct_tolerance_residu->Li_enu_etendu_scalaire(); List_io & li_quelc = fct_tolerance_residu->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 = fct_tolerance_residu->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 de pilotage de la precision " << " doit calculer un scalaire or le tableau de retour est de taille " << tab_val.Taille() << " ce n'est pas normal !\n"; cout << " LoiContraintesPlanesDouble::Calcul_dsigma_deps\n"; Sortie(1); }; #endif // on récupère le premier élément du tableau uniquement double tol = tab_val(1); #ifdef MISE_AU_POINT if (Permet_affichage() > 5) cout << "\n Newton_prec: tol_= "<< tol; #endif alg_zero.Modif_prec_res_abs(tol); }; if (fct_tolerance_residu_rel != 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 = fct_tolerance_residu_rel->Li_enu_etendu_scalaire(); List_io & li_quelc = fct_tolerance_residu_rel->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 = fct_tolerance_residu_rel->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 de pilotage de la precision relative " << " doit calculer un scalaire or le tableau de retour est de taille " << tab_val.Taille() << " ce n'est pas normal !\n"; cout << " LoiContraintesPlanesDouble::Calcul_dsigma_deps\n"; Sortie(1); }; #endif // on récupère le premier élément du tableau uniquement double tol_rel = tab_val(1); #ifdef MISE_AU_POINT if (Permet_affichage() > 5) cout << ", tol_relative= "<< tol_rel; #endif alg_zero.Modif_prec_res_rel(tol_rel); }; }; bool conver=alg_zero.Newton_raphson (*this,&LoiContraintesPlanesDouble::Residu_constitutif_3D ,&LoiContraintesPlanesDouble::Mat_tangente_constitutif_3D ,val_initiale_3D,racine_3D,derResidu_3D,nb_incr_total,nb_iter_total ,maxi_delta_var_eps_sur_iter_pour_Newton); if(sortie_post) // sauvegarde éventuelle des indicateurs {save_resul.indicateurs_resolution(1)+=nb_incr_total; save_resul.indicateurs_resolution(2)+=nb_iter_total; }; // on vérifie qu'il n'y a pas de pb de convergence double absracinemax=racine_3D.Max_val_abs(); if ((!conver) || (!isfinite(absracinemax)) || (isnan(absracinemax)) ) { if (Permet_affichage() > 0) { cout << "\n**>> non convergence sur l'algo de la resolution de (sigma.V_2=0, sigma.V_3=0),\n"; if (ptintmeca_en_cours != NULL) ptintmeca_en_cours->Signature(); cout << ", nb_incr_total=" << nb_incr_total << ", nb_iter_total=" << nb_iter_total<<", val obtenues:" << "\n eps_P(2,2)= " << racine_3D(1) << ", " << " eps_P(3,3)= " << racine_3D(2) << ", "<< " eps_P(1,2)= " << racine_3D(3) << "\n precedentes: "< 0) { cout << "\n erreur de non convergence avec l'algo de la resolution de" << " (sig'22, sig'33, sig'12)=(0,0,0) " << " on obtient une valeur infinie ou NaN " << "\n dernier_residu: "<< residu_3D(1) <<", "< 0) { cout << "\n erreur non identifiee sur l'algo de la resolution de " << " (sig'22, sig'33, sig'12)=(0,0,0) " << "\n dernier_residu: "<< residu_3D(1) <<", "< 6) { cout << "\nLoiContraintesPlanesDouble::Calcul_dsigma_deps: bonne convergence de Newton "; TenseurHH* ptHH = NevezTenseurHH(sig_HH_3D); sig_HH_3D.BaseAbsolue(*ptHH,giB_tdt_3D); cout << "\n sigma apres CP2: "; ptHH->Ecriture(cout); delete ptHH; }; if (Permet_affichage() > 5) { cout << "\n def_P(2,2) " << save_resul.def_P(1) << " def_P(3,3) " << save_resul.def_P(2) << " def_P(1,2) " << save_resul.def_P(3) << "\n en g^i: eps_mecaBB.Coor(2,2) " << eps_mecaBB.Coor(2,2) << " eps_mecaBB.Coor(3,3) " << eps_mecaBB.Coor(3,3) << " eps_mecaBB.Coor(1,2) " << eps_mecaBB.Coor(1,2) << "\n en V_a: eps_P_mecaBB.Coor(2,2) " << eps_P_mecaBB.Coor(2,2) << " eps_P_mecaBB.Coor(3,3) " << eps_P_mecaBB.Coor(3,3) << " eps_P_mecaBB.Coor(1,2) " << eps_P_mecaBB.Coor(1,2) << "\n module_compressibilite= " << module_compressibilite << " module_cisaillement= " << module_cisaillement; // on affiche les épaisseur et largeur double& hsurh0 = save_resul.hsurh0;double& bsurb0 = save_resul.bsurb0; cout << "\n hsurh0= "<< hsurh0 << " bsurb0= " << bsurb0 << flush; }; if (Permet_affichage() > 8) { cout << "\n dans le repere locale d_sigma_deps_3D= \n"; 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;} }; Tenseur3HHHH inter_HHHH; d_sigma_deps_3D.ChangeBase(inter_HHHH,giB_tdt_3D); cout << "\n dans le repere orthonormee d_sigma_deps_3D= \n"; 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;} }; }; #endif break; }; // sinon on ne fait pas de break, donc on continue avec la méthode de perturbation }; default: // cas de la version avec perturbation, on encore du cas où la méthode de Newton n'a pas convergé { // initialisation du tenseurs contrainte sig_HH_3D.Inita(0.); // dans le cas ou on est passé par la méthode de newton et que cela n'a pas // convergé, on doit réinitialiser les variables de départ if ((newtonlocal) && (Permet_affichage() > 3)) cout << "\n calcul direct sans Newton "; save_resul.hsurh0 = sauve_hsurh0; save_resul.bsurb0 = sauve_bsurb0; // appel du calcul en perturbation Cal_avec_perturbation2(); // on met à jour les modules module_compressibilite= module_compressibilite_3D; module_cisaillement= module_cisaillement_3D; if (mauvaise_convergence) {if (Permet_affichage() > 0) { cout << ": valeur final de h/h_0(t+dt)= " << save_resul.hsurh0 << " et de b/b_0(t+dt)= " << save_resul.bsurb0; }; // on annulle les dérivées des épaisseurs save_resul.d_hsurh0.Zero();save_resul.d_bsurb0.Zero(); }; } break; }; // sig_HH_3D.Ecriture(cout); (*save_resul.l_sigoHH) = sig_HH_3D; // sauvegarde en locale // ---calcul des invariants de déformation et de vitesse de déformation Calcul_invariants_et_def_cumul(); energ = save_resul.l_energ; // récup des énergies // --- on remet à jour éventuellement l'épaisseur // dans le cas d'une contrainte par perturbation // if ((type_de_contrainte == PERTURBATION )||mauvaise_convergence) if (type_de_contrainte == PERTURBATION ) // calcul de la déformation d'épaisseur correspondant à la condition de contraintes planes { //Tenseur1BH sigBH = gijBB_tdt * sigHH_tdt; Tenseur3BH sigBH = gijBB_tdt_3D * sig_HH_3D; Tenseur3BH sigBH_t = gijBB_t_3D * sig_HH_t_3D; Calcul_eps_trans_parVarVolume2(sigBH_t,jacobien_0,module_compressibilite,jacobien,sigBH,*(ex.jacobien_t)); if ((Permet_affichage() > 0) && mauvaise_convergence) { cout << "\n valeur final de h/h_0(t+dt)= " << save_resul.hsurh0 << " et de b/b_0(t+dt)= " << save_resul.bsurb0; }; }; 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 LoiContraintesPlanesDouble::RepercuteChangeTemperature(Enum_dure temps) { lois_interne->temperature_0 = this->temperature_0; lois_interne->temperature_t = this->temperature_t; lois_interne->temperature_tdt = this->temperature_tdt; lois_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 (lois_interne->epsBB_therm == NULL) { lois_interne->epsBB_therm = NevezTenseurBB(dim_tens);} else if (lois_interne->epsBB_therm->Dimension() != dim_tens) { delete lois_interne->epsBB_therm;lois_interne->epsBB_therm = NevezTenseurBB(dim_tens);}; // -- cas de la vitesse de déformation if (lois_interne->DepsBB_therm == NULL) { lois_interne->DepsBB_therm = NevezTenseurBB(dim_tens);} else if (lois_interne->DepsBB_therm->Dimension() != dim_tens) { delete lois_interne->DepsBB_therm;lois_interne->DepsBB_totale = NevezTenseurBB(dim_tens);}; // b- affectation des tenseurs (*lois_interne->epsBB_therm)=(*epsBB_therm); (*lois_interne->DepsBB_therm)=(*DepsBB_therm); }; // puis en interne lois_interne->RepercuteChangeTemperature(temps); switch (temps) { case TEMPS_0: {lois_interne->temperature = &lois_interne->temperature_0; break; } case TEMPS_t: {lois_interne->temperature = &lois_interne->temperature_t; break; } case TEMPS_tdt: {lois_interne->temperature = &lois_interne->temperature_tdt; break; } default: { cout << "\n erreur, cas de temps non prevu !! " << "\n LoiContraintesPlanesDouble::RepercuteChangeTemperature(..."; Sortie(1); }; }; }; void LoiContraintesPlanesDouble::CalculGrandeurTravail (const PtIntegMecaInterne& ptintmec ,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 des infos spécifiques SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul); // recup de l'incrément de temps double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant(); double unSurDeltat=0; if (Abs(deltat) >= ConstMath::trespetit) {unSurDeltat = 1./deltat;} else // si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand { // non un pas de temps doit être positif !! or certaine fois il peut y avoir des pb if (unSurDeltat < 0) { cout << "\n le pas de temps est négatif !! "; }; unSurDeltat = ConstMath::tresgrand; }; // par défaut on active les invariants et on intègre les infos def en 3D if (!calcul_en_3D_via_direction_quelconque) { //dans le cas classique, on dispose de la variation d'épaisseur et de largeur pour déterminer les def // ptintmec concerne des tenseurs d'ordres 1 donc il faut transformer en 3D bool plusZero=true; // on ajoute des 0 pour les grandeurs manquantes dans une première étape // on commence par transférer le tout ptintmeca.Affectation_1D_a_3D(ptintmec,plusZero); // ensuite on traite les points particuliers // pour tout ce qui est contrainte: l'ajout de 0 est ok // pour les déformations on met à jour en fonction des grandeurs sauvegardées double eps33=0.; double eps33_t=0.; //init par défaut double eps22=0.; double eps22_t=0.; //init par défaut // -- maintenant on tient compte de l'élongation d'épaisseur switch (type_de_deformation) {case DEFORMATION_STANDART : case DEFORMATION_POUTRE_PLAQUE_STANDART : // cas d'une déformation d'Almansi { // dans le repère local: epsBB33 = 1/2 * (h^2 - 1.), or h0=1. donc : epsBB33 = 1/2 * ((h/h0)^2 - 1.) eps33 = 0.5 * (save_resul.hsurh0 * save_resul.hsurh0 - 1.); eps33_t = 0.5 * (save_resul.h_tsurh0 * save_resul.h_tsurh0 - 1.); eps22 = 0.5 * (save_resul.bsurb0 * save_resul.bsurb0 - 1.); eps22_t = 0.5 * (save_resul.b_tsurb0 * save_resul.b_tsurb0 - 1.); }; break; case DEFORMATION_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEFORMATION_CUMU_LOGARITHMIQUE : // cas d'une def logarithmique ou une approximation { eps33 = log(save_resul.hsurh0); eps33_t = log(save_resul.h_tsurh0); eps22 = log(save_resul.bsurb0); eps22_t = log(save_resul.b_tsurb0); }; break; default : cout << "\nErreur : type de deformation qui n'est pas actuellement pris en compte, type= " << Nom_type_deformation(type_de_deformation); cout << "\n LoiContraintesPlanesDouble::CalculGrandeurTravail \n"; Sortie(1); }; (*ptintmeca.EpsBB()).Coor(3,3) = eps33; (*ptintmeca.DeltaEpsBB()).Coor(3,3) = eps33 - eps33_t; (*ptintmeca.EpsBB()).Coor(2,2) = eps22; (*ptintmeca.DeltaEpsBB()).Coor(2,2) = eps22 - eps22_t; (*ptintmeca.DepsBB()).Coor(3,3) = (eps33 - eps33_t) * unSurDeltat; (*ptintmeca.DepsBB()).Coor(2,2) = (eps22 - eps22_t) * unSurDeltat; } else // dans le cas où on travaille dans le repère gi en 3D on dispose directement des infos de déformation {//récup de eps_mecaBB Tenseur3BB& eps_mecaBB_t = *((Tenseur3BB*) (save_resul.eps_mecaBB_t)); Tenseur3BB& eps_mecaBB = *((Tenseur3BB*) (save_resul.eps_mecaBB)); // on sauve ce qu'il y a dans la direction 11 pour éviter les erreurs d'arrondis double eps11= (*ptintmeca.EpsBB())(1,1); double Deps11= (*ptintmeca.DepsBB())(1,1); double delta_eps11= (*ptintmeca.DeltaEpsBB())(1,1); // les manips entre tenseurs (*ptintmeca.EpsBB()) = eps_mecaBB; (*ptintmeca.DeltaEpsBB()) = eps_mecaBB - eps_mecaBB_t; (*ptintmeca.DepsBB()) = (*ptintmeca.DeltaEpsBB()) * unSurDeltat; // récup des valeurs sauvegardées (normalement ne devrait pas changer...) (*ptintmeca.EpsBB()).Coor(1,1) = eps11; (*ptintmeca.DeltaEpsBB()).Coor(1,1) = delta_eps11; (*ptintmeca.DepsBB()).Coor(1,1) = Deps11; }; // on met à jour les invariants 3D, on récupère ce qui a été sauvegardé if (ptintmeca.Statut_Invariants_deformation()) // le conteneur des invariants a pu être effacé par Affectation_1D_a_3D ptintmeca.EpsInvar() = save_resul.epsInvar; if (ptintmeca.Statut_Invariants_vitesseDeformation()) // le conteneur des invariants a pu être effacé par Affectation_1D_a_3D ptintmeca.DepsInvar() = save_resul.depsInvar; // idem au niveau des déformations cumulées ptintmeca.Deformation_equi() = save_resul.def_equi; ptintmeca.Deformation_equi_t() = save_resul.def_equi_t; // passage des informations spécifique à la loi le_SaveResul lois_interne->IndiqueSaveResult(save_resul.le_SaveResul); lois_interne->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca lois_interne->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours lois_interne->CalculGrandeurTravail(ptintmeca,def,temps,dTP ,ex_impli,ex_expli_tdt,ex_umat,exclure_dd_etend,exclure_Q); // passage à la loi 3D }; // passage des grandeurs métriques de l'ordre 1 à 3, cas implicite void LoiContraintesPlanesDouble::Passage_metrique_ordre1_vers_3(const Met_abstraite::Impli& ex) {// on s'occupe du redimensionnement éventuel // on affecte et/ou on redimensionne éventuellement les tableaux fonction du nombre de ddl pour le passage 3D // la partie dépendant des vitesses: entre accolades pour pouvoir fermer {if (ex.gradVmoyBB_t != NULL) {impli_3D->gradVmoyBB_t= gradVmoyBB_t_3D_P = &gradVmoyBB_t_3D;}; if (ex.gradVmoyBB_tdt != NULL) {impli_3D->gradVmoyBB_tdt=gradVmoyBB_tdt_3D_P = &gradVmoyBB_tdt_3D;}; if (ex.gradVBB_tdt != NULL) {impli_3D->gradVBB_tdt=gradVBB_tdt_3D_P = &gradVBB_tdt_3D;}; // on s'occupe tout d'abord des tableaux de vitesses qui peuvent ne pas exister if (ex.d_gradVmoyBB_t != NULL) // cas où il existe { int tail=ex.d_gradVmoyBB_t->Taille(); if (d_gradVmoyBB_t_3D_P == NULL) {d_gradVmoyBB_t_3D_P = new Tableau (tail); impli_3D->d_gradVmoyBB_t = d_gradVmoyBB_t_3D_P;} else {d_gradVmoyBB_t_3D_P->Change_taille(tail);}; d_gradVmoyBB_t_3D.Change_taille(tail); for (int i=1;i<= tail;i++) (*d_gradVmoyBB_t_3D_P)(i) = &(d_gradVmoyBB_t_3D(i)); }; if (ex.d_gradVmoyBB_tdt != NULL) // cas où il existe { int tail=ex.d_gradVmoyBB_tdt->Taille(); if (d_gradVmoyBB_tdt_3D_P == NULL) {d_gradVmoyBB_tdt_3D_P = new Tableau (tail); impli_3D->d_gradVmoyBB_tdt = d_gradVmoyBB_tdt_3D_P;} else {d_gradVmoyBB_tdt_3D_P->Change_taille(tail);}; d_gradVmoyBB_tdt_3D.Change_taille(tail); for (int i=1;i<= tail;i++) (*d_gradVmoyBB_tdt_3D_P)(i) = &(d_gradVmoyBB_tdt_3D(i)); }; if (ex.d_gradVBB_t != NULL) // cas où il existe { int tail=ex.d_gradVBB_t->Taille(); if (d_gradVBB_t_3D_P == NULL) {d_gradVBB_t_3D_P = new Tableau (tail); impli_3D->d_gradVBB_t = d_gradVBB_t_3D_P;} else {d_gradVBB_t_3D_P->Change_taille(tail);}; d_gradVBB_t_3D.Change_taille(tail); for (int i=1;i<= tail;i++) (*d_gradVBB_t_3D_P)(i) = &(d_gradVBB_t_3D(i)); }; if (ex.d_gradVBB_tdt != NULL) // cas où il existe { int tail=ex.d_gradVBB_tdt->Taille(); if (d_gradVBB_tdt_3D_P == NULL) {d_gradVBB_tdt_3D_P = new Tableau (tail); impli_3D->d_gradVBB_tdt = d_gradVBB_tdt_3D_P;} else {d_gradVBB_tdt_3D_P->Change_taille(tail);}; d_gradVBB_tdt_3D.Change_taille(tail); for (int i=1;i<= tail;i++) (*d_gradVBB_tdt_3D_P)(i) = &(d_gradVBB_tdt_3D(i)); }; }; // fin de la partie dédiée à la vitesse // maintenant on s'occupe uniquement du redimensionnement des tableaux restants // -- on s'occupe des tableaux nécessaire à la métrique int ta_ex_d_giB_tdt = ex.d_giB_tdt->Taille(); // la dimension if (d_giB_tdt_3D.Taille() != ta_ex_d_giB_tdt) { d_giB_tdt_3D.Change_taille(ta_ex_d_giB_tdt);}; int ta_ex_d_giH_tdt = ex.d_giH_tdt->Taille(); // la dimension if (d_giH_tdt_3D.Taille() != ta_ex_d_giH_tdt) { d_giH_tdt_3D.Change_taille(ta_ex_d_giH_tdt);}; int ta_ex_d_gijBB_tdt = ex.d_gijBB_tdt->Taille(); // la dimension if (d_gijBB_tdt_3D.Taille() != ta_ex_d_gijBB_tdt) { d_gijBB_tdt_3D.Change_taille(ta_ex_d_gijBB_tdt); d_gijBB_tdt_3D_P.Change_taille(ta_ex_d_gijBB_tdt); for (int i=1;i<=ta_ex_d_gijBB_tdt;i++) {d_gijBB_tdt_3D_P(i) = &(d_gijBB_tdt_3D(i));}; }; int ta_ex_d_gijHH_tdt = ex.d_gijHH_tdt->Taille(); if (d_gijHH_tdt_3D.Taille() != ta_ex_d_gijHH_tdt) { d_gijHH_tdt_3D.Change_taille(ta_ex_d_gijHH_tdt); d_gijHH_tdt_3D_P.Change_taille(ta_ex_d_gijHH_tdt); for (int i=1;i<=ta_ex_d_gijHH_tdt;i++) {d_gijHH_tdt_3D_P(i) = &(d_gijHH_tdt_3D(i));}; }; if( d_jacobien_tdt_3D.Taille() != ex.d_jacobien_tdt->Taille()) {d_jacobien_tdt_3D.Change_taille(ex.d_jacobien_tdt->Taille());} // le tableau à double dimension if (ex.d2_gijBB_tdt != NULL) { int taille1=ex.d2_gijBB_tdt->Taille1(); int taille2=ex.d2_gijBB_tdt->Taille2(); if (d2_gijBB_tdt_3D_P == NULL) { d2_gijBB_tdt_3D_P = impli_3D->d2_gijBB_tdt = new Tableau2 (taille1,taille2); d2_gijBB_tdt_3D.Change_taille(taille1,taille2); for (int i=1;i<=taille1;i++) for (int j=1;j<= taille2;j++) { (*d2_gijBB_tdt_3D_P)(i,j) = &d2_gijBB_tdt_3D(i,j);}; } else if ((taille1 != d2_gijBB_tdt_3D.Taille1()) || (taille2 != d2_gijBB_tdt_3D.Taille2())) { d2_gijBB_tdt_3D_P->Change_taille(taille1,taille2); d2_gijBB_tdt_3D.Change_taille(taille1,taille2); for (int i=1;i<=taille1;i++) for (int j=1;j<= taille2;j++) { (*d2_gijBB_tdt_3D_P)(i,j) = &d2_gijBB_tdt_3D(i,j);}; }; }; // récup du conteneur spécifique SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul); // si les grandeurs à 0 ont déjà été calculées, on les sauvegarde d'abord car elles vont // être écrasées // on commence par recopier les grandeurs de l'ordre 1 à 3 bool plusZero = true; // on complète avec des 0 dans un premier temps int type_recopie = 0; // init: on recopie les grandeurs de 0,t et tdt if ( save_resul.meti_ref_00.giB_ != NULL) type_recopie = 1; // = 1 -> on transfert les grandeurs à t et tdt impli_3D->Passage_de_Ordre1_vers_Ordre3(ex,plusZero,type_recopie); #ifdef MISE_AU_POINT if (Permet_affichage() > 8) { cout << "\n LoiContraintesPlanesDouble::Passage_metrique_ordre1_vers_3(" << "\n 1) base giB_tdt_3D(1) "<< giB_tdt_3D(1) << "\n base giB_tdt_3D(2) "<< giB_tdt_3D(2) << "\n base giB_tdt_3D(2) "<< giB_tdt_3D(3) << flush; }; #endif // maintenant on s'occupe de mettre à jour les grandeurs manquantes // - les bases naturelles: les vecteurs normaux dans les directions 2 et 3 sont normées // et sont identiques pour les bases naturelles et duales // Dans le cas d'un comportement isotrope, on choisit un repère par défaut // si les repères associés ne sont pas définis on les définit if ( save_resul.meti_ref_00.giB_ == NULL) { Deformation::Stmet inter(3,3); // création d'un conteneur bien dimensionné save_resul.meti_ref_00 = save_resul.meti_ref_t = save_resul.meti_ref_tdt = inter; // on s'occupe de la création du premier repère CoordonneeB & giB0_1 = (*(save_resul.meti_ref_00.giB_)).CoordoB(1); // pour simplifier giB0_1 = giB_0_3D(1); // on récupère la direction du premier vecteur giB0_1.Normer(); // on le norme // on crée 2 vecteurs normés, perpendiculaires à ce premier vecteur CoordonneeB & giB0_2 = (*(save_resul.meti_ref_00.giB_)).CoordoB(2); // pour simplifier CoordonneeB & giB0_3 = (*(save_resul.meti_ref_00.giB_)).CoordoB(3); // pour simplifier // deux cas suivant que l'on dispose d'une orientation supplémentaire ou non if (ex.giB_0->NbVecteur() > 1) { // a priori le second vecteur de la base est un vecteur d'un plan de ref giB0_3 = (Util::ProdVec_coorB(giB_0_3D(1), (*(ex.giB_0))(2))).Normer(); giB0_2 = Util::ProdVec_coorB(giB0_3,giB0_1); } else { // cas où on n'a pas d'indication sup: -> on definit des vecteurs a priori MathUtil2::Def_vecteurs_plan(giB0_1,giB0_2,giB0_3); }; ////--- debug // cout << "\n debug LoiContraintesPlanesDouble::Passage_metrique_ordre1_vers_3("; // cout << "\n giB0_1: "; giB0_1.Affiche(); // cout << "\n giB0_2: "; giB0_2.Affiche(); // cout << "\n giB0_3: "; giB0_3.Affiche(); //// --- fin debug giB_0_3D.CoordoB(2)=giB0_2;giB_0_3D.CoordoB(3)=giB0_3; giH_0_3D.CoordoH(2) = giB_0_3D(2).Bas_haut(); giH_0_3D.CoordoH(3) = giB_0_3D(3).Bas_haut(); }; ////--- debug // cout << "\n debug LoiContraintesPlanesDouble::Passage_metrique_ordre1_vers_3("; // cout << "\n giH_0(2): "; giH_0_3D(2).Affiche(); // cout << "\n giH_0(3): "; giH_0_3D(3).Affiche(); //// --- fin debug // on met à jour les deux autres directions // *** pour l'instant on fait la même chose que pour t= 0, pour les deux autres temps // *** , mais il faudra surement améliorer CoordonneeB & giBt_1 = (*(save_resul.meti_ref_t.giB_)).CoordoB(1); // pour simplifier giBt_1 = giB_t_3D(1); // on récupère la direction du premier vecteur giBt_1.Normer(); // on le norme // on crée 2 vecteurs normés, perpendiculaires à ce premier vecteur CoordonneeB & giBt_2 = (*(save_resul.meti_ref_t.giB_)).CoordoB(2); // pour simplifier CoordonneeB & giBt_3 = (*(save_resul.meti_ref_t.giB_)).CoordoB(3); // pour simplifier // deux cas suivant que l'on dispose d'une orientation supplémentaire ou non if (ex.giB_t->NbVecteur() > 1) { // a priori le second vecteur de la base est un vecteur d'un plan de ref giBt_3 = (Util::ProdVec_coorB(giB_t_3D(1), (*(ex.giB_t))(2))).Normer(); giBt_2 = Util::ProdVec_coorB(giBt_3,giBt_1); } else { // cas où on n'a pas d'indication sup: -> on definit des vecteurs a priori MathUtil2::Def_vecteurs_plan(giBt_1,giBt_2,giBt_3); }; giB_t_3D.CoordoB(2)=giBt_2;giB_t_3D.CoordoB(3)=giBt_3; giH_t_3D.CoordoH(2) = giB_t_3D(2).Bas_haut(); giH_t_3D.CoordoH(3) = giB_t_3D(3).Bas_haut(); #ifdef MISE_AU_POINT if (Permet_affichage() > 8) { cout << "\n 2) base giB_tdt_3D(1) "<< giB_tdt_3D(1) << "\n base giB_tdt_3D(2) "<< giB_tdt_3D(2) << "\n base giB_tdt_3D(2) "<< giB_tdt_3D(3) << flush; }; #endif CoordonneeB & giBtdt_1 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(1); // pour simplifier giBtdt_1 = giB_tdt_3D(1); // on récupère la direction du premier vecteur giBtdt_1.Normer(); // on le norme // on crée 2 vecteurs normés, perpendiculaires à ce premier vecteur CoordonneeB & giBtdt_2 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(2); // pour simplifier CoordonneeB & giBtdt_3 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(3); // pour simplifier // deux cas suivant que l'on dispose d'une orientation supplémentaire ou non if (ex.giB_tdt->NbVecteur() > 1) { // a priori le second vecteur de la base est un vecteur d'un plan de ref giBtdt_3 = (Util::ProdVec_coorB(giB_tdt_3D(1), (*(ex.giB_tdt))(2))).Normer(); giBtdt_2 = Util::ProdVec_coorB(giBtdt_3,giBtdt_1); } else { // cas où on n'a pas d'indication sup: -> on definit des vecteurs a priori MathUtil2::Def_vecteurs_plan(giBtdt_1,giBtdt_2,giBtdt_3); }; giB_tdt_3D.CoordoB(2)=giBtdt_2;giB_tdt_3D.CoordoB(3)=giBtdt_3; giH_tdt_3D.CoordoH(2) = giB_tdt_3D(2).Bas_haut(); giH_tdt_3D.CoordoH(3) = giB_tdt_3D(3).Bas_haut(); #ifdef MISE_AU_POINT if (Permet_affichage() > 8) { cout << "\n 3) base giB_tdt_3D(1) "<< giB_tdt_3D(1) << "\n base giB_tdt_3D(2) "<< giB_tdt_3D(2) << "\n base giB_tdt_3D(2) "<< giB_tdt_3D(3) << flush; }; #endif // ici on calcul les vecteurs // >>>> et la première partie de leurs variations, fonction du premier vecteur uniquement // - les tenseurs métriques: a priori 1 pour les directions 2 et 3, initialement gijBB_0_3D.Coor(2,2)=gijHH_0_3D.Coor(2,2)=gijBB_t_3D.Coor(2,2)=gijHH_t_3D.Coor(2,2) =gijBB_tdt_3D.Coor(2,2)=gijHH_tdt_3D.Coor(2,2)=1.; gijBB_0_3D.Coor(3,3)=gijHH_0_3D.Coor(3,3)=gijBB_t_3D.Coor(3,3)=gijHH_t_3D.Coor(3,3) =gijBB_tdt_3D.Coor(3,3)=gijHH_tdt_3D.Coor(3,3)=1.; // lors d'un premier appel, les variables save_resul.h_tsurh0 et save_resul.hsurh0 et idem pour l'épaisseur // ne sont pas affectés car elles sont issues d'un premier calcul, dans ce cas on les mets arbitrairement à 1 // ensuite elles évolueront, idem pour la largeur bool premier_passage = false; if (save_resul.h_tsurh0 == 0.) { save_resul.h_tsurh0 = 1.; save_resul.hsurh0 = 1.; save_resul.b_tsurb0 = 1.; save_resul.bsurb0 = 1.; premier_passage = true; }; if (save_resul.hsurh0 == 0.) // peut arriver dans le cas où on a une erreur dès le début { save_resul.hsurh0 = save_resul.h_tsurh0;}; // on réinitialise if (save_resul.bsurb0 == 0.) // peut arriver dans le cas où on a une erreur dès le début { save_resul.bsurb0 = save_resul.b_tsurb0;}; // on réinitialise // on calcul les vecteur 2 et 3 naturels et duals giB_t_3D.CoordoB(2) *= save_resul.b_tsurb0; giH_t_3D.CoordoH(2) /= save_resul.b_tsurb0; giB_tdt_3D.CoordoB(2) *= save_resul.bsurb0; giH_tdt_3D.CoordoH(2) /= save_resul.bsurb0; giB_t_3D.CoordoB(3) *= save_resul.h_tsurh0; giH_t_3D.CoordoH(3) /= save_resul.h_tsurh0; giB_tdt_3D.CoordoB(3) *= save_resul.hsurh0; giH_tdt_3D.CoordoH(3) /= save_resul.hsurh0; #ifdef MISE_AU_POINT if (Permet_affichage() > 8) { cout << "\n 4) base giB_tdt_3D(1) "<< giB_tdt_3D(1) << "\n base giB_tdt_3D(2) "<< giB_tdt_3D(2) << "\n base giB_tdt_3D(2) "<< giB_tdt_3D(3) << flush; }; #endif // - et les tenseurs métriques à t et tdt, comme les vecteurs en épaisseurs et largeurs // sont normées initialement, seule l'intensité // des normales est à mettre à jour compte tenue de la variation d'épaisseurs double h_tsurh0_carre = save_resul.h_tsurh0 * save_resul.h_tsurh0; gijBB_t_3D.Coor(3,3)=h_tsurh0_carre; gijHH_t_3D.Coor(3,3)= 1./h_tsurh0_carre; double hsurh0_carre = save_resul.hsurh0 * save_resul.hsurh0; gijBB_tdt_3D.Coor(3,3) = hsurh0_carre;gijHH_tdt_3D.Coor(3,3) = 1. / hsurh0_carre; double b_tsurb0_carre = save_resul.b_tsurb0 * save_resul.b_tsurb0; gijBB_t_3D.Coor(2,2)=b_tsurb0_carre; gijHH_t_3D.Coor(2,2)= 1./b_tsurb0_carre; double bsurb0_carre = save_resul.bsurb0 * save_resul.bsurb0; gijBB_tdt_3D.Coor(2,2) = bsurb0_carre;gijHH_tdt_3D.Coor(2,2) = 1. / bsurb0_carre; // -- cas des variations if (save_resul.d_hsurh0.Taille() != ta_ex_d_giB_tdt) {save_resul.d_hsurh0.Change_taille(ta_ex_d_giB_tdt); // donc à 0 la première fois save_resul.d_bsurb0.Change_taille(ta_ex_d_giB_tdt); }; // - les variations du vecteur normal #ifdef MISE_AU_POINT if (ex.d_giB_tdt->Taille() != ex.d_giH_tdt->Taille()) { cout << "\n **** sans doute une erreur: (ex.d_giB_tdt->Taille() "<< ex.d_giB_tdt->Taille() << " != ex.d_giH_tdt->Taille()) " << ex.d_giH_tdt->Taille() << "\n LoiDeformationsPlanes::Passage_metrique_ordre1_vers_3(const Met_abstraite::Impli& ex)"; Sortie(1); }; #endif // maintenant on s'occupe de la seconde partie des variations // >>>> fonction du changement d'épaisseur et de largeur if (!premier_passage) {Vecteur& d_hsurh0 = save_resul.d_hsurh0; Vecteur& d_bsurb0 = save_resul.d_bsurb0; for (int iddl=1;iddl<= ta_ex_d_giB_tdt;iddl++) { double d_hsurh0_iddl = d_hsurh0(iddl); // gib(3) = h/h0 * N -> d_gib(3) = d (h/h0 * N) = d_(h/h0) * N + h/h0 * d_N // actuellement, c'est la partie d_N qui est stockée dans d_gib(3), on rajoute donc la partie restante d_giB_tdt_3D(iddl).CoordoB(3) *= save_resul.hsurh0; d_giB_tdt_3D(iddl).CoordoB(3) += d_hsurh0_iddl * giB_normer_3_tdt_3D_sauve; // base naturelle // gih(3) = 1/giB(3) -> d_gih(3)(3) = - d_giB(3)(3) / (giB(3)*giB(3)) d_giH_tdt_3D(iddl).CoordoH(3) = (d_giB_tdt_3D(iddl)(3) / (-hsurh0_carre)).Bas_haut() ; // base duale // gijBB(3)= giB(3) * giB(3) -> d_gijBB(3)= 2. * d_giB(3) * giB(3) d_gijBB_tdt_3D(iddl).Coor(3,3) = 2. * (d_giB_tdt_3D(iddl)(3).ScalBB(giB_tdt_3D(3))); // gijHH(3)= giH(3) * giH(3) -> d_gijHH(3)= 2. * d_giH(3) * giH(3) d_gijHH_tdt_3D (iddl).Coor(3,3) = 2. * (d_giH_tdt_3D(iddl)(3).ScalHH(giH_tdt_3D(3))); double d_bsurb0_iddl = d_bsurb0(iddl); // gib(2) = b/b0 * N -> d_gib(2) = d (b/b0 * N) = d_(b/b0) * N + b/b0 * d_N // actuellement, c'est la partie d_N qui est stockée dans d_gib(3), on rajoute donc la partie restante d_giB_tdt_3D(iddl).CoordoB(2) *= save_resul.bsurb0; d_giB_tdt_3D(iddl).CoordoB(2) += d_bsurb0_iddl * giB_normer_3_tdt_3D_sauve; // base naturelle // gih(2) = 1/giB(2) -> d_gih(2)(2) = - d_giB(3)(3) / (giB(3)*giB(3)) d_giH_tdt_3D(iddl).CoordoH(2) = (d_giB_tdt_3D(iddl)(2) / (-bsurb0_carre)).Bas_haut() ; // base duale // gijBB(2)= giB(2) * giB(2) -> d_gijBB(2)= 2. * d_giB(2) * giB(2) d_gijBB_tdt_3D(iddl).Coor(2,2) = 2. * (d_giB_tdt_3D(iddl)(2).ScalBB(giB_tdt_3D(2))); // gijHH(2)= giH(2) * giH(2) -> d_gijHH(2)= 2. * d_giH(2) * giH(2) d_gijHH_tdt_3D (iddl).Coor(2,2) = 2. * (d_giH_tdt_3D(iddl)(2).ScalHH(giH_tdt_3D(2))); }; }; }; // passage des grandeurs métriques de l'ordre 1 à 3: cas explicite void LoiContraintesPlanesDouble::Passage_metrique_ordre1_vers_3(const Met_abstraite::Expli_t_tdt& ex) { // on s'occupe du redimensionnement éventuel // on affecte et/ou on redimensionne éventuellement les tableaux fonction du nombre de ddl pour le passage 3D // la partie dépendant des vitesses: entre accolades pour pouvoir fermer {if (ex.gradVmoyBB_t != NULL) {expli_3D->gradVmoyBB_t= gradVmoyBB_t_3D_P = &gradVmoyBB_t_3D;}; if (ex.gradVmoyBB_tdt != NULL) {expli_3D->gradVmoyBB_tdt=gradVmoyBB_tdt_3D_P = &gradVmoyBB_tdt_3D;}; if (ex.gradVBB_tdt != NULL) {expli_3D->gradVBB_tdt=gradVBB_tdt_3D_P = &gradVBB_tdt_3D;}; }; // fin de la partie dédiée à la vitesse // la dimension des tableaux : on considère que tous les tableaux doivent avoir la même dimension int ta_ex_d_gijBB_tdt = ex.d_gijBB_tdt->Taille(); // la dimension // maintenant on s'occupe uniquement du redimensionnement des tableaux restants int ta_d_gijBB_tdt_3D = d_gijBB_tdt_3D.Taille(); if (ta_d_gijBB_tdt_3D != ta_ex_d_gijBB_tdt) {// cela veut dire que tous les tableaux sont mal dimensionnés // -- on s'occupe des tableaux nécessaire à la métrique d_gijBB_tdt_3D.Change_taille(ta_ex_d_gijBB_tdt); d_gijBB_tdt_3D_P.Change_taille(ta_ex_d_gijBB_tdt); for (int i=1;i<=ta_ex_d_gijBB_tdt;i++) {d_gijBB_tdt_3D_P(i) = &(d_gijBB_tdt_3D(i));}; }; // récup du conteneur spécifique SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul); // on commence par recopier les grandeurs de l'ordre 1 à 3 bool plusZero = true; // on complète avec des 0 dans un premier temps int type_recopie = 0; // init: on recopie les grandeurs de 0,t et tdt if ( save_resul.meti_ref_00.giB_ != NULL) type_recopie = 1; // = 1 -> on transfert les grandeurs à t et tdt expli_3D->Passage_de_Ordre1_vers_Ordre3(ex,plusZero,type_recopie); // maintenant on s'occupe de mettre à jour les grandeurs manquantes // - les bases naturelles: les vecteurs normaux dans les directions 2 et 3 sont normées // et sont identiques pour les bases naturelles et duales // Dans le cas d'un comportement isotrope, on choisit un repère par défaut // si les repères associés ne sont définis on les définit if ( save_resul.meti_ref_00.giB_ == NULL) { Deformation::Stmet inter(3,3); // création d'un conteneur bien dimensionné save_resul.meti_ref_00 = save_resul.meti_ref_t = save_resul.meti_ref_tdt = inter; // on s'occupe de la création du premier repère CoordonneeB & giB0_1 = (*(save_resul.meti_ref_00.giB_)).CoordoB(1); // pour simplifier giB0_1 = giB_0_3D(1); // on récupère la direction du premier vecteur giB0_1.Normer(); // on le norme // on crée 2 vecteurs normés, perpendiculaires à ce premier vecteur CoordonneeB & giB0_2 = (*(save_resul.meti_ref_00.giB_)).CoordoB(2); // pour simplifier CoordonneeB & giB0_3 = (*(save_resul.meti_ref_00.giB_)).CoordoB(3); // pour simplifier // Def_vecteurs_plan(giB0_1,giB0_2,giB0_3); giB_0_3D.CoordoB(2)=giB0_2;giB_0_3D.CoordoB(3)=giB0_3; }; // on met à jour les deux autres directions // *** pour l'instant on fait la même chose que pour t= 0, pour les deux autres temps // *** , mais il faudra surement améliorer CoordonneeB & giBt_1 = (*(save_resul.meti_ref_t.giB_)).CoordoB(1); // pour simplifier giBt_1 = giB_t_3D(1); // on récupère la direction du premier vecteur giBt_1.Normer(); // on le norme // on crée 2 vecteurs normés, perpendiculaires à ce premier vecteur CoordonneeB & giBt_2 = (*(save_resul.meti_ref_t.giB_)).CoordoB(2); // pour simplifier CoordonneeB & giBt_3 = (*(save_resul.meti_ref_t.giB_)).CoordoB(3); // pour simplifier // Def_vecteurs_plan(giBt_1,giBt_2,giBt_3); giB_t_3D.CoordoB(2)=giBt_2;giB_t_3D.CoordoB(3)=giBt_3; CoordonneeB & giBtdt_1 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(1); // pour simplifier giBtdt_1 = giB_tdt_3D(1); // on récupère la direction du premier vecteur giBtdt_1.Normer(); // on le norme // on crée 2 vecteurs normés, perpendiculaires à ce premier vecteur CoordonneeB & giBtdt_2 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(2); // pour simplifier CoordonneeB & giBtdt_3 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(3); // pour simplifier // Def_vecteurs_plan(giBtdt_1,giBtdt_2,giBtdt_3); giB_tdt_3D.CoordoB(2)=giBtdt_2;giB_tdt_3D.CoordoB(3)=giBtdt_3; // - les tenseurs métriques: a priori 1 pour les directions 2 et 3, initialement gijBB_0_3D.Coor(2,2)=gijHH_0_3D.Coor(2,2)=gijBB_t_3D.Coor(2,2)=gijHH_t_3D.Coor(2,2) =gijBB_tdt_3D.Coor(2,2)=gijHH_tdt_3D.Coor(2,2)=1.; gijBB_0_3D.Coor(3,3)=gijHH_0_3D.Coor(3,3)=gijBB_t_3D.Coor(3,3)=gijHH_t_3D.Coor(3,3) =gijBB_tdt_3D.Coor(3,3)=gijHH_tdt_3D.Coor(3,3)=1.; // lors d'un premier appel, les variables save_resul.h_tsurh0 et save_resul.hsurh0 // ne sont pas affecté car elles sont issues d'un premier calcul, dans ce cas on les mets arbitrairement à 1 // ensuite elles évolueront, idem pour la largeur bool premier_passage = false; if (save_resul.h_tsurh0 == 0.) { save_resul.h_tsurh0 = 1.; save_resul.hsurh0 = 1.; save_resul.b_tsurb0 = 1.; save_resul.bsurb0 = 1.; premier_passage = true; }; if (save_resul.hsurh0 == 0.) // peut arriver dans le cas où on a une erreur dès le début { save_resul.hsurh0 = save_resul.h_tsurh0;}; // on réinitialise if (save_resul.bsurb0 == 0.) // peut arriver dans le cas où on a une erreur dès le début { save_resul.bsurb0 = save_resul.b_tsurb0;}; // on réinitialise // on calcul les vecteur 2 et 3 naturels et duals giB_t_3D.CoordoB(2) *= save_resul.b_tsurb0; giH_t_3D.CoordoH(2) /= save_resul.b_tsurb0; giB_tdt_3D.CoordoB(2) *= save_resul.bsurb0; giH_tdt_3D.CoordoH(2) /= save_resul.bsurb0; giB_t_3D.CoordoB(3) *= save_resul.h_tsurh0; giH_t_3D.CoordoH(3) /= save_resul.h_tsurh0; giB_tdt_3D.CoordoB(3) *= save_resul.hsurh0; giH_tdt_3D.CoordoH(3) /= save_resul.hsurh0; // - et les tenseurs métriques à t et tdt, comme les vecteurs en épaisseurs et largeurs // sont normées initialement, seule l'intensité // des normales est à mettre à jour compte tenue de la variation d'épaisseurs double b_tsurb0_carre = save_resul.b_tsurb0 * save_resul.b_tsurb0; gijBB_t_3D.Coor(2,2)=b_tsurb0_carre; gijHH_t_3D.Coor(2,2)= 1./b_tsurb0_carre; double bsurb0_carre = save_resul.bsurb0 * save_resul.bsurb0; gijBB_tdt_3D.Coor(2,2) = bsurb0_carre;gijHH_tdt_3D.Coor(2,2) = 1. / bsurb0_carre; double h_tsurh0_carre = save_resul.h_tsurh0 * save_resul.h_tsurh0; gijBB_t_3D.Coor(3,3)=h_tsurh0_carre; gijHH_t_3D.Coor(3,3)= 1./h_tsurh0_carre; double hsurh0_carre = save_resul.hsurh0 * save_resul.hsurh0; gijBB_tdt_3D.Coor(3,3) = hsurh0_carre;gijHH_tdt_3D.Coor(3,3) = 1. / hsurh0_carre; }; // passage des grandeurs métriques de l'ordre 1 à 3: cas Umat void LoiContraintesPlanesDouble::Passage_metrique_ordre1_vers_3(const Met_abstraite::Umat_cont& ex) { // on s'occupe du redimensionnement éventuel // on affecte et/ou on redimensionne éventuellement les tableaux fonction du nombre de ddl pour le passage 3D // la partie dépendant des vitesses: entre accolades pour pouvoir fermer {if (ex.gradVmoyBB_t != NULL) {umat_cont_3D->gradVmoyBB_t= gradVmoyBB_t_3D_P = &gradVmoyBB_t_3D;}; if (ex.gradVmoyBB_tdt != NULL) {umat_cont_3D->gradVmoyBB_tdt=gradVmoyBB_tdt_3D_P = &gradVmoyBB_tdt_3D;}; if (ex.gradVBB_tdt != NULL) {umat_cont_3D->gradVBB_tdt=gradVBB_tdt_3D_P = &gradVBB_tdt_3D;}; }; // fin de la partie dédiée à la vitesse // récup du conteneur spécifique SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul); // on commence par recopier les grandeurs de l'ordre 1 à 3 bool plusZero = true; // on complète avec des 0 dans un premier temps int type_recopie = 0; // init: on recopie les grandeurs de 0,t et tdt if ( save_resul.meti_ref_00.giB_ != NULL) type_recopie = 1; // = 1 -> on transfert les grandeurs à t et tdt umat_cont_3D->Passage_de_Ordre1_vers_Ordre3(ex,plusZero,type_recopie); // maintenant on s'occupe de mettre à jour les grandeurs manquantes // - les bases naturelles: les vecteurs normaux dans les directions 2 et 3 sont normées // et sont identiques pour les bases naturelles et duales // Dans le cas d'un comportement isotrope, on choisit un repère par défaut // si les repères associés ne sont définis on les définit if ( save_resul.meti_ref_00.giB_ == NULL) { Deformation::Stmet inter(3,3); // création d'un conteneur bien dimensionné save_resul.meti_ref_00 = save_resul.meti_ref_t = save_resul.meti_ref_tdt = inter; // on s'occupe de la création du premier repère CoordonneeB & giB0_1 = (*(save_resul.meti_ref_00.giB_)).CoordoB(1); // pour simplifier giB0_1 = giB_0_3D(1); // on récupère la direction du premier vecteur giB0_1.Normer(); // on le norme // on crée 2 vecteurs normés, perpendiculaires à ce premier vecteur CoordonneeB & giB0_2 = (*(save_resul.meti_ref_00.giB_)).CoordoB(2); // pour simplifier CoordonneeB & giB0_3 = (*(save_resul.meti_ref_00.giB_)).CoordoB(3); // pour simplifier MathUtil2::Def_vecteurs_plan(giB0_1,giB0_2,giB0_3); // comme la base est orthonormée, les giH sont identiques aux giB (*(save_resul.meti_ref_00.giH_)).Affectation_trans_variance((*(save_resul.meti_ref_00.giB_))); // on affecte les vecteurs qui seront transmis via l'umat giB_0_3D.CoordoB(2)=giB0_2;giB_0_3D.CoordoB(3)=giB0_3; BaseH& a0H = (*(save_resul.meti_ref_00.giH_)); // pour simplifier giH_0_3D.CoordoH(1)=a0H(1);giH_0_3D.CoordoH(2)=a0H(2);giH_0_3D.CoordoH(3)=a0H(3); }; ////--- debug // cout << "\n debug LoiContraintesPlanesDouble::Passage_metrique_ordre1_vers_3("; // cout << "\n giH_0(2): "; giH_0_3D(2).Affiche(); // cout << "\n giH_0(3): "; giH_0_3D(3).Affiche(); //// --- fin debug // on met à jour les deux autres directions // *** pour l'instant on fait la même chose que pour t= 0, pour les deux autres temps // *** , mais il faudra surement améliorer CoordonneeB & giBt_1 = (*(save_resul.meti_ref_t.giB_)).CoordoB(1); // pour simplifier giBt_1 = giB_t_3D(1); // on récupère la direction du premier vecteur giBt_1.Normer(); // on le norme // on crée 2 vecteurs normés, perpendiculaires à ce premier vecteur CoordonneeB & giBt_2 = (*(save_resul.meti_ref_t.giB_)).CoordoB(2); // pour simplifier CoordonneeB & giBt_3 = (*(save_resul.meti_ref_t.giB_)).CoordoB(3); // pour simplifier MathUtil2::Def_vecteurs_plan(giBt_1,giBt_2,giBt_3); // comme la base est orthonormée, les giH sont identiques aux giB // ensuite plus bas, les normes seront changées pour tenir compte des variations d'épaisseur et de largeur (*(save_resul.meti_ref_t.giH_)).Affectation_trans_variance((*(save_resul.meti_ref_t.giB_))); // on affecte les vecteurs qui seront transmis via l'umat giB_t_3D.CoordoB(2)=giBt_2;giB_t_3D.CoordoB(3)=giBt_3; BaseH& a_t_H = (*(save_resul.meti_ref_t.giH_)); // pour simplifier giH_t_3D.CoordoH(1)=a_t_H(1);giH_t_3D.CoordoH(2)=a_t_H(2);giH_t_3D.CoordoH(3)=a_t_H(3); //--- cas à tdt CoordonneeB & giBtdt_1 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(1); // pour simplifier giBtdt_1 = giB_tdt_3D(1); // on récupère la direction du premier vecteur giBtdt_1.Normer(); // on le norme // on crée 2 vecteurs normés, perpendiculaires à ce premier vecteur CoordonneeB & giBtdt_2 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(2); // pour simplifier CoordonneeB & giBtdt_3 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(3); // pour simplifier MathUtil2::Def_vecteurs_plan(giBtdt_1,giBtdt_2,giBtdt_3); giB_tdt_3D.CoordoB(2)=giBtdt_2;giB_tdt_3D.CoordoB(3)=giBtdt_3; // comme la base est orthonormée ici, les giH sont identiques aux giB // ensuite plus bas, les normes seront changées pour tenir compte des variations d'épaisseur et de largeur (*(save_resul.meti_ref_tdt.giH_)).Affectation_trans_variance((*(save_resul.meti_ref_tdt.giB_))); // on affecte les vecteurs qui seront transmis via l'umat giB_tdt_3D.CoordoB(2)=giBtdt_2;giB_tdt_3D.CoordoB(3)=giBtdt_3; BaseH& a_tdt_H = (*(save_resul.meti_ref_tdt.giH_)); // pour simplifier giH_tdt_3D.CoordoH(1)=a_tdt_H(1);giH_tdt_3D.CoordoH(2)=a_tdt_H(2);giH_tdt_3D.CoordoH(3)=a_tdt_H(3); // - les tenseurs métriques: a priori 1 pour les directions 2 et 3, initialement gijBB_0_3D.Coor(2,2)=gijHH_0_3D.Coor(2,2)=gijBB_t_3D.Coor(2,2)=gijHH_t_3D.Coor(2,2) =gijBB_tdt_3D.Coor(2,2)=gijHH_tdt_3D.Coor(2,2)=1.; gijBB_0_3D.Coor(3,3)=gijHH_0_3D.Coor(3,3)=gijBB_t_3D.Coor(3,3)=gijHH_t_3D.Coor(3,3) =gijBB_tdt_3D.Coor(3,3)=gijHH_tdt_3D.Coor(3,3)=1.; // lors d'un premier appel, les variables save_resul.h_tsurh0 et save_resul.hsurh0 // ne sont pas affecté car elles sont issues d'un premier calcul, dans ce cas on les mets arbitrairement à 1 // ensuite elles évolueront, idem pour la largeur bool premier_passage = false; if (save_resul.h_tsurh0 == 0.) { save_resul.h_tsurh0 = 1.; save_resul.hsurh0 = 1.; premier_passage = true; }; if (save_resul.hsurh0 == 0.) // peut arriver dans le cas où on a une erreur dès le début { save_resul.hsurh0 = save_resul.h_tsurh0;}; // on réinitialise // on peut avoir la même chose en b, indépendamment, lorsque l'on passe de contrainte plane // à doublement plane if (save_resul.b_tsurb0 == 0.) { save_resul.b_tsurb0 = 1.; save_resul.bsurb0 = 1.; premier_passage = true; }; if (save_resul.bsurb0 == 0.) // peut arriver dans le cas où on a une erreur dès le début { save_resul.bsurb0 = save_resul.b_tsurb0;}; // on réinitialise // on calcul les vecteur 2 et 3 naturels et duals giB_t_3D.CoordoB(2) *= save_resul.b_tsurb0; giH_t_3D.CoordoH(2) /= save_resul.b_tsurb0; giB_tdt_3D.CoordoB(2) *= save_resul.bsurb0; giH_tdt_3D.CoordoH(2) /= save_resul.bsurb0; giB_t_3D.CoordoB(3) *= save_resul.h_tsurh0; giH_t_3D.CoordoH(3) /= save_resul.h_tsurh0; giB_tdt_3D.CoordoB(3) *= save_resul.hsurh0; giH_tdt_3D.CoordoH(3) /= save_resul.hsurh0; // - et les tenseurs métriques à t et tdt, comme les vecteurs en épaisseurs et largeurs // sont normées initialement, seule l'intensité // des normales est à mettre à jour compte tenue de la variation d'épaisseurs double b_tsurb0_carre = save_resul.b_tsurb0 * save_resul.b_tsurb0; gijBB_t_3D.Coor(2,2)=b_tsurb0_carre; gijHH_t_3D.Coor(2,2)= 1./b_tsurb0_carre; double bsurb0_carre = save_resul.bsurb0 * save_resul.bsurb0; gijBB_tdt_3D.Coor(2,2) = bsurb0_carre;gijHH_tdt_3D.Coor(2,2) = 1. / bsurb0_carre; double h_tsurh0_carre = save_resul.h_tsurh0 * save_resul.h_tsurh0; gijBB_t_3D.Coor(3,3)=h_tsurh0_carre; gijHH_t_3D.Coor(3,3)= 1./h_tsurh0_carre; double hsurh0_carre = save_resul.hsurh0 * save_resul.hsurh0; gijBB_tdt_3D.Coor(3,3) = hsurh0_carre;gijHH_tdt_3D.Coor(3,3) = 1. / hsurh0_carre; }; // passage des informations liées à la déformation de 1 vers 3, et variation de volume // utilisée pour les méthodes 1 et 2 // entre autre: calcul du jacobien 3D en fonction de l'élongation 1D et des variations h/h0 et b/b0 void LoiContraintesPlanesDouble::Passage_deformation_volume_ordre1_vers_3 // (int cas, TenseurBB& DepsBB,TenseurBB & epsBB_tdt,Tableau * d_epsBB (TenseurBB& DepsBB,TenseurBB & epsBB_tdt,Tableau * d_epsBB ,TenseurBB & delta_epsBB,const double& jacobien_0,double& jacobien ,Vecteur* d_jacobien_tdt,const double& jacobien_t) { // au début on complète avec des 0, puis dans un second temps on tient compte de la déformation d'épaisseur eps33 bool plusZero = true; Deps_BB_3D.Affectation_trans_dimension(*((Tenseur1BB*) &DepsBB),plusZero); eps_BB_3D.Affectation_trans_dimension(*((Tenseur1BB*) &epsBB_tdt),plusZero); delta_eps_BB_3D.Affectation_trans_dimension(*((Tenseur1BB*) &delta_epsBB),plusZero); // récup du conteneur spécifique SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul); if(d_epsBB != NULL) { int taille = d_epsBB->Taille(); // redimensionnement éventuel int ta_d_eps_BB_3D = d_eps_BB_3D.Taille(); if (ta_d_eps_BB_3D != taille) { // cela veut dire que tous les tableaux sont mal dimensionnés d_eps_BB_3D.Change_taille(taille); d_eps_BB_3D_P.Change_taille(taille); for (int i=1;i<=taille;i++) {d_eps_BB_3D_P(i) = &(d_eps_BB_3D(i));} }; // passage 1D 3D for (int i=1;i<=taille;i++) { d_eps_BB_3D(i).Affectation_trans_dimension(*((Tenseur1BB*) (*d_epsBB)(i)),plusZero);} if (save_resul.d_hsurh0.Taille() != taille) save_resul.d_hsurh0.Change_taille(taille); // donc à 0 la première fois if (save_resul.d_bsurb0.Taille() != taille) save_resul.d_bsurb0.Change_taille(taille); // donc à 0 la première fois }; // -- calcul du jacobien 3D /* la partie cas = 2: ne fonctionne pas bien le choix est fait d'utiliser les variations d'épaisseur et de largeur // dans le cas d'un calcul dans une direction quelconque // on utilise la déformation mécanique sauvegardée pour calculer les jacobiens if (cas == 2) { //récup de eps_mecaBB_t Tenseur3BB& eps_mecaBB_t = *((Tenseur3BB*) (save_resul.eps_mecaBB_t)); // --- on s'occupe des jacobiens // à t le jacobien est calculée à partir de la déformation supposée d'Almansi // ici il s'agit du jacobien relatif au comportement mécanique // |J| = sqrt(det(2 * eps_ij_t + g_ij(0))) // calcul de la matrice correspondante à (2 * eps_ij_t + g_ij(0)) gij_meca_BB_t = (2. * eps_mecaBB_t + (*(umat_cont_3D->gijBB_0))); gij_meca_BB_t.Matrice_composante(mat_inter); // calcul du jacobien jacobien_t_3D = sqrt(Dabs(mat_inter.Determinant())); // on fait de même pour le jacobien initial ce qui permet d'être cohérent // avec la métrique initiale et la déformation au sens d'Almansi (umat_cont_3D->gijBB_0)->Matrice_composante(mat_inter); jacobien_0_3D = sqrt(Dabs(mat_inter.Determinant())); // le jacobien à tdt sera calculé pendant la résolution } else if (cas == 1) */ {// première phase on se contente de recopier, ce qui suppose une épaisseur = 1. jacobien_0_3D = jacobien_0; // -> partie 1D jacobien_tdt_3D = sauve_jacobien1D_tdt = jacobien; // ici, l'épaisseur initiale h0 est toujours 1., donc h/h0 = également h et idem pour b/b0 jacobien_tdt_3D *= save_resul.hsurh0 * save_resul.bsurb0; // même travail pour t jacobien_t_3D = jacobien_t; jacobien_t_3D *= save_resul.h_tsurh0 * save_resul.b_tsurb0; }; // recup de l'incrément de temps double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant(); double unSurDeltat=0; if (Abs(deltat) >= ConstMath::trespetit) {unSurDeltat = 1./deltat;} else // si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand { // non un pas de temps doit être positif !! or certaine fois il peut y avoir des pb if (unSurDeltat < 0) { cout << "\n le pas de temps est négatif !! "; }; unSurDeltat = ConstMath::tresgrand; }; // cas des def, delta def et D if (!calcul_en_3D_via_direction_quelconque) { //dans le cas classique, on dispose de la variation d'épaisseur et de largeur pour déterminer les def switch (type_de_deformation) {case DEFORMATION_STANDART : case DEFORMATION_POUTRE_PLAQUE_STANDART : // cas d'une déformation d'Almansi { // epsBB33 = 1/2 * (1. - (h0/h)^2), en orthonormee // dans le repère local: epsBB33 = 1/2 * (h^2 - 1.), or h0=1. donc : epsBB33 = 1/2 * ((h/h0)^2 - 1.) eps_BB_3D.Coor(3,3) = 0.5 * (save_resul.hsurh0 * save_resul.hsurh0 - 1.); delta_eps_BB_3D.Coor(3,3) = 0.5 * (save_resul.hsurh0 * save_resul.hsurh0 - save_resul.h_tsurh0 * save_resul.h_tsurh0); // idem pour la largeur eps_BB_3D.Coor(2,2) = 0.5 * (save_resul.bsurb0 * save_resul.bsurb0 - 1.); delta_eps_BB_3D.Coor(2,2) = 0.5 * (save_resul.bsurb0 * save_resul.bsurb0 - save_resul.b_tsurb0 * save_resul.b_tsurb0); Deps_BB_3D.Coor(3,3) = delta_eps_BB_3D(3,3)* unSurDeltat; Deps_BB_3D.Coor(2,2) = delta_eps_BB_3D(2,2)* unSurDeltat; // dans le cas où on calcule les variations, on intègre également les variations de eps33 et eps22 if (d_epsBB != NULL) { Vecteur& d_hsurh0 = save_resul.d_hsurh0; Vecteur& d_bsurb0 = save_resul.d_bsurb0; int taille = d_epsBB->Taille(); for (int i=1;i<=taille;i++) {d_eps_BB_3D(i).Coor(3,3)= save_resul.hsurh0 * d_hsurh0(i); d_eps_BB_3D(i).Coor(2,2)= save_resul.bsurb0 * d_bsurb0(i); } }; }; break; case DEFORMATION_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEFORMATION_CUMU_LOGARITHMIQUE : // cas d'une def logarithmique ou une approximation { eps_BB_3D.Coor(3,3) = log(save_resul.hsurh0); delta_eps_BB_3D.Coor(3,3) = log(save_resul.hsurh0) - log(save_resul.h_tsurh0); // idem pour la largeur eps_BB_3D.Coor(2,2) = log(save_resul.bsurb0); delta_eps_BB_3D.Coor(2,2) = log(save_resul.bsurb0) - log(save_resul.b_tsurb0); Deps_BB_3D.Coor(3,3) = delta_eps_BB_3D(3,3)* unSurDeltat; Deps_BB_3D.Coor(2,2) = delta_eps_BB_3D(2,2)* unSurDeltat; // dans le cas où on calcule les variations, on intègre également les variations de eps33 et eps22 if (d_epsBB != NULL) { Vecteur& d_hsurh0 = save_resul.d_hsurh0; Vecteur& d_bsurb0 = save_resul.d_bsurb0; int taille = d_epsBB->Taille(); // d_eps_BB_3D(3,3) = d_hsurh0 * exp(save_resul.hsurh0) for (int i=1;i<=taille;i++) {d_eps_BB_3D(i).Coor(3,3)= d_hsurh0(i) * eps_BB_3D(3,3); d_eps_BB_3D(i).Coor(2,2)= d_bsurb0(i) * eps_BB_3D(2,2); } }; }; break; default : cout << "\nErreur : type de deformation qui n'est pas actuellement pris en compte, type= " << Nom_type_deformation(type_de_deformation); cout << "\n LoiContraintesPlanesDouble::Passage_deformation_volume_ordre1_vers_3 \n"; Sortie(1); }; } else // dans le cas où on travaille dans le repère gi en 3D on dispose directement des infos de déformation {//récup de eps_mecaBB Tenseur3BB& eps_mecaBB_t = *((Tenseur3BB*) (save_resul.eps_mecaBB_t)); Tenseur3BB& eps_mecaBB = *((Tenseur3BB*) (save_resul.eps_mecaBB)); // on sauve ce qu'il y a dans la direction 11 pour éviter les erreurs d'arrondis double eps11= (*ptintmeca.EpsBB())(1,1); double Deps11= (*ptintmeca.DepsBB())(1,1); double delta_eps11= (*ptintmeca.DeltaEpsBB())(1,1); // les manips entre tenseurs (*ptintmeca.EpsBB()) = eps_mecaBB; (*ptintmeca.DeltaEpsBB()) = eps_mecaBB - eps_mecaBB_t; (*ptintmeca.DepsBB()) = (*ptintmeca.DeltaEpsBB()) * unSurDeltat; // récup des valeurs sauvegardées (normalement ne devrait pas changer...) (*ptintmeca.EpsBB()).Coor(1,1) = eps11; (*ptintmeca.DeltaEpsBB()).Coor(1,1) = delta_eps11; (*ptintmeca.DepsBB()).Coor(1,1) = Deps11; }; if(d_jacobien_tdt != NULL) { Vecteur& d_hsurh0 = save_resul.d_hsurh0; Vecteur& d_bsurb0 = save_resul.d_bsurb0; // jacobien_tdt_3D = hsurh0 * jacobien_1D // --> d_jacobien_tdt_3D = d_hsurh0 * jacobien_1D + hsurh0 * d_jacobien_1D d_jacobien_tdt_3D = d_hsurh0 * save_resul.bsurb0 * jacobien + save_resul.hsurh0 * d_bsurb0 * jacobien + save_resul.hsurh0 * save_resul.bsurb0 * (*d_jacobien_tdt); }; //---debug //cout << "\n LoiContraintesPlanesDouble::Passage_deformation_volume_ordre1_vers_3, eps_BB_3D(3,3) = " // << eps_BB_3D(3,3) << " jacobien_tdt_3D= " << jacobien_tdt_3D; // --- fin debug }; // mise à jour des informations liées à la déformation de 1 vers 3 // uniquement méthode 1 void LoiContraintesPlanesDouble::Mise_a_jour_deformations_et_Jacobien_en_3D () { // récup du conteneur spécifique SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul); // -- calcul du jacobien 3D // première phase on se contente de recopier, ce qui suppose une épaisseur = 1. et une largeur = 1. jacobien_tdt_3D = sauve_jacobien1D_tdt * save_resul.hsurh0 * save_resul.bsurb0; // -- maintenant on tient compte de la déformation d'épaisseur switch (type_de_deformation) {case DEFORMATION_STANDART : case DEFORMATION_POUTRE_PLAQUE_STANDART : // cas d'une déformation d'Almansi { // epsBB33 = 1/2 * (1. - (h0/h)^2), en orthonormee // dans le repère local: epsBB33 = 1/2 * (h^2 - 1.), or h0=1. donc : epsBB33 = 1/2 * ((h/h0)^2 - 1.) eps_BB_3D.Coor(3,3) = 0.5 * (save_resul.hsurh0 * save_resul.hsurh0 - 1.); delta_eps_BB_3D.Coor(3,3) = 0.5 * (save_resul.hsurh0 * save_resul.hsurh0 - save_resul.h_tsurh0 * save_resul.h_tsurh0); // idem pour la direction 2 eps_BB_3D.Coor(2,2) = 0.5 * (save_resul.bsurb0 * save_resul.bsurb0 - 1.); delta_eps_BB_3D.Coor(2,2) = 0.5 * (save_resul.bsurb0 * save_resul.bsurb0 - save_resul.b_tsurb0 * save_resul.b_tsurb0); }; break; case DEFORMATION_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEFORMATION_CUMU_LOGARITHMIQUE : // cas d'une def logarithmique ou une approximation { eps_BB_3D.Coor(3,3) = log(save_resul.hsurh0); delta_eps_BB_3D.Coor(3,3) = log(save_resul.hsurh0) - log(save_resul.h_tsurh0); // idem pour la direction 2 eps_BB_3D.Coor(2,2) = log(save_resul.bsurb0); delta_eps_BB_3D.Coor(2,2) = log(save_resul.bsurb0) - log(save_resul.b_tsurb0); }; break; default : cout << "\nErreur : type de deformation qui n'est pas actuellement pris en compte, type= " << Nom_type_deformation(type_de_deformation); cout << "\n LoiContraintesPlanesDouble::Passage_deformation_volume_ordre1_vers_3 \n"; Sortie(1); }; // -- cas de la vitesse de déformation // recup de l'incrément de temps double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant(); double unSurDeltat=0; if (Abs(deltat) >= ConstMath::trespetit) {unSurDeltat = 1./deltat;} else // si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand { // non un pas de temps doit être positif !! or certaine fois il peut y avoir des pb if (unSurDeltat < 0) { cout << "\n le pas de temps est négatif !! "; }; unSurDeltat = ConstMath::tresgrand; }; Deps_BB_3D.Coor(2,2) = delta_eps_BB_3D(2,2) * unSurDeltat; Deps_BB_3D.Coor(3,3) = delta_eps_BB_3D(3,3) * unSurDeltat; }; // calcul de la déformation d'épaisseur et de largeur // cas de la méthode 1 void LoiContraintesPlanesDouble::Calcul_eps_trans_parVarVolume1(Tenseur3BH& sigBH_t,double& jaco_1D_0,const double& module_compressibilite,double& jaco_1D_tdt ,Tenseur3BH& sigBH,double& jaco_1D_t) { // récup des infos spécifiques SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul); // on utilise la relation: (V-V_0)/V = trace(sigma)/3 /K_moy // avec trace(sigma) en 1D = idem en 3D car on est en contraintes doublement planes // jacobien 1D = la longueur donc le volume = jacobien 1D * h * b -> (jaco1D_tdt * h * b -jaco1D_0*h_0*b_0) = delta_V // on considère de plus que l'on est isotrope donc h/h_0 = b/b_0 // en appelant B= trace(sigma)/3 /K_moy on a: // (h/h_0)^2 = jaco1D_0 / jaco1D_tdt * 1./(1.-B) d'où la déformation logarithmique if (Dabs(module_compressibilite)>0.) // si le module est nul, cela signifie qu'il n'est pas disponible { //double B = (sigBH(1,1)+sigBH(2,2)) / (3. * module_compressibilite ); double log_VsurV0 = (sigBH.Trace()) / (3. * module_compressibilite ); double exp_log_VsurV0 = exp(log_VsurV0); double hSurh_0 = sqrt((jaco_1D_0 / jaco_1D_tdt) * exp_log_VsurV0) ; // on test les mini-maxi if (hSurh_0 < mini_hsurh0) {if (Permet_affichage() > 3) {cout << "\n *** attention hsurh0 " << hSurh_0 << "est inferieur a la limite fixee "< maxi_hsurh0) {if (Permet_affichage() > 3) {cout << "\n *** attention bsurb0 " << maxi_hsurh0 << "est superieur a la limite fixee "< (jaco1D_tdt * h * b -jaco1D_t*h_t*b_t) = delta_V // // on considère de plus que l'on est isotrope donc delta_h/h = delta_b/b d'où h/h_t = b/b_t // // en appelant B= trace(delta_sigma)/3 /K / (h_t*b_t) on a: // // (h/h_t)^2 = jaco1D_t / (jaco1D_tdt * (1.-B)) // if (Dabs(module_compressibilite)>0.) // si le module est nul, cela signifie qu'il n'est pas disponible // { //double B = (sigBH(1,1)+sigBH(2,2)) / (3. * module_compressibilite ); // double B = (sigBH(1,1)-sigBH_t(1,1)) / (3. * module_compressibilite ); // double hSurh_t = sqrt((jaco_1D_t / jaco_1D_tdt) / (1.-B)) ; // // save_resul.hsurh0 = hSurh_t * save_resul.h_tsurh0; // save_resul.bsurb0 = hSurh_t * save_resul.b_tsurb0; // élongation d'épaisseur // } // else // { save_resul.hsurh0 = save_resul.bsurb0 = 1.;}; }; // calcul de la déformation d'épaisseur et de largeur // cas de la méthode 2 void LoiContraintesPlanesDouble::Calcul_eps_trans_parVarVolume2(Tenseur3BH& sigBH_t,double& jaco_1D_0,const double& module_compressibilite,double& jaco_1D_tdt ,Tenseur3BH& sigBH,double& jaco_1D_t) { // récup des infos spécifiques SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul); // on utilise la relation: (V-V_0)/V = trace(sigma)/3 /K_moy // avec trace(sigma) en 1D = idem en 3D car on est en contraintes doublement planes // jacobien 1D = la longueur donc le volume = jacobien 1D * h * b -> (jaco1D_tdt * h * b -jaco1D_0*h_0*b_0) = delta_V // on considère de plus que l'on est isotrope donc h/h_0 = b/b_0 // en appelant B= trace(sigma)/3 /K_moy on a: // (h/h_0)^2 = jaco1D_0 / jaco1D_tdt * 1./(1.-B) d'où la déformation logarithmique if (Dabs(module_compressibilite)>0.) // si le module est nul, cela signifie qu'il n'est pas disponible { //double B = (sigBH(1,1)+sigBH(2,2)) / (3. * module_compressibilite ); double log_VsurV0 = (sigBH.Trace()) / (3. * module_compressibilite ); double exp_log_VsurV0 = exp(log_VsurV0); double hSurh_0 = sqrt((jaco_1D_0 / jaco_1D_tdt) * exp_log_VsurV0) ; // on test les mini-maxi if (hSurh_0 < mini_hsurh0) {if (Permet_affichage() > 3) {cout << "\n *** attention hsurh0 " << hSurh_0 << "est inferieur a la limite fixee "< maxi_hsurh0) {if (Permet_affichage() > 3) {cout << "\n *** attention bsurb0 " << maxi_hsurh0 << "est superieur a la limite fixee "< (jaco1D_tdt * h * b -jaco1D_t*h_t*b_t) = delta_V // // on considère de plus que l'on est isotrope donc delta_h/h = delta_b/b d'où h/h_t = b/b_t // // en appelant B= trace(delta_sigma)/3 /K / (h_t*b_t) on a: // // (h/h_t)^2 = jaco1D_t / (jaco1D_tdt * (1.-B)) // if (Dabs(module_compressibilite)>0.) // si le module est nul, cela signifie qu'il n'est pas disponible // { //double B = (sigBH(1,1)+sigBH(2,2)) / (3. * module_compressibilite ); // double B = (sigBH(1,1)-sigBH_t(1,1)) / (3. * module_compressibilite ); // double hSurh_t = sqrt((jaco_1D_t / jaco_1D_tdt) / (1.-B)) ; // // save_resul.hsurh0 = hSurh_t * save_resul.h_tsurh0; // save_resul.bsurb0 = hSurh_t * save_resul.b_tsurb0; // élongation d'épaisseur // } // else // { save_resul.hsurh0 = save_resul.bsurb0 = 1.;}; }; // calcul des déformations d'épaisseur et de largeur et des variations // méthode 1 void LoiContraintesPlanesDouble::Calcul_d_eps_trans_parVarVolume(double& jaco_1D_0,const double& module_compressibilite,double& jaco_1D_tdt ,TenseurHH& sigHH_,Vecteur& d_jaco_1D ,Tableau & d_sigHH,Tableau & d_gijBB_tdt,TenseurBB & gijBB_) { // récup des infos spécifiques SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul); // on utilise la relation: log(V/V0) = trace(sigma)/3 /K_moy // avec trace(sigma) en 1D = idem en 3D car on est en contraintes planes double // jacobien 1D = la longueur, donc le volume: V = jacobien 1D * h * b -> (jaco1D_tdt * h * b)/(jaco1D_0*h_0*b_0) = V/V0 // en appelant log_VsurV0= trace(sigma)/3 /K_moy on a: // h/h_0 * b/b_0= jaco1D_0 / jaco1D_tdt * exp(log_VsurV0) // ici sans info sup, on considère une loi isotrope d'où h/h_0 = b/b_0 // -> h/h_0 = (jaco1D_0 / jaco1D_tdt * exp(log_VsurV0))^(0.5) if (Dabs(module_compressibilite)>0.) // si le module est nul, cela signifie qu'il n'est pas disponible { const Tenseur1BB & gijBB = *((Tenseur1BB*) &gijBB_); // pour simplifier const Tenseur1HH & sigHH = *((Tenseur1HH*) &sigHH_); // pour simplifier Tenseur1BH sigBH = gijBB * sigHH; double log_VsurV0 = (sigBH.Trace()) / (3. * module_compressibilite ); double exp_log_VsurV0 = exp(log_VsurV0); double hSurh_0 = sqrt((jaco_1D_0 / jaco_1D_tdt) * exp_log_VsurV0) ; // on test les mini-maxi if (hSurh_0 < mini_hsurh0) {if (Permet_affichage() > 3) {cout << "\n *** attention hsurh0 " << hSurh_0 << "est inferieur a la limite fixee "< maxi_hsurh0) {if (Permet_affichage() > 3) {cout << "\n *** attention bsurb0 " << maxi_hsurh0 << "est superieur a la limite fixee "<= ConstMath::trespetit) {unSurDeltat = 1./deltat;} else // si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand { // non un pas de temps doit être positif !! or certaine fois il peut y avoir des pb if (unSurDeltat < 0) { cout << "\n le pas de temps est négatif !! "; }; unSurDeltat = ConstMath::tresgrand; }; // ---calcul des invariants de déformation et de vitesse de déformation Tenseur3BH espBH = eps_BB_3D * gijHH_tdt_3D; Tenseur3BH delta_espBH = delta_eps_BB_3D * gijHH_tdt_3D; save_resul.epsInvar(1) = espBH.Trace(); save_resul.epsInvar(2) = espBH.II(); save_resul.epsInvar(3) = espBH.Det(); save_resul.depsInvar(1) = unSurDeltat * delta_espBH.Trace(); save_resul.depsInvar(2) = unSurDeltat * delta_espBH.II(); save_resul.depsInvar(3) = unSurDeltat * delta_espBH.Det(); // cas des grandeurs cumulées (cf. la classe Deformation) // tableau relatif aux différentes grandeurs de type def scalaires équivalentes // def_equi(1) = deformation cumulée = somme des sqrt(2./3. * (delta_eps_barre_BH && delta_eps_barre_BH)) ; // def_equi(2) = deformation duale de la contrainte de mises = sqrt(2./3. * (eps_barre_BH && eps_barre_BH)) ; // def_equi(3) = niveau maxi atteind par def_equi(2) // def_equi(4) = delta def cumulée = sqrt(2./3. * (delta_eps_barre_BH && delta_eps_barre_BH)); double delta_eps_equi = sqrt(2./3. * ( (delta_espBH && delta_espBH) - Sqr(delta_espBH.Trace()) /3. )); save_resul.def_equi(1) = save_resul.def_equi_t(1) + delta_eps_equi ; save_resul.def_equi(2) = sqrt(2./3. * (espBH && espBH)) ; if (save_resul.def_equi(2) > save_resul.def_equi_t(3)) save_resul.def_equi(3) = save_resul.def_equi(2); save_resul.def_equi(4) = delta_eps_equi; }; // calcul de la fonction résidu de la résolution de l'équation constitutive: sig^ef(h/h0,b/b0) = 0 // avec "e,f" = 2 et 3 // h/h0, bb0 sont les inconnues du problème et sont l'élément d'entrée: // l'argument test ramène // . 1 si le calcul a été ok, -1 s'il y a eu un pb, mais on peut continuer, 0 s'il y a eu un pb // fatal, qui invalide le calcul du résidu Vecteur& LoiContraintesPlanesDouble::Residu_constitutif (const double & alpha,const Vecteur & x, int& test) { // récup du conteneur spécifique SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul); test = 1; // init par défaut // %%% on met à jour les conteneurs locaux en fonction des paramètres d'entrée %%% // -- prise en compte de la variation de la déformation d'épaisseur // pour nous ici on travaille avec giB_03D qui est normé et = 1 c-a-d h0 = 1 // donc à tdt il faut multiplier par h/h0 à tdt double bsurb0 = x(1);double hsurh0 = x(2); // vérif des grandeurs bool erreur_sortie = false; // pour gestion de sortie d'infos supplémentaires if (Limitation_h_b(hsurh0,bsurb0)) {if (Permet_affichage() > 3) cout << "\n LoiContraintesPlanesDouble::Residu_constitutif(... " << endl; erreur_sortie = true; test = -1; // l'erreur n'est pas fatale mais elle signifie que ce n'est pas très normal !! }; if (erreur_sortie && (Permet_affichage() > 4)) {cout << "\n giH_tdt: " << *(umat_cont_3D->giH_tdt); cout << "\n defBB: ";eps_BB_3D.Ecriture(cout); cout << "\n DepsBB: ";Deps_BB_3D.Ecriture(cout); }; save_resul.hsurh0 = hsurh0; // sauvegarde de l'élongation d'épaisseur save_resul.bsurb0 = bsurb0; // sauvegarde de l'élongation de largeur CoordonneeB & giBtdt_2 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(2); // pour simplifier CoordonneeB & giBtdt_3 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(3); // pour simplifier giB_tdt_3D.CoordoB(3) = giBtdt_3 * hsurh0; giH_tdt_3D.CoordoH(3) = (giBtdt_3 / hsurh0).Bas_haut(); giB_tdt_3D.CoordoB(2) = giBtdt_2 * bsurb0; giH_tdt_3D.CoordoH(2) = (giBtdt_2 / bsurb0).Bas_haut(); // - et les tenseurs métriques à t et tdt, comme les vecteurs en épaisseurs // et en largeurs sont normées initialement, seule l'intensité // des normales est à mettre à jour compte tenue de la variation d'épaisseurs et de largeur double hsurh0_2 = hsurh0 * hsurh0; gijBB_tdt_3D.Coor(3,3) = hsurh0_2; gijHH_tdt_3D.Coor(3,3) = 1. / hsurh0_2; double bsurb0_2 = bsurb0 * bsurb0; gijBB_tdt_3D.Coor(2,2) = bsurb0_2; gijHH_tdt_3D.Coor(2,2) = 1. / bsurb0_2; // mise à jour des informations liées à la déformation de 1 vers 3 Mise_a_jour_deformations_et_Jacobien_en_3D(); // calcul des invariants de déformation et de vitesse de déformation, et les def cumulées // correspondant aux cas 3D Calcul_invariants_et_def_cumul(); // initialisation du comportement tangent / au def d_sigma_deps_3D.Inita(0.); // appel du calcul de sig et dsig bool en_base_orthonormee = false; // ici les tenseurs ne sont pas forcément en orthonormee lois_interne->Calcul_dsigma_deps (en_base_orthonormee, sig_HH_t_3D,Deps_BB_3D,eps_BB_3D ,delta_eps_BB_3D,jacobien_0_3D,jacobien_tdt_3D ,sig_HH_3D,d_sigma_deps_3D ,save_resul.l_energ,save_resul.l_energ_t,module_compressibilite_3D ,module_cisaillement_3D,*umat_cont_3D); // retour des grandeurs voulues residu(1) = sig_HH_3D(2,2); residu(2) = sig_HH_3D(3,3); return residu; }; // calcul de la matrice tangente de la résolution de l'équation constitutive: sig^ef(h/h0,b/b0) = 0 // avec "e,f" = 2 et 3 // h/h0, bb0 sont les inconnues du problème et sont l'élément d'entrée: // l'argument test ramène // . 1 si le calcul a été ok, -1 s'il y a eu un pb, mais on peut continuer, 0 s'il y a eu un pb // fatal, qui invalide le calcul du résidu et de la dérivée Mat_abstraite& LoiContraintesPlanesDouble::Mat_tangente_constitutif (const double & alphap,const Vecteur & x, Vecteur& residu, int& test) { // récup du conteneur spécifique SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul); test = 1; // init par défaut // %%% on met à jour les conteneurs locaux en fonction des paramètres d'entrée %%% // -- prise en compte de la variation de la déformation d'épaisseur et de largeur // pour nous ici on travail avec giB_03D qui est normé et = 1 c-a-d h0 = b0 = 1 // donc à tdt il faut multiplier par h/h0 à tdt et idem pour b/b0 double bsurb0 = x(1);double hsurh0 = x(2); // vérif des grandeurs bool erreur_sortie = false; // pour gestion de sortie d'infos supplémentaires if (Limitation_h_b(hsurh0,bsurb0)) {if (Permet_affichage() > 3) cout << "\n LoiContraintesPlanesDouble::Mat_tangente_constitutif(... " << endl; erreur_sortie = true; test = -1; // l'erreur n'est pas fatale mais elle signifie que ce n'est pas très normal !! }; if (erreur_sortie && (Permet_affichage() > 4)) {cout << "\n giH_tdt: " << *(umat_cont_3D->giH_tdt); cout << "\n defBB: ";eps_BB_3D.Ecriture(cout); cout << "\n DepsBB: ";Deps_BB_3D.Ecriture(cout); }; save_resul.hsurh0 = hsurh0; // sauvegarde de l'élongation d'épaisseur save_resul.bsurb0 = bsurb0; // sauvegarde de l'élongation de largeur CoordonneeB & giBtdt_2 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(2); // pour simplifier CoordonneeB & giBtdt_3 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(3); // pour simplifier giB_tdt_3D.CoordoB(3) = giBtdt_3 * hsurh0; giH_tdt_3D.CoordoH(3) = (giBtdt_3 / hsurh0).Bas_haut(); giB_tdt_3D.CoordoB(2) = giBtdt_2 * bsurb0; giH_tdt_3D.CoordoH(2) = (giBtdt_2 / bsurb0).Bas_haut(); // - et les tenseurs métriques à t et tdt, comme les vecteurs en épaisseurs sont normées initialement, seule l'intensité // des normales est à mettre à jour compte tenue de la variation d'épaisseurs double hsurh0_2 = hsurh0 * hsurh0; gijBB_tdt_3D.Coor(3,3) = hsurh0_2; gijHH_tdt_3D.Coor(3,3) = 1. / hsurh0_2; double bsurb0_2 = bsurb0 * bsurb0; gijBB_tdt_3D.Coor(2,2) = bsurb0_2; gijHH_tdt_3D.Coor(2,2) = 1. / bsurb0_2; // mise à jour des informations liées à la déformation de 1 vers 3 Mise_a_jour_deformations_et_Jacobien_en_3D(); // calcul des invariants de déformation et de vitesse de déformation, et les def cumulées // correspondant aux cas 3D Calcul_invariants_et_def_cumul(); // initialisation du comportement tangent / au def d_sigma_deps_3D.Inita(0.); // appel du calcul de sig et dsig bool en_base_orthonormee = false; // ici les tenseurs ne sont pas a priori en orthonormee lois_interne->Calcul_dsigma_deps (en_base_orthonormee, sig_HH_t_3D,Deps_BB_3D,eps_BB_3D ,delta_eps_BB_3D,jacobien_0_3D,jacobien_tdt_3D ,sig_HH_3D,d_sigma_deps_3D ,save_resul.l_energ,save_resul.l_energ_t,module_compressibilite_3D ,module_cisaillement_3D,*umat_cont_3D); // retour des grandeurs voulues residu(1) = sig_HH_3D(2,2); residu(2) = sig_HH_3D(3,3); // la matrice tangente dépend du type de mesure de déformation, avec la relation // en appelant hb/hb0 les deux ddl: h/h0 et b/b0, i,j,k et l variant de 2 à 3 // d_sig^ij(h/h0,b/b0) / d_ddl = d_sig^ij(h/h0,b/b0)/d_eps_kl * d_eps_kl/d_ddl // comme les repères restent orthogonales à tous moments il n'y a pas de couplage entre les directions 2 et 3 Vecteur d_eps_kl_sur_d_ddl(2,0.); // init // -- choix en fonction du type de déformation switch (type_de_deformation) {case DEFORMATION_STANDART : case DEFORMATION_POUTRE_PLAQUE_STANDART : // cas d'une déformation d'Almansi { // epsBB33 = 1/2 * (1. - (h0/h)^2), en orthonormee // dans le repère local: epsBB33 = 1/2 * (h^2 - 1.), or h0=1. donc : epsBB33 = 1/2 * ((h/h0)^2 - 1.) // idem pour la direction 22 d_eps_kl_sur_d_ddl(1) = bsurb0;d_eps_kl_sur_d_ddl(2) = hsurh0; }; break; case DEFORMATION_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEFORMATION_CUMU_LOGARITHMIQUE : // cas d'une def logarithmique ou une approximation: eps_BB_3D(3,3) = log(hsurh0); { d_eps_kl_sur_d_ddl(1) = log(bsurb0);d_eps_kl_sur_d_ddl(2) = log(hsurh0); }; break; default : cout << "\nErreur : type de deformation qui n'est pas actuellement pris en compte, type= " << Nom_type_deformation(type_de_deformation); cout << "\n LoiContraintesPlanesDouble::Mat_tangente_constitutif \n"; Sortie(1); }; // d'où la dérivée du résidu, en considérant qu'il n'y a pas de couplage entre les directions 2 et 3 // c-a-d d_eps33_sur_d_bSurb0 = 0 et d_eps22_sur_d_hSurh0 = 0 // non c'est faux, du à la partie sphérique des contraintes par exemple, il faut tout considérer derResidu(1,1) = d_sigma_deps_3D(2,2,2,2) * d_eps_kl_sur_d_ddl(1); derResidu(1,2) = d_sigma_deps_3D(2,2,3,3) * d_eps_kl_sur_d_ddl(2); derResidu(2,1) = d_sigma_deps_3D(3,3,2,2) * d_eps_kl_sur_d_ddl(1); derResidu(2,2) = d_sigma_deps_3D(3,3,3,3) * d_eps_kl_sur_d_ddl(2); return derResidu; }; //--- cas de la résolution de l'équation sigij(eps_meca)*V_j{.l}=0, l=2 et 3 // calcul de la fonction résidu de la résolution de l'équation constitutive // l'argument test ramène // . 1 si le calcul a été ok, -1 s'il y a eu un pb, mais on peut continuer, 0 s'il y a eu un pb // fatal, qui invalide le calcul du résidu Vecteur& LoiContraintesPlanesDouble::Residu_constitutif_3D(const double & alpha,const Vecteur & x, int& test) { // récup du conteneur spécifique SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul); test = 1; // init par défaut //récup de eps_mecaBB_t Tenseur3BB& eps_mecaBB_t = *((Tenseur3BB*) (save_resul.eps_mecaBB_t)); // les inconnues sont les déformations mécaniques {epsilon'}_kl; // (k,l) = (22) (33) (12) : on a donc 3 inconnues que l'on suppose rangées dans cette ordre // c-a-d les def qui vont servir dans l'appel de la loi 3D eps_P_BB.Coor(1,2) = x(3);eps_P_BB.Coor(2,2) = x(1);eps_P_BB.Coor(3,3) = x(2); eps_P_BB.Coor(1,3) = 0.; eps_P_BB.Coor(2,3) = 0.; if (Permet_affichage() > 4) {cout << "\n eps_P_BB (dans Va) avant limitation : " ;eps_P_BB.Ecriture(cout);} // vérif des grandeurs et calcul des variations d'épaisseur et de largeur double& hsurh0 = save_resul.hsurh0;double& bsurb0 = save_resul.bsurb0; // la méthode va mettre à jour les variations bsurb0 et hsurh0 et le jacobien bool erreur_sortie = false; // pour gestion de sortie d'infos supplémentaires int info_limit = Calcul_et_Limitation2_h_b(hsurh0,eps_P_BB,bsurb0,jacobien_tdt_3D,jacobien_0_3D); if (info_limit) {if (Permet_affichage() > 3) cout << "\n LoiContraintesPlanesDouble::Residu_constitutif_3D(... " << endl; erreur_sortie = true;test = info_limit - 2; }; if (erreur_sortie && (Permet_affichage() > 4)) {cout << "\n giH_tdt: " << *(umat_cont_3D->giH_tdt); cout << "\n eps_BB_3D: ";eps_BB_3D.Ecriture(cout); cout << "\n DepsBB: ";Deps_BB_3D.Ecriture(cout); cout << "\n x(1)= "<< x(1) << " x(2)= "<< x(2) << " x(3)= "<< x(3) << flush; }; // dans la direction V_1 c'est la déformation issue de la cinématique // elle a déjà été calculée, et les autres composantes demeurent nulle // donc eps_P_BB est au complet, eps_BB_3D=eps_P_BB; // recopie dans eps_BB_3D: là on est dans le repère V_a eps_BB_3D.ChBase(beta3D); // changement de base, là on est dans le repère g^i // on s'occupe maintenant de l'incrément de déformation delta_eps_BB_3D = eps_BB_3D - eps_mecaBB_t; // au cas où, on impose (normalement c'est inutile) que les composantes 13 et 23 sont nulles delta_eps_BB_3D.Coor(1,3) = 0.; delta_eps_BB_3D.Coor(2,3) = 0.; // recup de l'incrément de temps double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant(); double unSurDeltat; if (Abs(deltat) >= ConstMath::trespetit) {unSurDeltat = 1./deltat;} else // si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand { // un pas de temps doit être positif !! or certaine fois il peut y avoir des pb #ifdef MISE_AU_POINT if (unSurDeltat < 0) { cout << "\n le pas de temps est négatif !! " << "\n LoiContraintesPlanesDouble::Residu_constitutif_3D(..."; }; #endif unSurDeltat = ConstMath::tresgrand; }; // ici on considère que la déformation est de type Almansi Deps_BB_3D = delta_eps_BB_3D * unSurDeltat; // calcul des invariants de déformation et de vitesse de déformation, et les def cumulées // correspondant aux cas 3D Calcul_invariants_et_def_cumul(); /* // --- on s'occupe des jacobiens // à tdt le jacobien est calculée à partir de la déformation supposée d'Almansi // ici il s'agit du jacobien relatif au comportement mécanique // |J| = sqrt(det(2 * eps_ij + g_ij(0))) // calcul de la matrice correspondante à (2 * eps_ij + g_ij(0)) gij_meca_BB = (2. * eps_BB_3D + (*(umat_cont_3D->gijBB_0))); gij_meca_BB.Matrice_composante(mat_inter); // calcul du jacobien jacobien_tdt_3D = sqrt(Dabs(mat_inter.Determinant())); */ // initialisation du comportement tangent / au def d_sigma_deps_3D.Inita(0.); // appel du calcul de sig et dsig bool en_base_orthonormee = false; // ici les tenseurs ne sont pas en orthonormee // car on travaille dans la base naturelle #ifdef MISE_AU_POINT if (Permet_affichage() > 8) {cout << "\n LoiContraintesPlanesDouble::Residu_constitutif_3D(..." << "\n giH_tdt: " << *(umat_cont_3D->giH_tdt); cout << "\n defBB: ";eps_BB_3D.Ecriture(cout); cout << "\n DepsBB: ";Deps_BB_3D.Ecriture(cout); cout << "\n x(1)= "<< x(1) << " x(2)= "<< x(2) << " x(3)= "<< x(3) ; // en base orthonormee Tenseur3BB epsBB_3D_inter; eps_BB_3D.BaseAbsolue(epsBB_3D_inter,*(umat_cont_3D->giH_tdt)); cout << "\n eps_BB_3D en absolue 3D (dans Va): "< 8) {cout << "\n en g_i: sig_HH * ViB(2)= " << V_sig_H << " df_ds_22= " << residu_3D(1) << " df_ds_21= " << residu_3D(3) << flush; }; #endif V_sig_H = sig_HH_3D * (*ViB_3D)(3); // residu_3D(2) = V_sig_H(3); // seule la composante dans la direction 3 est utilisée residu_3D(2) = V_sig_H * (*ViB_3D)(3); // composante 33 #ifdef MISE_AU_POINT if (Permet_affichage() > 8) {cout << "\n en g_i: sig_HH * ViB(3)= " << V_sig_H << " df_ds_33= " << residu_3D(2); // pour info on calcul la projection symétrique double f_12 = (*ViB_3D)(1)* sig_HH_3D * (*ViB_3D)(2); cout << " df_ds_12= " << f_12 << flush; }; #endif return residu_3D; }; //--- cas de la résolution de l'équation sigij(eps_meca)*V_j{.l}=0, l=2 et 3 // calcul de la matrice tangente de la résolution de l'équation constitutive // l'argument test ramène // . 1 si le calcul a été ok, -1 s'il y a eu un pb, mais on peut continuer, 0 s'il y a eu un pb // fatal, qui invalide le calcul du résidu et de la dérivée Mat_abstraite& LoiContraintesPlanesDouble::Mat_tangente_constitutif_3D (const double & alphap,const Vecteur & x, Vecteur& residu_local, int& test) { // récup du conteneur spécifique SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul); test = 1; // init par défaut //récup de eps_mecaBB_t Tenseur3BB& eps_mecaBB_t = *((Tenseur3BB*) (save_resul.eps_mecaBB_t)); // les inconnues sont les déformations mécaniques {epsilon'}_kl; // (k,l) = (22) (33) (12) : on a donc 3 inconnues que l'on suppose rangées dans cette ordre // c-a-d les def qui vont servir dans l'appel de la loi 3D eps_P_BB.Coor(1,2) = x(3);eps_P_BB.Coor(2,2) = x(1);eps_P_BB.Coor(3,3) = x(2); eps_P_BB.Coor(1,3) = 0.; eps_P_BB.Coor(2,3) = 0.; // vérif des grandeurs et calcul des variations d'épaisseur et de largeur double& hsurh0 = save_resul.hsurh0;double& bsurb0 = save_resul.bsurb0; // la méthode va mettre à jour les valeurs de bsurb0 et hsurh0, et le jacobien bool erreur_sortie = false; // pour gestion de sortie d'infos supplémentaires if (Permet_affichage() > 4) {cout << "\n eps_P_BB (dans Va) avant limitation : " ;eps_P_BB.Ecriture(cout);}; int info_limit = Calcul_et_Limitation2_h_b(hsurh0,eps_P_BB,bsurb0,jacobien_tdt_3D,jacobien_0_3D); if (info_limit) {if (Permet_affichage() > 3) cout << "\n LoiContraintesPlanesDouble::Mat_tangente_constitutif_3D(... " << endl; erreur_sortie = true;test = info_limit - 2; }; if (erreur_sortie && (Permet_affichage() > 4)) {cout << "\n giH_tdt: " << *(umat_cont_3D->giH_tdt); cout << "\n defBB: ";eps_BB_3D.Ecriture(cout); cout << "\n DepsBB: ";Deps_BB_3D.Ecriture(cout); cout << "\n x(1)= "<< x(1) << " x(2)= "<< x(2) << " x(3)= "<< x(3) << flush; }; // dans la direction V_1 c'est la déformation issue de la cinématique // elle a déjà été calculée, et les autres composantes demeurent nulle // donc eps_P_BB est au complet, eps_BB_3D=eps_P_BB; // recopie dans eps_BB_3D: là on est dans le repère V_a eps_BB_3D.ChBase(beta3D); // changement de base, là on est dans le repère g^i // on s'occupe maintenant de l'incrément de déformation delta_eps_BB_3D = eps_BB_3D - eps_mecaBB_t; // au cas où, on impose (normalement c'est inutile) que les composantes 13 et 23 sont nulles delta_eps_BB_3D.Coor(1,3) = 0.; delta_eps_BB_3D.Coor(2,3) = 0.; // recup de l'incrément de temps double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant(); double unSurDeltat; if (Abs(deltat) >= ConstMath::trespetit) {unSurDeltat = 1./deltat;} else // si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand { // un pas de temps doit être positif !! or certaine fois il peut y avoir des pb #ifdef MISE_AU_POINT if (unSurDeltat < 0) { cout << "\n le pas de temps est négatif !! " << "\n LoiContraintesPlanesDouble::Mat_tangente_constitutif_3D(..."; }; #endif unSurDeltat = ConstMath::tresgrand; }; // ici on considère que la déformation est de type Almansi Deps_BB_3D = delta_eps_BB_3D * unSurDeltat; // calcul des invariants de déformation et de vitesse de déformation, et les def cumulées // correspondant aux cas 3D Calcul_invariants_et_def_cumul(); /* // --- on s'occupe des jacobiens // à t=0 on considère que c'est le même jacobien que transmis jacobien_0_3D = *(umat_cont_3D->jacobien_0); // à tdt le jacobien est calculée à partir de la déformation supposée d'Almansi // ici il s'agit du jacobien relatif au comportement mécanique // |J| = sqrt(det(2 * eps_ij + g_ij(0))) // calcul de la matrice correspondante à (2 * eps_ij + g_ij(0)) gij_meca_BB = (2. * eps_BB_3D + (*(umat_cont_3D->gijBB_0))); gij_meca_BB.Matrice_composante(mat_inter); // calcul du jacobien jacobien_tdt_3D = sqrt(Dabs(mat_inter.Determinant())); */ // initialisation du comportement tangent / au def d_sigma_deps_3D.Inita(0.); // appel du calcul de sig et dsig bool en_base_orthonormee = false; // ici les tenseurs ne sont pas a priori en orthonormee #ifdef MISE_AU_POINT if (Permet_affichage() > 8) {cout << "\n LoiContraintesPlanesDouble::Mat_tangente_constitutif_3D(..." << "\n giH_tdt: " << *(umat_cont_3D->giH_tdt); cout << "\n defBB: ";eps_BB_3D.Ecriture(cout); cout << "\n DepsBB: ";Deps_BB_3D.Ecriture(cout); cout << "\n x(1)= "<< x(1) << " x(2)= "<< x(2) << " x(3)= "<< x(3) ; // en base orthonormee Tenseur3BB epsBB_3D_inter; eps_BB_3D.BaseAbsolue(epsBB_3D_inter,*(umat_cont_3D->giH_tdt)); cout << "\n eps_BB_3D en absolue 3D (dans Va): "< 8) {cout << "\n en g_i: sig_HH * ViB(2)= " << V_sig_H << " df_ds_22= " << residu_3D(1) << " df_ds_21= " << residu_3D(3) << flush; }; #endif V_sig_H = sig_HH_3D * (*ViB_3D)(3); // = \sigma . V_3 residu_local(2) = V_sig_H * (*ViB_3D)(3); // composante 33 = V_3 . \sigma . V_3 #ifdef MISE_AU_POINT if (Permet_affichage() > 8) {cout << "\n en g_i: sig_HH * ViB(3)= " << V_sig_H << " df_ds_33= " << residu_3D(2); // pour info on calcul la projection symétrique double f_12 = (*ViB_3D)(1)* sig_HH_3D * (*ViB_3D)(2); cout << " df_ds_12= " << f_12 << flush; }; #endif // calcul de la matrice tangente // formule générique //\frac{\partial \left( \sigma^{ij}(\epsilon'_{kl}) ~ V_{mj} \right )}{\partial \epsilon'_{rs}} // = V_{mj}~\frac{\partial \sigma^{ij}(\epsilon_{kl}) }{\partial \epsilon_{op}}~V^r_{~.o}~ V^s_{~.p} // ici on doit utiliser uniquement: //\frac{\partial \left( \sigma^{3j}(\epsilon'_{kl}) ~ V_{3j} \right ) }{\partial \epsilon'_{rs}} //\frac{\partial \left( \sigma^{\alpha j}(\epsilon'_{kl}) ~ V_{2j} \right ) }{\partial \epsilon'_{rs}} // avec \alpha =1,2 ; (k,l) et (r,s) } = (2,2) ; (3,3) ; (1,2) // d (V_{mi} ~\sigma^{ij} ~V_{nj} \right ) / d \epsilon'_{gh} // = V_{mi}~V_{nj}~ d \sigma^{ij} / d \epsilon_{op} ~V^r_{~.o}~ V^s_{~.p} // pour (m,n) et (g,h) = (2,2); (3,3); et (1,2) derResidu_3D.Initialise(0.); // init // for (int j=1;j<4;j++) // j représente la composante de l'axe de projection // { for (int i=1;i<4;i++) // i représente le classement de (\epsilon'_{kl}) // // i= 1 pour (k,l) = (2,2), i=2 pour (k,l) = (3,3), i=3 pour (k,l) = (1,2) // {// d (sig(2,j) V(2)(j)) / d (eps')(k,l) // derResidu_3D(1,i) += (*ViB_3D)(2)(j) * // (d_sigma_deps_3D(2,j,1,1) * (*ViH_3D)(indx(i))(1) * (*ViH_3D)(indy(i))(1) // + d_sigma_deps_3D(2,j,1,2) * (*ViH_3D)(indx(i))(1) * (*ViH_3D)(indy(i))(2) // + d_sigma_deps_3D(2,j,2,1) * (*ViH_3D)(indx(i))(2) * (*ViH_3D)(indy(i))(1) // + d_sigma_deps_3D(2,j,3,3) * (*ViH_3D)(indx(i))(3) * (*ViH_3D)(indy(i))(3) // ); // // d (sig(1,j) V(2)(j)) / d (eps')(k,l) // derResidu_3D(3,i) += (*ViB_3D)(2)(j) * // (d_sigma_deps_3D(1,j,1,1) * (*ViH_3D)(indx(i))(1) * (*ViH_3D)(indy(i))(1) // + d_sigma_deps_3D(1,j,1,2) * (*ViH_3D)(indx(i))(1) * (*ViH_3D)(indy(i))(2) // + d_sigma_deps_3D(1,j,2,1) * (*ViH_3D)(indx(i))(2) * (*ViH_3D)(indy(i))(1) // + d_sigma_deps_3D(1,j,3,3) * (*ViH_3D)(indx(i))(3) * (*ViH_3D)(indy(i))(3) // ); // // d (sig(3,j) V(2)(j)) / d (eps')(k,l) // derResidu_3D(2,i) += (*ViB_3D)(3)(j) * // (d_sigma_deps_3D(3,j,1,1) * (*ViH_3D)(indx(i))(1) * (*ViH_3D)(indy(i))(1) // + d_sigma_deps_3D(3,j,1,2) * (*ViH_3D)(indx(i))(1) * (*ViH_3D)(indy(i))(2) // + d_sigma_deps_3D(3,j,2,1) * (*ViH_3D)(indx(i))(2) * (*ViH_3D)(indy(i))(1) // + d_sigma_deps_3D(3,j,3,3) * (*ViH_3D)(indx(i))(3) * (*ViH_3D)(indy(i))(3) // ); // // }; // }; // pour (m,n) et (g,h) = (2,2); (3,3); et (1,2) // d (V_{mi} ~\sigma^{ij} ~V_{nj} ) / d\epsilon'_{gh} = // (V_{mi} V_{nj}) (d \sigma^{ij} / d \epsilon_{op}) (V^g_{~.o} V^h_{~.p}) // pour 2,2 et 3,3 pas de pb de symétrie // pour 1,2 for (int mn=1;mn<4;mn++) // mn représente la composante de l'axe de projection {// d'abord les termes diagonaux for (int gh=1;gh<3;gh++) // gh représente le classement de (\epsilon'_{gh}) derResidu_3D(mn,gh) = VhVg_BB(mn) && (d_sigma_deps_3D && VhVg_BB(gh)); // maintenant les termes non diagonaux à doubler derResidu_3D(mn,3) = 2.* VhVg_BB(mn) && (d_sigma_deps_3D && VhVg_BB(3)); }; return derResidu_3D; }; // limitation des variations d'épaisseurs et largeurs // ramène true s'il y a eu une modif: sert pour la méthode 1 bool LoiContraintesPlanesDouble::Limitation_h_b(double& hsurh0, double& bsurb0) { bool retour = false; // il ne faut pas que la nouvelle épaisseur soit inf au mini if (hsurh0 < mini_hsurh0) {if (Permet_affichage() > 3) {cout << "\n *** attention hsurh0 " << hsurh0 << ", est inferieur a la limite fixee "< 3) {cout << "\n *** attention bsurb0 " << bsurb0 << ", est inferieur a la limite fixee "< maxi_hsurh0) {if (Permet_affichage() > 3) {cout << "\n *** attention hsurh0 " << hsurh0 << ", est superieur a la limite fixee "< maxi_bsurb0) {if (Permet_affichage() > 3) {cout << "\n *** attention bsurb0 " << bsurb0 << ", est superieur a la limite fixee "< 8) { cout << "\n dans le repere locale d_sigma_deps_3D= \n"; 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;} }; Tenseur3HHHH inter_HHHH; d_sigma_deps_3D.ChangeBase(inter_HHHH,giB_tdt_3D); cout << "\n dans le repere orthonormee d_sigma_deps_3D= \n"; 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;} }; }; #endif // on calcule deux grandeurs intermédiaires // a) d sigma^{ij} / d epsilon_{o'p'}(3D)~~V^1_{~.o'}~ V^1_{~.p'} // on récupère que le pointeur, ce qui évite d'utiliser l'opérateur de copie du tenseur // !!!!**** a vérifier -> oui c'est ok // const Tenseur3BB & epsBB = *((Tenseur3BB*) &epsBB_tdt); // passage en dim 3 Tenseur3HH dSigDeps11P_HH(d_sigma_deps_3D && V1V1_BB); #ifdef MISE_AU_POINT if (Permet_affichage() > 7) { cout << "\n (*ViB_3D)(1)= "<<(*ViB_3D)(1); cout << "\n V1V1_BB: "<< V1V1_BB << "\n dSigDeps11P_HH: "<< dSigDeps11P_HH << flush; }; #endif // b) d sigma^{ij} / d epsilon_{o'p'}(3D)~~V^g_{~.o'}~ V^h_{~.p'} Tableau dsigdeps_gh_P(3); for (int gh=1;gh<4;gh++) {dsigdeps_gh_P(gh) = ((Tenseur3HH*) &( d_sigma_deps_3D && VhVg_BB(gh))); #ifdef MISE_AU_POINT if (Permet_affichage() > 7) { cout << "\n VhVg_BB("< 7) { cout << "\n mat1 "<< mat1; cout << "\n SM: "<< SM << flush; } #endif // d) calcul des variations des déformations transversales // en fonction de la déformation longitudinale // d epsilon'_gh / d epsilon'_11 = // - [ V_{mi}~(d sigma^{ij} / d epsilon_{op}(3D)~~V^g_{~.o}~ V^h_{~.p}) ~~V_{nj}]^{-1}~ // * ( V_{mi}~~ d sigma^{ij} / d epsilon_{o'p'}(3D)~~V^1_{~.o'}~ V^1_{~.p'}~~V_{nj} ) Vecteur depsP_gh_depsP_11_BB(3); depsP_gh_depsP_11_BB = - mat1.Inverse() * SM; #ifdef MISE_AU_POINT if (Permet_affichage() > 7) { cout << "\n depsP_gh_depsP_11_BB "<< depsP_gh_depsP_11_BB << flush; } #endif // e) d sigma'^{11} / d epsilon'_11 (1D~CP) = // = V_{1i}~V_{1j}~d sigma^{ij} / d epsilon_{op}(3D)~~V^1_{~.o}~ V^1_{~.p} // + V_{1i}~V_{1j}~d sigma^{ij} / d epsilon_{op}(3D)~~~V^g_{~.o}~ V^h_{~.p} // * d epsilon'_gh / d epsilon'_11 // ici on se sert du fait que l'on a déjà calculé: // dSigDeps11P_HH = d sigma^{ij} / d epsilon_{op}(3D)~~V^1_{~.o}~ V^1_{~.p} Tenseur1HHHH d_sigP11_depsP11_HHHH ( (V1V1_BB && dSigDeps11P_HH) + (V1V1_BB && ( (*dsigdeps_gh_P(1))*depsP_gh_depsP_11_BB(1) + (*dsigdeps_gh_P(2))*depsP_gh_depsP_11_BB(2) + (*dsigdeps_gh_P(3))*depsP_gh_depsP_11_BB(3) ) ) ); #ifdef MISE_AU_POINT if (Permet_affichage() > 7) cout << "\n d_sigP11_depsP11_HHHH "<< d_sigP11_depsP11_HHHH << flush; #endif // f) d_sigma^{ij} / d_epsilon_{kl} \approx // V_1^{~.i}~V_1^{~.j}~d sigma'^{11} / d epsilon'_11 (1D~CP)~\gamma^{k}_{~.1} ~\gamma^{l}_{~.1} //fonctions static définissant le produit tensoriel de deux vecteurs // si les vecteurs sont égaux le tenseur est symétrique sinon il est non symétrique TenseurHH & inter1_HH = Tenseur3HH::Prod_tensoriel((*ViH_3D)(1),(*ViH_3D)(1)); Coordonnee3H u_H(gamma3D.Colonne(1)); // qui correspond aux \gamma^{k}_{~.1} TenseurHH & inter2_HH = Tenseur3HH::Prod_tensoriel(u_H,u_H); d_sigma_deps = Tenseur3HHHH::Prod_tensoriel(inter1_HH,inter2_HH); d_sigma_deps *= d_sigP11_depsP11_HHHH(1,1,1,1); #ifdef MISE_AU_POINT if (Permet_affichage() > 8) { Tenseur3HHHH inter_HHHH; cout << "\n dans le repere locale d_sigma_deps= \n"; 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;} }; Tenseur3HHHH inter1_HHHH(d_sigma_deps); inter1_HHHH.ChangeBase(inter_HHHH,giB_tdt_3D); cout << "\n dans le repere orthonormee d_sigma_deps= \n"; 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;} }; }; #endif }; // vérif des grandeurs et calcul des valeurs de l'épaisseur et de la largeur // ainsi que calcul du jacobien final // = 0 pas de modif // = 1 modif due aux maxi permis de h et b, = 2 si def d'entrée incorrecte // cas de la 2ième méthode int LoiContraintesPlanesDouble::Calcul_et_Limitation2_h_b (double& hsurh0,Tenseur3BB& eps_P_BB_3D, double& bsurb0,double& jacobien_tdt_3DD, const double & jacobien_0_3DD) { int retour = 0; // init par défaut bool modif_hsurh0 = false; bool modif_bsurb0 = false; // init // à partir de la valeur des déformations en cours on regarde les variations transversales correspondantes // ici les déformations eps_BB_3D sont exprimées dans le repère V_a donc orthonormée switch (type_de_deformation) {case DEFORMATION_STANDART : case DEFORMATION_POUTRE_PLAQUE_STANDART : // cas d'une déformation d'Almansi { // on est dans le repère V_a, V_3 est direction principale du tenseur de def -> formule classique // epsBB33 = 1/2 * (1. -(h_0/h_tdt)**2) avec un maxi de o.5 if (eps_P_BB_3D(3,3) > 0.5) {if (Permet_affichage() > 0) cout << "\n LoiContraintesPlanesDouble::Calcul_et_Limitation2_h_b(.." << "\n **erreur: la deformation d'epaisseur dans V_a "< 3) {cout << "\n *** attention hsurh0 " << hsurh0 << ", est inferieur a la limite fixee "< maxi_hsurh0) {if (Permet_affichage() > 3) {cout << "\n *** attention hsurh0 " << hsurh0 << ", est superieur a la limite fixee "< 0.5) || (epsP_II > 0.5)) if (epsP_I > 0.5) {if (Permet_affichage() > 0) cout << "\n LoiContraintesPlanesDouble::Calcul_et_Limitation2_h_b(.." << "\n **erreur: la deformation eps'_I "< 0.5) {if (Permet_affichage() > 0) cout << "\n LoiContraintesPlanesDouble::Calcul_et_Limitation2_h_b(.." << "\n **erreur: la deformation eps'_II "< eps_P_BB_3D(2,2), cela veut dire que epsP_I est de son côté // par contre si c'est < , cela veut dire que c'est epsP_II qui est de son côté // d'où le choix qui suit { if (eps_P_BB_3D(1,1) > eps_P_BB_3D(2,2)) {bsurb0 = 1./sqrt(1.-2.*epsP_II);} else // cas d'une compression {bsurb0 = 1./sqrt(1.-2.*epsP_I);}; }; // il ne faut pas que la nouvelle largeur soit inf au mini if (bsurb0 < mini_bsurb0) {if (Permet_affichage() > 3) {cout << "\n *** attention bsurb0 " << bsurb0 << ", est inferieur a la limite fixee "< maxi_bsurb0) {if (Permet_affichage() > 3) {cout << "\n *** attention bsurb0 " << bsurb0 << ", est superieur a la limite fixee "< 0.5) {if (Permet_affichage() > 0) cout << "\n LoiContraintesPlanesDouble::Calcul_et_Limitation2_h_b(.." << "\n **erreur: la deformation eps'_I (deuxieme passe!!) "< 0.5) {if (Permet_affichage() > 0) cout << "\n LoiContraintesPlanesDouble::Calcul_et_Limitation2_h_b(.." << "\n **erreur: la deformation eps'_II (deuxieme passe!!) "< 3) cout << "\n LoiContraintesPlanesDouble::Cal_avec_perturbation2(... " << endl; erreur_sortie = true; }; if (erreur_sortie && (Permet_affichage() > 4)) {cout << "\n giH_tdt: " << *(umat_cont_3D->giH_tdt); cout << "\n defBB: ";eps_BB_3D.Ecriture(cout); cout << "\n DepsBB: ";Deps_BB_3D.Ecriture(cout); }; // dans la direction V_1 c'est la déformation issue de la cinématique // elle a déjà été calculée, et les autres composantes demeurent nulle // donc eps_P_BB est au complet, eps_BB_3D=eps_P_BB; // recopie dans eps_BB_3D: là on est dans le repère V_a eps_BB_3D.ChBase(beta3D); // changement de base, là on est dans le repère g^i // on s'occupe maintenant de l'incrément de déformation delta_eps_BB_3D = eps_BB_3D - eps_mecaBB_t; // au cas où, on impose (normalement c'est inutile) que les composantes 13 et 23 sont nulles delta_eps_BB_3D.Coor(1,3) = 0.; delta_eps_BB_3D.Coor(2,3) = 0.; // recup de l'incrément de temps double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant(); double unSurDeltat; if (Abs(deltat) >= ConstMath::trespetit) {unSurDeltat = 1./deltat;} else // si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand { // un pas de temps doit être positif !! or certaine fois il peut y avoir des pb #ifdef MISE_AU_POINT if (unSurDeltat < 0) { cout << "\n le pas de temps est négatif !! " << "\n LoiContraintesPlanesDouble::Cal_avec_perturbation2(..."; }; #endif unSurDeltat = ConstMath::tresgrand; }; // ici on considère que la déformation est de type Almansi Deps_BB_3D = delta_eps_BB_3D * unSurDeltat; // calcul des invariants de déformation et de vitesse de déformation, et les def cumulées // correspondant aux cas 3D Calcul_invariants_et_def_cumul(); // --- on s'occupe des jacobiens // à t=0 on considère que c'est le même jacobien que transmis jacobien_0_3D = *(umat_cont_3D->jacobien_0); // à tdt le jacobien est calculée à partir de la déformation supposée d'Almansi // ici il s'agit du jacobien relatif au comportement mécanique // |J| = sqrt(det(2 * eps_ij + g_ij(0))) // calcul de la matrice correspondante à (2 * eps_ij + g_ij(0)) gij_meca_BB = (2. * eps_BB_3D + (*(umat_cont_3D->gijBB_0))); gij_meca_BB.Matrice_composante(mat_inter); // calcul du jacobien jacobien_tdt_3D = sqrt(Dabs(mat_inter.Determinant())); // initialisation du comportement tangent / au def d_sigma_deps_3D.Inita(0.); // appel du calcul de sig et dsig bool en_base_orthonormee = false; // ici les tenseurs ne sont pas en orthonormee // car on travaille dans la base naturelle #ifdef MISE_AU_POINT if (Permet_affichage() > 8) {cout << "\n LoiContraintesPlanesDouble::Cal_avec_perturbation2(..." << "\n giH_tdt: " << *(umat_cont_3D->giH_tdt); cout << "\n defBB: ";eps_BB_3D.Ecriture(cout); cout << "\n DepsBB: ";Deps_BB_3D.Ecriture(cout); }; #endif lois_interne->Calcul_dsigma_deps (en_base_orthonormee, sig_HH_t_3D,Deps_BB_3D,eps_BB_3D ,delta_eps_BB_3D,jacobien_0_3D,jacobien_tdt_3D ,sig_HH_3D,d_sigma_deps_3D ,save_resul.l_energ,save_resul.l_energ_t,module_compressibilite_3D ,module_cisaillement_3D,*umat_cont_3D); #ifdef MISE_AU_POINT if (Permet_affichage() > 8) {cout << "\n sig_HH_3D: " << sig_HH_3D; cout << "\n d_sigma_deps_3D: "<< d_sigma_deps_3D << flush; }; #endif // sauvegarde des résultats save_resul.def_P(1) = eps_P_BB(2,2); // récup de la solution dans le repère V_a save_resul.def_P(2) = eps_P_BB(3,3); // " save_resul.def_P(3) = eps_P_BB(1,2); // " // on doit sauvegarder les def méca dans le repère g^i, ce sont directement // les dernières composantes utilisées pour l'appel de la loi 3D Tenseur3BB& eps_mecaBB = *((Tenseur3BB*) (save_resul.eps_mecaBB)); eps_mecaBB = eps_BB_3D; // en g^i eps_P_mecaBB = eps_P_BB; // dans V_a pour le post traitement }; // passage entre le calcul classique en 1D de Calcul_dsigma_deps et le calcul 3D // méthode 2 void LoiContraintesPlanesDouble::Passage_Calcul_1D_3D_dsigma_deps (bool en_base_orthonormee, TenseurHH & sigHH_t,TenseurBB& DepsBB ,TenseurBB & epsBB_tdt,TenseurBB & delta_epsBB,double& jacobien_0,double& jacobien ,TenseurHH& sigHH_tdt,TenseurHHHH& d_sigma_deps ,EnergieMeca & energ,const EnergieMeca & ,double& module_compressibilite,double& module_cisaillement ,const Met_abstraite::Umat_cont& ex ) { #ifdef MISE_AU_POINT if (Permet_affichage() > 7) cout << "\n LoiContraintesPlanesDouble::Passage_Calcul_1D_3D_dsigma_deps"; #endif // récup du conteneur spécifique SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul); module_compressibilite=module_cisaillement=0.; // init energ.Inita(0.); // initialisation des énergies mises en jeux // --- pour les contraintes passage en 3D bool plusZero = true; // on affecte les contraintes a t: en fait pour les lois incrémentales, les infos à t // sont déjà stocké, donc cela ne sert à rien, mais pour une loi élastique par exemple ce n'est pas le cas sig_HH_t_3D.Affectation_trans_dimension(*((Tenseur1HH*) &sigHH_t),plusZero); // --- pour la cinématique // passage des informations spécifique à la loi le_SaveResul // initialisation du tenseurs contrainte sig_HH_3D.Inita(0.); sig_HH_3D.Affectation_trans_dimension(*((Tenseur1HH*) &sigHH_tdt),plusZero); // passage des métriques de l'ordre 1 vers 3 Passage_metrique_ordre1_vers_3(ex); // passage des informations liées à la déformation de 1 vers 3, et variation de volume Tableau * toto = NULL; // pour dire que ce n'est pas attribué Vecteur* titi = NULL; // " " " Passage_deformation_volume_ordre1_vers_3(DepsBB,epsBB_tdt,toto,delta_epsBB ,jacobien_0,jacobien,titi,*(ex.jacobien_t)); // -- construction de la base ortho associée à la direction de traction/compression // ici il s'agit pour le premier vecteur de la direction 1, // et compte tenu de Passage_metrique_ordre1_vers_3, le repère gi est orthogonale // on va donc le normer BaseB Vi_B(3); BaseH Vi_H(3); BaseB * ViB = &Vi_B;BaseH * ViH = &Vi_H; // tout d'abord on récupère la base gi actuelle et on la norme: // on se sert de Vi_B comme stockage transitoire // cout << "\n base giB(1) "<< (* ex.giB_tdt)(1) // << "\n base giB(2) "<< (* ex.giB_tdt)(2); #ifdef MISE_AU_POINT if (Permet_affichage() > 8) { cout << "\n base giB_tdt_3D(1) "<< giB_tdt_3D(1) << "\n base giB_tdt_3D(2) "<< giB_tdt_3D(2) << "\n base giB_tdt_3D(2) "<< giB_tdt_3D(3) << flush; }; #endif Vi_B.CoordoB(1) = giB_tdt_3D(1);Vi_B.CoordoB(1).Normer(); Vi_B.CoordoB(2) = giB_tdt_3D(2);Vi_B.CoordoB(2).Normer(); Vi_B.CoordoB(3) = giB_tdt_3D(3);Vi_B.CoordoB(3).Normer(); // calcul des coordonnées locales de V_a en contravariants: // V_a^{~i} = \vec V_a . \vec g^j for (int a=1;a<4;a++) for (int i=1;i<4;i++) Vi_H.CoordoH(a)(i) = Vi_B.CoordoB(a) * giH_tdt_3D(i); // calcul des coordonnées contra // Vi_B(a) = g_ij * Vi_H(a) for (int a=1;a<4;a++) Vi_B.CoordoB(a) = gijBB_t_3D * Vi_H(a); // appel de la résolution 3D // calcul des contraintes et ses variations par rapport aux déformations a t+dt // ceci dans le cas où l'axe de traction simple est quelconque // ici on suppose que: // - tous les calculs sont en dim 3 // - l'axe 3 est normal aux deux autres (ceci pour Vi et pour gi) // // ViB et ViH : correspond à la base de traction telle que ViB(1) = ViH(1) = l'axe de traction // La base Vi est supposée orthonormée // en_base_orthonormee: le tenseur de contrainte en entrée est en orthonormee // le tenseur de déformation et son incrémentsont également en orthonormees // si = false: les bases transmises sont utilisées // ex: contient les éléments de métrique relativement au paramétrage matériel = X_(0)^a Calcul_dsigma_deps (en_base_orthonormee,ViB,ViH,sig_HH_t_3D,Deps_BB_3D ,eps_BB_3D,delta_eps_BB_3D,jacobien_0_3D,jacobien_tdt_3D ,sig_HH_3D,d_sigma_deps_3D,save_resul.l_energ,save_resul.l_energ_t ,module_compressibilite,module_cisaillement,*umat_cont_3D); // passage des tenseurs résultats à l'ordre 1 ((Tenseur1HH*) &sigHH_tdt)->Affectation_trans_dimension(sig_HH_3D,false); // maintenant on renseigne le tenseur de sortie bool pluszero = true; d_sigma_deps.Affectation_trans_dimension(d_sigma_deps_3D, pluszero); }; // passage entre le calcul classique en 1D de Calcul_DsigmaHH_tdt et le calcul 3D // méthode 2 void LoiContraintesPlanesDouble::Passage_Calcul_1D_3D_dsigma_DsigmaHH_tdt (TenseurHH& sigHH_t,TenseurBB& DepsBB,DdlElement & tab_ddl ,BaseB& giB_t,TenseurBB & gijBB_t,TenseurHH & gijHH_t ,BaseB& giB_tdt,Tableau & d_giB_tdt,BaseH& giH_tdt,Tableau & d_giH_tdt ,TenseurBB & epsBB_tdt,Tableau & d_epsBB ,TenseurBB & delta_epsBB,TenseurBB & gijBB_tdt,TenseurHH & gijHH_tdt ,Tableau & d_gijBB_tdt ,Tableau & d_gijHH_tdt,double& jacobien_0,double& jacobien ,Vecteur& d_jacobien_tdt,TenseurHH& sigHH_tdt,Tableau & d_sigHH ,EnergieMeca & energ,const EnergieMeca & ,double& module_compressibilite,double& module_cisaillement ,const Met_abstraite::Impli& ex) { #ifdef MISE_AU_POINT if (Permet_affichage() > 7) cout << "\n LoiContraintesPlanesDouble::Passage_Calcul_1D_3D_dsigma_DsigmaHH_td"; #endif // récup du conteneur spécifique SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul); module_compressibilite=module_cisaillement=0.; // init energ.Inita(0.); // initialisation des énergies mises en jeux // --- pour les contraintes passage en 3D bool plusZero = true; // on affecte les contraintes a t: en fait pour les lois incrémentales, les infos à t // sont déjà stocké, donc cela ne sert à rien, mais pour une loi élastique par exemple ce n'est pas le cas sig_HH_t_3D.Affectation_trans_dimension(*((Tenseur1HH*) &sigHH_t),plusZero); // --- pour la cinématique // passage des informations spécifique à la loi le_SaveResul // initialisation du tenseurs contrainte sig_HH_3D.Inita(0.); sig_HH_3D.Affectation_trans_dimension(*((Tenseur1HH*) &sigHH_tdt),plusZero); // passage des métriques de l'ordre 1 vers 3 Passage_metrique_ordre1_vers_3(ex); // passage des informations liées à la déformation de 1 vers 3, et variation de volume Tableau * toto = NULL; // pour dire que ce n'est pas attribué Vecteur* titi = NULL; // " " " Passage_deformation_volume_ordre1_vers_3(DepsBB,epsBB_tdt,toto,delta_epsBB ,jacobien_0,jacobien,titi,*(ex.jacobien_t)); // -- construction de la base ortho associée à la direction de traction/compression // ici il s'agit pour le premier vecteur de la direction 1, // et compte tenu de Passage_metrique_ordre1_vers_3, le repère gi est orthogonale // on va donc le normer BaseB Vi_B(3); BaseH Vi_H(3); BaseB * ViB = &Vi_B;BaseH * ViH = &Vi_H; // tout d'abord on récupère la base gi actuelle et on la norme: // on se sert de Vi_B comme stockage transitoire #ifdef MISE_AU_POINT if (Permet_affichage() > 8) { cout << "\n base giB_tdt_3D(1) "<< giB_tdt_3D(1) << "\n base giB_tdt_3D(2) "<< giB_tdt_3D(2) << "\n base giB_tdt_3D(2) "<< giB_tdt_3D(3) << flush; }; #endif Vi_B.CoordoB(1) = giB_tdt_3D(1);Vi_B.CoordoB(1).Normer(); Vi_B.CoordoB(2) = giB_tdt_3D(2);Vi_B.CoordoB(2).Normer(); Vi_B.CoordoB(3) = giB_tdt_3D(3);Vi_B.CoordoB(3).Normer(); // calcul des coordonnées locales de V_a en contravariants: // V_a^{~i} = \vec V_a . \vec g^j for (int a=1;a<4;a++) for (int i=1;i<4;i++) Vi_H.CoordoH(a)(i) = Vi_B.CoordoB(a) * giH_tdt_3D(i); // calcul des coordonnées contra // Vi_B(a) = g_ij * Vi_H(a) for (int a=1;a<4;a++) Vi_B.CoordoB(a) = gijBB_t_3D * Vi_H(a); #ifdef MISE_AU_POINT if (Permet_affichage() > 4) {cout << "\n LoiContraintesPlanesDouble::Passage_Calcul_1D_3D_dsigma_DsigmaHH_td( "; cout << "\n base Vi_B(1) "<< Vi_B(1) << "\n base Vi_B(2) "<< Vi_B(2) << "\n base Vi_B(3) "<< Vi_B(3) << "\n base Vi_H(1) "<< Vi_H(1) << "\n base Vi_H(2) "<< Vi_H(2) << "\n base Vi_H(3) "<< Vi_H(3) << flush; }; #endif // appel de la résolution 3D // calcul des contraintes et ses variations par rapport aux déformations a t+dt // ceci dans le cas où l'axe de traction simple est quelconque // ici on suppose que: // - tous les calculs sont en dim 3 // - l'axe 3 est normal aux deux autres (ceci pour Vi et pour gi) // // ViB et ViH : correspond à la base de traction telle que ViB(1) = ViH(1) = l'axe de traction // La base Vi est supposée orthonormée // en_base_orthonormee: le tenseur de contrainte en entrée est en orthonormee // le tenseur de déformation et son incrémentsont également en orthonormees // si = false: les bases transmises sont utilisées // ex: contient les éléments de métrique relativement au paramétrage matériel = X_(0)^a bool en_base_orthonormee = false; Calcul_dsigma_deps (en_base_orthonormee,ViB,ViH,sig_HH_t_3D,Deps_BB_3D ,eps_BB_3D,delta_eps_BB_3D,jacobien_0_3D,jacobien_tdt_3D ,sig_HH_3D,d_sigma_deps_3D,save_resul.l_energ,save_resul.l_energ_t ,module_compressibilite,module_cisaillement,*umat_cont_3D); // passage des tenseurs résultats à l'ordre 1 ((Tenseur1HH*) &sigHH_tdt)->Affectation_trans_dimension(sig_HH_3D,false); // maintenant on renseigne le tenseur de sortie bool pluszero = true; // d_sigma / d_ddl = d_sigma / d_eps * d_eps / d_ddl // ici l'opérateur tangent correspond à la sensibilité de d sigma'^11 / d eps'_11 // et la direction V_1 c'est la direction de g_1 (à la norme près donc // d_sigma / d_eps normalement c'est == à d sigma'^11 / d eps'_11 // du coup ici on n'a pas à itérer sur toutes les déformations int nb_ddlPlus1 = d_epsBB.Taille()+1; for (int i_ddl=1;i_ddlCoor(1,1) = (d_sigma_deps_3D(1,1,1,1) * (*d_epsBB(i_ddl)))(1,1); };