// FICHIER : Loi_ortho2D_C_entrainee.cc
// CLASSE : Loi_ortho2D_C_entrainee
// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) .
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//
// For more information, please consult: .
//#include "Debug.h"
# include
using namespace std; //introduces namespace std
#include
#include
#include "Sortie.h"
#include "TypeConsTens.h"
#include "ConstMath.h"
#include "Loi_ortho2D_C_entrainee.h"
#include "NevezTenseur.h"
#include "MathUtil.h"
#include "Util.h"
#include "Enum_TypeQuelconque.h"
#include "TypeQuelconqueParticulier.h"
#include "TenseurQ2gene.h"
#include "MathUtil.h"
#include "MathUtil2.h"
#include "CharUtil.h"
#include "Coordonnee2.h"
// ========== fonctions pour la classe de sauvegarde des résultats =========
// constructeur par défaut
Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee(const int type_transport):
O_B(NULL), O_H(NULL),Op_H(2,2),Op_H_t(2,2),eps_loc_HH(NULL),sig_loc_HH(NULL)
,para_loi(NULL)
{
};
// constructeur de copie
Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee(const SaveResulLoi_ortho2D_C_entrainee& sav):
O_B(NULL), O_H(NULL),Op_H(2,2),Op_H_t(2,2),eps_loc_HH(NULL),sig_loc_HH(NULL)
,para_loi(NULL)
{
// partie repère d'orthotropie
if (sav.O_B != NULL)
O_B = new BaseB(*sav.O_B);
if (sav.O_H != NULL)
O_H = new BaseH(*sav.O_H);
if (sav.eps_loc_HH != NULL)
eps_loc_HH = NevezTenseurHH(*sav.eps_loc_HH);
if (sav.sig_loc_HH != NULL)
sig_loc_HH = NevezTenseurHH(*sav.sig_loc_HH);
if (sav.para_loi != NULL)
para_loi = new Vecteur (*sav.para_loi);
};
// destructeur
Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::~SaveResulLoi_ortho2D_C_entrainee()
{
// partie repère d'orthotropie
if (O_B != NULL)
delete O_B;
if (O_H != NULL)
delete O_H;
if (eps_loc_HH != NULL)
delete eps_loc_HH;
if (sig_loc_HH != NULL)
delete sig_loc_HH;
if (para_loi != NULL)
delete para_loi;
};
// affectation
Loi_comp_abstraite::SaveResul & Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::operator = ( const Loi_comp_abstraite::SaveResul & a)
{ Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee& sav = *((Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee*) &a);
eps33=sav.eps33;eps33_t=sav.eps33_t;
// partie repère d'orthotropie
if (sav.O_B != NULL)
{if (O_B == NULL) {O_B = new BaseB(*sav.O_B);}
else {*O_B = *sav.O_B;};
}
else // sinon cas NULL
{if (O_B != NULL) {delete O_B;O_B=NULL;}} ;
if (sav.O_H != NULL)
{if (O_H == NULL) {O_H = new BaseH(*sav.O_H);}
else {*O_H = *sav.O_H;};
}
else // sinon cas NULL
{if (O_H != NULL) {delete O_H;O_H=NULL;}} ;
if (sav.eps_loc_HH != NULL)
{if (eps_loc_HH == NULL) {eps_loc_HH = NevezTenseurHH(*sav.eps_loc_HH);}
else {*eps_loc_HH = *sav.eps_loc_HH;};
}
else // sinon cas NULL
{if (eps_loc_HH != NULL) {delete eps_loc_HH;eps_loc_HH=NULL;}} ;
if (sav.sig_loc_HH != NULL)
{if (sig_loc_HH == NULL) {sig_loc_HH = NevezTenseurHH(*sav.sig_loc_HH);}
else {*sig_loc_HH = *sav.sig_loc_HH;};
}
else // sinon cas NULL
{if (sig_loc_HH != NULL) {delete sig_loc_HH; sig_loc_HH= NULL;};
} ;
if (sav.para_loi != NULL)
{if (para_loi == NULL) para_loi = new Vecteur (*sav.para_loi);
else {*para_loi = *sav.para_loi; };
}
else // sinon cas NULL
{if (para_loi != NULL) {delete para_loi;para_loi=NULL;}} ;
// et la base
Op_H = sav.Op_H;
Op_H_t = sav.Op_H_t;
return *this;
};
//------- lecture écriture dans base info -------
// cas donne le niveau de la récupération
// = 1 : on récupère tout
// = 2 : on récupère uniquement les données variables (supposées comme telles)
void Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Lecture_base_info(istream& ent,const int cas)
{ string nom;
ent >> nom ;
#ifdef MISE_AU_POINT
if (nom != "S_Ortho_2D_C")
{ cout << "\nErreur : on attendait le mot cle: S_Ortho_2D_C "
<< " et on a lue "<> nom >> *O_B;}
else if (O_H != NULL)
{ ent >> nom >> *O_H;}
// la base convectée
ent >> nom >> Op_H_t ;
Op_H = Op_H_t;
// les stockages conditionnels
int test;
ent >> nom >> test;
if (test == 0)
{ if (eps_loc_HH != NULL)
{delete eps_loc_HH;eps_loc_HH=NULL;}
if (sig_loc_HH != NULL)
{delete sig_loc_HH;sig_loc_HH=NULL;}
if (para_loi != NULL)
{delete para_loi;para_loi=NULL;}
}
else // sinon cas où on a des données additionnelles
{ if (eps_loc_HH == NULL) eps_loc_HH = NevezTenseurHH(2);
ent >> nom ; eps_loc_HH->Lecture(ent);
if (sig_loc_HH == NULL) sig_loc_HH = NevezTenseurHH(2);
ent >> nom ; sig_loc_HH->Lecture(ent);
if (para_loi == NULL) para_loi = new Vecteur (7);
ent >> *para_loi;
};
break;
}
case 2 :
{
// la base convectée
ent >> nom >> Op_H_t ;
// les stockages conditionnels
int test;
ent >> nom >> test;
if (test == 0)
{ if (eps_loc_HH != NULL)
{delete eps_loc_HH;eps_loc_HH=NULL;}
if (sig_loc_HH != NULL)
{delete sig_loc_HH;sig_loc_HH=NULL;}
if (para_loi != NULL)
{delete para_loi;para_loi=NULL;}
}
else // sinon cas où on a des données additionnelles
{ if (eps_loc_HH == NULL) eps_loc_HH = NevezTenseurHH(2);
ent >> nom ; eps_loc_HH->Lecture(ent);
if (sig_loc_HH == NULL) sig_loc_HH = NevezTenseurHH(2);
ent >> nom ; sig_loc_HH->Lecture(ent);
if (para_loi == NULL) para_loi = new Vecteur(7);
ent >> nom >> *para_loi;
};
break;
}
default:
cout << "\n cas non considere !!: cas= " << cas
<< "\n Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Ecriture_base_info(...";
Sortie(1);
};
};
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables
//(supposées comme telles)
void Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Ecriture_base_info(ostream& sort,const int cas )
{ sort << "\n S_Ortho_2D_C ";
// on ne sauvegarde que ce qui est à 0 et à t, ce qui est à tdt est considéré une zone de travail
switch (cas)
{ case 1 :
{
// la base initiale
if (O_B != NULL)
{ sort << " O_B: "<< *O_B;}
else if (O_H != NULL)
{ sort << " O_H: "<< *O_H;}
// la base convectée
sort << " Op_H_t: "<< Op_H_t << " ";
// les stockages conditionnels
if (eps_loc_HH != NULL)
{ sort << " addi: 1 " << "\n eps_loc_HH: ";
eps_loc_HH->Ecriture(sort);
sort << "\n sig_loc_HH: ";
sig_loc_HH->Ecriture(sort);
sort << "\n para_loi: " << *para_loi << " ";
}
else
{ sort << " addi: 0 ";};
break;
}
case 2 :
{
// la base convectée
sort << " Op_H_t: "<< Op_H_t << " ";
// les stockages conditionnels
if (eps_loc_HH != NULL)
{ sort << "\n addi: 1 "<< "\n eps_loc_HH: " ;
eps_loc_HH->Ecriture(sort);
sort << "\n sig_loc_HH: " ;
sig_loc_HH->Ecriture(sort);
sort << "\n para_loi: " << *para_loi << " ";
}
else
{ sort << "\n addi: 0 ";};
break;
}
default:
cout << "\n cas non considere !!: cas= " << cas
<< "\n Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Ecriture_base_info(...";
Sortie(1);
};
};
// mise à jour des informations transitoires
void Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::TdtversT()
{ Op_H_t = Op_H;
eps33_t=eps33;
};
void Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::TversTdt()
{ Op_H = Op_H_t;
eps33=eps33_t;
};
// affichage à l'écran des infos
void Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Affiche() const
{ cout << "\n SaveResulLoi_ortho2D_C_entrainee: " ;
if (O_B != NULL)
{cout << "\n O_B= "; O_B->Affiche();
};
if (O_H != NULL)
{cout << "\n O_H= "; O_H->Affiche();
};
cout << "\n Op_H= ";Op_H.Affiche();
// les tenseurs intermédiaires
if (eps_loc_HH != NULL)
{ cout << "\n eps_loc_HH= "; eps_loc_HH->Ecriture(cout);
};
if (sig_loc_HH != NULL)
{ cout << "\n sig_loc_HH= "; sig_loc_HH->Ecriture(cout);
};
// paramètre variables éventuelles de la loi
if (para_loi != NULL)
{ cout << "\n para_loi: ";
for (int i=1; i< 8;i++)
cout << " coef("< dans un plan
#ifdef MISE_AU_POINT
if ((beta.Nb_colonne() != 2) || (beta.Nb_ligne() != 2))
{ cout << "\nErreur : la dimension devrait etre 2 pour la matrice de changement de base = beta!"
<< " alors n_colonne= " << beta.Nb_colonne() << " et nb_ligne= " << beta.Nb_ligne()
<< " \n SaveResulLoi_ortho2D_C_entrainee::ChBase_des_grandeurs(... ";
Sortie(1);
};
if ((gamma.Nb_colonne() != 2) || (gamma.Nb_ligne() != 2))
{ cout << "\nErreur : la dimension devrait etre 2 pour la matrice de changement de base = gamma!"
<< " alors n_colonne= " << gamma.Nb_colonne() << " et nb_ligne= " << gamma.Nb_ligne()
<< " \n SaveResulLoi_ortho2D_C_entrainee::ChBase_des_grandeurs(... ";
Sortie(1);
};
#endif
if (O_B != NULL)
{for (int i=1;i<3;i++)
{ CoordonneeB Ap_B(2); // inter
MathUtil2::ChBase(O_B->CoordoB(i),beta,Ap_B);
O_B->CoordoB(i)=Ap_B;
}
};
if (O_H != NULL)
{for (int i=1;i<3;i++)
{ CoordonneeH Ap_H(2); // inter
MathUtil2::ChBase(O_H->CoordoH(i),gamma,Ap_H);
O_H->CoordoH(i)=Ap_H;
}
};
// les autres grandeurs sont issues du calcul
// normalement elles sont calculées en même temps que les contraintes
// mais on les change de repère néanmoins, au cas on on ferait une sortie
// d'info sans calcul (c'est pénalisant pour le cas avec calcul, mais cela
// évite peut-être des pb potentiels ??)
// Op_H est toujours calculé
{for (int i=1;i<3;i++)
{ CoordonneeH Ap_H(2); // inter
MathUtil2::ChBase(Op_H_t.CoordoH(i),gamma,Ap_H);
Op_H_t.CoordoH(i)=Ap_H;
}
};
// cas des grandeurs locales si elles sont sauvegardées
if (eps_loc_HH != NULL)
{ eps_loc_HH->ChBase(gamma);};
if (sig_loc_HH != NULL)
{ sig_loc_HH->ChBase(gamma);};
};
// procedure permettant de completer éventuellement les données particulières
// de la loi stockées
// au niveau du point d'intégration par exemple: exemple: un repère d'anisotropie
// completer est appelé apres sa creation avec les donnees du bloc transmis
// peut etre appeler plusieurs fois
Loi_comp_abstraite::SaveResul* Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee
::Complete_SaveResul(const BlocGen & bloc, const Tableau & tab_coor
,const Loi_comp_abstraite* loi)
{// on regarde s'il s'agit d'un repère d'orthotropie
if (bloc.Nom(1) == "repere_anisotropie_")
{// ensuite on vérifie le nom de l'identificateur
Loi_ortho2D_C_entrainee* loiOrtho = (Loi_ortho2D_C_entrainee*) loi;
// dimensionnement des bases d'orthotropie
// . elles ont la dimension de l'espace: donc soit 2 soit 3
// . on utilise seulement les deux premiers vecteurs
int dim = ParaGlob::Dimension();
if (loiOrtho->Type_transport() == 0)
{O_H = new BaseH(dim,2); sig_loc_HH = NevezTenseurHH(2); }
else
{O_B = new BaseB(dim,2); eps_loc_HH = NevezTenseurHH(2); };
// récupération du repère
if (bloc.Nom(2) == loiOrtho->NomRepere())
{// c'est le bon, récupération des 2 premiers vecteurs
if (O_B != NULL)
{for (int i=1;i<3;i++)
O_B->CoordoB(i).Change_val(tab_coor(i));
};
if (O_H != NULL)
{for (int i=1;i<3;i++)
O_H->CoordoH(i).Change_val(tab_coor(i));
};
};
};
//
return this;
};
// initialise les informations de travail concernant le pas de temps en cours
void Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Init_debut_calcul()
{ };
// ========== fin des fonctions pour la classe de sauvegarde des résultats =========
Loi_ortho2D_C_entrainee::Loi_ortho2D_C_entrainee () : // Constructeur par defaut
Loi_comp_abstraite(ORTHOELA2D_C,CAT_MECANIQUE,2)
,E1(-ConstMath::trespetit),E2(-ConstMath::trespetit),E3(-ConstMath::trespetit)
,nu12(-ConstMath::trespetit),nu13(-ConstMath::trespetit),nu23(-ConstMath::trespetit)
,G12(-ConstMath::trespetit)
,fct_para(7),cas_calcul(0),type_transport(0)
,verification_convexite(1),sortie_post(0)
,nom_repere("")
,inv_loi(2,2),Op_B(2,2),d_Op_B(2,2),d_Op_H(2,2),pO_B(2,2),pO_H(2,2)
,beta_inv(2,2),beta(2,2),gamma(2,2),beta_transpose(2,2),gamma_transpose(2,2)
,alpha_H(2,2)
,I_x_I_HHHH(),I_xbarre_I_HHHH(),I_x_eps_HHHH(),Ixbarre_eps_HHHH()
{for (int i=1;i< 8;i++)
fct_para(i) = NULL;
null_fct_para=1; // pour l'instant pas de fonction
};
// Contructeur fonction de tous les paramètres constants de la loi
Loi_ortho2D_C_entrainee::Loi_ortho2D_C_entrainee(const double& EE1,const double& EE2,const double& EE3
,const double& nunu12,const double& nunu13,const double& nunu23
,const double& GG12
,const string& nom_rep):
Loi_comp_abstraite(ORTHOELA2D_C,CAT_THERMO_MECANIQUE,2)
,E1(EE1),E2(EE2),E3(EE3),nu12(nunu12),nu13(nunu13),nu23(nunu23)
,G12(GG12)
,fct_para(7),cas_calcul(0),type_transport(0)
,verification_convexite(1),sortie_post(0)
,nom_repere(nom_rep)
,inv_loi(2,2),Op_B(2,2),d_Op_B(2,2),d_Op_H(2,2),pO_B(2,2),pO_H(2,2)
,beta_inv(2,2),beta(2,2),gamma(2,2),beta_transpose(2,2),gamma_transpose(2,2)
,alpha_H(2,2)
,I_x_I_HHHH(),I_xbarre_I_HHHH(),I_x_eps_HHHH(),Ixbarre_eps_HHHH()
{for (int i=1;i< 8;i++)
fct_para(i) = NULL;
null_fct_para=1; // pour l'instant pas de fonction
};
// Constructeur de copie
Loi_ortho2D_C_entrainee::Loi_ortho2D_C_entrainee (const Loi_ortho2D_C_entrainee& loi) :
Loi_comp_abstraite(loi)
,E1(loi.E1),E2(loi.E2),E3(loi.E3),nu12(loi.nu12),nu13(loi.nu13),nu23(loi.nu23)
,G12(loi.G12)
,fct_para(loi.fct_para),cas_calcul(loi.cas_calcul)
,inv_loi(loi.inv_loi),Op_B(2,2),d_Op_B(2,2),d_Op_H(2,2),pO_B(2,2),pO_H(2,2)
,beta_inv(2,2),beta(2,2),gamma(2,2),beta_transpose(2,2),gamma_transpose(2,2)
,alpha_H(2,2)
,type_transport(loi.type_transport)
,verification_convexite(loi.verification_convexite),sortie_post(loi.sortie_post)
,nom_repere(loi.nom_repere)
,I_x_I_HHHH(),I_xbarre_I_HHHH(),I_x_eps_HHHH(),Ixbarre_eps_HHHH()
{// on regarde s'il s'agit d'une courbe locale ou d'une courbe globale
for (int i=1;i< 8;i++)
{if (fct_para(i) != NULL)
{null_fct_para=0; // dans tous les cas on indique qu'il y a des fonctions
if (fct_para(i)->NomFonction() == "_")
{// comme il s'agit d'une fonction locale on la redéfinie (sinon pb lors du destructeur de loi)
string non_fonction("_");
fct_para(i) = Fonction_nD::New_Fonction_nD(*fct_para(i));
};
};
};
};
Loi_ortho2D_C_entrainee::~Loi_ortho2D_C_entrainee ()
// Destructeur
{ for (int i=1;i< 8;i++)
{if (fct_para(i) != NULL)
if (fct_para(i)->NomFonction() == "_") delete fct_para(i);
};
};
// Lecture des donnees de la classe sur fichier
void Loi_ortho2D_C_entrainee::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D
,LesFonctions_nD& lesFonctionsnD)
{
// on lit les coefficients dans l'ordre
string nom_class_methode("Loi_ortho2D_C_entrainee::LectureDonneesParticulieres");
double val_defaut=0.;
double min = 0.; double max = -1; // max < min => la condition n'est pas prise en compte
// pour faire une boucle de lecture on constitue un tableau de mots clés
Tableau tab_mot_cle(7);
tab_mot_cle(1) = "E1";tab_mot_cle(2) = "E2";tab_mot_cle(3) = "E3";
tab_mot_cle(4) = "nu12";tab_mot_cle(5) = "nu13";tab_mot_cle(6) = "nu23";
tab_mot_cle(7) = "G12";
// puis un tableau pour les valeurs
Tableau < double * > coef(7);
coef(1) = &E1; coef(2) = & E2;coef(3) = &E3;
coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23;
coef(7) = & G12;
// on boucle sur les 7 coefficients
for (int i=1;i< 8;i++)
{string mot_cle1=tab_mot_cle(i)+"=";
string mot_cle2=tab_mot_cle(i)+"_fonction_nD:";
if(strstr(entreePrinc->tablcar,mot_cle2.c_str())==0)
{// lecture du paramètre
if (i<4) // dans le cas des Ei, il faut qu'ils soient tous non nulles
// sinon on ne peut pas calculer inv_loi
{ min = ConstMath::unpeupetit; max = ConstMath::grand; }
else {min = 0.; max = -1; };// max < min => la condition n'est pas prise en compte
if (!entreePrinc->Lecture_un_parametre_double(val_defaut,nom_class_methode
,min,max,mot_cle1, *coef(i) ))
{ entreePrinc->MessageBuffer("**erreur en lecture** "+mot_cle1);
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
}
else // on lit une fonction
{// on passe le mot clé générique
bool lec = entreePrinc->Lecture_et_verif_mot_cle(nom_class_methode,mot_cle1);
// on lit le nom de la fonction
string nom_fonct;
lec = lec && entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle2,nom_fonct);
if (!lec )
{ entreePrinc->MessageBuffer("**erreur en lecture** "+mot_cle2);
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
null_fct_para=0; // on indique qu'il y a des fonctions
// maintenant on définit la fonction
if (lesFonctionsnD.Existe(nom_fonct))
{fct_para(i) = lesFonctionsnD.Trouve(nom_fonct);
}
else
{// sinon il faut la lire maintenant
string non("_");
fct_para(i) = Fonction_nD::New_Fonction_nD(non, Id_Nom_Fonction_nD(nom_fonct));
// lecture de la courbe
fct_para(i)->LectDonnParticulieres_Fonction_nD (non,entreePrinc);
// maintenant on vérifie que la fonction est utilisable
if (fct_para(i)->NbComposante() != 1 )
{ cout << "\n erreur en lecture, la fonction " << nom_fonct
<< " est une fonction vectorielle a " << fct_para(i)->NbComposante()
<< " composante alors qu'elle devrait etre scalaire ! "
<< " elle n'est donc pas utilisable !! ";
string message("\n**erreur08** \n"+nom_class_methode+"(...");
entreePrinc->MessageBuffer(message);
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
};
if (i != 7)
entreePrinc->NouvelleDonnee(); // on se positionne sur un nouvel enreg
};
}; // fin de la boucle for (int i=1;i< 7;i++)
// lecture du repère d'orthotropie entraîné, associé
string mot_cle("nom_repere_associe_");
entreePrinc->NouvelleDonnee(); // on se positionne sur un nouvel enreg
bool lec = entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle,nom_repere);
if (!lec )
{ entreePrinc->MessageBuffer("**erreur en lecture** "+mot_cle);
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// --- lecture éventuelle des paramètres de réglage ----
cas_calcul = 0; // par défaut
if(strstr(entreePrinc->tablcar,"avec_parametres_de_reglage_")!=0)
{string nom;
entreePrinc->NouvelleDonnee(); // on se positionne sur un nouvel enreg
// on lit tant que l'on ne rencontre pas la ligne contenant "fin_parametres_reglage_"
// ou un nouveau mot clé global auquel cas il y a pb !!
MotCle motCle; // ref aux mots cle
while (strstr(entreePrinc->tablcar,"fin_parametres_reglage_")==0)
{
// si on a un mot clé global dans la ligne courante c-a-d dans tablcar --> erreur
if ( motCle.SimotCle(entreePrinc->tablcar))
{ cout << "\n erreur de lecture des parametre de reglage : on n'a pas trouve le mot cle "
<< " fin_parametres_reglage_ et par contre la ligne courante contient un mot cle global ";
entreePrinc->MessageBuffer("** erreur5 des parametres de reglage de la loi de comportement de Loi_ortho2D_C_entrainee **");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// lecture d'un mot clé
*(entreePrinc->entree) >> nom;
if ((entreePrinc->entree)->rdstate() == 0)
{} // lecture normale
#ifdef ENLINUX
else if ((entreePrinc->entree)->fail())
// on a atteind la fin de la ligne et on appelle un nouvel enregistrement
{ entreePrinc->NouvelleDonnee(); // lecture d'un nouvelle enregistrement
*(entreePrinc->entree) >>nom;
}
#else
else if ((entreePrinc->entree)->eof())
// la lecture est bonne mais on a atteind la fin de la ligne
{ if(nom != "fin_parametres_reglage_")
{entreePrinc->NouvelleDonnee(); *(entreePrinc->entree) >> nom;};
}
#endif
else // cas d'une erreur de lecture
{ cout << "\n erreur de lecture inconnue ";
entreePrinc->MessageBuffer("** erreur4 des parametres de reglage de la loi de comportement de Loi_ortho2D_C_entrainee **");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// type de transport
if (nom == "type_transport_")
{ // lecture du type
*(entreePrinc->entree) >> type_transport;
if ((type_transport!=0)&&(type_transport!=1))
{ cout << "\n le type de transport lue pour la loi de Loi_ortho2D_C_entrainee: "<< type_transport
<< " n'est pas acceptable (uniquement 0 ou 1), on utilise le type par defaut (0)"
<< " qui correspond a un transport de type contravariant ";
type_transport = 0;
};
}
// forcer un affichage particulier pour les méthodes
else if (nom == "permet_affichage_")
{Lecture_permet_affichage(entreePrinc,lesFonctionsnD);
}
// on regarde si le calcul est éventuellement uniquement déviatorique
else if (nom == "seule_deviatorique")
{if (cas_calcul == 2) {cas_calcul=0;} else {cas_calcul = 1;};}
// idem pour la partie sphérique
else if (nom == "seule_spherique")
{if (cas_calcul == 1) {cas_calcul=0;} else {cas_calcul = 2;};}
// cas de la vérification de la convexité
else if (nom == "verification_convexite_")
{*(entreePrinc->entree) >> verification_convexite;
}
// forcer un stockage pour des sorties
else if (nom == "sortie_post_")
{*(entreePrinc->entree) >> sortie_post;
}
// sinon ce n'est pas un mot clé connu, on le signale
else if (nom != "fin_parametres_reglage_")
{ cout << "\n erreur en lecture d'un parametre, le mot cle est inconnu "
<< " on a lu : " << nom << endl;
if (ParaGlob::NiveauImpression()>3)
cout << "\n Loi_ortho2D_C_entrainee::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ;
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
}; //-- fin du while
}; //-- fin de la lecture des paramètres de réglage
// appel au niveau de la classe mère
Loi_comp_abstraite::Lecture_type_deformation_et_niveau_commentaire
(*entreePrinc,lesFonctionsnD);
// dans le cas particulier où il n'y a pas de fonction nD on peut calculer inv_loi
if (null_fct_para)
{// on vérifie la convexité
if (verification_convexite)
Verif_convexite();
// on commence par remplir la matrice
inv_loi(1,1) = 1./E1;inv_loi(2,2) = 1./E2;
inv_loi(1,2) = inv_loi(2,1) = -nu12/E1;
inv_loi = inv_loi.Inverse(); // on inverse la matrice
};
};
// affichage de la loi
void Loi_ortho2D_C_entrainee::Affiche() const
{ // pour faire une boucle on constitue un tableau de mots clés
Tableau tab_mot_cle(7);
tab_mot_cle(1) = "E1";tab_mot_cle(2) = "E2";tab_mot_cle(3) = "E3";
tab_mot_cle(4) = "nu12";tab_mot_cle(5) = "nu13";tab_mot_cle(6) = "nu23";
tab_mot_cle(7) = "G12";
// puis un tableau pour les valeurs
Tableau < const double * > coef(7);
coef(1) = &E1; coef(2) = & E2;coef(3) = &E3;
coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23;
coef(7) = & G12;
// on boucle sur les 7 coefficients
cout << "\n loi de comportement orthotrope elastique 2D CP ";
for (int i=1;i< 8;i++)
{string mot_cle1=tab_mot_cle(i)+"= ";
string mot_cle2=tab_mot_cle(i)+"_fonction_nD:";
cout << mot_cle1 ;
if (fct_para(i) == NULL)
cout << *coef(i) << " ";
else
{cout << mot_cle2 << " ";
if (fct_para(i)->NomFonction() != "_")
cout << fct_para(i)->NomFonction();
else
fct_para(i)->Affiche();
cout << "\n";
};
};
// le nom du repère associé
cout << "\n nom_repere_associe " << nom_repere;
// indicateur de cas de calcul
if (cas_calcul != 0)
{ if (cas_calcul == 1)
{cout << "\n calcul uniquement deviatorique ";}
else if (cas_calcul == 2)
{cout << " calcul uniquement spherique ";}
else
{cout << " cas de calcul mal defini !! ";};
};
// affichage du type de transport
cout << " type_transport: " << type_transport;
// niveau d'affichage
cout << " niveau_affichage_local: ";
Affiche_niveau_affichage();
cout << " verification_convexite: "<< verification_convexite;
cout << " sortie_post: "<< sortie_post;
cout << endl;
// appel de la classe mère
Loi_comp_abstraite::Affiche_don_classe_abstraite();
};
// affichage et definition interactive des commandes particulières à chaques lois
void Loi_ortho2D_C_entrainee::Info_commande_LoisDeComp(UtilLecture& entreePrinc)
{ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier
cout << "\n definition standart (rep o) ou exemples exhaustifs (rep n'importe quoi) ? ";
string rep = "_";
// procédure de lecture avec prise en charge d'un retour chariot
rep = lect_return_defaut(true,"o");
// pour faire une boucle on constitue un tableau de mots clés
Tableau tab_mot_cle(7);
tab_mot_cle(1) = "E1";tab_mot_cle(2) = "E2";tab_mot_cle(3) = "E3";
tab_mot_cle(4) = "nu12";tab_mot_cle(5) = "nu13";tab_mot_cle(6) = "nu23";
tab_mot_cle(7) = "G12";
// puis un tableau pour les valeurs
Tableau < double * > coef(7);
coef(1) = &E1; coef(2) = & E2;coef(3) = &E3;
coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23;
coef(7) = & G12;
E1=100000; E2= 50000;E3= 20000;
nu12= 0.2; nu13 = 0.3; nu23 = 0.1;
G12 = 20000;
sort << "\n# ....... loi de comportement orthotrope elastique 2D contrainte plane........"
<< "\n# 7 parametres materiau: 3 modules, 3 coef de Poisson, 1 module de cisaillement "
<< "\n# et un nom de repere associe ";
for (int i=1;i< 8;i++)
{string mot_cle1=tab_mot_cle(i)+"= ";
string mot_cle2=tab_mot_cle(i)+"_fonction_nD:";
sort << mot_cle1 << setprecision(6) << *coef(i) << " ";
};
sort << "\n nom_repere_associe_ repere1 ";
sort << endl;
// cas avec plus d'information
if ((rep != "o") && (rep != "O" ) && (rep != "0") )
{ // cas d'une loi thermo dépendante
sort << "\n# .... infos complementaires ...."
<<"\n# 1) Pour chaque parametre materiau, individuellement, il est possible "
<<"\n# d'utiliser une fonction nD a la place d'une valeur numerique. "
<<"\n# La fonction nD peut alors dependre de toutes les grandeurs disponibles "
<<"\n# localement, en particulier la position, les donnees imposees par l'utilisateur "
<<"\n# par exe: une temperature, ou tout ddl obtenu directement ou par interpolation "
<<"\n# suivant sa disponibilite, sachant que l'on regarde d'abord si la grandeur est "
<<"\n# directement disponible au point d'integration, sinon on regarde si elle est "
<<"\n# disponible par interpolation. "
<<"\n# "
<<"\n# Supposons que l'on veuille que E2 soit une fonction nD on ecrira: "
<<"\n# soit a: "
<<"\n# E2= E2_fonction_nD: un_nom_de_fonction_existant "
<<"\n# soit b: "
<<"\n# E2= E2_fonction_nD: un_nom_de_type_de_fonction_existant "
<<"\n# suivit sur la ligne suivante de la definition specifique de la fonction "
<<"\n# "
<<"\n# exemple d'un cas a: "
<<"\n# E2= E2_fonction_nD: f1_temperature "
<<"\n# fi_temperature doit alors avoir ete definie dans les fonctions nD"
<<"\n# "
<<"\n# exemple d'un cas b: "
<<"\n# E2= E2_fonction_nD: FONCTION_EXPRESSION_LITTERALE_nD "
<<"\n# deb_list_var_ TEMP fin_list_var_ "
<<"\n# fct= (100726-101325)/50*TEMP + 101325 "
<<"\n# fin_parametres_fonction_expression_litterale_ "
<<"\n# "
<<"\n# Remarques: "
<<"\n# a) apres chaque definition d'une fonction nD on change de ligne "
<<"\n# b) pour les autres coefficients, on remplace E2 par E1, ou"
<<"\n# nu12 ou nu13 ou n23 ou G12 "
<<"\n# "
<<"\n# 2) Par defaut, la base initiale d'orthotropie est transportee dans l'etat courant "
<<"\n# via une methode de type transport contravariant (cf. doc) "
<<"\n# Il est possible d'indiquer un transport de type covariant. Pour ce faire "
<<"\n# on utilise le mot cle: type_transport_ suivi de 0 ou 1 "
<<"\n# 0 : pour un transport de type contravariant (valeur par defaut) "
<<"\n# 1 : pour un transport de type covariant "
<<"\n# "
<<"\n# 3)"
<< "\n# -------------- affichage des erreurs et des warning ---------- "
<< "\n# - l'affichage normale est fonction du parametre global d'affichage gerer"
<< "\n# par le niveau d'affichage cependant pour des raisons par exemple de mise au point,"
<< "\n# il est possible de permettre l'affichage a un niveau particulier "
<< "\n# (mot cle : permet_affichage_ suivi d'un nombre entier) en plus de l'affichage normal. "
<< "\n# l'affichage s'effectuera donc en fonction de l'affichage normale et de l'affichage particulier."
<< "\n# Le fonctionnement de l'affichage particulier suit les mêmes règles que l'affichage globale"
<< "\n# soit permet_affichage_ est nulle (cas par defaut), dans ce cas l'affichage est fonction du niveau global"
<< "\n# soit permet_affichage_ vaut n par exemple, dans ce cas l'affichage est fonction uniquement de n "
<< "\n# "
<< "\n# ex: permet_affichage_ 5 "
<< "\n# "
<<"\n# "
<<"\n# 4) Il est possible de calculer que la partie spherique du tenseur de contrainte "
<<"\n# ou que la partie deviatorique "
<<"\n# Pour ce faire on indique a la suite des autres parametres:"
<<"\n# soit le mot clef : seule_deviatorique "
<<"\n# soit le mot clef : seule_spherique "
<<"\n# "
<<"\n# 4) Par defaut, on verifie la convexite du potentiel (cf. theorie) "
<<"\n# mais le calcul ne s'arrete pas si le potentiel n'est pas convexe,"
<<"\n# il y a seulement un message d'erreur"
<<"\n# "
<<"\n# on peut supprimer cette verification a l'aide du mote cle "
<<"\n# verification_convexite_ "
<<"\n# suivi de 0 ou 1 (val par defaut) suivant que l'on ne veut pas de verification "
<<"\n# ou le contraire "
<<"\n# "
<< "\n# 5) --------------- acces en sortie a des grandeurs intermediaires de calcul -------"
<< "\n# A chaque resolution, il est possible de stocker: "
<< "\n# - le tenseur des contraintes exprime dans le repere d'anisotropie "
<< "\n# - le tenseur des deformation exprime dans le repere d'anisotropie "
<< "\n# - les parametres d'orthotropie entrainee: interessant s'ils varient "
<< "\n# le mot cle est sortie_post_ , par defaut il vaut 0, dans ce cas aucun indicateur n'est stoke"
<< "\n# s'il est different de 0, on peut acceder aux grandeurs "
<< "\n# seules les grandeurs en cours sont disponibles, il n'y a pas de stockage sur plusieurs increment "
<< "\n# "
<< "\n# ex: sortie_post_ 1 "
<< "\n# "
<<"\n# "
;
};
// appel de la classe mère
Loi_comp_abstraite::Info_commande_don_LoisDeComp(entreePrinc);
};
// test si la loi est complete
int Loi_ortho2D_C_entrainee::TestComplet()
{ int ret = LoiAbstraiteGeneral::TestComplet();
// pour faire une boucle on constitue un tableau de mots clés
Tableau tab_mot_cle(7);
tab_mot_cle(1) = "E1";tab_mot_cle(2) = "E2";tab_mot_cle(3) = "E3";
tab_mot_cle(4) = "nu12";tab_mot_cle(5) = "nu13";tab_mot_cle(6) = "nu23";
tab_mot_cle(7) = "G12";
// puis un tableau pour les valeurs
Tableau < double * > coef(7);
coef(1) = &E1; coef(2) = & E2;coef(3) = &E3;
coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23;
coef(7) = & G12;
for (int i=1;i< 8;i++)
if ((*coef(i) == -ConstMath::trespetit) && (fct_para(i) == NULL))
{string mot_cle1=tab_mot_cle(i)+"= ";
cout << mot_cle1 << " n'est pas defini \n " ;
ret = 0;
};
// test du cas de calcul
if ((cas_calcul < 0) || (cas_calcul > 2))
{ cout << "\n l'indicateur de calcul cas_calcul= " << cas_calcul << " n'est pas correcte "
<< "\n ceci pour la Loi_ortho2D_C_entrainee";
ret = 0;
};
// le nom du repère associé
if (nom_repere.length() == 0)
{ cout << "\n le nom du repere assoce n'est pas defini "
<< "\n ceci pour la Loi_ortho2D_C_entrainee";
ret = 0;
};
// info globale disponible actuellement
if (!ret)
{ cout << "\n loi ortho elastique incomplete : ";
Affiche();
};
// retour
return ret;
};
// récupération des grandeurs particulière (hors ddl )
// correspondant à liTQ
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
void Loi_ortho2D_C_entrainee::Grandeur_particuliere
(bool ,List_io& liTQ,Loi_comp_abstraite::SaveResul * saveDon,list& decal) const
{ // ici on est en 2D et les grandeurs sont par principe en locale, donc la variable absolue ne sert pas
// on passe en revue la liste
List_io::iterator itq,itqfin=liTQ.end();
list::iterator idecal=decal.begin();
for (itq=liTQ.begin();itq!=itqfin;itq++,idecal++)
{TypeQuelconque& tipParticu = (*itq); // pour simplifier
if (tipParticu.EnuTypeQuelconque().Nom_vide()) // veut dire que c'est un enum pur
switch (tipParticu.EnuTypeQuelconque().EnumTQ())
{
// -----cas de la déformation d'épaisseur à t
case DEF_EPAISSEUR:
{SaveResulLoi_ortho2D_C_entrainee & save_resul = *((SaveResulLoi_ortho2D_C_entrainee*) saveDon);Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
tyTQ(1+(*idecal)) = save_resul.eps33;
break;
};
case REPERE_D_ANISOTROPIE:
// a) ----- cas du repère d'anisotropie
{ SaveResulLoi_ortho2D_C_entrainee & save_resul = *((SaveResulLoi_ortho2D_C_entrainee*) saveDon);
Tab_Grandeur_BaseH& tyTQ= *((Tab_Grandeur_BaseH*) (*itq).Grandeur_pointee()); // pour simplifier
tyTQ(1+(*idecal))=save_resul.Op_H;
//////----- debug
//cout << "\n debug Loi_ortho2D_C_entrainee::Grandeur_particuliere(.. "
// << "\n save_resul.Op_H: "<< save_resul.Op_H << "\n ";
//Signature_pti_encours(cout);
//
//////----- fin debug
(*idecal)++; break;
}
case EPS_TRANSPORTEE_ANISO:
// ----- cas de la déformation transportée dans le repère d'orthotropie
{ SaveResulLoi_ortho2D_C_entrainee & save_resul = *((SaveResulLoi_ortho2D_C_entrainee*) saveDon);
Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier
if (sortie_post) {tyTQ(1+(*idecal))= *(save_resul.eps_loc_HH);}
else {tyTQ(1+(*idecal)).Inita(0.);};
(*idecal)++; break;
}
case SIGMA_DANS_ANISO:
// ----- cas de la contrainte calculée dans le repère d'orthotropie
{ SaveResulLoi_ortho2D_C_entrainee & save_resul = *((SaveResulLoi_ortho2D_C_entrainee*) saveDon);
Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier
if (sortie_post) {tyTQ(1+(*idecal))= *(save_resul.sig_loc_HH);}
else {tyTQ(1+(*idecal)).Inita(0.);};
(*idecal)++; break;
}
case PARA_ORTHO:
// ----- cas des paramètres d'orthotropie
{ SaveResulLoi_ortho2D_C_entrainee & save_resul = *((SaveResulLoi_ortho2D_C_entrainee*) saveDon);
Tab_Grandeur_Vecteur& tyTQ= *((Tab_Grandeur_Vecteur*) (*itq).Grandeur_pointee()); // pour simplifier
if (sortie_post) {tyTQ(1+(*idecal))= *(save_resul.para_loi);}
else {tyTQ(1+(*idecal)).Zero();};
(*idecal)++; break;
}
default: ;// on ne fait rien
};
};
};
// récupération et création de la liste de tous les grandeurs particulières
// ces grandeurs sont ajoutées à la liste passées en paramètres
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
void Loi_ortho2D_C_entrainee::ListeGrandeurs_particulieres(bool absolue,List_io& liTQ) const
{
// pour le stockage
Tableau tab_double(1);
Tab_Grandeur_scalaire_double grand_courant(tab_double); // $$$ cas du repère local d'orthotropie
int dim_espace = ParaGlob::Dimension();
{List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == REPERE_D_ANISOTROPIE)
{ Tab_Grandeur_BaseH& tyTQ= *((Tab_Grandeur_BaseH*) (*itq).Grandeur_pointee()); // pour simplifier
int taille = tyTQ.Taille()+1;
tyTQ.Change_taille(taille); nexistePas = false;
};
if (nexistePas)
{Grandeur_BaseH v_rep(dim_espace,2);
Tab_Grandeur_BaseH grand5(v_rep,1); // def d'une grandeur courante
TypeQuelconque typQ6(REPERE_D_ANISOTROPIE,EPS11,grand5);
liTQ.push_back(typQ6);
};
};
// -----cas de la déformation d'épaisseur à t uniquement
//on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée
{List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == DEF_EPAISSEUR)
{ Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
int taille = tyTQ.Taille()+1;
tyTQ.Change_taille(taille); nexistePas = false;
};
if (nexistePas)
{TypeQuelconque typQ1(DEF_EPAISSEUR,EPS11,grand_courant);
liTQ.push_back(typQ1);
};
};
// ---- la suite dépend de l'indicateur : sortie_post
if (sortie_post)
{ // $$$ cas de la déformation transportée dans le repère d'orthotropie
{List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == EPS_TRANSPORTEE_ANISO)
{Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier
int taille = tyTQ.Taille()+1;
tyTQ.Change_taille(taille); nexistePas = false;
};
if (nexistePas)
{TenseurHH* tens = NevezTenseurHH(2); // un tenseur typique
Tab_Grandeur_TenseurHH eps_loc_HH(*tens,1);
// def d'un type quelconque représentatif
TypeQuelconque typQ(EPS_TRANSPORTEE_ANISO,EPS11,eps_loc_HH);
liTQ.push_back(typQ);
delete tens; // car on n'en a plus besoin
};
};
// $$$ cas de la contrainte calculée dans le repère d'orthotropie
{List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == SIGMA_DANS_ANISO)
{Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier
int taille = tyTQ.Taille()+1;
tyTQ.Change_taille(taille); nexistePas = false;
};
if (nexistePas)
{TenseurHH* tens = NevezTenseurHH(2); // un tenseur typique
Tab_Grandeur_TenseurHH eps_loc_HH(*tens,1);
// def d'un type quelconque représentatif
TypeQuelconque typQ(SIGMA_DANS_ANISO,SIG11,eps_loc_HH);
liTQ.push_back(typQ);
delete tens; // car on n'en a plus besoin
};
};
// $$$ cas des paramètres de la loi de comportement
{List_io::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == PARA_ORTHO)
{Tab_Grandeur_Vecteur& tyTQ= *((Tab_Grandeur_Vecteur*) (*itq).Grandeur_pointee()); // pour simplifier
int taille = tyTQ.Taille()+1;
tyTQ.Change_taille(taille); nexistePas = false;
};
if (nexistePas)
{Vecteur tens(7); // les 7 paramètres
Tab_Grandeur_Vecteur gr_vec_para(tens,1);
// def d'un type quelconque représentatif
TypeQuelconque typQ(PARA_ORTHO,EPS11,gr_vec_para);
liTQ.push_back(typQ);
};
};
}; // fin du cas ou sortie_post est actif, c-a-d que l'on veut des infos sur les indicateurs
// de résolution
};
//----- lecture écriture de restart -----
// cas donne le niveau de la récupération
// = 1 : on récupère tout
// = 2 : on récupère uniquement les données variables (supposées comme telles)
void Loi_ortho2D_C_entrainee::Lecture_base_info_loi(istream& ent,const int cas,LesReferences& lesRef,LesCourbes1D& lesCourbes1D
,LesFonctions_nD& lesFonctionsnD)
{ string toto,nom;
if (cas == 1)
{ ent >> nom ;
if (nom != "ORTHOELA2D_C")
{cout <<"\n *** erreur en lecture du type de la loi de comportement, on attendait"
<< " la chaine de caracteres: ORTHOELA2D_C et on a lu "
<< nom <<" !!! on ne peut pas continuer "
<< "\n Loi_ortho2D_C_entrainee::Lecture_base_info_loi(.. "
<< flush;
Sortie(1);
};
// pour faire une boucle on constitue un tableau de mots clés
Tableau tab_mot_cle(7);
tab_mot_cle(1) = "E1";tab_mot_cle(2) = "E2";tab_mot_cle(3) = "E3";
tab_mot_cle(4) = "nu12";tab_mot_cle(5) = "nu13";tab_mot_cle(6) = "nu23";
tab_mot_cle(7) = "G12";
// puis un tableau pour les valeurs
Tableau < double * > coef(7);
coef(1) = &E1; coef(2) = & E2; coef(3) = &E3;
coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23;
coef(7) = & G12;
// cela va permettre de choisir entre une valeur fixe et une fonction nD
for (int i=1;i< 8;i++)
{ ent >> toto >> nom;
string mot_cle2=tab_mot_cle(i)+"_fonction_nD:";
if (nom == mot_cle2)
// cas d'une fonction nD
{fct_para(i) = lesFonctionsnD.Lecture_pour_base_info(ent,cas,fct_para(i));
}
else // cas d'une valeur fixe
{(*coef(i)) = ChangeReel(nom);};
};
// lecture du repère associé
ent >> nom >> nom_repere;
// indicateur pour les calculs partielles
ent >> nom >> cas_calcul ;
// le type de transport
ent >> nom >> type_transport;
// le niveau d'affichage
Lecture_permet_affichage(ent,cas,lesFonctionsnD);
// sortie_post
ent >> nom >> sortie_post;
};
// appel de la classe mère
Loi_comp_abstraite::Lecture_don_base_info(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD);
};
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void Loi_ortho2D_C_entrainee::Ecriture_base_info_loi(ostream& sort,const int cas)
{ if (cas == 1)
{ sort << " ORTHOELA2D_C " ;
// pour faire une boucle on constitue un tableau de mots clés
Tableau tab_mot_cle(7);
tab_mot_cle(1) = "E1";tab_mot_cle(2) = "E2";tab_mot_cle(3) = "E3";
tab_mot_cle(4) = "nu12";tab_mot_cle(5) = "nu13";tab_mot_cle(6) = "nu23";
tab_mot_cle(7) = "G12";
// puis un tableau pour les valeurs
Tableau < double * > coef(7);
coef(1) = &E1; coef(2) = & E2; coef(3) = &E3;
coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23;
coef(7) = & G12;
// on boucle sur les 7 coefficients
sort << "\n loi de comportement orthotrope elastique 2D contrainte plane";
for (int i=1;i< 8;i++)
{string mot_cle1=tab_mot_cle(i)+"= ";
string mot_cle2=tab_mot_cle(i)+"_fonction_nD:";
sort << mot_cle1 ;
if (fct_para(i) == NULL)
sort << *coef(i) << " ";
else
{sort << mot_cle2 << " ";
if (fct_para(i)->NomFonction() != "_")
sort << fct_para(i)->NomFonction();
else
fct_para(i)->Affiche();
sort << "\n";
};
};
// le nom du repère associé
sort << "\n nom_repere_associe_ "<< nom_repere;
// indicateur de cas de calcul
if (cas_calcul != 0)
{ if (cas_calcul == 1)
{sort << "\n seul_deviatorique ";}
else if (cas_calcul == 2)
{sort << " seul_spherique ";}
else
{sort << " cas_de_calcul_mal_defini ";};
};
// affichage du type de transport
sort << " type_transport: " << type_transport;
// niveau d'affichage
Affiche_niveau_affichage(sort,cas);
sort << " verification_convexite: "<< verification_convexite;
sort << " sortie_post: "<Valeur(temperature_tdt);
};
*/
cout << "\n *** attention, methode non implante: "
<< "\n Loi_ortho2D_C_entrainee::Module_young_equivalent(...";
Sortie(1);
};
// récupération d'un module de compressibilité équivalent à la loi pour un chargement nul
// il s'agit ici de la relation -pression = sigma_trace/3. = module de compressibilité * I_eps
double Loi_ortho2D_C_entrainee::Module_compressibilite_equivalent(Enum_dure temps,const Deformation & def,SaveResul * )
{/* if (!thermo_dependant)
{ return E/(3.*(1.-2.*nu));}
else
{ temperature_tdt = def.DonneeInterpoleeScalaire(TEMP,temps);
return E_temperature->Valeur(temperature_tdt)/(3.*(1.-2.*nu));
};
*/
cout << "\n *** attention, methode non implante: "
<< "\n Loi_ortho2D_C_entrainee::Module_compressibilite_equivalent(...";
Sortie(1);
};
// ========== codage des METHODES VIRTUELLES protegees:================
// virtual void Calcul_SigmaHH
// (TenseurHH & sigHH_t,TenseurBB& DepsBB,DdlElement & tab_ddl
// ,TenseurBB & gijBB_t,TenseurHH & gijHH_t,BaseB& giB,BaseH& gi_H,TenseurBB & epsBB
// ,TenseurBB & delta_epsBB,TenseurBB & gijBB,TenseurHH & gijHH,Tableau & d_gijBB
// ,double& jacobien_0,double& jacobien,TenseurHH & sigHH
// ,EnergieMeca & energ,const EnergieMeca & energ_t,double& module_compressibilite,double& module_cisaillement
// ,const Met_abstraite::Expli_t_tdt& ex) = 0; // calcul des contraintes a t+dt
void Loi_ortho2D_C_entrainee::Calcul_SigmaHH (TenseurHH& sigHH_t,TenseurBB& ,DdlElement & tab_ddl
,TenseurBB & ,TenseurHH & ,BaseB& ,BaseH& ,TenseurBB& epsBB_
,TenseurBB& ,TenseurBB& gijBB_
,TenseurHH & gijHH_,Tableau & d_gijBB_,double& ,double&
,TenseurHH & sigHH_,EnergieMeca & energ,const EnergieMeca &
,double& module_compressibilite,double& module_cisaillement
,const Met_abstraite::Expli_t_tdt& ex)
{
#ifdef MISE_AU_POINT
if (epsBB_.Dimension() != 2)
{ cout << "\nErreur : la dimension devrait etre 2 !\n";
cout << " Loi_ortho2D_C_entrainee::Calcul_SigmaHH\n";
Sortie(1);
};
#endif
bool affichage = (Permet_affichage() > 5);
#ifdef MISE_AU_POINT
if (affichage)
{cout << "\n --- loi de comportement orthotrope entrainee --- ";
};
#endif
const Tenseur2BB & epsBB = *((Tenseur2BB*) &epsBB_); // passage en dim 2
const Tenseur2HH & gijHH = *((Tenseur2HH*) &gijHH_); // " " " "
const Tenseur2BB & gijBB = *((Tenseur2BB*) &gijBB_); // " " " "
Tenseur2HH & sigHH = *((Tenseur2HH*) &sigHH_); // " " " "
Tenseur2BH epsBH = epsBB * gijHH; // deformation en mixte
int dim = ParaGlob::Dimension(); // pour les affichages de vecteurs
// récup du conteneur spécifique
SaveResulLoi_ortho2D_C_entrainee & save_resul = *((SaveResulLoi_ortho2D_C_entrainee*) saveResul);
// on commence par calculer le repère d'orthotropie transporté
// Op_H_i sont les coordonnées contravariantes de la nouvelle base
// donc par rapport à g_i,
BaseH& Op_H = save_resul.Op_H;
Tableau tab_norme(2);
if (type_transport == 0)
// transport de type contravariant
{ // on calcule les coordonnées de la base O' dans la base naturelle
#ifdef MISE_AU_POINT
if (save_resul.O_H == NULL)
{cout << "\n *** erreur, le repere d'anisotropie n'est pas defini "
<<"on ne peut pas continuer " << flush ;
cout << " Loi_ortho2D_C_entrainee::Calcul_SigmaHH\n";
Sortie(1);
};
#endif
BaseH& O_H = (*save_resul.O_H); // coordonnées en absolu de la base d'orthotropie
// calcul des coordonnées alpha_a^{.i} = O_H(a) * g^i à t= 0
for (int a = 1;a < 3; a++)
{CoordonneeH& inter = alpha_H.CoordoH(a);
for (int i=1;i < 3;i++)
inter(i)= O_H(a).ScalHH((*ex.giH_0)(i));
};
// calcule des beta_a^{.i} tel que O'_a = beta_a^{.i} \hat{g}_i donc au temps t+dt
for (int a=1; a<3;a++)
{ // tout d'abord la base non normalisée
// Op_H(a) non normé a les mêmes coordonnées alpha_a^{.j}
// mais exprimés dans le repère actuel \hat \vec g_j
CoordonneeH& Op_H_a = Op_H.CoordoH(a);
Op_H_a = alpha_H(a);
// calcul de la norme du vecteur Op_H_a
double norme = sqrt(Op_H_a * gijBB * Op_H_a);
tab_norme(a) = norme;
// coordonnées finales
Op_H_a /= norme;
#ifdef MISE_AU_POINT
if (affichage)
{cout << "\n Op_H("< gp_i = beta_i^j * g_j
// calcul des coordonnées de la déformation dans le repère O'^i
#ifdef MISE_AU_POINT
if (affichage)
{ TenseurBB* eps_p_BB = NevezTenseurBB(epsBB);
cout <<"\n eps_p_BB: "; eps_p_BB->Ecriture(cout);
delete eps_p_BB;
};
#endif
// c-a-d les coordonnées dans le dual de O'_i
// il faut passer en 2 fois contravariant
Tenseur2BB eps_p_BB(epsBB);
//cout <<"\n eps_p_BB: "; eps_p_BB.Ecriture(cout);
// il faut passer en 2 fois contravariant
// on utilise l'opérateur d'affectation, car le résultat doit-être symétrique, or
// les multiplications intermédiaires vont générer un tenseur systématiquement non symétrique
Tenseur2HH eps_p_HH = gijHH * eps_p_BB * gijHH;
eps_p_HH.ChBase(gamma); // res = (gamma * res) * gamma.Transpose();
#ifdef MISE_AU_POINT
if (affichage)
{ cout <<"\n eps_p_HH: "; eps_p_HH.Ecriture(cout);
TenseurHH* toto = NevezTenseurHH(eps_p_HH);
toto->ChBase(beta_transpose);
cout << "\n retour dans la base g^i de eps^{ij} :";toto->Ecriture(cout);
TenseurBB* titi = NevezTenseurBB(gijBB * (*toto) * gijBB);
cout << "\n def eps_ij :";titi->Ecriture(cout);
delete toto; delete titi;
};
#endif
double untiers = 1./3.;
// dans le cas de fonctions nD récupération des valeurs
if (!null_fct_para)
// Tableau fct_para; // fonction nD éventuelle d'évolution des paramètres
{// un tableau de travail pour les valeurs sous forme indicée
Tableau < double * > coef(7);
coef(1) = &E1; coef(2) = & E2;coef(3) = &E3;
coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23;
coef(7) = & G12;
// opération de transmission de la métrique
const Met_abstraite::Impli* ex_impli = NULL;
const Met_abstraite::Expli_t_tdt* ex_expli_tdt = &ex;
const Met_abstraite::Umat_cont* ex_expli = NULL;
// on passe en revue les fonctions nD
for (int i=1;i< 8;i++)
{if (fct_para(i) != NULL)
{ Fonction_nD* pt_fonct = fct_para(i); // pour simplifier
// on utilise la méthode générique de loi abstraite
Tableau & tab_val = Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(pt_fonct,1 // une seule valeur attendue en retour
,ex_impli,ex_expli_tdt,ex_expli
,NULL
,NULL
,NULL
);
/* // ici on utilise les variables connues aux pti, ou calculées à partir de
// on commence par récupérer les conteneurs des grandeurs à fournir
List_io & li_enu_scal = pt_fonct->Li_enu_etendu_scalaire();
List_io & li_quelc = pt_fonct->Li_equi_Quel_evolue();
bool absolue = true; // on se place systématiquement en absolu
// on va utiliser la méhode Valeur_multi_interpoler_ou_calculer
// pour les grandeurs strictement scalaire
Tableau val_ddl_enum(Valeur_multi_interpoler_ou_calculer
(absolue,TEMPS_tdt,li_enu_scal,ex_impli,ex_expli_tdt,ex_expli,NULL)
);
// on utilise la méthode Valeurs_Tensorielles_interpoler_ou_calculer
// pour les Coordonnees et Tenseur
Valeurs_Tensorielles_interpoler_ou_calculer
(absolue,TEMPS_tdt,li_quelc,ex_impli,ex_expli_tdt,ex_expli,NULL);
// calcul de la valeur et retour dans tab_ret
Tableau & tab_val = pt_fonct->Valeur_FnD_Evoluee(&val_ddl_enum,&li_enu_scal,&li_quelc,NULL,NULL);
#ifdef MISE_AU_POINT
if (tab_val.Taille() != 1)
{ cout << "\nErreur : la fonction nD relative au parametre materiau " << i
<< " doit calculer un scalaire or le tableau de retour est de taille "
<< tab_val.Taille() << " ce n'est pas normal !\n";
cout << " Loi_ortho2D_C_entrainee::Calcul_SigmaHH\n";
Sortie(1);
};
#endif
*/
// on récupère le premier élément du tableau uniquement
(*coef(i)) = tab_val(1);
};
};
};
// puis fabrication de la matrice inv_loi
{// on commence par remplir la matrice
inv_loi(1,1) = 1./E1;inv_loi(2,2) = 1./E2;
inv_loi(1,2) = inv_loi(2,1) = -nu12/E1;
inv_loi = inv_loi.Inverse(); // on inverse la matrice
};
// on vérifie éventuellement la convexité
if (verification_convexite)
Verif_convexite();
// calcul des contraintes dans le repère O_p
Vecteur eps_ii(2);Vecteur sig_ii(2);
for (int i=1; i<3;i++)
eps_ii(i) = eps_p_HH(i,i);
sig_ii = inv_loi * eps_ii;
// Tenseur2HH sig_HH;
for (int i=1; i<3;i++)
{sigHH.Coor(i,i) = sig_ii(i);
};
sigHH.Coor(1,2) = 2.* G12 * eps_p_HH(1,2);
// dans le cas où on veut une sortie des grandeurs on sauvegarde
if (sortie_post)
{ if (save_resul.eps_loc_HH == NULL)
{save_resul.eps_loc_HH = NevezTenseurHH(2);
save_resul.sig_loc_HH = NevezTenseurHH(2);
save_resul.para_loi = new Vecteur (7);
};
(*save_resul.eps_loc_HH) = eps_p_HH;
(*save_resul.sig_loc_HH) = sigHH;
// paramètres de la loi
(*save_resul.para_loi)(1) = E1; (*save_resul.para_loi)(2) = E2;
(*save_resul.para_loi)(3) = E3;
(*save_resul.para_loi)(4) = nu12; (*save_resul.para_loi)(5) = nu13;
(*save_resul.para_loi)(6) = nu23;
(*save_resul.para_loi)(7) = G12;
};
// calcul des contraintes dans le repère g_i
// l'inverse de gamma c'est beta transposée
sigHH.ChBase(beta_transpose);
// beta_inv = beta.Inverse();
// sig_BB.ChBase(beta_inv);
// passage dans la bonne variance
Tenseur2BH sigBH = gijBB * sigHH ;
switch (cas_calcul)
{ case 0: // calcul normal (tous les termes)
{ // on ne fait rien de spécial
break;
}
case 1: // calcul de la partie déviatorique seule
{ double trace_sig = sigBH.Trace();
sigBH -= (untiers * trace_sig) * IdBH2;
sigHH -= (untiers * trace_sig) * gijHH;
break;
}
case 2: // calcul de la partie sphérique seule
{ double trace_sig = sigBH.Trace();
sigBH = (untiers * trace_sig) * IdBH2;
sigHH = (untiers * trace_sig) * gijHH;
break;
}
default:
{ cout << "\n erreur l'indicateur cas_calcul= " << cas_calcul << " n'a pas une valeur correcte !! "
<< "\n Loi_ortho2D_C_entrainee::Calcul_SigmaHH (.... ";
Sortie(1);
}
};
#ifdef MISE_AU_POINT
if (affichage)
{ cout << "\n epsBB="< ConstMath::petit)
{module_compressibilite = untiers * sigBH.Trace() / (log_var_vol);}
else // si la variation de volume est trop faible on passe par la moyenne
// des compressibilités dans les 2 directions d'orthotropie (cf. théorie)
{double unsurKs1 = 1./E1 - nu12/E1 -nu13/E1;
double unsurKs2 = -nu12/E1+1./E2-nu23/E2;
double unsurKs3 = -nu13/E1-nu23/E2+1./E3;
module_compressibilite = untiers * untiers * (1./unsurKs1+1./unsurKs2+1./unsurKs3);
};
}
else
// dans le cas d'une loi purement déviatorique, le module de compressibilité = 0 (approximativement)
{module_compressibilite = 0.;};
#ifdef MISE_AU_POINT
if (Permet_affichage() > 4)
{ cout << "\n var_vol="<<((*(ex.jacobien_tdt))/(*(ex.jacobien_0))*var_epai)
<< " log_var_vol= " << log_var_vol
<< " sigBH.Trace()= " << sigBH.Trace()
<< " module_compressibilite= " << module_compressibilite
<< flush ;
if (Permet_affichage() > 5) cout << "\n cas_calcul= " << cas_calcul;
};
#endif
// pour la partie cisaillement on garde la forme associée à la loi
if ((cas_calcul == 0) || (cas_calcul == 1))
{module_cisaillement = 2. * (G12);}
else
// en purement sphérique, le module est supposé nul
{module_cisaillement = 0.; };
LibereTenseur();
};
// calcul des contraintes a t+dt et de ses variations
// void Calcul_DsigmaHH_tdt (TenseurHH & sigHH_t,TenseurBB& DepsBB,DdlElement & tab_ddl
// ,BaseB& giB_t,TenseurBB & gijBB_t,TenseurHH & gijHH_t
// ,BaseB& giB_tdt,Tableau & d_giB_tdt,BaseH& giH_tdt,Tableau & d_giH_tdt
// ,TenseurBB & epsBB_tdt,Tableau & d_epsBB
// ,TenseurBB & delta_epsBB,TenseurBB & gijBB_tdt,TenseurHH & gijHH_tdt
// ,Tableau & d_gijBB_tdt
// ,Tableau & d_gijHH_tdt,double& jacobien_0,double& jacobien
// ,Vecteur& d_jacobien_tdt,TenseurHH& sigHH,Tableau & d_sigHH
// ,EnergieMeca & energ,const EnergieMeca & energ_t,double& module_compressibilite,double& module_cisaillement
// ,const Met_abstraite::Impli& ex);
void Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt (TenseurHH& ,TenseurBB& ,DdlElement & tab_ddl
,BaseB& ,TenseurBB & ,TenseurHH &
,BaseB& ,Tableau & ,BaseH& ,Tableau &
,TenseurBB & epsBB_tdt,Tableau & d_epsBB
,TenseurBB & delta_epsBB,TenseurBB & gijBB_tdt,TenseurHH & gijHH_tdt
,Tableau & d_gijBB_tdt
,Tableau & d_gijHH_tdt,double& ,double&
,Vecteur& ,TenseurHH& sigHH_tdt,Tableau & d_sigHH
,EnergieMeca & energ,const EnergieMeca &
,double& module_compressibilite,double& module_cisaillement
,const Met_abstraite::Impli& ex)
{
#ifdef MISE_AU_POINT
if (epsBB_tdt.Dimension() != 2)
{ cout << "\nErreur : la dimension devrait etre 2 !\n";
cout << " Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt\n";
Sortie(1);
};
if (tab_ddl.NbDdl() != d_gijBB_tdt.Taille())
{ cout << "\nErreur : le nb de ddl est != de la taille de d_gijBB_tdt !\n";
cout << " Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt\n";
Sortie(1);
};
#endif
bool affichage = (Permet_affichage() > 5);
#ifdef MISE_AU_POINT
if (affichage)
{cout << "\n --- loi de comportement orthotrope entrainee --- ";
};
#endif
const Tenseur2BB & epsBB = *((Tenseur2BB*) &epsBB_tdt); // passage en dim 2
const Tenseur2HH & gijHH = *((Tenseur2HH*) &gijHH_tdt); // " " " "
Tenseur2HH & sigHH = *((Tenseur2HH*) &sigHH_tdt); // " " " "
const Tenseur2BB & gijBB = *((Tenseur2BB*) &gijBB_tdt); // " " " "
Tenseur2BH epsBH = epsBB * gijHH; // deformation en mixte
Tenseur2HH epsHH = gijHH * epsBH; // en deuxfois contra
int dim = ParaGlob::Dimension(); // pour les affichages de vecteurs
// récup du conteneur spécifique
SaveResulLoi_ortho2D_C_entrainee & save_resul = *((SaveResulLoi_ortho2D_C_entrainee*) saveResul);
// on commence par calculer le repère d'orthotropie transporté
// Op_H_i sont les coordonnées contravariantes de la nouvelle base
// donc par rapport à g_i,
BaseH& Op_H = save_resul.Op_H;
Tableau tab_norme(2);
if (type_transport == 0)
// transport de type contravariant
{ // on calcule les coordonnées de la base O' dans la base naturelle
#ifdef MISE_AU_POINT
if (save_resul.O_H == NULL)
{cout << "\n *** erreur, le repere d'anisotropie n'est pas defini "
<<"on ne peut pas continuer " << flush ;
cout << " Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt\n";
Sortie(1);
};
#endif
BaseH& O_H = (*save_resul.O_H); // coordonnées en absolu de la base d'orthotropie
// calcul des coordonnées alpha_a^{.i} = O_H(a) * g^i à t= 0
for (int a = 1;a < 3; a++)
{CoordonneeH& inter = alpha_H.CoordoH(a);
for (int i=1;i < 3;i++)
inter(i)= O_H(a).ScalHH((*ex.giH_0)(i));
};
// calcule des beta_a^{.i} tel que O'_a = beta_a^{.i} \hat{g}_i donc au temps t+dt
for (int a=1; a<3;a++)
{ // tout d'abord la base non normalisée
// Op_H(a) non normé a les mêmes coordonnées alpha_a^{.j}
// mais exprimés dans le repère actuel \hat \vec g_j
CoordonneeH& Op_H_a = Op_H.CoordoH(a); // pour simplifier
Op_H_a = alpha_H(a);
// calcul de la norme du vecteur Op_H_a
double norme = sqrt(Op_H_a * gijBB * Op_H_a);
tab_norme(a) = norme;
// coordonnées finales
Op_H_a /= norme;
#ifdef MISE_AU_POINT
if (affichage)
{cout << "\n Op_H("< gp_i = beta_i^j * g_j
// calcul des coordonnées de la déformation dans le repère O'_i
#ifdef MISE_AU_POINT
if (affichage)
{// Tenseur2BB eps_p_BB(epsBB);
cout <<"\n eps_p_BB en g^i: "; epsBB.Ecriture(cout);
Tenseur2BB tiutiu;
epsBB.BaseAbsolue(tiutiu,*(ex.giH_tdt));
cout << "\n eps en absolu :";tiutiu.Ecriture(cout);
};
#endif
// il faut passer en 2 fois contravariant
Tenseur2HH eps_p_HH(epsHH); // init
#ifdef MISE_AU_POINT
if (affichage)
{cout <<"\n eps_p_HH en g_i: "; eps_p_HH.Ecriture(cout);
};
#endif
eps_p_HH.ChBase(gamma); // res = (gamma * res) * gamma.Transpose();
#ifdef MISE_AU_POINT
if (affichage)
{ cout <<"\n eps_p_HH: "; eps_p_HH.Ecriture(cout);
TenseurHH* toto = NevezTenseurHH(eps_p_HH);
toto->ChBase(beta_transpose);
cout << "\n retour dans la base g^i de eps^{ij} :";toto->Ecriture(cout);
TenseurBB* titi = NevezTenseurBB(gijBB * (*toto) * gijBB);
cout << "\n def eps_ij :";titi->Ecriture(cout);
delete toto; delete titi;
};
#endif
double untiers = 1./3.;
// dans le cas de fonctions nD récupération des valeurs
if (!null_fct_para)
// Tableau fct_para; // fonction nD éventuelle d'évolution des paramètres
{// un tableau de travail pour les valeurs sous forme indicée
Tableau < double * > coef(7);
coef(1) = &E1; coef(2) = & E2;coef(3) = &E3;
coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23;
coef(7) = & G12;
// opération de transmission de la métrique
const Met_abstraite::Impli* ex_impli = &ex;
const Met_abstraite::Expli_t_tdt* ex_expli_tdt = NULL;
const Met_abstraite::Umat_cont* ex_expli = NULL;
// on passe en revue les fonctions nD
for (int i=1;i<8;i++)
{if (fct_para(i) != NULL)
{ Fonction_nD* pt_fonct = fct_para(i); // pour simplifier
// on utilise la méthode générique de loi abstraite
Tableau & tab_val = Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(pt_fonct,1 // une seule valeur attendue en retour
,ex_impli,ex_expli_tdt,ex_expli
,NULL
,NULL
,NULL
);
/* // ici on utilise les variables connues aux pti, ou calculées à partir de
// on commence par récupérer les conteneurs des grandeurs à fournir
List_io & li_enu_scal = pt_fonct->Li_enu_etendu_scalaire();
List_io & li_quelc = pt_fonct->Li_equi_Quel_evolue();
bool absolue = true; // on se place systématiquement en absolu
// on va utiliser la méhode Valeur_multi_interpoler_ou_calculer
// pour les grandeurs strictement scalaire
Tableau val_ddl_enum(Valeur_multi_interpoler_ou_calculer
(absolue,TEMPS_tdt,li_enu_scal,ex_impli,ex_expli_tdt,ex_expli,NULL)
);
// on utilise la méthode Valeurs_Tensorielles_interpoler_ou_calculer
// pour les Coordonnees et Tenseur
Valeurs_Tensorielles_interpoler_ou_calculer
(absolue,TEMPS_tdt,li_quelc,ex_impli,ex_expli_tdt,ex_expli,NULL);
// calcul de la valeur et retour dans tab_ret
Tableau & tab_val = pt_fonct->Valeur_FnD_Evoluee(&val_ddl_enum,&li_enu_scal,&li_quelc,NULL,NULL);
#ifdef MISE_AU_POINT
if (tab_val.Taille() != 1)
{ cout << "\nErreur : la fonction nD relative au parametre materiau " << i
<< " doit calculer un scalaire or le tableau de retour est de taille "
<< tab_val.Taille() << " ce n'est pas normal !\n";
cout << " Loi_ortho2D_C_entrainee::Calcul_DsigmaHH\n";
Sortie(1);
};
#endif
*/
// on récupère le premier élément du tableau uniquement
(*coef(i)) = tab_val(1);
};
};
};
// puis fabrication de la matrice inv_loi
{// on commence par remplir la matrice
inv_loi(1,1) = 1./E1;inv_loi(2,2) = 1./E2;
inv_loi(1,2) = inv_loi(2,1) = -nu12/E1;
inv_loi = inv_loi.Inverse(); // on inverse la matrice
};
// on vérifie éventuellement la convexité
if (verification_convexite)
Verif_convexite();
// calcul des contraintes dans le repère O_p
Vecteur eps_ii(2);Vecteur sig_ii(2);
for (int i=1; i<3;i++)
eps_ii(i) = eps_p_HH(i,i);
sig_ii = inv_loi * eps_ii;
for (int i=1; i<3;i++)
{sigHH.Coor(i,i) = sig_ii(i);
};
sigHH.Coor(1,2) = 2.* G12 * eps_p_HH(1,2);
// dans le cas où on veut une sortie des grandeurs on sauvegarde
if (sortie_post)
{ if (save_resul.eps_loc_HH == NULL)
{save_resul.eps_loc_HH = NevezTenseurHH(2);
save_resul.sig_loc_HH = NevezTenseurHH(2);
save_resul.para_loi = new Vecteur (7);
};
(*save_resul.eps_loc_HH) = eps_p_HH;
(*save_resul.sig_loc_HH) = sigHH;
// paramètres de la loi
(*save_resul.para_loi)(1) = E1; (*save_resul.para_loi)(2) = E2;
(*save_resul.para_loi)(3) = E3;
(*save_resul.para_loi)(4) = nu12; (*save_resul.para_loi)(5) = nu13;
(*save_resul.para_loi)(6) = nu23;
(*save_resul.para_loi)(7) = G12;
};
// calcul des contraintes dans le repère g_i
// l'inverse de gamma c'est beta transposée
sigHH.ChBase(beta_transpose);
#ifdef MISE_AU_POINT
if (affichage)
{cout << "\n sig_ijHH complet :";sigHH.Ecriture(cout);
Tenseur2HH tutu;
sigHH.BaseAbsolue(tutu,*(ex.giB_tdt));
cout << "\n sig en absolu :";tutu.Ecriture(cout);
};
#endif
// passage dans la bonne variance
Tenseur2BH sigBH = gijBB * sigHH ;
switch (cas_calcul)
{ case 0: // calcul normal (tous les termes)
{ // on ne fait rien de spécial
break;
}
case 1: // calcul de la partie déviatorique seule
{ double trace_sig = sigBH.Trace();
sigBH -= (untiers * trace_sig) * IdBH2;
sigHH -= (untiers * trace_sig) * gijHH;
break;
}
case 2: // calcul de la partie sphérique seule
{ double trace_sig = sigBH.Trace();
sigBH = (untiers * trace_sig) * IdBH2;
sigHH = (untiers * trace_sig) * gijHH;
break;
}
default:
{ cout << "\n erreur l'indicateur cas_calcul= " << cas_calcul << " n'a pas une valeur correcte !! "
<< "\n Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt (.... ";
Sortie(1);
}
};
#ifdef MISE_AU_POINT
if (affichage)
{ cout << "\n epsBB="< ConstMath::petit)
{ module_compressibilite = untiers * sigBH.Trace() / (log_var_vol);
// module_compressibilite = untiers * sigBH.Trace() /
// (1.- 1./((*(ex.jacobien_tdt))/(*(ex.jacobien_0))*var_epai));
}
else // si la variation de volume est trop faible on passe par la moyenne
// des compressibilités dans les 3 directions d'orthotropie (cf. théorie)
{double unsurKs1 = 1./E1 - nu12/E1 -nu13/E1;
double unsurKs2 = -nu12/E1+1./E2-nu23/E2;
double unsurKs3 = -nu13/E1-nu23/E2+1./E3;
module_compressibilite = untiers * untiers * (1./unsurKs1+1./unsurKs2+1./unsurKs3);
};
}
else
// dans le cas d'une loi purement déviatorique, le module de compressibilité = 0 (approximativement)
{module_compressibilite = 0.;};
#ifdef MISE_AU_POINT
if (Permet_affichage() > 4)
{ cout << "\n eps33= " << save_resul.eps33
<< " var_epai= " << var_epai
<< " var_surf= " << var_surf
<< "\n var_vol="<<((*(ex.jacobien_tdt))/(*(ex.jacobien_0))*var_epai)
<< " log_var_vol= " << log_var_vol
<< " sigBH.Trace()= " << sigBH.Trace()
<< " module_compressibilite= " << module_compressibilite
<< flush ;
};
#endif
// pour la partie cisaillement on garde la forme associée à la loi
// on prend la moyenne des 3
if ((cas_calcul == 0) || (cas_calcul == 1))
{module_cisaillement = 2. * (G12);}
else
// en purement sphérique, le module est supposé nul
{module_cisaillement = 0.; };
// cas le la variation du tenseur des contraintes
int nbddl = d_gijBB_tdt.Taille();
// des tenseurs de travail
Tenseur2BH d_sigBH; Tenseur2HH d_sig_HH;
Tenseur2HH d_epsHH;Mat_pleine mat_d_epsHH(2,2);
Vecteur d_eps_ii(2);Vecteur d_sig_ii(2);
Mat_pleine d_beta(2,2);Mat_pleine d_beta_inv(2,2);
Mat_pleine d_beta_transpose(2,2);
Mat_pleine d_gamma(2,2);
Mat_pleine mat_d_eps_p_HH(2,2);
// on récupère la matrice des composantes de déformation dans O_p_a
Mat_pleine mat_epsHH(2,2);epsHH.Matrice_composante(mat_epsHH);
//cout << "\n mat_epsHH: ";mat_epsHH.Affiche();
for (int i = 1; i<= nbddl; i++)
{ // on fait uniquement une égalité d'adresse et de ne pas utiliser
// le constructeur d'ou la profusion d'* et de ()
Tenseur2HH & dsigHH = *((Tenseur2HH*) (d_sigHH(i))); // passage en dim 2
const Tenseur2HH & dgijHH = *((Tenseur2HH*)(d_gijHH_tdt(i))) ; // pour simplifier l'ecriture
const Tenseur2BB & dgijBB = *((Tenseur2BB*)(d_gijBB_tdt(i))) ; // pour simplifier l'ecriture
const Tenseur2BB & depsBB = *((Tenseur2BB *) (d_epsBB(i))); // "
//Tableau * d_giB_tdt
BaseB & d_giB = (*ex.d_giB_tdt)(i);
BaseH & d_giH = (*ex.d_giH_tdt)(i);
// pour chacun des ddl on calcul les tenseurs derivees
Tenseur2BH depsBH = epsBB * dgijHH + depsBB * gijHH ;
//cout <<"\n depsBH: "; depsBH.Ecriture(cout);
/* // calcul des variations du repère O'_i
// en fait il s'agit des variations des beta_a^{.j}
if (type_transport == 0)
// transport de type contravariant
{ // on calcule les coordonnées de la base O' dans la base naturelle
BaseH& O_H = (*save_resul.O_H); // pour simplifier
for (int a=1; a<3;a++)
{ // calcul des variations du vecteur non normé
CoordonneeH d_pO_H_i(3);
d_pO_H_i.Zero();
// on a: Op_H(a) non normé = alpha_a^{.k} * \hat \vec g_k
// d'où : d_Op_H(a) non normé = alpha_a^{.k} * d(\hat \vec g_k)
for (int k=1; k<3;k++)
{const CoordonneeB& d_giB_k = d_giB(k);
// on change la variance car, celle-ci en fait dépend de la base
// et non de gi_B, mais ici on utilise la base sous forme d'un scalaire
// O_H(a)(k) et la variance est donnée par d_inter...
CoordonneeH d_inter(3);
d_inter.ConstructionAPartirDe_B(d_giB_k);
d_pO_H_i += O_H(a)(k) * d_inter;
};
// calcul de la variation du vecteur unitaire connaissant la variation du
// vecteur non unitaire et la norme
// d_Op_H.CoordoH(a) = Util::VarUnVect_coorH(pO_B.CoordoB(a),d_pO_H_i,tab_norme(a));
};
}
else
// transport de type covariant
{ // on calcule les coordonnées de la base O' dans la base duale
BaseB& O_B = (*save_resul.O_B); // pour simplifier
for (int iloc=1; iloc<3;iloc++)
{ // tout d'abord la base non normalisée
CoordonneeH& d_pO_H_i = d_Op_H.CoordoH(iloc);
d_pO_H_i.Zero();
for (int k=1; k<3;k++)
{CoordonneeH d_giH_k = d_giH(k);
d_pO_H_i += O_B(i)(k) * d_giH_k;
};
// calcul de la variation du vecteur unitaire connaissant la variation du
// vecteur non unitaire et la norme
CoordonneeH interH = Util::VarUnVect_coorH(pO_H.CoordoH(iloc),d_pO_H_i,tab_norme(iloc));
};
// maintenant on calcule la base d_Op_B correspondante
for (int i=1; i<3;i++)
d_Op_B.CoordoB(i) = d_Op_H.CoordoH(i) * gijBB + Op_H.CoordoH(i) * dgijBB;
};
*/
// on calcul la variation de matrice de passage de la base g_i vers la base O'_a
// O'_a = beta_a^{.i} * g_i
if (type_transport == 0)
// transport de type contravariant
{for (int a=1; a<3;a++)
{const CoordonneeH& alpha_H_a = alpha_H.CoordoH(a);
// on calcul d'abord le produit alpha_a^l * alpha_a^m * d_g_ij(l,m)
double inter = 0.;
for (int l =1;l<3;l++)
for (int m =1;m<3;m++)
inter += alpha_H_a(l) * alpha_H_a(m) * dgijBB(l,m);
for (int i=1; i<3;i++)
{double & d_beta_ai = d_beta(a,i); // pour simplifier
// ajout des termes or boucle
d_beta_ai *= - 0.5 * alpha_H_a(i) * inter / PUISSN(tab_norme(a), 3);
};
};
// on calcule ensuite la variation de gamma
d_beta_transpose = d_beta.Transpose();
//cout << "\n gamma: ";gamma.Affiche();
// d_gamma = (gamma * d_beta_transpose);
d_gamma = - gamma * d_beta_transpose * gamma;
#ifdef MISE_AU_POINT
if (affichage)
{cout << "\n d_beta: ";d_beta.Affiche();
cout << "\n d_beta_transpose: ";d_beta_transpose.Affiche();
cout << "\n d_gamma: ";d_gamma.Affiche();
d_gamma = -d_gamma;
cout << "\n d_gamma: ";d_gamma.Affiche();
};
#endif
}
else
{cout << "\n **** cas en attente "
<< "\n Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt (.... "<< endl;
Sortie(1);
};
// calcul des coordonnées de la variation de déformation dans le repère O'_i
// -- 1) en coordonnees contravariantes tout d'abord variations dans g_i
// epsHH = gijHH * epsBB * gijHH dans g_i
d_epsHH = dgijHH * epsBB * gijHH + gijHH * depsBB * gijHH
+ gijHH * epsBB * dgijHH;
//cout <<"\n d_epsHH: "; d_epsHH.Ecriture(cout);
// -- maintenant on s'occupe du changement de base
// les beta et gamma sont des matrices et non des tenseurs ... on transforme localement
// en matrice
d_epsHH.Matrice_composante(mat_d_epsHH);
// -- calcul final de la variation de déformation dans le repère O'_i
// rappel du changement de base : res = (gamma * res) * gamma.Transpose();
//cout << "\n d_gamma: ";d_gamma.Affiche();
mat_d_eps_p_HH = (d_gamma * mat_epsHH * gamma_transpose)
+ (gamma * mat_d_epsHH * gamma_transpose)
+ gamma * mat_epsHH * d_gamma.Transpose();
//cout << "\n mat_d_eps_p_HH: ";mat_d_eps_p_HH.Affiche();
// -- 2) calcul de la variation des contraintes dans le repère O_p
for (int i=1; i<3;i++)
d_eps_ii(i) = mat_d_eps_p_HH(i,i); // les def de la diagonale
d_sig_ii = inv_loi * d_eps_ii; // les contraintes en ii
for (int i=1; i<3;i++)
{dsigHH.Coor(i,i) = d_sig_ii(i); // affectation des contraintes en ii
};
// puis les contraintes en cisaillement
dsigHH.Coor(1,2) = 2.* G12 * mat_d_eps_p_HH(1,2);
//cout <<"\n dsigHH en O_p : "; dsigHH.Ecriture(cout);
// -- 3) calcul de la variation des contraintes dans le repère g_i
// c'est l'opération inverse et beta_transpose joue le rôle de gamma dans l'autre sens
sigHH.Var_tenseur_dans_nouvelle_base(beta_transpose,dsigHH,d_beta_transpose);
//cout <<"\n dsigHH en gi : "; dsigHH.Ecriture(cout);
double untiers = 1./3.;
switch (cas_calcul)
{ case 0: // calcul normal (tous les termes)
{ // on ne fait rien de spécial
break;
}
case 1: // calcul de la partie déviatorique seule
{// passage en mixte pour le calcul de la trace
d_sigBH = dgijBB * sigHH + gijBB * dsigHH;
double d_trace_sig = d_sigBH.Trace();
d_sigBH -= (untiers * d_trace_sig) * IdBH2;
// passage en deux fois contravariant
dsigHH = dgijHH * sigBH + gijHH * d_sigBH;
break;
}
case 2: // calcul de la partie sphérique seule
{// passage en mixte pour le calcul de la trace
d_sigBH = dgijBB * sigHH + gijBB * dsigHH;
double d_trace_sig = d_sigBH.Trace();
d_sigBH = (untiers * d_trace_sig) * IdBH2;
// passage en deux fois contravariant
dsigHH = dgijHH * sigBH + gijHH * d_sigBH;
break;
}
default: break;//l'erreur a déjà été traitée dans le calcul de la contrainte
};
////----------------- debug
// if ((i==2) || (i==5))
// {cout << "\n dsighh("< 5);
#ifdef MISE_AU_POINT
if (affichage)
{cout << "\n --- loi de comportement orthotrope entrainee --- ";
};
#endif
const Tenseur2HH & gijHH = *((Tenseur2HH*) ex.gijHH_tdt); // " " " "
const Tenseur2BB & gijBB = *((Tenseur2BB*) ex.gijBB_tdt); // " " " "
const Tenseur2BB & epsBB = *((Tenseur2BB*) &epsBB_tdt); // passage en dim 2
Tenseur2HH & sigHH = *((Tenseur2HH*) &sigHH_tdt); // " " " "
Tenseur2HHHH& d_sigma_deps = *((Tenseur2HHHH*) &d_sigma_deps_);
Tenseur2BH epsBH = epsBB * gijHH; // deformation en mixte
Tenseur2HH epsHH(gijHH * epsBH); // en deuxfois contra
int dim = ParaGlob::Dimension(); // pour les affichages de vecteurs
// récup du conteneur spécifique
SaveResulLoi_ortho2D_C_entrainee & save_resul = *((SaveResulLoi_ortho2D_C_entrainee*) saveResul);
// on commence par calculer le repère d'orthotropie transporté
// Op_H_i sont les coordonnées contravariantes de la nouvelle base
// donc par rapport à g_i,
BaseH& Op_H = save_resul.Op_H;
Tableau tab_norme(2);
if (type_transport == 0)
// transport de type contravariant
{ // on calcule les coordonnées de la base O' dans la base naturelle
#ifdef MISE_AU_POINT
if (save_resul.O_H == NULL)
{cout << "\n *** erreur, le repere d'anisotropie n'est pas defini "
<<"on ne peut pas continuer " << flush ;
cout << " Loi_ortho2D_C_entrainee::Calcul_dsigma_deps\n";
Sortie(1);
};
#endif
BaseH& O_H = (*save_resul.O_H); // coordonnées en absolu de la base d'orthotropie
// calcul des coordonnées alpha_a^{.i} = O_H(a) * g^i à t= 0
for (int a = 1;a < 3; a++)
{CoordonneeH& inter = alpha_H.CoordoH(a);
for (int i=1;i < 3;i++)
inter(i)= O_H(a).ScalHH((*ex.giH_0)(i));
#ifdef MISE_AU_POINT
if (affichage)
{cout << "\n O_H("< gp_i = beta_i^j * g_j
// calcul des coordonnées de la déformation dans le repère O'_i
#ifdef MISE_AU_POINT
if (affichage)
{// Tenseur2BB eps_p_BB(epsBB);
cout <<"\n eps_p_BB en g^i: "; epsBB.Ecriture(cout);
Tenseur2BB tiutiu;
epsBB.BaseAbsolue(tiutiu,*(ex.giH_tdt));
cout << "\n eps en absolu :";tiutiu.Ecriture(cout);
};
#endif
// il faut passer en 2 fois contravariant
Tenseur2HH eps_p_HH(epsHH); // init
#ifdef MISE_AU_POINT
if (affichage)
{cout <<"\n eps_p_HH en g_i: "; eps_p_HH.Ecriture(cout);
};
#endif
eps_p_HH.ChBase(gamma); // res = (gamma * res) * gamma.Transpose();
#ifdef MISE_AU_POINT
if (affichage)
{ cout <<"\n eps_p_HH: "; eps_p_HH.Ecriture(cout);
TenseurHH* toto = NevezTenseurHH(eps_p_HH);
toto->ChBase(beta_transpose);
cout << "\n retour dans la base g^i de eps^{ij} :";toto->Ecriture(cout);
TenseurBB* titi = NevezTenseurBB(gijBB * (*toto) * gijBB);
cout << "\n def eps_ij :";titi->Ecriture(cout);
delete toto; delete titi;
};
#endif
double untiers = 1./3.;
// dans le cas de fonctions nD récupération des valeurs
if (!null_fct_para)
//rappel: Tableau fct_para; // fonction nD éventuelle d'évolution des paramètres
{// un tableau de travail pour les valeurs sous forme indicée
Tableau < double * > coef(7);
coef(1) = &E1; coef(2) = & E2;coef(3) = &E3;
coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23;
coef(7) = & G12;
// opération de transmission de la métrique
const Met_abstraite::Impli* ex_impli = NULL;
const Met_abstraite::Expli_t_tdt* ex_expli_tdt = NULL;
const Met_abstraite::Umat_cont* ex_expli = &ex;
// on passe en revue les fonctions nD
for (int i=1;i<8;i++)
{if (fct_para(i) != NULL)
{ Fonction_nD* pt_fonct = fct_para(i); // pour simplifier
// on utilise la méthode générique de loi abstraite
Tableau & tab_val = Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(pt_fonct,1 // une seule valeur attendue en retour
,ex_impli,ex_expli_tdt,ex_expli
,NULL
,NULL
,NULL
);
/* // ici on utilise les variables connues aux pti, ou calculées à partir de
// on commence par récupérer les conteneurs des grandeurs à fournir
List_io & li_enu_scal = pt_fonct->Li_enu_etendu_scalaire();
List_io & li_quelc = pt_fonct->Li_equi_Quel_evolue();
bool absolue = true; // on se place systématiquement en absolu
// on va utiliser la méhode Valeur_multi_interpoler_ou_calculer
// pour les grandeurs strictement scalaire
Tableau val_ddl_enum(Valeur_multi_interpoler_ou_calculer
(absolue,TEMPS_tdt,li_enu_scal,ex_impli,ex_expli_tdt,ex_expli,NULL)
);
// on utilise la méthode Valeurs_Tensorielles_interpoler_ou_calculer
// pour les Coordonnees et Tenseur
Valeurs_Tensorielles_interpoler_ou_calculer
(absolue,TEMPS_tdt,li_quelc,ex_impli,ex_expli_tdt,ex_expli,NULL);
// calcul de la valeur et retour dans tab_ret
Tableau & tab_val = pt_fonct->Valeur_FnD_Evoluee(&val_ddl_enum,&li_enu_scal,&li_quelc,NULL,NULL);
#ifdef MISE_AU_POINT
if (tab_val.Taille() != 1)
{ cout << "\nErreur : la fonction nD relative au parametre materiau " << i
<< " doit calculer un scalaire or le tableau de retour est de taille "
<< tab_val.Taille() << " ce n'est pas normal !\n";
cout << " Loi_ortho2D_C_entrainee::Calcul_SigmaHH\n";
Sortie(1);
};
#endif
*/
// on récupère le premier élément du tableau uniquement
(*coef(i)) = tab_val(1);
};
};
};
// puis fabrication de la matrice inv_loi
{// on commence par remplir la matrice
inv_loi(1,1) = 1./E1;inv_loi(2,2) = 1./E2;
inv_loi(1,2) = inv_loi(2,1) = -nu12/E1;
inv_loi = inv_loi.Inverse(); // on inverse la matrice
};
// on vérifie éventuellement la convexité
if (verification_convexite)
Verif_convexite();
// calcul des contraintes dans le repère O_p
Vecteur eps_ii(2);Vecteur sig_ii(2);
for (int i=1; i<3;i++)
eps_ii(i) = eps_p_HH(i,i);
sig_ii = inv_loi * eps_ii;
for (int i=1; i<3;i++)
{sigHH.Coor(i,i) = sig_ii(i);
};
sigHH.Coor(1,2) = 2.* G12 * eps_p_HH(1,2);
#ifdef MISE_AU_POINT
if (affichage)
{cout << "\n sig_abHH :";sigHH.Ecriture(cout);
};
#endif
Tenseur2HH sig_ab_HH(sigHH);
// dans le cas où on veut une sortie des grandeurs on sauvegarde
if (sortie_post)
{ if (save_resul.eps_loc_HH == NULL)
{save_resul.eps_loc_HH = NevezTenseurHH(2);
save_resul.sig_loc_HH = NevezTenseurHH(2);
save_resul.para_loi = new Vecteur (7);
};
(*save_resul.eps_loc_HH) = eps_p_HH;
(*save_resul.sig_loc_HH) = sig_ab_HH;
// paramètres de la loi
(*save_resul.para_loi)(1) = E1; (*save_resul.para_loi)(2) = E2;
(*save_resul.para_loi)(3) = E3;
(*save_resul.para_loi)(4) = nu12; (*save_resul.para_loi)(5) = nu13;
(*save_resul.para_loi)(6) = nu23;
(*save_resul.para_loi)(7) = G12;
};
// calcul des contraintes dans le repère g_i
// l'inverse de gamma c'est beta transposée
sigHH.ChBase(beta_transpose);
#ifdef MISE_AU_POINT
if (affichage)
{cout << "\n sig_ijHH complet :";sigHH.Ecriture(cout);
Tenseur2HH tutu;
sigHH.BaseAbsolue(tutu,*(ex.giB_tdt));
cout << "\n sig en absolu :";tutu.Ecriture(cout);
};
#endif
// passage dans la variance mixte
Tenseur2BH sigBH = gijBB * sigHH ;
switch (cas_calcul)
{ case 0: // calcul normal (tous les termes)
{ // on ne fait rien de spécial
break;
}
case 1: // calcul de la partie déviatorique seule
{ double trace_sig = sigBH.Trace();
sigBH -= (untiers * trace_sig) * IdBH2;
sigHH -= (untiers * trace_sig) * gijHH;
break;
}
case 2: // calcul de la partie sphérique seule
{ double trace_sig = sigBH.Trace();
sigBH = (untiers * trace_sig) * IdBH2;
sigHH = (untiers * trace_sig) * gijHH;
break;
}
default:
{ cout << "\n erreur l'indicateur cas_calcul= " << cas_calcul << " n'a pas une valeur correcte !! "
<< "\n Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt (.... ";
Sortie(1);
}
};
#ifdef MISE_AU_POINT
if (affichage)
{ cout << "\n epsBB="< ConstMath::petit)
{module_compressibilite = untiers * sigBH.Trace() / (log_var_vol);}
else // si la variation de volume est trop faible on passe par la moyenne
// des compressibilités dans les 3 directions d'orthotropie (cf. théorie)
{double unsurKs1 = 1./E1 - nu12/E1 -nu13/E1;
double unsurKs2 = -nu12/E1+1./E2-nu23/E2;
double unsurKs3 = -nu13/E1-nu23/E2+1./E3;
module_compressibilite = untiers * untiers * (1./unsurKs1+1./unsurKs2+1./unsurKs3);
};
}
else
// dans le cas d'une loi purement déviatorique, le module de compressibilité = 0 (approximativement)
{module_compressibilite = 0.;
};
#ifdef MISE_AU_POINT
if (Permet_affichage() > 4)
{ cout << "\n var_vol="<<((*(ex.jacobien_tdt))/(*(ex.jacobien_0))*var_epai)
<< " log_var_vol= " << log_var_vol
<< " sigBH.Trace()= " << sigBH.Trace()
<< " module_compressibilite= " << module_compressibilite
<< flush ;
if (Permet_affichage() > 5) cout << "\n cas_calcul= " << cas_calcul;
};
#endif
// pour la partie cisaillement on garde la forme associée à la loi
// on prend la moyenne des 3
if ((cas_calcul == 0) || (cas_calcul == 1))
{module_cisaillement = 2. * (G12);}
else
// en purement sphérique, le module est supposé nul
{module_cisaillement = 0.; };
// ----- calcul de l'opérateur tangent -----------
// calcul des variations de sigma / eps dans le repère transporté
Tenseur2HHBB var_sig_ab_cd_HHBB;
for (int i=1; i<3;i++)
for (int j=1; j<3;j++)
var_sig_ab_cd_HHBB.Change(i,i,j,j,inv_loi(i,j));
var_sig_ab_cd_HHBB.Change(1,2,1,2,G12); // du coup = (1,2,2,1) = (2,1,1,2) = (2,1,2,1)
#ifdef MISE_AU_POINT
if (affichage)
{cout << "\n var_sig_ab_cd_HHBB= ";
var_sig_ab_cd_HHBB.Affiche_bidim(cout);
};
#endif
// cas de la variation des beta_a^{.i} par rapport aux eps_kl
// on va les stocker dans un tableau d_beta(a,i) de tenseur HH
Tableau2 d_beta_HH(2,2);
Tableau2 d_beta_transpose_HH(2,2);
if (type_transport == 0)
// transport de type contravariant
{ // on calcule les coordonnées de la base O' dans la base naturelle
BaseH& O_H = (*save_resul.O_H); // pour simplifier
for (int a=1;a<3;a++)
{// calcul de la norme du vecteur O'_a
CoordonneeH alpha_H_a = alpha_H(a);
double n_O_a = tab_norme(a);
for (int i=1;i<3;i++)
{d_beta_transpose_HH(i,a)
= d_beta_HH(a,i)
= -(alpha_H_a(i)
/(n_O_a*n_O_a*n_O_a))*Tenseur2HH::Prod_tensoriel(alpha_H_a,alpha_H_a);
};
};
}; // fin du transport 0
//**** à faire le second transport
// vérif d_beta OK
/*{// vérif en différence finie de d_beta
for (int a=1;a<3;a++)
{ CoordonneeH alpha_H_a = alpha_H(a);
//Tenseur2HH toto(Tenseur2HH::Prod_tensoriel(alpha_H_a,alpha_H_a));
//cout << "\n Prod_tensoriel(alpha_H_a,alpha_H_a)= ";
//toto.Ecriture(cout);
//Tenseur2HH titi;
//for (int j=1;j<3;j++)
// for (int i=1;i<3;i++)
// titi.Coor(i,j) = alpha_H_a(i) * alpha_H_a(j);
//cout << "\n Prod_tensoriel(alpha_H_a,alpha_H_a) numerique = ";
//titi.Ecriture(cout);
// calcul de la norme du vecteur O'_a
double d_beta_num=0.;
double n_O_a = tab_norme(a);
for (int i=1;i<3;i++)
{d_beta_num = d_beta_HH(a,i) && epsBB;
cout << "\n delta_beta("< d_gamma_HH(2,2);
for (int b=1;b<3;b++)
for (int j=1;j<3;j++)
{for (int a=1;a<3;a++)
for (int i=1;i<3;i++)
d_gamma_HH(b,j) -= (gamma(a,j) * gamma(b,i)) * d_beta_HH(a,i);
};
/*
// vérification numérique de d_gamma
// on a \hat{\vec g}_j = {\gamma}_{.j}^{b}~\hat{\vec O'}_b
{Mat_pleine gamma_0(2,2);
Mat_pleine O_p_0_ij(2,2);Mat_pleine O_p_tdt_ij(2,2);
for (int a=1;a<3;a++)
{
CoordonneeH alpha_H_a = alpha_H(a);
//Tenseur2HH toto(Tenseur2HH::Prod_tensoriel(alpha_H_a,alpha_H_a));
//cout << "\n Prod_tensoriel(alpha_H_a,alpha_H_a)= ";
//toto.Ecriture(cout);
//Tenseur2HH titi;
//for (int j=1;j<3;j++)
// for (int i=1;i<3;i++)
// titi.Coor(i,j) = alpha_H_a(i) * alpha_H_a(j);
//cout << "\n Prod_tensoriel(alpha_H_a,alpha_H_a) numerique = ";
//titi.Ecriture(cout);
// calcul de la norme du vecteur O'_a
double d_beta_num=0.;
double n_O_a = tab_norme(a);
for (int i=1;i<3;i++)
{d_beta_num = d_beta_HH(a,i) && epsBB;
cout << "\n delta_beta("<