Herezh_dev/comportement/anisotropie/Loi_ortho2D_C_entrainee.cc
2023-05-03 17:23:49 +02:00

3041 lines
128 KiB
C++
Executable file

// 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) <https://www.irdl.fr/>.
//
// 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 <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 "Loi_ortho2D_C_entrainee.h"
#include "NevezTenseur.h"
#include "MathUtil.h"
#include "Util.h"
#include "Enum_TypeQuelconque.h"
#include "TypeQuelconqueParticulier.h"
#include "TenseurQ2gene.h"
#include "MathUtil.h"
#include "MathUtil2.h"
#include "CharUtil.h"
#include "Coordonnee2.h"
// ========== fonctions pour la classe de sauvegarde des résultats =========
// constructeur par défaut
Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee(const int type_transport):
O_B(NULL), O_H(NULL),Op_H(2,2),Op_H_t(2,2),eps_loc_HH(NULL),sig_loc_HH(NULL)
,para_loi(NULL)
{
};
// constructeur de copie
Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee(const SaveResulLoi_ortho2D_C_entrainee& sav):
O_B(NULL), O_H(NULL),Op_H(2,2),Op_H_t(2,2),eps_loc_HH(NULL),sig_loc_HH(NULL)
,para_loi(NULL)
{
// partie repère d'orthotropie
if (sav.O_B != NULL)
O_B = new BaseB(*sav.O_B);
if (sav.O_H != NULL)
O_H = new BaseH(*sav.O_H);
if (sav.eps_loc_HH != NULL)
eps_loc_HH = NevezTenseurHH(*sav.eps_loc_HH);
if (sav.sig_loc_HH != NULL)
sig_loc_HH = NevezTenseurHH(*sav.sig_loc_HH);
if (sav.para_loi != NULL)
para_loi = new Vecteur (*sav.para_loi);
};
// destructeur
Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::~SaveResulLoi_ortho2D_C_entrainee()
{
// partie repère d'orthotropie
if (O_B != NULL)
delete O_B;
if (O_H != NULL)
delete O_H;
if (eps_loc_HH != NULL)
delete eps_loc_HH;
if (sig_loc_HH != NULL)
delete sig_loc_HH;
if (para_loi != NULL)
delete para_loi;
};
// affectation
Loi_comp_abstraite::SaveResul & Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::operator = ( const Loi_comp_abstraite::SaveResul & a)
{ Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee& sav = *((Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee*) &a);
eps33=sav.eps33;eps33_t=sav.eps33_t;
// partie repère d'orthotropie
if (sav.O_B != NULL)
{if (O_B == NULL) {O_B = new BaseB(*sav.O_B);}
else {*O_B = *sav.O_B;};
}
else // sinon cas NULL
{if (O_B != NULL) {delete O_B;O_B=NULL;}} ;
if (sav.O_H != NULL)
{if (O_H == NULL) {O_H = new BaseH(*sav.O_H);}
else {*O_H = *sav.O_H;};
}
else // sinon cas NULL
{if (O_H != NULL) {delete O_H;O_H=NULL;}} ;
if (sav.eps_loc_HH != NULL)
{if (eps_loc_HH == NULL) {eps_loc_HH = NevezTenseurHH(*sav.eps_loc_HH);}
else {*eps_loc_HH = *sav.eps_loc_HH;};
}
else // sinon cas NULL
{if (eps_loc_HH != NULL) {delete eps_loc_HH;eps_loc_HH=NULL;}} ;
if (sav.sig_loc_HH != NULL)
{if (sig_loc_HH == NULL) {sig_loc_HH = NevezTenseurHH(*sav.sig_loc_HH);}
else {*sig_loc_HH = *sav.sig_loc_HH;};
}
else // sinon cas NULL
{if (sig_loc_HH != NULL) {delete sig_loc_HH; sig_loc_HH= NULL;};
} ;
if (sav.para_loi != NULL)
{if (para_loi == NULL) para_loi = new Vecteur (*sav.para_loi);
else {*para_loi = *sav.para_loi; };
}
else // sinon cas NULL
{if (para_loi != NULL) {delete para_loi;para_loi=NULL;}} ;
// et la base
Op_H = sav.Op_H;
Op_H_t = sav.Op_H_t;
return *this;
};
//------- lecture écriture dans base info -------
// cas donne le niveau de la récupération
// = 1 : on récupère tout
// = 2 : on récupère uniquement les données variables (supposées comme telles)
void Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Lecture_base_info(ifstream& ent,const int cas)
{ string nom;
ent >> nom ;
#ifdef MISE_AU_POINT
if (nom != "S_Ortho_2D_C")
{ cout << "\nErreur : on attendait le mot cle: S_Ortho_2D_C "
<< " et on a lue "<<nom;
cout << " Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Lecture_base_info\n";
Sortie(1);
};
#endif
// on lit 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)
{ ent >> nom >> *O_B;}
else if (O_H != NULL)
{ ent >> nom >> *O_H;}
// la base convectée
ent >> nom >> Op_H_t ;
Op_H = Op_H_t;
// les stockages conditionnels
int test;
ent >> nom >> test;
if (test == 0)
{ if (eps_loc_HH != NULL)
{delete eps_loc_HH;eps_loc_HH=NULL;}
if (sig_loc_HH != NULL)
{delete sig_loc_HH;sig_loc_HH=NULL;}
if (para_loi != NULL)
{delete para_loi;para_loi=NULL;}
}
else // sinon cas où on a des données additionnelles
{ if (eps_loc_HH == NULL) eps_loc_HH = NevezTenseurHH(2);
ent >> nom ; eps_loc_HH->Lecture(ent);
if (sig_loc_HH == NULL) sig_loc_HH = NevezTenseurHH(2);
ent >> nom ; sig_loc_HH->Lecture(ent);
if (para_loi == NULL) para_loi = new Vecteur (7);
ent >> *para_loi;
};
break;
}
case 2 :
{
// la base convectée
ent >> nom >> Op_H_t ;
// les stockages conditionnels
int test;
ent >> nom >> test;
if (test == 0)
{ if (eps_loc_HH != NULL)
{delete eps_loc_HH;eps_loc_HH=NULL;}
if (sig_loc_HH != NULL)
{delete sig_loc_HH;sig_loc_HH=NULL;}
if (para_loi != NULL)
{delete para_loi;para_loi=NULL;}
}
else // sinon cas où on a des données additionnelles
{ if (eps_loc_HH == NULL) eps_loc_HH = NevezTenseurHH(2);
ent >> nom ; eps_loc_HH->Lecture(ent);
if (sig_loc_HH == NULL) sig_loc_HH = NevezTenseurHH(2);
ent >> nom ; sig_loc_HH->Lecture(ent);
if (para_loi == NULL) para_loi = new Vecteur(7);
ent >> nom >> *para_loi;
};
break;
}
default:
cout << "\n cas non considere !!: cas= " << cas
<< "\n Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Ecriture_base_info(...";
Sortie(1);
};
};
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables
//(supposées comme telles)
void Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Ecriture_base_info(ofstream& sort,const int cas )
{ sort << "\n S_Ortho_2D_C ";
// on ne sauvegarde que ce qui est à 0 et à t, ce qui est à tdt est considéré une zone de travail
switch (cas)
{ case 1 :
{
// la base initiale
if (O_B != NULL)
{ sort << " O_B: "<< *O_B;}
else if (O_H != NULL)
{ sort << " O_H: "<< *O_H;}
// la base convectée
sort << " Op_H_t: "<< Op_H_t << " ";
// les stockages conditionnels
if (eps_loc_HH != NULL)
{ sort << " addi: 1 " << "\n eps_loc_HH: ";
eps_loc_HH->Ecriture(sort);
sort << "\n sig_loc_HH: ";
sig_loc_HH->Ecriture(sort);
sort << "\n para_loi: " << *para_loi << " ";
}
else
{ sort << " addi: 0 ";};
break;
}
case 2 :
{
// la base convectée
sort << " Op_H_t: "<< Op_H_t << " ";
// les stockages conditionnels
if (eps_loc_HH != NULL)
{ sort << "\n addi: 1 "<< "\n eps_loc_HH: " ;
eps_loc_HH->Ecriture(sort);
sort << "\n sig_loc_HH: " ;
sig_loc_HH->Ecriture(sort);
sort << "\n para_loi: " << *para_loi << " ";
}
else
{ sort << "\n addi: 0 ";};
break;
}
default:
cout << "\n cas non considere !!: cas= " << cas
<< "\n Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Ecriture_base_info(...";
Sortie(1);
};
};
// mise à jour des informations transitoires
void Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::TdtversT()
{ Op_H_t = Op_H;
eps33_t=eps33;
};
void Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::TversTdt()
{ Op_H = Op_H_t;
eps33=eps33_t;
};
// affichage à l'écran des infos
void Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::Affiche() const
{ cout << "\n SaveResulLoi_ortho2D_C_entrainee: " ;
if (O_B != NULL)
{cout << "\n O_B= "; O_B->Affiche();
};
if (O_H != NULL)
{cout << "\n O_H= "; O_H->Affiche();
};
cout << "\n Op_H= ";Op_H.Affiche();
// les tenseurs intermédiaires
if (eps_loc_HH != NULL)
{ cout << "\n eps_loc_HH= "; eps_loc_HH->Ecriture(cout);
};
if (sig_loc_HH != NULL)
{ cout << "\n sig_loc_HH= "; sig_loc_HH->Ecriture(cout);
};
// paramètre variables éventuelles de la loi
if (para_loi != NULL)
{ cout << "\n para_loi: ";
for (int i=1; i< 8;i++)
cout << " coef("<<i<<")= "<< (*para_loi)(i);
cout << " ";
};
cout << "\n .. fin SaveResulLoi_ortho2D_C_entrainee ... ";
};
//changement de base de toutes les grandeurs internes tensorielles stockées
// b(i,j) represente les coordonnees de la nouvelle base naturelle gpB dans l'ancienne gB
// gpB(i) = beta(i,j) * gB(j), i indice de ligne, j indice de colonne
// gpH(i) = gamma(i,j) * gH(j)
void Loi_ortho2D_C_entrainee::SaveResulLoi_ortho2D_C_entrainee::ChBase_des_grandeurs(const Mat_pleine& beta,const Mat_pleine& gamma)
{ // on ne s'intéresse qu'aux grandeurs tensorielles
// il faut que l'on exprime le repère d'orthotropie dans le nouveau repère
// !!! on travaille ici en 2D -> 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 <Coordonnee>& 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 <string > 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 <string > 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 <string > 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 <string > 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<TypeQuelconque>& liTQ,Loi_comp_abstraite::SaveResul * saveDon,list<int>& 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<TypeQuelconque>::iterator itq,itqfin=liTQ.end();
list<int>::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<TypeQuelconque>& liTQ) const
{
// pour le stockage
Tableau <double> 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<TypeQuelconque>::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<TypeQuelconque>::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<TypeQuelconque>::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<TypeQuelconque>::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<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == PARA_ORTHO)
{Tab_Grandeur_Vecteur& tyTQ= *((Tab_Grandeur_Vecteur*) (*itq).Grandeur_pointee()); // pour simplifier
int taille = tyTQ.Taille()+1;
tyTQ.Change_taille(taille); nexistePas = false;
};
if (nexistePas)
{Vecteur tens(7); // les 7 paramètres
Tab_Grandeur_Vecteur gr_vec_para(tens,1);
// def d'un type quelconque représentatif
TypeQuelconque typQ(PARA_ORTHO,EPS11,gr_vec_para);
liTQ.push_back(typQ);
};
};
}; // fin du cas ou sortie_post est actif, c-a-d que l'on veut des infos sur les indicateurs
// de résolution
};
//----- lecture écriture de restart -----
// cas donne le niveau de la récupération
// = 1 : on récupère tout
// = 2 : on récupère uniquement les données variables (supposées comme telles)
void Loi_ortho2D_C_entrainee::Lecture_base_info_loi(ifstream& ent,const int cas,LesReferences& lesRef,LesCourbes1D& lesCourbes1D
,LesFonctions_nD& lesFonctionsnD)
{ string toto,nom;
if (cas == 1)
{ ent >> nom ;
if (nom != "ORTHOELA2D_C")
{cout <<"\n *** erreur en lecture du type de la loi de comportement, on attendait"
<< " la chaine de caracteres: ORTHOELA2D_C et on a lu "
<< nom <<" !!! on ne peut pas continuer "
<< "\n Loi_ortho2D_C_entrainee::Lecture_base_info_loi(.. "
<< flush;
Sortie(1);
};
// pour faire une boucle on constitue un tableau de mots clés
Tableau <string > tab_mot_cle(7);
tab_mot_cle(1) = "E1";tab_mot_cle(2) = "E2";tab_mot_cle(3) = "E3";
tab_mot_cle(4) = "nu12";tab_mot_cle(5) = "nu13";tab_mot_cle(6) = "nu23";
tab_mot_cle(7) = "G12";
// puis un tableau pour les valeurs
Tableau < double * > coef(7);
coef(1) = &E1; coef(2) = & E2; coef(3) = &E3;
coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23;
coef(7) = & G12;
// cela va permettre de choisir entre une valeur fixe et une fonction nD
for (int i=1;i< 8;i++)
{ ent >> toto >> nom;
string mot_cle2=tab_mot_cle(i)+"_fonction_nD:";
if (nom == mot_cle2)
// cas d'une fonction nD
{fct_para(i) = lesFonctionsnD.Lecture_pour_base_info(ent,cas,fct_para(i));
}
else // cas d'une valeur fixe
{(*coef(i)) = ChangeReel(nom);};
};
// lecture du repère associé
ent >> nom >> nom_repere;
// indicateur pour les calculs partielles
ent >> nom >> cas_calcul ;
// le type de transport
ent >> nom >> type_transport;
// le niveau d'affichage
Lecture_permet_affichage(ent,cas,lesFonctionsnD);
// sortie_post
ent >> nom >> sortie_post;
};
// appel de la classe mère
Loi_comp_abstraite::Lecture_don_base_info(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD);
};
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void Loi_ortho2D_C_entrainee::Ecriture_base_info_loi(ofstream& sort,const int cas)
{ if (cas == 1)
{ sort << " ORTHOELA2D_C " ;
// pour faire une boucle on constitue un tableau de mots clés
Tableau <string > 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: "<<sortie_post;
sort << endl;
};
// 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_ortho2D_C_entrainee::Module_young_equivalent(Enum_dure temps,const Deformation & def,SaveResul * )
{ /*if (!thermo_dependant)
{ return E;}
else
{ temperature_tdt = def.DonneeInterpoleeScalaire(TEMP,temps);
return E_temperature->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 <TenseurBB *>& 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 <TenseurBB *>& 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 <double> 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("<<a<<"): ";
Op_H_a.Affiche();
cout << "\n alpha_H("<<a<<"): ";
alpha_H(a).Affiche();
cout << "\n giB_tdt"; (*ex.giB_tdt)(a).Affiche();
// affichage du repère tournée
CoordonneeB V(dim);
for (int j=1;j<= 2;j++) V += (*ex.giB_tdt)(j) * Op_H_a(j);
cout << "\n op_H("<<a<<"): en absolu " << V ;
};
#endif
};
}
else
// transport de type covariant
{ // on calcule les coordonnées de la base O' dans la base duale
#ifdef MISE_AU_POINT
if (save_resul.O_B == 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
BaseB& O_B = (*save_resul.O_B); // pour simplifier
for (int a=1; a<3;a++)
{ // tout d'abord la base non normalisée
CoordonneeB& Op_B_a = Op_B.CoordoB(a);
// calcul de la norme du vecteur Op_B_a
double norme = sqrt(Op_B_a * gijHH * Op_B_a);
// coordonnées finales
Op_B_a /= norme;
};
// maintenant on calcule la base Op_H correspondante
for (int i=1; i<3;i++)
Op_H.CoordoH(i) = Op_B.CoordoB(i) * gijHH;
};
// on calcul la matrice de passage de la base g_i vers la base O'_i
// O'_i = beta_i^{.j} * g_j
// et on a également \hat{\vec g}^i = {\beta}_{a}^{.i}~\hat{\vec O'}^a
// comme O'_i est déjà exprimé dans g_j, ses coordonnées sont directement béta
for (int i=1; i<3;i++)
for (int j=1; j<3;j++)
{ beta(i,j) = Op_H(i)(j);};
// puis on calcul les coordonnées de la base duale
beta_transpose = beta.Transpose();
gamma = beta_transpose.Inverse();
gamma_transpose = gamma.Transpose();
#ifdef MISE_AU_POINT
if (affichage)
{cout << "\n beta: ";beta.Affiche();
cout << "\n beta_transpose: ";beta_transpose.Affiche();
cout << "\n gamma: ";gamma.Affiche();
cout << "\n gamma_transpose: ";gamma_transpose.Affiche();
};
#endif
// changement de base (cf. théorie) : la matrice beta est telle que:
// gpB(i) = beta(i,j) * gB(j) <==> 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 <Fonction_nD* > 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 <double> & 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 <Ddl_enum_etendu>& li_enu_scal = pt_fonct->Li_enu_etendu_scalaire();
List_io <TypeQuelconque >& 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 <double> 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 <double> & 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="<<epsBB << " gijBB_tdt= " << gijBB << " gijHH_tdt= " << gijHH<<" ";
cout << "\n sighh="<<sigHH<<" "<< flush ;
};
#endif
// calcul de la déformation d'épaisseur
//\varepsilon_{33} = -\frac{1}{1 - \nu_{12}.\nu_{21}}\left[ (\nu_{13} + \nu_{23}.\nu_{12})~\varepsilon_{11} + (\nu_{23} + \nu_{13}.\nu_{21}) ~\varepsilon_{22}\right]
double nu21 = nu12*E2/E1;
save_resul.eps33 = -1/(1.-nu12*nu21)*(
epsBH(1,1)*(nu12*nu23 + nu13)+epsBH(2,2)*(nu23+nu13*nu21)
);
// traitement des énergies
energ.Inita(0.);
energ.ChangeEnergieElastique(0.5 * (sigHH && epsBB));
// -- calcul des modules
// on n'utilise plus la forme linéaire, mais à la place la variation relative de volume
// constaté, au sens d'une mesure logarithmique, sauf dans le cas où cette variation est trop petite
double var_surf = (*(ex.jacobien_tdt))/(*(ex.jacobien_0)); // la variation de surface
// on cherche à intégrer la variation d'épaisseur calculée avec eps33
double var_epai = 0.; // init
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)= 1/2 * (1. - 1./(var_epai)^2), en orthonormee
var_epai = sqrt(1./(1.-2.* save_resul.eps33));
};
break;
case DEFORMATION_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEFORMATION_CUMU_LOGARITHMIQUE :
// cas d'une def logarithmique ou une approximation
{ // eps_33 = log(var_epai);
var_epai = exp(save_resul.eps33);
};
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_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt (... \n";
Sortie(1);
};
// calcul de la valeur de la variation relative de volume en log
double log_var_vol = log((*(ex.jacobien_tdt))/(*(ex.jacobien_0))*var_epai);
// pour le module de compressibilité, choix entre les différents cas
if ((cas_calcul == 0) || (cas_calcul == 2))
{if (log_var_vol > 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 <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,Tableau <TenseurHH *>& 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 <BaseB> & ,BaseH& ,Tableau <BaseH> &
,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& ,double&
,Vecteur& ,TenseurHH& sigHH_tdt,Tableau <TenseurHH *>& 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 <double> 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("<<a<<"): ";
Op_H_a.Affiche();
cout << "\n alpha_H("<<a<<"): ";
alpha_H(a).Affiche();
cout << "\n giB_tdt"; (*ex.giB_tdt)(a).Affiche();
// affichage du repère tournée
CoordonneeB V(dim);
for (int j=1;j<= 2;j++) V += (*ex.giB_tdt)(j) * Op_H_a(j);
cout << "\n op_H("<<a<<"): en absolu " << V ;
};
#endif
};
}
else
// transport de type covariant
{ // on calcule les coordonnées de la base O' dans la base duale
#ifdef MISE_AU_POINT
if (save_resul.O_B == 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
BaseB& O_B = (*save_resul.O_B); // pour simplifier
for (int a=1; a<3;a++)
{ // tout d'abord la base non normalisée
CoordonneeB& Op_B_a = Op_B.CoordoB(a);
// calcul de la norme du vecteur Op_B_a
double norme = sqrt(Op_B_a * gijHH * Op_B_a);
tab_norme(a) = norme;
// coordonnées finales
Op_B_a /= norme;
};
// maintenant on calcule la base Op_H correspondante
for (int i=1; i<3;i++)
Op_H.CoordoH(i) = Op_B.CoordoB(i) * gijHH;
};
// on calcul la matrice de passage de la base g_i vers la base O'_i
// O'_i = beta_i^{.j} * g_j
// et on a également \hat{\vec g}^i = {\beta}_{a}^{.i}~\hat{\vec O'}^a
// comme O'_i est déjà exprimé dans g_j, ses coordonnées sont directement béta
for (int i=1; i<3;i++)
for (int j=1; j<3;j++)
{ beta(i,j) = Op_H(i)(j);};
// puis on calcul les coordonnées de la base duale
beta_transpose = beta.Transpose();
gamma = beta_transpose.Inverse();
gamma_transpose = gamma.Transpose();
#ifdef MISE_AU_POINT
if (affichage)
{cout << "\n beta: ";beta.Affiche();
cout << "\n beta_transpose: ";beta_transpose.Affiche();
cout << "\n gamma: ";gamma.Affiche();
cout << "\n gamma_transpose: ";gamma_transpose.Affiche();
};
#endif
// changement de base (cf. théorie) : la matrice beta est telle que:
// gpB(i) = beta(i,j) * gB(j) <==> 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 <Fonction_nD* > 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 <double> & 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 <Ddl_enum_etendu>& li_enu_scal = pt_fonct->Li_enu_etendu_scalaire();
List_io <TypeQuelconque >& 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 <double> 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 <double> & 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="<<epsBB << " gijBB_tdt= " << gijBB << " gijHH_tdt= " << gijHH<<" ";
cout << "\n sighh="<<sigHH<<" "<< flush ;
};
#endif
// calcul de la déformation d'épaisseur
//\varepsilon_{33} = -\frac{1}{1 - \nu_{12}.\nu_{21}}\left[ (\nu_{13} + \nu_{23}.\nu_{12})~\varepsilon_{11} + (\nu_{23} + \nu_{13}.\nu_{21}) ~\varepsilon_{22}\right]
double nu21 = nu12*E2/E1;
save_resul.eps33 = -1/(1.-nu12*nu21)*(
epsBH(1,1)*(nu12*nu23 + nu13)+epsBH(2,2)*(nu23+nu13*nu21)
);
// traitement des énergies
energ.Inita(0.);
energ.ChangeEnergieElastique(0.5 * (sigHH && epsBB));
// -- calcul des modules
// on n'utilise plus la forme linéaire, mais à la place la variation relative de volume
// constaté, au sens d'une mesure logarithmique, sauf dans le cas où cette variation est trop petite
double var_surf = (*(ex.jacobien_tdt))/(*(ex.jacobien_0)); // la variation de surface
// on cherche à intégrer la variation d'épaisseur calculée avec eps33
double var_epai = 0.; // init
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)= 1/2 * (1. - 1./(var_epai)^2), en orthonormee
var_epai = sqrt(1./(1.-2.* save_resul.eps33));
};
break;
case DEFORMATION_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEFORMATION_CUMU_LOGARITHMIQUE :
// cas d'une def logarithmique ou une approximation
{ // eps_33 = log(var_epai);
var_epai = exp(save_resul.eps33);
};
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_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt (... \n";
Sortie(1);
};
// calcul de la valeur de la variation relative de volume en log
double log_var_vol = log((*(ex.jacobien_tdt))/(*(ex.jacobien_0))*var_epai);
// pour le module de compressibilité, choix entre les différents cas
if ((cas_calcul == 0) || (cas_calcul == 2))
{
if (log_var_vol > 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 <BaseB> * 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("<<i<<")="<<dsigHH<<" "
// << " dgijHH= " << dgijHH << " depsBB= " << depsBB ;
// };
//----------- fin debug
};
////----------------- debug
//cout << "\n\n\n"<<endl;Sortie(1);
//----------- fin debug
////debug
//cout << "\n Loi_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt ";
//cout << "\n sigHH: "; sigHH.Ecriture(cout);
//cout << "\n epsBB: "; epsBB.Ecriture(cout);
// << " epsBH.Trace()= " << Ieps
// << " sigBH.Trace()= " << sigBH.Trace() << " module_compressibilite= " << module_compressibilite;
////fin debug
LibereTenseur();
};
// void 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,TenseurHHHH& d_sigma_deps
// ,EnergieMeca & energ,const EnergieMeca & energ_t,double& module_compressibilite,double& module_cisaillement
// ,const Met_abstraite::Umat_cont& ex) ; //= 0;
// calcul des contraintes et ses variations par rapport aux déformations a t+dt
// en_base_orthonormee:
// si true: 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, sinon il s'agit de la base orthonormeee fixe
// ex: contient les éléments de métrique relativement au paramétrage matériel = X_(0)^a
void Loi_ortho2D_C_entrainee::Calcul_dsigma_deps (bool en_base_orthonormee, TenseurHH & ,TenseurBB&
,TenseurBB & epsBB_tdt,TenseurBB & ,double& ,double&
,TenseurHH& sigHH_tdt,TenseurHHHH& d_sigma_deps_
,EnergieMeca & energ,const EnergieMeca &
,double& module_compressibilite,double& module_cisaillement
,const Met_abstraite::Umat_cont& ex)
{
#ifdef MISE_AU_POINT
if (epsBB_tdt.Dimension() != 2)
{ cout << "\nErreur : la dimension devrait etre 2 !\n";
cout << " Loi_ortho2D_C_entrainee::Calcul_dsigma_deps\n";
Sortie(1);
};
#endif
bool affichage = (Permet_affichage() > 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 <double> 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("<<a<<"): ";O_H(a).Affiche();
cout << "\n giH_0("<<a<<"): "; (*ex.giH_0)(a).Affiche();
//if ((*ex.giH_0)(a).Norme() < ConstMath::petit)
// cout << "\n debug lor_ortho pb ";
// cout << "\n alpha_H("<<a<<"): ";alpha_H(a).Affiche();
};
#endif
};
// 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
// récup du conteneur et affectation des coordonnées initiales
// Op_H(a) non normé a les mêmes coordonnées alpha_a^{.j}
// que O_H(a), 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("<<a<<"): ";
Op_H_a.Affiche();
cout << "\n giB_tdt("<<a<<"): "; (*ex.giB_tdt)(a).Affiche();
cout << "\n giH_tdt("<<a<<"): "; (*ex.giH_tdt)(a).Affiche();
// affichage du repère tournée
CoordonneeB V(dim);
for (int j=1;j<= 2;j++) V += (*ex.giB_tdt)(j) * Op_H_a(j);
cout << "\n op_H("<<a<<"): en absolu " << V ;
};
#endif
};
}
else
// transport de type covariant
{ // on calcule les coordonnées de la base O' dans la base duale
#ifdef MISE_AU_POINT
if (save_resul.O_B == 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
BaseB& O_B = (*save_resul.O_B); // pour simplifier
for (int a=1; a<3;a++)
{ // tout d'abord la base non normalisée
CoordonneeB& Op_B_a = Op_B.CoordoB(a);
// calcul de la norme du vecteur Op_B_a
double norme = sqrt(Op_B_a * gijHH * Op_B_a);
// coordonnées finales
Op_B_a /= norme;
};
// maintenant on calcule la base Op_H correspondante
for (int i=1; i<3;i++)
Op_H.CoordoH(i) = Op_B.CoordoB(i) * gijHH;
};
// on calcul la matrice de passage de la base g_i vers la base O'_i
// O'_i = beta_i^{.j} * g_j
// et on a également \hat{\vec g}^i = {\beta}_{a}^{.i}~\hat{\vec O'}^a
// comme O'_i est déjà exprimé dans g_j, ses coordonnées sont directement béta
for (int i=1; i<3;i++)
for (int j=1; j<3;j++)
{ beta(i,j) = Op_H(i)(j);};
// puis on calcul les coordonnées de la base duale
beta_transpose = beta.Transpose();
gamma = beta_transpose.Inverse();
gamma_transpose = gamma.Transpose();
#ifdef MISE_AU_POINT
if (affichage)
{cout << "\n beta: ";beta.Affiche();
cout << "\n beta_transpose: ";beta_transpose.Affiche();
cout << "\n gamma: ";gamma.Affiche();
cout << "\n gamma_transpose: ";gamma_transpose.Affiche();
};
#endif
// changement de base (cf. théorie) : la matrice beta est telle que:
// gpB(i) = beta(i,j) * gB(j) <==> 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 <Fonction_nD* > 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 <double> & 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 <Ddl_enum_etendu>& li_enu_scal = pt_fonct->Li_enu_etendu_scalaire();
List_io <TypeQuelconque >& 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 <double> 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 <double> & 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="<<epsBB << " gijBB_tdt= " << gijBB << " gijHH_tdt= " << gijHH<<" ";
cout << "\n sighh="<<sigHH<<" "<< flush ;
};
#endif
// calcul de la déformation d'épaisseur
//\varepsilon_{33} = -\frac{1}{1 - \nu_{12}.\nu_{21}}\left[ (\nu_{13} + \nu_{23}.\nu_{12})~\varepsilon_{11} + (\nu_{23} + \nu_{13}.\nu_{21}) ~\varepsilon_{22}\right]
double nu21 = nu12*E2/E1;
save_resul.eps33 = -1/(1.-nu12*nu21)*(
epsBH(1,1)*(nu12*nu23 + nu13)+epsBH(2,2)*(nu23+nu13*nu21)
);
// traitement des énergies
energ.Inita(0.);
energ.ChangeEnergieElastique(0.5 * (sigHH && epsBB));
// -- calcul des modules
// on n'utilise plus la forme linéaire, mais à la place la variation relative de volume
// constaté, au sens d'une mesure logarithmique, sauf dans le cas où cette variation est trop petite
double var_surf = (*(ex.jacobien_tdt))/(*(ex.jacobien_0)); // la variation de surface
// on cherche à intégrer la variation d'épaisseur calculée avec eps33
double var_epai = 0.; // init
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)= 1/2 * (1. - 1./(var_epai)^2), en orthonormee
var_epai = sqrt(1./(1.-2.* save_resul.eps33));
};
break;
case DEFORMATION_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEFORMATION_CUMU_LOGARITHMIQUE :
// cas d'une def logarithmique ou une approximation
{ // eps_33 = log(var_epai);
var_epai = exp(save_resul.eps33);
};
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_ortho2D_C_entrainee::Calcul_DsigmaHH_tdt (... \n";
Sortie(1);
};
// calcul de la valeur de la variation relative de volume en log
double log_var_vol = log((*(ex.jacobien_tdt))/(*(ex.jacobien_0))*var_epai);
// pour le module de compressibilité, choix entre les différents cas
if ((cas_calcul == 0) || (cas_calcul == 2))
{if (log_var_vol > 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 <Tenseur2HH> d_beta_HH(2,2);
Tableau2 <Tenseur2HH> 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("<<a<<","<<i<<")= "
<< (beta(a,i)-alpha_H_a(i))<< " num: "<<d_beta_num
<< " beta(a,i)= " << beta(a,i) << " alpha_H_a(i)= " << alpha_H_a(i) ;
}
}
};
Sortie(1);
*/
// on calcule maintenant la variation de gamma
Tableau2 <Tenseur2HH> 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("<<a<<","<<i<<")= "
<< (beta(a,i)-alpha_H_a(i))<< " num: "<<d_beta_num
<< " beta(a,i)= " << beta(a,i) << " alpha_H_a(i)= " << alpha_H_a(i) ;
}
}
};
*/
//variation des déformations epsHH / eps_ij dans le repère initial gi
// Tenseur2HHHH var_eps_nm_kl_HHHH(Tenseur2HHHH::Prod_tensoriel_barre(gijHH,gijHH));
//--// Tenseur2HHHH var_eps_nm_kl_HHHH(Tenseur2HHHH::Prod_tensoriel_croise(gijHH,gijHH));
//cout << "\n (1) var_eps_nm_kl_HHHH= ";
//var_eps_nm_kl_HHHH.Affiche_bidim(cout);
//{// pour vérification on va calculer par composante
// Tenseur2HHHH deps_nmkl;
// for (int n=1;n<3;n++) for (int m=1;m<3;m++) for (int k=1;k<3;k++) for (int l=1;l<3;l++)
// { double inter= gijHH(n,k) * gijHH(l,m);
// deps_nmkl.Change(n,m,k,l,inter);
// };
// cout << "\n (1) deps_nmkl= calcul en composantes";
// deps_nmkl.Affiche_bidim(cout);
//}
// Tenseur2HHHH interHHHH1(Tenseur2HHHH::Prod_tensoriel_barre(gijHH,eps_p_HH));
// Tenseur2HHHH interHHHH2(Tenseur2HHHH::Prod_tensoriel_barre(eps_p_HH,gijHH));
//--// Tenseur2HHHH interHHHH1(Tenseur2HHHH::Prod_tensoriel_croise(gijHH,eps_HH));
//--// Tenseur2HHHH interHHHH2(Tenseur2HHHH::Prod_tensoriel_croise(eps_HH,gijHH));
//Tenseur2HHHH interHHHH2(interHHHH1+interHHHH2);
//cout << "\n interHHHH2= ";
//interHHHH2.Affiche_bidim(cout);
//cout << "\n interHHHH1= ";
//interHHHH1.Affiche_bidim(cout);
//cout << "\n interHHHH2= ";
//interHHHH2.Affiche_bidim(cout);
//{Tenseur2HHHH A(interHHHH2);
//A += interHHHH2;
//cout << "\n A= ";A.Affiche_bidim(cout);
//Tenseur2HHHH B(var_eps_nm_kl_HHHH);
//cout << "\n (1) B= ";B.Affiche_bidim(cout);
//B -= 2. * interHHHH2;
//cout << "\n B= ";B.Affiche_bidim(cout);
//
//}
//--// var_eps_nm_kl_HHHH -= 2. * (interHHHH1+interHHHH2);
//Tenseur2HHHH::Prod_tensoriel_barre(gijHH,eps_p_HH);
//(interHHHH1+interHHHH2);
//--//cout << "\n var_eps_nm_kl_HHHH: ";
//--//var_eps_nm_kl_HHHH.Affiche_bidim(cout);
/*
// vérif numérique de la variation
{Tenseur2HH delta_eps = var_eps_nm_kl_HHHH && epsBB;
cout << "\n delta_eps= "; delta_eps.Ecriture(cout);
Tenseur2HH eps_p_HH(gijHH * epsBB * gijHH);
cout <<"\n eps_p_HH en g_i: "; eps_p_HH.Ecriture(cout);
// vérif var de g^ij
Tenseur2HHHH d_gijHH(Tenseur2HHHH::Prod_tensoriel_croise(gijHH,gijHH));
d_gijHH *= -2.;
Tenseur2HH delta_gijHH(gijHH-(*ex.gijHH_0));
Tenseur2HH delta_gijHH_num = d_gijHH && epsBB;
cout << "\n delta_gijHH= "; delta_gijHH.Ecriture(cout);
cout << "\n delta_gijHH_num (1) "; delta_gijHH_num.Ecriture(cout);
for (int n=1;n<3;n++) for (int m=1;m<3;m++)
{delta_gijHH_num.Coor(n,m)=0;
for (int i=1;i<3;i++) for (int j=1;j<3;j++)
delta_gijHH_num.Coor(n,m) += d_gijHH(n,m,i,j) * epsBB(i,j);
}
cout << "\n delta_gijHH_num (2)) = "; delta_gijHH_num.Ecriture(cout);
for (int n=1;n<3;n++) for (int m=1;m<3;m++)
{delta_gijHH_num.Coor(n,m)=0;
for (int i=1;i<3;i++) for (int j=1;j<3;j++)
delta_gijHH_num.Coor(n,m) += -2.* gijHH(n,i) * gijHH(j,m) * epsBB(i,j);
}
cout << "\n delta_gijHH_num (2)) = "; delta_gijHH_num.Ecriture(cout);
Tenseur2HHHH d_gijHH_num;
for (int n=1;n<3;n++) for (int m=1;m<3;m++)
for (int i=1;i<3;i++) for (int j=1;j<3;j++)
d_gijHH_num.Change(n,m,i,j,(-2.* gijHH(n,i) * gijHH(j,m))) ;
for (int n=1;n<3;n++) for (int m=1;m<3;m++)
for (int i=1;i<3;i++) for (int j=1;j<3;j++)
{ cout << "\n d_gijHH("<<n <<","<<m<<","<<i<<","<<j<<") et "
<< " -2.* gijHH("<<n<<","<<i<<") * gijHH("<<j<<","<<m<<")= et d_gijHH_num "
<< d_gijHH(n,m,i,j) << " "
<< (-2.* gijHH(n,i) * gijHH(j,m))<< " "
<< d_gijHH_num(n,m,i,j) ;
}
}
*/
//{Tenseur2HH A(1,2,2,0.,0.,0.);
// Tenseur2HH B(4,5,6,0.,0.,0.);
// Tenseur2HHHH C(Tenseur2HHHH::Prod_tensoriel(A,B));
//cout << "\n C= ";C.Affiche_bidim(cout);
// Tenseur2HHHH C1(Tenseur2HHHH::Prod_tensoriel_barre(A,B));
//cout << "\n Prod_tensoriel_barre(A,B)= ";C1.Affiche_bidim(cout);
// Tenseur2HHHH C2(Tenseur2HHHH::Prod_tensoriel_croise(A,B));
//cout << "\n Prod_tensoriel_croise(A,B)= ";C2.Affiche_bidim(cout);
// Tenseur2HHHH C2(Tenseur2HHHH::Prod_tensoriel_croise_croise(A,B));
//cout << "\n Prod_tensoriel_croise_croise(A,B)= ";C2.Affiche_bidim(cout);
//}
//--// var_eps_nm_kl_HHHH -= 2. * (interHHHH1+interHHHH2);
// on calcul par composante car il y a des pb de symétrie qui sont difficiles à maîtriser
// en tensoriel avec un stockage symétrique (il faudra peut-être essayer d'améliorer via les tenseurs
// généraux) mais cela doit-être cependant assez efficace !
TenseurQ2geneHHHH deps_nmkl_HHHH;
{for (int n=1;n<3;n++) for (int m=1;m<3;m++) for (int k=1;k<3;k++) for (int l=1;l<3;l++)
{ double inter= gijHH(n,k) * gijHH(l,m)
-2.*(gijHH(n,k) * epsHH(l,m) + epsHH(n,l) * gijHH(m,k));
deps_nmkl_HHHH.Change(n,m,k,l,inter);
};
//// vérification du stockage
//cout << "\n deps_nmkl= calcul en composantes";
//for (int n=1;n<3;n++) for (int m=1;m<3;m++) for (int k=1;k<3;k++) for (int l=1;l<3;l++)
// { double inter= gijHH(n,k) * gijHH(l,m)
// -2.*(gijHH(n,k) * epsHH(l,m) + epsHH(n,l) * gijHH(m,k));
// cout << "\n deps_nmkl("<<n <<","<<m<<","<<k<<","<<l<<") = et formule directe "
// << inter <<" " << deps_nmkl_HHHH(n,m,k,l);
// };
};
// OK vérif variation deps_nmkl_HHHH
/*{
Tenseur2HH delta_epsHH_num;
for (int n=1;n<3;n++) for (int m=1;m<3;m++)
{delta_epsHH_num.Coor(n,m)=0;
for (int i=1;i<3;i++) for (int j=1;j<3;j++)
delta_epsHH_num.Coor(n,m) += deps_nmkl_HHHH(n,m,i,j) * epsBB(i,j);
}
cout << "\n delta_epsHH_num = "; delta_epsHH_num.Ecriture(cout);
cout << "\n epsHH = "; epsHH.Ecriture(cout);
}
Sortie(1);
*/
//variation des déformations epsHH / eps_ij dans le repère transporté / au eps_kl
// c'est à dire la variation de eps^ab / eps_kl
//--// Tenseur2HHHH var_eps_ab_kl_HHHH = Tenseur2HHHH::Var_tenseur_dans_nouvelle_base
//--// (gamma,var_eps_nm_kl_HHHH,d_gamma_HH,eps_p_HH);
//--//cout << "\n var_eps_ab_kl_HHHH= ";
//--//var_eps_ab_kl_HHHH.Affiche_bidim(cout);
// on calcul par composante car il y a des pb de symétrie qui sont difficiles à maîtriser
// en tensoriel avec un stockage symétrique (il faudra peut-être essayer d'améliorer via les tenseurs
// généraux) mais cela doit-être cependant assez efficace !
TenseurQ2geneHHHH deps_abkl_HHHH;
{for (int a=1;a<3;a++) for (int b=1;b<3;b++) for (int k=1;k<3;k++) for (int l=1;l<3;l++)
{ double inter= 0.;
for (int n=1;n<3;n++) for (int m=1;m<3;m++)
inter += d_gamma_HH(a,n)(k,l) * epsHH(n,m) * gamma(b,m)
+ gamma(a,n) * deps_nmkl_HHHH(n,m,k,l) * gamma(b,m)
+ gamma(a,n) * epsHH(n,m) * d_gamma_HH(b,m)(k,l);
deps_abkl_HHHH.Change(a,b,k,l,inter);
};
//cout << "\n deps_abkl= calcul en composantes";
//deps_abkl.Affiche_bidim(cout);
};
// OK vérif numérique de la variation
/*{
Tenseur2HH delta_eps_ab_HH_num;
for (int n=1;n<3;n++) for (int m=1;m<3;m++)
{delta_eps_ab_HH_num.Coor(n,m)=0;
for (int i=1;i<3;i++) for (int j=1;j<3;j++)
delta_eps_ab_HH_num.Coor(n,m) += deps_abkl_HHHH(n,m,i,j) * epsBB(i,j);
}
cout << "\n delta_eps_ab_HH_num = "; delta_eps_ab_HH_num.Ecriture(cout);
cout << "\n eps_p_HH = "; eps_p_HH.Ecriture(cout);
Sortie(1);
}
*/
// variation des contraintes (composantes dans le repère transporté) / au eps_kl
//--// Tenseur2HHHH var_sig_ab_kl_HHHH = var_sig_ab_cd_HHBB && var_eps_ab_kl_HHHH;
TenseurQ2geneHHHH dsig_abkl_HHHH;
{// pour vérification on va calculer par composante
for (int a=1;a<3;a++) for (int b=1;b<3;b++) for (int k=1;k<3;k++) for (int l=1;l<3;l++)
{ double inter= 0.;
for (int n=1;n<3;n++) for (int m=1;m<3;m++)
inter += var_sig_ab_cd_HHBB(a,b,n,m) * deps_abkl_HHHH(m,n,k,l);
dsig_abkl_HHHH.Change(a,b,k,l,inter);
};
// cout << "\n dsig_abkl= calcul en composantes";
// dsig_abkl.Affiche_bidim(cout);
};
//cout << "\n var_sig_ab_kl_HHHH= ";
//var_sig_ab_kl_HHHH.Affiche_bidim(cout);
// OK vérif numérique de la variation
/*{
Tenseur2HH delta_sigma_ab_HH_num;
for (int n=1;n<3;n++) for (int m=1;m<3;m++)
{delta_sigma_ab_HH_num.Coor(n,m)=0;
for (int i=1;i<3;i++) for (int j=1;j<3;j++)
delta_sigma_ab_HH_num.Coor(n,m) += dsig_abkl_HHHH(n,m,i,j) * epsBB(i,j);
}
cout << "\n delta_sigma_ab_HH_num = "; delta_sigma_ab_HH_num.Ecriture(cout);
cout << "\n sigma_ab_HH = "; sig_sauveHH.Ecriture(cout);
Sortie(1);
}
*/
// variation des contraintes (composantes dans le repère g_i ) / au eps_kl
// on peut maintenant calculer la variation de sig_ij / eps_kl
//--// d_sigma_deps = Tenseur2HHHH::Var_tenseur_dans_nouvelle_base
//--// (beta_transpose,var_sig_ab_kl_HHHH,d_beta_transpose_HH,sigHH);
// on calcul par composante car il y a des pb de symétrie qui sont difficiles à maîtriser
// en tensoriel avec un stockage symétrique (il faudra peut-être essayer d'améliorer via les tenseurs
// généraux) mais cela doit-être cependant assez efficace !
TenseurQ2geneHHHH dsig_ijkl_HHHH;
{for (int i=1;i<3;i++) for (int j=1;j<3;j++) for (int k=1;k<3;k++) for (int l=1;l<3;l++)
{ double inter= 0.;
for (int a=1;a<3;a++) for (int b=1;b<3;b++)
inter += d_beta_HH(a,i)(k,l) * sig_ab_HH(a,b) * beta(b,j)
+ beta(a,i) * dsig_abkl_HHHH(a,b,k,l) * beta(b,j)
+ beta(a,i) * sig_ab_HH(a,b) * d_beta_HH(b,j)(k,l);
dsig_ijkl_HHHH.Change(i,j,k,l,inter);
};
//cout << "\n deps_abkl= calcul en composantes";
//deps_abkl.Affiche_bidim(cout);
};
// vérif numérique de la variation
/*{
Tenseur2HH delta_sigma_ij_HH_num;
for (int n=1;n<3;n++) for (int m=1;m<3;m++)
{delta_sigma_ij_HH_num.Coor(n,m)=0;
for (int i=1;i<3;i++) for (int j=1;j<3;j++)
delta_sigma_ij_HH_num.Coor(n,m) += dsig_ijkl_HHHH(n,m,i,j) * epsBB(i,j);
}
cout << "\n delta_sigma_ij_HH_num = "; delta_sigma_ij_HH_num.Ecriture(cout);
cout << "\n sigma_ij_HH = "; sigHH.Ecriture(cout);
Sortie(1);
}
*/
// on passe au tenseur de retour
d_sigma_deps.TransfertDunTenseurGeneral(dsig_ijkl_HHHH.Symetrise1et2_3et4());
//cout << "\n d_sigma_deps= ";
//d_sigma_deps.Affiche_bidim(cout);
//
// d_sigma_deps = Tenseur2HHHH::Var_tenseur_dans_nouvelle_base
// (beta,var_sig_ab_kl_HHHH,d_beta_HH,sigHH);
//
//cout << "\n (2) d_sigma_deps= ";
//d_sigma_deps.Affiche_bidim(cout);
// Sortie(1);
/* // 1) la variation de d eps_ij / d eps_kl (dans le repère natuelle
// ici on utilise le fait que IdBB2(i,j) représente le kronecker et idem pour IdHH2(i,j)
// donc on met la variance qui va bien mais elle n'est pas utilisée
// var_eps_ab_BBHH(i,j,k,l) = delta_i^k * delta_j^l : puis avec les symétries
// car on peut changer i et j d'une part et k et l d'autre part
Tenseur2BBHH var_eps_ij_kl_BBHH(Tenseur2BBHH::Prod_tensoriel_barre(IdBB2,IdHH2));
// 2) la variation d eps_ab / d eps_ij
Tenseur2BBHH var_eps_ab_kl_BBHH = Tenseur2BBHH::Var_tenseur_dans_nouvelle_base
(beta,var_eps_ij_kl_BBHH,d_beta_HH,eps_p_BB);
// maintenant on calcul la variation de sigma_ab / d epsilon_kl
Tenseur2BBHH var_sig_ab_kl_BBHH = var_sig_ab_cd_BBHH && var_eps_ab_kl_BBHH;
// calcul de la variation de l'inverse de beta
// beta_inv = beta.Inverse();
Tableau2 <Tenseur2HH> d_beta_inv_HH(2,2);
for (int b=1;b<3;b++)
for (int j=1;j<3;j++)
{Tenseur2HH& resHH = d_beta_inv_HH(j,b);
for (int a=1;a<3;a++)
for (int i=1;i<3;i++)
resHH -= (beta_inv(j,a) * beta_inv(i,b)) * d_beta_HH(a,i);
};
// on peut maintenant calculer la variation de sig_ij / eps_kl
Tenseur2BBHH var_sig_ij_kl_BBHH = Tenseur2BBHH::Var_tenseur_dans_nouvelle_base
(beta_inv,var_sig_ab_kl_BBHH,d_beta_inv_HH,sig_BB);
// calcul de la variation de \hat g^ij
Tenseur2HHHH gijkl_HHHH(Tenseur2HHHH::Prod_tensoriel_barre(gijHH,gijHH));
Tenseur2HHHH d_gij_kl_HHHH(-2.*Tenseur2HHHH::Prod_tensoriel_barre(gijHH,gijHH));
Tenseur2HHBB interHHBB(Tenseur2HHBB::Prod_tensoriel_barre(gijHH,sig_BB));
// puis on calcul l'opérateur tangent dans la la bonne variance
d_sigma_deps = (gijkl_HHHH && var_sig_ij_kl_BBHH)
+ (d_gij_kl_HHHH && (Tenseur2BBHH::Prod_tensoriel_barre(sig_BB,gijHH)))
+ (interHHBB && d_gij_kl_HHHH);
*/
LibereTenseur();
LibereTenseurQ();
};
//vérification de la convexité du potentiel
bool Loi_ortho2D_C_entrainee::Verif_convexite()
{ // double E1,E2,E3,nu12,nu13,nu23,G12,G13,G23; // paramètres de la loi
//1. - \nu_{12} . \nu_{13} . \nu_{23}. \left ( \frac{E_3}{E_1} - \frac{E_2}{E_1}. \frac{E_3}{E_2} \right ) - \nu_{12}^2 . \frac{E_2}{E_1}-\nu_{13}^2 . \frac{E_3}{E_1}-\nu_{23}^2 . \frac{E_3}{E_2} > 0
bool convexe = true; // vrai a priori
bool affichage = (Permet_affichage() > 0);
if (1. <= nu12*nu12*E2/E1)
{if (affichage)
cout << "\n attention nu12*nu12*E2/E1 = "<<(nu12*nu12*E2/E1) << ", etant superieur a 1. "
<< " le potentiel n'est pas strictement convexe! ";
convexe = false;
};
if (1. <= nu23*nu23*E3/E2)
{if (affichage)
cout << "\n attention nu23*nu23*E3/E2 = "<<(nu23*nu23*E3/E2) << ", etant superieur a 1. "
<< " le potentiel n'est pas strictement convexe! ";
convexe = false;
};
if (1. <= nu13*nu13*E3/E1)
{if (affichage)
cout << "\n attention nu13*nu13*E3/E1 = "<<(nu13*nu13*E3/E1) << ", etant superieur a 1. "
<< " le potentiel n'est pas strictement convexe! ";
convexe = false;
};
double x = 1. - nu12 * nu13 * nu23 * (E3/E1 - E2/E1 * E3/E2)
- nu12*nu12 * E2/E1 - nu13*nu13 * E3/E1 - nu23*nu23 * E3/E2 ;
if (x <= 0)
{if (affichage)
cout << "\n attention: 1. - nu12*nu13*nu23*(E3/E1-E2/E1*E3/E2)"
<< " - nu12*nu12 * E2/E1 - nu13*nu13 * E3/E1 - nu23*nu23 * E3/E2 = "
<< x << ", etant inferieur ou egal a 0 "
<< " le potentiel n'est pas strictement convexe! ";
convexe = false;
};
// retour
return convexe;
};