Herezh_dev/comportement/anisotropie/Hypo_ortho3D_entrainee.cc
Gérard Rio a317216f06 V 7.021 - 7.023
- modification des sorties post pour loi hypo 2D_C et 1D_C
- corr bug lecture fct_nD avec toutes les lois hypo isotropes
- corr bug sur le calcul de la compressibilité pour les loi hypo 2D_C
- première mise en place du calcul parallèle sur le contact
- ajout d'une fct nD pour gérer le niveau de commentaire sur LesContacts (indépendante de celle qui gère le niveau de commentaire concernant les éléments de contact)
- amélioration de la méthode d'initialisation du contact, utilisée en début d'incrément
2024-01-30 20:55:48 +01:00

3115 lines
136 KiB
C++
Executable file

// FICHIER : Hypo_ortho3D_entrainee.cc
// CLASSE : Hypo_ortho3D_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 "Hypo_ortho3D_entrainee.h"
#include "NevezTenseur.h"
#include "MathUtil.h"
#include "Util.h"
#include "Enum_TypeQuelconque.h"
#include "TypeQuelconqueParticulier.h"
#include "TenseurQ3gene.h"
#include "MathUtil.h"
#include "MathUtil2.h"
#include "CharUtil.h"
// ========== fonctions pour la classe de sauvegarde des résultats =========
// constructeur par défaut
Hypo_ortho3D_entrainee::SaveResulHypo_ortho3D_entrainee::SaveResulHypo_ortho3D_entrainee(const int type_transport):
O_B(NULL), O_H(NULL),Op_H(3,3),Op_H_t(3,3)
,eps_loc_HH(NULL),sig_loc_HH(NULL),delta_eps_loc_HH(NULL),delta_sig_loc_HH(NULL)
,para_loi(NULL)
{
// non on ne fait pas de définition par défaut
// if (type_transport == 0)
// {O_H = new BaseH(); sig_loc_HH = NevezTenseurHH(3); }
// else
// {O_B = new BaseB(); eps_loc_HH = NevezTenseurHH(3); };
};
// constructeur de copie
Hypo_ortho3D_entrainee::SaveResulHypo_ortho3D_entrainee::SaveResulHypo_ortho3D_entrainee(const SaveResulHypo_ortho3D_entrainee& sav):
O_B(NULL), O_H(NULL),Op_H(3,3),Op_H_t(3,3)
,eps_loc_HH(NULL),sig_loc_HH(NULL),delta_eps_loc_HH(NULL),delta_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.delta_eps_loc_HH != NULL)
delta_eps_loc_HH = NevezTenseurHH(*sav.delta_eps_loc_HH);
if (sav.delta_sig_loc_HH != NULL)
delta_sig_loc_HH = NevezTenseurHH(*sav.delta_sig_loc_HH);
if (sav.para_loi != NULL)
para_loi = new Vecteur (*sav.para_loi);
};
// destructeur
Hypo_ortho3D_entrainee::SaveResulHypo_ortho3D_entrainee::~SaveResulHypo_ortho3D_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 (delta_eps_loc_HH != NULL)
delete delta_eps_loc_HH;
if (delta_sig_loc_HH != NULL)
delete delta_sig_loc_HH;
if (para_loi != NULL)
delete para_loi;
};
// affectation
Loi_comp_abstraite::SaveResul & Hypo_ortho3D_entrainee::SaveResulHypo_ortho3D_entrainee::operator = ( const Loi_comp_abstraite::SaveResul & a)
{ Hypo_ortho3D_entrainee::SaveResulHypo_ortho3D_entrainee& sav = *((Hypo_ortho3D_entrainee::SaveResulHypo_ortho3D_entrainee*) &a);
// 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.delta_eps_loc_HH != NULL)
{if (delta_eps_loc_HH == NULL) {delta_eps_loc_HH = NevezTenseurHH(*sav.delta_eps_loc_HH);}
else {*delta_eps_loc_HH = *sav.delta_eps_loc_HH;};
}
else // sinon cas NULL
{if (delta_eps_loc_HH != NULL) {delete delta_eps_loc_HH;delta_eps_loc_HH=NULL;}} ;
if (sav.delta_sig_loc_HH != NULL)
{if (delta_sig_loc_HH == NULL) {delta_sig_loc_HH = NevezTenseurHH(*sav.delta_sig_loc_HH);}
else {*delta_sig_loc_HH = *sav.delta_sig_loc_HH;};
}
else // sinon cas NULL
{if (delta_sig_loc_HH != NULL) {delete delta_sig_loc_HH; delta_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 Hypo_ortho3D_entrainee::SaveResulHypo_ortho3D_entrainee::Lecture_base_info(ifstream& ent,const int cas)
{ string nom;
ent >> nom ;
#ifdef MISE_AU_POINT
if (nom != "S_Ortho_3D")
{ cout << "\nErreur : on attendait le mot cle: S_Ortho_3D "
<< " et on a lue "<<nom;
cout << " Hypo_ortho3D_entrainee::SaveResulHypo_ortho3D_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 (delta_eps_loc_HH != NULL)
{delete delta_eps_loc_HH;delta_eps_loc_HH=NULL;}
if (delta_sig_loc_HH != NULL)
{delete delta_sig_loc_HH;delta_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(3);
ent >> nom ; eps_loc_HH->Lecture(ent);
if (sig_loc_HH == NULL) sig_loc_HH = NevezTenseurHH(3);
ent >> nom ; sig_loc_HH->Lecture(ent);
if (delta_eps_loc_HH == NULL) delta_eps_loc_HH = NevezTenseurHH(3);
ent >> nom ; delta_eps_loc_HH->Lecture(ent);
if (delta_sig_loc_HH == NULL) delta_sig_loc_HH = NevezTenseurHH(3);
ent >> nom ; delta_sig_loc_HH->Lecture(ent);
if (para_loi == NULL) para_loi = new Vecteur (9);
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 (delta_eps_loc_HH != NULL)
{delete delta_eps_loc_HH;delta_eps_loc_HH=NULL;}
if (delta_sig_loc_HH != NULL)
{delete delta_sig_loc_HH;delta_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(3);
ent >> nom ; eps_loc_HH->Lecture(ent);
if (sig_loc_HH == NULL) sig_loc_HH = NevezTenseurHH(3);
ent >> nom ; sig_loc_HH->Lecture(ent);
if (delta_eps_loc_HH == NULL) delta_eps_loc_HH = NevezTenseurHH(3);
ent >> nom ; delta_eps_loc_HH->Lecture(ent);
if (delta_sig_loc_HH == NULL) delta_sig_loc_HH = NevezTenseurHH(3);
ent >> nom ; delta_sig_loc_HH->Lecture(ent);
if (para_loi == NULL) para_loi = new Vecteur(9);
ent >> nom >> *para_loi;
};
break;
}
default:
cout << "\n cas non considere !!: cas= " << cas
<< "\n Hypo_ortho3D_entrainee::SaveResulHypo_ortho3D_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 Hypo_ortho3D_entrainee::SaveResulHypo_ortho3D_entrainee::Ecriture_base_info(ofstream& sort,const int cas )
{ sort << "\n S_Ortho_3D ";
// 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 << " sig_loc_HH: ";
sig_loc_HH->Ecriture(sort);
sort << "\n delta_eps_loc_HH: ";
delta_eps_loc_HH->Ecriture(sort);
sort << " delta_sig_loc_HH: ";
delta_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 << " sig_loc_HH: " ;
sig_loc_HH->Ecriture(sort);
sort << "\n delta_eps_loc_HH: ";
delta_eps_loc_HH->Ecriture(sort);
sort << " delta_sig_loc_HH: ";
delta_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 Hypo_ortho3D_entrainee::SaveResulHypo_ortho3D_entrainee::Ecriture_base_info(...";
Sortie(1);
};
};
// mise à jour des informations transitoires
void Hypo_ortho3D_entrainee::SaveResulHypo_ortho3D_entrainee::TdtversT()
{ Op_H_t = Op_H;
};
void Hypo_ortho3D_entrainee::SaveResulHypo_ortho3D_entrainee::TversTdt()
{ Op_H = Op_H_t;
};
// affichage à l'écran des infos
void Hypo_ortho3D_entrainee::SaveResulHypo_ortho3D_entrainee::Affiche() const
{ cout << "\n SaveResulHypo_ortho3D_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);
};
if (delta_eps_loc_HH != NULL)
{ cout << "\n delta_eps_loc_HH= "; delta_eps_loc_HH->Ecriture(cout);
};
if (delta_sig_loc_HH != NULL)
{ cout << "\n delta_sig_loc_HH= "; delta_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< 10;i++)
cout << " coef("<<i<<")= "<< (*para_loi)(i);
cout << " ";
};
cout << "\n .. fin SaveResulHypo_ortho3D_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 Hypo_ortho3D_entrainee::SaveResulHypo_ortho3D_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
if (O_B != NULL)
{for (int i=1;i<4;i++)
{ CoordonneeB Ap_B(3); // 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<4;i++)
{ CoordonneeH Ap_H(3); // 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<4;i++)
{ CoordonneeH Ap_H(3); // 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);};
// cas des grandeurs locales si elles sont sauvegardées
if (delta_eps_loc_HH != NULL)
{ delta_eps_loc_HH->ChBase(gamma);};
if (delta_sig_loc_HH != NULL)
{ delta_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* Hypo_ortho3D_entrainee::SaveResulHypo_ortho3D_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
Hypo_ortho3D_entrainee* loiOrtho = (Hypo_ortho3D_entrainee*) loi;
// dimensionnement des bases
if (loiOrtho->Type_transport() == 0)
{O_H = new BaseH(); sig_loc_HH = NevezTenseurHH(3); delta_sig_loc_HH = NevezTenseurHH(3); }
else
{O_B = new BaseB(); eps_loc_HH = NevezTenseurHH(3); delta_eps_loc_HH = NevezTenseurHH(3); };
// récupération du repère
if (bloc.Nom(2) == loiOrtho->NomRepere())
{// c'est le bon, récupération du repère
if (O_B != NULL)
{for (int i=1;i<4;i++)
O_B->CoordoB(i).Change_val(tab_coor(i));
};
if (O_H != NULL)
{for (int i=1;i<4;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 Hypo_ortho3D_entrainee::SaveResulHypo_ortho3D_entrainee::Init_debut_calcul()
{ };
// ========== fin des fonctions pour la classe de sauvegarde des résultats =========
Hypo_ortho3D_entrainee::Hypo_ortho3D_entrainee () : // Constructeur par defaut
Loi_comp_abstraite(HYPO_ORTHO3D,CAT_MECANIQUE,3)
,E1(-ConstMath::trespetit),E2(-ConstMath::trespetit),E3(-ConstMath::trespetit)
,nu12(-ConstMath::trespetit),nu13(-ConstMath::trespetit),nu23(-ConstMath::trespetit)
,G12(-ConstMath::trespetit),G13(-ConstMath::trespetit),G23(-ConstMath::trespetit)
,fct_para(9),cas_calcul(0)
,type_transport(0),type_derive(-1)
,sortie_post(0)
,nom_repere("")
,inv_loi(3,3),Op_B(3,3),d_Op_B(3,3),d_Op_H(3,3),pO_B(3,3),pO_H(3,3)
,beta_inv(3,3),beta(3,3),gamma(3,3),beta_transpose(3,3),gamma_transpose(3,3)
,alpha_H(3,3)
,I_x_I_HHHH(),I_xbarre_I_HHHH(),I_x_eps_HHHH(),Ixbarre_eps_HHHH()
{for (int i=1;i<=9;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
Hypo_ortho3D_entrainee::Hypo_ortho3D_entrainee(const double& EE1,const double& EE2,const double& EE3
,const double& nunu12,const double& nunu13,const double& nunu23
,const double& GG12,const double& GG13,const double& GG23
,const string& nom_rep):
Loi_comp_abstraite(HYPO_ORTHO3D,CAT_THERMO_MECANIQUE,3)
,E1(EE1),E2(EE2),E3(EE3),nu12(nunu12),nu13(nunu13),nu23(nunu23)
,G12(GG12),G13(GG13),G23(GG23)
,fct_para(9),cas_calcul(0)
,type_transport(0),type_derive(-1)
,sortie_post(0)
,nom_repere(nom_rep)
,inv_loi(3,3),Op_B(3,3),d_Op_B(3,3),d_Op_H(3,3),pO_B(3,3),pO_H(3,3)
,beta_inv(3,3),beta(3,3),gamma(3,3),beta_transpose(3,3),gamma_transpose(3,3)
,alpha_H(3,3)
,I_x_I_HHHH(),I_xbarre_I_HHHH(),I_x_eps_HHHH(),Ixbarre_eps_HHHH()
{for (int i=1;i<=9;i++)
fct_para(i) = NULL;
null_fct_para=1; // pour l'instant pas de fonction
};
// Constructeur de copie
Hypo_ortho3D_entrainee::Hypo_ortho3D_entrainee (const Hypo_ortho3D_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),G13(loi.G13),G23(loi.G23)
,fct_para(loi.fct_para),cas_calcul(loi.cas_calcul)
,inv_loi(loi.inv_loi),Op_B(3,3),d_Op_B(3,3),d_Op_H(3,3),pO_B(3,3),pO_H(3,3)
,beta_inv(3,3),beta(3,3),gamma(3,3),beta_transpose(3,3),gamma_transpose(3,3)
,alpha_H(3,3)
,type_derive(loi.type_derive),type_transport(loi.type_transport)
,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<=9;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));
};
};
};
};
Hypo_ortho3D_entrainee::~Hypo_ortho3D_entrainee ()
// Destructeur
{ for (int i=1;i<=9;i++)
{if (fct_para(i) != NULL)
if (fct_para(i)->NomFonction() == "_") delete fct_para(i);
};
};
// Lecture des donnees de la classe sur fichier
void Hypo_ortho3D_entrainee::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D
,LesFonctions_nD& lesFonctionsnD)
{
// on lit les coefficients dans l'ordre
string nom_class_methode("Hypo_ortho3D_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(9);
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";tab_mot_cle(8) = "G13";tab_mot_cle(9) = "G23";
// puis un tableau pour les valeurs
Tableau < double * > coef(9);
coef(1) = &E1; coef(2) = & E2; coef(3) = &E3;
coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23;
coef(7) = & G12; coef(8) = & G13; coef(9) = & G23;
// on boucle sur les 9 coefficients
for (int i=1;i<=9;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);
};
};
entreePrinc->NouvelleDonnee(); // on se positionne sur un nouvel enreg
};
}; // fin de la boucle for (int i=1;i<=9;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 Hypo_ortho3D_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 Hypo_ortho3D_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 Hypo_ortho3D_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;
};
}
// on regarde ensuite si le type de dérivée est indiqué
else if (nom == "type_derivee")
{ // lecture du type
string toto;
*(entreePrinc->entree) >> toto >> type_derive;
if ((type_derive!=0)&&(type_derive!=-1)&&(type_derive!=1))
{ cout << "\n le type de derivee indique pour la loi Hypo_ortho3D_entrainee: "<< type_derive
<< " n'est pas acceptable (uniquement -1 ou 0 ou 1), on utilise le type par defaut (-1 -> Jauman)"
<< " qui correspond à la derivee mixte de Lie deux fois covariantes, deux fois contravariantes";
type_derive = -1;
};
}
// 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;};}
// 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 Hypo_ortho3D_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 commence par remplir la matrice
inv_loi(1,1) = 1./E1;inv_loi(2,2) = 1./E2;inv_loi(3,3) = 1./E3;
inv_loi(1,2) = inv_loi(2,1) = -nu12/E1;
inv_loi(1,3) = inv_loi(3,1) = -nu13/E1;
inv_loi(3,2) = inv_loi(2,3) = -nu23/E2;
inv_loi = inv_loi.Inverse(); // on inverse la matrice
};
};
// affichage de la loi
void Hypo_ortho3D_entrainee::Affiche() const
{ // pour faire une boucle on constitue un tableau de mots clés
Tableau <string > tab_mot_cle(9);
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";tab_mot_cle(8) = "G13";tab_mot_cle(9) = "G23";
// puis un tableau pour les valeurs
Tableau < const double * > coef(9);
coef(1) = &E1; coef(2) = & E2; coef(3) = &E3;
coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23;
coef(7) = & G12; coef(8) = & G13; coef(9) = & G23;
// on boucle sur les 9 coefficients
cout << "\n loi de comportement orthotrope elastique 3D ";
for (int i=1;i<=9;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;
// et du type de dérivée objective
switch (type_derive)
{ case -1: cout << ", et derivee de jauman pour la contrainte" << endl;break;
case 0: cout << ", et derivee de Lie deux fois covariantes (Rivlin) pour la contrainte" << endl; break;
case 1: cout << ", et derivee de Lie deux fois contravariantes (Oldroyd) pour la contrainte" << endl; break;
};
// niveau d'affichage
Affiche_niveau_affichage();
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 Hypo_ortho3D_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(9);
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";tab_mot_cle(8) = "G13";tab_mot_cle(9) = "G23";
// puis un tableau pour les valeurs
Tableau < double * > coef(9);
coef(1) = &E1; coef(2) = & E2; coef(3) = &E3;
coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23;
coef(7) = & G12; coef(8) = & G13; coef(9) = & G23;
E1=100000; E2= 50000; E3= 20000;
nu12= 0.2; nu13 = 0.3; nu23 = 0.1;
G12 = 20000; G13 = 10000; G23 = 2000;
sort << "\n# ....... loi de comportement hypo elastique orthotrope 3D ........"
<< "\n# 9 parametres materiau: 3 modules tangent de traction, 3 coef type Poisson"
<< "\n# , 3 modules type cisaillement tangent "
<< "\n# et un nom de repere associe \n";
for (int i=1;i<=9;i++)
{string mot_cle1=tab_mot_cle(i)+"= ";
string mot_cle2=tab_mot_cle(i)+"_fonction_nD:";
if ((i==3)||(i==6)) sort << " \\ \n";
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 E3 soit une fonction nD on ecrira: "
<<"\n# soit a: "
<<"\n# E3= E3_fonction_nD: un_nom_de_fonction_existant "
<<"\n# soit b: "
<<"\n# E3= E3_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# E3= E3_fonction_nD: f1_temperature "
<<"\n# fi_temperature doit alors avoir ete definie dans les fonctions nD"
<<"\n# "
<<"\n# exemple d'un cas b: "
<<"\n# E3= E3_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 E3 par E1, ou E2, ou"
<<"\n# nu12 ou nu13 ou n23 ou G12 ou G13 ou G23 "
<<"\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) le type de derivee objective utilisee pour la contrainte, est optionnel: "
<< "\n# = -1 -> derivee de jauman (valeur par defaut), "
<< "\n# = 0 -> derivee deux fois covariantes (ou de Rivlin), "
<< "\n# = 1 -> derivee deux fois contravariantes (ou d'Oldroyd)"
<< "\n# dans le cas ou l'on veut une valeur differente de la valeur par defaut il faut mettre le mot cle"
<< "\n# type_derivee suivi de la valeur -1 ou 0 ou 1"
<<"\n# "
<<"\n# 4)"
<< "\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# 5) 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# "
<< "\n# 6) --------------- 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 Hypo_ortho3D_entrainee::TestComplet()
{ int ret = LoiAbstraiteGeneral::TestComplet();
// pour faire une boucle on constitue un tableau de mots clés
Tableau <string > tab_mot_cle(9);
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";tab_mot_cle(8) = "G13";tab_mot_cle(9) = "G23";
// puis un tableau pour les valeurs
Tableau < double * > coef(9);
coef(1) = &E1; coef(2) = & E2; coef(3) = &E3;
coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23;
coef(7) = & G12; coef(8) = & G13; coef(9) = & G23;
for (int i=1;i<=9;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 Hypo_ortho3D_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 Hypo_ortho3D_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 Hypo_ortho3D_entrainee::Grandeur_particuliere
(bool ,List_io<TypeQuelconque>& liTQ,Loi_comp_abstraite::SaveResul * saveDon,list<int>& decal) const
{ // ici on est en 3D 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())
{ case REPERE_D_ANISOTROPIE:
// a) ----- cas du repère d'anisotropie
{ SaveResulHypo_ortho3D_entrainee & save_resul = *((SaveResulHypo_ortho3D_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 Hypo_ortho3D_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
{ SaveResulHypo_ortho3D_entrainee & save_resul = *((SaveResulHypo_ortho3D_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
{ SaveResulHypo_ortho3D_entrainee & save_resul = *((SaveResulHypo_ortho3D_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 DELTA_EPS_TRANSPORTEE_ANISO:
// ----- cas de la déformation transportée dans le repère d'orthotropie
{ SaveResulHypo_ortho3D_entrainee & save_resul = *((SaveResulHypo_ortho3D_entrainee*) saveDon);
Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier
if (sortie_post) {tyTQ(1+(*idecal))= *(save_resul.delta_eps_loc_HH);}
else {tyTQ(1+(*idecal)).Inita(0.);};
(*idecal)++; break;
}
case DELTA_SIGMA_DANS_ANISO:
// ----- cas de la contrainte calculée dans le repère d'orthotropie
{ SaveResulHypo_ortho3D_entrainee & save_resul = *((SaveResulHypo_ortho3D_entrainee*) saveDon);
Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier
if (sortie_post) {tyTQ(1+(*idecal))= *(save_resul.delta_sig_loc_HH);}
else {tyTQ(1+(*idecal)).Inita(0.);};
(*idecal)++; break;
}
case PARA_ORTHO:
// ----- cas des paramètres d'orthotropie
{ SaveResulHypo_ortho3D_entrainee & save_resul = *((SaveResulHypo_ortho3D_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 Hypo_ortho3D_entrainee::ListeGrandeurs_particulieres(bool absolue,List_io<TypeQuelconque>& liTQ) const
{
// $$$ cas du repère local d'orthotropie
int dim_espace = 3;
{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,3);
Tab_Grandeur_BaseH grand5(v_rep,1); // def d'une grandeur courante
TypeQuelconque typQ6(REPERE_D_ANISOTROPIE,EPS11,grand5);
liTQ.push_back(typQ6);
};
};
// ---- 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(3); // 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(3); // 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 de delta 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() == DELTA_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(3); // un tenseur typique
Tab_Grandeur_TenseurHH delta_eps_loc_HH(*tens,1);
// def d'un type quelconque représentatif
TypeQuelconque typQ(DELTA_EPS_TRANSPORTEE_ANISO,EPS11,delta_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() == DELTA_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(3); // un tenseur typique
Tab_Grandeur_TenseurHH delta_sig_loc_HH(*tens,1);
// def d'un type quelconque représentatif
TypeQuelconque typQ(DELTA_SIGMA_DANS_ANISO,SIG11,delta_sig_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(9); // les 9 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 Hypo_ortho3D_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 != "ORTHOELAS3D")
{cout <<"\n *** erreur en lecture du type de la loi de comportement, on attendait"
<< " la chaine de caracteres: ORTHOELAS3D et on a lu "
<< nom <<" !!! on ne peut pas continuer "
<< "\n Hypo_ortho3D_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(9);
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";tab_mot_cle(8) = "G13";tab_mot_cle(9) = "G23";
// puis un tableau pour les valeurs
Tableau < double * > coef(9);
coef(1) = &E1; coef(2) = & E2; coef(3) = &E3;
coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23;
coef(7) = & G12; coef(8) = & G13; coef(9) = & G23;
// cela va permettre de choisir entre une valeur fixe et une fonction nD
for (int i=1;i<10;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 type de dérivée objective
ent >> nom >> type_derive;
// 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 Hypo_ortho3D_entrainee::Ecriture_base_info_loi(ofstream& sort,const int cas)
{ if (cas == 1)
{ sort << " ORTHOELAS3D " ;
// pour faire une boucle on constitue un tableau de mots clés
Tableau <string > tab_mot_cle(9);
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";tab_mot_cle(8) = "G13";tab_mot_cle(9) = "G23";
// puis un tableau pour les valeurs
Tableau < const double * > coef(9);
coef(1) = &E1; coef(2) = & E2; coef(3) = &E3;
coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23;
coef(7) = & G12; coef(8) = & G13; coef(9) = & G23;
// on boucle sur les 9 coefficients
sort << "\n loi de comportement orthotrope elastique 3D ";
for (int i=1;i<10;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;
// type de dérivée objective
sort << " type_derive_objective: " << type_derive;
// niveau d'affichage
Affiche_niveau_affichage(sort,cas);
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 Hypo_ortho3D_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 Hypo_ortho3D_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 Hypo_ortho3D_entrainee::Module_compressibilite_equivalent(Enum_dure temps,const Deformation & def,SaveResul * )
{
if (null_fct_para)
{double unsurKs1 = 1./E1 - nu12/E1 -nu13/E1;
double unsurKs2 = -nu12/E1+1./E2-nu23/E2;
double unsurKs3 = -nu13/E1-nu23/E2+1./E3;
double module_compressibilite = 1./9.*(1./unsurKs1+1./unsurKs2+1./unsurKs3);
return module_compressibilite;
}
else
{
cout << "\n *** attention, methode non implante: "
<< "\n Hypo_ortho3D_entrainee::Module_compressibilite_equivalent(...";
Sortie(1);
};
/* 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));
};
*/ };
// ========== 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 Hypo_ortho3D_entrainee::Calcul_SigmaHH (TenseurHH& sigHH_t,TenseurBB& ,DdlElement & tab_ddl
,TenseurBB & gijBB_t,TenseurHH & ,BaseB& ,BaseH& ,TenseurBB& epsBB_
,TenseurBB& delta_epsBB_,TenseurBB& gijBB_
,TenseurHH & gijHH_,Tableau <TenseurBB *>& d_gijBB_,double& ,double&
,TenseurHH & sigHH_,EnergieMeca & energ,const EnergieMeca & energ_t
,double& module_compressibilite,double& module_cisaillement
,const Met_abstraite::Expli_t_tdt& ex)
{
#ifdef MISE_AU_POINT
if (epsBB_.Dimension() != 3)
{ cout << "\nErreur : la dimension devrait etre 3 !\n";
cout << " Hypo_ortho3D_entrainee::Calcul_SigmaHH\n";
Sortie(1);
};
#endif
const Tenseur3BB & epsBB = *((Tenseur3BB*) &epsBB_); // passage en dim 3
const Tenseur3BB & delta_epsBB = *((Tenseur3BB*) &delta_epsBB_); // passage en dim 3
const Tenseur3HH & gijHH = *((Tenseur3HH*) &gijHH_); // " " " "
const Tenseur3BB & gijBB = *((Tenseur3BB*) &gijBB_); // " " " "
Tenseur3HH & sigHH = *((Tenseur3HH*) &sigHH_); // " " " "
Tenseur3HH & sigHH_nn = *((Tenseur3HH*) &sigHH_t); // " " " "
// --- opération de transport du tenseur sigma(t), de t à tdt
// tenseur intermédiaires utilisées selon les cas (par forcément dans tous les cas !!)
Tenseur3BH sigBH_n;Tenseur3HH sigHH_n; Tenseur3BB sigBB_n;Tenseur3BB sig_interBB_n;
switch (type_derive) //case 1: cas d'une dérivée de Lie deux fois contravariante : cas par défaut
{case -1: // cas d'une dérivée de jauman: 1/2 deux fois covariant + deux fois contra
{sig_interBB_n = gijBB_t * sigHH_nn * gijBB_t;
sigBH_n = 0.5*( sig_interBB_n * gijHH + gijBB * sigHH_nn) ;
sigHH_n = gijHH * sigBH_n ;
sigBB_n = sigBH_n * gijBB; break;}
case 0: // cas d'une dérivée de Lie deux fois covariantes
{sigBB_n = gijBB_t * sigHH_nn * gijBB_t;
sigBH_n = sigBB_n * gijHH ;
sigHH_n = gijHH * sigBH_n ; break;}
case 1: // cas d'une dérivée de Lie deux fois contravariantes
{sigHH_n = sigHH_nn;
sigBH_n = gijBB * sigHH_n;
sigBB_n = sigBH_n * gijBB;
break;}
};
// ---- calcul relatif à l'incrément de contrainte -----
Tenseur3BH epsBH = epsBB * gijHH; // deformation en mixte
//---- le repère d'anisotropie
// récup du conteneur spécifique
SaveResulHypo_ortho3D_entrainee & save_resul = *((SaveResulHypo_ortho3D_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(3);
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 << " Hypo_ortho3D_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 < 4; a++)
{CoordonneeH& inter = alpha_H.CoordoH(a);
for (int i=1;i < 4;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<4;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;
//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();
};
}
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 << " Hypo_ortho3D_entrainee::Calcul_SigmaHH\n";
Sortie(1);
};
#endif
BaseB& O_B = (*save_resul.O_B); // pour simplifier
for (int a=1; a<4;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<4;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<4;i++)
for (int j=1; j<4;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();
//cout << "\n beta: ";beta.Affiche();
//cout << "\n beta_transpose: ";beta_transpose.Affiche();
//cout << "\n gamma: ";gamma.Affiche();
//cout << "\n gamma_transpose: ";gamma_transpose.Affiche();
// 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 l'incrément de déformation dans le repère O'^i
// c-a-d les coordonnées dans le dual de O'_i
// Tenseur3BB delta_eps_p_BB(delta_epsBB);
//cout <<"\n delta_eps_p_BB: "; delta_eps_p_BB.Ecriture(cout);
// il faut passer en 2 fois contravariant
Tenseur3HH delta_eps_p_HH = gijHH * delta_epsBB * gijHH;
delta_eps_p_HH.ChBase(gamma); // res = (gamma * res) * gamma.Transpose();
//cout <<"\n delta_eps_p_HH: "; delta_eps_p_HH.Ecriture(cout);
//Tenseur3HH toto(delta_eps_p_HH);
//toto.ChBase(beta_transpose);
//cout << "\n retour dans la base g^i de eps^{ij} :";toto.Ecriture(cout);
//Tenseur3BB titi(gijBB * toto * gijBB);
//cout << "\n delta def eps_ij :";titi.Ecriture(cout);
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(9);
coef(1) = &E1; coef(2) = & E2; coef(3) = &E3;
coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23;
coef(7) = & G12; coef(8) = & G13; coef(9) = & G23;
// 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<10;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 << " Hypo_ortho3D_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(3,3) = 1./E3;
inv_loi(1,2) = inv_loi(2,1) = -nu12/E1;
inv_loi(1,3) = inv_loi(3,1) = -nu13/E1;
inv_loi(3,2) = inv_loi(2,3) = -nu23/E2;
inv_loi = inv_loi.Inverse(); // on inverse la matrice
};
// calcul de l'accroissement des contraintes dans le repère O_p
Vecteur delta_eps_ii(3);Vecteur delta_sig_ii(3);
for (int i=1; i<4;i++)
delta_eps_ii(i) = delta_eps_p_HH(i,i);
delta_sig_ii = inv_loi * delta_eps_ii;
// Tenseur3HH sig_HH;
// l'accroissement est stocké momentanément dans sigHH
// ensuite on ajoutera la contrainte à t transportée de t à tdt
for (int i=1; i<4;i++)
{sigHH.Coor(i,i) = delta_sig_ii(i);
};
sigHH.Coor(1,2) = 2.* G12 * delta_eps_p_HH(1,2);
sigHH.Coor(1,3) = 2.* G13 * delta_eps_p_HH(1,3);
sigHH.Coor(2,3) = 2.* G23 * delta_eps_p_HH(2,3);
// dans le cas où on veut une sortie des grandeurs on sauvegarde
if (sortie_post)
{ if (save_resul.delta_eps_loc_HH == NULL)
{save_resul.delta_eps_loc_HH = NevezTenseurHH(3);
save_resul.delta_sig_loc_HH = NevezTenseurHH(3);
save_resul.para_loi = new Vecteur (9);
save_resul.eps_loc_HH = NevezTenseurHH(3);
save_resul.sig_loc_HH = NevezTenseurHH(3);
};
(*save_resul.delta_eps_loc_HH) = delta_eps_p_HH;
(*save_resul.delta_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; (*save_resul.para_loi)(8) = G13;
(*save_resul.para_loi)(9) = G23;
};
// calcul de l'acroissement des contraintes dans le repère g_i
// l'inverse de gamma c'est beta transposée
sigHH.ChBase(beta_transpose);
// maintenant on ajoute les contraintes à t, transportées
sigHH += sigHH_n;
// dans le cas où on veut une sortie des grandeurs locale on sauvegarde
if (sortie_post)
{ Tenseur3HH eps_p_HH = gijHH * epsBB * gijHH;
eps_p_HH.ChBase(gamma);
Tenseur3HH sig_p_HH(sigHH);
sig_p_HH.ChBase(gamma);
(*save_resul.eps_loc_HH) = eps_p_HH;
(*save_resul.sig_loc_HH) = sig_p_HH;
};
// beta_inv = beta.Inverse();
// sig_BB.ChBase(beta_inv);
// passage dans la bonne variance
Tenseur3BH 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) * IdBH3;
sigHH -= (untiers * trace_sig) * gijHH;
break;
}
case 2: // calcul de la partie sphérique seule
{ double trace_sig = sigBH.Trace();
sigBH = (untiers * trace_sig) * IdBH3;
sigHH = (untiers * trace_sig) * gijHH;
break;
}
default:
{ cout << "\n erreur l'indicateur cas_calcul= " << cas_calcul << " n'a pas une valeur correcte !! "
<< "\n Hypo_ortho3D_entrainee::Calcul_SigmaHH (.... ";
Sortie(1);
}
};
//----------------- debug
// const Tenseur3BB & gijBB = *((Tenseur3BB*) &gijBB_tdt); // passage en dim 3
//cout << "\n epsBB="<<epsBB << " gijBB_tdt= " << gijBB << " gijHH_tdt= " << gijHH<<" ";
//cout << "\n sighh="<<sigHH<<" "<< endl ;
//----------- fin debug
// traitement des énergies
// arbitrairement, on considère qu'il s'agit d'un accroissement d'énergie élastique
energ.Inita(0.);
energ.ChangeEnergieElastique(energ_t.EnergieElastique() + 0.5 * (sigHH && delta_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
//module_compressibilite = E/(3.*(1.-2.*nu));
// calcul de la valeur de la variation relative de volume en log
double log_var_vol = log((*(ex.jacobien_tdt))/(*(ex.jacobien_0)));
// 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.;};
// 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 = untiers * 2. * (G12+G13+G23);}
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 Hypo_ortho3D_entrainee::Calcul_DsigmaHH_tdt (TenseurHH& sigHH_t,TenseurBB& ,DdlElement & tab_ddl
,BaseB& ,TenseurBB & gijBB_t_,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 & energ_t
,double& module_compressibilite,double& module_cisaillement
,const Met_abstraite::Impli& ex)
{
#ifdef MISE_AU_POINT
if (epsBB_tdt.Dimension() != 3)
{ cout << "\nErreur : la dimension devrait etre 3 !\n";
cout << " Hypo_ortho3D_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 << " Hypo_ortho3D_entrainee::Calcul_DsigmaHH_tdt\n";
Sortie(1);
};
#endif
bool affichage = (Permet_affichage() > 5);
const Tenseur3BB & delta_epsBB = *((Tenseur3BB*) &delta_epsBB_); // passage en dim 3
const Tenseur3BB & epsBB = *((Tenseur3BB*) &epsBB_tdt); // passage en dim 3
const Tenseur3HH & gijHH = *((Tenseur3HH*) &gijHH_tdt); // " " " "
Tenseur3HH & sigHH = *((Tenseur3HH*) &sigHH_tdt); // " " " "
Tenseur3HH & sigHH_nn = *((Tenseur3HH*) &sigHH_t); // " " " "
const Tenseur3BB & gijBB = *((Tenseur3BB*) &gijBB_tdt); // " " " "
const Tenseur3BB & gijBB_t = *((Tenseur3BB*) &gijBB_t_); // " " " "
// --- opération de transport du tenseur sigma(t), de t à tdt
// tenseur intermédiaires utilisées selon les cas (par forcément dans tous les cas !!)
Tenseur3BH sigBH_n;Tenseur3HH sigHH_n; Tenseur3BB sigBB_n;Tenseur3BB sig_interBB_n;
switch (type_derive) //case 1: cas d'une dérivée de Lie deux fois contravariante : cas par défaut
{case -1: // cas d'une dérivée de jauman: 1/2 deux fois covariant + deux fois contra
{sig_interBB_n = gijBB_t * sigHH_nn * gijBB_t;
sigBH_n = 0.5*( sig_interBB_n * gijHH + gijBB * sigHH_nn) ;
sigHH_n = gijHH * sigBH_n ;
sigBB_n = sigBH_n * gijBB; break;}
case 0: // cas d'une dérivée de Lie deux fois covariantes
{sigBB_n = gijBB_t * sigHH_nn * gijBB_t;
sigBH_n = sigBB_n * gijHH ;
sigHH_n = gijHH * sigBH_n ; break;}
case 1: // cas d'une dérivée de Lie deux fois contravariantes
{sigHH_n = sigHH_nn;
sigBH_n = gijBB * sigHH_n;
sigBB_n = sigBH_n * gijBB;
break;}
};
//---- le repère d'anisotropie
// récup du conteneur spécifique
SaveResulHypo_ortho3D_entrainee & save_resul = *((SaveResulHypo_ortho3D_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(3);
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 << " Hypo_ortho3D_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 < 4; a++)
{CoordonneeH& inter = alpha_H.CoordoH(a);
for (int i=1;i < 4;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<4;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
Coordonnee3B V;
for (int j=1;j<4;j++) V += Op_H_a(j) * (*ex.giB_tdt)(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 << " Hypo_ortho3D_entrainee::Calcul_DsigmaHH_tdt\n";
Sortie(1);
};
#endif
BaseB& O_B = (*save_resul.O_B); // pour simplifier
for (int a=1; a<4;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<4;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<4;i++)
for (int j=1; j<4;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
// ------- partie déformation
Tenseur3BH delta_epsBH = delta_epsBB * gijHH; // accroissement de deformation en mixte
Tenseur3HH delta_epsHH = gijHH * delta_epsBH; // en deuxfois contra
// calcul des coordonnées de l'incrément de déformation dans le repère O'^i
#ifdef MISE_AU_POINT
if (affichage)
{ cout <<"\n delta_eps_BB en g^i: "; delta_epsBB.Ecriture(cout);
};
#endif
// c-a-d les coordonnées dans le dual de O'_i
// il faut passer en 2 fois contravariant
Tenseur3HH delta_eps_p_HH(delta_epsHH);
delta_eps_p_HH.ChBase(gamma); // res = (gamma * res) * gamma.Transpose();
#ifdef MISE_AU_POINT
if (affichage)
{ cout <<"\n delta_eps_p_HH: "; delta_eps_p_HH.Ecriture(cout);
Tenseur3HH toto(delta_eps_p_HH);
toto.ChBase(beta_transpose);
cout << "\n retour dans la base g^i de eps^{ij} :";toto.Ecriture(cout);
Tenseur3BB titi = gijBB * toto * gijBB;
cout << "\n def eps_ij :";titi.Ecriture(cout);
};
#endif
static const 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(9);
coef(1) = &E1; coef(2) = & E2; coef(3) = &E3;
coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23;
coef(7) = & G12; coef(8) = & G13; coef(9) = & G23;
// 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<10;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 << " Hypo_ortho3D_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(3,3) = 1./E3;
inv_loi(1,2) = inv_loi(2,1) = -nu12/E1;
inv_loi(1,3) = inv_loi(3,1) = -nu13/E1;
inv_loi(3,2) = inv_loi(2,3) = -nu23/E2;
inv_loi = inv_loi.Inverse(); // on inverse la matrice
};
// calcul de l'accroissement des contraintes dans le repère O_p
Tenseur3HH delta_sig_abij_HH; // au début c'est ab puis après chgt de base devient en ij
Vecteur delta_eps_ii(3);Vecteur delta_sig_ii(3);
for (int i=1; i<4;i++)
delta_eps_ii(i) = delta_eps_p_HH(i,i);
delta_sig_ii = inv_loi * delta_eps_ii;
// l'accroissement est stocké dans delta_sig_abij_HH: on en a besoin pour l'opérateur tangent
// ensuite on ajoutera la contrainte à t transportée de t à tdt
for (int i=1; i<4;i++)
delta_sig_abij_HH.Coor(i,i) = delta_sig_ii(i);
delta_sig_abij_HH.Coor(1,2) = 2.* G12 * delta_eps_p_HH(1,2);
delta_sig_abij_HH.Coor(1,3) = 2.* G13 * delta_eps_p_HH(1,3);
delta_sig_abij_HH.Coor(2,3) = 2.* G23 * delta_eps_p_HH(2,3);
// 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(3);
save_resul.sig_loc_HH = NevezTenseurHH(3);
save_resul.para_loi = new Vecteur (9);
save_resul.delta_eps_loc_HH = NevezTenseurHH(3);
save_resul.delta_sig_loc_HH = NevezTenseurHH(3);
};
(*save_resul.delta_eps_loc_HH) = delta_eps_p_HH;
(*save_resul.delta_sig_loc_HH) = delta_sig_abij_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; (*save_resul.para_loi)(8) = G13;
(*save_resul.para_loi)(9) = G23;
};
// calcul de l'acroissement des contraintes dans le repère g_i
// l'inverse de gamma c'est beta transposée
delta_sig_abij_HH.ChBase(beta_transpose);
// maintenant on ajoute les contraintes à t, transportées
sigHH = delta_sig_abij_HH + sigHH_n;
// dans le cas où on veut une sortie des grandeurs locale on sauvegarde
if (sortie_post)
{ Tenseur3HH eps_p_HH = gijHH * epsBB * gijHH;
eps_p_HH.ChBase(gamma);
Tenseur3HH sig_p_HH(sigHH);
sig_p_HH.ChBase(gamma);
(*save_resul.eps_loc_HH) = eps_p_HH;
(*save_resul.sig_loc_HH) = sig_p_HH;
};
// passage dans la bonne variance
Tenseur3BH 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) * IdBH3;
sigHH -= (untiers * trace_sig) * gijHH;
break;
}
case 2: // calcul de la partie sphérique seule
{ double trace_sig = sigBH.Trace();
sigBH = (untiers * trace_sig) * IdBH3;
sigHH = (untiers * trace_sig) * gijHH;
break;
}
default:
{ cout << "\n erreur l'indicateur cas_calcul= " << cas_calcul << " n'a pas une valeur correcte !! "
<< "\n Hypo_ortho3D_entrainee::Calcul_DsigmaHH_tdt (.... ";
Sortie(1);
}
};
//----------------- debug
#ifdef MISE_AU_POINT
if (affichage)
{ cout << "\n epsBB="<<epsBB << " gijBB_tdt= " << gijBB << " gijHH_tdt= " << gijHH<<" ";
cout << "\n sighh="<<sigHH<<" "<< endl ;
};
#endif
//----------- fin debug
// traitement des énergies
// arbitrairement, on considère qu'il s'agit d'un accroissement d'énergie élastique
energ.Inita(0.);
energ.ChangeEnergieElastique(energ_t.EnergieElastique() + 0.5 * (sigHH && delta_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
//module_compressibilite = E/(3.*(1.-2.*nu));
// calcul de la valeur de la variation relative de volume en log
double log_var_vol = log((*(ex.jacobien_tdt))/(*(ex.jacobien_0)));
// 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.;};
// 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 = untiers * 2. * (G12+G13+G23);}
else
// en purement sphérique, le module est supposé nul
{module_cisaillement = 0.; };
// -------- cas le la variation du tenseur des contraintes par rapport aux ddl ---------
int nbddl = d_gijBB_tdt.Taille();
// des tenseurs de travail
Tenseur3BH dsigBH_n,d_SBH_n; // tenseurs de travail
Tenseur3BH d_sigBH; Tenseur3HH d_sig_HH,dsigHH_n;
// Tenseur3HH d_epsHH;Mat_pleine mat_d_epsHH(3,3);
Tenseur3HH d_delta_epsHH;Mat_pleine mat_d_delta_epsHH(3,3);
Vecteur d_delta_eps_ii(3);Vecteur d_delta_sig_ii(3);
Mat_pleine d_beta(3,3);Mat_pleine d_beta_inv(3,3);
Mat_pleine d_beta_transpose(3,3);
Mat_pleine d_gamma(3,3);
Mat_pleine mat_d_delta_eps_p_HH(3,3);
// on récupère la matrice des composantes de déformation dans O_p_a
Mat_pleine mat_delta_epsHH(3,3);delta_epsHH.Matrice_composante(mat_delta_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 ()
Tenseur3HH & dsigHH = *((Tenseur3HH*) (d_sigHH(i))); // passage en dim 3
const Tenseur3HH & dgijHH = *((Tenseur3HH*)(d_gijHH_tdt(i))) ; // pour simplifier l'ecriture
const Tenseur3BB & dgijBB = *((Tenseur3BB*)(d_gijBB_tdt(i))) ; // pour simplifier l'ecriture
const Tenseur3BB & depsBB = *((Tenseur3BB *) (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
Tenseur3BH depsBH = epsBB * dgijHH + depsBB * gijHH ;
//cout <<"\n depsBH: "; depsBH.Ecriture(cout);
double dIeps = depsBH.Trace();
// -- variation de sigma_n
switch (type_derive)
{ case -1: // // cas d'une dérivée de jauman: 1/2 deux fois covariant + deux fois contra
{// pour info sigBH_n = 0.5*(gijBB * sigHH_n + (gijBB_t * sigHH_n * gijBB_t) * gijHH)
dsigBH_n = 0.5*(sig_interBB_n * dgijHH + dgijBB * sigHH_nn );
break;}
case 0: // cas d'une dérivée de Lie deux fois covariantes
{// pour info sigBH_n = (gijBB_t * sigHH_n * gijBB_t) * gijHH
dsigBH_n = sigBB_n * dgijHH;
break;}
case 1: // cas d'une dérivée de Lie deux fois contravariantes
{// pour info sigBH_n = gijBB * sigHH_n
dsigBH_n = dgijBB * sigHH_n; break;}
};
// variation de la trace de sigma_n du au transport
double dIsig_n = dsigBH_n.Trace();
// variation du déviateur due au transport
d_SBH_n = dsigBH_n - (untiers * dIsig_n) * IdBH3;
//--- prise en compte de la variation du repère d'anisotropie
/* // 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<4;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<4;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<4;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<4;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<4;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<4;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<4;l++)
for (int m =1;m<4;m++)
inter += alpha_H_a(l) * alpha_H_a(m) * dgijBB(l,m);
for (int i=1; i<4;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 Hypo_ortho3D_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
// delta_epsHH = gijHH * delta_epsBB * gijHH dans g_i
// de d_delta_epsBB/d_ddl = d_epsBB/d_ddl
d_delta_epsHH = dgijHH * delta_epsBB * gijHH + gijHH * depsBB * gijHH
+ gijHH * delta_epsBB * dgijHH;
//cout <<"\n d_delta_epsHH: "; d_delta_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_delta_epsHH.Matrice_composante(mat_d_delta_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_delta_eps_p_HH = (d_gamma * mat_delta_epsHH * gamma_transpose)
+ (gamma * mat_d_delta_epsHH * gamma_transpose)
+ gamma * mat_delta_epsHH * d_gamma.Transpose();
//cout << "\n mat_d_eps_p_HH: ";mat_d_eps_p_HH.Affiche();
// -- 2) calcul de la variation de l'accroissement des contraintes dans le repère O_p
for (int i=1; i<4;i++)
d_delta_eps_ii(i) = mat_d_delta_eps_p_HH(i,i); // les delta def de la diagonale
d_delta_sig_ii = inv_loi * d_delta_eps_ii; // les delta contraintes en ii
// on se sert du conteneur dsigHH
for (int i=1; i<4;i++)
{dsigHH.Coor(i,i) = d_delta_sig_ii(i); // affectation des delta contraintes en ii
};
// puis les contraintes en cisaillement
dsigHH.Coor(1,2) = 2.* G12 * mat_d_delta_eps_p_HH(1,2);
dsigHH.Coor(1,3) = 2.* G13 * mat_d_delta_eps_p_HH(1,3);
dsigHH.Coor(2,3) = 2.* G23 * mat_d_delta_eps_p_HH(2,3);
//cout <<"\n dsigHH en O_p : "; dsigHH.Ecriture(cout);
// -- 3) calcul de la variation des delta 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
delta_sig_abij_HH.Var_tenseur_dans_nouvelle_base(beta_transpose,dsigHH,d_beta_transpose);
//cout <<"\n dsigHH en gi : "; dsigHH.Ecriture(cout);
// assemblage final en tenant compte des contraintes à t transportées
// sachant que dsigHH contient les variations de delta sigHH
switch (cas_calcul)
{ case 0: // calcul normal (tous les termes)
{ // sigHH_n = gijHH * sigBH_n d'où
dsigHH_n = dgijHH * sigBH_n + gijHH * dsigBH_n;
dsigHH += dsigHH_n; // assemblage
break;
}
case 1: // calcul de la partie déviatorique seule
{ // -- la partie delta sigma
// passage en mixte pour le calcul de la trace
d_sigBH = dgijBB * delta_sig_abij_HH + gijBB * dsigHH;
double d_trace_sig = d_sigBH.Trace();
d_sigBH -= (untiers * d_trace_sig) * IdBH3;
// -- ajout de la partie transportée en déviateur
// ( somme de 2 déviateurs = un déviateur)
d_sigBH += d_SBH_n;
// -- passage en deux fois contravariant
dsigHH = dgijHH * sigBH + gijHH * d_sigBH;
break;
}
case 2: // calcul de la partie sphérique seule
{ // -- la partie delta sigma
// passage en mixte pour le calcul de la trace
d_sigBH = dgijBB * delta_sig_abij_HH + gijBB * dsigHH;
double d_trace_sig = d_sigBH.Trace();
// -- ajout de la partie transportée en sphérique
// ( somme de 2 sphériques = un sphérique)
d_sigBH = (untiers * d_trace_sig + dIsig_n) * IdBH3;
// 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 Hypo_ortho3D_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 Hypo_ortho3D_entrainee::Calcul_dsigma_deps (bool en_base_orthonormee, TenseurHH & sigHH_t,TenseurBB&
,TenseurBB & epsBB_tdt,TenseurBB & delta_epsBB_,double& ,double&
,TenseurHH& sigHH_tdt,TenseurHHHH& d_sigma_deps_
,EnergieMeca & energ,const EnergieMeca & energ_t
,double& module_compressibilite,double& module_cisaillement
,const Met_abstraite::Umat_cont& ex)
{
#ifdef MISE_AU_POINT
if (epsBB_tdt.Dimension() != 3)
{ cout << "\nErreur : la dimension devrait etre 3 !\n";
cout << " Hypo_ortho3D_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 Tenseur3BB & epsBB = *((Tenseur3BB*) &epsBB_tdt); // passage en dim 3
const Tenseur3BB & delta_epsBB = *((Tenseur3BB*) &delta_epsBB_);
Tenseur3HH & sigHH = *((Tenseur3HH*) &sigHH_tdt); // " " " "
Tenseur3HH & sigHH_nn = *((Tenseur3HH*) &sigHH_t); // " " " "
Tenseur3HHHH& d_sigma_deps = *((Tenseur3HHHH*) &d_sigma_deps_);
const Tenseur3HH & gijHH = *((Tenseur3HH*) ex.gijHH_tdt); // " " " "
const Tenseur3BB & gijBB = *((Tenseur3BB*) ex.gijBB_tdt); // " " " "
const Tenseur3HH & gijHH_t = *((Tenseur3HH*) ex.gijHH_t); // " " " "
const Tenseur3BB & gijBB_t = *((Tenseur3BB*) ex.gijBB_t); // " " " "
// --- opération de transport du tenseur sigma(t), de t à tdt
// tenseur intermédiaires utilisées selon les cas (par forcément dans tous les cas !!)
Tenseur3BH sigBH_n;Tenseur3HH sigHH_n; Tenseur3BB sigBB_n;Tenseur3BB sig_interBB_n;
if (en_base_orthonormee)
{// pour l'instant le transport s'effectue dans la base orthonormee!! ce qui est peut-être
// mauvais dans le cas de grandes transformations !!
sigBH_n = IdBB3 * sigHH_nn;
} // deformation en mixte
else
{ switch (type_derive) //case 1: cas d'une dérivée de Lie deux fois contravariante : cas par défaut
{case -1: // cas d'une dérivée de jauman: 1/2 deux fois covariant + deux fois contra
{sig_interBB_n = gijBB_t * sigHH_nn * gijBB_t;
sigBH_n = 0.5*( sig_interBB_n * gijHH + gijBB * sigHH_nn) ;
sigHH_n = gijHH * sigBH_n ;
sigBB_n = sigBH_n * gijBB; break;}
case 0: // cas d'une dérivée de Lie deux fois covariantes
{sigBB_n = gijBB_t * sigHH_nn * gijBB_t;
sigBH_n = sigBB_n * gijHH ;
sigHH_n = gijHH * sigBH_n ; break;}
case 1: // cas d'une dérivée de Lie deux fois contravariantes
{sigHH_n = sigHH_nn;
sigBH_n = gijBB * sigHH_n;
sigBB_n = sigBH_n * gijBB;
break;}
};
};
//---- le repère d'anisotropie
// récup du conteneur spécifique
SaveResulHypo_ortho3D_entrainee & save_resul = *((SaveResulHypo_ortho3D_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(3);
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 << " Hypo_ortho3D_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 < 4; a++)
{CoordonneeH& inter = alpha_H.CoordoH(a);
for (int i=1;i < 4;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<4;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(3);
for (int j=1;j<4;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 << " Hypo_ortho3D_entrainee::Calcul_dsigma_deps\n";
Sortie(1);
};
#endif
BaseB& O_B = (*save_resul.O_B); // pour simplifier
for (int a=1; a<4;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<4;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<4;i++)
for (int j=1; j<4;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
// ------- partie déformation
Tenseur3BH delta_epsBH = delta_epsBB * gijHH; // accroissement de deformation en mixte
Tenseur3HH delta_epsHH = gijHH * delta_epsBH; // en deuxfois contra
// calcul des coordonnées de l'incrément de déformation dans le repère O'^i
// calcul des coordonnées de la déformation dans le repère O'_i
#ifdef MISE_AU_POINT
if (affichage)
{cout <<"\n delta_eps_BB en g^i: "; delta_epsBB.Ecriture(cout);
Tenseur3BB tiutiu;
delta_epsBB.BaseAbsolue(tiutiu,*(ex.giH_tdt));
cout << "\n delta_eps en absolu :";tiutiu.Ecriture(cout);
};
#endif
// il faut passer en 2 fois contravariant
Tenseur3HH delta_eps_p_HH(delta_epsHH);
delta_eps_p_HH.ChBase(gamma); // res = (gamma * res) * gamma.Transpose();
#ifdef MISE_AU_POINT
if (affichage)
{ cout <<"\n delta_eps_p_HH: "; delta_eps_p_HH.Ecriture(cout);
Tenseur3HH toto(delta_eps_p_HH);
toto.ChBase(beta_transpose);
cout << "\n retour dans la base g^i de eps^{ij} :";toto.Ecriture(cout);
Tenseur3BB titi = gijBB * toto * gijBB;
cout << "\n def eps_ij :";titi.Ecriture(cout);
};
#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(9);
coef(1) = &E1; coef(2) = & E2; coef(3) = &E3;
coef(4) = & nu12; coef(5) = & nu13; coef(6) = & nu23;
coef(7) = & G12; coef(8) = & G13; coef(9) = & G23;
// 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<10;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 << " Hypo_ortho3D_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(3,3) = 1./E3;
inv_loi(1,2) = inv_loi(2,1) = -nu12/E1;
inv_loi(1,3) = inv_loi(3,1) = -nu13/E1;
inv_loi(3,2) = inv_loi(2,3) = -nu23/E2;
inv_loi = inv_loi.Inverse(); // on inverse la matrice
};
// calcul de l'accroissement des contraintes dans le repère O_p
Tenseur3HH delta_sig_ab_HH; // au début c'est ab puis après chgt de base devient en ij
Vecteur delta_eps_ii(3);Vecteur delta_sig_ii(3);
for (int i=1; i<4;i++)
delta_eps_ii(i) = delta_eps_p_HH(i,i);
delta_sig_ii = inv_loi * delta_eps_ii;
// l'accroissement est stocké dans delta_sig_abij_HH: on en a besoin pour l'opérateur tangent
// ensuite on ajoutera la contrainte à t transportée de t à tdt
for (int i=1; i<4;i++)
delta_sig_ab_HH.Coor(i,i) = delta_sig_ii(i);
delta_sig_ab_HH.Coor(1,2) = 2.* G12 * delta_eps_p_HH(1,2);
delta_sig_ab_HH.Coor(1,3) = 2.* G13 * delta_eps_p_HH(1,3);
delta_sig_ab_HH.Coor(2,3) = 2.* G23 * delta_eps_p_HH(2,3);
#ifdef MISE_AU_POINT
if (affichage)
{cout << "\n delta_sig_ab_HH :";delta_sig_ab_HH.Ecriture(cout);
};
#endif
// 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(3);
save_resul.sig_loc_HH = NevezTenseurHH(3);
save_resul.para_loi = new Vecteur (9);
save_resul.delta_eps_loc_HH = NevezTenseurHH(3);
save_resul.delta_sig_loc_HH = NevezTenseurHH(3);
};
(*save_resul.delta_eps_loc_HH) = delta_eps_p_HH;
(*save_resul.delta_sig_loc_HH) = delta_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; (*save_resul.para_loi)(8) = G13;
(*save_resul.para_loi)(9) = G23;
};
// calcul de l'acroissement des contraintes dans le repère g_i
// l'inverse de gamma c'est beta transposée
Tenseur3HH delta_sig_ij_HH(delta_sig_ab_HH);
delta_sig_ij_HH.ChBase(beta_transpose);
// maintenant on ajoute les contraintes à t, transportées
sigHH = delta_sig_ij_HH + sigHH_n;
#ifdef MISE_AU_POINT
if (affichage)
{cout << "\n sig_ijHH :";sigHH.Ecriture(cout);
Tenseur3HH tutu;
sigHH.BaseAbsolue(tutu,*(ex.giB_tdt));
cout << "\n sig en absolu :";tutu.Ecriture(cout);
};
#endif
// dans le cas où on veut une sortie des grandeurs locale on sauvegarde
if (sortie_post)
{ Tenseur3HH eps_p_HH = gijHH * epsBB * gijHH;
eps_p_HH.ChBase(gamma);
Tenseur3HH sig_p_HH(sigHH);
sig_p_HH.ChBase(gamma);
(*save_resul.eps_loc_HH) = eps_p_HH;
(*save_resul.sig_loc_HH) = sig_p_HH;
};
// passage dans la variance mixte
Tenseur3BH 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) * IdBH3;
sigHH -= (untiers * trace_sig) * gijHH;
break;
}
case 2: // calcul de la partie sphérique seule
{ double trace_sig = sigBH.Trace();
sigBH = (untiers * trace_sig) * IdBH3;
sigHH = (untiers * trace_sig) * gijHH;
break;
}
default:
{ cout << "\n erreur l'indicateur cas_calcul= " << cas_calcul << " n'a pas une valeur correcte !! "
<< "\n Hypo_ortho3D_entrainee::Calcul_DsigmaHH_tdt (.... ";
Sortie(1);
}
};
//----------------- debug
#ifdef MISE_AU_POINT
if (affichage)
{ cout << "\n epsBB="<<epsBB << " gijBB_tdt= " << gijBB << " gijHH_tdt= " << gijHH<<" ";
cout << "\n sighh="<<sigHH<<" "<< endl ;
};
#endif
//----------- fin debug
// traitement des énergies
// arbitrairement, on considère qu'il s'agit d'un accroissement d'énergie élastique
energ.Inita(0.);
energ.ChangeEnergieElastique(energ_t.EnergieElastique() + 0.5 * (sigHH && delta_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
//module_compressibilite = E/(3.*(1.-2.*nu));
// calcul de la valeur de la variation relative de volume en log
double log_var_vol = log((*(ex.jacobien_tdt))/(*(ex.jacobien_0)));
// 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);
};
#ifdef MISE_AU_POINT
if (Permet_affichage() > 4)
cout << "\n module_compressibilite= " << module_compressibilite;
if (Permet_affichage() > 5) cout << "\n cas_calcul= " << cas_calcul;
#endif
}
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 module_compressibilite= " << module_compressibilite;
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 = untiers * 2. * (G12+G13+G23);}
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é
Tenseur3HHBB var_sig_ab_cd_HHBB;
for (int i=1; i<4;i++)
for (int j=1; j<4;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)
var_sig_ab_cd_HHBB.Change(1,3,1,3,G13); // "
var_sig_ab_cd_HHBB.Change(2,3,2,3,G23); // *
#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 <Tenseur3HH> d_beta_HH(3,3);
Tableau2 <Tenseur3HH> d_beta_transpose_HH(3,3);
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<4;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<4;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))*Tenseur3HH::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<4;a++)
{ CoordonneeH alpha_H_a = alpha_H(a);
//Tenseur3HH toto(Tenseur3HH::Prod_tensoriel(alpha_H_a,alpha_H_a));
//cout << "\n Prod_tensoriel(alpha_H_a,alpha_H_a)= ";
//toto.Ecriture(cout);
//Tenseur3HH titi;
//for (int j=1;j<4;j++)
// for (int i=1;i<4;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<4;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 <Tenseur3HH> d_gamma_HH(3,3);
for (int b=1;b<4;b++)
for (int j=1;j<4;j++)
{for (int a=1;a<4;a++)
for (int i=1;i<4;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(3,3);
Mat_pleine O_p_0_ij(3,3);Mat_pleine O_p_tdt_ij(3,3);
for (int a=1;a<4;a++)
{
CoordonneeH alpha_H_a = alpha_H(a);
//Tenseur3HH toto(Tenseur3HH::Prod_tensoriel(alpha_H_a,alpha_H_a));
//cout << "\n Prod_tensoriel(alpha_H_a,alpha_H_a)= ";
//toto.Ecriture(cout);
//Tenseur3HH titi;
//for (int j=1;j<4;j++)
// for (int i=1;i<4;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<4;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
// Tenseur3HHHH var_eps_nm_kl_HHHH(Tenseur3HHHH::Prod_tensoriel_barre(gijHH,gijHH));
//--// Tenseur3HHHH var_eps_nm_kl_HHHH(Tenseur3HHHH::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
// Tenseur3HHHH deps_nmkl;
// for (int n=1;n<4;n++) for (int m=1;m<4;m++) for (int k=1;k<4;k++) for (int l=1;l<4;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);
//}
// Tenseur3HHHH interHHHH1(Tenseur3HHHH::Prod_tensoriel_barre(gijHH,eps_p_HH));
// Tenseur3HHHH interHHHH2(Tenseur3HHHH::Prod_tensoriel_barre(eps_p_HH,gijHH));
//--// Tenseur3HHHH interHHHH1(Tenseur3HHHH::Prod_tensoriel_croise(gijHH,eps_HH));
//--// Tenseur3HHHH interHHHH2(Tenseur3HHHH::Prod_tensoriel_croise(eps_HH,gijHH));
//Tenseur3HHHH interHHHH3(interHHHH1+interHHHH2);
//cout << "\n interHHHH3= ";
//interHHHH3.Affiche_bidim(cout);
//cout << "\n interHHHH1= ";
//interHHHH1.Affiche_bidim(cout);
//cout << "\n interHHHH2= ";
//interHHHH2.Affiche_bidim(cout);
//{Tenseur3HHHH A(interHHHH3);
//A += interHHHH3;
//cout << "\n A= ";A.Affiche_bidim(cout);
//Tenseur3HHHH B(var_eps_nm_kl_HHHH);
//cout << "\n (1) B= ";B.Affiche_bidim(cout);
//B -= 2. * interHHHH3;
//cout << "\n B= ";B.Affiche_bidim(cout);
//
//}
//--// var_eps_nm_kl_HHHH -= 2. * (interHHHH1+interHHHH2);
//Tenseur3HHHH::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
{Tenseur3HH delta_eps = var_eps_nm_kl_HHHH && epsBB;
cout << "\n delta_eps= "; delta_eps.Ecriture(cout);
Tenseur3HH 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
Tenseur3HHHH d_gijHH(Tenseur3HHHH::Prod_tensoriel_croise(gijHH,gijHH));
d_gijHH *= -2.;
Tenseur3HH delta_gijHH(gijHH-(*ex.gijHH_0));
Tenseur3HH 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<4;n++) for (int m=1;m<4;m++)
{delta_gijHH_num.Coor(n,m)=0;
for (int i=1;i<4;i++) for (int j=1;j<4;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<4;n++) for (int m=1;m<4;m++)
{delta_gijHH_num.Coor(n,m)=0;
for (int i=1;i<4;i++) for (int j=1;j<4;j++)
delta_gijHH_num.Coor(n,m) += -2.* gijHH(n,i) * gijHH(j,m) * epsBB(i,j);
}
cout << "\n delta_gijHH_num (3)) = "; delta_gijHH_num.Ecriture(cout);
Tenseur3HHHH d_gijHH_num;
for (int n=1;n<4;n++) for (int m=1;m<4;m++)
for (int i=1;i<4;i++) for (int j=1;j<4;j++)
d_gijHH_num.Change(n,m,i,j,(-2.* gijHH(n,i) * gijHH(j,m))) ;
for (int n=1;n<4;n++) for (int m=1;m<4;m++)
for (int i=1;i<4;i++) for (int j=1;j<4;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) ;
}
}
*/
//{Tenseur3HH A(1,2,3,0.,0.,0.);
// Tenseur3HH B(4,5,6,0.,0.,0.);
// Tenseur3HHHH C(Tenseur3HHHH::Prod_tensoriel(A,B));
//cout << "\n C= ";C.Affiche_bidim(cout);
// Tenseur3HHHH C1(Tenseur3HHHH::Prod_tensoriel_barre(A,B));
//cout << "\n Prod_tensoriel_barre(A,B)= ";C1.Affiche_bidim(cout);
// Tenseur3HHHH C2(Tenseur3HHHH::Prod_tensoriel_croise(A,B));
//cout << "\n Prod_tensoriel_croise(A,B)= ";C2.Affiche_bidim(cout);
// Tenseur3HHHH C3(Tenseur3HHHH::Prod_tensoriel_croise_croise(A,B));
//cout << "\n Prod_tensoriel_croise_croise(A,B)= ";C3.Affiche_bidim(cout);
//}
//--// var_delta_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 !
// d_Delta_epsilon^{nm} / d_epsilon_{kl} = -2 ( g^{nk} . Delta_epsilon^{lm} + Delta_epsilon^{nk} . g^{ml} ) + g^{nk} . g^{lm}
TenseurQ3geneHHHH d_delta_eps_nmkl_HHHH;
{for (int n=1;n<4;n++) for (int m=1;m<4;m++) for (int k=1;k<4;k++) for (int l=1;l<4;l++)
{ double inter= gijHH(n,k) * gijHH(l,m)
-2.*(gijHH(n,k) * delta_epsHH(l,m) + delta_epsHH(n,l) * gijHH(m,k));
d_delta_eps_nmkl_HHHH.Change(n,m,k,l,inter);
};
//// vérification du stockage
//cout << "\n deps_nmkl= calcul en composantes";
//for (int n=1;n<4;n++) for (int m=1;m<4;m++) for (int k=1;k<4;k++) for (int l=1;l<4;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
/*{
Tenseur3HH delta_epsHH_num;
for (int n=1;n<4;n++) for (int m=1;m<4;m++)
{delta_epsHH_num.Coor(n,m)=0;
for (int i=1;i<4;i++) for (int j=1;j<4;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 delta déformations delta_epsHH / eps_ij dans le repère transporté / au eps_kl
// c'est à dire la variation de delta_eps^ab / eps_kl
// d_delta_epsilon^{ab} / d_epsilon_{kl} = d_gamma^a_{.n} / d_epsilon_{kl} . Delta_epsilon^{nm} . gamma^b_{.m}
// + gamma^a_{.n} . d_Delta_epsilon^{nm} / d_epsilon_{kl} . gamma^b_{.m}
// + gamma^a_{.n} . Delta_epsilon^{nm} . d_gamma^b_{.m} / d_epsilon_{kl}
// 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 !
TenseurQ3geneHHHH d_delta_eps_abkl_HHHH;
{for (int a=1;a<4;a++) for (int b=1;b<4;b++) for (int k=1;k<4;k++) for (int l=1;l<4;l++)
{ double inter= 0.;
for (int n=1;n<4;n++) for (int m=1;m<4;m++)
inter += d_gamma_HH(a,n)(k,l) * delta_epsHH(n,m) * gamma(b,m)
+ gamma(a,n) * d_delta_eps_nmkl_HHHH(n,m,k,l) * gamma(b,m)
+ gamma(a,n) * delta_epsHH(n,m) * d_gamma_HH(b,m)(k,l);
d_delta_eps_abkl_HHHH.Change(a,b,k,l,inter);
};
//cout << "\n d_delta_eps_abkl_HHHH= calcul en composantes";
//d_delta_eps_abkl_HHHH.Affiche_bidim(cout);
};
// OK vérif numérique de la variation
/*{
Tenseur3HH delta_eps_ab_HH_num;
for (int n=1;n<4;n++) for (int m=1;m<4;m++)
{delta_eps_ab_HH_num.Coor(n,m)=0;
for (int i=1;i<4;i++) for (int j=1;j<4;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
//--// Tenseur3HHHH var_sig_ab_kl_HHHH = var_sig_ab_cd_HHBB && var_eps_ab_kl_HHHH;
TenseurQ3geneHHHH d_delta_sig_abkl_HHHH;
{// pour vérification on va calculer par composante
for (int a=1;a<4;a++) for (int b=1;b<4;b++) for (int k=1;k<4;k++) for (int l=1;l<4;l++)
{ double inter= 0.;
for (int n=1;n<4;n++) for (int m=1;m<4;m++)
inter += var_sig_ab_cd_HHBB(a,b,n,m) * d_delta_eps_abkl_HHHH(m,n,k,l);
d_delta_sig_abkl_HHHH.Change(a,b,k,l,inter);
};
// cout << "\n d_delta_sig_abkl_HHHH= calcul en composantes";
// d_delta_sig_abkl_HHHH.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
/*{
Tenseur3HH delta_sigma_ab_HH_num;
for (int n=1;n<4;n++) for (int m=1;m<4;m++)
{delta_sigma_ab_HH_num.Coor(n,m)=0;
for (int i=1;i<4;i++) for (int j=1;j<4;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 = Tenseur3HHHH::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 !
// d_delta_sigma^{ij} / d_epsilon_{kl} = d_beta^{.i}_{a} / d_epsilon_{kl} . delta_sigma^{ab} . beta^{.j}_{b}
// + beta^{.i}_{a} . d_delta_sigma^{ab} \ d_epsilon_{kl} . beta^{.j}_{b}
// + beta^{.i}_{a} . delta_sigma^{ab} . d_beta^{.j}_{b} \ d_epsilon_{kl}
TenseurQ3geneHHHH dsig_ijkl_HHHH;
{for (int i=1;i<4;i++) for (int j=1;j<4;j++) for (int k=1;k<4;k++) for (int l=1;l<4;l++)
{ double inter= 0.;
for (int a=1;a<4;a++) for (int b=1;b<4;b++)
inter += d_beta_HH(a,i)(k,l) * delta_sig_ab_HH(a,b) * beta(b,j)
+ beta(a,i) * d_delta_sig_abkl_HHHH(a,b,k,l) * beta(b,j)
+ beta(a,i) * delta_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
/*{
Tenseur3HH delta_sigma_ij_HH_num;
for (int n=1;n<4;n++) for (int m=1;m<4;m++)
{delta_sigma_ij_HH_num.Coor(n,m)=0;
for (int i=1;i<4;i++) for (int j=1;j<4;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 = Tenseur3HHHH::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 IdBB3(i,j) représente le kronecker et idem pour IdHH3(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
Tenseur3BBHH var_eps_ij_kl_BBHH(Tenseur3BBHH::Prod_tensoriel_barre(IdBB3,IdHH3));
// 2) la variation d eps_ab / d eps_ij
Tenseur3BBHH var_eps_ab_kl_BBHH = Tenseur3BBHH::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
Tenseur3BBHH 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 <Tenseur3HH> d_beta_inv_HH(3,3);
for (int b=1;b<4;b++)
for (int j=1;j<4;j++)
{Tenseur3HH& resHH = d_beta_inv_HH(j,b);
for (int a=1;a<4;a++)
for (int i=1;i<4;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
Tenseur3BBHH var_sig_ij_kl_BBHH = Tenseur3BBHH::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
Tenseur3HHHH gijkl_HHHH(Tenseur3HHHH::Prod_tensoriel_barre(gijHH,gijHH));
Tenseur3HHHH d_gij_kl_HHHH(-2.*Tenseur3HHHH::Prod_tensoriel_barre(gijHH,gijHH));
Tenseur3HHBB interHHBB(Tenseur3HHBB::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 && (Tenseur3BBHH::Prod_tensoriel_barre(sig_BB,gijHH)))
+ (interHHBB && d_gij_kl_HHHH);
*/
LibereTenseur();
LibereTenseurQ();
};