3076 lines
158 KiB
C++
Executable file
3076 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);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|