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