// 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-2021 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 "CharUtil.h" #include "LoiContraintesPlanesDouble.h" //==================== cas de la class de sauvegarde SaveResul =================== // constructeur par défaut à ne pas utiliser LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble() : LoiContraintesPlanes::SaveResul_LoiContraintesPlanes() ,def_P(),def_P_t() ,bsurb0(0.),b_tsurb0(0.),d_bsurb0() ,meti_ref_00(0,0),meti_ref_t(0,0),meti_ref_tdt(0,0) { cout << "\n erreur, le constructeur par defaut ne doit pas etre utilise !" << "\n LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble()"; Sortie(1); }; // le constructeur courant LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble (SaveResul* l_des_SaveResul): LoiContraintesPlanes::SaveResul_LoiContraintesPlanes(l_des_SaveResul) ,def_P(),def_P_t() ,bsurb0(0.),b_tsurb0(0.),d_bsurb0() ,meti_ref_00(),meti_ref_t(),meti_ref_tdt() // les références sont en 3D, mais on init à null { if (l_des_SaveResul != NULL) le_SaveResul = l_des_SaveResul->Nevez_SaveResul(); // par défaut les contraintes sont en dim 3 l_sigoHH=NevezTenseurHH(3,0); // idem interHH, par défaut les contraintes sont en dim 3 l_sigoHH_t =NevezTenseurHH(3,0.); }; // constructeur de copie LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble (const LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble& sav ): LoiContraintesPlanes::SaveResul_LoiContraintesPlanes(sav) ,def_P(sav.def_P),def_P_t(sav.def_P_t) ,bsurb0(sav.bsurb0),b_tsurb0(sav.b_tsurb0),d_bsurb0() ,meti_ref_00(),meti_ref_t(),meti_ref_tdt() { // les métriques peuvent être non affectées au début, c'est seulement lors de leurs utilisations // qu'elles seront affectées aux bonnes dimmensions if ( sav.meti_ref_00.giB_ != NULL) meti_ref_00 = sav.meti_ref_00; if ( sav.meti_ref_t.giB_ != NULL) meti_ref_t = sav.meti_ref_t; if ( sav.meti_ref_tdt.giB_ != NULL) meti_ref_tdt = sav.meti_ref_tdt; }; // destructeur LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble::~SaveResul_LoiContraintesPlanesDouble() { }; // affectation Loi_comp_abstraite::SaveResul & LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble::operator = ( const Loi_comp_abstraite::SaveResul & a) { LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble& sav = *((LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble*) &a); // tout d'abord on s'occupe des infos de contraintes planes this->LoiContraintesPlanes::SaveResul_LoiContraintesPlanes::operator=(a); meti_ref_00 = sav.meti_ref_00; meti_ref_t = sav.meti_ref_t; meti_ref_tdt = sav.meti_ref_tdt; def_P = sav.def_P;def_P_t=sav.def_P_t; bsurb0 = sav.bsurb0; b_tsurb0 = sav.b_tsurb0; // d_hsurh0 = sav.d_hsurh0; d_bsurb0 = sav.d_bsurb0; return *this; }; //============= lecture écriture dans base info ========== // cas donne le niveau de la récupération // = 1 : on récupère tout // = 2 : on récupère uniquement les données variables (supposées comme telles) void LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble::Lecture_base_info (ifstream& ent,const int cas) { // ici toutes les données sont toujours a priori variables // ou en tout cas pour les méthodes appelées, elles sont gérées par le paramètre: cas string toto; ent >> toto; #ifdef MISE_AU_POINT if (toto != "S_C_Plane_D") { cout << "\n erreur en lecture du conteneur pour la loi de contrainte plane generique " << " \n LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble::Lecture_base_info(.."; Sortie(1); } #endif // on lit d'abord la loi contrainte plane SaveResul_LoiContraintesPlanes::Lecture_base_info(ent,cas); // ensuite les éléments spécifiques à la contrainte plane double ent >> toto >> b_tsurb0; bsurb0 = b_tsurb0; // puis init au cas où de la valeur à tdt ent >> toto >> def_P_t; def_P=def_P_t; switch (cas) { case 1 : ent >> toto ; if (toto == "meti_ref_00") // là c'est affecté ent >> meti_ref_00 ; ent >> toto; if (toto == "meti_ref_t") // là c'est affecté ent >> meti_ref_t ; break; case 2 : // -- on test -- // ent >> nom >> meti_t ; break; default: cout << "\n cas non considere !!: cas= " << cas << "\n LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble::Lecture_base_info (..."; Sortie(1); }; }; // cas donne le niveau de sauvegarde // = 1 : on sauvegarde tout // = 2 : on sauvegarde uniquement les données variables (supposées comme telles) void LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble::Ecriture_base_info (ofstream& sort,const int cas) { // ici toutes les données sont toujours a priori variables // ou en tout cas pour les méthodes appelées, elles sont gérées par le paramètre: cas sort << "\n S_C_Plane_D "; // on écrit d'abord la loi contrainte plane SaveResul_LoiContraintesPlanes::Ecriture_base_info(sort,cas); // ensuite les éléments spécifiques à la contrainte plane double sort << " b_tsurb0 " << b_tsurb0; // la variation de largeur sort << " def_P " << def_P_t; // on ne sauvegarde que ce qui est à 0 et à t, ce qui est à tdt est considéré une zone de travail switch (cas) { case 1 : // les métriques peuvent être non affectées au début, c'est seulement lors de leurs utilisations // qu'elles seront affectées aux bonnes dimmensions if ( meti_ref_00.giB_ != NULL) { sort << "meti_ref_00 "<< meti_ref_00 << " ";} else { sort << "meti_ref_00_pas_affectee ";} if ( meti_ref_t.giB_ != NULL) { sort << "meti_ref_t "<< meti_ref_t << " ";} else { sort << "meti_ref_t_pas_affectee ";} break; case 2 : // -- on test -- // sort << " SaveDefResul: "; // sort << " meti_t: " << meti_t << " "; break; default: cout << "\n cas non considere !!: cas= " << cas << "\n LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble::Ecriture_base_info(..."; Sortie(1); }; }; // mise à jour des informations transitoires en définitif s'il y a convergence // par exemple (pour la plasticité par exemple) void LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble::TdtversT() { // appel de la méthode de CP SaveResul_LoiContraintesPlanes::TdtversT(); // les données particulières à CPD2 meti_ref_t = meti_ref_tdt; b_tsurb0 = bsurb0; def_P_t = def_P; // d_hsurh0.Zero(); // on initialise le vecteur tangent // h_tsurh0 = hsurh0; // -- idem pour la largeur d_bsurb0.Zero(); // " }; void LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble::TversTdt() { // appel de la méthode de CP SaveResul_LoiContraintesPlanes::TversTdt(); // les données particulières à CPD2 meti_ref_tdt = meti_ref_t; bsurb0 = b_tsurb0; def_P = def_P_t; d_bsurb0.Zero(); // on initialise le vecteur tangent // h_tsurh0 = hsurh0; // -- idem pour la largeur // d_hsurh0.Zero(); // " }; // affichage à l'écran des infos void LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble::Affiche() const { cout << "\n SaveResul_LoiContraintesPlanesDouble: " ; // d'abord la classe sup SaveResul_LoiContraintesPlanes::Affiche(); // puis les données particulières à CPD2 cout << "\n b_tsurb0 "<< b_tsurb0 << " def_P_t " << def_P_t <<" "; cout << "\n meti_ref_00: " << meti_ref_00 << " meti_ref_t " << meti_ref_t << " meti_ref_tdt " << meti_ref_tdt <<" "; cout << "\n -- partie relative a la loi interne: "; le_SaveResul->Affiche(); cout << "\n .. fin SaveResul_LoiContraintesPlanesDouble:.. \n" ; }; //changement de base de toutes les grandeurs internes tensorielles stockées // beta(i,j) represente les coordonnees de la nouvelle base naturelle gpB dans l'ancienne gB // gpB(i) = beta(i,j) * gB(j), i indice de ligne, j indice de colonne // gpH(i) = gamma(i,j) * gH(j) void LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble::ChBase_des_grandeurs(const Mat_pleine& beta,const Mat_pleine& gamma) { // on appelle la classe mere LoiContraintesPlanes::SaveResul_LoiContraintesPlanes::ChBase_des_grandeurs(beta,gamma); // les vecteurs sont un moyen de stockage mais pas dépendant de la base, donc pas de chgt de coordonnées }; // procedure permettant de completer éventuellement les données particulières // de la loi stockées // au niveau du point d'intégration par exemple: exemple: un repère d'anisotropie // completer est appelé apres sa creation avec les donnees du bloc transmis // peut etre appeler plusieurs fois Loi_comp_abstraite::SaveResul* LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble ::Complete_SaveResul(const BlocGen & bloc, const Tableau & tab_coor ,const Loi_comp_abstraite* loi) {// on transmet au conteneur 3D interne const LoiContraintesPlanesDouble * loi_CP = (const LoiContraintesPlanesDouble*) loi; le_SaveResul->Complete_SaveResul(bloc,tab_coor,loi_CP->lois_interne); return this; }; // ---- récupération d'information: spécifique à certaine classe dérivée double LoiContraintesPlanesDouble::SaveResul_LoiContraintesPlanesDouble::Deformation_plastique() { cout << "\n pour l'instant cette option n'est pas implante dans le cas d'une loi" << "\n contrainte plane quelconque " << "\n double Loi_comp_abstraite::SaveResul_LoiContraintesPlanesDouble::Deformation_plastique()"; Sortie(1); return 0.; // pour taire le warning, mais on ne passe jamais là }; //==================== fin du cas de la class de sauvegarde SaveResul ============ LoiContraintesPlanesDouble::LoiContraintesPlanesDouble () : // Constructeur par defaut Loi_comp_abstraite(LOI_CONTRAINTES_PLANES_DOUBLE,RIEN_CATEGORIE_LOI_COMP,1) ,type_de_contrainte(RIEN_CONTRAINTE_MATHEMATIQUE),fac_penal(30.),prec(0.005) ,lois_interne(NULL) ,alg_zero(),maxi_delta_var_eps_sur_iter_pour_Newton(0.1) ,sortie_post(0),calcul_en_3D_via_direction_quelconque(false) ,d_sig_ef_gh(2,2),d_eps_ef_11(2) ,fct_tolerance_residu(NULL),fct_tolerance_residu_rel(NULL) // ---- réglage par défaut de la résolution avec linéarisation de sig22_33(bsurb0,hsurh0)=(0,0) ,val_initiale(2),racine(2)//,der_at_racine(2,2) ,der_at_racine(2,2,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT) ,residu(2)//,derResidu(2,2), ,derResidu(2,2,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT) //-------- spécifiques à Calcul_dsigma_deps hors axes ------------------------ ,ViB_3D(NULL),ViH_3D(NULL) ,val_initiale_3D(3),residu_3D(3),derResidu_3D(3,3,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT) ,eps_P_BB(),Deps_P_BB(),delta_eps_P_BB(),racine_3D(3) ,gamma3D(3,3),beta3D(3,3),gammaP_3D(3,3),betaP_3D(3,3) ,epsBB_tdt_cin(NULL),DepsBB_cin(NULL),delta_epsBB_cin(NULL) ,mat_inter(3,3),gij_meca_BB(),gij_meca_BB_t() ,V1V1_BB(),ind(3),jnd(3),VhVg_BB(3) //-------- fin spécifiques à Calcul_dsigma_deps hors axes ------------------------ ,mini_hsurh0(0.001),mini_bsurb0(0.001),maxi_hsurh0(1000.),maxi_bsurb0(1000.) ,giB_normer_3_tdt_3D_sauve(3),giB_normer_2_tdt_3D_sauve(3) // -- conteneur des métriques ,expli_3D(NULL),impli_3D(NULL),umat_cont_3D(NULL) // -- les variables pointées dans les conteneurs, et leur pointeur associé éventuellement ,giB_0_3D(),giH_0_3D(),giB_t_3D(),giH_t_3D(),giB_tdt_3D(),giH_tdt_3D() ,gijBB_0_3D(),gijHH_0_3D(),gijBB_t_3D(),gijHH_t_3D() ,gijBB_tdt_3D(),gijHH_tdt_3D() ,gradVmoyBB_t_3D(),gradVmoyBB_tdt_3D(),gradVBB_tdt_3D() ,gradVmoyBB_t_3D_P(NULL),gradVmoyBB_tdt_3D_P(NULL),gradVBB_tdt_3D_P(NULL) ,jacobien_tdt_3D(0.),jacobien_0_3D(0.) // les vrais tableaux associés aux tableaux de pointeurs ,d_giB_tdt_3D(),d_giH_tdt_3D() ,d_gijBB_tdt_3D(),d2_gijBB_tdt_3D(),d_gijHH_tdt_3D() ,d_gijBB_tdt_3D_P(NULL),d2_gijBB_tdt_3D_P(NULL),d_gijHH_tdt_3D_P(NULL) ,d_jacobien_tdt_3D(NULL) ,d_gradVmoyBB_t_3D(),d_gradVmoyBB_tdt_3D(),d_gradVBB_t_3D(),d_gradVBB_tdt_3D() ,d_gradVmoyBB_t_3D_P(NULL),d_gradVmoyBB_tdt_3D_P(NULL),d_gradVBB_t_3D_P(NULL),d_gradVBB_tdt_3D_P(NULL) // puis les grandeurs hors métriques ,sig_HH_t_3D(),sig_HH_3D(),Deps_BB_3D(),eps_BB_3D(),delta_eps_BB_3D() ,d_eps_BB_3D_P(),d_sig_HH_3D_P() ,d_eps_BB_3D(),d_sig_HH_3D(),d_sigma_deps_3D(),d_sigma_deps_1D() // un conteneur d'un point d'intégration courant ,ptintmeca(3) { // conteneurs des métriques // a priori seules les grandeurs principales sont affecté expli_3D = new Met_abstraite::Expli_t_tdt // constructeur normal (&giB_0_3D,&giH_0_3D,&giB_t_3D,&giH_t_3D,&giB_tdt_3D,&giH_tdt_3D ,&gijBB_0_3D,&gijHH_0_3D,&gijBB_t_3D,&gijHH_t_3D ,&gijBB_tdt_3D,&gijHH_tdt_3D ,gradVmoyBB_t_3D_P,gradVmoyBB_tdt_3D_P,gradVBB_tdt_3D_P // pas affecté par défaut ,&d_gijBB_tdt_3D_P,&jacobien_tdt_3D,&jacobien_t_3D,&jacobien_0_3D); impli_3D = new Met_abstraite::Impli // constructeur normal (&giB_0_3D,&giH_0_3D,&giB_t_3D,&giH_t_3D,&giB_tdt_3D,&d_giB_tdt_3D,&giH_tdt_3D,&d_giH_tdt_3D ,&gijBB_0_3D,&gijHH_0_3D,&gijBB_t_3D,&gijHH_t_3D,&gijBB_tdt_3D,&gijHH_tdt_3D ,gradVmoyBB_t_3D_P,gradVmoyBB_tdt_3D_P,gradVBB_tdt_3D_P // pas affecté par défaut ,&d_gijBB_tdt_3D_P ,d2_gijBB_tdt_3D_P // pas affecté par défaut ,&d_gijHH_tdt_3D_P ,&jacobien_tdt_3D,&jacobien_t_3D,&jacobien_0_3D,&d_jacobien_tdt_3D ,d_gradVmoyBB_t_3D_P,d_gradVmoyBB_tdt_3D_P // pas affecté par défaut ,d_gradVBB_t_3D_P,d_gradVBB_tdt_3D_P); // pas affecté par défaut umat_cont_3D = new Met_abstraite::Umat_cont // constructeur normal (&giB_0_3D,&giH_0_3D,&giB_t_3D,&giH_t_3D,&giB_tdt_3D,&giH_tdt_3D ,&gijBB_0_3D,&gijHH_0_3D,&gijBB_t_3D,&gijHH_t_3D ,&gijBB_tdt_3D,&gijHH_tdt_3D ,gradVmoyBB_t_3D_P,gradVmoyBB_tdt_3D_P,gradVBB_tdt_3D_P // pas affecté par défaut ,&jacobien_tdt_3D,&jacobien_t_3D,&jacobien_0_3D); // on ajoute les invariants au pt integ courant ptintmeca.Change_statut_Invariants_contrainte (true); // initialisation par défaut des paramètres de la résolution de newton double tolerance_residu = 5.e-3; double tolerance_residu_rel = 1.e-4; int nb_boucle_maxi = 6; // le maximum d'itération permis int nb_dichotomie = 4; // le maxi de dichotomie prévu pour l'équation de Newton alg_zero.Modif_prec_res_abs(tolerance_residu); alg_zero.Modif_prec_res_rel(tolerance_residu_rel); alg_zero.Modif_iter_max(nb_boucle_maxi); alg_zero.Modif_nbMaxiIncre(nb_dichotomie); // def des indices ind(1)=2;ind(2)=3;ind(3)=2; jnd(1)=2;jnd(2)=3;jnd(3)=1; // résolution de d_sig_ef_gh // d_sig_ef_gh.Change_Choix_resolution(CRAMER,RIEN_PRECONDITIONNEMENT); // der_at_racine.Change_Choix_resolution(CRAMER,RIEN_PRECONDITIONNEMENT); // derResidu.Change_Choix_resolution(CRAMER,RIEN_PRECONDITIONNEMENT); }; // constructeur à partir d'une instance de contraintes planes // à condition que cette loi s'appuie sur un comportement 3D // les deux lois étant proche, les paramètres semblables sont mis en commun LoiContraintesPlanesDouble::LoiContraintesPlanesDouble (LoiContraintesPlanes& loi,bool calcul_en_3D_via_direction_quelconque_): Loi_comp_abstraite(LOI_CONTRAINTES_PLANES_DOUBLE,loi.Id_categorie(),1) ,calcul_en_3D_via_direction_quelconque(calcul_en_3D_via_direction_quelconque_) ,type_de_contrainte(loi.type_de_contrainte) ,fac_penal(loi.fac_penal),prec(loi.prec) ,lois_interne(NULL) ,alg_zero(loi.alg_zero),maxi_delta_var_eps_sur_iter_pour_Newton(loi.maxi_delta_var_eps_sur_iter_pour_Newton) ,sortie_post(loi.sortie_post) ,d_sig_ef_gh(2,2),d_eps_ef_11(2) ,fct_tolerance_residu(NULL),fct_tolerance_residu_rel(NULL) // ---- réglage résolution avec linéarisation ,val_initiale(2),racine(2)//,der_at_racine(2,2) ,residu(2)//,derResidu(2,2) ,der_at_racine(2,2,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT) ,derResidu(2,2,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT) //-------- spécifiques à Calcul_dsigma_deps hors axes ------------------------ ,ViB_3D(NULL),ViH_3D(NULL) ,val_initiale_3D(3),residu_3D(3),derResidu_3D(3,3,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT) ,eps_P_BB(),Deps_P_BB(),delta_eps_P_BB(),racine_3D(3) ,gamma3D(3,3),beta3D(3,3),gammaP_3D(3,3),betaP_3D(3,3) ,epsBB_tdt_cin(NULL),DepsBB_cin(NULL),delta_epsBB_cin(NULL) ,mat_inter(3,3),gij_meca_BB(),gij_meca_BB_t() ,V1V1_BB(),ind(3),jnd(3),VhVg_BB(3) //-------- fin spécifiques à Calcul_dsigma_deps hors axes ------------------------ // pour les mini et maxi on utilise ceux de h ,mini_hsurh0(loi.mini_hsurh0),mini_bsurb0(loi.mini_hsurh0) ,maxi_hsurh0(loi.maxi_hsurh0),maxi_bsurb0(loi.maxi_hsurh0) ,giB_normer_3_tdt_3D_sauve(3),giB_normer_2_tdt_3D_sauve(3) // -- conteneur des métriques: ce sont des pointeurs, pour l'instant on ne les affecte pas ,expli_3D(NULL),impli_3D(NULL),umat_cont_3D(NULL) // -- les variables pointées dans les conteneurs ,giB_0_3D(loi.giB_0_3D),giH_0_3D(loi.giH_0_3D),giB_t_3D(loi.giB_t_3D),giH_t_3D(loi.giH_t_3D) ,giB_tdt_3D(loi.giB_tdt_3D),d_giB_tdt_3D(loi.d_giB_tdt_3D),giH_tdt_3D(loi.giH_tdt_3D) ,d_giH_tdt_3D(loi.d_giH_tdt_3D),gijBB_0_3D(loi.gijBB_0_3D),gijHH_0_3D(loi.gijHH_0_3D) ,gijBB_t_3D(loi.gijBB_t_3D),gijHH_t_3D(loi.gijHH_t_3D),gijBB_tdt_3D(loi.gijBB_tdt_3D) ,gijHH_tdt_3D(loi.gijHH_tdt_3D),gradVmoyBB_t_3D(loi.gradVmoyBB_t_3D) ,gradVmoyBB_tdt_3D(loi.gradVmoyBB_tdt_3D),gradVBB_tdt_3D(loi.gradVBB_tdt_3D) ,jacobien_0_3D(loi.jacobien_0_3D),d_jacobien_tdt_3D(loi.d_jacobien_tdt_3D) ,d_gradVBB_t_3D_P(loi.d_gradVBB_t_3D_P),d_gradVBB_tdt_3D_P(loi.d_gradVBB_tdt_3D_P) // avec les vrais tableaux associés aux tableaux de pointeurs: ici uniquement le dimensionnement ,d_gijBB_tdt_3D(loi.d_gijBB_tdt_3D),d2_gijBB_tdt_3D(loi.d2_gijBB_tdt_3D) ,d_gijHH_tdt_3D(loi.d_gijHH_tdt_3D) ,d_gradVmoyBB_t_3D(loi.d_gradVmoyBB_t_3D),d_gradVmoyBB_tdt_3D(loi.d_gradVmoyBB_tdt_3D) ,d_gradVBB_t_3D(loi.d_gradVBB_t_3D),d_gradVBB_tdt_3D(loi.d_gradVBB_tdt_3D) // puis les grandeurs hors métriques, pour les tableaux de pointeurs, c'est uniquement du dimensionnement ,sig_HH_t_3D(loi.sig_HH_t_3D),sig_HH_3D(loi.sig_HH_3D),Deps_BB_3D(loi.Deps_BB_3D) ,eps_BB_3D(loi.eps_BB_3D),delta_eps_BB_3D(loi.delta_eps_BB_3D) ,d_eps_BB_3D_P(loi.d_eps_BB_3D_P),d_sig_HH_3D_P(loi.d_sig_HH_3D_P) ,d_eps_BB_3D(loi.d_eps_BB_3D),d_sig_HH_3D(loi.d_sig_HH_3D),d_sigma_deps_3D(loi.d_sigma_deps_3D) ,d_sigma_deps_1D() // un conteneur d'un point d'intégration courant ,ptintmeca(loi.ptintmeca) { lois_interne = loi.lois_interne->Nouvelle_loi_identique(); // association des pointeurs de grandeurs si nécessaire if (loi.gradVmoyBB_t_3D_P != NULL) {gradVmoyBB_t_3D_P = &gradVmoyBB_t_3D;}; if (loi.gradVmoyBB_tdt_3D_P != NULL) {gradVmoyBB_tdt_3D_P = &gradVmoyBB_tdt_3D;}; if (loi.gradVBB_tdt_3D_P != NULL) {gradVBB_tdt_3D_P = &gradVBB_tdt_3D;}; // def des tableaux de pointeurs pour les conteneurs de métriques // -- cas des tableaux de pointeurs, ils ont déjà la bonne dimension int ta_d_gijBB_tdt_3D = loi.d_gijBB_tdt_3D.Taille(); for (int i=1;i<= ta_d_gijBB_tdt_3D;i++) d_gijBB_tdt_3D_P(i) = &(d_gijBB_tdt_3D(i)); if (loi.d2_gijBB_tdt_3D_P!= NULL) { int tai_d2_gijBB_tdt_3D = d2_gijBB_tdt_3D.Taille1(); d2_gijBB_tdt_3D_P = new Tableau2 (tai_d2_gijBB_tdt_3D); int taj_d2_gijBB_tdt_3D = d2_gijBB_tdt_3D.Taille2(); for (int i=1;i<= tai_d2_gijBB_tdt_3D;i++) for (int j=1;j<= taj_d2_gijBB_tdt_3D;j++) (*d2_gijBB_tdt_3D_P)(i,j) = &(d2_gijBB_tdt_3D(i,j)); }; int ta_d_gijHH_tdt_3D = d_gijHH_tdt_3D.Taille(); for (int i=1;i<= ta_d_gijHH_tdt_3D;i++) d_gijHH_tdt_3D_P(i) = &(d_gijHH_tdt_3D(i)); if (loi.d_gradVmoyBB_t_3D_P != NULL) { int ta_d_gradVmoyBB_t_3D = d_gradVmoyBB_t_3D.Taille(); d_gradVmoyBB_t_3D_P = new Tableau (ta_d_gradVmoyBB_t_3D); for (int i=1;i<= ta_d_gradVmoyBB_t_3D;i++) (*d_gradVmoyBB_t_3D_P)(i) = &(d_gradVmoyBB_t_3D(i)); }; if (loi.d_gradVmoyBB_tdt_3D_P != NULL) { int ta_d_gradVmoyBB_tdt_3D = d_gradVmoyBB_tdt_3D.Taille(); d_gradVmoyBB_tdt_3D_P = new Tableau (ta_d_gradVmoyBB_tdt_3D); for (int i=1;i<= ta_d_gradVmoyBB_tdt_3D;i++) (*d_gradVmoyBB_tdt_3D_P)(i) = &(d_gradVmoyBB_tdt_3D(i)); }; if (loi.d_gradVBB_t_3D_P != NULL) { int ta_d_gradVBB_t_3D = d_gradVBB_t_3D.Taille(); d_gradVBB_t_3D_P = new Tableau (ta_d_gradVBB_t_3D); for (int i=1;i<= ta_d_gradVBB_t_3D;i++) (*d_gradVBB_t_3D_P)(i) = &(d_gradVBB_t_3D(i)); }; if (loi.d_gradVBB_tdt_3D_P != NULL) { int ta_d_gradVBB_tdt_3D = d_gradVBB_tdt_3D.Taille(); d_gradVBB_tdt_3D_P = new Tableau (ta_d_gradVBB_tdt_3D); for (int i=1;i<= ta_d_gradVBB_tdt_3D;i++) (*d_gradVBB_tdt_3D_P)(i) = &(d_gradVBB_tdt_3D(i)); }; // conteneurs des métriques // a priori seules les grandeurs principales sont affecté expli_3D = new Met_abstraite::Expli_t_tdt // constructeur normal (&giB_0_3D,&giH_0_3D,&giB_t_3D,&giH_t_3D,&giB_tdt_3D,&giH_tdt_3D ,&gijBB_0_3D,&gijHH_0_3D,&gijBB_t_3D,&gijHH_t_3D ,&gijBB_tdt_3D,&gijHH_tdt_3D ,gradVmoyBB_t_3D_P,gradVmoyBB_tdt_3D_P,gradVBB_tdt_3D_P // pas affecté par défaut ,&d_gijBB_tdt_3D_P,&jacobien_tdt_3D,&jacobien_t_3D,&jacobien_0_3D); impli_3D = new Met_abstraite::Impli // constructeur normal (&giB_0_3D,&giH_0_3D,&giB_t_3D,&giH_t_3D,&giB_tdt_3D,&d_giB_tdt_3D,&giH_tdt_3D,&d_giH_tdt_3D ,&gijBB_0_3D,&gijHH_0_3D,&gijBB_t_3D,&gijHH_t_3D,&gijBB_tdt_3D,&gijHH_tdt_3D ,gradVmoyBB_t_3D_P,gradVmoyBB_tdt_3D_P,gradVBB_tdt_3D_P // pas affecté par défaut ,&d_gijBB_tdt_3D_P ,d2_gijBB_tdt_3D_P // pas affecté par défaut ,&d_gijHH_tdt_3D_P ,&jacobien_tdt_3D,&jacobien_t_3D,&jacobien_0_3D,&d_jacobien_tdt_3D ,d_gradVmoyBB_t_3D_P,d_gradVmoyBB_tdt_3D_P // pas affecté par défaut ,d_gradVBB_t_3D_P,d_gradVBB_tdt_3D_P); // pas affecté par défaut umat_cont_3D = new Met_abstraite::Umat_cont // constructeur normal (&giB_0_3D,&giH_0_3D,&giB_t_3D,&giH_t_3D,&giB_tdt_3D,&giH_tdt_3D ,&gijBB_0_3D,&gijHH_0_3D,&gijBB_t_3D,&gijHH_t_3D ,&gijBB_tdt_3D,&gijHH_tdt_3D ,gradVmoyBB_t_3D_P,gradVmoyBB_tdt_3D_P,gradVBB_tdt_3D_P // pas affecté par défaut ,&jacobien_tdt_3D,&jacobien_t_3D,&jacobien_0_3D); // puis les tableaux de pointeurs de grandeurs hors métriques int ta_d_eps_BB_3D = d_eps_BB_3D.Taille(); for (int i=1;i<= ta_d_eps_BB_3D;i++) d_eps_BB_3D_P(i) = &(d_eps_BB_3D(i)); int ta_d_sig_HH_3D = d_sig_HH_3D.Taille(); for (int i=1;i<= ta_d_sig_HH_3D;i++) d_sig_HH_3D_P(i) = &(d_sig_HH_3D(i)); // def des indices ind(1)=2;ind(2)=3;ind(3)=1; jnd(1)=2;jnd(2)=3;jnd(3)=2; }; // Constructeur de copie LoiContraintesPlanesDouble::LoiContraintesPlanesDouble (const LoiContraintesPlanesDouble& loi) : Loi_comp_abstraite(loi) ,type_de_contrainte(loi.type_de_contrainte) ,fac_penal(loi.fac_penal),prec(loi.prec) ,lois_interne(NULL) ,alg_zero(loi.alg_zero),maxi_delta_var_eps_sur_iter_pour_Newton(loi.maxi_delta_var_eps_sur_iter_pour_Newton) ,sortie_post(loi.sortie_post) ,fct_tolerance_residu(loi.fct_tolerance_residu),fct_tolerance_residu_rel(loi.fct_tolerance_residu_rel) ,calcul_en_3D_via_direction_quelconque(loi.calcul_en_3D_via_direction_quelconque) ,d_sig_ef_gh(2,2),d_eps_ef_11(2) // ---- réglage résolution avec linéarisation ,val_initiale(2),racine(2)//,der_at_racine(2,2) ,residu(2)//,derResidu(2,2) ,der_at_racine(2,2,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT) ,derResidu(2,2,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT) //-------- spécifiques à Calcul_dsigma_deps hors axes ------------------------ ,ViB_3D(NULL),ViH_3D(NULL) ,val_initiale_3D(3),residu_3D(3),derResidu_3D(3,3,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT) ,eps_P_BB(loi.eps_P_BB),Deps_P_BB(loi.Deps_P_BB),delta_eps_P_BB(loi.delta_eps_P_BB) ,racine_3D(3) ,gamma3D(3,3),beta3D(3,3),gammaP_3D(3,3),betaP_3D(3,3) ,epsBB_tdt_cin(NULL),DepsBB_cin(NULL),delta_epsBB_cin(NULL) ,mat_inter(3,3),gij_meca_BB(),gij_meca_BB_t() ,V1V1_BB(),ind(3),jnd(3),VhVg_BB(3) //-------- fin spécifiques à Calcul_dsigma_deps hors axes ------------------------ ,mini_hsurh0(loi.mini_hsurh0),mini_bsurb0(loi.mini_bsurb0) ,maxi_hsurh0(loi.maxi_hsurh0),maxi_bsurb0(loi.maxi_bsurb0) ,giB_normer_3_tdt_3D_sauve(3),giB_normer_2_tdt_3D_sauve(3) // -- conteneur des métriques: ce sont des pointeurs, pour l'instant on ne les affecte pas ,expli_3D(NULL),impli_3D(NULL),umat_cont_3D(NULL) // -- les variables pointées dans les conteneurs ,giB_0_3D(loi.giB_0_3D),giH_0_3D(loi.giH_0_3D),giB_t_3D(loi.giB_t_3D),giH_t_3D(loi.giH_t_3D) ,giB_tdt_3D(loi.giB_tdt_3D),d_giB_tdt_3D(loi.d_giB_tdt_3D),giH_tdt_3D(loi.giH_tdt_3D) ,d_giH_tdt_3D(loi.d_giH_tdt_3D),gijBB_0_3D(loi.gijBB_0_3D),gijHH_0_3D(loi.gijHH_0_3D) ,gijBB_t_3D(loi.gijBB_t_3D),gijHH_t_3D(loi.gijHH_t_3D),gijBB_tdt_3D(loi.gijBB_tdt_3D) ,gijHH_tdt_3D(loi.gijHH_tdt_3D),gradVmoyBB_t_3D(loi.gradVmoyBB_t_3D) ,gradVmoyBB_tdt_3D(loi.gradVmoyBB_tdt_3D),gradVBB_tdt_3D(loi.gradVBB_tdt_3D) ,jacobien_0_3D(loi.jacobien_0_3D),d_jacobien_tdt_3D(loi.d_jacobien_tdt_3D) ,d_gradVBB_t_3D_P(loi.d_gradVBB_t_3D_P),d_gradVBB_tdt_3D_P(loi.d_gradVBB_tdt_3D_P) // avec les vrais tableaux associés aux tableaux de pointeurs: ici uniquement le dimensionnement ,d_gijBB_tdt_3D(loi.d_gijBB_tdt_3D),d2_gijBB_tdt_3D(loi.d2_gijBB_tdt_3D) ,d_gijHH_tdt_3D(loi.d_gijHH_tdt_3D) ,d_gradVmoyBB_t_3D(loi.d_gradVmoyBB_t_3D),d_gradVmoyBB_tdt_3D(loi.d_gradVmoyBB_tdt_3D) ,d_gradVBB_t_3D(loi.d_gradVBB_t_3D),d_gradVBB_tdt_3D(loi.d_gradVBB_tdt_3D) // puis les grandeurs hors métriques, pour les tableaux de pointeurs, c'est uniquement du dimensionnement ,sig_HH_t_3D(loi.sig_HH_t_3D),sig_HH_3D(loi.sig_HH_3D),Deps_BB_3D(loi.Deps_BB_3D) ,eps_BB_3D(loi.eps_BB_3D),delta_eps_BB_3D(loi.delta_eps_BB_3D) ,d_eps_BB_3D_P(loi.d_eps_BB_3D_P),d_sig_HH_3D_P(loi.d_sig_HH_3D_P) ,d_eps_BB_3D(loi.d_eps_BB_3D),d_sig_HH_3D(loi.d_sig_HH_3D),d_sigma_deps_3D(loi.d_sigma_deps_3D) ,d_sigma_deps_1D(loi.d_sigma_deps_1D) // un conteneur d'un point d'intégration courant ,ptintmeca(loi.ptintmeca) { lois_interne = loi.lois_interne->Nouvelle_loi_identique(); // association des pointeurs de grandeurs si nécessaire if (loi.gradVmoyBB_t_3D_P != NULL) {gradVmoyBB_t_3D_P = &gradVmoyBB_t_3D;}; if (loi.gradVmoyBB_tdt_3D_P != NULL) {gradVmoyBB_tdt_3D_P = &gradVmoyBB_tdt_3D;}; if (loi.gradVBB_tdt_3D_P != NULL) {gradVBB_tdt_3D_P = &gradVBB_tdt_3D;}; // def des tableaux de pointeurs pour les conteneurs de métriques // -- cas des tableaux de pointeurs, ils ont déjà la bonne dimension int ta_d_gijBB_tdt_3D = loi.d_gijBB_tdt_3D.Taille(); for (int i=1;i<= ta_d_gijBB_tdt_3D;i++) d_gijBB_tdt_3D_P(i) = &(d_gijBB_tdt_3D(i)); if (loi.d2_gijBB_tdt_3D_P!= NULL) { int tai_d2_gijBB_tdt_3D = d2_gijBB_tdt_3D.Taille1(); d2_gijBB_tdt_3D_P = new Tableau2 (tai_d2_gijBB_tdt_3D); int taj_d2_gijBB_tdt_3D = d2_gijBB_tdt_3D.Taille2(); for (int i=1;i<= tai_d2_gijBB_tdt_3D;i++) for (int j=1;j<= taj_d2_gijBB_tdt_3D;j++) (*d2_gijBB_tdt_3D_P)(i,j) = &(d2_gijBB_tdt_3D(i,j)); }; int ta_d_gijHH_tdt_3D = d_gijHH_tdt_3D.Taille(); for (int i=1;i<= ta_d_gijHH_tdt_3D;i++) d_gijHH_tdt_3D_P(i) = &(d_gijHH_tdt_3D(i)); if (loi.d_gradVmoyBB_t_3D_P != NULL) { int ta_d_gradVmoyBB_t_3D = d_gradVmoyBB_t_3D.Taille(); d_gradVmoyBB_t_3D_P = new Tableau (ta_d_gradVmoyBB_t_3D); for (int i=1;i<= ta_d_gradVmoyBB_t_3D;i++) (*d_gradVmoyBB_t_3D_P)(i) = &(d_gradVmoyBB_t_3D(i)); }; if (loi.d_gradVmoyBB_tdt_3D_P != NULL) { int ta_d_gradVmoyBB_tdt_3D = d_gradVmoyBB_tdt_3D.Taille(); d_gradVmoyBB_tdt_3D_P = new Tableau (ta_d_gradVmoyBB_tdt_3D); for (int i=1;i<= ta_d_gradVmoyBB_tdt_3D;i++) (*d_gradVmoyBB_tdt_3D_P)(i) = &(d_gradVmoyBB_tdt_3D(i)); }; if (loi.d_gradVBB_t_3D_P != NULL) { int ta_d_gradVBB_t_3D = d_gradVBB_t_3D.Taille(); d_gradVBB_t_3D_P = new Tableau (ta_d_gradVBB_t_3D); for (int i=1;i<= ta_d_gradVBB_t_3D;i++) (*d_gradVBB_t_3D_P)(i) = &(d_gradVBB_t_3D(i)); }; if (loi.d_gradVBB_tdt_3D_P != NULL) { int ta_d_gradVBB_tdt_3D = d_gradVBB_tdt_3D.Taille(); d_gradVBB_tdt_3D_P = new Tableau (ta_d_gradVBB_tdt_3D); for (int i=1;i<= ta_d_gradVBB_tdt_3D;i++) (*d_gradVBB_tdt_3D_P)(i) = &(d_gradVBB_tdt_3D(i)); }; // conteneurs des métriques // a priori seules les grandeurs principales sont affecté expli_3D = new Met_abstraite::Expli_t_tdt // constructeur normal (&giB_0_3D,&giH_0_3D,&giB_t_3D,&giH_t_3D,&giB_tdt_3D,&giH_tdt_3D ,&gijBB_0_3D,&gijHH_0_3D,&gijBB_t_3D,&gijHH_t_3D ,&gijBB_tdt_3D,&gijHH_tdt_3D ,gradVmoyBB_t_3D_P,gradVmoyBB_tdt_3D_P,gradVBB_tdt_3D_P // pas affecté par défaut ,&d_gijBB_tdt_3D_P,&jacobien_tdt_3D,&jacobien_t_3D,&jacobien_0_3D); impli_3D = new Met_abstraite::Impli // constructeur normal (&giB_0_3D,&giH_0_3D,&giB_t_3D,&giH_t_3D,&giB_tdt_3D,&d_giB_tdt_3D,&giH_tdt_3D,&d_giH_tdt_3D ,&gijBB_0_3D,&gijHH_0_3D,&gijBB_t_3D,&gijHH_t_3D,&gijBB_tdt_3D,&gijHH_tdt_3D ,gradVmoyBB_t_3D_P,gradVmoyBB_tdt_3D_P,gradVBB_tdt_3D_P // pas affecté par défaut ,&d_gijBB_tdt_3D_P ,d2_gijBB_tdt_3D_P // pas affecté par défaut ,&d_gijHH_tdt_3D_P ,&jacobien_tdt_3D,&jacobien_t_3D,&jacobien_0_3D,&d_jacobien_tdt_3D ,d_gradVmoyBB_t_3D_P,d_gradVmoyBB_tdt_3D_P // pas affecté par défaut ,d_gradVBB_t_3D_P,d_gradVBB_tdt_3D_P); // pas affecté par défaut umat_cont_3D = new Met_abstraite::Umat_cont // constructeur normal (&giB_0_3D,&giH_0_3D,&giB_t_3D,&giH_t_3D,&giB_tdt_3D,&giH_tdt_3D ,&gijBB_0_3D,&gijHH_0_3D,&gijBB_t_3D,&gijHH_t_3D ,&gijBB_tdt_3D,&gijHH_tdt_3D ,gradVmoyBB_t_3D_P,gradVmoyBB_tdt_3D_P,gradVBB_tdt_3D_P // pas affecté par défaut ,&jacobien_tdt_3D,&jacobien_t_3D,&jacobien_0_3D); // puis les tableaux de pointeurs de grandeurs hors métriques int ta_d_eps_BB_3D = d_eps_BB_3D.Taille(); for (int i=1;i<= ta_d_eps_BB_3D;i++) d_eps_BB_3D_P(i) = &(d_eps_BB_3D(i)); int ta_d_sig_HH_3D = d_sig_HH_3D.Taille(); for (int i=1;i<= ta_d_sig_HH_3D;i++) d_sig_HH_3D_P(i) = &(d_sig_HH_3D(i)); // initialisation des paramètres de la résolution de newton // résolution de d_sig_ef_gh // d_sig_ef_gh.Change_Choix_resolution(CRAMER,RIEN_PRECONDITIONNEMENT); // der_at_racine.Change_Choix_resolution(CRAMER,RIEN_PRECONDITIONNEMENT); // derResidu.Change_Choix_resolution(CRAMER,RIEN_PRECONDITIONNEMENT); // def des indices ind(1)=2;ind(2)=3;ind(3)=1; jnd(1)=2;jnd(2)=3;jnd(3)=2; // on regarde s'il y a un pilotage via des fct nD de la précision if (fct_tolerance_residu != NULL) { if (fct_tolerance_residu->NomFonction() == "_") {// comme il s'agit d'une fonction locale on la redéfinie (sinon pb lors du destructeur de loi) string non_fonction("_"); fct_tolerance_residu = Fonction_nD::New_Fonction_nD(*fct_tolerance_residu); }; }; if (fct_tolerance_residu_rel != NULL) { if (fct_tolerance_residu_rel->NomFonction() == "_") {// comme il s'agit d'une fonction locale on la redéfinie (sinon pb lors du destructeur de loi) string non_fonction("_"); fct_tolerance_residu_rel = Fonction_nD::New_Fonction_nD(*fct_tolerance_residu_rel); }; }; }; LoiContraintesPlanesDouble::~LoiContraintesPlanesDouble () // Destructeur { if (lois_interne != NULL) delete lois_interne; // les conteneurs de pointeurs: delete expli_3D;delete impli_3D; delete umat_cont_3D; // pour les grandeurs de base, pas de new, donc pas de delete // pour les tableaux de pointeurs, idem s'ils ne sont pas addressé par un pointeur // sinon il faut détruire le tableau if (d2_gijBB_tdt_3D_P!= NULL) delete d2_gijBB_tdt_3D_P; if (d_gradVmoyBB_t_3D_P!= NULL) delete d_gradVmoyBB_t_3D_P; if (d_gradVmoyBB_tdt_3D_P!= NULL) delete d_gradVmoyBB_tdt_3D_P; if (d_gradVBB_t_3D_P!= NULL) delete d_gradVBB_t_3D_P; if (d_gradVBB_tdt_3D_P!= NULL) delete d_gradVBB_tdt_3D_P; // cas du pilotage de la précision if (fct_tolerance_residu != NULL) if (fct_tolerance_residu->NomFonction() == "_") delete fct_tolerance_residu; if (fct_tolerance_residu_rel != NULL) if (fct_tolerance_residu_rel->NomFonction() == "_") delete fct_tolerance_residu_rel; }; // def d'une instance de données spécifiques, et initialisation // valable une fois que les différentes lois internes sont définit LoiContraintesPlanesDouble::SaveResul * LoiContraintesPlanesDouble::New_et_Initialise() { // on crée éventuellement le conteneur pour la loi SaveResul* le_SaveResul = NULL; if (lois_interne != NULL) le_SaveResul = lois_interne->New_et_Initialise(); // on ramène la bonne instance LoiContraintesPlanesDouble::SaveResul * retour = new SaveResul_LoiContraintesPlanesDouble(le_SaveResul); SaveResul_LoiContraintesPlanesDouble * inter = (SaveResul_LoiContraintesPlanesDouble *) retour; if (calcul_en_3D_via_direction_quelconque) {inter->Creation_def_mecanique(); inter->def_P.Change_taille(3);inter->def_P_t.Change_taille(3); }; // retour return retour; }; // Lecture des donnees de la classe sur fichier void LoiContraintesPlanesDouble::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D ,LesFonctions_nD& lesFonctionsnD) { // vérification que la dimension de l'espace est 3D if (ParaGlob::Dimension() != 3) { cout << "\n *** erreur 1 : la dimension de l'espace doit etre 3, pour pouvoir utiliser une loi de contrainte plane "; throw (UtilLecture::ErrNouvelleDonnee(-1)); if (ParaGlob::NiveauImpression() > 5) cout << "\n LoiContraintesPlanesDouble::LectureDonneesParticulieres (... "; Sortie(1); }; string nom_class_methode("LoiContraintesPlanesDouble::LectureDonneesParticulieres" ); // on lit tout d'abord la méthode pour prendre en compte la contrainte *(entreePrinc->entree) >> type_de_contrainte; // on met tout d'abord les valeurs par défaut prec = 0.005; fac_penal = 30.; string nom; // on traite en fonction du type de contrainte switch (type_de_contrainte) { case PERTURBATION : { if (strstr(entreePrinc->tablcar,"deformation_transversale")!=NULL) { *(entreePrinc->entree) >> nom; if (nom != "deformation_transversale") { cout << "\n erreur en lecture de la loi Contraintes planes, on attendait le mot cle deformation_transversale" << " alors que l'on a lue " << nom; entreePrinc->MessageBuffer("**erreur 2 LoiContraintesPlanesDouble::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; } else // sinon les autres cas de perturbation ne sont actuellement pas pris en compte { cout << "\n erreur en lecture du type de perturbation : pour l'instant seule " << " le type: deformation_transversale , est pris en compte " ; entreePrinc->MessageBuffer("**erreur 3 LoiContraintesPlanesDouble::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; break; } case PENALISATION : case MULTIPLICATEUR_DE_LAGRANGE : { // ---- on regarde s'il faut lire une précision if (strstr(entreePrinc->tablcar,"prec=")!=NULL) { *(entreePrinc->entree) >> nom; if (nom != "prec=") { cout << "\n erreur en lecture de la loi Contraintes planes, on attendait le mot cle prec=" << " alors que l'on a lue " << nom; entreePrinc->MessageBuffer("**erreur 4 LoiContraintesPlanesDouble::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; *(entreePrinc->entree) >> prec; }; // --- on regarde s'il faut lire la pénalisation if (strstr(entreePrinc->tablcar,"fac=")!=NULL) { *(entreePrinc->entree) >> nom; if (nom != "fac=") { cout << "\n erreur en lecture de la loi Contraintes planes, on attendait le mot cle fac=" << " alors que l'on a lue " << nom; entreePrinc->MessageBuffer("**erreur 5 LoiContraintesPlanesDouble::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; *(entreePrinc->entree) >> fac_penal; }; break; } case NEWTON_LOCAL : { // ---- on regarde s'il faut lire des paramètres de réglage // --- lecture éventuelle des paramètres de réglage ---- // de l'algo de résolution de l'équation d'avancement temporel if(strstr(entreePrinc->tablcar,"avec_parametres_de_reglage_")!=0) {entreePrinc->NouvelleDonnee(); // on se positionne sur un nouvel enreg // on lit tant que l'on ne rencontre pas la ligne contenant "fin_parametres_reglage_Algo_Newton_" // ou un nouveau mot clé global auquel cas il y a pb !! MotCle motCle; // ref aux mots cle while (strstr(entreePrinc->tablcar,"fin_parametres_reglage_Algo_Newton_")==0) { // si on a un mot clé global dans la ligne courante c-a-d dans tablcar --> erreur if ( motCle.SimotCle(entreePrinc->tablcar)) { cout << "\n erreur de lecture des parametre de reglage de l'algorithme de Newton: on n'a pas trouve le mot cle " << " fin_parametres_reglage_Algo_Newton_ et par contre la ligne courante contient un mot cle global "; entreePrinc->MessageBuffer("** erreur5 des parametres de reglage de la loi de comportement de contraintes planes**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // lecture d'un mot clé *(entreePrinc->entree) >> nom; if ((entreePrinc->entree)->rdstate() == 0) {} // lecture normale #ifdef ENLINUX else if ((entreePrinc->entree)->fail()) // on a atteind la fin de la ligne et on appelle un nouvel enregistrement { entreePrinc->NouvelleDonnee(); // lecture d'un nouvelle enregistrement *(entreePrinc->entree) >>nom; } #else else if ((entreePrinc->entree)->eof()) // la lecture est bonne mais on a atteind la fin de la ligne { if(nom != "fin_parametres_reglage_Algo_Newton_") {entreePrinc->NouvelleDonnee(); *(entreePrinc->entree) >> nom;}; } #endif else // cas d'une erreur de lecture { cout << "\n erreur de lecture inconnue "; entreePrinc->MessageBuffer("** erreur4 des parametres de reglage de l'algoritheme de Newton de la loi de comportement de contraintes planes**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // nombre d'itération maxi if (nom == "nb_iteration_maxi_") {int nb_boucle_maxi; // le maximum d'itération permis *(entreePrinc->entree) >> nb_boucle_maxi; alg_zero.Modif_iter_max(nb_boucle_maxi); } // nombre de dichotomie maxi else if (nom == "nb_dichotomie_maxi_") {int nb_dichotomie; // le maxi de dichotomie prévu pour l'équation de Newton *(entreePrinc->entree) >> nb_dichotomie; alg_zero.Modif_nbMaxiIncre(nb_dichotomie); } // tolérance absolue sur le résidu else if (nom == "tolerance_residu_") { string mot_cle("=fonction_nD:"); if(strstr(entreePrinc->tablcar,mot_cle.c_str())==0) {// lecture du paramètre double tolerance_residu; // tolérance absolue sur la résolution de l'équation *(entreePrinc->entree) >> tolerance_residu; alg_zero.Modif_prec_res_abs(tolerance_residu); } else // on lit une fonction {// on lit le nom de la fonction string nom_fonct; bool lec = entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle,nom_fonct); if (!lec ) { entreePrinc->MessageBuffer("**erreur en lecture** tolerance_residu_ via une fonction nD"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // maintenant on définit la fonction if (lesFonctionsnD.Existe(nom_fonct)) {fct_tolerance_residu = lesFonctionsnD.Trouve(nom_fonct); } else {// sinon il faut la lire maintenant string non("_"); fct_tolerance_residu = Fonction_nD::New_Fonction_nD(non, Id_Nom_Fonction_nD(nom_fonct)); // lecture de la courbe fct_tolerance_residu->LectDonnParticulieres_Fonction_nD (non,entreePrinc); // maintenant on vérifie que la fonction est utilisable if (fct_tolerance_residu->NbComposante() != 1 ) { cout << "\n erreur en lecture, la fonction " << nom_fonct << " est une fonction vectorielle a " << fct_tolerance_residu->NbComposante() << " composantes alors qu'elle devrait etre scalaire ! " << " elle n'est donc pas utilisable !! "; string message("\n**erreur** \n"+nom_class_methode+"(..."); entreePrinc->MessageBuffer(message); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; // on mettra à jour pendant le calcul, la valeur de la précision }; } // tolérance relative sur le résidu else if (nom == "tolerance_residu_rel_") { string mot_cle("=fonction_nD:"); if(strstr(entreePrinc->tablcar,mot_cle.c_str())==0) {// lecture du paramètre double tolerance_residu_rel; // tolérance absolue sur la résolution de l'équation *(entreePrinc->entree) >> tolerance_residu_rel; alg_zero.Modif_prec_res_rel(tolerance_residu_rel); } else // on lit une fonction {// on lit le nom de la fonction string nom_fonct; bool lec = entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle,nom_fonct); if (!lec ) { entreePrinc->MessageBuffer("**erreur en lecture** tolerance_residu_ via une fonction nD"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // maintenant on définit la fonction if (lesFonctionsnD.Existe(nom_fonct)) {fct_tolerance_residu_rel = lesFonctionsnD.Trouve(nom_fonct); } else {// sinon il faut la lire maintenant string non("_"); fct_tolerance_residu_rel = Fonction_nD::New_Fonction_nD(non, Id_Nom_Fonction_nD(nom_fonct)); // lecture de la courbe fct_tolerance_residu_rel->LectDonnParticulieres_Fonction_nD (non,entreePrinc); // maintenant on vérifie que la fonction est utilisable if (fct_tolerance_residu_rel->NbComposante() != 1 ) { cout << "\n erreur en lecture, la fonction " << nom_fonct << " est une fonction vectorielle a " << fct_tolerance_residu_rel->NbComposante() << " composantes alors qu'elle devrait etre scalaire ! " << " elle n'est donc pas utilisable !! "; string message("\n**erreur** \n"+nom_class_methode+"(..."); entreePrinc->MessageBuffer(message); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; // on mettra à jour pendant le calcul, la valeur de la précision relative }; } // maxi_delta_var_eps_sur_iter_pour_Newton else if (nom == "maxi_delta_var_eps_sur_iter_pour_Newton_") { *(entreePrinc->entree) >> maxi_delta_var_eps_sur_iter_pour_Newton; } // le minimum de hsurh0 else if (nom == "mini_hsurh0_") {*(entreePrinc->entree) >> mini_hsurh0; } // le maximum de hsurh0 else if (nom == "maxi_hsurh0_") {*(entreePrinc->entree) >> maxi_hsurh0; } // le minimum de bsurb0 else if (nom == "mini_bsurb0_") {*(entreePrinc->entree) >> mini_bsurb0; } // le maximum de bsurb0 else if (nom == "maxi_bsurb0_") {*(entreePrinc->entree) >> maxi_bsurb0; } // forcer un stockage des indicateurs de la résolution else if (nom == "sortie_post_") {*(entreePrinc->entree) >> sortie_post; } else if (nom == "calcul_en_3D_via_direction_quelconque_") {calcul_en_3D_via_direction_quelconque = true; } // forcer un affichage particulier pour les méthodes else if (nom == "permet_affichage_") {int niveau=0; *(entreePrinc->entree) >> niveau; alg_zero.Modif_affichage(niveau); // on met à jour l'algo de newton } // sinon ce n'est pas un mot clé connu, on le signale else if (nom != "fin_parametres_reglage_Algo_Newton_") { cout << "\n erreur en lecture d'un parametre, le mot cle est inconnu " << " on a lu : " << nom << endl; if (ParaGlob::NiveauImpression()>3) cout << "\n LoiContraintesPlanesDouble::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } }; //-- fin du while }; //-- fin de la lecture des paramètres de réglage break; } default : cout << "\nErreur : valeur incorrecte du type de contrainte lue !: " << type_de_contrainte << " \n"; entreePrinc->MessageBuffer("**erreur 6 LoiContraintesPlanesDouble::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // -- on lit maintenant au choix soit rien, soit un facteur de pénalisation et/ou une précision // maintenant lecture de la loi entreePrinc->NouvelleDonnee(); // lecture du nom de la loi string st2,nom3; *(entreePrinc->entree) >> st2; // definition de la loi LoiAbstraiteGeneral * pt = LesLoisDeComp::Def_loi(st2); lois_interne = (Loi_comp_abstraite*) LesLoisDeComp::Def_loi(st2); pt = lois_interne; // --- lecture des informations particulières propres à la loi entreePrinc->NouvelleDonnee(); // prepa du flot de lecture pt->LectureDonneesParticulieres (entreePrinc,lesCourbes1D,lesFonctionsnD); // on s'occupe de la catégorie après la lecture des informations particulières (variable def dans LoiAbstraiteGeneral) LoiAbstraiteGeneral::categorie_loi_comp = pt->Id_categorie(); if (!GroupeMecanique(categorie_loi_comp)) { cout << "\n erreur1 en lecture des lois constitutives elementaire d'une loi LoiContraintesPlanesDouble" << "\n la loi lue: " << pt->Nom_comport() << " n'est pas une loi mecanique, elle fait partie " << " de la categorie: "<< Nom_categorie_loi_comp(categorie_loi_comp); entreePrinc->MessageBuffer("**erreur 7 LoiContraintesPlanesDouble::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // si la loi est thermo dépendante on indique que la loi de contrainte plane l'est aussi if (((Loi_comp_abstraite*)pt)->ThermoDependante()) this->thermo_dependant = true; // entreePrinc->NouvelleDonnee(); // prepa du flot de lecture pour d'autre loi éventuellement // appel au niveau de la classe mère Loi_comp_abstraite::Lecture_type_deformation_et_niveau_commentaire (*entreePrinc,lesFonctionsnD,true); }; // Lecture des paramètres particuliers de l'objet sur fichier // cette lecture est utilisée lorsque l'objet a été déjà défini // il s'agit donc d'une lecture à l'intérieur d'une autre loi par exemple void LoiContraintesPlanesDouble::LectureParametres_controles (UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D ,LesFonctions_nD& lesFonctionsnD) { // vérification que la dimension de l'espace est 3D if (ParaGlob::Dimension() != 3) { cout << "\n *** erreur 1 : la dimension de l'espace doit etre 3, pour pouvoir utiliser une loi de contrainte plane "; throw (UtilLecture::ErrNouvelleDonnee(-1)); if (ParaGlob::NiveauImpression() > 5) cout << "\n LoiContraintesPlanesDouble::LectureDonneesParticulieres (... "; Sortie(1); }; string nom_class_methode("LoiContraintesPlanesDouble::LectureParametres_controles" ); // on lit tout d'abord la méthode pour prendre en compte la contrainte *(entreePrinc->entree) >> type_de_contrainte; string nom; // on traite en fonction du type de contrainte switch (type_de_contrainte) { case PERTURBATION : { if (strstr(entreePrinc->tablcar,"deformation_transversale")!=NULL) { *(entreePrinc->entree) >> nom; if (nom != "deformation_transversale") { cout << "\n erreur en lecture de la loi Contraintes planes, on attendait le mot cle deformation_transversale" << " alors que l'on a lue " << nom; entreePrinc->MessageBuffer("**erreur 2 LoiContraintesPlanesDouble::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; } else // sinon les autres cas de perturbation ne sont actuellement pas pris en compte { cout << "\n erreur en lecture du type de perturbation : pour l'instant seule " << " le type: deformation_transversale , est pris en compte " ; entreePrinc->MessageBuffer("**erreur 3 LoiContraintesPlanesDouble::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; break; } case PENALISATION : case MULTIPLICATEUR_DE_LAGRANGE : { // ---- on regarde s'il faut lire une précision if (strstr(entreePrinc->tablcar,"prec=")!=NULL) { *(entreePrinc->entree) >> nom; if (nom != "prec=") { cout << "\n erreur en lecture de la loi Contraintes planes, on attendait le mot cle prec=" << " alors que l'on a lue " << nom; entreePrinc->MessageBuffer("**erreur 4 LoiContraintesPlanesDouble::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; *(entreePrinc->entree) >> prec; }; // --- on regarde s'il faut lire la pénalisation if (strstr(entreePrinc->tablcar,"fac=")!=NULL) { *(entreePrinc->entree) >> nom; if (nom != "fac=") { cout << "\n erreur en lecture de la loi Contraintes planes, on attendait le mot cle fac=" << " alors que l'on a lue " << nom; entreePrinc->MessageBuffer("**erreur 5 LoiContraintesPlanesDouble::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; *(entreePrinc->entree) >> fac_penal; }; break; } case NEWTON_LOCAL : { // ---- on regarde s'il faut lire des paramètres de réglage // --- lecture éventuelle des paramètres de réglage ---- // de l'algo de résolution de l'équation d'avancement temporel if(strstr(entreePrinc->tablcar,"avec_parametres_de_reglage_")!=0) {entreePrinc->NouvelleDonnee(); // on se positionne sur un nouvel enreg // on lit tant que l'on ne rencontre pas la ligne contenant "fin_parametres_reglage_Algo_Newton_" // ou un nouveau mot clé global auquel cas il y a pb !! MotCle motCle; // ref aux mots cle while (strstr(entreePrinc->tablcar,"fin_parametres_reglage_Algo_Newton_")==0) { // si on a un mot clé global dans la ligne courante c-a-d dans tablcar --> erreur if ( motCle.SimotCle(entreePrinc->tablcar)) { cout << "\n erreur de lecture des parametre de reglage de l'algorithme de Newton: on n'a pas trouve le mot cle " << " fin_parametres_reglage_Algo_Newton_ et par contre la ligne courante contient un mot cle global "; entreePrinc->MessageBuffer("** erreur5 des parametres de reglage de la loi de comportement de contraintes planes**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // lecture d'un mot clé *(entreePrinc->entree) >> nom; if ((entreePrinc->entree)->rdstate() == 0) {} // lecture normale #ifdef ENLINUX else if ((entreePrinc->entree)->fail()) // on a atteind la fin de la ligne et on appelle un nouvel enregistrement { entreePrinc->NouvelleDonnee(); // lecture d'un nouvelle enregistrement *(entreePrinc->entree) >>nom; } #else else if ((entreePrinc->entree)->eof()) // la lecture est bonne mais on a atteind la fin de la ligne { if(nom != "fin_parametres_reglage_Algo_Newton_") {entreePrinc->NouvelleDonnee(); *(entreePrinc->entree) >> nom;}; } #endif else // cas d'une erreur de lecture { cout << "\n erreur de lecture inconnue "; entreePrinc->MessageBuffer("** erreur4 des parametres de reglage de l'algoritheme de Newton de la loi de comportement de contraintes planes**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // nombre d'itération maxi if (nom == "nb_iteration_maxi_") {int nb_boucle_maxi; // le maximum d'itération permis *(entreePrinc->entree) >> nb_boucle_maxi; alg_zero.Modif_iter_max(nb_boucle_maxi); } // nombre de dichotomie maxi else if (nom == "nb_dichotomie_maxi_") {int nb_dichotomie; // le maxi de dichotomie prévu pour l'équation de Newton *(entreePrinc->entree) >> nb_dichotomie; alg_zero.Modif_nbMaxiIncre(nb_dichotomie); } // tolérance absolue sur le résidu else if (nom == "tolerance_residu_") { string mot_cle("=fonction_nD:"); if(strstr(entreePrinc->tablcar,mot_cle.c_str())==0) {// lecture du paramètre double tolerance_residu; // tolérance absolue sur la résolution de l'équation *(entreePrinc->entree) >> tolerance_residu; alg_zero.Modif_prec_res_abs(tolerance_residu); } else // on lit une fonction {// on lit le nom de la fonction string nom_fonct; bool lec = entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle,nom_fonct); if (!lec ) { entreePrinc->MessageBuffer("**erreur en lecture** tolerance_residu_ via une fonction nD"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // maintenant on définit la fonction if (lesFonctionsnD.Existe(nom_fonct)) {fct_tolerance_residu = lesFonctionsnD.Trouve(nom_fonct); } else {// sinon il faut la lire maintenant string non("_"); fct_tolerance_residu = Fonction_nD::New_Fonction_nD(non, Id_Nom_Fonction_nD(nom_fonct)); // lecture de la courbe fct_tolerance_residu->LectDonnParticulieres_Fonction_nD (non,entreePrinc); // maintenant on vérifie que la fonction est utilisable if (fct_tolerance_residu->NbComposante() != 1 ) { cout << "\n erreur en lecture, la fonction " << nom_fonct << " est une fonction vectorielle a " << fct_tolerance_residu->NbComposante() << " composantes alors qu'elle devrait etre scalaire ! " << " elle n'est donc pas utilisable !! "; string message("\n**erreur** \n"+nom_class_methode+"(..."); entreePrinc->MessageBuffer(message); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; // on mettra à jour pendant le calcul, la valeur de la précision }; } // tolérance relative sur le résidu else if (nom == "tolerance_residu_rel_") { string mot_cle("=fonction_nD:"); if(strstr(entreePrinc->tablcar,mot_cle.c_str())==0) {// lecture du paramètre double tolerance_residu_rel; // tolérance absolue sur la résolution de l'équation *(entreePrinc->entree) >> tolerance_residu_rel; alg_zero.Modif_prec_res_rel(tolerance_residu_rel); } else // on lit une fonction {// on lit le nom de la fonction string nom_fonct; bool lec = entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle,nom_fonct); if (!lec ) { entreePrinc->MessageBuffer("**erreur en lecture** tolerance_residu_ via une fonction nD"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // maintenant on définit la fonction if (lesFonctionsnD.Existe(nom_fonct)) {fct_tolerance_residu_rel = lesFonctionsnD.Trouve(nom_fonct); } else {// sinon il faut la lire maintenant string non("_"); fct_tolerance_residu_rel = Fonction_nD::New_Fonction_nD(non, Id_Nom_Fonction_nD(nom_fonct)); // lecture de la courbe fct_tolerance_residu_rel->LectDonnParticulieres_Fonction_nD (non,entreePrinc); // maintenant on vérifie que la fonction est utilisable if (fct_tolerance_residu_rel->NbComposante() != 1 ) { cout << "\n erreur en lecture, la fonction " << nom_fonct << " est une fonction vectorielle a " << fct_tolerance_residu_rel->NbComposante() << " composantes alors qu'elle devrait etre scalaire ! " << " elle n'est donc pas utilisable !! "; string message("\n**erreur** \n"+nom_class_methode+"(..."); entreePrinc->MessageBuffer(message); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; // on mettra à jour pendant le calcul, la valeur de la précision relative }; } // maxi_delta_var_eps_sur_iter_pour_Newton else if (nom == "maxi_delta_var_eps_sur_iter_pour_Newton_") { *(entreePrinc->entree) >> maxi_delta_var_eps_sur_iter_pour_Newton; } // le minimum de hsurh0 else if (nom == "mini_hsurh0_") {*(entreePrinc->entree) >> mini_hsurh0; } // le maximum de hsurh0 else if (nom == "maxi_hsurh0_") {*(entreePrinc->entree) >> maxi_hsurh0; } // le minimum de bsurb0 else if (nom == "mini_bsurb0_") {*(entreePrinc->entree) >> mini_bsurb0; } // le maximum de bsurb0 else if (nom == "maxi_bsurb0_") {*(entreePrinc->entree) >> maxi_bsurb0; } // forcer un stockage des indicateurs de la résolution else if (nom == "sortie_post_") {*(entreePrinc->entree) >> sortie_post; } // forcer un affichage particulier pour les méthodes else if (nom == "permet_affichage_") {int niveau=0; *(entreePrinc->entree) >> niveau; alg_zero.Modif_affichage(niveau); // on met à jour l'algo de newton } else if (nom == "calcul_en_3D_via_direction_quelconque_") {calcul_en_3D_via_direction_quelconque = true; } // sinon ce n'est pas un mot clé connu, on le signale else if (nom != "fin_parametres_reglage_Algo_Newton_") { cout << "\n erreur en lecture d'un parametre, le mot cle est inconnu " << " on a lu : " << nom << endl; if (ParaGlob::NiveauImpression()>3) cout << "\n LoiContraintesPlanesDouble::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ; throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } }; //-- fin du while }; //-- fin de la lecture des paramètres de réglage break; } default : cout << "\nErreur : valeur incorrecte du type de contrainte lue !: " << type_de_contrainte << " \n"; entreePrinc->MessageBuffer("**erreur 6 LoiContraintesPlanesDouble::LectureDonneesParticulieres (...**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // entreePrinc->NouvelleDonnee(); // prepa du flot de lecture pour d'autre loi éventuellement // appel au niveau de la classe mère Loi_comp_abstraite::Lecture_type_deformation_et_niveau_commentaire (*entreePrinc,lesFonctionsnD,true); }; // affichage de la loi void LoiContraintesPlanesDouble::Affiche() const { cout << "\n ....... loi de comportement LoiContraintesPlanesDouble ........"; cout << "\n type_de_contrainte: " << Nom_contrainte_mathematique(type_de_contrainte) << " prec= " << prec << " "; if (type_de_contrainte == PENALISATION) { cout << " fac_penal= " << fac_penal << " ";} else if (type_de_contrainte == NEWTON_LOCAL) { // --- paramètre de réglage cout << "\n reglage_algo_newton_equadiff: " ; alg_zero.Affiche(); cout << " maxi_delta_var_eps_sur_iter_pour_Newton_ "<NomFonction() != "_") cout << fct_tolerance_residu->NomFonction(); else fct_tolerance_residu->Affiche(); cout << "\n"; }; if (fct_tolerance_residu_rel != NULL) {cout << "\n pilotage tol_residu_rel: "; if (fct_tolerance_residu_rel->NomFonction() != "_") cout << fct_tolerance_residu_rel->NomFonction(); else fct_tolerance_residu_rel->Affiche(); cout << "\n"; }; // niveau d'affichage Affiche_niveau_affichage(); cout << " sortie_post "<< sortie_post << " "; cout << " calcul_en_3D_via_direction_quelconque "<< calcul_en_3D_via_direction_quelconque << " "; }; lois_interne->Affiche(); cout << "\n ....... fin de la loi de comportement LoiContraintesPlanesDouble ........"; }; // affichage et definition interactive des commandes particulières à chaques lois void LoiContraintesPlanesDouble::Info_commande_LoisDeComp(UtilLecture& entreePrinc) {ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier cout << "\n definition standart pour CP2 (rep o) ou exemples exhaustifs (rep n'importe quoi) ? "; string rep = "_"; // procédure de lecture avec prise en charge d'un retour chariot rep = lect_return_defaut(true,"o"); if ((rep == "o") || (rep != "O" )) sort << "\n# --- exemple de declaration pour une loi elastique --- " << "\n# " << "\n# toto LOI_CONTRAINTES_PLANES_DOUBLE " << "\n# NEWTON_LOCAL avec_parametres_de_reglage_ " << "\n# nb_iteration_maxi_ 20 " << "\n# nb_dichotomie_maxi_ 20 " << "\n# tolerance_residu_ 1.e-3 " << "\n# fin_parametres_reglage_Algo_Newton_ " << "\n# " << "\n# ISOELAS " << "\n# 200000 0.3 " << "\n# fin_loi_contrainte_plane # --- fin de la loi de contrainte plane double " << "\n\n \n "; if ((rep != "o") && (rep != "O" ) && (rep != "0") ) {sort << "\n# ....... loi de comportement LoiContraintesPlanesDouble ........" << "\n# a)sur la premiere ligne on indique : " << "\n# Obligatoirement : la methode utilisee pour imposer les contraintes plane: par defaut par multiplicateur de Lagrange " << "\n# les differents choix sont: " << "\n# " << "\n# PERTURBATION deformation_transversale : a chaque iteration (en implicite) ou increment (en explicite) la deformation d'epaisseur et de largeur " << "\n# est mise a jour, c'est a dire la deformation eps33 et eps22 " << "\n# pour cela on se sert du module de compressibilite et de la condition de " << "\n# de contrainte plane " << "\n# " << "\n# " /* << "\n# MULTIPLICATEUR_LAGRANGE : utilisation d'un multiplicateur de Lagrange, l'equilibre n'est cependant pas exact " << "\n# il depend de la valeur des ddl calcules globalement. La precision de la condition " << "\n# sig33=0 est consultee lors de la resolution globale, on peut ainsi indiquer une precision " << "\n# en dessous de laquelle on considerera que la condition est ok. Par defaut cette precision " << "\n# est relative et vaut 0.005 * Max|sig_ij|. On peut indiquer a la suite du mot cle prec= valeur" << "\n# ou prec= est un mot cle facultatif, valeur indique la precision que l'on desire " << "\n# " << "\n# PENALISATION : utilisation d'un facteur de penalisation dont la valeur est par defaut " << "\n# 30 fois le maximum de |d_sig_ij/d_ddl| , a la suite du " << "\n# mot cle on peut indiquer fac= facteur , ou fac= est un mot cle et facteur " << "\n# est un nombre qui multiplie par le maxi de |d_sig_ij/d_ddl| sera la penalisation " << "\n# comme pour la methode avec multiplicateur de Lagrange, la condition est approchee aussi " << "\n# la precision de la contrainte sig33=0 est consultee lors de la resolution globale. On " << "\n# peut donc aussi indiquer une precision differente de celle par defaut de la meme maniere " << "\n# que pour le multiplicateu de Lagrange " << "\n# " */ << "\n# NEWTON : utilisation d'une methode interne de Newton pour imposer precisemment la condition " << "\n# La methode itere localement en chaque point d'integration pour imposer la condition " << "\n# Par defaut, on considere que la convergence est ok lorsque la condition est satisfaite " << "\n# pour une precision relative de 0.005 * Max|sig_ij|. " << "\n# --- exemple de declaration: --- " << "\n# NEWTON " << "\n# " << "\n# ** il est egalement possible (mais pas obligatoire) de definir des parametres de reglage " << "\n# de la resolution. Dans ce cas, a la suite du mot cle NEWTON on indique le mot cle: avec_parametres_de_reglage_ " << "\n# ensuite on defini (dans un ordre quelconque) les parametres que l'on souhaites " << "\n# chaque parametre est precede d'un mot cle, on a donc une succession de mot cle suivi d'une grandeur " << "\n# on peut avoir un ou plusieur couple parametre-grandeur sur chaque ligne " << "\n# par contre la derniere ligne doit comporter uniquement le mot cle: " << "\n# fin_parametres_reglage_Algo_Newton_ " << "\n# les differents parametres sont: " << "\n# le nombre d'iteration ex: nb_iteration_maxi_ 20 " << "\n# le nombre de dichotomie ex: nb_dichotomie_maxi_ 20 " << "\n# la tolerance absolue sur le residu ex: tolerance_residu_ 5.e-3 " << "\n# la tolerance relative sur le residu ex: tolerance_residu_rel_ 1.e-4 " << "\n# le minimum de variation de h sur h0 (par defaut 0.001) ex: mini_hsurh0_ 1.e-4 " << "\n# le minimum de variation de b sur b0 (par defaut 0.001) ex: mini_bsurb0_ 1.e-4 " << "\n# le maximum de variation de h sur h0 (par defaut 1000) ex: maxi_hsurh0_ 1000. " << "\n# le maximum de variation de b sur b0 (par defaut 1000) ex: mini_bsurb0_ 1000. " << "\n# la valeur absolue maximale du delta deformation qui est permise a chaque iteration de Newton " << "\n# par defaut = 0.1 , si on veut une autre valeur: exe: " << "\n# maxi_delta_var_eps_sur_iter_pour_Newton_ 0.2 " << "\n# si on donne une valeur negative, il n'y a plus de limite " << "\n# " << "\n# Le mot cle: calcul_en_3D_via_direction_quelconque_ " << "\n# cela correspond a un comportement particulier pour lequel on utilise la loi 3D " << "\n# dans des directions quelconques (cf. partie theorique). Ce fonctionnement " << "\n# est en particulier mis en place pour verifier et valider la loi plis dans sa " << "\n# deuxieme version, donc a ne pas utiliser d'une maniere generale" << "\n# " << "\n# le mot cle sortie_post_ , par defaut il vaut 0, dans ce cas aucun indicateur n'est stoke" << "\n# s'il est different de 0, on peut acceder aux indicateurs en post-traitement (nombre d'iteration, dichotomie ... " << "\n# seules les indicateurs en cours sont disponibles, il n'y a pas de stockage sur plusieurs increment " << "\n# " << "\n# ex: sortie_post_ 1 " << "\n# " << "\n# -------------- affichage des erreurs et des warning ---------- " << "\n# - l'affichage normale est fonction du parametre global d'affichage gerer par le niveau d'affichage" << "\n# cependant pour des raisons par exemple de mise au point, il est possible de permettre l'affichage " << "\n# a un niveau particulier (mot cle : permet_affichage_ suivi d'un nombre entier) en plus de l'affichage normal. " << "\n# l'affichage s'effectuera donc en fonction de l'affichage normale et de l'affichage particulier." << "\n# Le fonctionnement de l'affichage particulier suit les mêmes règles que l'affichage globale" << "\n# soit permet_affichage_ est nulle (cas par defaut), dans ce cas l'affichage est fonction du niveau global" << "\n# soit permet_affichage_ vaut n par exemple, dans ce cas l'affichage est fonction uniquement de n " << "\n# " << "\n# ex: permet_affichage_ 5 " << "\n# " << "\n# -- exemple de declaration: -- " << "\n# NEWTON_LOCAL avec_parametres_de_reglage_" << "\n# nb_iteration_maxi_ 20 " << "\n# nb_dichotomie_maxi_ 20 " << "\n# tolerance_residu_ 5.e-3 " << "\n# tolerance_residu_rel_ 1.e-4 " << "\n# mini_hsurh0_ 1.e-4 " << "\n# mini_bsurb0_ 1.e-4 " << "\n# maxi_hsurh0_ 1000. " << "\n# mini_bsurb0_ 1000. " << "\n# sortie_post_ 1 " << "\n# permet_affichage_ 3 " << "\n# fin_parametres_reglage_Algo_Newton_ " << "\n# " << "\n# NB: il est possible de piloter les tolerances de l'algo de Newton avec une fonction nD " << "\n# ce qui permet par exemple d'avoir des tolerances qui varient en fct de la precision globlae " << "\n# " << "\n# exemples: avec fc1 et fc2, 2 fct nD " << "\n# tolerance_residu_ =fonction_nD: fc1 " << "\n# tolerance_residu_rel_ =fonction_nD: fc2 " << "\n# " << "\n# " << "\n#-----------------------------------" << "\n# b)puis sur la ligne suivante: " << "\n# Obligatoirement: le nom de la loi de comportement 3D sur laquelle on veut imposer une condition de contrainte plane " << "\n# La suite des informations est relative a la loi 3D, voir donc la syntaxe associee" << "\n# " << "\n# " << "\n# exemple 0: " << "\n PERTURBATION deformation_transversale " << "\n HYSTERESIS_3D " << "\n# .... # partie relative aux parametres specifiques a la loi d'Hysteresis " << "\n# " /* << "\n# exemple 1: " << "\n# MULTIPLICATEUR_LAGRANGE prec= 1.e-3 " << "\n# HYSTERESIS_3D " << "\n# .... # partie relative aux parametres specifiques a la loi d'Hysteresis " << "\n# " << "\n# exemple 2: prec et fac sont facultatifs, mais prec doit etre avant fac " << "\n# PENALISATION prec= 1.e-3 fac= 40. " << "\n# HYSTERESIS_3D " << "\n# .... # partie relative aux parametres specifiques a la loi d'Hysteresis " << "\n# " << "\n# exemple 3: " << "\n# NEWTON_LOCAL prec= 1.e-3 " << "\n# HYSTERESIS_3D " << "\n# .... # partie relative aux parametres specifiques a la loi d'Hysteresis " */ << "\n# " << "\n# a la fin de fin de la loi, on indique un mot cle de fin "; sort << "\n fin_loi_contrainte_plane_double # ----- fin de Loi de contrainte plane double " << endl; }; }; // test si la loi est complete int LoiContraintesPlanesDouble::TestComplet() { int ret = LoiAbstraiteGeneral::TestComplet(); ret *=lois_interne->TestComplet(); return ret; }; // calcul d'un module d'young équivalent à la loi, ceci pour un // chargement nul double LoiContraintesPlanesDouble::Module_young_equivalent(Enum_dure temps,const Deformation & def ,SaveResul * saveResul_ex) { SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul_ex); double E =lois_interne->Module_young_equivalent(temps,def,save_resul.le_SaveResul); return E; }; // récupération d'un module de compressibilité équivalent à la loi, ceci pour un chargement nul // il s'agit ici de la relation -pression = sigma_trace/3. = module de compressibilité * I_eps double LoiContraintesPlanesDouble::Module_compressibilite_equivalent(Enum_dure temps,const Deformation & def ,SaveResul * saveResul_ex) { SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul_ex); double module_compressibilite =lois_interne->Module_compressibilite_equivalent(temps,def,save_resul.le_SaveResul); return module_compressibilite; }; // activation des données des noeuds et/ou elements nécessaires au fonctionnement de la loi // exemple: mise en service des ddl de température aux noeuds // ici la grandeur qui sert de proportion entre la première loi et la seconde void LoiContraintesPlanesDouble::Activation_donnees(Tableau& tabnoeud,bool dilatation,LesPtIntegMecaInterne& lesPtMecaInt) { // appel relatif à la lois associée lois_interne->Activation_donnees(tabnoeud,dilatation,lesPtMecaInt); // appel de la méthode de la classe mère Loi_comp_abstraite::Activ_donnees(tabnoeud,dilatation,lesPtMecaInt); }; // récupération des grandeurs particulière (hors ddl ) // correspondant à liTQ // absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière void LoiContraintesPlanesDouble::Grandeur_particuliere (bool absolue,List_io& liTQ,Loi_comp_abstraite::SaveResul * saveDon,list& decal) const { // tout d'abord on récupère le conteneur SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveDon); // maintenant on s'occupe des grandeurs de la loi elle même, List_io::iterator itq,itqfin=liTQ.end(); list::iterator idecal=decal.begin(); for (itq=liTQ.begin();itq!=itqfin;itq++,idecal++) { SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveDon); TypeQuelconque& tipParticu = (*itq); // pour simplifier if (tipParticu.EnuTypeQuelconque().Nom_vide()) // veut dire que c'est un enum pur switch (tipParticu.EnuTypeQuelconque().EnumTQ()) { case CONTRAINTE_INDIVIDUELLE_A_CHAQUE_LOI_A_T: // 2) -----cas des contraintes individuelles à chaque loi à t uniquement { Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier // en fait on utilise systématiquement un tenseur d'ordre le + élevé, car c'est le conteneur le plus générique // et Tab_Grandeur_TenseurHH ne supporte que des tenseurs du même ordre donc s'il y a un tenseur élevé // interne il faut que tous les tenseurs soient du même ordre TenseurHH* sigHH = (save_resul.l_sigoHH_t); // pour simplifier if (Dabs(sigHH->Dimension()) != dim) {tyTQ(1+(*idecal)).Affectation_trans_dimension(*sigHH,true); } else // cas même dimension {tyTQ(1+(*idecal)) = (*(save_resul.l_sigoHH_t)); }; (*idecal)++; break; } case ENERGIE_ELASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T: // 3) -----cas de l'énergie élastique individuelles à chaque loi à t { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier tyTQ(1+(*idecal)) = save_resul.l_energ_t.EnergieElastique(); (*idecal)++; break; } case ENERGIE_PLASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T: // 4) -----cas de l'énergie plastique individuelles à chaque loi à t if ((*itq).EnuTypeQuelconque() == ENERGIE_PLASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier tyTQ(1+(*idecal)) = save_resul.l_energ_t.DissipationPlastique(); (*idecal)++; break; } case ENERGIE_VISQUEUSE_INDIVIDUELLE_A_CHAQUE_LOI_A_T: // 5) -----cas de l'énergie visqueuse individuelles à chaque loi à t if ((*itq).EnuTypeQuelconque() == ENERGIE_VISQUEUSE_INDIVIDUELLE_A_CHAQUE_LOI_A_T) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier tyTQ(1+(*idecal)) = save_resul.l_energ_t.DissipationVisqueuse(); (*idecal)++; break; } case DEF_EPAISSEUR: // 6) -----cas de la déformation d'épaisseur à t if ((*itq).EnuTypeQuelconque() == DEF_EPAISSEUR) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier // -- on calcul en fonction de l'élongation d'épaisseur double hsurh0=1. ; // init par défaut: on utilise une variable inter, car s'il n'y a pas eu // de calcul préalable,save_resul.hsurh0 == 0 ce qui conduit à une def infinie if (save_resul.hsurh0 != 0.) // cas où il y a eu un calcul hsurh0=save_resul.hsurh0; 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 dans le repère global : epsBB33 = 1/2 * (1. - 1./(h/h0)^2) tyTQ(1+(*idecal)) = 0.5 * (1. - 1./(hsurh0 * hsurh0));(*idecal)++; }; break; case DEFORMATION_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEFORMATION_CUMU_LOGARITHMIQUE : // cas d'une def logarithmique ou une approximation { tyTQ(1+(*idecal)) = log(hsurh0);(*idecal)++; }; break; default : cout << "\nErreur : type de deformation qui n'est pas actuellement pris en compte, type= " << Nom_type_deformation(type_de_deformation); cout << "\n LoiContraintesPlanes::Grandeur_particuliere \n"; Sortie(1); }; break; } case DEF_LARGEUR: // 6) -----cas de la déformation de largeur à t if ((*itq).EnuTypeQuelconque() == DEF_LARGEUR) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier // -- on calcul en fonction de l'élongation d'épaisseur double bsurb0=1. ; // init par défaut: on utilise une variable inter, car s'il n'y a pas eu // de calcul préalable,save_resul.bsurb0 == 0 ce qui conduit à une def infinie if (save_resul.bsurb0 != 0.) // cas où il y a eu un calcul bsurb0=save_resul.bsurb0; switch (type_de_deformation) {case DEFORMATION_STANDART : case DEFORMATION_POUTRE_PLAQUE_STANDART : // cas d'une déformation d'Almansi { // dans le repère local: epsBB22 = 1/2 * (b^2 - 1.), or b0=1. // donc dans le repère global : epsBB22 = 1/2 * (1.-1./(b/b0)^2) tyTQ(1+(*idecal)) = 0.5 * (1.-1./(bsurb0 * bsurb0));(*idecal)++; }; break; case DEFORMATION_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEFORMATION_CUMU_LOGARITHMIQUE : // cas d'une def logarithmique ou une approximation { tyTQ(1+(*idecal)) = log(bsurb0);(*idecal)++; }; break; default : cout << "\nErreur : type de deformation qui n'est pas actuellement pris en compte, type= " << Nom_type_deformation(type_de_deformation); cout << "\n LoiContraintesPlanes::Grandeur_particuliere \n"; Sortie(1); }; break; } // -----cas des deformations dans le repère de traction def_P // calculées dans le cadre de l'option: calcul_en_3D_via_direction_quelconque == true //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée case DEF_P_DANS_V_A: { Tab_Grandeur_Vecteur& tyTQ= *((Tab_Grandeur_Vecteur*) (*itq).Grandeur_pointee()); // pour simplifier if (save_resul.def_P_t.Taille()) tyTQ(1+(*idecal)) = save_resul.def_P_t; else tyTQ(1+(*idecal)).Zero(); (*idecal)++; break; } case NB_INCRE_TOTAL_RESIDU: { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier if ((save_resul.indicateurs_resolution_t.Taille())) tyTQ(1+(*idecal)) = save_resul.indicateurs_resolution_t(1); else tyTQ(1+(*idecal)) = 0.; (*idecal)++; break; } case NB_ITER_TOTAL_RESIDU: { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier if ((save_resul.indicateurs_resolution_t.Taille())) tyTQ(1+(*idecal)) = save_resul.indicateurs_resolution_t(2); else tyTQ(1+(*idecal)) = 0.; (*idecal)++; break; } default: ;// on ne fait rien }; }; // puis appel pour la lois associée lois_interne->Grandeur_particuliere(absolue,liTQ,save_resul.le_SaveResul,decal); }; // récupération de la liste de tous les grandeurs particulières // ces grandeurs sont ajoutées à la liste passées en paramètres void LoiContraintesPlanesDouble::ListeGrandeurs_particulieres(bool absolue,List_io& liTQ) const { // tout d'abord on passe en revue les grandeurs des lois associées // ** au niveau de l'exécution ce sera l'inverse de cette ordre: on s'occupera d'abord de this puis les lois internes // ** mais a priori cela n'a pas d'importance // appel de la loi 3D int nb_loi = 1; // pour être identique pour la loi additive !! lois_interne->ListeGrandeurs_particulieres(absolue,liTQ); // ... maintenant on s'occupe des grandeurs de la loi elle même, // 1) -----cas des contraintes individuelles à la loi à t uniquement {// ici il s'agit du tenseur des contraintes du pas précédent ou du pas actuel //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == CONTRAINTE_INDIVIDUELLE_A_CHAQUE_LOI_A_T) { Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+nb_loi; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TenseurHH* tens = NevezTenseurHH(ParaGlob::Dimension()); // un tenseur typique // qui fonctionnera en absolue ou non Tab_Grandeur_TenseurHH gtHH(*tens,nb_loi); // def d'un type quelconque représentatif TypeQuelconque typQ(CONTRAINTE_INDIVIDUELLE_A_CHAQUE_LOI_A_T,SIG11,gtHH); liTQ.push_back(typQ); delete tens; // car on n'en a plus besoin }; }; }; // pour toutes les énergies Tableau tab_double(nb_loi); Tab_Grandeur_scalaire_double grand_courant(tab_double); // 3) -----cas de l'énergie élastique individuelles à chaque loi à t uniquement //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == ENERGIE_ELASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+nb_loi; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(ENERGIE_ELASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; // 4) -----cas de l'énergie plastique individuelles à chaque loi à t uniquement //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == ENERGIE_PLASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+nb_loi; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(ENERGIE_PLASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; // 5) -----cas de l'énergie visqueuse individuelles à chaque loi à t uniquement //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == ENERGIE_VISQUEUSE_INDIVIDUELLE_A_CHAQUE_LOI_A_T) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+nb_loi; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(ENERGIE_VISQUEUSE_INDIVIDUELLE_A_CHAQUE_LOI_A_T,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; // -----cas de la déformation d'épaisseur à t uniquement //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == DEF_EPAISSEUR) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+nb_loi; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(DEF_EPAISSEUR,EPS11,grand_courant); liTQ.push_back(typQ1); }; }; // -----cas de la déformation de largeur à t uniquement //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == DEF_LARGEUR) { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+nb_loi; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(DEF_LARGEUR,EPS11,grand_courant); liTQ.push_back(typQ1); }; }; // -----cas des deformations dans le repère de traction def_P // calculées dans le cadre de l'option: calcul_en_3D_via_direction_quelconque == true //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée {Vecteur VV(3); Tab_Grandeur_Vecteur grand_vecteur_3(VV,1); List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == DEF_P_DANS_V_A) { Tab_Grandeur_Vecteur& tyTQ= *((Tab_Grandeur_Vecteur*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+nb_loi; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(DEF_P_DANS_V_A,EPS11,grand_vecteur_3); liTQ.push_back(typQ1); }; }; // ---- la suite dépend de l'indicateur : sortie_post if (sortie_post) { // j) ----- NB_INCRE_TOTAL_RESIDU {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == NB_INCRE_TOTAL_RESIDU) {Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(NB_INCRE_TOTAL_RESIDU,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; // k) ----- NB_ITER_TOTAL_RESIDU {List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true; for (itq=liTQ.begin();itq!=itqfin;itq++) if ((*itq).EnuTypeQuelconque() == NB_ITER_TOTAL_RESIDU) {Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier int taille = tyTQ.Taille()+1; tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) {TypeQuelconque typQ1(NB_ITER_TOTAL_RESIDU,SIG11,grand_courant); liTQ.push_back(typQ1); }; }; }; // fin du cas ou sortie_post est actif, c-a-d que l'on veut des infos sur les indicateurs de résolution }; //----- lecture écriture de restart ----- // cas donne le niveau de la récupération // = 1 : on récupère tout // = 2 : on récupère uniquement les données variables (supposées comme telles) void LoiContraintesPlanesDouble::Lecture_base_info_loi(ifstream& ent,const int cas,LesReferences& lesRef,LesCourbes1D& lesCourbes1D ,LesFonctions_nD& lesFonctionsnD) { if (cas == 1) { string st1; string nom; ent >> st1 >> nom >> type_de_contrainte >> nom >> fac_penal >> nom >> prec; // --- paramètre de réglage ent >> nom ; // lecture de "parametre_algo_newton_equadiff:" alg_zero.Lecture_base_info(ent,cas); // le paramètre maxi_delta_var_eps_sur_iter_pour_Newton ent >> nom >> maxi_delta_var_eps_sur_iter_pour_Newton ; // pilotage éventuel de la précision ent >> nom; if (nom != "non_pilot_tol_residu") { ent >> nom; // lecture fct locale ou globale if (nom == "fct_globale") {ent >> nom; // lecture du nom de la fonction if (fct_tolerance_residu != NULL) delete fct_tolerance_residu; // maintenant on définit la fonction if (lesFonctionsnD.Existe(nom)) {fct_tolerance_residu = lesFonctionsnD.Trouve(nom);} else { cout << "\n *** erreur en lecture de la fonction nD " << nom << " on ne la trouve pas !! "; Sortie(1); }; } else // sinon c'est une fonction locale { if (nom != "fct_locale") { cout << "\n *** erreur en lecture de la fonction nD " << " on attendait le mot cle fct_locale !! "; Sortie(1); } else {// on lit le type de fonction ent >> nom; EnumFonction_nD enu = Id_Nom_Fonction_nD(nom); nom = "_"; fct_tolerance_residu = Fonction_nD::New_Fonction_nD(nom, enu); fct_tolerance_residu->Lecture_base_info(ent,cas); }; }; }; if (nom != "non_pilot_tol_residu") { ent >> nom; // lecture fct locale ou globale if (nom == "fct_globale") {ent >> nom; // lecture du nom de la fonction if (fct_tolerance_residu_rel != NULL) delete fct_tolerance_residu_rel; // maintenant on définit la fonction if (lesFonctionsnD.Existe(nom)) {fct_tolerance_residu_rel = lesFonctionsnD.Trouve(nom);} else { cout << "\n *** erreur en lecture de la fonction nD " << nom << " on ne la trouve pas !! "; Sortie(1); }; } else // sinon c'est une fonction locale { if (nom != "fct_locale") { cout << "\n *** erreur en lecture de la fonction nD " << " on attendait le mot cle fct_locale !! "; Sortie(1); } else {// on lit le type de fonction ent >> nom; EnumFonction_nD enu = Id_Nom_Fonction_nD(nom); nom = "_"; fct_tolerance_residu_rel = Fonction_nD::New_Fonction_nD(nom, enu); fct_tolerance_residu_rel->Lecture_base_info(ent,cas); }; }; }; // les autres paramètres ent >> nom; // entête ent >> nom >> mini_hsurh0; ent >> nom >> mini_bsurb0; // le niveau d'affichage Lecture_permet_affichage(ent,cas,lesFonctionsnD); ent >> nom >> sortie_post >> nom >> calcul_en_3D_via_direction_quelconque; // non cas l'affichage dans l'algo est propre à l'algo alg_zero.Modif_affichage(permet_affichage); // on met à jour l'algo de newton // --- la loi associée ent >> nom ; if (st1 != "LOI_CONTRAINTES_PLANES_DOUBLE") { cout << "\n erreur en lecture de la loi : LOI_CONTRAINTES_PLANES_DOUBLE, on attendait le mot cle : LOI_CONTRAINTES_PLANES_DOUBLE " << " et on a lue: " << st1 << "\n LoiContraintesPlanesDouble::Lecture_base_info_loi(..."; Sortie(1); }; // on lit la loi 3D ent >> st1; lois_interne = (Loi_comp_abstraite *) LesLoisDeComp::Def_loi(st1); lois_interne->Lecture_base_info_loi(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD); } else { // on utilise directement la loi déjà défini lois_interne->Lecture_base_info_loi(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD); }; }; // cas donne le niveau de sauvegarde // = 1 : on sauvegarde tout // = 2 : on sauvegarde uniquement les données variables (supposées comme telles) void LoiContraintesPlanesDouble::Ecriture_base_info_loi(ofstream& sort,const int cas) { if (cas == 1) { sort << "\n LOI_CONTRAINTES_PLANES_DOUBLE " << " type_de_contrainte= " << type_de_contrainte << " fac_penal= " << fac_penal << " prec= " << prec ; // --- paramètre de réglage sort << "\n parametre_algo_newton_equadiff:--> "; alg_zero.Ecriture_base_info(sort,cas); // le paramètre maxi_delta_var_eps_sur_iter_pour_Newton sort << " maxi_delta_var_eps_sur_iter_pour_Newton_ "<NomFonction() != "_") sort << " fct_globale " << fct_tolerance_residu->NomFonction(); else {sort << " fct_locale " << Nom_Fonction_nD(fct_tolerance_residu->Type_Fonction()); fct_tolerance_residu->Ecriture_base_info(sort,cas); } sort << "\n"; }; if (fct_tolerance_residu_rel == NULL) sort << " non_pilot_tol_resi_rel "; else {sort << " pilot_tol_resi_rel "; if (fct_tolerance_residu_rel->NomFonction() != "_") sort << " fct_globale " << fct_tolerance_residu_rel->NomFonction(); else {sort << " fct_locale "<< Nom_Fonction_nD(fct_tolerance_residu->Type_Fonction()); fct_tolerance_residu_rel->Ecriture_base_info(sort,cas); } sort << "\n"; }; // les autres paramètres sort << "\n autres-parametres_loiCP2:--> "; sort << "\n mini_hsurh0: "<loi_associee_CP2: "; sort << lois_interne->Nom_comport() << " "; lois_interne->Ecriture_base_info_loi(sort,cas); } else { lois_interne->Ecriture_base_info_loi(sort,cas); } }; // ========== codage des METHODES VIRTUELLES protegees:================ // calcul des contraintes a t+dt void LoiContraintesPlanesDouble::Calcul_SigmaHH (TenseurHH& sigHH_t,TenseurBB& DepsBB,DdlElement & tab_ddl ,TenseurBB & gijBB_t,TenseurHH & gijHH_t,BaseB& giB,BaseH& gi_H ,TenseurBB & epsBB_,TenseurBB & delta_epsBB ,TenseurBB & gijBB_,TenseurHH & gijHH_,Tableau & d_gijBB_ ,double& jacobien_0,double& jacobien,TenseurHH & sigHH ,EnergieMeca & energ,const EnergieMeca & ,double& module_compressibilite,double& module_cisaillement ,const Met_abstraite::Expli_t_tdt& ex ) {// 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 // initialisation du tenseurs contrainte // sig_HH_3D.Inita(0.); // pour les contraintes bool plusZero = true; sig_HH_t_3D.Affectation_trans_dimension(*((Tenseur1HH*) &sigHH_t),plusZero); // sig_HH_3D.Affectation_trans_dimension(*((Tenseur1HH*) &sigHH),plusZero); // 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 // on sauvegarde les dimensions transverse, car elles vont être modifiées et si on doit // repartir au départ, ce ne sera plus possible sans cette sauvegarde double sauve_hsurh0=save_resul.hsurh0; double sauve_bsurb0=save_resul.bsurb0; // 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 éventuelle Vecteur* d_jacobien_tdt = NULL; // ne sert pas ici Tableau * d_epsBB=NULL; // " " Passage_deformation_volume_ordre1_vers_3(DepsBB,epsBB_,d_epsBB,delta_epsBB ,jacobien_0,jacobien,d_jacobien_tdt,*(ex.jacobien_t)); // 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 switch (type_de_contrainte) {case NEWTON_LOCAL: // cas de la version d_sig/d_eps { // initialisation du tenseurs contrainte sig_HH_3D.Inita(0.); sig_HH_3D.Affectation_trans_dimension(*((Tenseur1HH*) &sigHH),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 éventuelle Passage_deformation_volume_ordre1_vers_3(DepsBB,epsBB_,d_epsBB,delta_epsBB ,jacobien_0,jacobien,d_jacobien_tdt,*(ex.jacobien_t)); // on appel la procédure de résolution de sig22_33(bsurb0,hsurh0)=(0,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 val_initiale(1)=save_resul.b_tsurb0; // on démarre la recherche à la valeur à t val_initiale(2)=save_resul.h_tsurh0; // on démarre la recherche à la valeur à t // on impose que les grandeurs soient dans les limites admises if (Limitation_h_b(val_initiale(2),val_initiale(1))) {if ((ParaGlob::NiveauImpression() > 3) || (Permet_affichage() > 2)) cout << "\n val initiales: LoiContraintesPlanesDouble::Calcul_SigmaHH(... " << endl; }; racine.Zero(); // init du résultat à 0., mais c'est une grandeur de sortie donc cela ne sert à rien der_at_racine.Initialise(0.); // init de la matrice dérivée à 0. try // on met le bloc sous surveillance { int nb_incr_total,nb_iter_total; // variables intermédiaires d'indicateurs, pas utilisées ici // 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 = &ex; const Met_abstraite::Umat_cont* ex_expli = NULL; 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_SigmaHH\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()==0) && (ParaGlob::NiveauImpression() > 7)) || (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_SigmaHH\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()==0) && (ParaGlob::NiveauImpression() > 7)) || (Permet_affichage() > 5)) cout << ", tol_relative= "<< tol_rel; #endif alg_zero.Modif_prec_res_rel(tol_rel); }; }; // résolution de l'équation constitutive d'avancement discrétisée en euler implicite bool conver=alg_zero.Newton_raphson (*this,&LoiContraintesPlanesDouble::Residu_constitutif,&LoiContraintesPlanesDouble::Mat_tangente_constitutif ,val_initiale,racine,der_at_racine,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; ////---- debug // cout << "\n LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt: indicateurs_resolution(1)= "<< save_resul.indicateurs_resolution(1) // << " indicateurs_resolution(2)=" << save_resul.indicateurs_resolution(2) // << " nb_incr_total "<< nb_incr_total << " nb_iter_total "<< nb_iter_total<< endl; ////---- fin debug }; // on vérifie qu'il n'y a pas de pb de convergence double absracinemax=racine.Max_val_abs(); if ((!conver) || (!isfinite(absracinemax)) || (isnan(absracinemax)) ) { if ((ParaGlob::NiveauImpression() > 3) || (Permet_affichage() > 0)) { cout << "\n non convergence sur l'algo de la resolution de sig22_33(bsurb0,hsurh0)=(0,0) " << "\n b/b_0(t+dt)= " << racine(1) << " a t = " << save_resul.b_tsurb0 << " h/h_0(t+dt)= " << racine(2) << " a t = " << save_resul.h_tsurh0 << "\n nb_incr_total=" << nb_incr_total << " nb_iter_total=" << nb_iter_total << "\n LoiContraintesPlanesDouble::Calcul_SigmaHH (..."; }; // on garde en mémoire mauvaise_convergence=true; }; // on vérifie que les nouvelles dimensions transversales ne sont pas négatives if ((racine(1) < 0.) || (racine(2) < 0.) ) { if ((ParaGlob::NiveauImpression() > 3) || (Permet_affichage() > 0)) { cout << "\n **** erreur dans la resolution : on obtient une " << " dimension transversale negative " << "\n b/b_0(t+dt)= " << racine(1) << " a t = " << save_resul.b_tsurb0 << ", h/h_0(t+dt)= " << racine(2) << " a t = " << save_resul.h_tsurh0 << "\n LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt (..."; }; // on garde en mémoire mauvaise_convergence=true; }; } catch (ErrNonConvergence_Newton erreur) { if ((ParaGlob::NiveauImpression() > 2) || (Permet_affichage() > 0)) { cout << "\n erreur de non convergence avec l'algo de la resolution de sig22_33(bsurb0,hsurh0)=(0,0) " << " on obtient une valeur infinie ou NaN " << "\n LoiContraintesPlanesDouble::Calcul_SigmaHH_tdt (..."; }; // on garde en mémoire mauvaise_convergence=true; } catch (ErrSortieFinale) // cas d'une direction voulue vers la sortie // on relance l'interuption pour le niveau supérieur { ErrSortieFinale toto; throw (toto); } catch ( ... ) { // dans le cas d'une erreur inconnue, on génère également une exception if ((ParaGlob::NiveauImpression() > 2) || (Permet_affichage() > 0)) { cout << "\n erreur non identifiee sur l'algo de la resolution de sig22_33(bsurb0,hsurh0)=(0,0) " << "\n LoiContraintesPlanesDouble::Calcul_SigmaHH (..."; }; // on garde en mémoire mauvaise_convergence=true; }; if (!mauvaise_convergence) { // arrivée ici, cela veut dire que tout à bien fonctionné save_resul.bsurb0 = racine(1); // récup de la solution save_resul.hsurh0 = racine(2); // récup de la solution // on met à jour les modules module_compressibilite= module_compressibilite_3D; module_cisaillement= module_cisaillement_3D; // passage des tenseurs résultats à l'ordre 1 ((Tenseur1HH*) &sigHH)->Affectation_trans_dimension(sig_HH_3D,false); break; }; // sinon on ne fait pas de break, donc on continue avec la méthode de perturbation }; default: // cas de la version d_sig/d_ddl { // initialisation du tenseurs contrainte sig_HH_3D.Inita(0.); sig_HH_3D.Affectation_trans_dimension(*((Tenseur1HH*) &sigHH),plusZero); // récup de l'épaisseur et la largeur de départ // on impose que les grandeurs sauvegardées soient dans les limites admises if (Limitation_h_b(sauve_hsurh0,sauve_bsurb0)) {if ((ParaGlob::NiveauImpression() > 3) || (Permet_affichage() > 2)) cout << "calcul direct sans Newton " << "\n LoiContraintesPlanesDouble::Calcul_SigmaHH(... " << endl; }; save_resul.hsurh0 = sauve_hsurh0; save_resul.bsurb0 = sauve_bsurb0; // 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 éventuelle Passage_deformation_volume_ordre1_vers_3(DepsBB,epsBB_,d_epsBB,delta_epsBB ,jacobien_0,jacobien,d_jacobien_tdt,*(ex.jacobien_t)); lois_interne->Calcul_SigmaHH(sig_HH_t_3D,Deps_BB_3D,tab_ddl,gijBB_t_3D,gijHH_t_3D,giB_tdt_3D,giH_tdt_3D ,eps_BB_3D,delta_eps_BB_3D ,gijBB_tdt_3D,gijHH_tdt_3D,d_gijBB_tdt_3D_P,jacobien_0_3D,jacobien_tdt_3D,sig_HH_3D ,save_resul.l_energ,save_resul.l_energ_t,module_compressibilite,module_cisaillement,*expli_3D ); // passage des tenseurs résultats à l'ordre 1 ((Tenseur1HH*) &sigHH)->Affectation_trans_dimension(sig_HH_3D,false); if (((ParaGlob::NiveauImpression() > 4) || (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; }; // sigHH_tdt.Ecriture(cout); //debug //cout << "\n debug LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt sig33_3D= "< 4) || (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; }; }; energ = save_resul.l_energ; // récup des énergies // passage des tenseurs résultats à l'ordre 1 ((Tenseur1HH*) &sigHH)->Affectation_trans_dimension(sig_HH_3D,false); // sigHH_tdt.Ecriture(cout); LibereTenseur(); LibereTenseurQ(); }; // calcul des contraintes a t+dt et de ses variations void LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt (TenseurHH& sigHH_t,TenseurBB& DepsBB,DdlElement & tab_ddl ,BaseB& giB_t,TenseurBB & gijBB_t,TenseurHH & gijHH_t ,BaseB& giB_tdt,Tableau & d_giB_tdt,BaseH& giH_tdt,Tableau & d_giH_tdt ,TenseurBB & epsBB_tdt,Tableau & d_epsBB ,TenseurBB & delta_epsBB,TenseurBB & gijBB_tdt,TenseurHH & gijHH_tdt ,Tableau & d_gijBB_tdt ,Tableau & d_gijHH_tdt,double& jacobien_0,double& jacobien ,Vecteur& d_jacobien_tdt,TenseurHH& sigHH_tdt,Tableau & d_sigHH ,EnergieMeca & energ,const EnergieMeca & toto ,double& module_compressibilite,double& module_cisaillement ,const Met_abstraite::Impli& ex) { if (calcul_en_3D_via_direction_quelconque) {Passage_Calcul_1D_3D_dsigma_DsigmaHH_tdt(sigHH_t,DepsBB,tab_ddl,giB_t,gijBB_t,gijHH_t ,giB_tdt,d_giB_tdt,giH_tdt,d_giH_tdt,epsBB_tdt,d_epsBB,delta_epsBB,gijBB_tdt,gijHH_tdt ,d_gijBB_tdt,d_gijHH_tdt,jacobien_0,jacobien,d_jacobien_tdt,sigHH_tdt,d_sigHH ,energ,toto,module_compressibilite,module_cisaillement,ex); return; }; // 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 // on vérifie que les tableaux sont correctement // dimensionnés sinon on les modifie int taille = d_sigHH.Taille(); // on affecte et/ou on redimensionne éventuellement les tableaux contraintes-déformation fonctions du nombre de ddl // pour le passage 3D: on considère que tous les tableaux doivent avoir la même dimension: la même que dans le cas 1D int ta_d_sig_HH_3D = d_sig_HH_3D.Taille(); if (ta_d_sig_HH_3D != taille) { // cela veut dire que tous les tableaux sont mal dimensionnés ta_d_sig_HH_3D = d_sigHH.Taille(); d_sig_HH_3D.Change_taille(ta_d_sig_HH_3D); d_sig_HH_3D_P.Change_taille(ta_d_sig_HH_3D); for (int i=1;i<=ta_d_sig_HH_3D;i++) {d_sig_HH_3D_P(i) = &(d_sig_HH_3D(i));} }; for (int i=1;i<=ta_d_sig_HH_3D;i++) {d_sig_HH_3D_P(i)->Inita(0.);}; // initialisation du tenseurs contrainte // sig_HH_3D.Inita(0.); // --- pour les contraintes passage en 3D bool plusZero = true; sig_HH_t_3D.Affectation_trans_dimension(*((Tenseur1HH*) &sigHH_t),plusZero); // sig_HH_3D.Affectation_trans_dimension(*((Tenseur1HH*) &sigHH_tdt),plusZero); // --- 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 cours // on sauvegarde les dimensions transverse, car elles vont être modifiées et si on doit // repartir au départ, ce ne sera plus possible sans cette sauvegarde double sauve_hsurh0=save_resul.hsurh0; double sauve_bsurb0=save_resul.bsurb0; // 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 // Passage_deformation_volume_ordre1_vers_3(DepsBB,epsBB_tdt,&d_epsBB,delta_epsBB // ,jacobien_0,jacobien,&d_jacobien_tdt); ////debug //cout << "\n debug LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt sig33= "; //{Tenseur3BH epsBH = eps_BB_3D * gijHH_tdt_3D; //cout << "\n epsBH=";epsBH.Ecriture(cout); //int taille = d_eps_BB_3D.Taille(); //for (int i=1;i<=taille;i++) // { Tenseur3BH depsBH = d_eps_BB_3D(i) * gijHH_tdt_3D; // cout << "\n i= "<giH_0)(a).Affiche(); // }; //// --- fin debug // passage des informations liées à la déformation de 1 vers 3, et variation de volume Passage_deformation_volume_ordre1_vers_3(DepsBB,epsBB_tdt,&d_epsBB,delta_epsBB ,jacobien_0,jacobien,&d_jacobien_tdt,*(ex.jacobien_t)); // 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 val_initiale(1)=save_resul.b_tsurb0; // on démarre la recherche à la valeur à t val_initiale(2)=save_resul.h_tsurh0; // on démarre la recherche à la valeur à t // on impose que les grandeurs soient dans les limites admises if (Limitation_h_b(val_initiale(2),val_initiale(1))) {if ((ParaGlob::NiveauImpression() > 3) || (Permet_affichage() > 2)) cout << "\n val initiales: LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt(... " << endl; }; racine.Zero(); // init du résultat à 0., mais c'est une grandeur de sortie donc cela ne sert à rien der_at_racine.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, pas utilisées pour l'instant // 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 = &ex; const Met_abstraite::Expli_t_tdt* ex_expli_tdt = NULL; const Met_abstraite::Umat_cont* ex_expli = NULL; 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_DsigmaHH_tdt\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()==0) && (ParaGlob::NiveauImpression() > 7)) || (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_DsigmaHH_tdt\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()==0) && (ParaGlob::NiveauImpression() > 7)) || (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,&LoiContraintesPlanesDouble::Mat_tangente_constitutif ,val_initiale,racine,der_at_racine,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; ////---- debug // cout << "\n LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt: indicateurs_resolution(1)= "<< save_resul.indicateurs_resolution(1) // << " indicateurs_resolution(2)=" << save_resul.indicateurs_resolution(2) // << " nb_incr_total "<< nb_incr_total << " nb_iter_total "<< nb_iter_total<< endl; ////---- fin debug }; // on vérifie qu'il n'y a pas de pb de convergence double absracinemax=racine.Max_val_abs(); if ((!conver) || (!isfinite(absracinemax)) || (isnan(absracinemax)) ) { if ((ParaGlob::NiveauImpression() > 3) || (Permet_affichage() > 0)) { cout << "\n non convergence sur l'algo de la resolution de sig22_33(bsurb0,hsurh0)=(0,0) " << "\n b/b_0(t+dt)= " << racine(1) << " a t = " << save_resul.b_tsurb0 << " h/h_0(t+dt)= " << racine(2) << " a t = " << save_resul.h_tsurh0 << "\n nb_incr_total=" << nb_incr_total << " nb_iter_total=" << nb_iter_total << "\n LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt (..."; }; // on garde en mémoire mauvaise_convergence=true; }; // on vérifie que les nouvelles dimensions transversales ne sont pas négatives if ((racine(1) < 0.) || (racine(2) < 0.) ) { if ((ParaGlob::NiveauImpression() > 3) || (Permet_affichage() > 0)) { cout << "\n **** erreur dans la resolution : on obtient une " << " dimension transversale negative " << "\n b/b_0(t+dt)= " << racine(1) << " a t = " << save_resul.b_tsurb0 << ", h/h_0(t+dt)= " << racine(2) << " a t = " << save_resul.h_tsurh0 << "\n LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt (..."; }; // on garde en mémoire mauvaise_convergence=true; }; } catch (ErrNonConvergence_Newton erreur) { if ((ParaGlob::NiveauImpression() > 2) || (Permet_affichage() > 0)) { cout << "\n erreur de non convergence avec l'algo de la resolution de sig22_33(bsurb0,hsurh0)=(0,0) " << " on obtient une valeur infinie ou NaN " << "\n LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt (..."; }; // on garde en mémoire mauvaise_convergence=true; } catch (ErrSortieFinale) // cas d'une direction voulue vers la sortie // on relance l'interuption pour le niveau supérieur { ErrSortieFinale toto; throw (toto); } catch ( ... ) { // dans le cas d'une erreur inconnue, on génère également une exception if ((ParaGlob::NiveauImpression() > 2) || (Permet_affichage() > 0)) { cout << "\n erreur non identifiee sur l'algo de la resolution de sig22_33(bsurb0,hsurh0)=(0,0) " << "\n LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt (..."; }; // on garde en mémoire mauvaise_convergence=true; }; if (!mauvaise_convergence) { // arrivée ici, cela veut dire que tout à bien fonctionné save_resul.bsurb0 = racine(1); // récup de la solution save_resul.hsurh0 = racine(2); // récup de la solution // on met à jour les modules module_compressibilite= module_compressibilite_3D; module_cisaillement= module_cisaillement_3D; // calcul de la variation de la déformation d'épaisseur et de largeur en fonction de la def_11 Calcul_d_eps_eg_11(); // calcul des termes d_eps_ef_11 // récup de la variation de d sig^{11}/ d eps_22 et 33 Tableau d_sig11_deps_gh_HH(2); d_sig11_deps_gh_HH(1).Coor(1,1)=d_sigma_deps_3D(1,1,2,2); d_sig11_deps_gh_HH(2).Coor(1,1)=d_sigma_deps_3D(1,1,3,3); // construction de la variation de d sig^{11} / d eps_{11) Tenseur1HH d_sig11_deps_11(d_sigma_deps_3D(1,1,1,1)); // //debug // cout << "\n debug LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt cas Newton_local avant "; // d_sig11_deps_11.Ecriture(cout); // // fin debug d_sig11_deps_11.Coor(1,1) += d_sigma_deps_3D(1,1,2,2) * d_eps_ef_11(1) + d_sigma_deps_3D(1,1,3,3) * d_eps_ef_11(2); //// //debug // cout << "\n debug LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt cas Newton_local apres "; // d_sig11_deps_11.Ecriture(cout); //// // fin debug // passage des tenseurs résultats à l'ordre 1 ((Tenseur1HH*) &sigHH_tdt)->Affectation_trans_dimension(sig_HH_3D,false); // on calcul la matrice tangente en contrainte plane double // on a : d_sigHH_tdt/d_ddl = d_sigHH_tdt/d_eps * d_eps/d_ddl //debug //cout << "\n debug LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt cas Newton_local "; //d_sigma_deps_3D.Ecriture(cout); // fin debug if (Permet_affichage() > 7) { cout << "\n ContraintesPlanes: 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;} }; }; for (int i = 1; i<= taille; i++) { // on fait uniquement une égalité d'adresse et de ne pas utiliser // le constructeur d'ou la profusion d'* et de () Tenseur1HH & dsigHH = *((Tenseur1HH*) (d_sigHH(i))); // passage en dim 1 const Tenseur1BB & depsBB = *((Tenseur1BB *) (d_epsBB(i))); // " dsigHH.Coor(1,1) = d_sig11_deps_11(1,1) * depsBB(1,1); // //debug // cout << "\n debug LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt cas Newton_local (2) dsigHH="; // dsigHH.Ecriture(cout); // // fin debug }; break; }; // sinon on ne fait pas de break, donc on continue avec la méthode de perturbation }; default: // cas de la version d_sig/d_ddl, on encore du cas où la méthode de Newton n'a pas convergé //debug //cout << "\n debug LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt cas Newton_local "; //d_sigma_deps_3D.Ecriture(cout); // fin debug { // initialisation du tenseurs contrainte sig_HH_3D.Inita(0.); sig_HH_3D.Affectation_trans_dimension(*((Tenseur1HH*) &sigHH_tdt),plusZero); // récup de l'épaisseur et la largeur de départ save_resul.hsurh0 = sauve_hsurh0; save_resul.bsurb0 = sauve_bsurb0; // on impose que les grandeurs sauvegardées soient dans les limites admises if (Limitation_h_b(sauve_hsurh0,sauve_bsurb0)) {if ((ParaGlob::NiveauImpression() > 3) || (Permet_affichage() > 2)) cout << "calcul direct sans Newton " << "\n LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt(... " << endl; }; // 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 Passage_deformation_volume_ordre1_vers_3(DepsBB,epsBB_tdt,&d_epsBB,delta_epsBB ,jacobien_0,jacobien,&d_jacobien_tdt,*(ex.jacobien_t)); lois_interne->Calcul_DsigmaHH_tdt(sig_HH_t_3D,Deps_BB_3D,tab_ddl,giB_t_3D,gijBB_t_3D,gijHH_t_3D ,giB_tdt_3D,d_giB_tdt_3D,giH_tdt_3D,d_giH_tdt_3D ,eps_BB_3D,d_eps_BB_3D_P,delta_eps_BB_3D,gijBB_tdt_3D,gijHH_tdt_3D,d_gijBB_tdt_3D_P ,d_gijHH_tdt_3D_P,jacobien_0_3D,jacobien_tdt_3D,d_jacobien_tdt_3D ,sig_HH_3D,d_sig_HH_3D_P ,save_resul.l_energ,save_resul.l_energ_t,module_compressibilite,module_cisaillement,*impli_3D ); // passage des tenseurs résultats à l'ordre 1 ((Tenseur1HH*) &sigHH_tdt)->Affectation_trans_dimension(sig_HH_3D,false); // sigHH_tdt.Ecriture(cout); // récup de l'opérateur tangent for (int k=1;k<=taille;k++) ((Tenseur1HH*) d_sigHH(k))->Affectation_trans_dimension(*d_sig_HH_3D_P(k),false); if (mauvaise_convergence) {if ((ParaGlob::NiveauImpression() > 4) || (Permet_affichage() > 0)) { cout << "\n 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(); }; //debug //cout << "\n debug LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt sig33_3D= "< 7) { cout << "\nLoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt "; TenseurHH* ptHH = NevezTenseurHH(sig_HH_3D); sig_HH_3D.BaseAbsolue(*ptHH,giB_tdt_3D); cout << "\n sigma apres CP2: "; ptHH->Ecriture(cout); delete ptHH; }; #endif // 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; Calcul_d_eps_trans_parVarVolume(jacobien_0,module_compressibilite,jacobien,sigHH_tdt,d_jacobien_tdt ,d_sigHH,d_gijBB_tdt,gijBB_tdt); if (((ParaGlob::NiveauImpression() > 4) || (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; }; }; //debug //cout << "\n debug LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt: sigHH_tdt "; //sigHH_tdt.Ecriture(cout); //for (int i = 1; i<= taille; i++) // { // on fait uniquement une égalité d'adresse et de ne pas utiliser // // le constructeur d'ou la profusion d'* et de () // Tenseur1HH & dsigHH = *((Tenseur1HH*) (d_sigHH(i))); // passage en dim 1 // cout << "\n d_sigHH("<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 // on sauvegarde les dimensions transverse, car elles vont être modifiées et si on doit // repartir au départ, ce ne sera plus possible sans cette sauvegarde double sauve_hsurh0=save_resul.hsurh0; double sauve_bsurb0=save_resul.bsurb0; // // 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); // 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 switch (type_de_contrainte) {case NEWTON_LOCAL: // cas de la version d_sig/d_eps { // 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); //---- debug //if ((*(umat_cont_3D->giH_0))(2).Norme() < ConstMath::petit) // {cout << "\n debug LoiContraintesPlanesDouble::Calcul_dsigma_deps "; // Passage_metrique_ordre1_vers_3(ex); // }; //cout << "\n debug LoiContraintesPlanesDouble::Calcul_dsigma_deps "; //for (int a = 1;a < 4; a++) // {cout << "\n giB_0("<* 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)); // 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 val_initiale(1)=save_resul.b_tsurb0; // on démarre la recherche à la valeur à t val_initiale(2)=save_resul.h_tsurh0; // on démarre la recherche à la valeur à t // on impose que les grandeurs soient dans les limites admises if (Limitation_h_b(val_initiale(2),val_initiale(1))) {if ((ParaGlob::NiveauImpression() > 3) || (Permet_affichage() > 2)) cout << "\n val initiales: LoiContraintesPlanesDouble::Calcul_dsigma_deps(... " << endl; }; //// ---- 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 racine.Zero(); // init du résultat à 0., mais c'est une grandeur de sortie donc cela ne sert à rien der_at_racine.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, pas utilisées pour l'instant // 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()==0) && (ParaGlob::NiveauImpression() > 7)) || (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()==0) && (ParaGlob::NiveauImpression() > 7)) || (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 ,&LoiContraintesPlanesDouble::Mat_tangente_constitutif ,val_initiale,racine,der_at_racine,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.Max_val_abs(); if ((!conver) || (!isfinite(absracinemax)) || (isnan(absracinemax)) ) { if ((ParaGlob::NiveauImpression() > 3) || (Permet_affichage() > 0)) { cout << "\n non convergence sur l'algo de la resolution de sig22_33(bsurb0,hsurh0)=(0,0) " << "\n b/b_0(t+dt)= " << racine(1) << " a t = " << save_resul.b_tsurb0 << " h/h_0(t+dt)= " << racine(2) << " a t = " << save_resul.h_tsurh0 << "\n nb_incr_total=" << nb_incr_total << " nb_iter_total=" << nb_iter_total << "\n LoiContraintesPlanesDouble::Calcul_deps_tdt (..."; }; // on garde en mémoire mauvaise_convergence=true; }; // on vérifie que les nouvelles dimensions transversales ne sont pas négatives if ((racine(1) < 0.) || (racine(2) < 0.) ) { if ((ParaGlob::NiveauImpression() > 3) || (Permet_affichage() > 0)) { cout << "\n **** erreur dans la resolution : on obtient une " << " dimension transversale negative " << "\n b/b_0(t+dt)= " << racine(1) << " a t = " << save_resul.b_tsurb0 << ", h/h_0(t+dt)= " << racine(2) << " a t = " << save_resul.h_tsurh0 << "\n LoiContraintesPlanesDouble::Calcul_deps_tdt (..."; }; // on garde en mémoire mauvaise_convergence=true; }; } catch (ErrNonConvergence_Newton erreur) { if ((ParaGlob::NiveauImpression() > 2) || (Permet_affichage() > 0)) { cout << "\n erreur de non convergence avec l'algo de la resolution de sig22_33(bsurb0,hsurh0)=(0,0) " << " on obtient une valeur infinie ou NaN " << "\n LoiContraintesPlanesDouble::Calcul_deps_tdt (..."; }; // on garde en mémoire mauvaise_convergence=true; } catch (ErrSortieFinale) // cas d'une direction voulue vers la sortie // on relance l'interuption pour le niveau supérieur { ErrSortieFinale toto; throw (toto); } catch ( ... ) { // dans le cas d'une erreur inconnue, on génère également une exception if ((ParaGlob::NiveauImpression() > 2) || (Permet_affichage() > 0)) { cout << "\n erreur non identifiee sur l'algo de la resolution de sig22_33(bsurb0,hsurh0)=(0,0) " << "\n LoiContraintesPlanesDouble::Calcul_deps_tdt (..."; }; // on garde en mémoire mauvaise_convergence=true; }; if (!mauvaise_convergence) { // arrivée ici, cela veut dire que tout à bien fonctionné save_resul.bsurb0 = racine(1); // récup de la solution save_resul.hsurh0 = racine(2); // récup de la solution // on met à jour les modules module_compressibilite= module_compressibilite_3D; module_cisaillement= module_cisaillement_3D; // calcul de la variation de la déformation d'épaisseur et de largeur en fonction de la def_11 Calcul_d_eps_eg_11(); // calcul des termes d_eps_ef_11 // récup de la variation de d sig^{11}/ d eps_22 et 33 Tableau d_sig11_deps_gh_HH(2); d_sig11_deps_gh_HH(1).Coor(1,1)=d_sigma_deps_3D(1,1,2,2); d_sig11_deps_gh_HH(2).Coor(1,1)=d_sigma_deps_3D(1,1,3,3); #ifdef MISE_AU_POINT if (Permet_affichage() > 8) { cout << "\nLoiContraintesPlanesDouble::Calcul_dsigma_deps: bonne convergence de Newton "; cout << "\n d_sigma_deps_3D(1,1,1,1) "<< d_sigma_deps_3D(1,1,1,1) << "\n d_sigma_deps_3D(1,1,2,2) "<< d_sigma_deps_3D(1,1,2,2) << "\n d_sigma_deps_3D(1,1,3,3) "<< d_sigma_deps_3D(1,1,3,3) << "\n d_eps_ef_11(1) "<< d_eps_ef_11(1) << ", d_eps_ef_11(2) "<< d_eps_ef_11(2) << flush; }; #endif // construction de la variation de d sig^{11} / d eps_{11) Tenseur1HH d_sig11_deps_11(d_sigma_deps_3D(1,1,1,1)); d_sig11_deps_11.Coor(1,1) += d_sigma_deps_3D(1,1,2,2) * d_eps_ef_11(1) + d_sigma_deps_3D(1,1,3,3) * d_eps_ef_11(2); // on sauvegarde dans le format ad hoc d_sigma_deps.Inita(0.); d_sigma_deps.Change(1,1,1,1,d_sig11_deps_11(1,1)); if ((!isfinite(d_sigma_deps_3D(1,1,1,1))) || (isnan(d_sigma_deps_3D(1,1,1,1))) ) {cout << "\n *** attention d_sigma_deps_3D(1,1,1,1)= "<< d_sigma_deps_3D(1,1,1,1); if (Ptintmeca_en_cours() != NULL) Ptintmeca_en_cours()->Signature(); cout << "\nLoiContraintesPlanesDouble::Calcul_dsigma_deps:"; cout << flush; }; // passage des tenseurs résultats à l'ordre 1 ((Tenseur1HH*) &sigHH_tdt)->Affectation_trans_dimension(sig_HH_3D,false); // on calcul la matrice tangente en contrainte plane double // on a : d_sigHH_tdt/d_ddl = d_sigHH_tdt/d_eps * d_eps/d_ddl #ifdef MISE_AU_POINT if (Permet_affichage() > 7) { 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() > 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 d_sig/d_ddl, on encore du cas où la méthode de Newton n'a pas convergé { // initialisation du tenseurs contrainte sig_HH_3D.Inita(0.); sig_HH_3D.Affectation_trans_dimension(*((Tenseur1HH*) &sigHH_tdt),plusZero); // récup de l'épaisseur et la largeur de départ // on impose que les grandeurs sauvegardées soient dans les limites admises if (Limitation_h_b(sauve_hsurh0,sauve_bsurb0)) {if ((ParaGlob::NiveauImpression() > 3) || (Permet_affichage() > 2)) cout << "calcul direct sans Newton " << "\n LoiContraintesPlanesDouble::Calcul_dsigma_deps(... " << endl; }; save_resul.hsurh0 = sauve_hsurh0; save_resul.bsurb0 = sauve_bsurb0; // 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)); 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,module_cisaillement ,*umat_cont_3D); if ((!isfinite(d_sigma_deps_3D(1,1,1,1))) || (isnan(d_sigma_deps_3D(1,1,1,1))) ) {cout << "\n *** attention d_sigma_deps_3D(1,1,1,1)= "<< d_sigma_deps_3D(1,1,1,1); if (Ptintmeca_en_cours() != NULL) Ptintmeca_en_cours()->Signature(); cout << "\nLoiContraintesPlanesDouble::Calcul_dsigma_deps:"; cout << flush; }; // 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); if (mauvaise_convergence) {if ((ParaGlob::NiveauImpression() > 4) || (Permet_affichage() > 0)) { cout << "\n 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_parVarVolume1(sigBH_t,jacobien_0,module_compressibilite,jacobien,sigBH,*(ex.jacobien_t)); if (((ParaGlob::NiveauImpression() > 4) || (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(); };