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

3077 lines
158 KiB
C++
Executable file

// FICHIER : LoiContraintesPlanesDouble.cp
// CLASSE : LoiContraintesPlanesDouble
// 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 "LesLoisDeComp.h"
# include <iostream>
using namespace std; //introduces namespace std
#include <math.h>
#include <stdlib.h>
#include "Sortie.h"
#include "TypeQuelconqueParticulier.h"
#include "TypeConsTens.h"
#include "NevezTenseurQ.h"
#include "Util.h"
#include "ExceptionsLoiComp.h"
#include "MotCle.h"
#include "MathUtil.h"
#include "MathUtil2.h"
#include "LoiContraintesPlanesDouble.h"
// calcul des contraintes et ses variations par rapport aux déformations a t+dt
// ceci dans le cas où l'axe de traction simple est quelconque
// ici on suppose que:
// - tous les calculs sont en dim 3
// - l'axe 3 est normal aux deux autres (ceci pour Vi et pour gi)
//
// ViB et ViH : correspond à la base de traction: les vecteurs sont identiques
// par contre leurs composantes sont différentes car exprimés dans g^i et g_i
// telle que \vec ViB(1) = \vec ViH(1) = l'axe de traction
// La base Vi est supposée orthonormée
// 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 !!** non pas tout le temps a revoir
void LoiContraintesPlanesDouble::Calcul_dsigma_deps
(bool en_base_orthonormee,const BaseB * ViB,const BaseH * ViH
,const TenseurHH & sigHH_t,const TenseurBB& DepsBB
,const TenseurBB & epsBB_tdt,const TenseurBB & delta_epsBB,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)
{ // récup du conteneur spécifique
SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul);
module_compressibilite=module_cisaillement=0.; // init
energ.Inita(0.); // initialisation des énergies mises en jeux
//récup de eps_mecaBB_t
// 1) dans le repère gi
Tenseur3BB& eps_mecaBB_t = *((Tenseur3BB*) (save_resul.eps_mecaBB_t));
Tenseur3BB& eps_mecaBB = *((Tenseur3BB*) (save_resul.eps_mecaBB));
// 2) dans le dernier repère V_a: a utiliser en sortie post, pas pour le calcul !!
Tenseur3BB& eps_P_mecaBB_t = *((Tenseur3BB*) (save_resul.eps_P_mecaBB_t));
Tenseur3BB& eps_P_mecaBB = *((Tenseur3BB*) (save_resul.eps_P_mecaBB));
// on récupère la dimension de l'espace de travail qui doit-être de dimension 3
// ainsi que le nombre de vecteur: pour l'instant 3
#ifdef MISE_AU_POINT
{if (Permet_affichage() > 5)
cout << "\n LoiContraintesPlanesDouble::Calcul_dsigma_deps(...";
if ((ViB->Dimension() != 3) || (ViH->Dimension() != 3))
{ cout << "\n***Erreur : la dimension de la base ViB = "<< ViB->Dimension()
<< " ou la dimension de la base ViH = " << ViH->Dimension()
<< " est different de 3, on ne peut pas continuer ! "
<< "\n LoiContraintesPlanesDouble::Calcul_dsigma_deps(...";
Sortie(1);
};
if ((ViB->NbVecteur() != 3) || (ViH->NbVecteur() != 3))
{ cout << "\n***Erreur : le nombre de vecteur de la base ViB = "
<< ViB->NbVecteur()
<< " ou le nombre de vecteur de la base ViH = " << ViH->NbVecteur()
<< " est different de 3, on ne peut pas continuer ! "
<< "\n LoiContraintesPlanesDouble::Calcul_dsigma_deps(...";
Sortie(1);
};
// idem pour l'Umat: là on ne test que les vecteurs à 0, pour alléger le test
if (ex.giB_0->Dimension() != 3)
{ cout << "\n***Erreur : la dimension de la base ex.giB_0 = "
<< ex.giB_0->Dimension()
<< " du conteneur Umat, est different de 3, on ne peut pas continuer ! "
<< "\n LoiContraintesPlanesDouble::Calcul_dsigma_deps(...";
Sortie(1);
};
if (ex.giB_0->NbVecteur() != 3)
{ cout << "\n***Erreur : le nombre de vecteur de la base ex.giB_0 = "
<< ex.giB_0->NbVecteur()
<< " du conteneur Umat est different de 3, on ne peut pas continuer ! "
<< "\n LoiContraintesPlanesDouble::Calcul_dsigma_deps(...";
Sortie(1);
};
}
#endif
// les coordonnées des vecteurs \vec V_e sont exprimées
// dans la base de travail g_i finale on a donc
// Vi_B(i) = {\beta'}_i^{.j} \hat{\vec g}_j = betaP(i,j) * giB_tdt(j)
// i indice de ligne, j indice de colonne
// \vec V_i = \vec V^i : les vecteurs sont égaux mais pas les composantes !
// 1 -- passage de la base \vec V_e à la base \hat{\vec g}_i
// et \vec V^e à la base \hat{\vec g}^i
// calcul des grandeurs gamma et beta:
// \hat{\vec g}^i = \gamma^i_{~.e}~\vec V^e
// \hat{\vec g}_i = \beta_i^{~.e}~\vec V_e
// 2 -- passage de la base \hat{\vec g}_i à la base \vec V_e
// et \hat{\vec g}^i à la base \vec V^e
//
// Vi_B(i) = {\beta'}_i^{.j} \hat{\vec g}_j
// Vi_H(i) = {\gamma'}^i_{.j} \hat{\vec g}^j
// gamma3D(i,e) = \gamma^i_{~.e} = \hat{\vec g}^i . \vec V_e
// ce qui donne que [gamma3D(i,e)] = [{\beta'}_i^{.j}]^T
for (int i=1;i<4;i++) // calcul de la matrice beta'
for (int e=1;e<4;e++) // au lieu de passer par un produit scalaire on récupère
{betaP_3D(i,e) = (*ViH)(i)(e); // directement les coordonnées
gammaP_3D(i,e) = (*ViB)(i)(e); // " "
};
// \beta_i^{~.e} = \hat{\vec g}_i . \vec V^e
// c'est aussi l'inverse de la transposé de gamma3D
// on choisit de calculer avec la formule
gamma3D = betaP_3D.Transpose(); // ok
beta3D = gammaP_3D.Transpose(); // betaP_3D.Inverse();
// gammaP_3D = beta3D.Transpose();
#ifdef MISE_AU_POINT
if (Permet_affichage() > 6)
{cout << "\n Vi_B(1)= "<<(*ViB)(1) << " Vi_B(2)= "<<(*ViB)(2) << " Vi_B(3)= "<<(*ViB)(3);
cout << "\n Vi_H(1)= "<<(*ViH)(1) << " Vi_H(2)= "<<(*ViH)(2) << " Vi_H(3)= "<<(*ViH)(3);
cout << "\n Vi_B(i) = {beta'}_i^{.j} hat{vec g}_j --> beta'= ";betaP_3D.Affiche();
cout << "\n Vi_H(i) = {gamma'}^i_{.j} hat{vec g}^j--> gamma'= ";gammaP_3D.Affiche();
cout << "\n hat{vec g}^i = gamma^i_{~.e}~vec V^e --> gamma= ";gamma3D.Affiche();
cout << "\n hat{vec g}_i = beta_i^{~.e}~vec V_e--> beta= ";beta3D.Affiche();
};
#endif
// on alimente les pointeurs de tenseurs d'entrée de la cinématique
epsBB_tdt_cin = ((Tenseur3BB*) &epsBB_tdt); // passage en dim 3
DepsBB_cin = ((Tenseur3BB*) &DepsBB); // passage en dim 3
delta_epsBB_cin = ((Tenseur3BB*) &delta_epsBB); // passage en dim 3
#ifdef MISE_AU_POINT
if (Permet_affichage() > 6)
{cout << "\n epsBB_tdt_cin "<< (*epsBB_tdt_cin) << "\n DepsBB_cin "<< (*DepsBB_cin)
<< "\n delta_epsBB_cin "<< (*delta_epsBB_cin) << flush;
// en base orthonormee
Tenseur3BB epsBB_tdt_cin_inter;
epsBB_tdt_cin->BaseAbsolue(epsBB_tdt_cin_inter,(* ex.giH_tdt));
cout << "\n epsBB_tdt_cin= en absolue 3D : "<<epsBB_tdt_cin_inter;
};
#endif
// --- initialisation des déformations mécaniques dans le repère V_a
eps_P_BB = eps_mecaBB_t; // init: là on est dans le repère g^i
// on passe ensuite dans le repère V_a qui est donc le nouveau repère, pour ce passage
eps_P_BB.ChBase(betaP_3D);
#ifdef MISE_AU_POINT
if (Permet_affichage() > 6)
{cout << "\n eps_mecaBB_t= "; eps_mecaBB_t.Ecriture(cout);
cout << "\n eps_P_BB apres change base donc en V_a "<< eps_P_BB;
};
#endif
// on calcul la déformation cinématique dans la direction V_1
// \epsilon'_{11}(t+\Delta t) = \epsilon_{kl}(t+\Delta t) ~\gamma^k_{~.1} ~\gamma^l_{~.1}
// idem pour l'accroissement de déformation et la vitesse de déformation
eps_P_BB.Coor(1,1) = 0.; Deps_P_BB.Coor(1,1) = 0.; delta_eps_P_BB.Coor(1,1) = 0.;
for (int k=1;k<4;k++) // calcul de la matrice gamma
for (int l=1;l<4;l++)
{eps_P_BB.Coor(1,1) += (*epsBB_tdt_cin)(k,l) * gamma3D(k,1) * gamma3D(l,1);
Deps_P_BB.Coor(1,1) += (*DepsBB_cin)(k,l) * gamma3D(k,1) * gamma3D(l,1);
delta_eps_P_BB.Coor(1,1) += (*delta_epsBB_cin)(k,l) * gamma3D(k,1) * gamma3D(l,1);
};
#ifdef MISE_AU_POINT
if (Permet_affichage() > 6)
{cout << "\n eps_P_BB avec la cinematique "<< eps_P_BB;
cout << "\n Deps_P_BB avec la cinematique "<< Deps_P_BB;
cout << "\n delta_eps_P_BB avec la cinematique "<< delta_eps_P_BB << flush;
};
#endif
// on affecte les contraintes a t: en fait pour les lois incrémentales, les infos à t
// sont déjà stocké, donc cela ne sert à rien, mais pour une loi élastique par exemple ce n'est pas le cas
sig_HH_t_3D = sigHH_t;
// concernant la métrique relative au repère de travail, on utilise celle passée en paramètre
(*umat_cont_3D)= ex;
// concernant le jacobien, le jacobien du conteneur est supposé être celui 1D
sauve_jacobien1D_tdt = *(ex.jacobien_tdt);
// --- pour les contraintes passage en 3D
// bool plusZero = true;
// --- pour la cinématique
// passage des informations spécifique à la loi le_SaveResul
lois_interne->IndiqueSaveResult(save_resul.le_SaveResul);
lois_interne->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca
lois_interne->IndiqueDef_en_cours(def_en_cours); // idem pour def en coursVhVg
// la base de traction
ViB_3D = ViB; ViH_3D = ViH;
// calcul d'élements intermédiaires
V1V1_BB = Tenseur3BB::Prod_tensoriel((*ViB_3D)(1),(*ViB_3D)(1));
#ifdef MISE_AU_POINT
if (Permet_affichage() > 7)
{ cout << "\n V1V1_BB: "<< V1V1_BB;
}
#endif
// pour (m,n) = (2,2); (3,3); (1,2), et pour (g,h) = (2,2); (3,3); et (1,2)
// on va utiliser des matrices intermédiaires tels que:
// in = 1 pour (2,2) , 2 pour (3,3) et 3 pour (1,2)
for (int gh=1;gh<4;gh++)
{//if (gh <3)
{VhVg_BB(gh) = Tenseur3BB::Prod_tensoriel((*ViB_3D)(jnd(gh)),(*ViB_3D)(ind(gh)));}
// else // donne des tenseurs non symétriques pour (1,2) -> on symétrise
// {VhVg_BB(gh) = 0.5* Tenseur3BB::Prod_tensoriel((*ViB_3D)(ind(gh)),(*ViB_3D)(jnd(gh)))
// + 0.5* Tenseur3BB::Prod_tensoriel((*ViB_3D)(jnd(gh)),(*ViB_3D)(ind(gh)));
// }
#ifdef MISE_AU_POINT
if (Permet_affichage() > 7)
{ cout << "\n VhVg_BB("<<gh<<")= "<< VhVg_BB(gh);
}
#endif
};
// on sauvegarde les dimensions transverse, car elles vont être modifiées et si on doit
// repartir au départ, ce ne sera plus possible sans cette sauvegarde
double sauve_hsurh0=save_resul.hsurh0;
double sauve_bsurb0=save_resul.bsurb0;
// on initialise les jacobiens à 0 et t
jacobien_0_3D = jacobien_0; // à t=0 -> save_resul.hsurh0 * save_resul.bsurb0 == 1;
jacobien_t_3D = (*ex.jacobien_t) * save_resul.h_tsurh0 * save_resul.b_tsurb0;
// choix entre calcul avec une boucle locale de Newton on non.
// Dans le premier cas il nous faut la version d_sig/d_eps
// au lieu de d_sig/d_ddl
bool mauvaise_convergence = false; // init
bool newtonlocal = false;
switch (type_de_contrainte)
{case NEWTON_LOCAL: // cas de la version d_sig/d_eps
{ newtonlocal=true; // pour la gestion du cas par défaut
// initialisation du tenseur final de contrainte
sig_HH_3D = sigHH_tdt; // c-a-d de la solution: peut-être pas nécessaire ***
// passage des informations liées à la déformation de 1 vers 3, et variation de volume
Tableau <TenseurBB *>* toto = NULL; // pour dire que ce n'est pas attribué
// on appel la procédure de résolution de sig33(..)=0
if ((sortie_post)&&(save_resul.indicateurs_resolution.Taille()!= 2)) // dimensionnement éventuelle de la sortie d'indicateurs
save_resul.indicateurs_resolution.Change_taille(2);
// ----- pour ce faire on appelle une méthode de recherche de zero
// on initialise les inconnues à 0. On pourrait partir des def_P sauvegardés
// mais si on change d'orientation dans la pratique la convergence est moins bonne ??
val_initiale_3D.Zero(); // = save_resul.def_P_t;
// val_initiale_3D = save_resul.def_P_t;
// on impose que les grandeurs soient dans les limites admises
double& hsurh0 = save_resul.h_tsurh0;double& bsurb0 = save_resul.b_tsurb0; // init
// la méthode va mettre à jour les variations bsurb0 et hsurh0 et le jacobien
if (Calcul_et_Limitation2_h_b(hsurh0,eps_P_BB,bsurb0,jacobien_tdt_3D,jacobien_0_3D))
{if (Permet_affichage() > 3)
cout << "\n pb limitation val initiales: LoiContraintesPlanesDouble::Calcul_dsigma_deps(... "
<< flush;
};
//// ---- debut
// // on vérifie que les anciennes transversales ne sont pas négatives
// if ((val_initiale(1) < 0.) || (val_initiale(2) < 0.) )
// { cout << "\n debug LoiContraintesPlanesDouble::Calcul_DsigmaHH_tdt : "
// << " initialement "
// << "\n save_resul.b_tsurb0 = " << save_resul.b_tsurb0
// << ", save_resul.h_tsurh0 " << save_resul.h_tsurh0 << endl;
// Sortie(1);
// };
////------ fin debug
residu_3D.Zero(); // init du résultat à 0., mais c'est une grandeur de sortie donc cela ne sert à rien
derResidu_3D.Initialise(0.); // init de la matrice dérivée à 0.
try // on met le bloc sous surveillance
{
// résolution de l'équation constitutive d'avancement discrétisée en euler implicite
int nb_incr_total,nb_iter_total; // variables intermédiaires d'indicateurs
// dans le cas où on utilise une précision qui est pilotée
{ // opération de transmission de la métrique: encapsulé ici
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;
if (fct_tolerance_residu != 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 = fct_tolerance_residu->Li_enu_etendu_scalaire();
List_io <TypeQuelconque >& li_quelc = fct_tolerance_residu->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 = fct_tolerance_residu->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 de pilotage de la precision "
<< " doit calculer un scalaire or le tableau de retour est de taille "
<< tab_val.Taille() << " ce n'est pas normal !\n";
cout << " LoiContraintesPlanesDouble::Calcul_dsigma_deps\n";
Sortie(1);
};
#endif
// on récupère le premier élément du tableau uniquement
double tol = tab_val(1);
#ifdef MISE_AU_POINT
if (Permet_affichage() > 5)
cout << "\n Newton_prec: tol_= "<< tol;
#endif
alg_zero.Modif_prec_res_abs(tol);
};
if (fct_tolerance_residu_rel != 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 = fct_tolerance_residu_rel->Li_enu_etendu_scalaire();
List_io <TypeQuelconque >& li_quelc = fct_tolerance_residu_rel->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 = fct_tolerance_residu_rel->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 de pilotage de la precision relative "
<< " doit calculer un scalaire or le tableau de retour est de taille "
<< tab_val.Taille() << " ce n'est pas normal !\n";
cout << " LoiContraintesPlanesDouble::Calcul_dsigma_deps\n";
Sortie(1);
};
#endif
// on récupère le premier élément du tableau uniquement
double tol_rel = tab_val(1);
#ifdef MISE_AU_POINT
if (Permet_affichage() > 5)
cout << ", tol_relative= "<< tol_rel;
#endif
alg_zero.Modif_prec_res_rel(tol_rel);
};
};
bool conver=alg_zero.Newton_raphson
(*this,&LoiContraintesPlanesDouble::Residu_constitutif_3D
,&LoiContraintesPlanesDouble::Mat_tangente_constitutif_3D
,val_initiale_3D,racine_3D,derResidu_3D,nb_incr_total,nb_iter_total
,maxi_delta_var_eps_sur_iter_pour_Newton);
if(sortie_post) // sauvegarde éventuelle des indicateurs
{save_resul.indicateurs_resolution(1)+=nb_incr_total;
save_resul.indicateurs_resolution(2)+=nb_iter_total;
};
// on vérifie qu'il n'y a pas de pb de convergence
double absracinemax=racine_3D.Max_val_abs();
if ((!conver) || (!isfinite(absracinemax)) || (isnan(absracinemax)) )
{ if (Permet_affichage() > 0)
{ cout << "\n**>> non convergence sur l'algo de la resolution de (sigma.V_2=0, sigma.V_3=0),\n";
if (ptintmeca_en_cours != NULL) ptintmeca_en_cours->Signature();
cout << ", nb_incr_total=" << nb_incr_total
<< ", nb_iter_total=" << nb_iter_total<<", val obtenues:"
<< "\n eps_P(2,2)= " << racine_3D(1) << ", "
<< " eps_P(3,3)= " << racine_3D(2) << ", "<< " eps_P(1,2)= " << racine_3D(3)
<< "\n precedentes: "<<eps_mecaBB_t(2,2)<<", "<<eps_mecaBB_t(3,3)<<", "<<eps_mecaBB_t(1,2);
cout << "\n dernier_residu: "<< residu_3D(1) <<", "<<residu_3D(2) <<", "<<residu_3D(3)
<< "\n LoiContraintesPlanesDouble::Calcul_dsigma_deps (...";
};
// on garde en mémoire
mauvaise_convergence=true;
};
}
catch (ErrNonConvergence_Newton erreur)
{
if (Permet_affichage() > 0)
{ cout << "\n erreur de non convergence avec l'algo de la resolution de"
<< " (sig'22, sig'33, sig'12)=(0,0,0) "
<< " on obtient une valeur infinie ou NaN "
<< "\n dernier_residu: "<< residu_3D(1) <<", "<<residu_3D(2) <<", "<<residu_3D(3)
<< "\n LoiContraintesPlanesDouble::Calcul_dsigma_deps (...";
};
// on garde en mémoire
mauvaise_convergence=true;
}
catch (ErrSortieFinale)
// cas d'une direction voulue vers la sortie
// on relance l'interuption pour le niveau supérieur
{ ErrSortieFinale toto;
throw (toto);
}
catch ( ... )
{ // dans le cas d'une erreur inconnue, on génère également une exception
if (Permet_affichage() > 0)
{ cout << "\n erreur non identifiee sur l'algo de la resolution de "
<< " (sig'22, sig'33, sig'12)=(0,0,0) "
<< "\n dernier_residu: "<< residu_3D(1) <<", "<<residu_3D(2) <<", "<<residu_3D(3)
<< "\n LoiContraintesPlanesDouble::Calcul_dsigma_deps (...";
};
// on garde en mémoire
mauvaise_convergence=true;
};
if (!mauvaise_convergence)
{ // arrivée ici, cela veut dire que tout à bien fonctionné
save_resul.def_P = racine_3D; // récup de la solution dans le repère V_a
// on doit sauvegarder les def méca dans le repère g^i, ce sont directement
// les dernières composantes utilisées pour l'appel de la loi 3D
eps_mecaBB = eps_BB_3D; // dans g^i
eps_P_mecaBB = eps_P_BB; // dans V_a pour le post traitement
// on met à jour les modules
module_compressibilite= module_compressibilite_3D;
module_cisaillement= module_cisaillement_3D;
// retour du tenseurs résultat
sigHH_tdt = sig_HH_3D;
// calcul de l'opérateur tangent final: ici en 3D
// d sigma^{ij} / d epsilon_{kl}
Calcul2_dsigma_deps(d_sigma_deps);
#ifdef MISE_AU_POINT
if (Permet_affichage() > 6)
{ cout << "\nLoiContraintesPlanesDouble::Calcul_dsigma_deps: bonne convergence de Newton ";
TenseurHH* ptHH = NevezTenseurHH(sig_HH_3D);
sig_HH_3D.BaseAbsolue(*ptHH,giB_tdt_3D);
cout << "\n sigma apres CP2: ";
ptHH->Ecriture(cout);
delete ptHH;
};
if (Permet_affichage() > 5)
{ cout << "\n def_P(2,2) " << save_resul.def_P(1)
<< " def_P(3,3) " << save_resul.def_P(2)
<< " def_P(1,2) " << save_resul.def_P(3)
<< "\n en g^i: eps_mecaBB.Coor(2,2) " << eps_mecaBB.Coor(2,2)
<< " eps_mecaBB.Coor(3,3) " << eps_mecaBB.Coor(3,3)
<< " eps_mecaBB.Coor(1,2) " << eps_mecaBB.Coor(1,2)
<< "\n en V_a: eps_P_mecaBB.Coor(2,2) " << eps_P_mecaBB.Coor(2,2)
<< " eps_P_mecaBB.Coor(3,3) " << eps_P_mecaBB.Coor(3,3)
<< " eps_P_mecaBB.Coor(1,2) " << eps_P_mecaBB.Coor(1,2)
<< "\n module_compressibilite= " << module_compressibilite
<< " module_cisaillement= " << module_cisaillement;
// on affiche les épaisseur et largeur
double& hsurh0 = save_resul.hsurh0;double& bsurb0 = save_resul.bsurb0;
cout << "\n hsurh0= "<< hsurh0 << " bsurb0= " << bsurb0 << flush;
};
if (Permet_affichage() > 8)
{ cout << "\n dans le repere locale d_sigma_deps_3D= \n";
int e=1;
for (int i=1;i<4;i++) for (int j=1;j<4;j++) for (int k=1;k<4;k++)for (int l=1;l<4;l++,e++)
{ cout << "("<<i<<","<<j<<","<<k<<","<<l<<")= "<<d_sigma_deps_3D(i,j,k,l) << " ; ";
if (e>6) {cout << "\n"; e=1;}
};
Tenseur3HHHH inter_HHHH;
d_sigma_deps_3D.ChangeBase(inter_HHHH,giB_tdt_3D);
cout << "\n dans le repere orthonormee d_sigma_deps_3D= \n";
e=1;
for (int i=1;i<4;i++) for (int j=1;j<4;j++) for (int k=1;k<4;k++)for (int l=1;l<4;l++,e++)
{ cout << "("<<i<<","<<j<<","<<k<<","<<l<<")= "<<inter_HHHH(i,j,k,l) << " ; ";
if (e>6) {cout << "\n"; e=1;}
};
};
#endif
break;
};
// sinon on ne fait pas de break, donc on continue avec la méthode de perturbation
};
default: // cas de la version avec perturbation, on encore du cas où la méthode de Newton n'a pas convergé
{
// initialisation du tenseurs contrainte
sig_HH_3D.Inita(0.);
// dans le cas ou on est passé par la méthode de newton et que cela n'a pas
// convergé, on doit réinitialiser les variables de départ
if ((newtonlocal) && (Permet_affichage() > 3))
cout << "\n calcul direct sans Newton ";
save_resul.hsurh0 = sauve_hsurh0;
save_resul.bsurb0 = sauve_bsurb0;
// appel du calcul en perturbation
Cal_avec_perturbation2();
// on met à jour les modules
module_compressibilite= module_compressibilite_3D;
module_cisaillement= module_cisaillement_3D;
if (mauvaise_convergence)
{if (Permet_affichage() > 0)
{ cout << ": valeur final de h/h_0(t+dt)= " << save_resul.hsurh0
<< " et de b/b_0(t+dt)= " << save_resul.bsurb0;
};
// on annulle les dérivées des épaisseurs
save_resul.d_hsurh0.Zero();save_resul.d_bsurb0.Zero();
};
}
break;
};
// sig_HH_3D.Ecriture(cout);
(*save_resul.l_sigoHH) = sig_HH_3D; // sauvegarde en locale
// ---calcul des invariants de déformation et de vitesse de déformation
Calcul_invariants_et_def_cumul();
energ = save_resul.l_energ; // récup des énergies
// --- on remet à jour éventuellement l'épaisseur
// dans le cas d'une contrainte par perturbation
// if ((type_de_contrainte == PERTURBATION )||mauvaise_convergence)
if (type_de_contrainte == PERTURBATION )
// calcul de la déformation d'épaisseur correspondant à la condition de contraintes planes
{ //Tenseur1BH sigBH = gijBB_tdt * sigHH_tdt;
Tenseur3BH sigBH = gijBB_tdt_3D * sig_HH_3D;
Tenseur3BH sigBH_t = gijBB_t_3D * sig_HH_t_3D;
Calcul_eps_trans_parVarVolume2(sigBH_t,jacobien_0,module_compressibilite,jacobien,sigBH,*(ex.jacobien_t));
if ((Permet_affichage() > 0) && mauvaise_convergence)
{ cout << "\n valeur final de h/h_0(t+dt)= " << save_resul.hsurh0
<< " et de b/b_0(t+dt)= " << save_resul.bsurb0;
};
};
LibereTenseur();
LibereTenseurQ();
};
// fonction interne utilisée par les classes dérivées de Loi_comp_abstraite
// pour répercuter les modifications de la température
// ici utiliser pour modifier la température des lois élémentaires
// l'Enum_dure: indique quel est la température courante : 0 t ou tdt
void LoiContraintesPlanesDouble::RepercuteChangeTemperature(Enum_dure temps)
{ lois_interne->temperature_0 = this->temperature_0;
lois_interne->temperature_t = this->temperature_t;
lois_interne->temperature_tdt = this->temperature_tdt;
lois_interne->dilatation=dilatation;
// on répercute également les déformations thermiques, qui ne sont utilisées
// telles quelles que pour certaines lois: ex: loi hyper-élastique
if (dilatation)
{// a- dimensionnement des tenseurs intermédiaires
int dim_tens = epsBB_therm->Dimension();
// -- cas de la déformation
if (lois_interne->epsBB_therm == NULL) { lois_interne->epsBB_therm = NevezTenseurBB(dim_tens);}
else if (lois_interne->epsBB_therm->Dimension() != dim_tens)
{ delete lois_interne->epsBB_therm;lois_interne->epsBB_therm = NevezTenseurBB(dim_tens);};
// -- cas de la vitesse de déformation
if (lois_interne->DepsBB_therm == NULL) { lois_interne->DepsBB_therm = NevezTenseurBB(dim_tens);}
else if (lois_interne->DepsBB_therm->Dimension() != dim_tens)
{ delete lois_interne->DepsBB_therm;lois_interne->DepsBB_totale = NevezTenseurBB(dim_tens);};
// b- affectation des tenseurs
(*lois_interne->epsBB_therm)=(*epsBB_therm);
(*lois_interne->DepsBB_therm)=(*DepsBB_therm);
};
// puis en interne
lois_interne->RepercuteChangeTemperature(temps);
switch (temps)
{ case TEMPS_0:
{lois_interne->temperature = &lois_interne->temperature_0;
break;
}
case TEMPS_t:
{lois_interne->temperature = &lois_interne->temperature_t;
break;
}
case TEMPS_tdt:
{lois_interne->temperature = &lois_interne->temperature_tdt;
break;
}
default:
{ cout << "\n erreur, cas de temps non prevu !! "
<< "\n LoiContraintesPlanesDouble::RepercuteChangeTemperature(...";
Sortie(1);
};
};
};
void LoiContraintesPlanesDouble::CalculGrandeurTravail
(const PtIntegMecaInterne& ptintmec
,const Deformation & def,Enum_dure temps,const ThermoDonnee& dTP
,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_etendu>* exclure_dd_etend
,const List_io<const TypeQuelconque *>* exclure_Q
)
{ // récup des infos spécifiques
SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul);
// recup de l'incrément de temps
double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant();
double unSurDeltat=0;
if (Abs(deltat) >= ConstMath::trespetit)
{unSurDeltat = 1./deltat;}
else
// si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand
{ // non un pas de temps doit être positif !! or certaine fois il peut y avoir des pb
if (unSurDeltat < 0)
{ cout << "\n le pas de temps est négatif !! "; };
unSurDeltat = ConstMath::tresgrand;
};
// par défaut on active les invariants et on intègre les infos def en 3D
if (!calcul_en_3D_via_direction_quelconque)
{ //dans le cas classique, on dispose de la variation d'épaisseur et de largeur pour déterminer les def
// ptintmec concerne des tenseurs d'ordres 1 donc il faut transformer en 3D
bool plusZero=true; // on ajoute des 0 pour les grandeurs manquantes dans une première étape
// on commence par transférer le tout
ptintmeca.Affectation_1D_a_3D(ptintmec,plusZero);
// ensuite on traite les points particuliers
// pour tout ce qui est contrainte: l'ajout de 0 est ok
// pour les déformations on met à jour en fonction des grandeurs sauvegardées
double eps33=0.; double eps33_t=0.; //init par défaut
double eps22=0.; double eps22_t=0.; //init par défaut
// -- maintenant on tient compte de l'élongation d'épaisseur
switch (type_de_deformation)
{case DEFORMATION_STANDART : case DEFORMATION_POUTRE_PLAQUE_STANDART :
// cas d'une déformation d'Almansi
{ // dans le repère local: epsBB33 = 1/2 * (h^2 - 1.), or h0=1. donc : epsBB33 = 1/2 * ((h/h0)^2 - 1.)
eps33 = 0.5 * (save_resul.hsurh0 * save_resul.hsurh0 - 1.);
eps33_t = 0.5 * (save_resul.h_tsurh0 * save_resul.h_tsurh0 - 1.);
eps22 = 0.5 * (save_resul.bsurb0 * save_resul.bsurb0 - 1.);
eps22_t = 0.5 * (save_resul.b_tsurb0 * save_resul.b_tsurb0 - 1.);
};
break;
case DEFORMATION_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEFORMATION_CUMU_LOGARITHMIQUE :
// cas d'une def logarithmique ou une approximation
{ eps33 = log(save_resul.hsurh0);
eps33_t = log(save_resul.h_tsurh0);
eps22 = log(save_resul.bsurb0);
eps22_t = log(save_resul.b_tsurb0);
};
break;
default :
cout << "\nErreur : type de deformation qui n'est pas actuellement pris en compte, type= "
<< Nom_type_deformation(type_de_deformation);
cout << "\n LoiContraintesPlanesDouble::CalculGrandeurTravail \n";
Sortie(1);
};
(*ptintmeca.EpsBB()).Coor(3,3) = eps33;
(*ptintmeca.DeltaEpsBB()).Coor(3,3) = eps33 - eps33_t;
(*ptintmeca.EpsBB()).Coor(2,2) = eps22;
(*ptintmeca.DeltaEpsBB()).Coor(2,2) = eps22 - eps22_t;
(*ptintmeca.DepsBB()).Coor(3,3) = (eps33 - eps33_t) * unSurDeltat;
(*ptintmeca.DepsBB()).Coor(2,2) = (eps22 - eps22_t) * unSurDeltat;
}
else
// dans le cas où on travaille dans le repère gi en 3D on dispose directement des infos de déformation
{//récup de eps_mecaBB
Tenseur3BB& eps_mecaBB_t = *((Tenseur3BB*) (save_resul.eps_mecaBB_t));
Tenseur3BB& eps_mecaBB = *((Tenseur3BB*) (save_resul.eps_mecaBB));
// on sauve ce qu'il y a dans la direction 11 pour éviter les erreurs d'arrondis
double eps11= (*ptintmeca.EpsBB())(1,1);
double Deps11= (*ptintmeca.DepsBB())(1,1);
double delta_eps11= (*ptintmeca.DeltaEpsBB())(1,1);
// les manips entre tenseurs
(*ptintmeca.EpsBB()) = eps_mecaBB;
(*ptintmeca.DeltaEpsBB()) = eps_mecaBB - eps_mecaBB_t;
(*ptintmeca.DepsBB()) = (*ptintmeca.DeltaEpsBB()) * unSurDeltat;
// récup des valeurs sauvegardées (normalement ne devrait pas changer...)
(*ptintmeca.EpsBB()).Coor(1,1) = eps11;
(*ptintmeca.DeltaEpsBB()).Coor(1,1) = delta_eps11;
(*ptintmeca.DepsBB()).Coor(1,1) = Deps11;
};
// on met à jour les invariants 3D, on récupère ce qui a été sauvegardé
if (ptintmeca.Statut_Invariants_deformation()) // le conteneur des invariants a pu être effacé par Affectation_1D_a_3D
ptintmeca.EpsInvar() = save_resul.epsInvar;
if (ptintmeca.Statut_Invariants_vitesseDeformation()) // le conteneur des invariants a pu être effacé par Affectation_1D_a_3D
ptintmeca.DepsInvar() = save_resul.depsInvar;
// idem au niveau des déformations cumulées
ptintmeca.Deformation_equi() = save_resul.def_equi;
ptintmeca.Deformation_equi_t() = save_resul.def_equi_t;
// passage des informations spécifique à la loi le_SaveResul
lois_interne->IndiqueSaveResult(save_resul.le_SaveResul);
lois_interne->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca
lois_interne->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours
lois_interne->CalculGrandeurTravail(ptintmeca,def,temps,dTP
,ex_impli,ex_expli_tdt,ex_umat,exclure_dd_etend,exclure_Q); // passage à la loi 3D
};
// passage des grandeurs métriques de l'ordre 1 à 3, cas implicite
void LoiContraintesPlanesDouble::Passage_metrique_ordre1_vers_3(const Met_abstraite::Impli& ex)
{// on s'occupe du redimensionnement éventuel
// on affecte et/ou on redimensionne éventuellement les tableaux fonction du nombre de ddl pour le passage 3D
// la partie dépendant des vitesses: entre accolades pour pouvoir fermer
{if (ex.gradVmoyBB_t != NULL) {impli_3D->gradVmoyBB_t= gradVmoyBB_t_3D_P = &gradVmoyBB_t_3D;};
if (ex.gradVmoyBB_tdt != NULL) {impli_3D->gradVmoyBB_tdt=gradVmoyBB_tdt_3D_P = &gradVmoyBB_tdt_3D;};
if (ex.gradVBB_tdt != NULL) {impli_3D->gradVBB_tdt=gradVBB_tdt_3D_P = &gradVBB_tdt_3D;};
// on s'occupe tout d'abord des tableaux de vitesses qui peuvent ne pas exister
if (ex.d_gradVmoyBB_t != NULL) // cas où il existe
{ int tail=ex.d_gradVmoyBB_t->Taille();
if (d_gradVmoyBB_t_3D_P == NULL) {d_gradVmoyBB_t_3D_P = new Tableau<TenseurBB *> (tail);
impli_3D->d_gradVmoyBB_t = d_gradVmoyBB_t_3D_P;}
else {d_gradVmoyBB_t_3D_P->Change_taille(tail);};
d_gradVmoyBB_t_3D.Change_taille(tail);
for (int i=1;i<= tail;i++)
(*d_gradVmoyBB_t_3D_P)(i) = &(d_gradVmoyBB_t_3D(i));
};
if (ex.d_gradVmoyBB_tdt != NULL) // cas où il existe
{ int tail=ex.d_gradVmoyBB_tdt->Taille();
if (d_gradVmoyBB_tdt_3D_P == NULL) {d_gradVmoyBB_tdt_3D_P = new Tableau<TenseurBB *> (tail);
impli_3D->d_gradVmoyBB_tdt = d_gradVmoyBB_tdt_3D_P;}
else {d_gradVmoyBB_tdt_3D_P->Change_taille(tail);};
d_gradVmoyBB_tdt_3D.Change_taille(tail);
for (int i=1;i<= tail;i++)
(*d_gradVmoyBB_tdt_3D_P)(i) = &(d_gradVmoyBB_tdt_3D(i));
};
if (ex.d_gradVBB_t != NULL) // cas où il existe
{ int tail=ex.d_gradVBB_t->Taille();
if (d_gradVBB_t_3D_P == NULL) {d_gradVBB_t_3D_P = new Tableau<TenseurBB *> (tail);
impli_3D->d_gradVBB_t = d_gradVBB_t_3D_P;}
else {d_gradVBB_t_3D_P->Change_taille(tail);};
d_gradVBB_t_3D.Change_taille(tail);
for (int i=1;i<= tail;i++)
(*d_gradVBB_t_3D_P)(i) = &(d_gradVBB_t_3D(i));
};
if (ex.d_gradVBB_tdt != NULL) // cas où il existe
{ int tail=ex.d_gradVBB_tdt->Taille();
if (d_gradVBB_tdt_3D_P == NULL) {d_gradVBB_tdt_3D_P = new Tableau<TenseurBB *> (tail);
impli_3D->d_gradVBB_tdt = d_gradVBB_tdt_3D_P;}
else {d_gradVBB_tdt_3D_P->Change_taille(tail);};
d_gradVBB_tdt_3D.Change_taille(tail);
for (int i=1;i<= tail;i++)
(*d_gradVBB_tdt_3D_P)(i) = &(d_gradVBB_tdt_3D(i));
};
}; // fin de la partie dédiée à la vitesse
// maintenant on s'occupe uniquement du redimensionnement des tableaux restants
// -- on s'occupe des tableaux nécessaire à la métrique
int ta_ex_d_giB_tdt = ex.d_giB_tdt->Taille(); // la dimension
if (d_giB_tdt_3D.Taille() != ta_ex_d_giB_tdt)
{ d_giB_tdt_3D.Change_taille(ta_ex_d_giB_tdt);};
int ta_ex_d_giH_tdt = ex.d_giH_tdt->Taille(); // la dimension
if (d_giH_tdt_3D.Taille() != ta_ex_d_giH_tdt)
{ d_giH_tdt_3D.Change_taille(ta_ex_d_giH_tdt);};
int ta_ex_d_gijBB_tdt = ex.d_gijBB_tdt->Taille(); // la dimension
if (d_gijBB_tdt_3D.Taille() != ta_ex_d_gijBB_tdt)
{ d_gijBB_tdt_3D.Change_taille(ta_ex_d_gijBB_tdt); d_gijBB_tdt_3D_P.Change_taille(ta_ex_d_gijBB_tdt);
for (int i=1;i<=ta_ex_d_gijBB_tdt;i++) {d_gijBB_tdt_3D_P(i) = &(d_gijBB_tdt_3D(i));};
};
int ta_ex_d_gijHH_tdt = ex.d_gijHH_tdt->Taille();
if (d_gijHH_tdt_3D.Taille() != ta_ex_d_gijHH_tdt)
{ d_gijHH_tdt_3D.Change_taille(ta_ex_d_gijHH_tdt); d_gijHH_tdt_3D_P.Change_taille(ta_ex_d_gijHH_tdt);
for (int i=1;i<=ta_ex_d_gijHH_tdt;i++) {d_gijHH_tdt_3D_P(i) = &(d_gijHH_tdt_3D(i));};
};
if( d_jacobien_tdt_3D.Taille() != ex.d_jacobien_tdt->Taille())
{d_jacobien_tdt_3D.Change_taille(ex.d_jacobien_tdt->Taille());}
// le tableau à double dimension
if (ex.d2_gijBB_tdt != NULL)
{ int taille1=ex.d2_gijBB_tdt->Taille1(); int taille2=ex.d2_gijBB_tdt->Taille2();
if (d2_gijBB_tdt_3D_P == NULL)
{ d2_gijBB_tdt_3D_P = impli_3D->d2_gijBB_tdt = new Tableau2<TenseurBB *> (taille1,taille2);
d2_gijBB_tdt_3D.Change_taille(taille1,taille2);
for (int i=1;i<=taille1;i++) for (int j=1;j<= taille2;j++)
{ (*d2_gijBB_tdt_3D_P)(i,j) = &d2_gijBB_tdt_3D(i,j);};
}
else if ((taille1 != d2_gijBB_tdt_3D.Taille1()) || (taille2 != d2_gijBB_tdt_3D.Taille2()))
{ d2_gijBB_tdt_3D_P->Change_taille(taille1,taille2);
d2_gijBB_tdt_3D.Change_taille(taille1,taille2);
for (int i=1;i<=taille1;i++) for (int j=1;j<= taille2;j++)
{ (*d2_gijBB_tdt_3D_P)(i,j) = &d2_gijBB_tdt_3D(i,j);};
};
};
// récup du conteneur spécifique
SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul);
// si les grandeurs à 0 ont déjà été calculées, on les sauvegarde d'abord car elles vont
// être écrasées
// on commence par recopier les grandeurs de l'ordre 1 à 3
bool plusZero = true; // on complète avec des 0 dans un premier temps
int type_recopie = 0; // init: on recopie les grandeurs de 0,t et tdt
if ( save_resul.meti_ref_00.giB_ != NULL)
type_recopie = 1; // = 1 -> on transfert les grandeurs à t et tdt
impli_3D->Passage_de_Ordre1_vers_Ordre3(ex,plusZero,type_recopie);
#ifdef MISE_AU_POINT
if (Permet_affichage() > 8)
{ cout << "\n LoiContraintesPlanesDouble::Passage_metrique_ordre1_vers_3("
<< "\n 1) base giB_tdt_3D(1) "<< giB_tdt_3D(1)
<< "\n base giB_tdt_3D(2) "<< giB_tdt_3D(2)
<< "\n base giB_tdt_3D(2) "<< giB_tdt_3D(3) << flush;
};
#endif
// maintenant on s'occupe de mettre à jour les grandeurs manquantes
// - les bases naturelles: les vecteurs normaux dans les directions 2 et 3 sont normées
// et sont identiques pour les bases naturelles et duales
// Dans le cas d'un comportement isotrope, on choisit un repère par défaut
// si les repères associés ne sont pas définis on les définit
if ( save_resul.meti_ref_00.giB_ == NULL)
{ Deformation::Stmet inter(3,3); // création d'un conteneur bien dimensionné
save_resul.meti_ref_00 = save_resul.meti_ref_t = save_resul.meti_ref_tdt = inter;
// on s'occupe de la création du premier repère
CoordonneeB & giB0_1 = (*(save_resul.meti_ref_00.giB_)).CoordoB(1); // pour simplifier
giB0_1 = giB_0_3D(1); // on récupère la direction du premier vecteur
giB0_1.Normer(); // on le norme
// on crée 2 vecteurs normés, perpendiculaires à ce premier vecteur
CoordonneeB & giB0_2 = (*(save_resul.meti_ref_00.giB_)).CoordoB(2); // pour simplifier
CoordonneeB & giB0_3 = (*(save_resul.meti_ref_00.giB_)).CoordoB(3); // pour simplifier
// deux cas suivant que l'on dispose d'une orientation supplémentaire ou non
if (ex.giB_0->NbVecteur() > 1)
{ // a priori le second vecteur de la base est un vecteur d'un plan de ref
giB0_3 = (Util::ProdVec_coorB(giB_0_3D(1), (*(ex.giB_0))(2))).Normer();
giB0_2 = Util::ProdVec_coorB(giB0_3,giB0_1);
}
else
{ // cas où on n'a pas d'indication sup: -> on definit des vecteurs a priori
MathUtil2::Def_vecteurs_plan(giB0_1,giB0_2,giB0_3);
};
////--- debug
// cout << "\n debug LoiContraintesPlanesDouble::Passage_metrique_ordre1_vers_3(";
// cout << "\n giB0_1: "; giB0_1.Affiche();
// cout << "\n giB0_2: "; giB0_2.Affiche();
// cout << "\n giB0_3: "; giB0_3.Affiche();
//// --- fin debug
giB_0_3D.CoordoB(2)=giB0_2;giB_0_3D.CoordoB(3)=giB0_3;
giH_0_3D.CoordoH(2) = giB_0_3D(2).Bas_haut();
giH_0_3D.CoordoH(3) = giB_0_3D(3).Bas_haut();
};
////--- debug
// cout << "\n debug LoiContraintesPlanesDouble::Passage_metrique_ordre1_vers_3(";
// cout << "\n giH_0(2): "; giH_0_3D(2).Affiche();
// cout << "\n giH_0(3): "; giH_0_3D(3).Affiche();
//// --- fin debug
// on met à jour les deux autres directions
// *** pour l'instant on fait la même chose que pour t= 0, pour les deux autres temps
// *** , mais il faudra surement améliorer
CoordonneeB & giBt_1 = (*(save_resul.meti_ref_t.giB_)).CoordoB(1); // pour simplifier
giBt_1 = giB_t_3D(1); // on récupère la direction du premier vecteur
giBt_1.Normer(); // on le norme
// on crée 2 vecteurs normés, perpendiculaires à ce premier vecteur
CoordonneeB & giBt_2 = (*(save_resul.meti_ref_t.giB_)).CoordoB(2); // pour simplifier
CoordonneeB & giBt_3 = (*(save_resul.meti_ref_t.giB_)).CoordoB(3); // pour simplifier
// deux cas suivant que l'on dispose d'une orientation supplémentaire ou non
if (ex.giB_t->NbVecteur() > 1)
{ // a priori le second vecteur de la base est un vecteur d'un plan de ref
giBt_3 = (Util::ProdVec_coorB(giB_t_3D(1), (*(ex.giB_t))(2))).Normer();
giBt_2 = Util::ProdVec_coorB(giBt_3,giBt_1);
}
else
{ // cas où on n'a pas d'indication sup: -> on definit des vecteurs a priori
MathUtil2::Def_vecteurs_plan(giBt_1,giBt_2,giBt_3);
};
giB_t_3D.CoordoB(2)=giBt_2;giB_t_3D.CoordoB(3)=giBt_3;
giH_t_3D.CoordoH(2) = giB_t_3D(2).Bas_haut();
giH_t_3D.CoordoH(3) = giB_t_3D(3).Bas_haut();
#ifdef MISE_AU_POINT
if (Permet_affichage() > 8)
{ cout << "\n 2) base giB_tdt_3D(1) "<< giB_tdt_3D(1)
<< "\n base giB_tdt_3D(2) "<< giB_tdt_3D(2)
<< "\n base giB_tdt_3D(2) "<< giB_tdt_3D(3) << flush;
};
#endif
CoordonneeB & giBtdt_1 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(1); // pour simplifier
giBtdt_1 = giB_tdt_3D(1); // on récupère la direction du premier vecteur
giBtdt_1.Normer(); // on le norme
// on crée 2 vecteurs normés, perpendiculaires à ce premier vecteur
CoordonneeB & giBtdt_2 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(2); // pour simplifier
CoordonneeB & giBtdt_3 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(3); // pour simplifier
// deux cas suivant que l'on dispose d'une orientation supplémentaire ou non
if (ex.giB_tdt->NbVecteur() > 1)
{ // a priori le second vecteur de la base est un vecteur d'un plan de ref
giBtdt_3 = (Util::ProdVec_coorB(giB_tdt_3D(1), (*(ex.giB_tdt))(2))).Normer();
giBtdt_2 = Util::ProdVec_coorB(giBtdt_3,giBtdt_1);
}
else
{ // cas où on n'a pas d'indication sup: -> on definit des vecteurs a priori
MathUtil2::Def_vecteurs_plan(giBtdt_1,giBtdt_2,giBtdt_3);
};
giB_tdt_3D.CoordoB(2)=giBtdt_2;giB_tdt_3D.CoordoB(3)=giBtdt_3;
giH_tdt_3D.CoordoH(2) = giB_tdt_3D(2).Bas_haut();
giH_tdt_3D.CoordoH(3) = giB_tdt_3D(3).Bas_haut();
#ifdef MISE_AU_POINT
if (Permet_affichage() > 8)
{ cout << "\n 3) base giB_tdt_3D(1) "<< giB_tdt_3D(1)
<< "\n base giB_tdt_3D(2) "<< giB_tdt_3D(2)
<< "\n base giB_tdt_3D(2) "<< giB_tdt_3D(3) << flush;
};
#endif
// ici on calcul les vecteurs
// >>>> et la première partie de leurs variations, fonction du premier vecteur uniquement
// - les tenseurs métriques: a priori 1 pour les directions 2 et 3, initialement
gijBB_0_3D.Coor(2,2)=gijHH_0_3D.Coor(2,2)=gijBB_t_3D.Coor(2,2)=gijHH_t_3D.Coor(2,2)
=gijBB_tdt_3D.Coor(2,2)=gijHH_tdt_3D.Coor(2,2)=1.;
gijBB_0_3D.Coor(3,3)=gijHH_0_3D.Coor(3,3)=gijBB_t_3D.Coor(3,3)=gijHH_t_3D.Coor(3,3)
=gijBB_tdt_3D.Coor(3,3)=gijHH_tdt_3D.Coor(3,3)=1.;
// lors d'un premier appel, les variables save_resul.h_tsurh0 et save_resul.hsurh0 et idem pour l'épaisseur
// ne sont pas affectés car elles sont issues d'un premier calcul, dans ce cas on les mets arbitrairement à 1
// ensuite elles évolueront, idem pour la largeur
bool premier_passage = false;
if (save_resul.h_tsurh0 == 0.)
{ save_resul.h_tsurh0 = 1.; save_resul.hsurh0 = 1.;
save_resul.b_tsurb0 = 1.; save_resul.bsurb0 = 1.;
premier_passage = true;
};
if (save_resul.hsurh0 == 0.) // peut arriver dans le cas où on a une erreur dès le début
{ save_resul.hsurh0 = save_resul.h_tsurh0;}; // on réinitialise
if (save_resul.bsurb0 == 0.) // peut arriver dans le cas où on a une erreur dès le début
{ save_resul.bsurb0 = save_resul.b_tsurb0;}; // on réinitialise
// on calcul les vecteur 2 et 3 naturels et duals
giB_t_3D.CoordoB(2) *= save_resul.b_tsurb0; giH_t_3D.CoordoH(2) /= save_resul.b_tsurb0;
giB_tdt_3D.CoordoB(2) *= save_resul.bsurb0; giH_tdt_3D.CoordoH(2) /= save_resul.bsurb0;
giB_t_3D.CoordoB(3) *= save_resul.h_tsurh0; giH_t_3D.CoordoH(3) /= save_resul.h_tsurh0;
giB_tdt_3D.CoordoB(3) *= save_resul.hsurh0; giH_tdt_3D.CoordoH(3) /= save_resul.hsurh0;
#ifdef MISE_AU_POINT
if (Permet_affichage() > 8)
{ cout << "\n 4) base giB_tdt_3D(1) "<< giB_tdt_3D(1)
<< "\n base giB_tdt_3D(2) "<< giB_tdt_3D(2)
<< "\n base giB_tdt_3D(2) "<< giB_tdt_3D(3) << flush;
};
#endif
// - et les tenseurs métriques à t et tdt, comme les vecteurs en épaisseurs et largeurs
// sont normées initialement, seule l'intensité
// des normales est à mettre à jour compte tenue de la variation d'épaisseurs
double h_tsurh0_carre = save_resul.h_tsurh0 * save_resul.h_tsurh0;
gijBB_t_3D.Coor(3,3)=h_tsurh0_carre; gijHH_t_3D.Coor(3,3)= 1./h_tsurh0_carre;
double hsurh0_carre = save_resul.hsurh0 * save_resul.hsurh0;
gijBB_tdt_3D.Coor(3,3) = hsurh0_carre;gijHH_tdt_3D.Coor(3,3) = 1. / hsurh0_carre;
double b_tsurb0_carre = save_resul.b_tsurb0 * save_resul.b_tsurb0;
gijBB_t_3D.Coor(2,2)=b_tsurb0_carre; gijHH_t_3D.Coor(2,2)= 1./b_tsurb0_carre;
double bsurb0_carre = save_resul.bsurb0 * save_resul.bsurb0;
gijBB_tdt_3D.Coor(2,2) = bsurb0_carre;gijHH_tdt_3D.Coor(2,2) = 1. / bsurb0_carre;
// -- cas des variations
if (save_resul.d_hsurh0.Taille() != ta_ex_d_giB_tdt)
{save_resul.d_hsurh0.Change_taille(ta_ex_d_giB_tdt); // donc à 0 la première fois
save_resul.d_bsurb0.Change_taille(ta_ex_d_giB_tdt);
};
// - les variations du vecteur normal
#ifdef MISE_AU_POINT
if (ex.d_giB_tdt->Taille() != ex.d_giH_tdt->Taille())
{ cout << "\n **** sans doute une erreur: (ex.d_giB_tdt->Taille() "<< ex.d_giB_tdt->Taille()
<< " != ex.d_giH_tdt->Taille()) " << ex.d_giH_tdt->Taille()
<< "\n LoiDeformationsPlanes::Passage_metrique_ordre1_vers_3(const Met_abstraite::Impli& ex)";
Sortie(1);
};
#endif
// maintenant on s'occupe de la seconde partie des variations
// >>>> fonction du changement d'épaisseur et de largeur
if (!premier_passage)
{Vecteur& d_hsurh0 = save_resul.d_hsurh0;
Vecteur& d_bsurb0 = save_resul.d_bsurb0;
for (int iddl=1;iddl<= ta_ex_d_giB_tdt;iddl++)
{ double d_hsurh0_iddl = d_hsurh0(iddl);
// gib(3) = h/h0 * N -> d_gib(3) = d (h/h0 * N) = d_(h/h0) * N + h/h0 * d_N
// actuellement, c'est la partie d_N qui est stockée dans d_gib(3), on rajoute donc la partie restante
d_giB_tdt_3D(iddl).CoordoB(3) *= save_resul.hsurh0;
d_giB_tdt_3D(iddl).CoordoB(3) += d_hsurh0_iddl * giB_normer_3_tdt_3D_sauve; // base naturelle
// gih(3) = 1/giB(3) -> d_gih(3)(3) = - d_giB(3)(3) / (giB(3)*giB(3))
d_giH_tdt_3D(iddl).CoordoH(3) = (d_giB_tdt_3D(iddl)(3) / (-hsurh0_carre)).Bas_haut() ; // base duale
// gijBB(3)= giB(3) * giB(3) -> d_gijBB(3)= 2. * d_giB(3) * giB(3)
d_gijBB_tdt_3D(iddl).Coor(3,3) = 2. * (d_giB_tdt_3D(iddl)(3).ScalBB(giB_tdt_3D(3)));
// gijHH(3)= giH(3) * giH(3) -> d_gijHH(3)= 2. * d_giH(3) * giH(3)
d_gijHH_tdt_3D (iddl).Coor(3,3) = 2. * (d_giH_tdt_3D(iddl)(3).ScalHH(giH_tdt_3D(3)));
double d_bsurb0_iddl = d_bsurb0(iddl);
// gib(2) = b/b0 * N -> d_gib(2) = d (b/b0 * N) = d_(b/b0) * N + b/b0 * d_N
// actuellement, c'est la partie d_N qui est stockée dans d_gib(3), on rajoute donc la partie restante
d_giB_tdt_3D(iddl).CoordoB(2) *= save_resul.bsurb0;
d_giB_tdt_3D(iddl).CoordoB(2) += d_bsurb0_iddl * giB_normer_3_tdt_3D_sauve; // base naturelle
// gih(2) = 1/giB(2) -> d_gih(2)(2) = - d_giB(3)(3) / (giB(3)*giB(3))
d_giH_tdt_3D(iddl).CoordoH(2) = (d_giB_tdt_3D(iddl)(2) / (-bsurb0_carre)).Bas_haut() ; // base duale
// gijBB(2)= giB(2) * giB(2) -> d_gijBB(2)= 2. * d_giB(2) * giB(2)
d_gijBB_tdt_3D(iddl).Coor(2,2) = 2. * (d_giB_tdt_3D(iddl)(2).ScalBB(giB_tdt_3D(2)));
// gijHH(2)= giH(2) * giH(2) -> d_gijHH(2)= 2. * d_giH(2) * giH(2)
d_gijHH_tdt_3D (iddl).Coor(2,2) = 2. * (d_giH_tdt_3D(iddl)(2).ScalHH(giH_tdt_3D(2)));
};
};
};
// passage des grandeurs métriques de l'ordre 1 à 3: cas explicite
void LoiContraintesPlanesDouble::Passage_metrique_ordre1_vers_3(const Met_abstraite::Expli_t_tdt& ex)
{ // on s'occupe du redimensionnement éventuel
// on affecte et/ou on redimensionne éventuellement les tableaux fonction du nombre de ddl pour le passage 3D
// la partie dépendant des vitesses: entre accolades pour pouvoir fermer
{if (ex.gradVmoyBB_t != NULL) {expli_3D->gradVmoyBB_t= gradVmoyBB_t_3D_P = &gradVmoyBB_t_3D;};
if (ex.gradVmoyBB_tdt != NULL) {expli_3D->gradVmoyBB_tdt=gradVmoyBB_tdt_3D_P = &gradVmoyBB_tdt_3D;};
if (ex.gradVBB_tdt != NULL) {expli_3D->gradVBB_tdt=gradVBB_tdt_3D_P = &gradVBB_tdt_3D;};
}; // fin de la partie dédiée à la vitesse
// la dimension des tableaux : on considère que tous les tableaux doivent avoir la même dimension
int ta_ex_d_gijBB_tdt = ex.d_gijBB_tdt->Taille(); // la dimension
// maintenant on s'occupe uniquement du redimensionnement des tableaux restants
int ta_d_gijBB_tdt_3D = d_gijBB_tdt_3D.Taille();
if (ta_d_gijBB_tdt_3D != ta_ex_d_gijBB_tdt)
{// cela veut dire que tous les tableaux sont mal dimensionnés
// -- on s'occupe des tableaux nécessaire à la métrique
d_gijBB_tdt_3D.Change_taille(ta_ex_d_gijBB_tdt); d_gijBB_tdt_3D_P.Change_taille(ta_ex_d_gijBB_tdt);
for (int i=1;i<=ta_ex_d_gijBB_tdt;i++) {d_gijBB_tdt_3D_P(i) = &(d_gijBB_tdt_3D(i));};
};
// récup du conteneur spécifique
SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul);
// on commence par recopier les grandeurs de l'ordre 1 à 3
bool plusZero = true; // on complète avec des 0 dans un premier temps
int type_recopie = 0; // init: on recopie les grandeurs de 0,t et tdt
if ( save_resul.meti_ref_00.giB_ != NULL)
type_recopie = 1; // = 1 -> on transfert les grandeurs à t et tdt
expli_3D->Passage_de_Ordre1_vers_Ordre3(ex,plusZero,type_recopie);
// maintenant on s'occupe de mettre à jour les grandeurs manquantes
// - les bases naturelles: les vecteurs normaux dans les directions 2 et 3 sont normées
// et sont identiques pour les bases naturelles et duales
// Dans le cas d'un comportement isotrope, on choisit un repère par défaut
// si les repères associés ne sont définis on les définit
if ( save_resul.meti_ref_00.giB_ == NULL)
{ Deformation::Stmet inter(3,3); // création d'un conteneur bien dimensionné
save_resul.meti_ref_00 = save_resul.meti_ref_t = save_resul.meti_ref_tdt = inter;
// on s'occupe de la création du premier repère
CoordonneeB & giB0_1 = (*(save_resul.meti_ref_00.giB_)).CoordoB(1); // pour simplifier
giB0_1 = giB_0_3D(1); // on récupère la direction du premier vecteur
giB0_1.Normer(); // on le norme
// on crée 2 vecteurs normés, perpendiculaires à ce premier vecteur
CoordonneeB & giB0_2 = (*(save_resul.meti_ref_00.giB_)).CoordoB(2); // pour simplifier
CoordonneeB & giB0_3 = (*(save_resul.meti_ref_00.giB_)).CoordoB(3); // pour simplifier
// Def_vecteurs_plan(giB0_1,giB0_2,giB0_3);
giB_0_3D.CoordoB(2)=giB0_2;giB_0_3D.CoordoB(3)=giB0_3;
};
// on met à jour les deux autres directions
// *** pour l'instant on fait la même chose que pour t= 0, pour les deux autres temps
// *** , mais il faudra surement améliorer
CoordonneeB & giBt_1 = (*(save_resul.meti_ref_t.giB_)).CoordoB(1); // pour simplifier
giBt_1 = giB_t_3D(1); // on récupère la direction du premier vecteur
giBt_1.Normer(); // on le norme
// on crée 2 vecteurs normés, perpendiculaires à ce premier vecteur
CoordonneeB & giBt_2 = (*(save_resul.meti_ref_t.giB_)).CoordoB(2); // pour simplifier
CoordonneeB & giBt_3 = (*(save_resul.meti_ref_t.giB_)).CoordoB(3); // pour simplifier
// Def_vecteurs_plan(giBt_1,giBt_2,giBt_3);
giB_t_3D.CoordoB(2)=giBt_2;giB_t_3D.CoordoB(3)=giBt_3;
CoordonneeB & giBtdt_1 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(1); // pour simplifier
giBtdt_1 = giB_tdt_3D(1); // on récupère la direction du premier vecteur
giBtdt_1.Normer(); // on le norme
// on crée 2 vecteurs normés, perpendiculaires à ce premier vecteur
CoordonneeB & giBtdt_2 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(2); // pour simplifier
CoordonneeB & giBtdt_3 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(3); // pour simplifier
// Def_vecteurs_plan(giBtdt_1,giBtdt_2,giBtdt_3);
giB_tdt_3D.CoordoB(2)=giBtdt_2;giB_tdt_3D.CoordoB(3)=giBtdt_3;
// - les tenseurs métriques: a priori 1 pour les directions 2 et 3, initialement
gijBB_0_3D.Coor(2,2)=gijHH_0_3D.Coor(2,2)=gijBB_t_3D.Coor(2,2)=gijHH_t_3D.Coor(2,2)
=gijBB_tdt_3D.Coor(2,2)=gijHH_tdt_3D.Coor(2,2)=1.;
gijBB_0_3D.Coor(3,3)=gijHH_0_3D.Coor(3,3)=gijBB_t_3D.Coor(3,3)=gijHH_t_3D.Coor(3,3)
=gijBB_tdt_3D.Coor(3,3)=gijHH_tdt_3D.Coor(3,3)=1.;
// lors d'un premier appel, les variables save_resul.h_tsurh0 et save_resul.hsurh0
// ne sont pas affecté car elles sont issues d'un premier calcul, dans ce cas on les mets arbitrairement à 1
// ensuite elles évolueront, idem pour la largeur
bool premier_passage = false;
if (save_resul.h_tsurh0 == 0.)
{ save_resul.h_tsurh0 = 1.; save_resul.hsurh0 = 1.;
save_resul.b_tsurb0 = 1.; save_resul.bsurb0 = 1.;
premier_passage = true;
};
if (save_resul.hsurh0 == 0.) // peut arriver dans le cas où on a une erreur dès le début
{ save_resul.hsurh0 = save_resul.h_tsurh0;}; // on réinitialise
if (save_resul.bsurb0 == 0.) // peut arriver dans le cas où on a une erreur dès le début
{ save_resul.bsurb0 = save_resul.b_tsurb0;}; // on réinitialise
// on calcul les vecteur 2 et 3 naturels et duals
giB_t_3D.CoordoB(2) *= save_resul.b_tsurb0; giH_t_3D.CoordoH(2) /= save_resul.b_tsurb0;
giB_tdt_3D.CoordoB(2) *= save_resul.bsurb0; giH_tdt_3D.CoordoH(2) /= save_resul.bsurb0;
giB_t_3D.CoordoB(3) *= save_resul.h_tsurh0; giH_t_3D.CoordoH(3) /= save_resul.h_tsurh0;
giB_tdt_3D.CoordoB(3) *= save_resul.hsurh0; giH_tdt_3D.CoordoH(3) /= save_resul.hsurh0;
// - et les tenseurs métriques à t et tdt, comme les vecteurs en épaisseurs et largeurs
// sont normées initialement, seule l'intensité
// des normales est à mettre à jour compte tenue de la variation d'épaisseurs
double b_tsurb0_carre = save_resul.b_tsurb0 * save_resul.b_tsurb0;
gijBB_t_3D.Coor(2,2)=b_tsurb0_carre; gijHH_t_3D.Coor(2,2)= 1./b_tsurb0_carre;
double bsurb0_carre = save_resul.bsurb0 * save_resul.bsurb0;
gijBB_tdt_3D.Coor(2,2) = bsurb0_carre;gijHH_tdt_3D.Coor(2,2) = 1. / bsurb0_carre;
double h_tsurh0_carre = save_resul.h_tsurh0 * save_resul.h_tsurh0;
gijBB_t_3D.Coor(3,3)=h_tsurh0_carre; gijHH_t_3D.Coor(3,3)= 1./h_tsurh0_carre;
double hsurh0_carre = save_resul.hsurh0 * save_resul.hsurh0;
gijBB_tdt_3D.Coor(3,3) = hsurh0_carre;gijHH_tdt_3D.Coor(3,3) = 1. / hsurh0_carre;
};
// passage des grandeurs métriques de l'ordre 1 à 3: cas Umat
void LoiContraintesPlanesDouble::Passage_metrique_ordre1_vers_3(const Met_abstraite::Umat_cont& ex)
{ // on s'occupe du redimensionnement éventuel
// on affecte et/ou on redimensionne éventuellement les tableaux fonction du nombre de ddl pour le passage 3D
// la partie dépendant des vitesses: entre accolades pour pouvoir fermer
{if (ex.gradVmoyBB_t != NULL) {umat_cont_3D->gradVmoyBB_t= gradVmoyBB_t_3D_P = &gradVmoyBB_t_3D;};
if (ex.gradVmoyBB_tdt != NULL) {umat_cont_3D->gradVmoyBB_tdt=gradVmoyBB_tdt_3D_P = &gradVmoyBB_tdt_3D;};
if (ex.gradVBB_tdt != NULL) {umat_cont_3D->gradVBB_tdt=gradVBB_tdt_3D_P = &gradVBB_tdt_3D;};
}; // fin de la partie dédiée à la vitesse
// récup du conteneur spécifique
SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul);
// on commence par recopier les grandeurs de l'ordre 1 à 3
bool plusZero = true; // on complète avec des 0 dans un premier temps
int type_recopie = 0; // init: on recopie les grandeurs de 0,t et tdt
if ( save_resul.meti_ref_00.giB_ != NULL)
type_recopie = 1; // = 1 -> on transfert les grandeurs à t et tdt
umat_cont_3D->Passage_de_Ordre1_vers_Ordre3(ex,plusZero,type_recopie);
// maintenant on s'occupe de mettre à jour les grandeurs manquantes
// - les bases naturelles: les vecteurs normaux dans les directions 2 et 3 sont normées
// et sont identiques pour les bases naturelles et duales
// Dans le cas d'un comportement isotrope, on choisit un repère par défaut
// si les repères associés ne sont définis on les définit
if ( save_resul.meti_ref_00.giB_ == NULL)
{ Deformation::Stmet inter(3,3); // création d'un conteneur bien dimensionné
save_resul.meti_ref_00 = save_resul.meti_ref_t = save_resul.meti_ref_tdt = inter;
// on s'occupe de la création du premier repère
CoordonneeB & giB0_1 = (*(save_resul.meti_ref_00.giB_)).CoordoB(1); // pour simplifier
giB0_1 = giB_0_3D(1); // on récupère la direction du premier vecteur
giB0_1.Normer(); // on le norme
// on crée 2 vecteurs normés, perpendiculaires à ce premier vecteur
CoordonneeB & giB0_2 = (*(save_resul.meti_ref_00.giB_)).CoordoB(2); // pour simplifier
CoordonneeB & giB0_3 = (*(save_resul.meti_ref_00.giB_)).CoordoB(3); // pour simplifier
MathUtil2::Def_vecteurs_plan(giB0_1,giB0_2,giB0_3);
// comme la base est orthonormée, les giH sont identiques aux giB
(*(save_resul.meti_ref_00.giH_)).Affectation_trans_variance((*(save_resul.meti_ref_00.giB_)));
// on affecte les vecteurs qui seront transmis via l'umat
giB_0_3D.CoordoB(2)=giB0_2;giB_0_3D.CoordoB(3)=giB0_3;
BaseH& a0H = (*(save_resul.meti_ref_00.giH_)); // pour simplifier
giH_0_3D.CoordoH(1)=a0H(1);giH_0_3D.CoordoH(2)=a0H(2);giH_0_3D.CoordoH(3)=a0H(3);
};
////--- debug
// cout << "\n debug LoiContraintesPlanesDouble::Passage_metrique_ordre1_vers_3(";
// cout << "\n giH_0(2): "; giH_0_3D(2).Affiche();
// cout << "\n giH_0(3): "; giH_0_3D(3).Affiche();
//// --- fin debug
// on met à jour les deux autres directions
// *** pour l'instant on fait la même chose que pour t= 0, pour les deux autres temps
// *** , mais il faudra surement améliorer
CoordonneeB & giBt_1 = (*(save_resul.meti_ref_t.giB_)).CoordoB(1); // pour simplifier
giBt_1 = giB_t_3D(1); // on récupère la direction du premier vecteur
giBt_1.Normer(); // on le norme
// on crée 2 vecteurs normés, perpendiculaires à ce premier vecteur
CoordonneeB & giBt_2 = (*(save_resul.meti_ref_t.giB_)).CoordoB(2); // pour simplifier
CoordonneeB & giBt_3 = (*(save_resul.meti_ref_t.giB_)).CoordoB(3); // pour simplifier
MathUtil2::Def_vecteurs_plan(giBt_1,giBt_2,giBt_3);
// comme la base est orthonormée, les giH sont identiques aux giB
// ensuite plus bas, les normes seront changées pour tenir compte des variations d'épaisseur et de largeur
(*(save_resul.meti_ref_t.giH_)).Affectation_trans_variance((*(save_resul.meti_ref_t.giB_)));
// on affecte les vecteurs qui seront transmis via l'umat
giB_t_3D.CoordoB(2)=giBt_2;giB_t_3D.CoordoB(3)=giBt_3;
BaseH& a_t_H = (*(save_resul.meti_ref_t.giH_)); // pour simplifier
giH_t_3D.CoordoH(1)=a_t_H(1);giH_t_3D.CoordoH(2)=a_t_H(2);giH_t_3D.CoordoH(3)=a_t_H(3);
//--- cas à tdt
CoordonneeB & giBtdt_1 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(1); // pour simplifier
giBtdt_1 = giB_tdt_3D(1); // on récupère la direction du premier vecteur
giBtdt_1.Normer(); // on le norme
// on crée 2 vecteurs normés, perpendiculaires à ce premier vecteur
CoordonneeB & giBtdt_2 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(2); // pour simplifier
CoordonneeB & giBtdt_3 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(3); // pour simplifier
MathUtil2::Def_vecteurs_plan(giBtdt_1,giBtdt_2,giBtdt_3);
giB_tdt_3D.CoordoB(2)=giBtdt_2;giB_tdt_3D.CoordoB(3)=giBtdt_3;
// comme la base est orthonormée ici, les giH sont identiques aux giB
// ensuite plus bas, les normes seront changées pour tenir compte des variations d'épaisseur et de largeur
(*(save_resul.meti_ref_tdt.giH_)).Affectation_trans_variance((*(save_resul.meti_ref_tdt.giB_)));
// on affecte les vecteurs qui seront transmis via l'umat
giB_tdt_3D.CoordoB(2)=giBtdt_2;giB_tdt_3D.CoordoB(3)=giBtdt_3;
BaseH& a_tdt_H = (*(save_resul.meti_ref_tdt.giH_)); // pour simplifier
giH_tdt_3D.CoordoH(1)=a_tdt_H(1);giH_tdt_3D.CoordoH(2)=a_tdt_H(2);giH_tdt_3D.CoordoH(3)=a_tdt_H(3);
// - les tenseurs métriques: a priori 1 pour les directions 2 et 3, initialement
gijBB_0_3D.Coor(2,2)=gijHH_0_3D.Coor(2,2)=gijBB_t_3D.Coor(2,2)=gijHH_t_3D.Coor(2,2)
=gijBB_tdt_3D.Coor(2,2)=gijHH_tdt_3D.Coor(2,2)=1.;
gijBB_0_3D.Coor(3,3)=gijHH_0_3D.Coor(3,3)=gijBB_t_3D.Coor(3,3)=gijHH_t_3D.Coor(3,3)
=gijBB_tdt_3D.Coor(3,3)=gijHH_tdt_3D.Coor(3,3)=1.;
// lors d'un premier appel, les variables save_resul.h_tsurh0 et save_resul.hsurh0
// ne sont pas affecté car elles sont issues d'un premier calcul, dans ce cas on les mets arbitrairement à 1
// ensuite elles évolueront, idem pour la largeur
bool premier_passage = false;
if (save_resul.h_tsurh0 == 0.)
{ save_resul.h_tsurh0 = 1.; save_resul.hsurh0 = 1.;
premier_passage = true;
};
if (save_resul.hsurh0 == 0.) // peut arriver dans le cas où on a une erreur dès le début
{ save_resul.hsurh0 = save_resul.h_tsurh0;}; // on réinitialise
// on peut avoir la même chose en b, indépendamment, lorsque l'on passe de contrainte plane
// à doublement plane
if (save_resul.b_tsurb0 == 0.)
{ save_resul.b_tsurb0 = 1.; save_resul.bsurb0 = 1.;
premier_passage = true;
};
if (save_resul.bsurb0 == 0.) // peut arriver dans le cas où on a une erreur dès le début
{ save_resul.bsurb0 = save_resul.b_tsurb0;}; // on réinitialise
// on calcul les vecteur 2 et 3 naturels et duals
giB_t_3D.CoordoB(2) *= save_resul.b_tsurb0; giH_t_3D.CoordoH(2) /= save_resul.b_tsurb0;
giB_tdt_3D.CoordoB(2) *= save_resul.bsurb0; giH_tdt_3D.CoordoH(2) /= save_resul.bsurb0;
giB_t_3D.CoordoB(3) *= save_resul.h_tsurh0; giH_t_3D.CoordoH(3) /= save_resul.h_tsurh0;
giB_tdt_3D.CoordoB(3) *= save_resul.hsurh0; giH_tdt_3D.CoordoH(3) /= save_resul.hsurh0;
// - et les tenseurs métriques à t et tdt, comme les vecteurs en épaisseurs et largeurs
// sont normées initialement, seule l'intensité
// des normales est à mettre à jour compte tenue de la variation d'épaisseurs
double b_tsurb0_carre = save_resul.b_tsurb0 * save_resul.b_tsurb0;
gijBB_t_3D.Coor(2,2)=b_tsurb0_carre; gijHH_t_3D.Coor(2,2)= 1./b_tsurb0_carre;
double bsurb0_carre = save_resul.bsurb0 * save_resul.bsurb0;
gijBB_tdt_3D.Coor(2,2) = bsurb0_carre;gijHH_tdt_3D.Coor(2,2) = 1. / bsurb0_carre;
double h_tsurh0_carre = save_resul.h_tsurh0 * save_resul.h_tsurh0;
gijBB_t_3D.Coor(3,3)=h_tsurh0_carre; gijHH_t_3D.Coor(3,3)= 1./h_tsurh0_carre;
double hsurh0_carre = save_resul.hsurh0 * save_resul.hsurh0;
gijBB_tdt_3D.Coor(3,3) = hsurh0_carre;gijHH_tdt_3D.Coor(3,3) = 1. / hsurh0_carre;
};
// passage des informations liées à la déformation de 1 vers 3, et variation de volume
// utilisée pour les méthodes 1 et 2
// entre autre: calcul du jacobien 3D en fonction de l'élongation 1D et des variations h/h0 et b/b0
void LoiContraintesPlanesDouble::Passage_deformation_volume_ordre1_vers_3
// (int cas, TenseurBB& DepsBB,TenseurBB & epsBB_tdt,Tableau <TenseurBB *>* d_epsBB
(TenseurBB& DepsBB,TenseurBB & epsBB_tdt,Tableau <TenseurBB *>* d_epsBB
,TenseurBB & delta_epsBB,const double& jacobien_0,double& jacobien
,Vecteur* d_jacobien_tdt,const double& jacobien_t)
{ // au début on complète avec des 0, puis dans un second temps on tient compte de la déformation d'épaisseur eps33
bool plusZero = true;
Deps_BB_3D.Affectation_trans_dimension(*((Tenseur1BB*) &DepsBB),plusZero);
eps_BB_3D.Affectation_trans_dimension(*((Tenseur1BB*) &epsBB_tdt),plusZero);
delta_eps_BB_3D.Affectation_trans_dimension(*((Tenseur1BB*) &delta_epsBB),plusZero);
// récup du conteneur spécifique
SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul);
if(d_epsBB != NULL)
{ int taille = d_epsBB->Taille();
// redimensionnement éventuel
int ta_d_eps_BB_3D = d_eps_BB_3D.Taille();
if (ta_d_eps_BB_3D != taille)
{ // cela veut dire que tous les tableaux sont mal dimensionnés
d_eps_BB_3D.Change_taille(taille); d_eps_BB_3D_P.Change_taille(taille);
for (int i=1;i<=taille;i++) {d_eps_BB_3D_P(i) = &(d_eps_BB_3D(i));}
};
// passage 1D 3D
for (int i=1;i<=taille;i++)
{ d_eps_BB_3D(i).Affectation_trans_dimension(*((Tenseur1BB*) (*d_epsBB)(i)),plusZero);}
if (save_resul.d_hsurh0.Taille() != taille)
save_resul.d_hsurh0.Change_taille(taille); // donc à 0 la première fois
if (save_resul.d_bsurb0.Taille() != taille)
save_resul.d_bsurb0.Change_taille(taille); // donc à 0 la première fois
};
// -- calcul du jacobien 3D
/* la partie cas = 2: ne fonctionne pas bien le choix est fait
d'utiliser les variations d'épaisseur et de largeur
// dans le cas d'un calcul dans une direction quelconque
// on utilise la déformation mécanique sauvegardée pour calculer les jacobiens
if (cas == 2)
{ //récup de eps_mecaBB_t
Tenseur3BB& eps_mecaBB_t = *((Tenseur3BB*) (save_resul.eps_mecaBB_t));
// --- on s'occupe des jacobiens
// à t le jacobien est calculée à partir de la déformation supposée d'Almansi
// ici il s'agit du jacobien relatif au comportement mécanique
// |J| = sqrt(det(2 * eps_ij_t + g_ij(0)))
// calcul de la matrice correspondante à (2 * eps_ij_t + g_ij(0))
gij_meca_BB_t = (2. * eps_mecaBB_t + (*(umat_cont_3D->gijBB_0)));
gij_meca_BB_t.Matrice_composante(mat_inter);
// calcul du jacobien
jacobien_t_3D = sqrt(Dabs(mat_inter.Determinant()));
// on fait de même pour le jacobien initial ce qui permet d'être cohérent
// avec la métrique initiale et la déformation au sens d'Almansi
(umat_cont_3D->gijBB_0)->Matrice_composante(mat_inter);
jacobien_0_3D = sqrt(Dabs(mat_inter.Determinant()));
// le jacobien à tdt sera calculé pendant la résolution
}
else if (cas == 1)
*/
{// première phase on se contente de recopier, ce qui suppose une épaisseur = 1.
jacobien_0_3D = jacobien_0; // -> partie 1D
jacobien_tdt_3D = sauve_jacobien1D_tdt = jacobien;
// ici, l'épaisseur initiale h0 est toujours 1., donc h/h0 = également h et idem pour b/b0
jacobien_tdt_3D *= save_resul.hsurh0 * save_resul.bsurb0;
// même travail pour t
jacobien_t_3D = jacobien_t;
jacobien_t_3D *= save_resul.h_tsurh0 * save_resul.b_tsurb0;
};
// recup de l'incrément de temps
double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant();
double unSurDeltat=0;
if (Abs(deltat) >= ConstMath::trespetit)
{unSurDeltat = 1./deltat;}
else
// si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand
{ // non un pas de temps doit être positif !! or certaine fois il peut y avoir des pb
if (unSurDeltat < 0)
{ cout << "\n le pas de temps est négatif !! "; };
unSurDeltat = ConstMath::tresgrand;
};
// cas des def, delta def et D
if (!calcul_en_3D_via_direction_quelconque)
{ //dans le cas classique, on dispose de la variation d'épaisseur et de largeur pour déterminer les def
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), en orthonormee
// dans le repère local: epsBB33 = 1/2 * (h^2 - 1.), or h0=1. donc : epsBB33 = 1/2 * ((h/h0)^2 - 1.)
eps_BB_3D.Coor(3,3) = 0.5 * (save_resul.hsurh0 * save_resul.hsurh0 - 1.);
delta_eps_BB_3D.Coor(3,3) = 0.5 * (save_resul.hsurh0 * save_resul.hsurh0 - save_resul.h_tsurh0 * save_resul.h_tsurh0);
// idem pour la largeur
eps_BB_3D.Coor(2,2) = 0.5 * (save_resul.bsurb0 * save_resul.bsurb0 - 1.);
delta_eps_BB_3D.Coor(2,2) = 0.5 * (save_resul.bsurb0 * save_resul.bsurb0 - save_resul.b_tsurb0 * save_resul.b_tsurb0);
Deps_BB_3D.Coor(3,3) = delta_eps_BB_3D(3,3)* unSurDeltat;
Deps_BB_3D.Coor(2,2) = delta_eps_BB_3D(2,2)* unSurDeltat;
// dans le cas où on calcule les variations, on intègre également les variations de eps33 et eps22
if (d_epsBB != NULL)
{ Vecteur& d_hsurh0 = save_resul.d_hsurh0;
Vecteur& d_bsurb0 = save_resul.d_bsurb0;
int taille = d_epsBB->Taille();
for (int i=1;i<=taille;i++)
{d_eps_BB_3D(i).Coor(3,3)= save_resul.hsurh0 * d_hsurh0(i);
d_eps_BB_3D(i).Coor(2,2)= save_resul.bsurb0 * d_bsurb0(i);
}
};
};
break;
case DEFORMATION_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEFORMATION_CUMU_LOGARITHMIQUE :
// cas d'une def logarithmique ou une approximation
{ eps_BB_3D.Coor(3,3) = log(save_resul.hsurh0);
delta_eps_BB_3D.Coor(3,3) = log(save_resul.hsurh0) - log(save_resul.h_tsurh0);
// idem pour la largeur
eps_BB_3D.Coor(2,2) = log(save_resul.bsurb0);
delta_eps_BB_3D.Coor(2,2) = log(save_resul.bsurb0) - log(save_resul.b_tsurb0);
Deps_BB_3D.Coor(3,3) = delta_eps_BB_3D(3,3)* unSurDeltat;
Deps_BB_3D.Coor(2,2) = delta_eps_BB_3D(2,2)* unSurDeltat;
// dans le cas où on calcule les variations, on intègre également les variations de eps33 et eps22
if (d_epsBB != NULL)
{ Vecteur& d_hsurh0 = save_resul.d_hsurh0;
Vecteur& d_bsurb0 = save_resul.d_bsurb0;
int taille = d_epsBB->Taille();
// d_eps_BB_3D(3,3) = d_hsurh0 * exp(save_resul.hsurh0)
for (int i=1;i<=taille;i++)
{d_eps_BB_3D(i).Coor(3,3)= d_hsurh0(i) * eps_BB_3D(3,3);
d_eps_BB_3D(i).Coor(2,2)= d_bsurb0(i) * eps_BB_3D(2,2);
}
};
};
break;
default :
cout << "\nErreur : type de deformation qui n'est pas actuellement pris en compte, type= "
<< Nom_type_deformation(type_de_deformation);
cout << "\n LoiContraintesPlanesDouble::Passage_deformation_volume_ordre1_vers_3 \n";
Sortie(1);
};
}
else
// dans le cas où on travaille dans le repère gi en 3D on dispose directement des infos de déformation
{//récup de eps_mecaBB
Tenseur3BB& eps_mecaBB_t = *((Tenseur3BB*) (save_resul.eps_mecaBB_t));
Tenseur3BB& eps_mecaBB = *((Tenseur3BB*) (save_resul.eps_mecaBB));
// on sauve ce qu'il y a dans la direction 11 pour éviter les erreurs d'arrondis
double eps11= (*ptintmeca.EpsBB())(1,1);
double Deps11= (*ptintmeca.DepsBB())(1,1);
double delta_eps11= (*ptintmeca.DeltaEpsBB())(1,1);
// les manips entre tenseurs
(*ptintmeca.EpsBB()) = eps_mecaBB;
(*ptintmeca.DeltaEpsBB()) = eps_mecaBB - eps_mecaBB_t;
(*ptintmeca.DepsBB()) = (*ptintmeca.DeltaEpsBB()) * unSurDeltat;
// récup des valeurs sauvegardées (normalement ne devrait pas changer...)
(*ptintmeca.EpsBB()).Coor(1,1) = eps11;
(*ptintmeca.DeltaEpsBB()).Coor(1,1) = delta_eps11;
(*ptintmeca.DepsBB()).Coor(1,1) = Deps11;
};
if(d_jacobien_tdt != NULL)
{ Vecteur& d_hsurh0 = save_resul.d_hsurh0;
Vecteur& d_bsurb0 = save_resul.d_bsurb0;
// jacobien_tdt_3D = hsurh0 * jacobien_1D
// --> d_jacobien_tdt_3D = d_hsurh0 * jacobien_1D + hsurh0 * d_jacobien_1D
d_jacobien_tdt_3D = d_hsurh0 * save_resul.bsurb0 * jacobien
+ save_resul.hsurh0 * d_bsurb0 * jacobien
+ save_resul.hsurh0 * save_resul.bsurb0 * (*d_jacobien_tdt);
};
//---debug
//cout << "\n LoiContraintesPlanesDouble::Passage_deformation_volume_ordre1_vers_3, eps_BB_3D(3,3) = "
// << eps_BB_3D(3,3) << " jacobien_tdt_3D= " << jacobien_tdt_3D;
// --- fin debug
};
// mise à jour des informations liées à la déformation de 1 vers 3
// uniquement méthode 1
void LoiContraintesPlanesDouble::Mise_a_jour_deformations_et_Jacobien_en_3D
()
{ // récup du conteneur spécifique
SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul);
// -- calcul du jacobien 3D
// première phase on se contente de recopier, ce qui suppose une épaisseur = 1. et une largeur = 1.
jacobien_tdt_3D = sauve_jacobien1D_tdt * save_resul.hsurh0 * save_resul.bsurb0;
// -- maintenant on tient compte de la déformation d'épaisseur
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), en orthonormee
// dans le repère local: epsBB33 = 1/2 * (h^2 - 1.), or h0=1. donc : epsBB33 = 1/2 * ((h/h0)^2 - 1.)
eps_BB_3D.Coor(3,3) = 0.5 * (save_resul.hsurh0 * save_resul.hsurh0 - 1.);
delta_eps_BB_3D.Coor(3,3) = 0.5 * (save_resul.hsurh0 * save_resul.hsurh0 - save_resul.h_tsurh0 * save_resul.h_tsurh0);
// idem pour la direction 2
eps_BB_3D.Coor(2,2) = 0.5 * (save_resul.bsurb0 * save_resul.bsurb0 - 1.);
delta_eps_BB_3D.Coor(2,2) = 0.5 * (save_resul.bsurb0 * save_resul.bsurb0 - save_resul.b_tsurb0 * save_resul.b_tsurb0);
};
break;
case DEFORMATION_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEFORMATION_CUMU_LOGARITHMIQUE :
// cas d'une def logarithmique ou une approximation
{ eps_BB_3D.Coor(3,3) = log(save_resul.hsurh0);
delta_eps_BB_3D.Coor(3,3) = log(save_resul.hsurh0) - log(save_resul.h_tsurh0);
// idem pour la direction 2
eps_BB_3D.Coor(2,2) = log(save_resul.bsurb0);
delta_eps_BB_3D.Coor(2,2) = log(save_resul.bsurb0) - log(save_resul.b_tsurb0);
};
break;
default :
cout << "\nErreur : type de deformation qui n'est pas actuellement pris en compte, type= "
<< Nom_type_deformation(type_de_deformation);
cout << "\n LoiContraintesPlanesDouble::Passage_deformation_volume_ordre1_vers_3 \n";
Sortie(1);
};
// -- cas de la vitesse de déformation
// recup de l'incrément de temps
double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant();
double unSurDeltat=0;
if (Abs(deltat) >= ConstMath::trespetit)
{unSurDeltat = 1./deltat;}
else
// si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand
{ // non un pas de temps doit être positif !! or certaine fois il peut y avoir des pb
if (unSurDeltat < 0)
{ cout << "\n le pas de temps est négatif !! "; };
unSurDeltat = ConstMath::tresgrand;
};
Deps_BB_3D.Coor(2,2) = delta_eps_BB_3D(2,2) * unSurDeltat;
Deps_BB_3D.Coor(3,3) = delta_eps_BB_3D(3,3) * unSurDeltat;
};
// calcul de la déformation d'épaisseur et de largeur
// cas de la méthode 1
void LoiContraintesPlanesDouble::Calcul_eps_trans_parVarVolume1(Tenseur3BH& sigBH_t,double& jaco_1D_0,const double& module_compressibilite,double& jaco_1D_tdt
,Tenseur3BH& sigBH,double& jaco_1D_t)
{ // récup des infos spécifiques
SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul);
// on utilise la relation: (V-V_0)/V = trace(sigma)/3 /K_moy
// avec trace(sigma) en 1D = idem en 3D car on est en contraintes doublement planes
// jacobien 1D = la longueur donc le volume = jacobien 1D * h * b -> (jaco1D_tdt * h * b -jaco1D_0*h_0*b_0) = delta_V
// on considère de plus que l'on est isotrope donc h/h_0 = b/b_0
// en appelant B= trace(sigma)/3 /K_moy on a:
// (h/h_0)^2 = jaco1D_0 / jaco1D_tdt * 1./(1.-B) d'où la déformation logarithmique
if (Dabs(module_compressibilite)>0.) // si le module est nul, cela signifie qu'il n'est pas disponible
{ //double B = (sigBH(1,1)+sigBH(2,2)) / (3. * module_compressibilite );
double log_VsurV0 = (sigBH.Trace()) / (3. * module_compressibilite );
double exp_log_VsurV0 = exp(log_VsurV0);
double hSurh_0 = sqrt((jaco_1D_0 / jaco_1D_tdt) * exp_log_VsurV0) ;
// on test les mini-maxi
if (hSurh_0 < mini_hsurh0)
{if (Permet_affichage() > 3)
{cout << "\n *** attention hsurh0 " << hSurh_0 << "est inferieur a la limite fixee "<<mini_hsurh0
<< " on le ramene a la limite "
<< "\n LoiContraintesPlanesDouble::Calcul_eps_trans_parVarVolume(... " << endl;
};
hSurh_0 = mini_hsurh0;
};
if (hSurh_0 > maxi_hsurh0)
{if (Permet_affichage() > 3)
{cout << "\n *** attention bsurb0 " << maxi_hsurh0 << "est superieur a la limite fixee "<<maxi_hsurh0
<< " on le ramene a la limite "
<< "\n LoiContraintesPlanesDouble::Calcul_eps_trans_parVarVolume(... " << endl;
};
hSurh_0 = maxi_hsurh0;
};
// on met à jour épaisseur et largeur d'une même valeur
save_resul.hsurh0 = hSurh_0; // élongation d'épaisseur
save_resul.bsurb0 = hSurh_0; // élongation de largeur
////--- debug
// save_resul.hsurh0 = save_resul.h_tsurh0; // élongation d'épaisseur
// save_resul.bsurb0 = save_resul.b_tsurb0; // élongation d'épaisseur
////-----fin debug
}
else
{ save_resul.hsurh0 = save_resul.bsurb0 = 1.;};
// ---- la suite est un essai, mais ne semble pas non plus fonctionner avec la loi critère
// car le jacobien à t n'est pas calculé ?? ce qui n'est pas normal
// ticket #120
// // a priori cela ne marche pas bien: on va tenter avec le delta jacobien
// // on utilise la relation: (V(tdt)-V(t))/V(tdt) = trace(delta_sigma)/3 /K_moy
// // avec trace(delta_sigma) en 1D = idem en 3D car on est en contraintes doublement planes
// // jacobien 1D = la longueur donc le volume = jacobien 1D * h * b -> (jaco1D_tdt * h * b -jaco1D_t*h_t*b_t) = delta_V
// // on considère de plus que l'on est isotrope donc delta_h/h = delta_b/b d'où h/h_t = b/b_t
// // en appelant B= trace(delta_sigma)/3 /K / (h_t*b_t) on a:
// // (h/h_t)^2 = jaco1D_t / (jaco1D_tdt * (1.-B))
// if (Dabs(module_compressibilite)>0.) // si le module est nul, cela signifie qu'il n'est pas disponible
// { //double B = (sigBH(1,1)+sigBH(2,2)) / (3. * module_compressibilite );
// double B = (sigBH(1,1)-sigBH_t(1,1)) / (3. * module_compressibilite );
// double hSurh_t = sqrt((jaco_1D_t / jaco_1D_tdt) / (1.-B)) ;
//
// save_resul.hsurh0 = hSurh_t * save_resul.h_tsurh0;
// save_resul.bsurb0 = hSurh_t * save_resul.b_tsurb0; // élongation d'épaisseur
// }
// else
// { save_resul.hsurh0 = save_resul.bsurb0 = 1.;};
};
// calcul de la déformation d'épaisseur et de largeur
// cas de la méthode 2
void LoiContraintesPlanesDouble::Calcul_eps_trans_parVarVolume2(Tenseur3BH& sigBH_t,double& jaco_1D_0,const double& module_compressibilite,double& jaco_1D_tdt
,Tenseur3BH& sigBH,double& jaco_1D_t)
{ // récup des infos spécifiques
SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul);
// on utilise la relation: (V-V_0)/V = trace(sigma)/3 /K_moy
// avec trace(sigma) en 1D = idem en 3D car on est en contraintes doublement planes
// jacobien 1D = la longueur donc le volume = jacobien 1D * h * b -> (jaco1D_tdt * h * b -jaco1D_0*h_0*b_0) = delta_V
// on considère de plus que l'on est isotrope donc h/h_0 = b/b_0
// en appelant B= trace(sigma)/3 /K_moy on a:
// (h/h_0)^2 = jaco1D_0 / jaco1D_tdt * 1./(1.-B) d'où la déformation logarithmique
if (Dabs(module_compressibilite)>0.) // si le module est nul, cela signifie qu'il n'est pas disponible
{ //double B = (sigBH(1,1)+sigBH(2,2)) / (3. * module_compressibilite );
double log_VsurV0 = (sigBH.Trace()) / (3. * module_compressibilite );
double exp_log_VsurV0 = exp(log_VsurV0);
double hSurh_0 = sqrt((jaco_1D_0 / jaco_1D_tdt) * exp_log_VsurV0) ;
// on test les mini-maxi
if (hSurh_0 < mini_hsurh0)
{if (Permet_affichage() > 3)
{cout << "\n *** attention hsurh0 " << hSurh_0 << "est inferieur a la limite fixee "<<mini_hsurh0
<< " on le ramene a la limite "
<< "\n LoiContraintesPlanesDouble::Calcul_eps_trans_parVarVolume2(... " << endl;
};
hSurh_0 = mini_hsurh0;
};
if (hSurh_0 > maxi_hsurh0)
{if (Permet_affichage() > 3)
{cout << "\n *** attention bsurb0 " << maxi_hsurh0 << "est superieur a la limite fixee "<<maxi_hsurh0
<< " on le ramene a la limite "
<< "\n LoiContraintesPlanesDouble::Calcul_eps_trans_parVarVolume1(... " << endl;
};
hSurh_0 = maxi_hsurh0;
};
// on met à jour épaisseur et largeur d'une même valeur
save_resul.hsurh0 = hSurh_0; // élongation d'épaisseur
save_resul.bsurb0 = hSurh_0; // élongation de largeur
////--- debug
// save_resul.hsurh0 = save_resul.h_tsurh0; // élongation d'épaisseur
// save_resul.bsurb0 = save_resul.b_tsurb0; // élongation d'épaisseur
////-----fin debug
}
else
{ save_resul.hsurh0 = save_resul.bsurb0 = 1.;};
// ---- la suite est un essai, mais ne semble pas non plus fonctionner avec la loi critère
// car le jacobien à t n'est pas calculé ?? ce qui n'est pas normal
// ticket #120
// // a priori cela ne marche pas bien: on va tenter avec le delta jacobien
// // on utilise la relation: (V(tdt)-V(t))/V(tdt) = trace(delta_sigma)/3 /K_moy
// // avec trace(delta_sigma) en 1D = idem en 3D car on est en contraintes doublement planes
// // jacobien 1D = la longueur donc le volume = jacobien 1D * h * b -> (jaco1D_tdt * h * b -jaco1D_t*h_t*b_t) = delta_V
// // on considère de plus que l'on est isotrope donc delta_h/h = delta_b/b d'où h/h_t = b/b_t
// // en appelant B= trace(delta_sigma)/3 /K / (h_t*b_t) on a:
// // (h/h_t)^2 = jaco1D_t / (jaco1D_tdt * (1.-B))
// if (Dabs(module_compressibilite)>0.) // si le module est nul, cela signifie qu'il n'est pas disponible
// { //double B = (sigBH(1,1)+sigBH(2,2)) / (3. * module_compressibilite );
// double B = (sigBH(1,1)-sigBH_t(1,1)) / (3. * module_compressibilite );
// double hSurh_t = sqrt((jaco_1D_t / jaco_1D_tdt) / (1.-B)) ;
//
// save_resul.hsurh0 = hSurh_t * save_resul.h_tsurh0;
// save_resul.bsurb0 = hSurh_t * save_resul.b_tsurb0; // élongation d'épaisseur
// }
// else
// { save_resul.hsurh0 = save_resul.bsurb0 = 1.;};
};
// calcul des déformations d'épaisseur et de largeur et des variations
// méthode 1
void LoiContraintesPlanesDouble::Calcul_d_eps_trans_parVarVolume(double& jaco_1D_0,const double& module_compressibilite,double& jaco_1D_tdt
,TenseurHH& sigHH_,Vecteur& d_jaco_1D
,Tableau <TenseurHH *>& d_sigHH,Tableau <TenseurBB *>& d_gijBB_tdt,TenseurBB & gijBB_)
{ // récup des infos spécifiques
SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul);
// on utilise la relation: log(V/V0) = trace(sigma)/3 /K_moy
// avec trace(sigma) en 1D = idem en 3D car on est en contraintes planes double
// jacobien 1D = la longueur, donc le volume: V = jacobien 1D * h * b -> (jaco1D_tdt * h * b)/(jaco1D_0*h_0*b_0) = V/V0
// en appelant log_VsurV0= trace(sigma)/3 /K_moy on a:
// h/h_0 * b/b_0= jaco1D_0 / jaco1D_tdt * exp(log_VsurV0)
// ici sans info sup, on considère une loi isotrope d'où h/h_0 = b/b_0
// -> h/h_0 = (jaco1D_0 / jaco1D_tdt * exp(log_VsurV0))^(0.5)
if (Dabs(module_compressibilite)>0.) // si le module est nul, cela signifie qu'il n'est pas disponible
{ const Tenseur1BB & gijBB = *((Tenseur1BB*) &gijBB_); // pour simplifier
const Tenseur1HH & sigHH = *((Tenseur1HH*) &sigHH_); // pour simplifier
Tenseur1BH sigBH = gijBB * sigHH;
double log_VsurV0 = (sigBH.Trace()) / (3. * module_compressibilite );
double exp_log_VsurV0 = exp(log_VsurV0);
double hSurh_0 = sqrt((jaco_1D_0 / jaco_1D_tdt) * exp_log_VsurV0) ;
// on test les mini-maxi
if (hSurh_0 < mini_hsurh0)
{if (Permet_affichage() > 3)
{cout << "\n *** attention hsurh0 " << hSurh_0 << "est inferieur a la limite fixee "<<mini_hsurh0
<< " on le ramene a la limite "
<< "\n LoiContraintesPlanesDouble::Calcul_d_eps_trans_parVarVolume(... " << endl;
};
hSurh_0 = mini_hsurh0;
};
if (hSurh_0 > maxi_hsurh0)
{if (Permet_affichage() > 3)
{cout << "\n *** attention bsurb0 " << maxi_hsurh0 << "est superieur a la limite fixee "<<maxi_hsurh0
<< " on le ramene a la limite "
<< "\n LoiContraintesPlanesDouble::Calcul_d_eps_trans_parVarVolume(... " << endl;
};
hSurh_0 = maxi_hsurh0;
};
// on met à jour épaisseur et largeur d'une même valeur
save_resul.hsurh0 = hSurh_0; // élongation d'épaisseur
save_resul.bsurb0 = hSurh_0; // élongation de largeur
// maintenant le cas de la variation de h/h0
// on tient compte de la variation relative à la dépendance du jacobien et à la trace de sigma
// a) vérification et modif éventuelle de la taille
Vecteur& d_hsurh0 = save_resul.d_hsurh0;
// b) calcul de la variation
//2.* h/h_0 * d h/h0 = - djaco_1D * (jaco_1D_0 / ((jaco_1D_tdt)^2)) * exp(log_VsurV0)
// + d_(sigBH.Trace()) * (jaco_1D_0 / jaco_1D_tdt) * exp(log_VsurV0) / (3. * module_compressibilite )
int taille = d_hsurh0.Taille();
double fact1 = - jaco_1D_0 / (jaco_1D_tdt*jaco_1D_tdt) * exp_log_VsurV0 / (2. * hSurh_0);
double fact2 = (jaco_1D_0 / jaco_1D_tdt) * exp_log_VsurV0 / (3. * module_compressibilite / (2. * hSurh_0));
////---debug
//cout << "\n Calcul_d_eps33_parVarVolume() module_compressibilite= " << module_compressibilite
// << " log_VsurV0= "<< log_VsurV0
// << " sigBH.Trace()= " << sigBH.Trace()
// << " hSurh_0 =" << hSurh_0
// << "\n fact1 =" << fact1 << " fact2 =" << fact2;
//// --- fin debug
for (int i=1;i<=taille;i++)
{
Tenseur1HH & dsigHH = *((Tenseur1HH*) (d_sigHH(i))); // passage en dim 1
const Tenseur1BB & dgijBB = *((Tenseur1BB*)(d_gijBB_tdt(i))) ; // pour simplifier l'ecriture
Tenseur1BH d_sigBH = gijBB * dsigHH + dgijBB * sigHH;
d_hsurh0(i) = fact1 * d_jaco_1D(i) + fact2 * (d_sigBH.Trace());
//---debug
//cout << "\n Calcul_d_eps33_parVarVolume() "
// << " d_hsurh0("<< i<<")= "<< d_hsurh0(i);
// --- fin debug
};
// en isotrope les axes h et b sont équivalents
save_resul.d_bsurb0 = save_resul.d_hsurh0;
}
else
{ save_resul.hsurh0 = save_resul.bsurb0 = 1.;
save_resul.d_hsurh0.Zero();save_resul.d_bsurb0.Zero();
};
};
// calcul de la variation des déformations d'hauteur et de largeur, par rapport à la def_11, à cause
// des contraintes planes doubles: première méthode
void LoiContraintesPlanesDouble::Calcul_d_eps_eg_11()
{ // on prépare la résolution
// ,d_sig_ef_gh(2,2),d_eps_ef_11(2)
// la matrice
double a = d_sig_ef_gh(1,1) = d_sigma_deps_3D(2,2,2,2);
double b = d_sig_ef_gh(1,2) = d_sigma_deps_3D(2,2,3,3);
double c = d_sig_ef_gh(2,1) = d_sigma_deps_3D(3,3,2,2);
double d = d_sig_ef_gh(2,2) = d_sigma_deps_3D(3,3,3,3);
double determinant = a*d - b*c;
// //----- debug
// cout << "\n debug LoiContraintesPlanesDouble::Calcul_d_eps_eg_11() "<< "\n d_sig_ef_gh= ";
// d_sig_ef_gh.Affiche();
// //---fin debug
if (Dabs(determinant) > ConstMath::petit)
{ // le second membre
d_eps_ef_11(1)=-d_sigma_deps_3D(2,2,1,1);
d_eps_ef_11(2)=-d_sigma_deps_3D(3,3,1,1);
// //----- debug
// cout << "\n second membre= "<< d_eps_ef_11(1) << ", " << d_eps_ef_11(2);
// //---fin debug
// résolution
d_sig_ef_gh.Resol_systID(d_eps_ef_11);
// //----- debug
// cout << "\n solution= "<< d_eps_ef_11(1) << ", " << d_eps_ef_11(2);
// // vérif
// a = d_sig_ef_gh(1,1) = d_sigma_deps_3D(2,2,2,2);
// b = d_sig_ef_gh(1,2) = d_sigma_deps_3D(2,2,3,3);
// c = d_sig_ef_gh(2,1) = d_sigma_deps_3D(3,3,2,2);
// d = d_sig_ef_gh(2,2) = d_sigma_deps_3D(3,3,3,3);
// Vecteur truc(2);
// truc = d_sig_ef_gh * d_eps_ef_11;
// cout << "\n second membre correspondant "<< truc(1) << ", " << truc(2)<< flush;
// //---fin debug
}
else // sinon on met à 0
{d_eps_ef_11.Inita(0.);};
};
// calcul des invariants de déformation et de vitesse de déformation, et les def cumulées
// correspondant aux cas 3D: valable pour les 2 méthodes
void LoiContraintesPlanesDouble::Calcul_invariants_et_def_cumul()
{ // récup des infos spécifiques
SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul);
// recup de l'incrément de temps
double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant();
double unSurDeltat=0;
if (Abs(deltat) >= ConstMath::trespetit)
{unSurDeltat = 1./deltat;}
else
// si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand
{ // non un pas de temps doit être positif !! or certaine fois il peut y avoir des pb
if (unSurDeltat < 0)
{ cout << "\n le pas de temps est négatif !! "; };
unSurDeltat = ConstMath::tresgrand;
};
// ---calcul des invariants de déformation et de vitesse de déformation
Tenseur3BH espBH = eps_BB_3D * gijHH_tdt_3D;
Tenseur3BH delta_espBH = delta_eps_BB_3D * gijHH_tdt_3D;
save_resul.epsInvar(1) = espBH.Trace();
save_resul.epsInvar(2) = espBH.II();
save_resul.epsInvar(3) = espBH.Det();
save_resul.depsInvar(1) = unSurDeltat * delta_espBH.Trace();
save_resul.depsInvar(2) = unSurDeltat * delta_espBH.II();
save_resul.depsInvar(3) = unSurDeltat * delta_espBH.Det();
// cas des grandeurs cumulées (cf. la classe Deformation)
// tableau relatif aux différentes grandeurs de type def scalaires équivalentes
// def_equi(1) = deformation cumulée = somme des sqrt(2./3. * (delta_eps_barre_BH && delta_eps_barre_BH)) ;
// def_equi(2) = deformation duale de la contrainte de mises = sqrt(2./3. * (eps_barre_BH && eps_barre_BH)) ;
// def_equi(3) = niveau maxi atteind par def_equi(2)
// def_equi(4) = delta def cumulée = sqrt(2./3. * (delta_eps_barre_BH && delta_eps_barre_BH));
double delta_eps_equi = sqrt(2./3. * ( (delta_espBH && delta_espBH) - Sqr(delta_espBH.Trace()) /3. ));
save_resul.def_equi(1) = save_resul.def_equi_t(1) + delta_eps_equi ;
save_resul.def_equi(2) = sqrt(2./3. * (espBH && espBH)) ;
if (save_resul.def_equi(2) > save_resul.def_equi_t(3))
save_resul.def_equi(3) = save_resul.def_equi(2);
save_resul.def_equi(4) = delta_eps_equi;
};
// calcul de la fonction résidu de la résolution de l'équation constitutive: sig^ef(h/h0,b/b0) = 0
// avec "e,f" = 2 et 3
// h/h0, bb0 sont les inconnues du problème et sont l'élément d'entrée: <x(1),x(2)>
// l'argument test ramène
// . 1 si le calcul a été ok, -1 s'il y a eu un pb, mais on peut continuer, 0 s'il y a eu un pb
// fatal, qui invalide le calcul du résidu
Vecteur& LoiContraintesPlanesDouble::Residu_constitutif (const double & alpha,const Vecteur & x, int& test)
{
// récup du conteneur spécifique
SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul);
test = 1; // init par défaut
// %%% on met à jour les conteneurs locaux en fonction des paramètres d'entrée %%%
// -- prise en compte de la variation de la déformation d'épaisseur
// pour nous ici on travaille avec giB_03D qui est normé et = 1 c-a-d h0 = 1
// donc à tdt il faut multiplier par h/h0 à tdt
double bsurb0 = x(1);double hsurh0 = x(2);
// vérif des grandeurs
bool erreur_sortie = false; // pour gestion de sortie d'infos supplémentaires
if (Limitation_h_b(hsurh0,bsurb0))
{if (Permet_affichage() > 3)
cout << "\n LoiContraintesPlanesDouble::Residu_constitutif(... " << endl;
erreur_sortie = true;
test = -1; // l'erreur n'est pas fatale mais elle signifie que ce n'est pas très normal !!
};
if (erreur_sortie && (Permet_affichage() > 4))
{cout << "\n giH_tdt: " << *(umat_cont_3D->giH_tdt);
cout << "\n defBB: ";eps_BB_3D.Ecriture(cout);
cout << "\n DepsBB: ";Deps_BB_3D.Ecriture(cout);
};
save_resul.hsurh0 = hsurh0; // sauvegarde de l'élongation d'épaisseur
save_resul.bsurb0 = bsurb0; // sauvegarde de l'élongation de largeur
CoordonneeB & giBtdt_2 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(2); // pour simplifier
CoordonneeB & giBtdt_3 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(3); // pour simplifier
giB_tdt_3D.CoordoB(3) = giBtdt_3 * hsurh0; giH_tdt_3D.CoordoH(3) = (giBtdt_3 / hsurh0).Bas_haut();
giB_tdt_3D.CoordoB(2) = giBtdt_2 * bsurb0; giH_tdt_3D.CoordoH(2) = (giBtdt_2 / bsurb0).Bas_haut();
// - et les tenseurs métriques à t et tdt, comme les vecteurs en épaisseurs
// et en largeurs sont normées initialement, seule l'intensité
// des normales est à mettre à jour compte tenue de la variation d'épaisseurs et de largeur
double hsurh0_2 = hsurh0 * hsurh0;
gijBB_tdt_3D.Coor(3,3) = hsurh0_2; gijHH_tdt_3D.Coor(3,3) = 1. / hsurh0_2;
double bsurb0_2 = bsurb0 * bsurb0;
gijBB_tdt_3D.Coor(2,2) = bsurb0_2; gijHH_tdt_3D.Coor(2,2) = 1. / bsurb0_2;
// mise à jour des informations liées à la déformation de 1 vers 3
Mise_a_jour_deformations_et_Jacobien_en_3D();
// calcul des invariants de déformation et de vitesse de déformation, et les def cumulées
// correspondant aux cas 3D
Calcul_invariants_et_def_cumul();
// initialisation du comportement tangent / au def
d_sigma_deps_3D.Inita(0.);
// appel du calcul de sig et dsig
bool en_base_orthonormee = false; // ici les tenseurs ne sont pas forcément en orthonormee
lois_interne->Calcul_dsigma_deps (en_base_orthonormee, sig_HH_t_3D,Deps_BB_3D,eps_BB_3D
,delta_eps_BB_3D,jacobien_0_3D,jacobien_tdt_3D
,sig_HH_3D,d_sigma_deps_3D
,save_resul.l_energ,save_resul.l_energ_t,module_compressibilite_3D
,module_cisaillement_3D,*umat_cont_3D);
// retour des grandeurs voulues
residu(1) = sig_HH_3D(2,2);
residu(2) = sig_HH_3D(3,3);
return residu;
};
// calcul de la matrice tangente de la résolution de l'équation constitutive: sig^ef(h/h0,b/b0) = 0
// avec "e,f" = 2 et 3
// h/h0, bb0 sont les inconnues du problème et sont l'élément d'entrée: <x(1),x(2)>
// l'argument test ramène
// . 1 si le calcul a été ok, -1 s'il y a eu un pb, mais on peut continuer, 0 s'il y a eu un pb
// fatal, qui invalide le calcul du résidu et de la dérivée
Mat_abstraite& LoiContraintesPlanesDouble::Mat_tangente_constitutif
(const double & alphap,const Vecteur & x, Vecteur& residu, int& test)
{
// récup du conteneur spécifique
SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul);
test = 1; // init par défaut
// %%% on met à jour les conteneurs locaux en fonction des paramètres d'entrée %%%
// -- prise en compte de la variation de la déformation d'épaisseur et de largeur
// pour nous ici on travail avec giB_03D qui est normé et = 1 c-a-d h0 = b0 = 1
// donc à tdt il faut multiplier par h/h0 à tdt et idem pour b/b0
double bsurb0 = x(1);double hsurh0 = x(2);
// vérif des grandeurs
bool erreur_sortie = false; // pour gestion de sortie d'infos supplémentaires
if (Limitation_h_b(hsurh0,bsurb0))
{if (Permet_affichage() > 3)
cout << "\n LoiContraintesPlanesDouble::Mat_tangente_constitutif(... " << endl;
erreur_sortie = true;
test = -1; // l'erreur n'est pas fatale mais elle signifie que ce n'est pas très normal !!
};
if (erreur_sortie && (Permet_affichage() > 4))
{cout << "\n giH_tdt: " << *(umat_cont_3D->giH_tdt);
cout << "\n defBB: ";eps_BB_3D.Ecriture(cout);
cout << "\n DepsBB: ";Deps_BB_3D.Ecriture(cout);
};
save_resul.hsurh0 = hsurh0; // sauvegarde de l'élongation d'épaisseur
save_resul.bsurb0 = bsurb0; // sauvegarde de l'élongation de largeur
CoordonneeB & giBtdt_2 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(2); // pour simplifier
CoordonneeB & giBtdt_3 = (*(save_resul.meti_ref_tdt.giB_)).CoordoB(3); // pour simplifier
giB_tdt_3D.CoordoB(3) = giBtdt_3 * hsurh0;
giH_tdt_3D.CoordoH(3) = (giBtdt_3 / hsurh0).Bas_haut();
giB_tdt_3D.CoordoB(2) = giBtdt_2 * bsurb0;
giH_tdt_3D.CoordoH(2) = (giBtdt_2 / bsurb0).Bas_haut();
// - et les tenseurs métriques à t et tdt, comme les vecteurs en épaisseurs sont normées initialement, seule l'intensité
// des normales est à mettre à jour compte tenue de la variation d'épaisseurs
double hsurh0_2 = hsurh0 * hsurh0;
gijBB_tdt_3D.Coor(3,3) = hsurh0_2;
gijHH_tdt_3D.Coor(3,3) = 1. / hsurh0_2;
double bsurb0_2 = bsurb0 * bsurb0;
gijBB_tdt_3D.Coor(2,2) = bsurb0_2;
gijHH_tdt_3D.Coor(2,2) = 1. / bsurb0_2;
// mise à jour des informations liées à la déformation de 1 vers 3
Mise_a_jour_deformations_et_Jacobien_en_3D();
// calcul des invariants de déformation et de vitesse de déformation, et les def cumulées
// correspondant aux cas 3D
Calcul_invariants_et_def_cumul();
// initialisation du comportement tangent / au def
d_sigma_deps_3D.Inita(0.);
// appel du calcul de sig et dsig
bool en_base_orthonormee = false; // ici les tenseurs ne sont pas a priori en orthonormee
lois_interne->Calcul_dsigma_deps (en_base_orthonormee, sig_HH_t_3D,Deps_BB_3D,eps_BB_3D
,delta_eps_BB_3D,jacobien_0_3D,jacobien_tdt_3D
,sig_HH_3D,d_sigma_deps_3D
,save_resul.l_energ,save_resul.l_energ_t,module_compressibilite_3D
,module_cisaillement_3D,*umat_cont_3D);
// retour des grandeurs voulues
residu(1) = sig_HH_3D(2,2);
residu(2) = sig_HH_3D(3,3);
// la matrice tangente dépend du type de mesure de déformation, avec la relation
// en appelant hb/hb0 les deux ddl: h/h0 et b/b0, i,j,k et l variant de 2 à 3
// d_sig^ij(h/h0,b/b0) / d_ddl = d_sig^ij(h/h0,b/b0)/d_eps_kl * d_eps_kl/d_ddl
// comme les repères restent orthogonales à tous moments il n'y a pas de couplage entre les directions 2 et 3
Vecteur d_eps_kl_sur_d_ddl(2,0.); // init
// -- choix en fonction du type de déformation
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), en orthonormee
// dans le repère local: epsBB33 = 1/2 * (h^2 - 1.), or h0=1. donc : epsBB33 = 1/2 * ((h/h0)^2 - 1.)
// idem pour la direction 22
d_eps_kl_sur_d_ddl(1) = bsurb0;d_eps_kl_sur_d_ddl(2) = hsurh0;
};
break;
case DEFORMATION_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEFORMATION_CUMU_LOGARITHMIQUE :
// cas d'une def logarithmique ou une approximation: eps_BB_3D(3,3) = log(hsurh0);
{ d_eps_kl_sur_d_ddl(1) = log(bsurb0);d_eps_kl_sur_d_ddl(2) = log(hsurh0);
};
break;
default :
cout << "\nErreur : type de deformation qui n'est pas actuellement pris en compte, type= "
<< Nom_type_deformation(type_de_deformation);
cout << "\n LoiContraintesPlanesDouble::Mat_tangente_constitutif \n";
Sortie(1);
};
// d'où la dérivée du résidu, en considérant qu'il n'y a pas de couplage entre les directions 2 et 3
// c-a-d d_eps33_sur_d_bSurb0 = 0 et d_eps22_sur_d_hSurh0 = 0
// non c'est faux, du à la partie sphérique des contraintes par exemple, il faut tout considérer
derResidu(1,1) = d_sigma_deps_3D(2,2,2,2) * d_eps_kl_sur_d_ddl(1);
derResidu(1,2) = d_sigma_deps_3D(2,2,3,3) * d_eps_kl_sur_d_ddl(2);
derResidu(2,1) = d_sigma_deps_3D(3,3,2,2) * d_eps_kl_sur_d_ddl(1);
derResidu(2,2) = d_sigma_deps_3D(3,3,3,3) * d_eps_kl_sur_d_ddl(2);
return derResidu;
};
//--- cas de la résolution de l'équation sigij(eps_meca)*V_j{.l}=0, l=2 et 3
// calcul de la fonction résidu de la résolution de l'équation constitutive
// l'argument test ramène
// . 1 si le calcul a été ok, -1 s'il y a eu un pb, mais on peut continuer, 0 s'il y a eu un pb
// fatal, qui invalide le calcul du résidu
Vecteur& LoiContraintesPlanesDouble::Residu_constitutif_3D(const double & alpha,const Vecteur & x, int& test)
{
// récup du conteneur spécifique
SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul);
test = 1; // init par défaut
//récup de eps_mecaBB_t
Tenseur3BB& eps_mecaBB_t = *((Tenseur3BB*) (save_resul.eps_mecaBB_t));
// les inconnues sont les déformations mécaniques {epsilon'}_kl;
// (k,l) = (22) (33) (12) : on a donc 3 inconnues que l'on suppose rangées dans cette ordre
// c-a-d les def qui vont servir dans l'appel de la loi 3D
eps_P_BB.Coor(1,2) = x(3);eps_P_BB.Coor(2,2) = x(1);eps_P_BB.Coor(3,3) = x(2);
eps_P_BB.Coor(1,3) = 0.; eps_P_BB.Coor(2,3) = 0.;
if (Permet_affichage() > 4)
{cout << "\n eps_P_BB (dans Va) avant limitation : " ;eps_P_BB.Ecriture(cout);}
// vérif des grandeurs et calcul des variations d'épaisseur et de largeur
double& hsurh0 = save_resul.hsurh0;double& bsurb0 = save_resul.bsurb0;
// la méthode va mettre à jour les variations bsurb0 et hsurh0 et le jacobien
bool erreur_sortie = false; // pour gestion de sortie d'infos supplémentaires
int info_limit = Calcul_et_Limitation2_h_b(hsurh0,eps_P_BB,bsurb0,jacobien_tdt_3D,jacobien_0_3D);
if (info_limit)
{if (Permet_affichage() > 3)
cout << "\n LoiContraintesPlanesDouble::Residu_constitutif_3D(... " << endl;
erreur_sortie = true;test = info_limit - 2;
};
if (erreur_sortie && (Permet_affichage() > 4))
{cout << "\n giH_tdt: " << *(umat_cont_3D->giH_tdt);
cout << "\n eps_BB_3D: ";eps_BB_3D.Ecriture(cout);
cout << "\n DepsBB: ";Deps_BB_3D.Ecriture(cout);
cout << "\n x(1)= "<< x(1) << " x(2)= "<< x(2) << " x(3)= "<< x(3) << flush;
};
// dans la direction V_1 c'est la déformation issue de la cinématique
// elle a déjà été calculée, et les autres composantes demeurent nulle
// donc eps_P_BB est au complet,
eps_BB_3D=eps_P_BB; // recopie dans eps_BB_3D: là on est dans le repère V_a
eps_BB_3D.ChBase(beta3D); // changement de base, là on est dans le repère g^i
// on s'occupe maintenant de l'incrément de déformation
delta_eps_BB_3D = eps_BB_3D - eps_mecaBB_t;
// au cas où, on impose (normalement c'est inutile) que les composantes 13 et 23 sont nulles
delta_eps_BB_3D.Coor(1,3) = 0.; delta_eps_BB_3D.Coor(2,3) = 0.;
// recup de l'incrément de temps
double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant();
double unSurDeltat;
if (Abs(deltat) >= ConstMath::trespetit)
{unSurDeltat = 1./deltat;}
else
// si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand
{ // un pas de temps doit être positif !! or certaine fois il peut y avoir des pb
#ifdef MISE_AU_POINT
if (unSurDeltat < 0)
{ cout << "\n le pas de temps est négatif !! "
<< "\n LoiContraintesPlanesDouble::Residu_constitutif_3D(...";
};
#endif
unSurDeltat = ConstMath::tresgrand;
};
// ici on considère que la déformation est de type Almansi
Deps_BB_3D = delta_eps_BB_3D * unSurDeltat;
// calcul des invariants de déformation et de vitesse de déformation, et les def cumulées
// correspondant aux cas 3D
Calcul_invariants_et_def_cumul();
/* // --- on s'occupe des jacobiens
// à tdt le jacobien est calculée à partir de la déformation supposée d'Almansi
// ici il s'agit du jacobien relatif au comportement mécanique
// |J| = sqrt(det(2 * eps_ij + g_ij(0)))
// calcul de la matrice correspondante à (2 * eps_ij + g_ij(0))
gij_meca_BB = (2. * eps_BB_3D + (*(umat_cont_3D->gijBB_0)));
gij_meca_BB.Matrice_composante(mat_inter);
// calcul du jacobien
jacobien_tdt_3D = sqrt(Dabs(mat_inter.Determinant()));
*/
// initialisation du comportement tangent / au def
d_sigma_deps_3D.Inita(0.);
// appel du calcul de sig et dsig
bool en_base_orthonormee = false; // ici les tenseurs ne sont pas en orthonormee
// car on travaille dans la base naturelle
#ifdef MISE_AU_POINT
if (Permet_affichage() > 8)
{cout << "\n LoiContraintesPlanesDouble::Residu_constitutif_3D(..."
<< "\n giH_tdt: " << *(umat_cont_3D->giH_tdt);
cout << "\n defBB: ";eps_BB_3D.Ecriture(cout);
cout << "\n DepsBB: ";Deps_BB_3D.Ecriture(cout);
cout << "\n x(1)= "<< x(1) << " x(2)= "<< x(2) << " x(3)= "<< x(3) ;
// en base orthonormee
Tenseur3BB epsBB_3D_inter;
eps_BB_3D.BaseAbsolue(epsBB_3D_inter,*(umat_cont_3D->giH_tdt));
cout << "\n eps_BB_3D en absolue 3D (dans Va): "<<epsBB_3D_inter;
cout << "\n jacobien_tdt_3D= "<< jacobien_tdt_3D
<< "\n jacobien_0= " << jacobien_0_3D
<< flush;
};
#endif
lois_interne->Calcul_dsigma_deps (en_base_orthonormee, sig_HH_t_3D,Deps_BB_3D,eps_BB_3D
,delta_eps_BB_3D,jacobien_0_3D,jacobien_tdt_3D
,sig_HH_3D,d_sigma_deps_3D
,save_resul.l_energ,save_resul.l_energ_t,module_compressibilite_3D
,module_cisaillement_3D,*umat_cont_3D);
#ifdef MISE_AU_POINT
if (Permet_affichage() > 8)
{cout << "\n sig_HH_3D: " << sig_HH_3D;
cout << "\n d_sigma_deps_3D: "<< d_sigma_deps_3D << flush;
};
#endif
//-------- calcul du residu -----------
// residu(mi) = V_{mj} * \sigma^{ij}(\epsilon'_{kl}) : m=2 et 3
CoordonneeH V_sig_H(sig_HH_3D * (*ViB_3D)(2));
// on considère que les densités d'effort interne dans le plan, la composante 23 devant
// être nulle compte tenu du tenseur des déformations
// residu_3D(1) = V_sig_H(1);residu_3D(3) = V_sig_H(2);
residu_3D(1) = V_sig_H * (*ViB_3D)(2); // composante 22
residu_3D(3) = (*ViB_3D)(1) * V_sig_H ; // composante 12
// essai avec le mixte
// residu_3D(3) = 0.5 * ((*ViB_3D)(1) * V_sig_H + V_sig_H * (*ViB_3D)(1)); // composante 12
#ifdef MISE_AU_POINT
if (Permet_affichage() > 8)
{cout << "\n en g_i: sig_HH * ViB(2)= " << V_sig_H
<< " df_ds_22= " << residu_3D(1) << " df_ds_21= " << residu_3D(3)
<< flush;
};
#endif
V_sig_H = sig_HH_3D * (*ViB_3D)(3);
// residu_3D(2) = V_sig_H(3); // seule la composante dans la direction 3 est utilisée
residu_3D(2) = V_sig_H * (*ViB_3D)(3); // composante 33
#ifdef MISE_AU_POINT
if (Permet_affichage() > 8)
{cout << "\n en g_i: sig_HH * ViB(3)= " << V_sig_H << " df_ds_33= " << residu_3D(2);
// pour info on calcul la projection symétrique
double f_12 = (*ViB_3D)(1)* sig_HH_3D * (*ViB_3D)(2);
cout << " df_ds_12= " << f_12 << flush;
};
#endif
return residu_3D;
};
//--- cas de la résolution de l'équation sigij(eps_meca)*V_j{.l}=0, l=2 et 3
// calcul de la matrice tangente de la résolution de l'équation constitutive
// l'argument test ramène
// . 1 si le calcul a été ok, -1 s'il y a eu un pb, mais on peut continuer, 0 s'il y a eu un pb
// fatal, qui invalide le calcul du résidu et de la dérivée
Mat_abstraite& LoiContraintesPlanesDouble::Mat_tangente_constitutif_3D
(const double & alphap,const Vecteur & x, Vecteur& residu_local, int& test)
{
// récup du conteneur spécifique
SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul);
test = 1; // init par défaut
//récup de eps_mecaBB_t
Tenseur3BB& eps_mecaBB_t = *((Tenseur3BB*) (save_resul.eps_mecaBB_t));
// les inconnues sont les déformations mécaniques {epsilon'}_kl;
// (k,l) = (22) (33) (12) : on a donc 3 inconnues que l'on suppose rangées dans cette ordre
// c-a-d les def qui vont servir dans l'appel de la loi 3D
eps_P_BB.Coor(1,2) = x(3);eps_P_BB.Coor(2,2) = x(1);eps_P_BB.Coor(3,3) = x(2);
eps_P_BB.Coor(1,3) = 0.; eps_P_BB.Coor(2,3) = 0.;
// vérif des grandeurs et calcul des variations d'épaisseur et de largeur
double& hsurh0 = save_resul.hsurh0;double& bsurb0 = save_resul.bsurb0;
// la méthode va mettre à jour les valeurs de bsurb0 et hsurh0, et le jacobien
bool erreur_sortie = false; // pour gestion de sortie d'infos supplémentaires
if (Permet_affichage() > 4)
{cout << "\n eps_P_BB (dans Va) avant limitation : " ;eps_P_BB.Ecriture(cout);};
int info_limit = Calcul_et_Limitation2_h_b(hsurh0,eps_P_BB,bsurb0,jacobien_tdt_3D,jacobien_0_3D);
if (info_limit)
{if (Permet_affichage() > 3)
cout << "\n LoiContraintesPlanesDouble::Mat_tangente_constitutif_3D(... " << endl;
erreur_sortie = true;test = info_limit - 2;
};
if (erreur_sortie && (Permet_affichage() > 4))
{cout << "\n giH_tdt: " << *(umat_cont_3D->giH_tdt);
cout << "\n defBB: ";eps_BB_3D.Ecriture(cout);
cout << "\n DepsBB: ";Deps_BB_3D.Ecriture(cout);
cout << "\n x(1)= "<< x(1) << " x(2)= "<< x(2) << " x(3)= "<< x(3) << flush;
};
// dans la direction V_1 c'est la déformation issue de la cinématique
// elle a déjà été calculée, et les autres composantes demeurent nulle
// donc eps_P_BB est au complet,
eps_BB_3D=eps_P_BB; // recopie dans eps_BB_3D: là on est dans le repère V_a
eps_BB_3D.ChBase(beta3D); // changement de base, là on est dans le repère g^i
// on s'occupe maintenant de l'incrément de déformation
delta_eps_BB_3D = eps_BB_3D - eps_mecaBB_t;
// au cas où, on impose (normalement c'est inutile) que les composantes 13 et 23 sont nulles
delta_eps_BB_3D.Coor(1,3) = 0.; delta_eps_BB_3D.Coor(2,3) = 0.;
// recup de l'incrément de temps
double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant();
double unSurDeltat;
if (Abs(deltat) >= ConstMath::trespetit)
{unSurDeltat = 1./deltat;}
else
// si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand
{ // un pas de temps doit être positif !! or certaine fois il peut y avoir des pb
#ifdef MISE_AU_POINT
if (unSurDeltat < 0)
{ cout << "\n le pas de temps est négatif !! "
<< "\n LoiContraintesPlanesDouble::Mat_tangente_constitutif_3D(...";
};
#endif
unSurDeltat = ConstMath::tresgrand;
};
// ici on considère que la déformation est de type Almansi
Deps_BB_3D = delta_eps_BB_3D * unSurDeltat;
// calcul des invariants de déformation et de vitesse de déformation, et les def cumulées
// correspondant aux cas 3D
Calcul_invariants_et_def_cumul();
/* // --- on s'occupe des jacobiens
// à t=0 on considère que c'est le même jacobien que transmis
jacobien_0_3D = *(umat_cont_3D->jacobien_0);
// à tdt le jacobien est calculée à partir de la déformation supposée d'Almansi
// ici il s'agit du jacobien relatif au comportement mécanique
// |J| = sqrt(det(2 * eps_ij + g_ij(0)))
// calcul de la matrice correspondante à (2 * eps_ij + g_ij(0))
gij_meca_BB = (2. * eps_BB_3D + (*(umat_cont_3D->gijBB_0)));
gij_meca_BB.Matrice_composante(mat_inter);
// calcul du jacobien
jacobien_tdt_3D = sqrt(Dabs(mat_inter.Determinant()));
*/
// initialisation du comportement tangent / au def
d_sigma_deps_3D.Inita(0.);
// appel du calcul de sig et dsig
bool en_base_orthonormee = false; // ici les tenseurs ne sont pas a priori en orthonormee
#ifdef MISE_AU_POINT
if (Permet_affichage() > 8)
{cout << "\n LoiContraintesPlanesDouble::Mat_tangente_constitutif_3D(..."
<< "\n giH_tdt: " << *(umat_cont_3D->giH_tdt);
cout << "\n defBB: ";eps_BB_3D.Ecriture(cout);
cout << "\n DepsBB: ";Deps_BB_3D.Ecriture(cout);
cout << "\n x(1)= "<< x(1) << " x(2)= "<< x(2) << " x(3)= "<< x(3) ;
// en base orthonormee
Tenseur3BB epsBB_3D_inter;
eps_BB_3D.BaseAbsolue(epsBB_3D_inter,*(umat_cont_3D->giH_tdt));
cout << "\n eps_BB_3D en absolue 3D (dans Va): "<<epsBB_3D_inter;
cout << "\n jacobien_tdt_3D= "<< jacobien_tdt_3D
<< "\n jacobien_0= " << jacobien_0_3D
<< flush;
};
#endif
lois_interne->Calcul_dsigma_deps (en_base_orthonormee, sig_HH_t_3D,Deps_BB_3D,eps_BB_3D
,delta_eps_BB_3D,jacobien_0_3D,jacobien_tdt_3D
,sig_HH_3D,d_sigma_deps_3D
,save_resul.l_energ,save_resul.l_energ_t,module_compressibilite_3D
,module_cisaillement_3D,*umat_cont_3D);
#ifdef MISE_AU_POINT
if (Permet_affichage() > 8)
{cout << "\n sig_HH_3D: " << sig_HH_3D;
cout << "\n d_sigma_deps_3D: "<< d_sigma_deps_3D << flush;
};
#endif
//-------- calcul du residu -----------
// residu(mi) = V_{mj} * \sigma^{ij}(\epsilon'_{kl}) : m=2 et 3
//residu(1) = V_2 . \sigma . V_2 = V_{2i} ~\sigma^{ij} ~V_{2j} = ( V_2 \otimes V_2) : \sigma
//residu(2) = V_3 . \sigma . V_3 = V_{3i} ~\sigma^{ij} ~V_{3j} = ( V_3 \otimes V_3) : \sigma
//residu(3) = V_1 . \sigma . V_2 = V_{1i} ~\sigma^{ij} ~V_{2j} = ( V_1 \otimes V_2) : \sigma
CoordonneeH V_sig_H(sig_HH_3D * (*ViB_3D)(2)); // = \sigma . V_2
// ici on utilise le vecteur passé en argument
residu_local(1) = V_sig_H * (*ViB_3D)(2); // composante 22 = V_2 . \sigma . V_2
// residu(3) = V_sig_H * (*ViB_3D)(1); // composante 21
residu_local(3) = (*ViB_3D)(1) * V_sig_H ; // composante 12 = V_1 . \sigma . V_2
// essai avec le mixte
// residu_local(3) = 0.5 * ((*ViB_3D)(1) * V_sig_H + V_sig_H * (*ViB_3D)(1)); // composante 12
#ifdef MISE_AU_POINT
if (Permet_affichage() > 8)
{cout << "\n en g_i: sig_HH * ViB(2)= " << V_sig_H
<< " df_ds_22= " << residu_3D(1) << " df_ds_21= " << residu_3D(3)
<< flush;
};
#endif
V_sig_H = sig_HH_3D * (*ViB_3D)(3); // = \sigma . V_3
residu_local(2) = V_sig_H * (*ViB_3D)(3); // composante 33 = V_3 . \sigma . V_3
#ifdef MISE_AU_POINT
if (Permet_affichage() > 8)
{cout << "\n en g_i: sig_HH * ViB(3)= " << V_sig_H << " df_ds_33= " << residu_3D(2);
// pour info on calcul la projection symétrique
double f_12 = (*ViB_3D)(1)* sig_HH_3D * (*ViB_3D)(2);
cout << " df_ds_12= " << f_12 << flush;
};
#endif
// calcul de la matrice tangente
// formule générique
//\frac{\partial \left( \sigma^{ij}(\epsilon'_{kl}) ~ V_{mj} \right )}{\partial \epsilon'_{rs}}
// = V_{mj}~\frac{\partial \sigma^{ij}(\epsilon_{kl}) }{\partial \epsilon_{op}}~V^r_{~.o}~ V^s_{~.p}
// ici on doit utiliser uniquement:
//\frac{\partial \left( \sigma^{3j}(\epsilon'_{kl}) ~ V_{3j} \right ) }{\partial \epsilon'_{rs}}
//\frac{\partial \left( \sigma^{\alpha j}(\epsilon'_{kl}) ~ V_{2j} \right ) }{\partial \epsilon'_{rs}}
// avec \alpha =1,2 ; (k,l) et (r,s) } = (2,2) ; (3,3) ; (1,2)
// d (V_{mi} ~\sigma^{ij} ~V_{nj} \right ) / d \epsilon'_{gh}
// = V_{mi}~V_{nj}~ d \sigma^{ij} / d \epsilon_{op} ~V^r_{~.o}~ V^s_{~.p}
// pour (m,n) et (g,h) = (2,2); (3,3); et (1,2)
derResidu_3D.Initialise(0.); // init
// for (int j=1;j<4;j++) // j représente la composante de l'axe de projection
// { for (int i=1;i<4;i++) // i représente le classement de (\epsilon'_{kl})
// // i= 1 pour (k,l) = (2,2), i=2 pour (k,l) = (3,3), i=3 pour (k,l) = (1,2)
// {// d (sig(2,j) V(2)(j)) / d (eps')(k,l)
// derResidu_3D(1,i) += (*ViB_3D)(2)(j) *
// (d_sigma_deps_3D(2,j,1,1) * (*ViH_3D)(indx(i))(1) * (*ViH_3D)(indy(i))(1)
// + d_sigma_deps_3D(2,j,1,2) * (*ViH_3D)(indx(i))(1) * (*ViH_3D)(indy(i))(2)
// + d_sigma_deps_3D(2,j,2,1) * (*ViH_3D)(indx(i))(2) * (*ViH_3D)(indy(i))(1)
// + d_sigma_deps_3D(2,j,3,3) * (*ViH_3D)(indx(i))(3) * (*ViH_3D)(indy(i))(3)
// );
// // d (sig(1,j) V(2)(j)) / d (eps')(k,l)
// derResidu_3D(3,i) += (*ViB_3D)(2)(j) *
// (d_sigma_deps_3D(1,j,1,1) * (*ViH_3D)(indx(i))(1) * (*ViH_3D)(indy(i))(1)
// + d_sigma_deps_3D(1,j,1,2) * (*ViH_3D)(indx(i))(1) * (*ViH_3D)(indy(i))(2)
// + d_sigma_deps_3D(1,j,2,1) * (*ViH_3D)(indx(i))(2) * (*ViH_3D)(indy(i))(1)
// + d_sigma_deps_3D(1,j,3,3) * (*ViH_3D)(indx(i))(3) * (*ViH_3D)(indy(i))(3)
// );
// // d (sig(3,j) V(2)(j)) / d (eps')(k,l)
// derResidu_3D(2,i) += (*ViB_3D)(3)(j) *
// (d_sigma_deps_3D(3,j,1,1) * (*ViH_3D)(indx(i))(1) * (*ViH_3D)(indy(i))(1)
// + d_sigma_deps_3D(3,j,1,2) * (*ViH_3D)(indx(i))(1) * (*ViH_3D)(indy(i))(2)
// + d_sigma_deps_3D(3,j,2,1) * (*ViH_3D)(indx(i))(2) * (*ViH_3D)(indy(i))(1)
// + d_sigma_deps_3D(3,j,3,3) * (*ViH_3D)(indx(i))(3) * (*ViH_3D)(indy(i))(3)
// );
//
// };
// };
// pour (m,n) et (g,h) = (2,2); (3,3); et (1,2)
// d (V_{mi} ~\sigma^{ij} ~V_{nj} ) / d\epsilon'_{gh} =
// (V_{mi} V_{nj}) (d \sigma^{ij} / d \epsilon_{op}) (V^g_{~.o} V^h_{~.p})
// pour 2,2 et 3,3 pas de pb de symétrie
// pour 1,2
for (int mn=1;mn<4;mn++) // mn représente la composante de l'axe de projection
{// d'abord les termes diagonaux
for (int gh=1;gh<3;gh++) // gh représente le classement de (\epsilon'_{gh})
derResidu_3D(mn,gh) = VhVg_BB(mn) && (d_sigma_deps_3D && VhVg_BB(gh));
// maintenant les termes non diagonaux à doubler
derResidu_3D(mn,3) = 2.* VhVg_BB(mn) && (d_sigma_deps_3D && VhVg_BB(3));
};
return derResidu_3D;
};
// limitation des variations d'épaisseurs et largeurs
// ramène true s'il y a eu une modif: sert pour la méthode 1
bool LoiContraintesPlanesDouble::Limitation_h_b(double& hsurh0, double& bsurb0)
{ bool retour = false;
// il ne faut pas que la nouvelle épaisseur soit inf au mini
if (hsurh0 < mini_hsurh0)
{if (Permet_affichage() > 3)
{cout << "\n *** attention hsurh0 " << hsurh0 << ", est inferieur a la limite fixee "<<mini_hsurh0
<< " on le ramene a la limite ";
};
hsurh0 = mini_hsurh0;retour = true;
};
// il ne faut pas que la nouvelle largeur soit inf au mini
if (bsurb0 < mini_bsurb0)
{if (Permet_affichage() > 3)
{cout << "\n *** attention bsurb0 " << bsurb0 << ", est inferieur a la limite fixee "<<mini_bsurb0
<< " on le ramene a la limite ";
};
bsurb0 = mini_bsurb0;retour = true;
};
// on regarde également pour les maxi
if (hsurh0 > maxi_hsurh0)
{if (Permet_affichage() > 3)
{cout << "\n *** attention hsurh0 " << hsurh0 << ", est superieur a la limite fixee "<<maxi_hsurh0
<< " on le ramene a la limite ";
};
hsurh0 = maxi_hsurh0;retour = true;
};
if (bsurb0 > maxi_bsurb0)
{if (Permet_affichage() > 3)
{cout << "\n *** attention bsurb0 " << bsurb0 << ", est superieur a la limite fixee "<<maxi_bsurb0
<< " on le ramene a la limite ";
};
bsurb0 = maxi_bsurb0;retour = true;
};
// retour
return retour;
};
// calcul de l'opérateur tangent (2ième méthode)
// d sigma^{ij} / d epsilon_{kl}
void LoiContraintesPlanesDouble::Calcul2_dsigma_deps(TenseurHHHH& d_sigma_deps)
{
#ifdef MISE_AU_POINT
if (Permet_affichage() > 8)
{ cout << "\n dans le repere locale d_sigma_deps_3D= \n";
int e=1;
for (int i=1;i<4;i++) for (int j=1;j<4;j++) for (int k=1;k<4;k++)for (int l=1;l<4;l++,e++)
{ cout << "("<<i<<","<<j<<","<<k<<","<<l<<")= "<<d_sigma_deps_3D(i,j,k,l) << " ; ";
if (e>6) {cout << "\n"; e=1;}
};
Tenseur3HHHH inter_HHHH;
d_sigma_deps_3D.ChangeBase(inter_HHHH,giB_tdt_3D);
cout << "\n dans le repere orthonormee d_sigma_deps_3D= \n";
e=1;
for (int i=1;i<4;i++) for (int j=1;j<4;j++) for (int k=1;k<4;k++)for (int l=1;l<4;l++,e++)
{ cout << "("<<i<<","<<j<<","<<k<<","<<l<<")= "<<inter_HHHH(i,j,k,l) << " ; ";
if (e>6) {cout << "\n"; e=1;}
};
};
#endif
// on calcule deux grandeurs intermédiaires
// a) d sigma^{ij} / d epsilon_{o'p'}(3D)~~V^1_{~.o'}~ V^1_{~.p'}
// on récupère que le pointeur, ce qui évite d'utiliser l'opérateur de copie du tenseur
// !!!!**** a vérifier -> oui c'est ok
// const Tenseur3BB & epsBB = *((Tenseur3BB*) &epsBB_tdt); // passage en dim 3
Tenseur3HH dSigDeps11P_HH(d_sigma_deps_3D && V1V1_BB);
#ifdef MISE_AU_POINT
if (Permet_affichage() > 7)
{ cout << "\n (*ViB_3D)(1)= "<<(*ViB_3D)(1);
cout << "\n V1V1_BB: "<< V1V1_BB
<< "\n dSigDeps11P_HH: "<< dSigDeps11P_HH
<< flush;
};
#endif
// b) d sigma^{ij} / d epsilon_{o'p'}(3D)~~V^g_{~.o'}~ V^h_{~.p'}
Tableau <Tenseur3HH* > dsigdeps_gh_P(3);
for (int gh=1;gh<4;gh++)
{dsigdeps_gh_P(gh) = ((Tenseur3HH*) &( d_sigma_deps_3D && VhVg_BB(gh)));
#ifdef MISE_AU_POINT
if (Permet_affichage() > 7)
{ cout << "\n VhVg_BB("<<gh<<")= "<< VhVg_BB(gh);
cout << "\n dsigdeps_gh_P(gh): "<< (*dsigdeps_gh_P(gh)) << flush;
}
#endif
};
// c) mat1(mn,gh) = [ V_{mi}~(d sigma^{ij} / d epsilon_{op}(3D)~~V^g_{~.o}~ V^h_{~.p}) ~~V_{nj}]
// SM(mn) = ( V_{mi}~~ d sigma^{ij} / d epsilon_{o'p'}(3D)~~V^1_{~.o'}~ V^1_{~.p'}~~V_{nj} )
Mat_pleine mat1(3,3);
Vecteur SM(3);
for (int mn=1;mn<4;mn++)
{SM(mn) = VhVg_BB(mn) && dSigDeps11P_HH;
for (int gh=1;gh<4;gh++)
mat1(mn,gh) = VhVg_BB(mn) && (*dsigdeps_gh_P(gh));
};
#ifdef MISE_AU_POINT
if (Permet_affichage() > 7)
{ cout << "\n mat1 "<< mat1;
cout << "\n SM: "<< SM << flush;
}
#endif
// d) calcul des variations des déformations transversales
// en fonction de la déformation longitudinale
// d epsilon'_gh / d epsilon'_11 =
// - [ V_{mi}~(d sigma^{ij} / d epsilon_{op}(3D)~~V^g_{~.o}~ V^h_{~.p}) ~~V_{nj}]^{-1}~
// * ( V_{mi}~~ d sigma^{ij} / d epsilon_{o'p'}(3D)~~V^1_{~.o'}~ V^1_{~.p'}~~V_{nj} )
Vecteur depsP_gh_depsP_11_BB(3);
depsP_gh_depsP_11_BB = - mat1.Inverse() * SM;
#ifdef MISE_AU_POINT
if (Permet_affichage() > 7)
{ cout << "\n depsP_gh_depsP_11_BB "<< depsP_gh_depsP_11_BB << flush;
}
#endif
// e) d sigma'^{11} / d epsilon'_11 (1D~CP) =
// = V_{1i}~V_{1j}~d sigma^{ij} / d epsilon_{op}(3D)~~V^1_{~.o}~ V^1_{~.p}
// + V_{1i}~V_{1j}~d sigma^{ij} / d epsilon_{op}(3D)~~~V^g_{~.o}~ V^h_{~.p}
// * d epsilon'_gh / d epsilon'_11
// ici on se sert du fait que l'on a déjà calculé:
// dSigDeps11P_HH = d sigma^{ij} / d epsilon_{op}(3D)~~V^1_{~.o}~ V^1_{~.p}
Tenseur1HHHH d_sigP11_depsP11_HHHH
( (V1V1_BB && dSigDeps11P_HH)
+ (V1V1_BB &&
( (*dsigdeps_gh_P(1))*depsP_gh_depsP_11_BB(1)
+ (*dsigdeps_gh_P(2))*depsP_gh_depsP_11_BB(2)
+ (*dsigdeps_gh_P(3))*depsP_gh_depsP_11_BB(3)
)
)
);
#ifdef MISE_AU_POINT
if (Permet_affichage() > 7)
cout << "\n d_sigP11_depsP11_HHHH "<< d_sigP11_depsP11_HHHH << flush;
#endif
// f) d_sigma^{ij} / d_epsilon_{kl} \approx
// V_1^{~.i}~V_1^{~.j}~d sigma'^{11} / d epsilon'_11 (1D~CP)~\gamma^{k}_{~.1} ~\gamma^{l}_{~.1}
//fonctions static définissant le produit tensoriel de deux vecteurs
// si les vecteurs sont égaux le tenseur est symétrique sinon il est non symétrique
TenseurHH & inter1_HH = Tenseur3HH::Prod_tensoriel((*ViH_3D)(1),(*ViH_3D)(1));
Coordonnee3H u_H(gamma3D.Colonne(1)); // qui correspond aux \gamma^{k}_{~.1}
TenseurHH & inter2_HH = Tenseur3HH::Prod_tensoriel(u_H,u_H);
d_sigma_deps = Tenseur3HHHH::Prod_tensoriel(inter1_HH,inter2_HH);
d_sigma_deps *= d_sigP11_depsP11_HHHH(1,1,1,1);
#ifdef MISE_AU_POINT
if (Permet_affichage() > 8)
{ Tenseur3HHHH inter_HHHH;
cout << "\n dans le repere locale d_sigma_deps= \n";
int e=1;
for (int i=1;i<4;i++) for (int j=1;j<4;j++) for (int k=1;k<4;k++)for (int l=1;l<4;l++,e++)
{ cout << "("<<i<<","<<j<<","<<k<<","<<l<<")= "<<d_sigma_deps(i,j,k,l) << " ; ";
if (e>6) {cout << "\n"; e=1;}
};
Tenseur3HHHH inter1_HHHH(d_sigma_deps);
inter1_HHHH.ChangeBase(inter_HHHH,giB_tdt_3D);
cout << "\n dans le repere orthonormee d_sigma_deps= \n";
e=1;
for (int i=1;i<4;i++) for (int j=1;j<4;j++) for (int k=1;k<4;k++)for (int l=1;l<4;l++,e++)
{ cout << "("<<i<<","<<j<<","<<k<<","<<l<<")= "<<inter_HHHH(i,j,k,l) << " ; ";
if (e>6) {cout << "\n"; e=1;}
};
};
#endif
};
// vérif des grandeurs et calcul des valeurs de l'épaisseur et de la largeur
// ainsi que calcul du jacobien final
// = 0 pas de modif
// = 1 modif due aux maxi permis de h et b, = 2 si def d'entrée incorrecte
// cas de la 2ième méthode
int LoiContraintesPlanesDouble::Calcul_et_Limitation2_h_b
(double& hsurh0,Tenseur3BB& eps_P_BB_3D, double& bsurb0,double& jacobien_tdt_3DD, const double & jacobien_0_3DD)
{ int retour = 0; // init par défaut
bool modif_hsurh0 = false; bool modif_bsurb0 = false; // init
// à partir de la valeur des déformations en cours on regarde les variations transversales correspondantes
// ici les déformations eps_BB_3D sont exprimées dans le repère V_a donc orthonormée
switch (type_de_deformation)
{case DEFORMATION_STANDART : case DEFORMATION_POUTRE_PLAQUE_STANDART :
// cas d'une déformation d'Almansi
{ // on est dans le repère V_a, V_3 est direction principale du tenseur de def -> formule classique
// epsBB33 = 1/2 * (1. -(h_0/h_tdt)**2) avec un maxi de o.5
if (eps_P_BB_3D(3,3) > 0.5)
{if (Permet_affichage() > 0)
cout << "\n LoiContraintesPlanesDouble::Calcul_et_Limitation2_h_b(.."
<< "\n **erreur: la deformation d'epaisseur dans V_a "<<eps_P_BB_3D(3,3)
<< ") est superieur a 0.5, on ne peut pas s'en servir pour mettre a jour"
<< " la nouvelle epaisseur, on garde donc l'ancienne " << flush;
retour = 2; // là le pb est sérieux
}
else // sinon cas normal
{hsurh0 = 1./sqrt(1.-2.*eps_P_BB_3D(3,3));
// il ne faut pas que la nouvelle épaisseur soit inf au mini
if (hsurh0 < mini_hsurh0)
{if (Permet_affichage() > 3)
{cout << "\n *** attention hsurh0 " << hsurh0 << ", est inferieur a la limite fixee "<<mini_hsurh0
<< " on le ramene a la limite ";
};
hsurh0 = mini_hsurh0; modif_hsurh0 = true;
retour = MaX(1,retour); // on signale qu'il y a eu un recadrage
};
// on regarde également pour les maxi
if (hsurh0 > maxi_hsurh0)
{if (Permet_affichage() > 3)
{cout << "\n *** attention hsurh0 " << hsurh0 << ", est superieur a la limite fixee "<<maxi_hsurh0
<< " on le ramene a la limite ";
};
hsurh0 = maxi_hsurh0;modif_hsurh0 = true;
retour = MaX(1,retour); // on signale qu'il y a eu un recadrage
};
// si on a modifié via les extrèmes il faut mettre à jour la def
if (modif_hsurh0)
eps_BB_3D.Coor(3,3) = 0.5 * (1.-hsurh0 * hsurh0);
};
// -- suite seulement si retour est différent de 2 ---
// c-a-d que l'on n'a pas eu de pb sérieux sur h
if (retour < 2)
{// pour les deux autres def on n'est pas en directions principales mais c'est un plan principal
// on calcule les def principales via la technique de Mohr (possible car on est en repère ortho)
double epsP_c = 0.5 * (eps_P_BB_3D(1,1) + eps_P_BB_3D(2,2)); // le centre
double R = sqrt(Sqr(eps_P_BB_3D(2,2) - epsP_c) + Sqr(eps_P_BB_3D(1,2)));
double epsP_I = epsP_c + R; // la plus grande
double epsP_II = epsP_c - R; // la deuxième mais qui en toute rigueur pourrait être intercalé avec eps_P_BB_3D(3,3)
// d'où la variation de jacobien à condition de ne pas avoir de pb
bool pb = false;
// if ((epsP_I > 0.5) || (epsP_II > 0.5))
if (epsP_I > 0.5)
{if (Permet_affichage() > 0)
cout << "\n LoiContraintesPlanesDouble::Calcul_et_Limitation2_h_b(.."
<< "\n **erreur: la deformation eps'_I "<<epsP_I
<< ") est superieur a 0.5, on ne peut pas s'en servir pour mettre a jour"
<< " la variation de volume " << flush;
epsP_I = 0.5-ConstMath::trespetit; // on le met au maxi
retour = 2; // là le pb est sérieux
pb = true;
};
if (epsP_II > 0.5)
{if (Permet_affichage() > 0)
cout << "\n LoiContraintesPlanesDouble::Calcul_et_Limitation2_h_b(.."
<< "\n **erreur: la deformation eps'_II "<<epsP_I
<< ") est superieur a 0.5, on ne peut pas s'en servir pour mettre a jour"
<< " la variation de volume " << flush;
epsP_II = 0.5-ConstMath::trespetit; // on le met au maxi
retour = 2; // là le pb est sérieux
pb = true;
};
// on considère que la direction tranversale est celle correspondante à celle différente de
// eps_P_BB_3D(1,1) donc on en déduit une variation de b mais qui ne sera celle de V_2 que
// dans un cas isotrope, sinon c'est celle de la direction principale de def dans le plan !
if (retour < 2) // là encore on ne modifie que si retour est < 2
// car si retour == 2 on va obtenir des bsurb0 infinie
// eps_P_BB_3D(1,1), c'est la déformation cinématique imposée selon V1
// si elle est > eps_P_BB_3D(2,2), cela veut dire que epsP_I est de son côté
// par contre si c'est < , cela veut dire que c'est epsP_II qui est de son côté
// d'où le choix qui suit
{ if (eps_P_BB_3D(1,1) > eps_P_BB_3D(2,2))
{bsurb0 = 1./sqrt(1.-2.*epsP_II);}
else // cas d'une compression
{bsurb0 = 1./sqrt(1.-2.*epsP_I);};
};
// il ne faut pas que la nouvelle largeur soit inf au mini
if (bsurb0 < mini_bsurb0)
{if (Permet_affichage() > 3)
{cout << "\n *** attention bsurb0 " << bsurb0 << ", est inferieur a la limite fixee "<<mini_bsurb0
<< " on le ramene a la limite ";
};
bsurb0 = mini_bsurb0; modif_bsurb0 = true;
retour = MaX(1,retour); // on signale qu'il y a eu un recadrage
};
if (bsurb0 > maxi_bsurb0)
{if (Permet_affichage() > 3)
{cout << "\n *** attention bsurb0 " << bsurb0 << ", est superieur a la limite fixee "<<maxi_bsurb0
<< " on le ramene a la limite ";
};
bsurb0 = maxi_bsurb0;modif_bsurb0 = true;
retour = MaX(1,retour); // on signale qu'il y a eu un recadrage
};
// si on a modifié via les extrèmes il faut mettre à jour la def
// ici il s'agit uniquement de limiter eps_BB_3D(2,2) à des valeurs non absurdes donc on
// fait l'approximation (fausse en ortho mais cela ne devrait pas être un gros pb)
if (modif_bsurb0)
{eps_BB_3D.Coor(2,2) = 0.5 * (1.-bsurb0 * bsurb0);
// on est obligé de refaire une passe sur les def principales qui vont ^tre utilisées
// pour la variation de jacobien
epsP_c = 0.5 * (eps_P_BB_3D(1,1) + eps_P_BB_3D(2,2)); // le centre
R = sqrt(Sqr(eps_P_BB_3D(2,2) - epsP_c) + Sqr(eps_P_BB_3D(1,2)));
epsP_I = epsP_c + R; // la plus grande
epsP_II = epsP_c - R; // la deuxième mais qui en toute rigueur pourrait être intercalé avec eps_P_BB_3D(3,3)
// d'où la variation de jacobien à condition de ne pas avoir de pb
if (epsP_I > 0.5)
{if (Permet_affichage() > 0)
cout << "\n LoiContraintesPlanesDouble::Calcul_et_Limitation2_h_b(.."
<< "\n **erreur: la deformation eps'_I (deuxieme passe!!) "<<epsP_I
<< ") est superieur a 0.5, on ne peut pas s'en servir pour mettre a jour"
<< " la variation de volume " << flush;
epsP_I = 0.5-ConstMath::trespetit; // on le met au maxi
retour = 2; // là le pb est sérieux
pb = true;
};
if (epsP_II > 0.5)
{if (Permet_affichage() > 0)
cout << "\n LoiContraintesPlanesDouble::Calcul_et_Limitation2_h_b(.."
<< "\n **erreur: la deformation eps'_II (deuxieme passe!!) "<<epsP_I
<< ") est superieur a 0.5, on ne peut pas s'en servir pour mettre a jour"
<< " la variation de volume " << flush;
epsP_II = 0.5-ConstMath::trespetit; // on le met au maxi
retour = 2; // là le pb est sérieux
pb = true;
};
};
if (!pb) // cas normal
{double var_vol = 1./sqrt((1-2.*eps_P_BB_3D(3,3))*(1-2.*epsP_I)*(1-2.*epsP_II));
// jacobien_0_3DD contient uniquement le jacobien_0_1D et on part par défaut
// avec ici h0 = b0 = 1, c-a-d ici dans la loi de comp: on ne calcule en fait que h/h0 et b/b0
// la véritable épaisseur et largeur est obtenue au niveau de l'élément fini
jacobien_tdt_3DD = jacobien_0_3DD * var_vol;
};
// sinon on laise en l'état
}; // fin du cas retour < 2
};
break;
// -- pour l'instant je laisse le log en attente
// case DEFORMATION_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEFORMATION_CUMU_LOGARITHMIQUE :
// // cas d'une def logarithmique ou une approximation
// { hsurh0 = exp(eps_BB_3D(3,3));
// bsurb0 = exp(eps_BB_3D(2,2));
// };
// break;
default :
cout << "\nErreur : type de deformation qui n'est pas actuellement pris en compte, type= "
<< Nom_type_deformation(type_de_deformation);
cout << "\n LoiContraintesPlanesDouble::Limitation2_h_b(.. \n";
Sortie(1);
};
//---- debug
//jacobien_tdt_3DD = jacobien_0_3DD; // pour voir si c'est un pb de jacob ien
// retour
return retour;
};
// calcul de l'état final, dans le cas de la méthode de perturbation: version 2
void LoiContraintesPlanesDouble::Cal_avec_perturbation2()
{
// récup du conteneur spécifique
SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul);
//récup de eps_mecaBB_t
// 1) dans le repère gi
Tenseur3BB& eps_mecaBB_t = *((Tenseur3BB*) (save_resul.eps_mecaBB_t));
// 2) dans le dernier repère V_a: a utiliser en sortie post, pas pour le calcul !!
Tenseur3BB& eps_P_mecaBB_t = *((Tenseur3BB*) (save_resul.eps_P_mecaBB_t));
Tenseur3BB& eps_P_mecaBB = *((Tenseur3BB*) (save_resul.eps_P_mecaBB));
// les inconnues sont les déformations mécaniques {epsilon'}_kl;
// (k,l) = (22) (33) (12) : on a donc 3 inconnues que l'on suppose rangées dans cette ordre
// c-a-d les def qui vont servir dans l'appel de la loi 3D
// contrairement au cas de la méthode de Newton, ici on utilise les grandeurs stockées à t
// sauf pour la cinématique
// --- initialisation des déformations mécaniques dans le repère V_a
eps_P_BB = eps_mecaBB_t; // là on est dans le repère g^i
// on passe dans le repère V_a qui est donc le nouveau repère, pour ce passage
eps_P_BB.ChBase(betaP_3D);
// on calcul la déformation cinématique dans la direction V_1
// \epsilon'_{11}(t+\Delta t) = \epsilon_{kl}(t+\Delta t) ~\gamma^k_{~.1} ~\gamma^l_{~.1}
// idem pour l'accroissement de déformation et la vitesse de déformation
eps_P_BB.Coor(1,1) = 0.; Deps_P_BB.Coor(1,1) = 0.; delta_eps_P_BB.Coor(1,1) = 0.;
eps_P_BB.Coor(1,3) = 0.; eps_P_BB.Coor(2,3) = 0.;
for (int k=1;k<4;k++) // calcul de la matrice gamma
for (int l=1;l<4;l++)
{eps_P_BB.Coor(1,1) += (*epsBB_tdt_cin)(k,l) * gamma3D(k,1) * gamma3D(l,1);
Deps_P_BB.Coor(1,1) += (*DepsBB_cin)(k,l) * gamma3D(k,1) * gamma3D(l,1);
delta_eps_P_BB.Coor(1,1) += (*delta_epsBB_cin)(k,l) * gamma3D(k,1) * gamma3D(l,1);
};
// vérif des grandeurs et calcul de la nouvelle épaisseur et largeur
double& hsurh0 = save_resul.hsurh0;double& bsurb0 = save_resul.bsurb0;
// la méthode va mettre à jour les valeurs bsurb0 et hsurh0 et du jacobien
bool erreur_sortie = false; // pour gestion de sortie d'infos supplémentaires
if (Calcul_et_Limitation2_h_b(hsurh0,eps_P_BB,bsurb0,jacobien_tdt_3D,jacobien_0_3D))
{if (Permet_affichage() > 3)
cout << "\n LoiContraintesPlanesDouble::Cal_avec_perturbation2(... " << endl;
erreur_sortie = true;
};
if (erreur_sortie && (Permet_affichage() > 4))
{cout << "\n giH_tdt: " << *(umat_cont_3D->giH_tdt);
cout << "\n defBB: ";eps_BB_3D.Ecriture(cout);
cout << "\n DepsBB: ";Deps_BB_3D.Ecriture(cout);
};
// dans la direction V_1 c'est la déformation issue de la cinématique
// elle a déjà été calculée, et les autres composantes demeurent nulle
// donc eps_P_BB est au complet,
eps_BB_3D=eps_P_BB; // recopie dans eps_BB_3D: là on est dans le repère V_a
eps_BB_3D.ChBase(beta3D); // changement de base, là on est dans le repère g^i
// on s'occupe maintenant de l'incrément de déformation
delta_eps_BB_3D = eps_BB_3D - eps_mecaBB_t;
// au cas où, on impose (normalement c'est inutile) que les composantes 13 et 23 sont nulles
delta_eps_BB_3D.Coor(1,3) = 0.; delta_eps_BB_3D.Coor(2,3) = 0.;
// recup de l'incrément de temps
double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant();
double unSurDeltat;
if (Abs(deltat) >= ConstMath::trespetit)
{unSurDeltat = 1./deltat;}
else
// si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand
{ // un pas de temps doit être positif !! or certaine fois il peut y avoir des pb
#ifdef MISE_AU_POINT
if (unSurDeltat < 0)
{ cout << "\n le pas de temps est négatif !! "
<< "\n LoiContraintesPlanesDouble::Cal_avec_perturbation2(...";
};
#endif
unSurDeltat = ConstMath::tresgrand;
};
// ici on considère que la déformation est de type Almansi
Deps_BB_3D = delta_eps_BB_3D * unSurDeltat;
// calcul des invariants de déformation et de vitesse de déformation, et les def cumulées
// correspondant aux cas 3D
Calcul_invariants_et_def_cumul();
// --- on s'occupe des jacobiens
// à t=0 on considère que c'est le même jacobien que transmis
jacobien_0_3D = *(umat_cont_3D->jacobien_0);
// à tdt le jacobien est calculée à partir de la déformation supposée d'Almansi
// ici il s'agit du jacobien relatif au comportement mécanique
// |J| = sqrt(det(2 * eps_ij + g_ij(0)))
// calcul de la matrice correspondante à (2 * eps_ij + g_ij(0))
gij_meca_BB = (2. * eps_BB_3D + (*(umat_cont_3D->gijBB_0)));
gij_meca_BB.Matrice_composante(mat_inter);
// calcul du jacobien
jacobien_tdt_3D = sqrt(Dabs(mat_inter.Determinant()));
// initialisation du comportement tangent / au def
d_sigma_deps_3D.Inita(0.);
// appel du calcul de sig et dsig
bool en_base_orthonormee = false; // ici les tenseurs ne sont pas en orthonormee
// car on travaille dans la base naturelle
#ifdef MISE_AU_POINT
if (Permet_affichage() > 8)
{cout << "\n LoiContraintesPlanesDouble::Cal_avec_perturbation2(..."
<< "\n giH_tdt: " << *(umat_cont_3D->giH_tdt);
cout << "\n defBB: ";eps_BB_3D.Ecriture(cout);
cout << "\n DepsBB: ";Deps_BB_3D.Ecriture(cout);
};
#endif
lois_interne->Calcul_dsigma_deps (en_base_orthonormee, sig_HH_t_3D,Deps_BB_3D,eps_BB_3D
,delta_eps_BB_3D,jacobien_0_3D,jacobien_tdt_3D
,sig_HH_3D,d_sigma_deps_3D
,save_resul.l_energ,save_resul.l_energ_t,module_compressibilite_3D
,module_cisaillement_3D,*umat_cont_3D);
#ifdef MISE_AU_POINT
if (Permet_affichage() > 8)
{cout << "\n sig_HH_3D: " << sig_HH_3D;
cout << "\n d_sigma_deps_3D: "<< d_sigma_deps_3D << flush;
};
#endif
// sauvegarde des résultats
save_resul.def_P(1) = eps_P_BB(2,2); // récup de la solution dans le repère V_a
save_resul.def_P(2) = eps_P_BB(3,3); // "
save_resul.def_P(3) = eps_P_BB(1,2); // "
// on doit sauvegarder les def méca dans le repère g^i, ce sont directement
// les dernières composantes utilisées pour l'appel de la loi 3D
Tenseur3BB& eps_mecaBB = *((Tenseur3BB*) (save_resul.eps_mecaBB));
eps_mecaBB = eps_BB_3D; // en g^i
eps_P_mecaBB = eps_P_BB; // dans V_a pour le post traitement
};
// passage entre le calcul classique en 1D de Calcul_dsigma_deps et le calcul 3D
// méthode 2
void LoiContraintesPlanesDouble::Passage_Calcul_1D_3D_dsigma_deps
(bool en_base_orthonormee, TenseurHH & sigHH_t,TenseurBB& DepsBB
,TenseurBB & epsBB_tdt,TenseurBB & delta_epsBB,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() > 7)
cout << "\n LoiContraintesPlanesDouble::Passage_Calcul_1D_3D_dsigma_deps";
#endif
// récup du conteneur spécifique
SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul);
module_compressibilite=module_cisaillement=0.; // init
energ.Inita(0.); // initialisation des énergies mises en jeux
// --- pour les contraintes passage en 3D
bool plusZero = true;
// on affecte les contraintes a t: en fait pour les lois incrémentales, les infos à t
// sont déjà stocké, donc cela ne sert à rien, mais pour une loi élastique par exemple ce n'est pas le cas
sig_HH_t_3D.Affectation_trans_dimension(*((Tenseur1HH*) &sigHH_t),plusZero);
// --- pour la cinématique
// passage des informations spécifique à la loi le_SaveResul
// initialisation du tenseurs contrainte
sig_HH_3D.Inita(0.);
sig_HH_3D.Affectation_trans_dimension(*((Tenseur1HH*) &sigHH_tdt),plusZero);
// passage des métriques de l'ordre 1 vers 3
Passage_metrique_ordre1_vers_3(ex);
// passage des informations liées à la déformation de 1 vers 3, et variation de volume
Tableau <TenseurBB *>* toto = NULL; // pour dire que ce n'est pas attribué
Vecteur* titi = NULL; // " " "
Passage_deformation_volume_ordre1_vers_3(DepsBB,epsBB_tdt,toto,delta_epsBB
,jacobien_0,jacobien,titi,*(ex.jacobien_t));
// -- construction de la base ortho associée à la direction de traction/compression
// ici il s'agit pour le premier vecteur de la direction 1,
// et compte tenu de Passage_metrique_ordre1_vers_3, le repère gi est orthogonale
// on va donc le normer
BaseB Vi_B(3); BaseH Vi_H(3);
BaseB * ViB = &Vi_B;BaseH * ViH = &Vi_H;
// tout d'abord on récupère la base gi actuelle et on la norme:
// on se sert de Vi_B comme stockage transitoire
// cout << "\n base giB(1) "<< (* ex.giB_tdt)(1)
// << "\n base giB(2) "<< (* ex.giB_tdt)(2);
#ifdef MISE_AU_POINT
if (Permet_affichage() > 8)
{ cout << "\n base giB_tdt_3D(1) "<< giB_tdt_3D(1)
<< "\n base giB_tdt_3D(2) "<< giB_tdt_3D(2)
<< "\n base giB_tdt_3D(2) "<< giB_tdt_3D(3) << flush;
};
#endif
Vi_B.CoordoB(1) = giB_tdt_3D(1);Vi_B.CoordoB(1).Normer();
Vi_B.CoordoB(2) = giB_tdt_3D(2);Vi_B.CoordoB(2).Normer();
Vi_B.CoordoB(3) = giB_tdt_3D(3);Vi_B.CoordoB(3).Normer();
// calcul des coordonnées locales de V_a en contravariants:
// V_a^{~i} = \vec V_a . \vec g^j
for (int a=1;a<4;a++) for (int i=1;i<4;i++)
Vi_H.CoordoH(a)(i) = Vi_B.CoordoB(a) * giH_tdt_3D(i);
// calcul des coordonnées contra
// Vi_B(a) = g_ij * Vi_H(a)
for (int a=1;a<4;a++)
Vi_B.CoordoB(a) = gijBB_t_3D * Vi_H(a);
// appel de la résolution 3D
// calcul des contraintes et ses variations par rapport aux déformations a t+dt
// ceci dans le cas où l'axe de traction simple est quelconque
// ici on suppose que:
// - tous les calculs sont en dim 3
// - l'axe 3 est normal aux deux autres (ceci pour Vi et pour gi)
//
// ViB et ViH : correspond à la base de traction telle que ViB(1) = ViH(1) = l'axe de traction
// La base Vi est supposée orthonormée
// 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
Calcul_dsigma_deps (en_base_orthonormee,ViB,ViH,sig_HH_t_3D,Deps_BB_3D
,eps_BB_3D,delta_eps_BB_3D,jacobien_0_3D,jacobien_tdt_3D
,sig_HH_3D,d_sigma_deps_3D,save_resul.l_energ,save_resul.l_energ_t
,module_compressibilite,module_cisaillement,*umat_cont_3D);
// passage des tenseurs résultats à l'ordre 1
((Tenseur1HH*) &sigHH_tdt)->Affectation_trans_dimension(sig_HH_3D,false);
// maintenant on renseigne le tenseur de sortie
bool pluszero = true;
d_sigma_deps.Affectation_trans_dimension(d_sigma_deps_3D, pluszero);
};
// passage entre le calcul classique en 1D de Calcul_DsigmaHH_tdt et le calcul 3D
// méthode 2
void LoiContraintesPlanesDouble::Passage_Calcul_1D_3D_dsigma_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_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() > 7)
cout << "\n LoiContraintesPlanesDouble::Passage_Calcul_1D_3D_dsigma_DsigmaHH_td";
#endif
// récup du conteneur spécifique
SaveResul_LoiContraintesPlanesDouble & save_resul = *((SaveResul_LoiContraintesPlanesDouble*) saveResul);
module_compressibilite=module_cisaillement=0.; // init
energ.Inita(0.); // initialisation des énergies mises en jeux
// --- pour les contraintes passage en 3D
bool plusZero = true;
// on affecte les contraintes a t: en fait pour les lois incrémentales, les infos à t
// sont déjà stocké, donc cela ne sert à rien, mais pour une loi élastique par exemple ce n'est pas le cas
sig_HH_t_3D.Affectation_trans_dimension(*((Tenseur1HH*) &sigHH_t),plusZero);
// --- pour la cinématique
// passage des informations spécifique à la loi le_SaveResul
// initialisation du tenseurs contrainte
sig_HH_3D.Inita(0.);
sig_HH_3D.Affectation_trans_dimension(*((Tenseur1HH*) &sigHH_tdt),plusZero);
// passage des métriques de l'ordre 1 vers 3
Passage_metrique_ordre1_vers_3(ex);
// passage des informations liées à la déformation de 1 vers 3, et variation de volume
Tableau <TenseurBB *>* toto = NULL; // pour dire que ce n'est pas attribué
Vecteur* titi = NULL; // " " "
Passage_deformation_volume_ordre1_vers_3(DepsBB,epsBB_tdt,toto,delta_epsBB
,jacobien_0,jacobien,titi,*(ex.jacobien_t));
// -- construction de la base ortho associée à la direction de traction/compression
// ici il s'agit pour le premier vecteur de la direction 1,
// et compte tenu de Passage_metrique_ordre1_vers_3, le repère gi est orthogonale
// on va donc le normer
BaseB Vi_B(3); BaseH Vi_H(3);
BaseB * ViB = &Vi_B;BaseH * ViH = &Vi_H;
// tout d'abord on récupère la base gi actuelle et on la norme:
// on se sert de Vi_B comme stockage transitoire
#ifdef MISE_AU_POINT
if (Permet_affichage() > 8)
{ cout << "\n base giB_tdt_3D(1) "<< giB_tdt_3D(1)
<< "\n base giB_tdt_3D(2) "<< giB_tdt_3D(2)
<< "\n base giB_tdt_3D(2) "<< giB_tdt_3D(3) << flush;
};
#endif
Vi_B.CoordoB(1) = giB_tdt_3D(1);Vi_B.CoordoB(1).Normer();
Vi_B.CoordoB(2) = giB_tdt_3D(2);Vi_B.CoordoB(2).Normer();
Vi_B.CoordoB(3) = giB_tdt_3D(3);Vi_B.CoordoB(3).Normer();
// calcul des coordonnées locales de V_a en contravariants:
// V_a^{~i} = \vec V_a . \vec g^j
for (int a=1;a<4;a++) for (int i=1;i<4;i++)
Vi_H.CoordoH(a)(i) = Vi_B.CoordoB(a) * giH_tdt_3D(i);
// calcul des coordonnées contra
// Vi_B(a) = g_ij * Vi_H(a)
for (int a=1;a<4;a++)
Vi_B.CoordoB(a) = gijBB_t_3D * Vi_H(a);
#ifdef MISE_AU_POINT
if (Permet_affichage() > 4)
{cout << "\n LoiContraintesPlanesDouble::Passage_Calcul_1D_3D_dsigma_DsigmaHH_td( ";
cout << "\n base Vi_B(1) "<< Vi_B(1) << "\n base Vi_B(2) "<< Vi_B(2)
<< "\n base Vi_B(3) "<< Vi_B(3)
<< "\n base Vi_H(1) "<< Vi_H(1) << "\n base Vi_H(2) "<< Vi_H(2)
<< "\n base Vi_H(3) "<< Vi_H(3) << flush;
};
#endif
// appel de la résolution 3D
// calcul des contraintes et ses variations par rapport aux déformations a t+dt
// ceci dans le cas où l'axe de traction simple est quelconque
// ici on suppose que:
// - tous les calculs sont en dim 3
// - l'axe 3 est normal aux deux autres (ceci pour Vi et pour gi)
//
// ViB et ViH : correspond à la base de traction telle que ViB(1) = ViH(1) = l'axe de traction
// La base Vi est supposée orthonormée
// 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
bool en_base_orthonormee = false;
Calcul_dsigma_deps (en_base_orthonormee,ViB,ViH,sig_HH_t_3D,Deps_BB_3D
,eps_BB_3D,delta_eps_BB_3D,jacobien_0_3D,jacobien_tdt_3D
,sig_HH_3D,d_sigma_deps_3D,save_resul.l_energ,save_resul.l_energ_t
,module_compressibilite,module_cisaillement,*umat_cont_3D);
// passage des tenseurs résultats à l'ordre 1
((Tenseur1HH*) &sigHH_tdt)->Affectation_trans_dimension(sig_HH_3D,false);
// maintenant on renseigne le tenseur de sortie
bool pluszero = true;
// d_sigma / d_ddl = d_sigma / d_eps * d_eps / d_ddl
// ici l'opérateur tangent correspond à la sensibilité de d sigma'^11 / d eps'_11
// et la direction V_1 c'est la direction de g_1 (à la norme près donc
// d_sigma / d_eps normalement c'est == à d sigma'^11 / d eps'_11
// du coup ici on n'a pas à itérer sur toutes les déformations
int nb_ddlPlus1 = d_epsBB.Taille()+1;
for (int i_ddl=1;i_ddl<nb_ddlPlus1;i_ddl++)
d_sigHH(i_ddl)->Coor(1,1) = (d_sigma_deps_3D(1,1,1,1) * (*d_epsBB(i_ddl)))(1,1);
};