1216 lines
60 KiB
C++
Executable file
1216 lines
60 KiB
C++
Executable file
// FICHIER : Loi_Umat.cp
|
|
// CLASSE : Loi_Umat
|
|
|
|
|
|
// 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) <https://www.irdl.fr/>.
|
|
//
|
|
// 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 <https://www.gnu.org/licenses/>.
|
|
//
|
|
// For more information, please consult: <https://herezh.irdl.fr/>.
|
|
|
|
|
|
//#include "Debug.h"
|
|
|
|
# include <iostream>
|
|
using namespace std; //introduces namespace std
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
#include "Sortie.h"
|
|
#include "TypeConsTens.h"
|
|
#include "ConstMath.h"
|
|
#include "MathUtil.h"
|
|
#include "CharUtil.h"
|
|
#include "Util.h"
|
|
|
|
#include "Loi_Umat.h"
|
|
|
|
// ------------------fonctions interne template ------------
|
|
// multiplication de tenseur par des bases
|
|
template <class T1,class T2,class Base2,class Base1>
|
|
T1 & produit_1_pourLoiUmat(T1 & A,T2& Nous, const Base2 & gi2, const Base1 & gi1)
|
|
{ int dim = abs(A.Dimension());
|
|
int dimint = abs(Nous.Dimension());
|
|
for (int i=1;i<= dim; i++)
|
|
for (int j=1; j<= dim; j++)
|
|
{ A.Coor(i,j) = 0.;
|
|
for (int al=1; al<= dimint; al++)
|
|
for (int be=1; be<= dimint; be++)
|
|
A.Coor(i,j) += Nous(al,be)* (gi1.Coordo(al)(i)*gi2.Coordo(be)(j)+gi2.Coordo(al)(i)*gi1.Coordo(be)(j));
|
|
}
|
|
return A;
|
|
};
|
|
|
|
|
|
//==================== cas de la class de sauvegarde SaveResul ===================
|
|
|
|
// constructeur par défaut
|
|
Loi_Umat::SaveResul_Loi_Umat::SaveResul_Loi_Umat() :
|
|
save_pour_loi_ext(NULL),hsurh0(ConstMath::tresgrand),h_tsurh0(ConstMath::tresgrand)
|
|
{};
|
|
|
|
// constructeur de copie
|
|
Loi_Umat::SaveResul_Loi_Umat::SaveResul_Loi_Umat(const Loi_Umat::SaveResul_Loi_Umat& sav ):
|
|
save_pour_loi_ext(sav.save_pour_loi_ext),hsurh0(sav.hsurh0),h_tsurh0(sav.h_tsurh0)
|
|
{};
|
|
|
|
// affectation
|
|
Loi_comp_abstraite::SaveResul &
|
|
Loi_Umat::SaveResul_Loi_Umat::operator = ( const Loi_comp_abstraite::SaveResul & a)
|
|
{ Loi_Umat::SaveResul_Loi_Umat& sav = *((Loi_Umat::SaveResul_Loi_Umat*) &a);
|
|
// on affecte si non dimensionné, sinon on crée à l'identique
|
|
if (sav.save_pour_loi_ext != NULL)
|
|
{ if (save_pour_loi_ext == NULL)
|
|
{save_pour_loi_ext = sav.save_pour_loi_ext->Nevez_SaveResul();}
|
|
else
|
|
{(*save_pour_loi_ext) = *(sav.save_pour_loi_ext);};
|
|
};
|
|
hsurh0 = sav.hsurh0; h_tsurh0 = sav.h_tsurh0;
|
|
return *this;
|
|
};
|
|
|
|
|
|
//============= lecture écriture dans base info ==========
|
|
|
|
// cas donne le niveau de la récupération
|
|
// = 1 : on récupère tout
|
|
// = 2 : on récupère uniquement les données variables (supposées comme telles)
|
|
void Loi_Umat::SaveResul_Loi_Umat::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;
|
|
int titi=0.;
|
|
ent >> titi;
|
|
if (titi == 1 )
|
|
ent >> toto >> hsurh0; h_tsurh0 = hsurh0;
|
|
|
|
#ifdef MISE_AU_POINT
|
|
if (toto != "S_R_LoiUmat")
|
|
{ cout << "\n erreur en lecture du conteneur pour la loi Umat"
|
|
<< " \n Loi_Umat::SaveResul_Loi_Umat::Lecture_base_info(..";
|
|
Sortie(1);
|
|
}
|
|
#endif
|
|
if (save_pour_loi_ext!=NULL)
|
|
{save_pour_loi_ext->Lecture_base_info(ent,cas);};
|
|
};
|
|
|
|
// cas donne le niveau de sauvegarde
|
|
// = 1 : on sauvegarde tout
|
|
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
|
|
void Loi_Umat::SaveResul_Loi_Umat::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_R_LoiUmat ";
|
|
if (hsurh0 != ConstMath::tresgrand )
|
|
sort << "\n 1 " << "CP:hsurh0= " << h_tsurh0;
|
|
else sort << "\n 0 ";
|
|
if (save_pour_loi_ext!=NULL)
|
|
{save_pour_loi_ext->Ecriture_base_info(sort,cas);};
|
|
};
|
|
|
|
// mise à jour des informations transitoires en définitif s'il y a convergence
|
|
// par exemple (pour la plasticité par exemple)
|
|
void Loi_Umat::SaveResul_Loi_Umat::TdtversT()
|
|
{ if (save_pour_loi_ext!=NULL)
|
|
save_pour_loi_ext->TdtversT();
|
|
// CP par défaut: car c'est aussi rapide que le test (sans doute ?)
|
|
h_tsurh0 = hsurh0;
|
|
|
|
};
|
|
void Loi_Umat::SaveResul_Loi_Umat::TversTdt()
|
|
{ if (save_pour_loi_ext!=NULL)
|
|
save_pour_loi_ext->TversTdt();
|
|
// CP par défaut: car c'est aussi rapide que le test (sans doute ?)
|
|
hsurh0 = h_tsurh0;
|
|
};
|
|
|
|
//==================== fin du cas de la class de sauvegarde SaveResul ============
|
|
|
|
Loi_Umat::Loi_Umat (Enum_comp enu) : // Constructeur par defaut
|
|
Loi_comp_abstraite(enu,CAT_MECANIQUE,0)
|
|
,nom_de_la_loi("_")
|
|
,umatAbaqus(ParaGlob::Dimension(),Loi_Umat::Choix_dim(enu))
|
|
,loi_ext(NULL)
|
|
,utilisation_umat_interne(NULL)
|
|
,umat_met3D(),umat_met2D(),umat_met1D()
|
|
,d_sigma_deps_2D(),d_sigma_deps_1D()
|
|
,gabBB_tdt(NULL),gabHH_tdt(NULL),gabBB_t(NULL),gabHH_t(NULL)
|
|
,gixB_0(),gixB_t(),gixB_tdt(),gixH_0(),gixH_t(),gixH_tdt()
|
|
// des pointeurs nulles pour les grandeurs qui actuellement ne servent pas
|
|
,ggaB_0null(NULL),ggaB_tnull(NULL),ggaH_0null(NULL)
|
|
,ggradVmoyBB_tnull(NULL),ggradVmoyBB_tdtnull(NULL),ggradVBB_tdtnull(NULL)
|
|
|
|
// --//\\-- grandeurs particulières pour le cas contraintes planes
|
|
// -- conteneur des métriques
|
|
,umat_cont_3D(NULL)
|
|
,umat_cont_2D(NULL)
|
|
,Ip2_B(ParaGlob::Dimension(),2) // pour définir la base 2D locale dans l'espace de travail
|
|
// -- 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.)
|
|
// idem en 2D
|
|
,Ip3B_0_3D(),Ip3H_0_3D() // ne fait pas partie de umat_cont_2D
|
|
,giB_0_2D(ParaGlob::Dimension(),2),giH_0_2D(ParaGlob::Dimension(),2)
|
|
,giB_t_2D(ParaGlob::Dimension(),2),giH_t_2D(ParaGlob::Dimension(),2)
|
|
,giB_tdt_2D(ParaGlob::Dimension(),2),giH_tdt_2D(ParaGlob::Dimension(),2)
|
|
,gijBB_0_2D(),gijHH_0_2D(),gijBB_t_2D(),gijHH_t_2D()
|
|
,gijBB_tdt_2D(),gijHH_tdt_2D()
|
|
,gradVmoyBB_t_2D(),gradVmoyBB_tdt_2D(),gradVBB_tdt_2D()
|
|
,gradVmoyBB_t_2D_P(NULL),gradVmoyBB_tdt_2D_P(NULL),gradVBB_tdt_2D_P(NULL)
|
|
,jacobien_tdt_2D(0.),jacobien_0_2D(0.)
|
|
|
|
// --//\\-- fin grandeurs particulières pour le cas contraintes planes
|
|
|
|
{ // définition de la métrique umat
|
|
int dim_base=3;
|
|
int nbvec_base_3D=3;
|
|
DdlElement tabddl; // init par défaut -> pas de ddl élément
|
|
int nb_noeud_interpol=0; // par de noeud, on n'a pas a s'en servir normalement
|
|
umat_met3D.Dim_NbVec(dim_base,nbvec_base_3D,tabddl,nb_noeud_interpol);
|
|
int nbvec_base_2D=2;//dim_base=2;
|
|
umat_met2D.Dim_NbVec(dim_base,nbvec_base_2D,tabddl,nb_noeud_interpol);
|
|
int nbvec_base_1D=1;//dim_base=1;
|
|
umat_met1D.Dim_NbVec(dim_base,nbvec_base_1D,tabddl,nb_noeud_interpol);
|
|
// on definit les variables a priori toujours utiles
|
|
Tableau<Enum_variable_metrique> tab(13);
|
|
tab(1)=igiB_0;tab(2)=igiB_t;tab(3)=igiB_tdt;
|
|
tab(4)=igiH_0;tab(5)=igiH_t;tab(6)=igiH_tdt ;
|
|
tab(7)=igijBB_0;tab(8)=igijBB_t;tab(9)=igijBB_tdt;
|
|
tab(10)=igijHH_0;tab(11)=igijHH_t;tab(12)=igijHH_tdt ;
|
|
tab(13)=igradVmoyBB_t;
|
|
umat_met3D.PlusInitVariables(tab) ;
|
|
umat_met2D.PlusInitVariables(tab) ;
|
|
umat_met1D.PlusInitVariables(tab) ;
|
|
|
|
// --//\\-- grandeurs particulières pour le cas contraintes planes
|
|
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);
|
|
// idem 2D
|
|
umat_cont_2D = new Met_abstraite::Umat_cont // constructeur normal
|
|
(&giB_0_2D,&giH_0_2D,&giB_t_2D,&giH_t_2D,&giB_tdt_2D,&giH_tdt_2D
|
|
,&gijBB_0_2D,&gijHH_0_2D,&gijBB_t_2D,&gijHH_t_2D
|
|
,&gijBB_tdt_2D,&gijHH_tdt_2D
|
|
,gradVmoyBB_t_2D_P,gradVmoyBB_tdt_2D_P,gradVBB_tdt_2D_P // pas affecté par défaut
|
|
,&jacobien_tdt_2D,&jacobien_t_2D,&jacobien_0_2D);
|
|
// --//\\-- fin grandeurs particulières pour le cas contraintes planes
|
|
|
|
|
|
};
|
|
|
|
// Constructeur de copie
|
|
Loi_Umat::Loi_Umat (const Loi_Umat& loi) :
|
|
Loi_comp_abstraite(loi)
|
|
,nom_de_la_loi(loi.nom_de_la_loi),umatAbaqus(loi.umatAbaqus)
|
|
,loi_ext(loi.loi_ext),utilisation_umat_interne(loi.utilisation_umat_interne)
|
|
,umat_met3D(loi.umat_met3D),umat_met2D(loi.umat_met2D),umat_met1D(loi.umat_met1D)
|
|
,d_sigma_deps_2D(loi.d_sigma_deps_2D),d_sigma_deps_1D(loi.d_sigma_deps_1D)
|
|
,gabBB_tdt(NULL),gabHH_tdt(NULL),gabBB_t(NULL),gabHH_t(NULL)
|
|
,gixB_0(),gixB_t(),gixB_tdt(),gixH_0(),gixH_t(),gixH_tdt()
|
|
|
|
// -- conteneur des métriques: ce sont des pointeurs, pour l'instant on ne les affecte pas
|
|
,umat_cont_3D(NULL)
|
|
,umat_cont_2D(loi.umat_cont_2D) // umat_cont_2D avec uniquement des pointeurs
|
|
,Ip2_B(loi.Ip2_B) // pour définir la base 2D locale dans l'espace travail
|
|
// -- 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)
|
|
,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)
|
|
// idem en 2D
|
|
,Ip3B_0_3D(loi.Ip3B_0_3D),Ip3H_0_3D(loi.Ip3H_0_3D) // ne fait pas partie de umat_cont_2D
|
|
,giB_0_2D(loi.giB_0_2D),giH_0_2D(loi.giH_0_2D),giB_t_2D(loi.giB_t_2D),giH_t_2D(loi.giH_t_2D)
|
|
,giB_tdt_2D(loi.giB_tdt_2D)
|
|
,gijBB_0_2D(loi.gijBB_0_2D),gijHH_0_2D(loi.gijHH_0_2D)
|
|
,gijBB_t_2D(loi.gijBB_t_2D),gijHH_t_2D(loi.gijHH_t_2D),gijBB_tdt_2D(loi.gijBB_tdt_2D)
|
|
,gijHH_tdt_2D(loi.gijHH_tdt_2D),gradVmoyBB_t_2D(loi.gradVmoyBB_t_2D)
|
|
,gradVmoyBB_tdt_2D(loi.gradVmoyBB_tdt_2D),gradVBB_tdt_2D(loi.gradVBB_tdt_2D)
|
|
,jacobien_0_2D(loi.jacobien_0_2D)
|
|
|
|
{ gabBB_tdt=NevezTenseurBB(*loi.gabBB_tdt);gabHH_tdt=NevezTenseurHH(*loi.gabHH_tdt);
|
|
gabBB_t=NevezTenseurBB(*loi.gabBB_t);gabHH_t=NevezTenseurHH(*loi.gabHH_t);
|
|
// 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;};
|
|
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);
|
|
// idem 2D
|
|
umat_cont_2D = new Met_abstraite::Umat_cont // constructeur normal
|
|
(&giB_0_2D,&giH_0_2D,&giB_t_2D,&giH_t_2D,&giB_tdt_2D,&giH_tdt_2D
|
|
,&gijBB_0_2D,&gijHH_0_2D,&gijBB_t_2D,&gijHH_t_2D
|
|
,&gijBB_tdt_2D,&gijHH_tdt_2D
|
|
,gradVmoyBB_t_2D_P,gradVmoyBB_tdt_2D_P,gradVBB_tdt_2D_P // pas affecté par défaut
|
|
,&jacobien_tdt_2D,&jacobien_t_2D,&jacobien_0_2D);
|
|
};
|
|
|
|
Loi_Umat::~Loi_Umat ()
|
|
// Destructeur
|
|
{ if (gabBB_tdt != NULL) delete gabBB_tdt;
|
|
if (gabHH_tdt != NULL) delete gabHH_tdt;
|
|
if (gabBB_t != NULL) delete gabBB_t;
|
|
if (gabHH_t != NULL) delete gabHH_t;
|
|
// les conteneurs de pointeurs:
|
|
delete umat_cont_3D;
|
|
delete umat_cont_2D;
|
|
|
|
// pour les grandeurs de base, pas de new, donc pas de delete
|
|
|
|
};
|
|
|
|
// def d'une instance de données spécifiques, et initialisation
|
|
Loi_comp_abstraite::SaveResul * Loi_Umat::New_et_Initialise()
|
|
{ Loi_comp_abstraite::SaveResul* sav = new SaveResul_Loi_Umat();
|
|
// dans le cas ou la loi est interne on stocke ses infos égalements
|
|
if (utilisation_umat_interne)
|
|
{ SaveResul_Loi_Umat* sv = (SaveResul_Loi_Umat*) sav;
|
|
sv->save_pour_loi_ext = ((Loi_comp_abstraite*)loi_ext)->New_et_Initialise();
|
|
};
|
|
return sav;
|
|
};
|
|
|
|
// fonction de travail
|
|
int Loi_Umat::Choix_dim(Enum_comp enu)
|
|
{if(enu == LOI_VIA_UMAT_CP)
|
|
return 2;
|
|
else
|
|
return 3;
|
|
};
|
|
|
|
|
|
// Lecture des donnees de la classe sur fichier
|
|
void Loi_Umat::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCourbes1D&
|
|
,LesFonctions_nD& lesFonctionsnD)
|
|
{ // lecture du nom de la loi
|
|
string toto;
|
|
*(entreePrinc->entree) >> toto >> nom_de_la_loi;
|
|
if (toto != "nom_de_la_loi=")
|
|
{ cout << "\n erreur en lecture du nom de la loi, on aurait du lire le mot cle nom_de_la_loi="
|
|
<< " suivi du nom de la loi ";
|
|
entreePrinc->MessageBuffer("**erreur1: Loi_Umat::LectureDonneesParticulieres(... **");
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
// lecture de la catégorie
|
|
string categorie;
|
|
*(entreePrinc->entree) >> toto >> categorie;
|
|
if (toto != "categorie=")
|
|
{ cout << "\n erreur en lecture du nom de la loi, on aurait du lire le mot cle categorie="
|
|
<< " suivi du nom de la categorie ";
|
|
entreePrinc->MessageBuffer("**erreur2: Loi_Umat::LectureDonneesParticulieres(... **");
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
// on met à jour la catégorie de la loi
|
|
Enum_categorie_loi_comp cat = Id_nom_categorie_loi_comp(categorie.c_str());
|
|
ChangeCategorie(cat);
|
|
if (cat==CAT_THERMO_MECANIQUE) {thermo_dependant=true;}
|
|
else {thermo_dependant=false;};
|
|
// lecture de la dimension
|
|
string dimension;
|
|
*(entreePrinc->entree) >> toto >> dimension;
|
|
if (toto != "dim_loi=")
|
|
{ cout << "\n erreur en lecture du nom de la loi, on aurait du lire le mot cle dim_loi="
|
|
<< " suivi de la dimension: 1D ou 2D ou 3D ";
|
|
entreePrinc->MessageBuffer("**erreur3: Loi_Umat::LectureDonneesParticulieres(... **");
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
// on met à jour la dimension de la loi
|
|
if ((dimension== "1D") || (dimension=="1")) {Change_dimension(1); }
|
|
else if ((dimension == "2D") || (dimension=="2")) {Change_dimension(2); }
|
|
else if ((dimension == "3D") || (dimension=="3")) {Change_dimension(3); }
|
|
else
|
|
{ cout << "\n erreur en lecture de la dimension de la loi geree par umat"
|
|
<< " on devrait lire 1 ou 2 ou 3 ou 1D ou 2D ou 3D";
|
|
entreePrinc->MessageBuffer("**erreur4: Loi_Umat::LectureDonneesParticulieres(... **");
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
|
|
string nom_class_methode("Loi_Umat::LectureDonneesParticulieres");
|
|
// lecture de la ligne qui suit
|
|
entreePrinc->NouvelleDonnee();
|
|
*(entreePrinc->entree) >> toto;
|
|
if (toto != "fin_loi_Umat")
|
|
{ if (toto == "nom_pipe_envoi=")
|
|
{// lecture du nom du pipe d'envoi
|
|
string nom_pipe_envoi; *(entreePrinc->entree) >> nom_pipe_envoi;
|
|
umatAbaqus.Change_nom_pipe_envoi(nom_pipe_envoi);
|
|
*(entreePrinc->entree) >> toto;
|
|
// on regarde si éventuellement il y a le pipe de reception
|
|
if(toto == "nom_pipe_reception=")
|
|
{ string nom_pipe_reception; *(entreePrinc->entree) >> nom_pipe_reception;
|
|
umatAbaqus.Change_nom_pipe_reception(nom_pipe_reception);
|
|
}
|
|
else
|
|
{ cout << "\n erreur en lecture du nom du pipe de reception, on aurait du lire le mot "
|
|
<< " cle nom_pipe_reception=, suivi du nom du pipe ";
|
|
entreePrinc->MessageBuffer("**erreur5: Loi_Umat::LectureDonneesParticulieres(... **");
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
entreePrinc->NouvelleDonnee();// préparation du flot
|
|
if(strstr(entreePrinc->tablcar,"permet_affichage_")!=0)
|
|
{// on lit le niveau de commentaire
|
|
string nom; *(entreePrinc->entree) >> nom;
|
|
Lecture_permet_affichage(entreePrinc,lesFonctionsnD);
|
|
// string mot_cle("permet_affichage_");
|
|
// entreePrinc->Lecture_un_parametre_int(0,nom_class_methode
|
|
// ,0, 10,mot_cle,permet_affichage);
|
|
entreePrinc->NouvelleDonnee();// préparation du flot
|
|
};
|
|
}
|
|
else if (toto == "utilisation_umat_interne")
|
|
{// cas d'une umat interne
|
|
utilisation_umat_interne=true;
|
|
entreePrinc->NouvelleDonnee();// préparation du flot
|
|
if(strstr(entreePrinc->tablcar,"permet_affichage_")!=0)
|
|
{// on lit le niveau de commentaire
|
|
string nom; *(entreePrinc->entree) >> nom;
|
|
Lecture_permet_affichage(entreePrinc,lesFonctionsnD);
|
|
// string mot_cle("permet_affichage_");
|
|
// entreePrinc->Lecture_un_parametre_int(0,nom_class_methode
|
|
// ,0, 10,mot_cle,permet_affichage);
|
|
entreePrinc->NouvelleDonnee();// préparation du flot
|
|
};
|
|
if(strstr(entreePrinc->tablcar,"fin_loi_Umat")==0)
|
|
{ cout << "\n erreur en lecture de la fin de la loi on devrait avoir le mot cle fin_loi_Umat "
|
|
<< " soit le mot cle : permet_affichage_ ";
|
|
entreePrinc->MessageBuffer("**erreur6: Loi_Umat::LectureDonneesParticulieres(... **");
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
}
|
|
else
|
|
{ cout << "\n erreur en lecture de la fin de la loi on devrait soit avoir le mot cle fin_loi_Umat "
|
|
<< " ou alors les noms des pipes d'envoi et de reception (cf doc) ";
|
|
entreePrinc->MessageBuffer("**erreur7: Loi_Umat::LectureDonneesParticulieres(... **");
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
};
|
|
|
|
// appel au niveau de la classe mère
|
|
Loi_comp_abstraite::Lecture_type_deformation_et_niveau_commentaire
|
|
(*entreePrinc,lesFonctionsnD);
|
|
|
|
};
|
|
|
|
// affichage de la loi
|
|
void Loi_Umat::Affiche() const
|
|
{ cout << "\n loi de comportement Umat "<<dim<<"D : "<< nom_de_la_loi << " ";
|
|
if(thermo_dependant) {cout << " thermodependante ";};
|
|
cout << " categorie " << Nom_categorie_loi_comp(categorie_loi_comp) << " ";
|
|
Loi_comp_abstraite::Affiche_don_classe_abstraite();
|
|
};
|
|
|
|
// affichage et definition interactive des commandes particulières à chaques lois
|
|
void Loi_Umat::Info_commande_LoisDeComp(UtilLecture& entreePrinc)
|
|
{ ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier
|
|
cout << "\n definition standart (rep o) ou exemples exhaustifs (rep n'importe quoi) ? ";
|
|
string rep = "_"; // procédure de lecture avec prise en charge d'un retour chariot
|
|
rep = lect_return_defaut(true,"o");
|
|
|
|
sort << "\n# ----------------------------------------------------------"
|
|
<< "\n# | exemple de loi de comportement defini en Umat |"
|
|
<< "\n# | via un processus qui dialogue avec herezh++ |"
|
|
<< "\n# ----------------------------------------------------------"
|
|
<< "\n nom_de_la_loi= acier categorie= CAT_MECANIQUE dim_loi= 3 "
|
|
<< "\n nom_pipe_envoi= pipe_envoi nom_pipe_reception= pipe_reception "
|
|
<< "\n fin_loi_Umat " << endl ;
|
|
if ((rep != "o") && (rep != "O" ) && (rep != "0") )
|
|
{ sort << "\n ....................................................................................."
|
|
<< "\n# NB: en contrainte plane, la loi se nomme LOI_VIA_UMAT_CP et il faut utiliser : dim_loi= 2 "
|
|
<< "\n# - le nom de la loi, peut permettre le choix entre plusieurs Umat "
|
|
<< "\n# - les differentes categorie sont: "
|
|
<< "\n# CAT_MECANIQUE pour une loi utilisable pour un calcul mecanique "
|
|
<< "\n# CAT_THERMO_MECANIQUE pour une loi utilisable pour un calcul thermo-mecanique "
|
|
<< "\n# CAT_THERMO_PHYSIQUE pour une loi thermo-physique "
|
|
<< "\n# - dim_loi peut etre: "
|
|
// << "\n# 1D : permet la traction - compression "
|
|
<< "\n# 2D : 2D contraintes planes ou deformations planes"
|
|
<< "\n# 3D : 3D classique (sans particularite) "
|
|
<< "\n# - la ligne suivante est facultative (par contre si elle existe elle doit etre complete)"
|
|
<< "\n# nom_pipe_envoi= suivi du nom du pipe d'envoi (par defaut = Umat_reception_Hz "
|
|
<< "\n# nom_pipe_reception= suivi du nom du pipe de recepetion (par defaut= Umat_envoi_Hz "
|
|
<< "\n# - a la place des nom de pipe il est possible de mettre le mot cle: utilisation_umat_interne "
|
|
<< "\n# dans ce cas il n'est pas fait appel au pipe, on travail directement avec une loi interne "
|
|
<< "\n# defini dans le fichier .info d'entree d'herezh "
|
|
<< "\n# permet_affichage_ <un entier> :"
|
|
<< "\n# - mot cle fin_loi_Umat "
|
|
<< "\n# - ensuite il est possible de definir le type de deformation a utiliser "
|
|
<< "\n# comme pour tous les autres lois "
|
|
<< "\n#:....................................................................................."
|
|
<< endl;
|
|
};
|
|
// appel de la classe mère
|
|
Loi_comp_abstraite::Info_commande_don_LoisDeComp(entreePrinc);
|
|
};
|
|
|
|
// test si la loi est complete
|
|
int Loi_Umat::TestComplet()
|
|
{ // appel de la fonction mère
|
|
return LoiAbstraiteGeneral::TestComplet();
|
|
};
|
|
|
|
//----- lecture écriture de restart -----
|
|
|
|
// cas donne le niveau de la récupération
|
|
// = 1 : on récupère tout
|
|
// = 2 : on récupère uniquement les données variables (supposées comme telles)
|
|
void Loi_Umat::Lecture_base_info_loi(ifstream& ent,const int cas,LesReferences& lesRef,LesCourbes1D& lesCourbes1D
|
|
,LesFonctions_nD& lesFonctionsnD)
|
|
{ string toto,nom;
|
|
if (cas == 1)
|
|
{ ent >> toto >> thermo_dependant;
|
|
};
|
|
// cas de la structure UmatAbaqus
|
|
umatAbaqus.Lecture_base_info(ent,cas);
|
|
// appel de la classe mère
|
|
Loi_comp_abstraite::Lecture_don_base_info(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD);
|
|
};
|
|
// cas donne le niveau de sauvegarde
|
|
// = 1 : on sauvegarde tout
|
|
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
|
|
void Loi_Umat::Ecriture_base_info_loi(ofstream& sort,const int cas)
|
|
{ if (cas == 1)
|
|
{ sort << " " << Nom_comp(this->Id_comport()) << " " << thermo_dependant;
|
|
};
|
|
// cas de la structure UmatAbaqus
|
|
umatAbaqus.Ecriture_base_info(sort,cas);
|
|
// appel de la classe mère
|
|
Loi_comp_abstraite::Ecriture_don_base_info(sort,cas);
|
|
};
|
|
// calcul d'un module d'young équivalent à la loi pour un chargement nul
|
|
double Loi_Umat::Module_young_equivalent(Enum_dure temps,const Deformation & def,SaveResul * )
|
|
{ if (thermo_dependant)
|
|
{temperature_tdt = def.DonneeInterpoleeScalaire(TEMP,temps);
|
|
temperature_t = def.DonneeInterpoleeScalaire(TEMP,TEMPS_t);
|
|
};
|
|
// comme on ne connait la loi, on fait un appel standart avec une déformation donnée
|
|
// on en déduit le module d'young
|
|
// .. définition de jeux de données adoc
|
|
umatAbaqus.Init_un();
|
|
// *** on impose une déformation de traction et de cisaillement arbitraire ******
|
|
double dep=0.001;// une valeur arbitraire
|
|
(*(umatAbaqus.eps_meca)).Coor(1,1)=(*(umatAbaqus.delta_eps_meca)).Coor(1,1)=dep;
|
|
(*(umatAbaqus.eps_meca)).Coor(1,2)=(*(umatAbaqus.delta_eps_meca)).Coor(1,2)=dep;
|
|
(*(umatAbaqus.eps_meca)).Coor(2,1)=(*(umatAbaqus.delta_eps_meca)).Coor(2,1)=dep;
|
|
umatAbaqus.temper_t= temperature_t;
|
|
umatAbaqus.delta_temper=temperature_tdt-temperature_t;
|
|
BaseH giH(3);
|
|
double jacobien_0,jacobien =1.;
|
|
EnergieMeca energ,energ_t; // variables intermédiaires, ne sert pas vraiment ici
|
|
double module_compressibilite=0.; double module_cisaillement=0. ;
|
|
// construction de la métrique umat associée:
|
|
// ici on considére que la base de référence actuelle est orthonormée
|
|
// ainsi: gijBB_tdt -> gabBB = identitée, idem en HH
|
|
// pour gijBB_0 et gijHH_0, on utilise la déformation arbitraire proposée
|
|
|
|
// a faire *******************
|
|
|
|
|
|
|
|
// (*gabBB_0) = (*gabBB_t) = IdBB3 - 2. * (*(umatAbaqus.eps_meca));
|
|
// (*gabHH_0) = (*gabHH_t) = gabBB_0->Monte2Indices();
|
|
// mise à jour du conteneur de la métrique umat
|
|
// umat_met3D.Mise_a_jour_grandeur(&gixB_0,&gixH_0,&gixB_t,&gixH_t,&gixB_tdt,&gixH_tdt
|
|
// ,IdBB,IdHH,gabBB_t,gabHH_t,gabBB_tdt,gabHH_tdt
|
|
// ,ggradVmoyBB_tnull,ggradVmoyBB_tdtnull,ggradVBB_tdtnull
|
|
// ,&jacobien,&jacobien_0);
|
|
// appel d'un calcul Umat
|
|
bool en_base_orthonormee = true; // les tenseurs sont en orthonormee a priori
|
|
Calcul_dsigma_deps (en_base_orthonormee, *(umatAbaqus.t_sigma),*(umatAbaqus.delta_eps_meca)
|
|
,(*(umatAbaqus.eps_meca)),(*(umatAbaqus.delta_eps_meca)),jacobien_0,jacobien
|
|
,*(umatAbaqus.t_sigma),*(umatAbaqus.d_sigma_deps),energ,energ_t
|
|
,module_compressibilite,module_cisaillement,umat_met3D.Conteneur_Umat()) ;
|
|
// calcul approché du E
|
|
// a) calcul du coefficient de compressibilité
|
|
Tenseur3HH& sig= *((Tenseur3HH*) umatAbaqus.t_sigma);
|
|
Tenseur3BB& eps= *((Tenseur3BB*) umatAbaqus.eps_meca);
|
|
double Isig= sig(1,1)+sig(2,2)+sig(3,3);
|
|
double Ieps= dep; //eps(1,1)+eps(2,2)+eps(3,3);
|
|
double Kc=(Isig)/(Ieps);
|
|
// b) calcul du coefficient de cisaillement moyen
|
|
double mu= sig(1,2)/dep;
|
|
// c) calcul de E approchée
|
|
double E=(3*Kc*mu)/(2*Kc+mu);
|
|
LibereTenseur();
|
|
LibereTenseurQ();
|
|
return E;
|
|
};
|
|
|
|
|
|
// ========== codage des METHODES VIRTUELLES protegees:================
|
|
// calcul des contraintes a t+dt
|
|
void Loi_Umat::Calcul_SigmaHH (TenseurHH& ,TenseurBB& ,DdlElement & tab_ddl,
|
|
TenseurBB & ,TenseurHH & ,BaseB& ,BaseH& ,TenseurBB& epsBB_,
|
|
TenseurBB& ,TenseurBB& ,
|
|
TenseurHH & ,Tableau <TenseurBB *>& d_gijBB_,double& ,double& ,
|
|
TenseurHH &
|
|
,EnergieMeca & ,const EnergieMeca &
|
|
,double& ,double&
|
|
,const Met_abstraite::Expli_t_tdt& )
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if (epsBB_.Dimension() != 3)
|
|
{ cout << "\nErreur : la dimension devrait etre 3 !\n";
|
|
cout << " Loi_Umat::Calcul_SigmaHH\n";
|
|
Sortie(1);
|
|
};
|
|
if (tab_ddl.NbDdl() != d_gijBB_.Taille())
|
|
{ cout << "\nErreur : le nb de ddl est != de la taille de d_gijBB_ !\n";
|
|
cout << " Loi_Umat::Calcul_SigmaHH\n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
cout << "\n pour l'instant le calcul en explicit n' implantees en Umat interne"
|
|
<< "\n Loi_Umat::Calcul_SigmaHH (.... ";
|
|
Sortie(1);
|
|
};
|
|
|
|
// calcul des contraintes a t+dt et de ses variations
|
|
void Loi_Umat::Calcul_DsigmaHH_tdt (TenseurHH& sigHH_t_,TenseurBB& DepsBB_,DdlElement & tab_ddl
|
|
,BaseB& giB_t,TenseurBB & gijBB_t,TenseurHH & gijHH_t
|
|
,BaseB& giB_tdt,Tableau <BaseB> & d_giB_tdt,BaseH& giH_tdt,Tableau <BaseH> & d_giH_tdt
|
|
,TenseurBB & epsBB_tdt,Tableau <TenseurBB *>& d_epsBB
|
|
,TenseurBB & delta_epsBB_,TenseurBB & gijBB_tdt,TenseurHH & gijHH_tdt
|
|
,Tableau <TenseurBB *>& d_gijBB_tdt
|
|
,Tableau <TenseurHH *>& d_gijHH_tdt,double& jacobien_0,double& jacobien
|
|
,Vecteur& d_jacobien_tdt,TenseurHH& sigHH_tdt,Tableau <TenseurHH *>& d_sigHH
|
|
,EnergieMeca & energ,const EnergieMeca & energ_t,double& module_compressibilite,double& module_cisaillement
|
|
,const Met_abstraite::Impli& ex)
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if (tab_ddl.NbDdl() != d_gijBB_tdt.Taille())
|
|
{ cout << "\nErreur : le nb de ddl est != de la taille de d_gijBB_tdt !\n";
|
|
cout << " Loi_Umat::Calcul_DsigmaHH_tdt\n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
|
|
// en fonction de la dimension on modifie les tenseurs de passage dans l'umat
|
|
switch (abs(epsBB_tdt.Dimension()))
|
|
{ case 2: // cas de tenseur en 2 dimension
|
|
{ const Tenseur2BB & epsBB = *((Tenseur2BB*) &epsBB_tdt); // passage explicite en dim 2
|
|
const Tenseur2BB & delta_epsBB = *((Tenseur2BB*) &delta_epsBB_); // passage en dim 2
|
|
const Tenseur2BB & DepsBB = *((Tenseur2BB*) &DepsBB_); // passage en dim 2
|
|
const Tenseur2HH & gijHH = *((Tenseur2HH*) &gijHH_tdt); // " " " "
|
|
Tenseur2HH & sigHH = *((Tenseur2HH*) &sigHH_tdt); // " " " "
|
|
Tenseur2HH & sigHH_t = *((Tenseur2HH*) &sigHH_t_); // " " " "
|
|
|
|
// on définit des tenseurs intermédiaires pour la contrainte et la déformation
|
|
Tenseur2BB eps_orthoBB(epsBB),delta_eps_orthoBB(delta_epsBB);
|
|
Tenseur2HH sig_orthoHH(sigHH_t);
|
|
Tenseur2BB D_orthoBB(DepsBB);
|
|
|
|
//la loi en dimension 2 doit s'exprimer dans un repère orthonormé de dimension 2
|
|
// on va utiliser une méthode particulière de la déformation associé
|
|
#ifdef MISE_AU_POINT
|
|
// vérif que le pointeur est ok
|
|
if (def_en_cours == NULL)
|
|
{ cout << "\nErreur : la deformation en cours n'est pas utilisable "
|
|
<< " on ne peut pas continuere ! !\n" ;
|
|
cout << " Loi_Umat::Calcul_DsigmaHH_tdt\n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
// détermination d'une bases particulière orthonormée pour représenter les tenseurs
|
|
// on est en contrainte plane ou déformation plane, la géométrie interpolée est de type 2D
|
|
// et on considère que la normale suivant laquelle la contrainte ou la déformation 33 est nulle
|
|
// est normale à la géométrie 2D, d'où l'utilisation d'une méthode ad hoc de la déformation en cours
|
|
|
|
// en sortie on a une matrice de passage, qui permet de passer de la base curviligne
|
|
// à cette base particulière que l'on va appeler IPa
|
|
// Le choix qui est fait est de calculer le passage gH(alpha) -> IP^beta ,
|
|
// c-a-d Aa(alpha,beta) = les coordonnées de gH(alpha) dans la base IP^beta,
|
|
// ou encore: la ligne alpha de Aa = les coordonnées locales de gH(alpha)
|
|
// NB: si on a besoin du passage de gB(alpha) on utilise la matrice
|
|
// inverse transposée de Aa
|
|
Mat_pleine Aa(2,2); // matrice de passage
|
|
bool absolue = false; // on utilise un repère locale ad hoc
|
|
def_en_cours->BasePassage(absolue,(*ex.giB_0),(*ex.giH_0),Aa);
|
|
|
|
// pour le changement de repère: la nouvelle base doit-être tel que
|
|
// gp^i = gamma^i_{.j} * g^j et gp_i = beta_i^{.j} g_j
|
|
// ici gp^i = Ip^i d'où [gamma] = [Aa]^{-1T} et [beta] = [Aa]^T
|
|
Mat_pleine gamma(Aa.Inverse().Transpose());
|
|
Mat_pleine beta(Aa.Transpose());
|
|
|
|
// on passe ensuite les tenseurs dans la base locale orthonormée
|
|
eps_orthoBB.ChBase(beta);
|
|
delta_eps_orthoBB.ChBase(beta);
|
|
D_orthoBB.ChBase(beta);
|
|
sig_orthoHH.ChBase(gamma);
|
|
sigHH.ChBase(gamma); // normalement ne sert à rien car est un résultat
|
|
|
|
// maintenant on va calculer l'équivalent local des bases à 0
|
|
ex.giB_0->ChangeBase_curviligne(Aa,giB_0_2D,giH_0_2D,Ip3B_0_3D);
|
|
// giB_0_2D et giH_0_2D contiennent les coordonnées des gi initiaux dans la nouvelle
|
|
// base ortho: mais il s'agit toujours des gi relatifs aux theta i de départ
|
|
// Ip3B_0_3D contient les coordonnées de la base ortho 2D + 1D (normal aux 2 premiers)
|
|
// , exprimées dans le repère 3D
|
|
// on doit avoir Ip3H_0_3D = Ip3B_0_3D mais comme la variance n'est pas la même il faut les
|
|
// affecter en passant outre la variance
|
|
Ip3H_0_3D.Affectation_trans_variance(Ip3B_0_3D);
|
|
|
|
// on change de base: pour exprimer les bases précédentes mais maintenant dans le nouveau
|
|
// repère Ip3B_0_3D
|
|
ex.giB_t->Change_repere(Ip3H_0_3D,giB_t_2D);
|
|
ex.giB_tdt->Change_repere(Ip3H_0_3D,giB_tdt_2D);
|
|
ex.giH_t->Change_repere(Ip3B_0_3D,giH_t_2D);
|
|
ex.giH_tdt->Change_repere(Ip3B_0_3D,giH_tdt_2D);
|
|
// donc maintenant umat_cont_2D contient via ses pointeurs les nouvelles bases
|
|
#ifdef MISE_AU_POINT
|
|
if (Permet_affichage() > 5)
|
|
{cout << "\n\n Loi_Umat::Calcul_SigmaHH (.. ";
|
|
cout << "\n gamma= "; Aa.Affiche();
|
|
cout << " base ex.giB_0:" << (*ex.giB_0);
|
|
cout << "\n base Ip : "<<Ip3B_0_3D;
|
|
cout << "\n base ex.giB_t:" << (*ex.giB_t);
|
|
cout << "\n dans Ip:" << giB_t_2D;
|
|
cout << "\n base ex.giB_tdt:" << (*ex.giB_tdt);
|
|
cout << "\n dans ip:" << giB_tdt_2D;
|
|
cout << "\n def epsBB: "<<epsBB;
|
|
cout << "\n def eps_orthoBB: "<< eps_orthoBB;
|
|
}
|
|
#endif
|
|
|
|
// maintenant on peut construire le reste de la métrique
|
|
const Met_abstraite::Umat_cont& umat_cont = umat_met2D.Construction_Umat(*umat_cont_2D);
|
|
|
|
#ifdef MISE_AU_POINT
|
|
if (Permet_affichage() > 5)
|
|
{cout << "\n base gip_B_t:" << (*umat_cont.giB_t);
|
|
cout << "\n base gip_B_tdt:" << (*umat_cont.giB_tdt);
|
|
};
|
|
#endif
|
|
|
|
bool en_base_orthonormee=true; // ici les tenseurs sont en orthonormee a priori
|
|
// c'est-à-dire dans un repère orthonormée, la direction 3 correspond à la direction
|
|
// pour laquelle sig^33 = 0
|
|
|
|
|
|
// appel de la procedure umat
|
|
Calcul_dsigma_deps (en_base_orthonormee, sig_orthoHH,D_orthoBB
|
|
,eps_orthoBB,delta_eps_orthoBB,jacobien_0,jacobien
|
|
,sigHH,d_sigma_deps_2D,energ,energ_t
|
|
,module_compressibilite,module_cisaillement,umat_cont);
|
|
|
|
#ifdef MISE_AU_POINT
|
|
if (Permet_affichage() > 5)
|
|
{cout << "\n contrainte sigHH dans Ip_a : "<<sigHH;
|
|
cout << "\n d_sigma_deps_2D dans Ip_a :" << d_sigma_deps_2D;
|
|
};
|
|
#endif
|
|
|
|
// la contrainte résultat : est tel qu'elle représente les composantes
|
|
// du tenseur contrainte dans le repère non orthonormée \hat I'_a
|
|
// les composantes de \hat I'_a dans I'_a sont giB_tdt_2D
|
|
// on a par définition: \hat I'_al = gamma(be,al) * \hat g_be
|
|
// la matrice gamma est utilisée sous forme de sa transposée
|
|
// maintenant on veut le tenseur des contraintes dans la base \hat g_be
|
|
// donc la relation \hat I'_al = gamma(be,al) * \hat g_be la relation de changement
|
|
// de base de l'ancienne base \hat I'_al à la nouvelle voulue \hat g_be
|
|
// avec comme matrice de changement: transposée (gamma)
|
|
sigHH.ChBase(gamma.Transpose(),true);
|
|
#ifdef MISE_AU_POINT
|
|
if (Permet_affichage() > 5)
|
|
{cout << "\n sigHH dans g_i :" <<sigHH;
|
|
};
|
|
#endif
|
|
|
|
// calcul de l'opérateur tangent / ddl
|
|
int nbddl = d_gijBB_tdt.Taille();
|
|
// ---- première solution --- on travail dans le repère local
|
|
int cas_resoudre = 1;
|
|
if (cas_resoudre==1)
|
|
{// on ramène l'opérateur tangent dans le repère local
|
|
Tenseur2HHHH d_sigma_depsHHHH; // init
|
|
// en sortie de Calcul_dsigma_deps, d_sigma_deps_2D est relatif à l'opérateur tangent
|
|
// dans le repère
|
|
// giH_tdt_2D
|
|
|
|
// ---- rappel du changement de repère pour le 4ième ordre ----
|
|
// changement des composantes du tenseur, retour donc dans la même variance
|
|
// en argument : A -> une reference sur le tenseur résultat qui a la même dimension
|
|
// retour d'une reference sur A
|
|
// A = A^{ijkl) g_i rond g_j rond g_k rond g_l = A'^{efgh) gp_i rond gpp_j rond g_k rond gp_l
|
|
// g_i = beta_i^j gp_j --> A'^{efgh) = A^{ijkl) beta_i^e beta_j^f beta_k^g beta_l^h
|
|
// TenseurHHHH & ChangeBase(TenseurHHHH & A,const BaseB & gi) const;
|
|
|
|
// pour simplifier on définit un nouveau repère qui va nous servir pour le
|
|
// changement de base, ceci à partir de la relation
|
|
// \hat I'_al = gamma(be,al) * \hat g_be
|
|
// gammaB est construit à partir de la matrice gamma transposée
|
|
BaseB gammaB(2,2);
|
|
gammaB.CoordoB(1)(1) = gamma(1,1);gammaB.CoordoB(1)(2) = gamma(2,1);
|
|
gammaB.CoordoB(2)(1) = gamma(1,2);gammaB.CoordoB(2)(2) = gamma(2,2);
|
|
// on change de repère
|
|
d_sigma_deps_2D.ChangeBase(d_sigma_depsHHHH,gammaB);
|
|
|
|
#ifdef MISE_AU_POINT
|
|
if (Permet_affichage() > 5)
|
|
{cout << "\n d_sigma_deps_2D: dans g_i" << d_sigma_deps_2D;
|
|
};
|
|
#endif
|
|
|
|
for (int i = 1; i<= nbddl; i++)
|
|
{ Tenseur2HH & dsigHH = *((Tenseur2HH*) (d_sigHH(i))); // passage en dim 2
|
|
const Tenseur2BB & depsBB = *((Tenseur2BB *) (d_epsBB(i))); // "
|
|
dsigHH = d_sigma_depsHHHH && depsBB;
|
|
};
|
|
};
|
|
// l'autre cas, voir 3D n'est pas d'actualité pour l'instant
|
|
break;
|
|
}
|
|
case 3: // cas en 3 dimension
|
|
{ const Tenseur3BB & epsBB = *((Tenseur3BB*) &epsBB_tdt); // passage en dim 3
|
|
const Tenseur3BB & delta_epsBB = *((Tenseur3BB*) &delta_epsBB_); // passage en dim 3
|
|
const Tenseur3BB & DepsBB = *((Tenseur3BB*) &DepsBB_); // passage en dim 3
|
|
const Tenseur3HH & gijHH = *((Tenseur3HH*) &gijHH_tdt); // " " " "
|
|
Tenseur3HH & sigHH = *((Tenseur3HH*) &sigHH_tdt); // " " " "
|
|
Tenseur3HH & sigHH_t = *((Tenseur3HH*) &sigHH_t_); // " " " "
|
|
|
|
// on définit des tenseurs intermédiaires pour la contrainte et la déformation
|
|
Tenseur3BB epsAA,delta_epsAA; Tenseur3HH sigAA;
|
|
|
|
// cout << "\n epsBB " << epsBB;
|
|
// calcul de la déformation et de l'accroissement dans le repère orthonormee
|
|
epsBB.BaseAbsolue(epsAA,giH_tdt);
|
|
// cout << "\n epsAA "; (umatAbaqus.eps_meca)->Ecriture(cout);
|
|
// int toto; cout << "\n une lettre ? "; cin >> toto;
|
|
delta_epsBB.BaseAbsolue(delta_epsAA,giH_tdt);
|
|
// calcul de la vitesse de déformation dans le repère orthonormee
|
|
Tenseur3BB D_abs_epsBB;
|
|
DepsBB.BaseAbsolue(D_abs_epsBB,giH_tdt);
|
|
// calcul de la contrainte initiale dans le repère orthonormee
|
|
sigHH_t.BaseAbsolue(sigAA,giB_tdt);
|
|
|
|
// construction de la métrique umat associée à la métrique actuelle,
|
|
// c'est-à-dire construction de la métrique correspondant aux coordonnées initiales
|
|
// considérées comme paramétrage matériel
|
|
const Met_abstraite::Umat_cont& umat_cont = umat_met3D.Construction_Umat(ex);
|
|
bool en_base_orthonormee=true; // ici les tenseurs sont en orthonormee a priori
|
|
// appel de la procedure umat
|
|
Calcul_dsigma_deps (en_base_orthonormee, sigAA,D_abs_epsBB
|
|
,epsAA,delta_epsAA,jacobien_0,jacobien
|
|
,*(umatAbaqus.t_sigma),*(umatAbaqus.d_sigma_deps),energ,energ_t
|
|
,module_compressibilite,module_cisaillement,umat_cont);
|
|
// passage de la contrainte dans la base locale HH
|
|
Tenseur3HH & sigabHH_tdt = *((Tenseur3HH*) (umatAbaqus.t_sigma)); // // passage en dim 3 explicite
|
|
sigabHH_tdt.Baselocale(sigHH,*(ex.giH_tdt));
|
|
// calcul de l'opérateur tangent / ddl
|
|
int nbddl = d_gijBB_tdt.Taille();
|
|
Tenseur3HHHH & d_sigma_deps = *((Tenseur3HHHH *) umatAbaqus.d_sigma_deps);
|
|
|
|
// ---- première solution --- on travail dans le repère local
|
|
int cas_resoudre = 1;
|
|
if (cas_resoudre==1)
|
|
{// on ramène l'opérateur tangent dans le repère local
|
|
Tenseur3HHHH d_sigma_depsHHHH;
|
|
d_sigma_deps.Baselocale(d_sigma_depsHHHH,*(ex.giH_tdt));
|
|
for (int i = 1; i<= nbddl; i++)
|
|
{ Tenseur3HH & dsigHH = *((Tenseur3HH*) (d_sigHH(i))); // passage en dim 3
|
|
const Tenseur3BB & depsBB = *((Tenseur3BB *) (d_epsBB(i))); // "
|
|
dsigHH = d_sigma_depsHHHH && depsBB;
|
|
};
|
|
}
|
|
else // ---- cas on travail dans le repère global ---- (ne fonctionne pas !!)
|
|
{
|
|
Tenseur3BB depsAA; Tenseur3BB dep1AA,dep2AA;
|
|
Tenseur3HH dsigAA; Tenseur3HH dsig1AA;
|
|
// on rajoute l'effet de la déformation
|
|
// terme sigma.D + D.sigma
|
|
d_sigma_deps += 2*Tenseur3HHHH::Prod_tensoriel_barre(sigabHH_tdt,IdHH3);
|
|
|
|
for (int i = 1; i<= nbddl; i++)
|
|
{ Tenseur3HH & dsigHH = *((Tenseur3HH*) (d_sigHH(i))); // passage en dim 3
|
|
const Tenseur3BB & d_gijBB = *((Tenseur3BB*)(d_gijBB_tdt(i))); // passage en dim 3
|
|
const Tenseur3HH & dgijHH = *((Tenseur3HH*)(d_gijHH_tdt(i))) ; // pour simplifier l'ecriture
|
|
const Tenseur3BB & depsBB = *((Tenseur3BB *) (d_epsBB(i))); // "
|
|
// tout d'abord variation de la déformation en orthonormee
|
|
depsBB.BaseAbsolue(depsAA,*(ex.giH_tdt)); // 1) prise en compte de la variation de depsBB
|
|
// 2) puis on tiens compte de la variation des gamma_a^i qui servent au changement de base
|
|
// de la base locale à la base orthonormee
|
|
depsAA += produit_1_pourLoiUmat(dep1AA,epsBB,(*(ex.d_giH_tdt))(i),*(ex.giH_tdt));
|
|
// dérivée de sigma^ab / d_ddl
|
|
dsigAA = d_sigma_deps && depsAA;
|
|
// dérivée de sigma^ij / d_ddl
|
|
dsigAA.Baselocale(dsigHH,*(ex.giH_tdt)); // 1) prise en compte de la variation de dsigAA
|
|
// 2) puis prise en compte de la variation des gamma_a^i qui servent au changement de base
|
|
// du global au locale (c'est-à-dire l'opération inverse que pour la déformation) mais dans
|
|
// les deux cas c'est les gamma_a^i qui servent !
|
|
// a priori ces les termes -W.sigma + sigma.W ?????
|
|
dsigHH += produit_1_pourLoiUmat(dsig1AA,sigabHH_tdt,(*(ex.d_giH_tdt))(i),*(ex.giH_tdt));
|
|
};
|
|
};
|
|
break;
|
|
}
|
|
default:
|
|
{cout << "\n pour l'instant seules les lois 3D sont implantees en Umat interne"
|
|
<< "\n Loi_Umat::Calcul_DsigmaHH_tdt (.... ";
|
|
Sortie(1);
|
|
}
|
|
};
|
|
// on libère les tenseurs intermédiaires
|
|
LibereTenseur();
|
|
LibereTenseurQ();
|
|
};
|
|
|
|
// calcul des contraintes et ses variations par rapport aux déformations a t+dt
|
|
// en_base_orthonormee: le tenseur de contrainte en entrée est en orthonormee
|
|
// le tenseur de déformation et son incrémentsont également en orthonormees
|
|
// si = false: les bases transmises sont utilisées
|
|
// ex: contient les éléments de métrique relativement au paramétrage matériel = X_(0)^a
|
|
void Loi_Umat::Calcul_dsigma_deps (bool en_base_orthonormee, TenseurHH & sigHH_t_,TenseurBB& DepsBB
|
|
,TenseurBB & epsBB_tdt,TenseurBB & delta_epsBB_,double& jacobien_0,double& jacobien
|
|
,TenseurHH& sigHH_tdt,TenseurHHHH& d_sigma_deps
|
|
,EnergieMeca & energ,const EnergieMeca & energ_t,double& module_compressibilite,double& module_cisaillement
|
|
,const Met_abstraite::Umat_cont& ex)
|
|
{
|
|
|
|
// si l'on est dans une utilisation interne de l'umat on appel
|
|
// directement la loi interne
|
|
if (utilisation_umat_interne)
|
|
{ // il faut passer les informations à la loi interne
|
|
((Loi_comp_abstraite*)loi_ext)->saveResul = ((SaveResul_Loi_Umat*) saveResul)->save_pour_loi_ext;
|
|
RepercuteChangeTemperature(TEMPS_tdt);
|
|
((Loi_comp_abstraite*)loi_ext)->Calcul_dsigma_deps (en_base_orthonormee, sigHH_t_,DepsBB,epsBB_tdt
|
|
,delta_epsBB_,jacobien_0,jacobien,sigHH_tdt
|
|
,d_sigma_deps,energ,energ_t,module_compressibilite,module_cisaillement,ex
|
|
);
|
|
// on met à jour la variation d'épaisseur constatée
|
|
Loi_Umat::SaveResul_Loi_Umat& sav = *((Loi_Umat::SaveResul_Loi_Umat*) &saveResul);
|
|
sav.h_tsurh0 = ((Loi_comp_abstraite*)loi_ext)->HsurH0(((Loi_comp_abstraite*)loi_ext)->saveResul);
|
|
return;
|
|
};
|
|
// sinon on dialogue via les pipes d'où le remplissage du conteneur UmatAbaqus
|
|
|
|
|
|
|
|
// const Tenseur3BB & epsBB = *((Tenseur3BB*) &epsBB_tdt); // passage en dim 3
|
|
// const Tenseur3BB & delta_epsBB = *((Tenseur3BB*) &delta_epsBB_); // passage en dim 3
|
|
// Tenseur3HH & sigHH = *((Tenseur3HH*) &sigHH_tdt); // " " " "
|
|
// Tenseur3HH & sigHH_t = *((Tenseur3HH*) &sigHH_t_); // " " " "
|
|
SaveResul_Loi_Umat & save_resul = *((SaveResul_Loi_Umat*) saveResul);
|
|
// .. définition de jeux de données adoc
|
|
// si on a des tenseurs à 2 dimensions, on considère que l'on est en CP par défaut
|
|
|
|
int dim_reel_tens = 3 ; // init par défaut: nb sigii
|
|
int nb_reel_tau_ij = 3 ; // idem
|
|
if (ex.giB_t->NbVecteur() == 2 )
|
|
{dim_reel_tens = 2; nb_reel_tau_ij=1; };
|
|
umatAbaqus.Init_un(dim_reel_tens,nb_reel_tau_ij);
|
|
|
|
// on renseigne la position du pti
|
|
// on devrait pouvoir le récupérer de l'appel venant de loi_comp_abstraite
|
|
// mais c'est pas simple donc je recalcule
|
|
umatAbaqus.coor_pt = def_en_cours->Position_tdt();
|
|
|
|
// umatAbaqus.Init_un();
|
|
// init de la déformation et de l'accroissement
|
|
// la dimension des tenseurs passés en paramètre, peut-être 2 ou 3
|
|
// non // par contre dans l'umatAbaqus on est toujours en 3D
|
|
// on fait donc une affectation trans dimension
|
|
bool plusZero = true; // on ajoute des zéros par défaut
|
|
// (umatAbaqus.eps_meca)->Affectation_trans_dimension(epsBB_tdt,plusZero);
|
|
*(umatAbaqus.eps_meca) = epsBB_tdt;
|
|
// (umatAbaqus.delta_eps_meca)->Affectation_trans_dimension(delta_epsBB_,plusZero);
|
|
*(umatAbaqus.delta_eps_meca) = delta_epsBB_;
|
|
// init de la contrainte initiale
|
|
// (umatAbaqus.t_sigma)->Affectation_trans_dimension(sigHH_t_,plusZero);
|
|
*(umatAbaqus.t_sigma)=sigHH_t_;
|
|
// récup des températures
|
|
umatAbaqus.temper_t=temperature_t; // température initiale
|
|
umatAbaqus.delta_temper=temperature_tdt-temperature_t; // variation de température
|
|
// récup des temps
|
|
const VariablesTemps& v_temps = ParaGlob::Variables_de_temps();
|
|
umatAbaqus.temps_tdt = v_temps.TempsCourant();
|
|
umatAbaqus.delta_t = v_temps.IncreTempsCourant();
|
|
umatAbaqus.temps_t = umatAbaqus.temps_tdt-umatAbaqus.delta_t;
|
|
// init des énergies
|
|
umatAbaqus.energie_elastique=energ_t.EnergieElastique();
|
|
umatAbaqus.dissipation_plastique=energ_t.DissipationPlastique();
|
|
umatAbaqus.dissipation_visqueuse=energ_t.DissipationVisqueuse();
|
|
// init des gradients
|
|
// les bases dans l'umatAbaqus ont toujours 3 vecteurs, mais
|
|
// ex peut en avoir que 2 : cas CP par exemple
|
|
int nb_vecteur = (ex.giB_t)->NbVecteur();
|
|
bool pas_Zero_base=false; // on ne veut pas changer le 3ième vecteur
|
|
// qui a été initialisé normalement correctement avec umatAbaqus.Init_un();
|
|
// umatAbaqus.giB_t.Affectation_partielle(nb_vecteur, *(ex.giB_t),pas_Zero_base);
|
|
umatAbaqus.giB_t = *(ex.giB_t);
|
|
// umatAbaqus.giB_tdt.Affectation_partielle(nb_vecteur, *(ex.giB_tdt),pas_Zero_base);
|
|
umatAbaqus.giB_tdt = *(ex.giB_tdt);
|
|
// si on est en tenseur 2D et en dimension 3 il faut définir les normales
|
|
if ((ex.giB_t->NbVecteur() == 2 )&& (ParaGlob::Dimension()==3))
|
|
{ umatAbaqus.N_t = Util::ProdVec_coorB( (*ex.giB_t)(1), (*ex.giB_t)(2));
|
|
umatAbaqus.N_tdt = Util::ProdVec_coorB( (*ex.giB_tdt)(1), (*ex.giB_tdt)(2));
|
|
};
|
|
// coordonnées du point, longueur caractéristique, les indices
|
|
if (umatAbaqus.nb_increment==1)
|
|
umatAbaqus.nom_materiau = nom_de_la_loi;
|
|
// le nombre d'itération est sytématiquement laissé à 1
|
|
// idem pour le nb de plis le np de pt d'integ dans le plis
|
|
// la longueur caractéristique est mise à 1. par défaut
|
|
// appel des routines Umat
|
|
umatAbaqus.EcritureDonneesPourUmat(utilisation_umat_interne,Permet_affichage());
|
|
umatAbaqus.LectureResultatUmat(utilisation_umat_interne,Permet_affichage());
|
|
// on met à jour la variation d'épaisseur constatée
|
|
Loi_Umat::SaveResul_Loi_Umat& sav = *((Loi_Umat::SaveResul_Loi_Umat*) &saveResul);
|
|
sav.hsurh0 = umatAbaqus.N_tdt.Norme();
|
|
// ------ retour des résultats
|
|
// les énergies
|
|
energ.ChangeEnergieElastique(umatAbaqus.energie_elastique);
|
|
energ.ChangeDissipationPlastique(umatAbaqus.dissipation_plastique);
|
|
energ.ChangeDissipationVisqueuse(umatAbaqus.dissipation_visqueuse);
|
|
// les contraintes
|
|
// les contraintes de l'umatAbaqus sont toujours en 3D,
|
|
// par contre l'utilisation interne peut-être en 2D: par exemple en CP
|
|
// sigHH_tdt.Affectation_trans_dimension(*(umatAbaqus.t_sigma),plusZero);
|
|
sigHH_tdt = *(umatAbaqus.t_sigma);
|
|
// l'opérateur tangent
|
|
// d_sigma_deps.Affectation_trans_dimension(*(umatAbaqus.d_sigma_deps),plusZero);
|
|
d_sigma_deps=*(umatAbaqus.d_sigma_deps);
|
|
// il faut maintenant calculer les modules de compressibilité et de cisaillement
|
|
Calcul_compressibilite_cisaillement(ex,module_compressibilite,module_cisaillement);
|
|
// on libère les tenseurs intermédiaires
|
|
LibereTenseur();
|
|
LibereTenseurQ();
|
|
};
|
|
|
|
|
|
// fonction interne utilisée par les classes dérivées de Loi_comp_abstraite
|
|
// pour répercuter les modifications de la température
|
|
// ici utiliser pour modifier la température des lois élémentaires
|
|
// l'Enum_dure: indique quel est la température courante : 0 t ou tdt
|
|
void Loi_Umat::RepercuteChangeTemperature(Enum_dure temps)
|
|
{ // la répercution n'est licite que s'il y a une loi interne
|
|
if (loi_ext != NULL)
|
|
{// pour l'instant on se place dans le cas d'une Loi_comp_abstraite
|
|
Loi_comp_abstraite * lois_interne = (Loi_comp_abstraite*) loi_ext;
|
|
|
|
lois_interne->temperature_0 = this->temperature_0;
|
|
lois_interne->temperature_t = this->temperature_t;
|
|
lois_interne->temperature_tdt = this->temperature_tdt;
|
|
lois_interne->dilatation=dilatation;
|
|
|
|
lois_interne->RepercuteChangeTemperature(temps);
|
|
// on répercute également les déformations thermiques, qui ne sont utilisées
|
|
// telles quelles que pour certaines lois: ex: loi hyper-élastique
|
|
if (dilatation)
|
|
{// a- dimensionnement des tenseurs intermédiaires
|
|
int dim_tens = epsBB_therm->Dimension();
|
|
// -- cas de la déformation
|
|
if (lois_interne->epsBB_therm == NULL) { lois_interne->epsBB_therm = NevezTenseurBB(dim_tens);}
|
|
else if (lois_interne->epsBB_therm->Dimension() != dim_tens)
|
|
{ delete lois_interne->epsBB_therm;lois_interne->epsBB_therm = NevezTenseurBB(dim_tens);};
|
|
// -- cas de la vitesse de déformation
|
|
if (lois_interne->DepsBB_therm == NULL) { lois_interne->DepsBB_therm = NevezTenseurBB(dim_tens);}
|
|
else if (lois_interne->DepsBB_therm->Dimension() != dim_tens)
|
|
{ delete lois_interne->DepsBB_therm;lois_interne->DepsBB_totale = NevezTenseurBB(dim_tens);};
|
|
// b- affectation des tenseurs
|
|
(*lois_interne->epsBB_therm)=(*epsBB_therm);
|
|
(*lois_interne->DepsBB_therm)=(*DepsBB_therm);
|
|
};
|
|
switch (temps)
|
|
{ case TEMPS_0:
|
|
{lois_interne->temperature = &lois_interne->temperature_0;
|
|
break;
|
|
}
|
|
case TEMPS_t:
|
|
{lois_interne->temperature = &lois_interne->temperature_t;
|
|
break;
|
|
}
|
|
case TEMPS_tdt:
|
|
{lois_interne->temperature = &lois_interne->temperature_tdt;
|
|
break;
|
|
}
|
|
default:
|
|
{ cout << "\n erreur, cas de temps non prevu !! "
|
|
<< "\n LoiContraintesPlanes::RepercuteChangeTemperature(...";
|
|
Sortie(1);
|
|
};
|
|
};
|
|
};
|
|
|
|
};
|
|
|
|
// passage des grandeurs métriques de l'ordre 2 à 3
|
|
void Loi_Umat::Passage_metrique_ordre2_vers_3(const Met_abstraite::Umat_cont& ex)
|
|
{// on s'occupe du redimensionnement éventuel
|
|
// la partie dépendant des vitesses: entre accolades pour pouvoir fermer
|
|
{if (ex.gradVmoyBB_t != NULL) {umat_cont_3D->gradVmoyBB_t= gradVmoyBB_t_3D_P = &gradVmoyBB_t_3D;};
|
|
if (ex.gradVmoyBB_tdt != NULL) {umat_cont_3D->gradVmoyBB_tdt=gradVmoyBB_tdt_3D_P = &gradVmoyBB_tdt_3D;};
|
|
if (ex.gradVBB_tdt != NULL) {umat_cont_3D->gradVBB_tdt=gradVBB_tdt_3D_P = &gradVBB_tdt_3D;};
|
|
}; // fin de la partie dédiée à la vitesse
|
|
// on commence par recopier les grandeurs de l'ordre 2 à 3
|
|
bool plusZero = true; // on complète avec des 0 dans un premier temps
|
|
int type_recopie=0; // = 0 -> on transfert les grandeurs à 0, t et tdt
|
|
umat_cont_3D->Passage_de_Ordre2_vers_Ordre3(ex,plusZero,type_recopie);
|
|
|
|
// maintenant on s'occupe de mettre à jour les grandeurs manquantes
|
|
// - les bases naturelles: le vecteur normal est normé et est identique pour les bases naturelles et duales
|
|
giB_0_3D.CoordoB(3) = (Util::ProdVec_coorB(giB_0_3D(1),giB_0_3D(2))).Normer();
|
|
giH_0_3D.CoordoH(3) = giB_0_3D(3).Bas_haut();
|
|
giB_t_3D.CoordoB(3) = (Util::ProdVec_coorB(giB_t_3D(1),giB_t_3D(2))).Normer();
|
|
giH_t_3D.CoordoH(3) = giB_t_3D(3).Bas_haut();
|
|
// cas particulier du vecteur tdt
|
|
giB_tdt_3D.CoordoB(3) = (Util::ProdVec_coorB(giB_tdt_3D(1),giB_tdt_3D(2))); // calcul du vecteur normal non normé
|
|
double norme_N_tdt = giB_tdt_3D(3).Norme(); // calcul de la norme qui nous servira pour les variations
|
|
giB_tdt_3D.CoordoB(3) /= norme_N_tdt;
|
|
giH_tdt_3D.CoordoH(3) = giB_tdt_3D(3).Bas_haut();
|
|
// - les tenseurs métriques: au début 1 pour la direction 3
|
|
gijBB_0_3D.Coor(3,3)=gijHH_0_3D.Coor(3,3)=gijBB_t_3D.Coor(3,3)=gijHH_t_3D.Coor(3,3)=gijBB_tdt_3D.Coor(3,3)=gijHH_tdt_3D.Coor(3,3)=1.;
|
|
|
|
};
|
|
|
|
|
|
// calcul des modules de compressibilité et de cisaillement
|
|
// en fonction des résultats de l'umat
|
|
void Loi_Umat::Calcul_compressibilite_cisaillement(const Met_abstraite::Umat_cont& ex
|
|
,double & module_compressibilite,double & module_cisaillement)
|
|
{
|
|
switch (umatAbaqus.t_sigma->Dimension())
|
|
{case 3:
|
|
{Tenseur3HB sigHB = (*umatAbaqus.t_sigma) * (*ex.gijBB_tdt);
|
|
// cas du module de compressibilité
|
|
double trace_sig_sur_trois = 1./3. * sigHB.Trace();
|
|
double log_V = log((*ex.jacobien_tdt));
|
|
module_compressibilite = trace_sig_sur_trois / log_V;
|
|
// cas du module de cisaillement
|
|
double Qsig = sigHB.II();
|
|
Tenseur3HB epsHB = (*ex.gijHH_tdt) * (*umatAbaqus.eps_meca) ;
|
|
double deux_Qeps = 2.*epsHB.II();
|
|
module_cisaillement = Qsig / deux_Qeps;
|
|
break;
|
|
}
|
|
case 2: // en CP
|
|
{if ((umatAbaqus.dim_tens == 2) && (umatAbaqus.nb_tau_ij == 1))
|
|
{Tenseur2HB sigHB = (*umatAbaqus.t_sigma) * (*ex.gijBB_tdt);
|
|
// cas du module de compressibilité
|
|
// la contrainte 33 = 0
|
|
double trace_sig_sur_trois = 1./3. * sigHB.Trace();
|
|
// on démarre d'une base ortho donc le jacobien initial par principe = 1
|
|
double V = Dabs((*ex.jacobien_tdt)); // cas de la surface
|
|
// il faut maintenant introduire la surface
|
|
// la normale en 3 = 1 initialement
|
|
double var_3 = umatAbaqus.N_tdt.Norme();
|
|
V *= var_3;
|
|
double log_V = log(V);
|
|
// pour éviter une division de 0/0 on régularise
|
|
module_compressibilite = Dabs(trace_sig_sur_trois / (log_V+DSigne(log_V)*ConstMath::petit));
|
|
// cas du module de cisaillement
|
|
double Qsig = sigHB.II();
|
|
// il faut que l'on reconstruise un tenseur 3D avec la déformation d'épaisseur
|
|
Tenseur3HB epsHB; double eps_33=0;double delta_eps_33 = 0.;
|
|
double var_3_t = umatAbaqus.N_t.Norme();
|
|
epsHB.Affectation_trans_dimension((*ex.gijHH_tdt) * (*umatAbaqus.eps_meca),true);
|
|
// N_tdt = la nouvelle normale, compte tenu de la variation d'épaisseur
|
|
// et on part de N_0 qui est normé, d'où on considère que ||N_tdt|| = h/h0
|
|
switch (type_de_deformation)
|
|
{case DEFORMATION_STANDART : case DEFORMATION_POUTRE_PLAQUE_STANDART :
|
|
// cas d'une déformation d'Almansi
|
|
{ // epsBB33 = 1/2 * (1. - (h0/h)^2), en orthonormee
|
|
// dans le repère local: epsBB33 = 1/2 * (h^2 - 1.), or h0=1. donc : epsBB33 = 1/2 * ((h/h0)^2 - 1.)
|
|
eps_33 = 0.5 * (var_3 * var_3 - 1.);
|
|
delta_eps_33 = 0.5 * (var_3 * var_3 - var_3_t * var_3_t);
|
|
};
|
|
break;
|
|
case DEFORMATION_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEFORMATION_CUMU_LOGARITHMIQUE :
|
|
// cas d'une def logarithmique ou une approximation
|
|
{ eps_33 = log(var_3);
|
|
delta_eps_33 = log(var_3) - log(var_3_t);
|
|
};
|
|
break;
|
|
default :
|
|
cout << "\nErreur : type de deformation qui n'est pas actuellement pris en compte, type= "
|
|
<< Nom_type_deformation(type_de_deformation);
|
|
cout << "\n Loi_Umat::Calcul_compressibilite_cisaillement(.. \n";
|
|
Sortie(1);
|
|
};
|
|
// le vecteur normal est normal à g_i à tous les temps (on considère que l'on reste dans le plan principal
|
|
// du coup g^{33} = h0^2/h^2 ce qui permet de calculer eps^3_3
|
|
epsHB.Coor(3,3)=eps_33 /(var_3*var_3);
|
|
double deux_Qeps = 2.*epsHB.II();
|
|
// pour éviter une division de 0/0 on régularise
|
|
module_cisaillement = Qsig / (deux_Qeps+ConstMath::petit);;
|
|
}
|
|
else
|
|
{ cout << "\n ** erreur, ce cas n'est pas encore pris en compte: "
|
|
<< " tenseur d'ordre 2 et situation non en contrainte plane !";
|
|
cout << "\n Loi_Umat::Calcul_compressibilite_cisaillement(.. \n";
|
|
Sortie(1);
|
|
};
|
|
break;
|
|
}
|
|
default:
|
|
cout << "\n ** erreur, ce cas n'est pas encore pris en compte: ";
|
|
cout << "\n Loi_Umat::Calcul_compressibilite_cisaillement(.. \n";
|
|
Sortie(1);
|
|
break;
|
|
};
|
|
|
|
#ifdef MISE_AU_POINT
|
|
if (Permet_affichage() > 4)
|
|
{cout << "\n module_compressibilite= " << module_compressibilite;
|
|
cout << "\n module_cisaillement= " << module_cisaillement;
|
|
};
|
|
#endif
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|