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

1363 lines
59 KiB
C++
Executable file

// FICHIER : Hyper_externe_W.cc
// CLASSE : Hyper_externe_W
// 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 "CharUtil.h"
#include "Hyper_externe_W.h"
#include "MathUtil.h"
#include "Enum_TypeQuelconque.h"
#include "TypeQuelconqueParticulier.h"
// CONSTRUCTEURS :
// ---------- classe de stockage des grandeurs spécifiques pour la loi ---------
Hyper_externe_W::SaveResulHyper_externe_W::SaveResulHyper_externe_W(): // constructeur par défaut
SaveResulHyper_W_gene_3D()
,module_compressibilite(0.),module_compressibilite_t(0.)
,W_poten(NULL),W_poten_t(NULL)
,inv_B(NULL),inv_B_t(NULL)
,inv_J(NULL),inv_J_t(NULL)
{};
Hyper_externe_W::SaveResulHyper_externe_W::SaveResulHyper_externe_W(int sortie_post): // avec init ou pas
SaveResulHyper_W_gene_3D(sortie_post)
,module_compressibilite(0.),module_compressibilite_t(0.)
,W_poten(NULL),W_poten_t(NULL)
,inv_B(NULL),inv_B_t(NULL)
,inv_J(NULL),inv_J_t(NULL)
{ if (sortie_post)
{W_poten = new Vecteur(9);
W_poten_t = new Vecteur(9);
inv_B = new Vecteur(3);
inv_B_t = new Vecteur(3);
inv_J = new Vecteur(3);
inv_J_t = new Vecteur(3);
};
};
Hyper_externe_W::SaveResulHyper_externe_W::SaveResulHyper_externe_W(const SaveResulHyper_externe_W& sav): // de copie
SaveResulHyper_W_gene_3D(sav) // par défaut on sauvegarde les infos
,module_compressibilite(sav.module_compressibilite),module_compressibilite_t(sav.module_compressibilite)
,W_poten(NULL),W_poten_t(NULL)
,inv_B(NULL),inv_B_t(NULL)
,inv_J(NULL),inv_J_t(NULL)
{if (sav.W_poten != NULL)
{W_poten = new Vecteur(*sav.W_poten);
W_poten_t = new Vecteur(*sav.W_poten_t);
inv_B = new Vecteur(*sav.inv_B);
inv_B_t = new Vecteur(*sav.inv_B_t);
inv_J = new Vecteur(*sav.inv_J);
inv_J_t = new Vecteur(*sav.inv_J_t);
};
};
Hyper_externe_W::SaveResulHyper_externe_W::~SaveResulHyper_externe_W() // destructeur
{if (W_poten != NULL)
{delete W_poten;
delete W_poten_t;
delete inv_B;
delete inv_B_t;
delete inv_J;
delete inv_J_t;
};
};
// affectation
Loi_comp_abstraite::SaveResul & Hyper_externe_W::SaveResulHyper_externe_W::operator = ( const SaveResul & a)
{ // on s'occupe tout d'abord de la classe mère
SaveResulHyper_W_gene_3D::operator = (a);
// puis les nouvelles variables
SaveResulHyper_externe_W& sav = *((SaveResulHyper_externe_W*) &a);
module_compressibilite = sav.module_compressibilite;
module_compressibilite_t = sav.module_compressibilite_t;
if (sav.W_poten != NULL)
{if (W_poten != NULL)
{*W_poten = (*sav.W_poten);
*W_poten_t = (*sav.W_poten_t);
*inv_B = (*sav.inv_B);
*inv_B_t = (*sav.inv_B_t);
*inv_J = (*sav.inv_J);
*inv_J_t = (*sav.inv_J_t);
}
else // sinon il faut définir les conteneurs
{W_poten = new Vecteur(*sav.W_poten);
W_poten_t = new Vecteur(*sav.W_poten_t);
inv_B = new Vecteur(*sav.inv_B);
inv_B_t = new Vecteur(*sav.inv_B_t);
inv_J = new Vecteur(*sav.inv_J);
inv_J_t = new Vecteur(*sav.inv_J_t);
};
}
else
{if (W_poten != NULL)
// il faut détruire les conteneurs
{delete W_poten;W_poten=NULL;
delete W_poten_t;W_poten_t=NULL;
delete inv_B;inv_B=NULL;
delete inv_B_t;inv_B_t=NULL;
delete inv_J;inv_J=NULL;
delete inv_J_t;inv_J_t=NULL;
};
// sinon rien n'a faire c'est ok
};
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 Hyper_externe_W::SaveResulHyper_externe_W::Lecture_base_info (ifstream& ent,const int cas)
{ // entête via la classe mère
Hyper_W_gene_3D::SaveResulHyper_W_gene_3D::Lecture_base_info(ent,cas);
// puis les données spécifiques
string toto;int test;
ent >> toto >> test;
if (test)
{if (W_poten == NULL)
{ W_poten = new Vecteur(9);
W_poten_t = new Vecteur(9);
inv_B = new Vecteur(3);
inv_B_t = new Vecteur(3);
inv_J = new Vecteur(3);
inv_J_t = new Vecteur(3);
};
ent >> toto >>(*W_poten)
>> toto >>(*inv_B)
>> toto >>(*inv_J);
*W_poten_t = (*W_poten);
*inv_B_t = (*inv_B);
*inv_J_t = (*inv_J);
}
else
{if (W_poten != NULL)
// il faut détruire les conteneurs
{delete W_poten;W_poten=NULL;
delete W_poten_t;W_poten_t=NULL;
delete inv_B;inv_B=NULL;
delete inv_B_t;inv_B_t=NULL;
delete inv_J;inv_J=NULL;
delete inv_J_t;inv_J_t=NULL;
};
// sinon rien n'a faire c'est ok
};
//module_compressibilite
ent >> toto >> module_compressibilite;
module_compressibilite_t = module_compressibilite;
};
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables
//(supposées comme telles)
void Hyper_externe_W::SaveResulHyper_externe_W::Ecriture_base_info(ofstream& sort,const int cas)
{ // entête via la classe mère
Hyper_W_gene_3D::SaveResulHyper_W_gene_3D::Ecriture_base_info(sort,cas);
// puis les données spécifiques
sort << "\n dat_Hyper_externe_W: ";
if (W_poten != NULL)
{sort << " 1 \n fonction_potentiel " << (*W_poten);
sort << "\n invar_B "<< (*inv_B) << " invar_J "<< (*inv_J);
}
else
{ sort << " 0 ";};
// module_compressibilite
sort << " module_compressibilite "<<module_compressibilite;
};
// mise à jour des informations transitoires
void Hyper_externe_W::SaveResulHyper_externe_W::TdtversT()
{ SaveResulHyper_W_gene_3D::TdtversT();
if (W_poten != NULL)
{*W_poten_t = (*W_poten);
*inv_B_t = (*inv_B);
*inv_J_t = (*inv_J);
};
module_compressibilite_t = module_compressibilite;
};
void Hyper_externe_W::SaveResulHyper_externe_W::TversTdt()
{ SaveResulHyper_W_gene_3D::TversTdt();
if (W_poten != NULL)
{*W_poten = (*W_poten_t);
*inv_B = (*inv_B_t);
*inv_J = (*inv_J_t);
};
module_compressibilite = module_compressibilite_t;
};
// affichage à l'écran des infos
void Hyper_externe_W::SaveResulHyper_externe_W::Affiche() const
{ // entête via la classe mère
Hyper_W_gene_3D::SaveResulHyper_W_gene_3D::Affiche();
// puis les données spécifiques
cout << "\n dat_Hyper_externe_W: ";
if (W_poten != NULL)
{cout << "\n fonction_potentiel " << (*W_poten);
cout << "\n invar_B "<< (*inv_B) << " invar_J "<< (*inv_J);
};
// module_compressibilite
cout << " module_compressibilite "<<module_compressibilite << " ";
};
// ---------- classe Hyper_externe_W ---------
Hyper_externe_W::Hyper_externe_W () : // Constructeur par defaut
Hyper_W_gene_3D(HYPER_EXTERNE_W,CAT_MECANIQUE,3)
,W_potentiel(NULL)
,W_d(0.),W_v(0.)
,W_d_J1(0.),W_d_J2(0.),W_v_J3(0.),W_v_J3J3(0.)
,W_d_J1_2(0.),W_d_J1_J2(0.),W_d_J2_2(0.)
// variables de travail
,invar(),exclure_ddenum()
{ // on remplit invar, pour l'appel de la fonction potentiel nD
Grandeur_scalaire_double grand_courant(0.);
{TypeQuelconque typQ(INVAR_B1,EPS11,grand_courant);
invar.push_back(typQ);
}
{TypeQuelconque typQ(INVAR_B2,EPS11,grand_courant);
invar.push_back(typQ);
}
{TypeQuelconque typQ(INVAR_B3,EPS11,grand_courant);
invar.push_back(typQ);
}
{TypeQuelconque typQ(INVAR_J1,EPS11,grand_courant);
invar.push_back(typQ);
}
{TypeQuelconque typQ(INVAR_J2,EPS11,grand_courant);
invar.push_back(typQ);
}
{TypeQuelconque typQ(INVAR_J3,EPS11,grand_courant);
invar.push_back(typQ);
}
// on rempli exclure_ddenum
exclure_ddenum.push_back(Ddl_enum_etendu("I_B"));
exclure_ddenum.push_back(Ddl_enum_etendu("II_B"));
exclure_ddenum.push_back(Ddl_enum_etendu("III_B"));
exclure_ddenum.push_back(Ddl_enum_etendu("J1"));
exclure_ddenum.push_back(Ddl_enum_etendu("J2"));
exclure_ddenum.push_back(Ddl_enum_etendu("J3"));
};
// Constructeur de copie
Hyper_externe_W::Hyper_externe_W (const Hyper_externe_W& loi) :
Hyper_W_gene_3D(loi)
,W_potentiel(loi.W_potentiel)
,W_d(loi.W_d),W_v(loi.W_v)
,W_d_J1(loi.W_d_J1),W_d_J2(loi.W_d_J2),W_v_J3(loi.W_v_J3),W_v_J3J3(loi.W_v_J3J3)
,W_d_J1_2(loi.W_d_J1_2),W_d_J1_J2(loi.W_d_J1_J2),W_d_J2_2(loi.W_d_J2_2)
// variables de travail
,invar(),exclure_ddenum()
{// on regarde s'il s'agit d'une fonction nD locale ou globale
if (W_potentiel != NULL)
if (W_potentiel->NomFonction() == "_")
{// comme il s'agit d'une fonction locale on la redéfinie (sinon pb lors du destructeur de loi)
string non_courbe("_");
W_potentiel = Fonction_nD::New_Fonction_nD(*loi.W_potentiel);
};
// on remplit invar, pour l'appel de la fonction potentiel nD
Grandeur_scalaire_double grand_courant(0.);
{TypeQuelconque typQ(INVAR_B1,EPS11,grand_courant);
invar.push_back(typQ);
}
{TypeQuelconque typQ(INVAR_B2,EPS11,grand_courant);
invar.push_back(typQ);
}
{TypeQuelconque typQ(INVAR_B3,EPS11,grand_courant);
invar.push_back(typQ);
}
{TypeQuelconque typQ(INVAR_J1,EPS11,grand_courant);
invar.push_back(typQ);
}
{TypeQuelconque typQ(INVAR_J2,EPS11,grand_courant);
invar.push_back(typQ);
}
{TypeQuelconque typQ(INVAR_J3,EPS11,grand_courant);
invar.push_back(typQ);
}
// on rempli exclure_ddenum
exclure_ddenum.push_back(Ddl_enum_etendu("I_B"));
exclure_ddenum.push_back(Ddl_enum_etendu("II_B"));
exclure_ddenum.push_back(Ddl_enum_etendu("III_B"));
exclure_ddenum.push_back(Ddl_enum_etendu("J1"));
exclure_ddenum.push_back(Ddl_enum_etendu("J2"));
exclure_ddenum.push_back(Ddl_enum_etendu("J3"));
};
Hyper_externe_W::~Hyper_externe_W ()
// Destructeur
{ if (W_potentiel != NULL)
if (W_potentiel->NomFonction() == "_") delete W_potentiel;
};
// Lecture des donnees de la classe sur fichier
void Hyper_externe_W::LectureDonneesParticulieres
(UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D
,LesFonctions_nD& lesFonctionsnD)
{ string nom_class_methode("Hyper_externe_W::LectureDonneesParticulieres");
string nom;
string mot_cle1="W_potentiel_fonction_nD:";
// on lit le nom de la fonction
string nom_fonct;
bool lec = entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle1,nom_fonct);
if (!lec )
{ entreePrinc->MessageBuffer("**erreur02 en lecture** "+mot_cle1);
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// maintenant on définit la fonction
if (lesFonctionsnD.Existe(nom_fonct))
{W_potentiel = lesFonctionsnD.Trouve(nom_fonct);
}
else
{// sinon il faut la lire maintenant
string non("_");
W_potentiel = Fonction_nD::New_Fonction_nD(non, Id_Nom_Fonction_nD(nom_fonct));
// lecture de la courbe
W_potentiel->LectDonnParticulieres_Fonction_nD (non,entreePrinc);
// maintenant on vérifie que la fonction est utilisable
if (W_potentiel->NbComposante() != 9 )
{ cout << "\n erreur en lecture de W_potentiel_fonction_nD:, la fonction " << nom_fonct
<< " est une fonction vectorielle a " << W_potentiel->NbComposante()
<< " composantes alors qu'elle devrait en avoir 9 ! "
<< " elle n'est donc pas utilisable !! ";
string message("\n**erreur03** \n"+nom_class_methode+"(...");
entreePrinc->MessageBuffer(message);
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
};
// on regarde si la fonction nD intègre la température
const Tableau <Ddl_enum_etendu>& tab_enu = W_potentiel->Tab_enu_etendu();
if (tab_enu.Contient(TEMP))
thermo_dependant=true;
// lecture de l'indication éventuelle du post traitement
string le_mot_cle = "sortie_post_";
entreePrinc->Lecture_un_parametre_int(0,nom_class_methode,0,1,le_mot_cle,sortie_post);
// --- appel au niveau de la classe mère
// ici il n'y a pas de type de déformation associé
// mais on prend la def standart d'almansi, pour les fonctions associées éventuelles
Loi_comp_abstraite::Lecture_type_deformation_et_niveau_commentaire
(*entreePrinc,lesFonctionsnD,true);
};
// affichage de la loi
void Hyper_externe_W::Affiche() const
{ cout << " \n loi de comportement hyper elastique 3D Hyper_externe_W \n";
cout << "\n la fonction potentiel calculee avec une fonction nD: ";
cout << "W_potentiel_fonction_nD:" << " ";
if (W_potentiel->NomFonction() != "_")
cout << W_potentiel->NomFonction();
else
W_potentiel->Affiche();
// appel de la classe mère
Loi_comp_abstraite::Affiche_don_classe_abstraite();
};
// affichage et definition interactive des commandes particulières à chaques lois
void Hyper_externe_W::Info_commande_LoisDeComp(UtilLecture& entreePrinc)
{ ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier
cout << "\n definition standart (rep o) ou exemples exhaustifs (rep n'importe quoi) ? ";
string rep = "_";
// procédure de lecture avec prise en charge d'un retour chariot
rep = lect_return_defaut(true,"o");
sort << "\n# ---------------------------------------------------------------------"
<< "\n# |... loi hyper elastique 3D Hyper_externe_W .. |"
<< "\n# ---------------------------------------------------------------------"
<< "\n\n# exemple de definition de loi"
<< "\n W_potentiel_fonction_nD: ma_fct_nD_W "
<< "\n# .. fin de la definition de la loi Hyper_externe_W \n" << endl;
if ((rep != "o") && (rep != "O" ) && (rep != "0") )
{ sort << "\n# "
<< "\n#------------------------------------------------------------------------------------"
<< "\n# la loi se construit via l'utilisation d'une fonction vectorielle nD "
<< "\n# celle-ci doit ramener un tableau tab_val de 9 valeurs tels que: "
<< "\n#------------------------------------------------------------------------------------"
<< "\n# (1) -> W_d c-a-d la valeur de la partie deviatorique du potentiel "
<< "\n# (2) -> W_v c-a-d la valeur de la partie spherique du potentiel "
<< "\n# (3) -> W_d_J1 c-a-d variation de W_d / a J1 "
<< "\n# (4) -> W_d_J2 c-a-d variation de W_d / a J2 "
<< "\n# (5) -> W_d_J1_2 c-a-d variation seconde de W_d / a J1 "
<< "\n# (6) -> W_d_J1_J2 c-a-d variation de W_d / a J1 et J2 "
<< "\n# (7) -> W_d_J2_2 c-a-d variation seconde de W_d / a J2 "
<< "\n# (8) -> W_v_J3 c-a-d variation de W_v / J3 "
<< "\n# (9) -> W_v_J3J3 c-a-d variation seconde de W_v / J3 "
<< "\n#------------------------------------------------------------------------------------"
<< "\n# les variables de passage a la fonction sont celles definies lors de la definition "
<< "\n# de la fonction nD, avec en particulier: "
<< "\n#------------------------------------------------------------------------------------"
<< "\n# INVAR_B1 -> I_B "
<< "\n# INVAR_B2 -> II_B "
<< "\n# INVAR_B3 -> III_B "
<< "\n# INVAR_J1 -> J1 "
<< "\n# INVAR_J2 -> J2 "
<< "\n# INVAR_J3 -> J3 "
<< "\n# on peut aussi y ajouter toutes les grandeurs locales ou globales generiques "
<< "\n#------------------------------------------------------------------------------------"
<< "\n# il est possible de recuperer differentes grandeurs de travail par exemple "
<< "\n# l'intensite du potentiel, comme ces grandeurs sont calculees au moment de la resolution "
<< "\n# et ne sont pas stockees, il faut indiquer le mot cle sortie_post_ suivi de 1 (par defaut = 0) "
<< "\n# ensuite au moment de la constitution du .CVisu on aura acces aux grandeurs de travail "
<< "\n# ex: "
<< "\n# sortie_post_ 1 "
<< "\n# ce mot cle est le dernier des parametres specifiques de la loi il doit se situe "
<< "\n# a la fin de la derniere ligne de donnees "
<< "\n#"
<< "\n#------------------------------------------------------------------------------------"
<< "\n# NB: pour la definition de la fct nD il est aussi possible"
<< "\n# d'introduire directement la fonction a la place de son nom, comme pour "
<< "\n# toutes les autres lois "
<< endl;
};
// appel de la classe Hyper_W_gene_3D
Hyper_W_gene_3D::Info_commande_LoisDeComp_hyper3D(entreePrinc);
// appel de la classe mère
Loi_comp_abstraite::Info_commande_don_LoisDeComp(entreePrinc);
};
// test si la loi est complete
int Hyper_externe_W::TestComplet()
{ int ret = LoiAbstraiteGeneral::TestComplet();
if (W_potentiel == NULL)
{ret = 0;};
//
if (ret == 0)
{this-> Affiche();
ret = 0;
};
return ret;
};
//----- 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 Hyper_externe_W::Lecture_base_info_loi(ifstream& ent,const int cas,LesReferences& lesRef,LesCourbes1D& lesCourbes1D
,LesFonctions_nD& lesFonctionsnD)
{ string nom; bool test;
if (cas == 1)
{ ent >> nom;
if (nom != "HYPER_EXTERNE_W")
{ cout << "\n erreur en lecture de la loi : Hyper_externe_W, on attendait le mot cle : HYPER_EXTERNE_W "
<< "\n HYPER_EXTERNE_W::Lecture_base_info_loi(...";
Sortie(1);
};
ent >> nom >> sortie_post;
int test; // sert pour le test de l'existence de la fonction
// compressibilité
ent >> test ;
if (test == 1)
{W_potentiel = lesFonctionsnD.Lecture_pour_base_info(ent,cas,W_potentiel);
}
else
{// cas où on ne peut pas lire la fonction
if (W_potentiel != NULL)
if (W_potentiel->NomFonction() == "_")
{delete W_potentiel;W_potentiel=NULL;
cout << "\n *** attention, on supprime la fonction potentiel, car"
<< " on ne peut pas la lire, l'utilisation de la loi est impossible par la suite ";
this->Affiche();
};
};
};
// 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 Hyper_externe_W::Ecriture_base_info_loi(ofstream& sort,const int cas)
{ if (cas == 1)
{ sort << " HYPER_EXTERNE_W sortie_post_ "<< sortie_post ;
if (W_potentiel != NULL)
{sort << " 1 W_potentiel: " << " ";
LesFonctions_nD::Ecriture_pour_base_info(sort, cas,W_potentiel);
}
else
{ sort << " 0 W_potentiel: " << " ";};
}
// appel de la classe mère
Loi_comp_abstraite::Ecriture_don_base_info(sort,cas);
};
// 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 Hyper_externe_W::Grandeur_particuliere
(bool absolue,List_io<TypeQuelconque>& liTQ,Loi_comp_abstraite::SaveResul * saveDon ,list<int>& decal ) const
{// tout d'abord on récupère le conteneur
SaveResulHyper_externe_W & sav = *((SaveResulHyper_externe_W*) saveDon);
// on passe en revue la liste
List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end();
list<int>::iterator idecal=decal.begin();
for (itq=liTQ.begin();itq!=itqfin;itq++,idecal++)
{TypeQuelconque& tipParticu = (*itq); // pour simplifier
if (tipParticu.EnuTypeQuelconque().Nom_vide()) // veut dire que c'est un enum pur
{switch (tipParticu.EnuTypeQuelconque().EnumTQ())
{
case MODULE_COMPRESSIBILITE:
{ Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
tyTQ(1+(*idecal))=sav.module_compressibilite;(*idecal)++;
break;
}
case INVAR_B1 :
{Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) ((*itq).Grandeur_pointee()));
if (sortie_post) {tyTQ(1+(*idecal))=(*sav.inv_B)(1);}
else {tyTQ(1+(*idecal))=0.;}
(*idecal)++;
break;
}
case INVAR_B2 :
{Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) ((*itq).Grandeur_pointee()));
if (sortie_post) {tyTQ(1+(*idecal))=(*sav.inv_B)(2);}
else {tyTQ(1+(*idecal))=0.;}
(*idecal)++;
break;
}
case INVAR_B3 :
{Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) ((*itq).Grandeur_pointee()));
if (sortie_post) {tyTQ(1+(*idecal))=(*sav.inv_B)(3);}
else {tyTQ(1+(*idecal))=0.;}
(*idecal)++;
break;
}
case INVAR_J1 :
{Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) ((*itq).Grandeur_pointee()));
if (sortie_post) {tyTQ(1+(*idecal))=(*sav.inv_J)(1);}
else {tyTQ(1+(*idecal))=0.;}
(*idecal)++;
break;
}
case INVAR_J2 :
{Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) ((*itq).Grandeur_pointee()));
if (sortie_post) {tyTQ(1+(*idecal))=(*sav.inv_J)(2);}
else {tyTQ(1+(*idecal))=0.;}
(*idecal)++;
break;
}
case INVAR_J3 :
{Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) ((*itq).Grandeur_pointee()));
if (sortie_post) {tyTQ(1+(*idecal))=(*sav.inv_J)(3);}
else {tyTQ(1+(*idecal))=0.;}
(*idecal)++;
break;
}
case FCT_POTENTIEL_ND :
{Tab_Grandeur_Vecteur& tyTQ= *((Tab_Grandeur_Vecteur*) ((*itq).Grandeur_pointee()));
if (sortie_post)
{tyTQ(1+(*idecal))=(*sav.W_poten);}
else
{tyTQ(1+(*idecal)).Zero();}
(*idecal)++;
break;
}
case MODULE_CISAILLEMENT:
{ Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
tyTQ(1+(*idecal))=0.;(*idecal)++;
break;
}
default: ;// on ne fait rien
};
}; // fin du if
}; // fin de la boucle
};
// 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 Hyper_externe_W::ListeGrandeurs_particulieres(bool absolue,List_io<TypeQuelconque>& liTQ) const
{//on commence par définir une grandeur_scalaire_double
Tableau <double> tab_1(1);
Tab_Grandeur_scalaire_double grand_courant(tab_1);
// def d'un type quelconque représentatif à chaque grandeur
// a priori ces grandeurs sont défini aux points d'intégration identique à la contrainte par exemple
// enu_ddl_type_pt est définit dans la loi Abtraite générale
//on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée
// $$$ cas de MODULE_COMPRESSIBILITE: intéressant quand il dépend de la température
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == MODULE_COMPRESSIBILITE)
{ 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(MODULE_COMPRESSIBILITE,enu_ddl_type_pt,grand_courant);
liTQ.push_back(typQ1);
};
};
// $$$ cas de MODULE_CISAILLEMENT: intéressant quand il dépend de la température
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == MODULE_CISAILLEMENT)
{ 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 typQ2(MODULE_CISAILLEMENT,enu_ddl_type_pt,grand_courant);
liTQ.push_back(typQ2);
};
};
// $$$ cas des invariants de B
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == INVAR_B1)
{ 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 typQ2(INVAR_B1,enu_ddl_type_pt,grand_courant);
liTQ.push_back(typQ2);
};
};
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == INVAR_B2)
{ 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 typQ2(INVAR_B2,enu_ddl_type_pt,grand_courant);
liTQ.push_back(typQ2);
};
};
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == INVAR_B3)
{ 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 typQ2(INVAR_B3,enu_ddl_type_pt,grand_courant);
liTQ.push_back(typQ2);
};
};
// $$$ cas des invariants de J
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == INVAR_J1)
{ 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 typQ2(INVAR_J1,enu_ddl_type_pt,grand_courant);
liTQ.push_back(typQ2);
};
};
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == INVAR_J2)
{ 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 typQ2(INVAR_J2,enu_ddl_type_pt,grand_courant);
liTQ.push_back(typQ2);
};
};
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == INVAR_J3)
{ 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 typQ2(INVAR_J3,enu_ddl_type_pt,grand_courant);
liTQ.push_back(typQ2);
};
};
// $$$ cas de la fonction potentiel et de ses dérivées
{Vecteur v(9);
List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == FCT_POTENTIEL_ND)
{ 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)
{Tab_Grandeur_Vecteur tab(v,1);
TypeQuelconque typQ2(FCT_POTENTIEL_ND,enu_ddl_type_pt,tab);
liTQ.push_back(typQ2);
};
};
};
// calcul d'un module d'young équivalent à la loi: pour l'instant à faire !!
double Hyper_externe_W::Module_young_equivalent(Enum_dure temps,const Deformation & ,SaveResul * )
{// on met un message d'erreur
cout << "\n *** erreur, pour l'instant le module d'Young n'est pas calcule !! "
<< "\n Hyper_externe_W::Module_young_equivalent(... "<<flush;
Sortie(1);
return 0.;
};
// récupération d'un module de compressibilité équivalent à la loi, ceci pour un chargement nul
// il s'agit ici de la relation -pression = sigma_trace/3. = module de compressibilité * I_eps
// >>> en fait ici il s'agit du dernier module tangent calculé !!
double Hyper_externe_W::Module_compressibilite_equivalent(Enum_dure temps,const Deformation & def,SaveResul * saveResul)
{ SaveResulHyper_externe_W& sav = *((SaveResulHyper_externe_W*) saveResul);
return sav.module_compressibilite;
};
// ========== codage des METHODES VIRTUELLES protegees:================
// calcul des contraintes a t+dt
void Hyper_externe_W::Calcul_SigmaHH (TenseurHH& ,TenseurBB& ,DdlElement & tab_ddl,
TenseurBB & gijBB_t,TenseurHH & gijHH_t,BaseB& giB,BaseH& gi_H,TenseurBB & epsBB_,
TenseurBB & ,
TenseurBB & gijBB_,TenseurHH & gijHH_,Tableau <TenseurBB *>& d_gijBB_,
double& jacobien_0,double& jacobien,TenseurHH & sigHH_
,EnergieMeca & energ,const EnergieMeca & ,double& module_compressibilite,double& module_cisaillement
,const Met_abstraite::Expli_t_tdt& ex)
{
#ifdef MISE_AU_POINT
if (Permet_affichage() > 3)
{ cout << "\n Hyper_externe_W::Calcul_SigmaHH: avant critere ";
cout << "\n ele= "<< (Ptintmeca_en_cours()->Nb_ele()) << ", nbpti= "<< (Ptintmeca_en_cours()->Nb_pti());
};
if (epsBB_.Dimension() != 3)
{ cout << "\nErreur : la dimension devrait etre 3 !\n";
cout << " Hyper_externe_W::Calcul_SigmaHH\n";
Sortie(1);
};
if (tab_ddl.NbDdl() != d_gijBB_.Taille())
{ cout << "\nErreur : le nb de ddl est != de la taille de d_gijBB_ !\n";
cout << " Hyper_externe_W::Calcul_SigmaHH\n";
Sortie(1);
};
#endif
Tenseur3HH & sigHH = *((Tenseur3HH*) &sigHH_); // passage explicite en tenseur dim 3
// calcul des invariants et de leurs variations premières (méthode de Hyper_W_gene_3D)
Invariants_et_var1(*(ex.gijBB_0),*(ex.gijHH_0),gijBB_,gijHH_,jacobien_0,jacobien);
// calcul du potentiel et de ses dérivées premières / aux invariants J_r
// le potentiel: il faut calculer la fonction nD
// 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_umat = NULL;
Potentiel_et_var2(ex_impli,ex_expli_tdt,ex_umat);
// calcul du tenseur des contraintes
sigHH = ((W_d_J1)/V) * d_J_r_epsBB_HH(1) + (W_d_J2/V) * d_J_r_epsBB_HH(2)
+ ((W_v_J3)/V) * d_J_r_epsBB_HH(3);
#ifdef MISE_AU_POINT
if (Permet_affichage() > 4)
{TenseurHH* ptHH = NevezTenseurHH(sigHH);
sigHH.BaseAbsolue(*ptHH,giB);
cout << "\n base giB(1) "<< giB(1)
<< "\n base giB(2) "<< giB(2);
cout << "\n sigHH= en giB "; sigHH.Ecriture(cout);
cout << "\n sigma en absolu: ";
ptHH->Ecriture(cout);
delete ptHH;
};
#endif
// calcul du module de compressibilité
module_compressibilite = 2. * W_v_J3;
SaveResulHyper_externe_W& sav = *((SaveResulHyper_externe_W*) saveResul);
sav.module_compressibilite = module_compressibilite;
// pour le module de cisaillement, pour l'instant je ne fais rien !! à voir ***
module_cisaillement = 0.;
// traitement des énergies
energ.Inita(0.);
energ.ChangeEnergieElastique((W_d)/V);
// energ.ChangeEnergieElastique((W_d+W_v)/V);
LibereTenseur();
};
// calcul des contraintes a t+dt et de ses variations
void Hyper_externe_W::Calcul_DsigmaHH_tdt (TenseurHH& ,TenseurBB& ,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 &
,TenseurBB & gijBB_tdt,TenseurHH & gijHH_tdt_
,Tableau <TenseurBB *>& d_gijBB_tdt
,Tableau <TenseurHH *>& ,double& jacobien_0,double& jacobien
,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 (Permet_affichage() > 3)
{ cout << "\n Hyper_externe_W::Calcul_DsigmaHH_tdt: ";
cout << "\n ele= "<< (Ptintmeca_en_cours()->Nb_ele()) << ", nbpti= "<< (Ptintmeca_en_cours()->Nb_pti());
};
if (epsBB_tdt.Dimension() != 3)
{ cout << "\nErreur : la dimension devrait etre 3 !\n";
cout << " Hyper_externe_W::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 << " Hyper_externe_W::Calcul_SDsigmaHH_tdt\n";
Sortie(1);
};
#endif
Tenseur3HH & sigHH = *((Tenseur3HH*) &sigHH_tdt); // passage en dim 3 explicite
Tenseur3HH & gijHH_tdt = *((Tenseur3HH*) &gijHH_tdt_); // passage en dim 3 explicite
// calcul des invariants et de leurs variations premières et secondes
Invariants_et_var2(*(ex.gijBB_0),*(ex.gijHH_0),gijBB_tdt,gijHH_tdt,jacobien_0,jacobien);
// calcul du potentiel et de ses dérivées premières et secondes / aux invariants J_r
// le potentiel: il faut calculer la fonction nD
// 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_umat = NULL;
Potentiel_et_var2(ex_impli,ex_expli_tdt,ex_umat);
// calcul du tenseur des contraintes
double unSurV=1./V;
sigHH = ((W_d_J1)/V) * d_J_r_epsBB_HH(1) + (W_d_J2/V) * d_J_r_epsBB_HH(2)
+ ((W_v_J3)/V) * d_J_r_epsBB_HH(3);
#ifdef MISE_AU_POINT
if (Permet_affichage() > 4)
{TenseurHH* ptHH = NevezTenseurHH(sigHH);
sigHH.BaseAbsolue(*ptHH,giB_tdt);
cout << "\n base giB(1) "<< giB_tdt(1)
<< "\n base giB(2) "<< giB_tdt(2);
cout << "\n sigHH= en giB "; sigHH.Ecriture(cout);
cout << "\n sigma en absolu: ";
ptHH->Ecriture(cout);
delete ptHH;
if (Permet_affichage() > 5)
cout << "\n d_J_r_epsBB_HH1 " << d_J_r_epsBB_HH(1)
<< "\n d_J_r_epsBB_HH2 " << d_J_r_epsBB_HH(2)
<< "\n d_J_r_epsBB_HH3 " << d_J_r_epsBB_HH(3)
<< "\n (W_d_J1*unSurV) " << (W_d_J1*unSurV)
<< " (W_d_J2*unSurV) " << (W_d_J2*unSurV)
<< " (W_d_J3*unSurV) " << (W_v_J3*unSurV);
};
#endif
// calcul de la variation seconde du potentiel par rapport à epsij epskl
Tenseur3HHHH d2W_d2epsHHHH
= // tout d'abord les dérivées secondes du potentiel déviatoire + courbure éventuellement
(W_d_J1_2 ) * Tenseur3HHHH::Prod_tensoriel(d_J_r_epsBB_HH(1),d_J_r_epsBB_HH(1))
+ W_d_J1_J2 * Tenseur3HHHH::Prod_tensoriel(d_J_r_epsBB_HH(1),d_J_r_epsBB_HH(2))
+ W_d_J2_2 * Tenseur3HHHH::Prod_tensoriel(d_J_r_epsBB_HH(2),d_J_r_epsBB_HH(2))
// puis les dérivées premières du potentiel déviatoire + courbure éventuellement
+ (W_d_J1 ) * d_J_1_eps2BB_HHHH + W_d_J2 * d_J_2_eps2BB_HHHH
// enfin les dérivées seconde et première du potentiel sphérique + courbure éventuellement
+ (W_v_J3 ) * d_J_3_eps2BB_HHHH
+ (W_v_J3J3 ) * Tenseur3HHHH::Prod_tensoriel(d_J_r_epsBB_HH(3),d_J_r_epsBB_HH(3));
// calcul de la variation du tenseur des contraintes par rapports aux déformations
// on tient compte du fait que V*sigHH = d W/ d epsij
Tenseur3HH interHH = -sigHH ; //* (-0.5*unSurV*unSurV);
// Tenseur3HHHH dSigdepsHHHH(1,interHH,d_J_r_epsBB_HH(3));
Tenseur3HHHH dSigdepsHHHH(1,interHH,gijHH_tdt);
// dSigdepsHHHH += (unSurV) * d2W_d2epsHHHH;
Tenseur3HHHH interHHHH((unSurV) * d2W_d2epsHHHH); // cas des tenseurs généraux
dSigdepsHHHH += interHHHH; // cas des tenseurs généraux
//---------------------------------------------------------------------------------
// vérif numérique de l'opérateur tangent
// Cal_dsigma_deps_num (*(ex.gijBB_0),*(ex.gijHH_0),gijBB_tdt
// ,gijHH_tdt,jacobien_0,jacobien,dSigdepsHHHH
// ,const Met_abstraite::Impli& ex );
//---------------------------------------------------------------------------------
// calcul des variations / aux ddl
int nbddl = d_gijBB_tdt.Taille();
for (int i = 1; i<= nbddl; i++)
{ // on fait uniquement une égalité d'adresse et de ne pas utiliser
// le constructeur d'ou la profusion d'* et de ()
Tenseur3HH & dsigHH = *((Tenseur3HH*) (d_sigHH(i))); // passage en dim 3
const Tenseur3BB & depsBB = *((Tenseur3BB *) (d_epsBB(i))); // "
dsigHH = dSigdepsHHHH && depsBB;
};
// calcul du module de compressibilité
module_compressibilite = 2. * W_v_J3;
SaveResulHyper_externe_W& sav = *((SaveResulHyper_externe_W*) saveResul);
sav.module_compressibilite = module_compressibilite;
// pour le module de cisaillement, pour l'instant je ne fais rien !! à voir ***
module_cisaillement = 0.;
// traitement des énergies
energ.Inita(0.);
energ.ChangeEnergieElastique((W_d+W_v)/V);
LibereTenseur();
LibereTenseurQ();
};
// calcul des contraintes et ses variations par rapport aux déformations a t+dt
// en_base_orthonormee: le tenseur de contrainte en entrée est en orthonormee
// le tenseur de déformation et son incrémentsont également en orthonormees
// si = false: les bases transmises sont utilisées
// ex: contient les éléments de métrique relativement au paramétrage matériel = X_(0)^a
void Hyper_externe_W::Calcul_dsigma_deps (bool en_base_orthonormee, TenseurHH & ,TenseurBB&
,TenseurBB & epsBB_tdt,TenseurBB &, double& jacobien_0,double& jacobien
,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 (Permet_affichage() > 3)
{ cout << "\n Hyper_externe_W::Calcul_dsigma_deps: ";
cout << "\n ele= "<< (Ptintmeca_en_cours()->Nb_ele()) << ", nbpti= "<< (Ptintmeca_en_cours()->Nb_pti());
};
if (epsBB_tdt.Dimension() != 3)
{ cout << "\nErreur : la dimension devrait etre 3 !\n";
cout << " Hyper_externe_W::Calcul_dsigma_deps\n";
Sortie(1);
};
#endif
Tenseur3HH & sigHH = *((Tenseur3HH*) &sigHH_tdt); // // passage en dim 3 explicite
Tenseur3HH & gijHH_tdt = *((Tenseur3HH*) ex.gijHH_tdt); // passage en dim 3 explicite
// calcul des invariants et de leurs variations premières et secondes
Invariants_et_var2(*(ex.gijBB_0),*(ex.gijHH_0),*(ex.gijBB_tdt),gijHH_tdt,jacobien_0,jacobien);
// calcul du potentiel et de ses dérivées premières et secondes / aux invariants J_r
// le potentiel: il faut calculer la fonction nD
// 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_umat = &ex;
Potentiel_et_var2(ex_impli,ex_expli_tdt,ex_umat);
// calcul du tenseur des contraintes, on travaille ici dans le repère matériel finale correspondant
// aux coordonnées initiales X_(0)^a, on obtient donc un tenseur dans la base naturelle finale
double unSurV=1./V;
Tenseur3HH sig_localeHH = ((W_d_J1)*unSurV) * d_J_r_epsBB_HH(1) + (W_d_J2*unSurV) * d_J_r_epsBB_HH(2)
+ ((W_v_J3)*unSurV) * d_J_r_epsBB_HH(3);
// passage éventuelle dans la base I_a
if (en_base_orthonormee)
{sig_localeHH.BaseAbsolue(sigHH,*(ex.giB_tdt));}
else {sigHH = sig_localeHH;}; // sinon la base locale est la bonne
#ifdef MISE_AU_POINT
if (Permet_affichage() > 4)
{cout << "\n sigHH en local" << sigHH;
Tenseur3HH sig_3D_inter;
sigHH.BaseAbsolue(sig_3D_inter,*(ex.giB_tdt));
cout << "\n sigHH en absolue 3D : "<<sig_3D_inter;
if (Permet_affichage() > 5)
cout << "\n d_J_r_epsBB_HH1 " << d_J_r_epsBB_HH(1)
<< "\n d_J_r_epsBB_HH2 " << d_J_r_epsBB_HH(2)
<< "\n d_J_r_epsBB_HH3 " << d_J_r_epsBB_HH(3)
<< "\n (W_d_J1*unSurV) " << (W_d_J1*unSurV)
<< " (W_d_J2*unSurV) " << (W_d_J2*unSurV)
<< " (W_d_J3*unSurV) " << (W_v_J3*unSurV);
};
#endif
// calcul de la variation seconde du potentiel par rapport à epsij epskl
// calcul de la variation seconde du potentiel par rapport à epsij epskl
Tenseur3HHHH d2W_d2epsHHHH
= // tout d'abord les dérivées secondes du potentiel déviatoire + courbure éventuellement
(W_d_J1_2 ) * Tenseur3HHHH::Prod_tensoriel(d_J_r_epsBB_HH(1),d_J_r_epsBB_HH(1))
+ W_d_J1_J2 * Tenseur3HHHH::Prod_tensoriel(d_J_r_epsBB_HH(1),d_J_r_epsBB_HH(2))
+ W_d_J2_2 * Tenseur3HHHH::Prod_tensoriel(d_J_r_epsBB_HH(2),d_J_r_epsBB_HH(2))
// puis les dérivées premières du potentiel déviatoire + courbure éventuellement
+ (W_d_J1 ) * d_J_1_eps2BB_HHHH + W_d_J2 * d_J_2_eps2BB_HHHH
// enfin les dérivées seconde et première du potentiel sphérique + courbure éventuellement
+ (W_v_J3 ) * d_J_3_eps2BB_HHHH
+ (W_v_J3J3 ) * Tenseur3HHHH::Prod_tensoriel(d_J_r_epsBB_HH(3),d_J_r_epsBB_HH(3));
// calcul de la variation du tenseur des contraintes par rapports aux déformations
// on tient compte du fait que V*sigHH = d W/ d epsij
Tenseur3HH interHH = -sig_localeHH ; //* (-0.5*unSurV*unSurV);
// calcul de la variation du tenseur des contraintes par rapports aux déformations
// on tient compte du fait que V*sigHH = d W/ d epsij
Tenseur3HHHH dSigdepsHHHH(1,interHH,gijHH_tdt);
Tenseur3HHHH interHHHH((unSurV) * d2W_d2epsHHHH); // cas des tenseurs généraux
dSigdepsHHHH += interHHHH; // cas des tenseurs généraux
// transfert des informations: on pas d'un tenseur de 81 composantes à 36
// avec des symétries par rapport aux deux premiers indices et par rapport aux deux derniers
/// Tenseur3HHHH d_sigma_depsHHHH; d_sigma_depsHHHH.TransfertDunTenseurGeneral(dSigdepsHHHH.Symetrise1et2_3et4());
// calcul de la première partie de l'opérateur tangent (correspond au changement de repère
// gi_tdt -> Ia de l'opérateur calculer précédemment
Tenseur3HHHH & d_sigma_depsFinHHHH = *((Tenseur3HHHH*) &d_sigma_deps_); // pour accés directe
// passage éventuelle dans la base I_a
if (en_base_orthonormee)
{dSigdepsHHHH.ChangeBase(d_sigma_depsFinHHHH,*(ex.giB_tdt));}
else
{d_sigma_depsFinHHHH = dSigdepsHHHH;};
// calcul du module de compressibilité
module_compressibilite = 2. * W_v_J3;
SaveResulHyper_externe_W& sav = *((SaveResulHyper_externe_W*) saveResul);
sav.module_compressibilite = module_compressibilite;
// pour le module de cisaillement, pour l'instant je ne fais rien !! à voir ***
module_cisaillement = 0.;
// traitement des énergies
energ.Inita(0.);
energ.ChangeEnergieElastique((W_d)/V);
// energ.ChangeEnergieElastique((W_d+W_v)/V);
LibereTenseur();
LibereTenseurQ();
};
//---------------------- méthodes privées -------------------------------
// calcul du potentiel et de ses dérivées premières / aux invariants J_r
void Hyper_externe_W::Potentiel_et_var2
(const Met_abstraite::Impli* ex_impli
,const Met_abstraite::Expli_t_tdt* ex_expli_tdt
,const Met_abstraite::Umat_cont* ex_umat)
{ // calcul de grandeurs intermédiaires
// le potentiel: il faut calculer la fonction nD
// 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 = W_potentiel->Li_enu_etendu_scalaire();
// on regarde s'il faut renseigner les invariants de B et/ou de J
List_io<Ddl_etendu> deja_calculer_etend;
{List_io<Ddl_enum_etendu>::iterator ipq,ipqfin=li_enu_scal.end();
for (ipq=li_enu_scal.begin();ipq!=ipqfin;ipq++)
{int posi = (*ipq).Position()-NbEnum_ddl();
switch (posi)
{
case 131 :
{deja_calculer_etend.push_back(Ddl_etendu((*ipq),I_B));
break;
}
case 132 :
{deja_calculer_etend.push_back(Ddl_etendu((*ipq),II_B));
break;
}
case 133 :
{deja_calculer_etend.push_back(Ddl_etendu((*ipq),III_B));
break;
}
case 134 :
{deja_calculer_etend.push_back(Ddl_etendu((*ipq),J_r(1)));
break;
}
case 135 :
{deja_calculer_etend.push_back(Ddl_etendu((*ipq),J_r(2)));
break;
}
case 136 :
{deja_calculer_etend.push_back(Ddl_etendu((*ipq),J_r(3)));
break;
}
default: // on ne fait rien
break;
};
};
}
// on utilise la méthode générique de loi abstraite
Tableau <double> & tab_val = Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(W_potentiel,9 // 9 valeurs attendue en retour
,ex_impli,ex_expli_tdt,ex_umat
,&deja_calculer_etend
,NULL
,NULL
);
/*
// Tableau <double> & Loi_comp_Valeur_FnD_Evoluee
// (Fonction_nD* fct,int nb_retour
// ,const Met_abstraite::Impli* ex_impli
// ,const Met_abstraite::Expli_t_tdt* ex_expli_tdt
// ,const Met_abstraite::Umat_cont* ex_umat
// ,const List_io<Ddl_enum_etendu>* exclure_dd_etend = NULL
// ,const List_io<EnumTypeQuelconque>* exclure_Q = NULL
// ,list <SaveResul*>* list_save = 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_umat,NULL);
// calcul de la valeur et retour dans tab_ret
Tableau <double> & tab_val = W_potentiel->Valeur_FnD_Evoluee(&val_ddl_enum,&li_enu_scal,&li_quelc,NULL,NULL);
#ifdef MISE_AU_POINT
if (tab_val.Taille() != 9)
{ cout << "\nErreur : la fonction nD relative a la fonction potentielle "
<< " doit calculer un vecteur de dimention 9 or le tableau de retour est de taille "
<< tab_val.Taille() << " ce n'est pas normal !\n";
cout << " Hyper_externe_W::Potentiel_et_var\n";
Sortie(1);
};
#endif
*/
// on récupère les valeurs du tableau
W_d= tab_val(1); W_v= tab_val(2); // le potentiel: partie déviatorique, partie sphérique
W_d_J1= tab_val(3);W_d_J2= tab_val(4); // dérivées premières du potentiel déviatoire par rapport aux J_1 et J_2
W_d_J1_2= tab_val(5);W_d_J1_J2= tab_val(6);W_d_J2_2= tab_val(7);; // dérivées secondes
W_v_J3= tab_val(8);W_v_J3J3= tab_val(9); // dérivées premières et seconde du potentiel volumique / J3
// stockage éventuel pour du post-traitement
if (sortie_post)
{ // récup du conteneur spécifique du point, pour sauvegarde éventuelle
SaveResulHyper_W_gene_3D & save_resulHyper_W = *((SaveResulHyper_W_gene_3D*) saveResul);
save_resulHyper_W.invP->potentiel= W_d + W_v;
// puis les nouvelles variables
SaveResulHyper_externe_W& sav = *((SaveResulHyper_externe_W*) saveResul);
Vecteur& inv__B = *sav.inv_B; // pour simplifier
inv__B(1) = I_B;
inv__B(2) = II_B;
inv__B(3) = III_B;
Vecteur& inv__J = *sav.inv_J; // pour simplifier
inv__J = J_r;
// cout << "\n inv__B= "<<inv__B << " inv__J= "<<inv__J<<flush;
Vecteur& W__poten = *sav.W_poten; // pour simplifier
W__poten(1) = W_d;
W__poten(2) = W_v;
W__poten(3) = W_d_J1;
W__poten(4) = W_d_J2;
W__poten(5) = W_d_J1_2;
W__poten(6) = W_d_J1_J2;
W__poten(7) = W_d_J2_2;
W__poten(8) = W_v_J3;
W__poten(9) = W_v_J3J3;
};
};
// calcul de la dérivée numérique de la contrainte
void Hyper_externe_W::Cal_dsigma_deps_num
(const TenseurBB & gijBB_0_,const TenseurHH & gijHH_0_
,const TenseurBB & gijBB_tdt_,const TenseurHH & gijHH_tdt_
,const double& jacobien_0,const double& jacobien
,Tenseur3HHHH& dSigdepsHHHH
,const Met_abstraite::Impli& ex )
{ const Tenseur3BB & gijBB_0 = *((Tenseur3BB*) &gijBB_0_); // passage en dim 3 explicit
const Tenseur3BB & gijBB_tdt = *((Tenseur3BB*) &gijBB_tdt_); // "
const Tenseur3HH & gijHH_0 = *((Tenseur3HH*) &gijHH_0_); // "
const Tenseur3HH & gijHH_tdt = *((Tenseur3HH*) &gijHH_tdt_); // "
Tenseur3BB gijBBtdt_N; // tenseur modifié
Tenseur3HH gijHHtdt_N; // idem_0
double delta = ConstMath::unpeupetit*10.;
double unSurDelta = 1./delta;
// cas des contraintes et de ses variations analytiques
// Tenseur3HHHH dSigdepsHHHH; // le tenseur contenant les dérivées analytiques
Tenseur3HH SigmaHH_deb;
Cal_sigmaEtDer_pour_num(gijBB_0_,gijHH_0_,gijBB_tdt_,gijHH_tdt_
,jacobien_0,jacobien,SigmaHH_deb,dSigdepsHHHH,ex);
// dimensionnement pour la matrice numérique
Tenseur3HHHH dSigdepsHHHH_num;
// on va boucler sur les composantes de gijBB
for (int i=1;i<=3;i++)
for (int j=1;j<=3;j++)
{ gijBBtdt_N = gijBB_tdt;
gijBBtdt_N.Coor(i,j) += delta;
// en fait dans l'opération précédente on a modifier les termes (i,j) et (j,i)
// car le tenseur est symétrique
// on a donc en variation numérique la somme des deux dérivées
// on définit un coeff multiplicatif qui vaut 1 ou 0.5
double coef=1.; if (i != j) coef = 0.5;
gijHHtdt_N = gijBBtdt_N.Inverse();
double jacobien_N=sqrt(gijBBtdt_N.Det());
// cas des contraintes
Tenseur3HH SigmaHH_N;
Cal_sigma_pour_num(gijBB_0_,gijHH_0_,(const TenseurBB &) gijBBtdt_N
,(const TenseurHH &) gijHHtdt_N
,jacobien_0,jacobien_N,SigmaHH_N,ex);
// calcul des dérivées numériques et comparaisons
for (int k=1;k<=3;k++)
for (int l=1;l<=3;l++)
{ //
double derSigNum = coef * 2.*(SigmaHH_N(k,l) - SigmaHH_deb(k,l) )*unSurDelta;
dSigdepsHHHH_num.Change(k,l,i,j,derSigNum);
double derSigAna = dSigdepsHHHH(k,l,i,j);//0.5*(dSigdepsHHHH(k,l,i,j) + dSigdepsHHHH(k,l,j,i));
bool erreur = false;
if (diffpourcent(derSigNum,derSigAna,MaX(Dabs(derSigNum),Dabs(derSigAna)),0.1))
if (MaX(Dabs(derSigNum),Dabs(derSigAna)) > 200.)
{if (MiN(Dabs(derSigNum),Dabs(derSigAna)) == 0.)
{if ( MaX(Dabs(derSigNum),Dabs(derSigAna)) > 50.*delta) erreur = true;}
else erreur = true;
};
// erreur = false; // a virer
if (erreur)
{
// calcul des dérivées d'éléments intermédiaires pour voir
//
cout << "\n erreur dans le calcul analytique de l'operateur tangent "
<< "\n derSigNum= " << derSigNum << " derSigAna= " << derSigAna
<< " klij= " << k << " " << l << " " << i << " " << j
<< " SigmaHH_N(k,l)= " << SigmaHH_N(k,l);
cout << "\n Hyper_externe_W::Calcul_derivee_numerique(..";
cout << "\n un caractere ";
// --- pour le débug ----
// calcul des invariants et de leurs variations premières en numérique
Invariants_et_var1_deb(gijBB_0_,gijHH_0_,(const TenseurBB &) gijBBtdt_N,(const TenseurHH &) gijHHtdt_N
,jacobien_0,jacobien_N);
// calcul des invariants et de leurs variations premières et secondes
Invariants_et_var2_deb(gijBB_0_,gijHH_0_,(const TenseurBB &) gijBBtdt_N,(const TenseurHH &) gijHHtdt_N
,jacobien_0,jacobien_N);
string toto;
toto= lect_chaine();
};
};
};
// passage des dérivées numériques aux dérivées finales
dSigdepsHHHH= dSigdepsHHHH_num;
};
// calcul de la contrainte avec le minimum de variable de passage, utilisé pour le numérique
void Hyper_externe_W::Cal_sigma_pour_num
(const TenseurBB & gijBB_0,const TenseurHH & gijHH_0
,const TenseurBB & gijBB_tdt,const TenseurHH & gijHH_tdt
,const double& jacobien_0,const double& jacobien,TenseurHH & sigHH_
,const Met_abstraite::Impli& ex)
{
Tenseur3HH & sigHH = *((Tenseur3HH*) &sigHH_); // passage en dim 3 explicite
// calcul des invariants et de leurs variations premières (méthode de Hyper_W_gene_3D)
// Invariants_et_var1(gijBB_0,gijHH_0,gijBB_tdt,gijHH_tdt,jacobien_0,jacobien);
// pour vérif on appelle var2, mais c'est à virer
Invariants_et_var1(gijBB_0,gijHH_0,gijBB_tdt,gijHH_tdt,jacobien_0,jacobien);
// calcul du potentiel et de ses dérivées premières / aux invariants J_r
// le potentiel: il faut calculer la fonction nD
// 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_umat = NULL;
Potentiel_et_var2(ex_impli,ex_expli_tdt,ex_umat);
// calcul du tenseur des contraintes
double unSurV=1./V;
sigHH = ((W_d_J1)/V) * d_J_r_epsBB_HH(1) + (W_d_J2/V) * d_J_r_epsBB_HH(2)
+ ((W_v_J3)/V) * d_J_r_epsBB_HH(3);
};
// idem avec la variation
void Hyper_externe_W::Cal_sigmaEtDer_pour_num
(const TenseurBB & gijBB_0,const TenseurHH & gijHH_0
,const TenseurBB & gijBB_tdt,const TenseurHH & gijHH_tdt
,const double& jacobien_0,const double& jacobien
,TenseurHH & sigHH_,Tenseur3HHHH& dSigdepsHHHH
,const Met_abstraite::Impli& ex)
{
Tenseur3HH & sigHH = *((Tenseur3HH*) &sigHH_); // passage en dim 3 explicite
// calcul des invariants et de leurs variations premières et seconde (méthode de Hyper_W_gene_3D)
Invariants_et_var2(gijBB_0,gijHH_0,gijBB_tdt,gijHH_tdt,jacobien_0,jacobien);
// calcul du potentiel et de ses dérivées premières / aux invariants J_r
// le potentiel: il faut calculer la fonction nD
// 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_umat = NULL;
Potentiel_et_var2(ex_impli,ex_expli_tdt,ex_umat);
// calcul du tenseur des contraintes
double unSurV=1./V;
sigHH = ((W_d_J1)/V) * d_J_r_epsBB_HH(1) + (W_d_J2/V) * d_J_r_epsBB_HH(2)
+ ((W_v_J3)/V) * d_J_r_epsBB_HH(3);
// calcul de la variation seconde du potentiel par rapport à epsij epskl
Tenseur3HHHH d2W_d2epsHHHH
= // tout d'abord les dérivées secondes du potentiel déviatoire + courbure éventuellement
(W_d_J1_2 ) * Tenseur3HHHH::Prod_tensoriel(d_J_r_epsBB_HH(1),d_J_r_epsBB_HH(1))
+ W_d_J1_J2 * Tenseur3HHHH::Prod_tensoriel(d_J_r_epsBB_HH(1),d_J_r_epsBB_HH(2))
+ W_d_J2_2 * Tenseur3HHHH::Prod_tensoriel(d_J_r_epsBB_HH(2),d_J_r_epsBB_HH(2))
// puis les dérivées premières du potentiel déviatoire + courbure éventuellement
+ (W_d_J1 ) * d_J_1_eps2BB_HHHH + W_d_J2 * d_J_2_eps2BB_HHHH
// enfin les dérivées seconde et première du potentiel sphérique + courbure éventuellement
+ (W_v_J3 ) * d_J_3_eps2BB_HHHH
+ (W_v_J3J3 ) * Tenseur3HHHH::Prod_tensoriel(d_J_r_epsBB_HH(3),d_J_r_epsBB_HH(3));
// calcul de la variation du tenseur des contraintes par rapports aux déformations
// on tient compte du fait que V*sigHH = d W/ d epsij
Tenseur3HH interHH = -sigHH ; //* (-0.5*unSurV*unSurV);
Tenseur3HHHH d_igdepsHHHH(1,interHH,gijHH_tdt);
d_igdepsHHHH += (unSurV) * d2W_d2epsHHHH;
dSigdepsHHHH = d_igdepsHHHH;
};