Gérard Rio
9692dbd130
- contient les éléments finis, métriques associées, déformations ... intégration du réperoire Géométrie: - contient les géométries 1D 2D et 3D, les frontières des éléments géométriques
2002 lines
93 KiB
C++
2002 lines
93 KiB
C++
|
|
// 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-2021 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 "Deformation.h"
|
|
#include "ConstMath.h"
|
|
#include "ParaGlob.h"
|
|
#include "MathUtil.h"
|
|
#include "Tenseur3.h"
|
|
#include "Tenseur2.h"
|
|
#include "Tenseur1.h"
|
|
# include "TypeConsTens.h"
|
|
#include "Util.h"
|
|
#include "MathUtil2.h"
|
|
|
|
|
|
//================== initialisation des variables static ======================
|
|
// change 2 mai 2020: int Deformation::numInteg = 0;
|
|
// indicateur utilisé par VerifCal_deflog
|
|
int Deformation::indic_VerifCal_implicit = 0;
|
|
// def de deux tableaux d'indices pour avoir la suite: 12 21 13 31 23 32 à partir de 6 nombres
|
|
const Deformation::UtilIndexDeformation Deformation::ccdex;
|
|
// partie statique ou sont stocké tous les cas différents des variables de travail
|
|
list <Tableau <TenseurBH * > > Deformation::list_var_tens_BH;
|
|
list <Tableau <Tableau <TenseurBH* > > > Deformation::list_var_var_tens_BH;
|
|
list <Tableau <Coordonnee > > Deformation::list_tab_coor;
|
|
int Deformation::nombre_d_instance_deformation=0;
|
|
|
|
//================== fin d'initialisation des variables static ================
|
|
|
|
// def du constructeur par défaut de UtilIndexDeformation
|
|
Deformation::UtilIndexDeformation::UtilIndexDeformation() :
|
|
iii(6),jjj(6)
|
|
{ iii(6); iii(1)=1; iii(2)=2;iii(3)=1;iii(4)=3;iii(5)=2;iii(6)=3;
|
|
jjj(6); jjj(1)=2; jjj(2)=1;jjj(3)=3;jjj(4)=1;jjj(5)=3;jjj(6)=2;
|
|
};
|
|
|
|
// ---------- constructeur----------------------------------------
|
|
Deformation::Deformation () // constructeur ne devant pas etre utilise
|
|
//#ifndef ENLINUX
|
|
: tabnoeud((new Tableau <Noeud *> )) // dans le cas de linux on ne déclare pas le tableau
|
|
,saveDefResul(NULL),numInteg(0),sauve_numInteg(0)
|
|
//#endif
|
|
|
|
// : tabnoeud()
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
{ cout << "\nErreur : le constructeur par defaut ne doit pa etre utilise !\n";
|
|
cout << "Deformation::Deformation () \n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
};
|
|
|
|
// constructeur normal dans le cas d'un ou de plusieurs pt d'integration
|
|
Deformation::Deformation (Met_abstraite & a,Tableau<Noeud *>& b,
|
|
Tableau <Mat_pleine> const & tabdphi,Tableau <Vecteur> const & tabphi
|
|
,Enum_type_deformation type_de_deformation) :
|
|
tabnoeud(&b),type_deformation(type_de_deformation)
|
|
,type_gradient_vitesse(GRADVITESSE_VCONST) // pour l'instant ********* en test
|
|
,saveDefResul(NULL)
|
|
// variables de travail pour log
|
|
,B_BH_tr(NULL),d_B_BH_tr(NULL),ki(),d_ki(NULL),Palpha_BH_tr(NULL),d_Palpha_BH_tr(NULL)
|
|
,dimensionnement_tableaux(0),numInteg(0)
|
|
,sauve_numInteg(0)
|
|
{ metrique = &a;
|
|
tabDphi = &tabdphi;
|
|
tabPhi = &tabphi;
|
|
nbNoeud = (*tabPhi)(1).Taille(); // par defaut
|
|
numInteg = 1; // 1 pt d'integ par defaut
|
|
nombre_d_instance_deformation++;
|
|
};
|
|
|
|
// constructeur de copie
|
|
Deformation::Deformation (const Deformation& a) :
|
|
tabnoeud(a.tabnoeud), type_deformation(a.type_deformation)
|
|
,type_gradient_vitesse(a.type_gradient_vitesse),saveDefResul(NULL)
|
|
// variables de travail pour log
|
|
,B_BH_tr(a.B_BH_tr),d_B_BH_tr(a.d_B_BH_tr),ki(a.ki),d_ki(a.d_ki)
|
|
,Palpha_BH_tr(a.Palpha_BH_tr),d_Palpha_BH_tr(a.d_Palpha_BH_tr)
|
|
,dimensionnement_tableaux(a.dimensionnement_tableaux)
|
|
,numInteg(a.numInteg),sauve_numInteg(a.sauve_numInteg)
|
|
{ metrique = a.metrique;
|
|
tabDphi = a.tabDphi;
|
|
tabPhi = a.tabPhi;
|
|
nbNoeud = a.nbNoeud;
|
|
nombre_d_instance_deformation++;
|
|
};
|
|
|
|
Deformation::~Deformation ()
|
|
{ LibereTenseur() ; nombre_d_instance_deformation--;
|
|
if (nombre_d_instance_deformation==0)
|
|
{// cas de la dernière instance
|
|
// ---- cas de list_var_tens_BH ----
|
|
list <Tableau <TenseurBH * > >::iterator ilv,ilvend= list_var_tens_BH.end();
|
|
for (ilv=list_var_tens_BH.begin();ilv!=ilvend;ilv++)
|
|
{ int tailletab=(*ilv).Taille();
|
|
for (int i=1;i<=tailletab;i++) delete (*ilv)(i);
|
|
};
|
|
list_var_tens_BH.erase(list_var_tens_BH.begin(),ilvend);
|
|
// ---- cas de list_var_var_tens_BH ----
|
|
list <Tableau <Tableau <TenseurBH* > > > ::iterator ilv1,ilvend1= list_var_var_tens_BH.end();
|
|
for (ilv1=list_var_var_tens_BH.begin();ilv1!=ilvend1;ilv1++)
|
|
{ int tailletab=(*ilv1).Taille();
|
|
for (int i=1;i<=tailletab;i++)
|
|
{ int tailletab2=(*ilv1)(i).Taille();
|
|
for (int j=1;j<=tailletab2;j++) delete (*ilv1)(i)(j);
|
|
};
|
|
};
|
|
list_var_var_tens_BH.erase(list_var_var_tens_BH.begin(),ilvend1);
|
|
// ---- cas de list_tab_coor ----
|
|
list_tab_coor.erase(list_tab_coor.begin(),list_tab_coor.end());
|
|
};
|
|
};
|
|
|
|
// réafectation du pointeur de tableau de noeuds interne
|
|
// il faut que le nouveau tableau ait la même taille que l'ancien (sert pour créer de nouveau éléments
|
|
// de même type, sinon ce n'est pas la bonne solution,
|
|
// il vaut mieux creer une nouvelle def
|
|
void Deformation::PointeurTableauNoeud(Tableau <Noeud *> & tabN)
|
|
{ // on vérifie la cohérence
|
|
if (tabN.Taille() != tabnoeud->Taille())
|
|
{ cout << "\n erreur de re-affectation de tableau de noeud dans la deformation ! "
|
|
<< " ancien nombre de noeud: " << tabnoeud->Taille() << " nouveau nombre: " << tabN.Taille()
|
|
<< "\n Deformation::PointeurTableauNoeud(..";
|
|
Sortie(1);
|
|
};
|
|
// sinon c'est ok
|
|
tabnoeud = &tabN;
|
|
};
|
|
|
|
// surcharge de l'opérateur d'affectation
|
|
Deformation& Deformation::operator= (const Deformation& def)
|
|
{ metrique = def.metrique;
|
|
tabnoeud = def.tabnoeud;
|
|
tabDphi = def.tabDphi;
|
|
tabPhi = def.tabPhi;
|
|
nbNoeud = def.nbNoeud;type_deformation=def.type_deformation;
|
|
numInteg = def.numInteg;
|
|
saveDefResul = def.saveDefResul;
|
|
// variables de travail pour log
|
|
B_BH_tr=def.B_BH_tr;d_B_BH_tr=def.d_B_BH_tr;ki=def.ki;d_ki=def.d_ki;
|
|
Palpha_BH_tr=def.Palpha_BH_tr;d_Palpha_BH_tr=def.d_Palpha_BH_tr;
|
|
|
|
return (*this);
|
|
};
|
|
|
|
// change le type de déformation
|
|
void Deformation::Change_type_de_deformation(Enum_type_deformation type_de_def)
|
|
{ // le changement de déformation doit-être cohérent avec la déformation actuelle d'où les
|
|
// différents choix restreinds
|
|
if ((type_de_def==DEFORMATION_STANDART) ||
|
|
(type_de_def==DEFORMATION_LOGARITHMIQUE) ||
|
|
(type_de_def==DEFORMATION_CUMU_LOGARITHMIQUE) ||
|
|
(type_de_def==DEF_CUMUL_CORROTATIONNEL) ||
|
|
(type_de_def==DEF_CUMUL_ROTATION_PROPRE) )
|
|
{ if ((type_deformation==DEFORMATION_STANDART) ||
|
|
(type_deformation==DEFORMATION_LOGARITHMIQUE) ||
|
|
(type_deformation==DEFORMATION_CUMU_LOGARITHMIQUE) ||
|
|
(type_deformation==DEF_CUMUL_CORROTATIONNEL) ||
|
|
(type_deformation==DEF_CUMUL_ROTATION_PROPRE) )
|
|
type_deformation = type_de_def; // ok cohérent
|
|
}
|
|
// sinon le type n'est pas pris en compte dans cette méthode donc erreur
|
|
else
|
|
{ cout << "\nErreur : valeur incorrecte du nouvrau type Enum_type_deformation !"
|
|
<< "\n type actuelle: " << Nom_type_deformation(type_deformation)
|
|
<< " type demande: " << Nom_type_deformation(type_de_def);
|
|
cout << "Deformation::Change_type_de_deformation(...) \n";
|
|
Sortie(1);
|
|
};
|
|
};
|
|
|
|
// affichage des informations
|
|
void Deformation::Affiche() const
|
|
{ cout << "\n -- deformation: --- "
|
|
<< "\n nb noeud concerne = "<< nbNoeud
|
|
<< " numInteg= "<< numInteg;
|
|
if (tabnoeud != NULL)
|
|
{cout << "\n -- information concernant les noeuds: \n";
|
|
for (int i = 1;i<= tabnoeud->Taille();i++)
|
|
(*tabnoeud)(i)->Affiche();
|
|
};
|
|
if (metrique != NULL)
|
|
{cout << "\n -- information concernant la metrique actuelle au pti --";
|
|
metrique->Affiche();
|
|
};
|
|
cout << flush;
|
|
};
|
|
|
|
|
|
// ============ METHODES PUBLIQUES : ==================
|
|
// ---------------- calcul des variables primaires pour la mécanique --------
|
|
// calcul explicit à t :tous les parametres sont des resultats
|
|
const Met_abstraite::Expli& Deformation::Cal_explicit_t
|
|
// ( bool gradV_instantane,TenseurBB & epsBB_t,Tableau <TenseurBB *> & d_epsBB
|
|
// ,TenseurBB& DepsBB,TenseurBB& delta_epsBB,bool premier_calcul)
|
|
// def_equi_t: est la def equi au debut du pas, et def_equi est la def finale
|
|
( const Tableau <double>& def_equi_t,TenseurBB & epsBB_t,Tableau <TenseurBB *> & d_epsBB
|
|
,Tableau <double>& def_equi,TenseurBB& DepsBB,TenseurBB& delta_epsBB,bool premier_calcul)
|
|
{bool gradV_instantane = false; // ************ pour l'instant figé
|
|
// appel de la metrique: on le fait ici et non dans les méthodes Cal_explicit_Almansi_tdt etc
|
|
// car pour d'autre déformation, par exemple sfe ou plaque, la méthode Deformation::Cal_explicit_tdt
|
|
// est surchargée car différentes, par contre les méthodes Cal_explicit_Almansi_tdt etc sont les mêmes
|
|
const Met_abstraite::Expli& ex =
|
|
metrique->Cal_explicit_t(*tabnoeud,gradV_instantane,(*tabDphi)(numInteg),
|
|
nbNoeud,(*tabPhi)(numInteg),premier_calcul);
|
|
|
|
// ici il y a le choix entre les différents types de calcul de la déformation (Almansi, Green-Lagrange ..
|
|
switch (type_deformation)
|
|
{ case DEFORMATION_STANDART :
|
|
{Cal_explicit_Almansi
|
|
(gradV_instantane,epsBB_t,d_epsBB,DepsBB,delta_epsBB,premier_calcul,ex);
|
|
break;
|
|
}
|
|
case DEFORMATION_LOGARITHMIQUE:
|
|
{Cal_explicit_Logarithmique
|
|
(gradV_instantane,epsBB_t,d_epsBB,DepsBB,delta_epsBB,premier_calcul,ex);
|
|
break;
|
|
}
|
|
|
|
// case DEFORMATION_CUMU_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEF_CUMUL_ROTATION_PROPRE :
|
|
// {Cal_explicit_def_cumule
|
|
// (gradV_instantane,epsBB_t,d_epsBB,DepsBB,delta_epsBB,premier_calcul,ex);
|
|
// break;
|
|
// }
|
|
default :
|
|
cout << "\nErreur : type de deformation ( " << Nom_type_deformation(type_deformation)
|
|
<< " ) non traite !\n";
|
|
cout << "Deformation::Cal_explicit(... \n";
|
|
Sortie(1);
|
|
};
|
|
|
|
// --- on calcul la déformation cumulée
|
|
|
|
{TenseurBH * delta_epsBH = NevezTenseurBH(delta_epsBB.Dimension(), 0.);
|
|
*delta_epsBH = delta_epsBB * (*ex.gijHH_t);
|
|
double delta_eps_equi = sqrt(2./3. * ( ((*delta_epsBH) && (*delta_epsBH)) - Sqr(delta_epsBH->Trace()) /3. ));
|
|
def_equi(1) = def_equi_t(1) + delta_eps_equi;
|
|
def_equi(4) = delta_eps_equi;
|
|
delete delta_epsBH;
|
|
};
|
|
{TenseurBH * epsBH = NevezTenseurBH(epsBB_t.Dimension(), 0.);
|
|
*epsBH = epsBB_t * (*ex.gijHH_t);
|
|
def_equi(2) = sqrt(2./3. * ( ((*epsBH) && (*epsBH)) - Sqr(epsBH->Trace()) /3. ));
|
|
delete epsBH;
|
|
if (def_equi(2) > def_equi_t(3))
|
|
def_equi(3) = def_equi(2);
|
|
};
|
|
|
|
// sauvegarde des infos à 0 éventuellement et init par recopie des grandeurs sur t
|
|
if (premier_calcul) saveDefResul->MiseAJourGrandeurs_a_0(metrique);
|
|
// *** pour supprimer les warnings à la compilation *** mais on ne doit jamais passer ici
|
|
// const Met_abstraite::Expli& toto = * (new Met_abstraite::Expli()); return toto;
|
|
return ex;
|
|
};
|
|
|
|
// calcul explicit à tdt :tous les parametres sont des resultats
|
|
const Met_abstraite::Expli_t_tdt& Deformation::Cal_explicit_tdt
|
|
// ( bool gradV_instantane,TenseurBB & epsBB_tdt,Tableau <TenseurBB *> & d_epsBB,TenseurBB& DepsBB
|
|
// ,TenseurBB& delta_epsBB_tdt,bool premier_calcul)
|
|
( const Tableau <double>& def_equi_t,TenseurBB & epsBB_tdt,Tableau <TenseurBB *> & d_epsBB
|
|
,Tableau <double>& def_equi,TenseurBB& DepsBB,TenseurBB& delta_epsBB_tdt,bool premier_calcul)
|
|
{ bool gradV_instantane = false; // ************ pour l'instant figé
|
|
// appel de la metrique: on le fait ici et non dans les méthodes Cal_explicit_Almansi_tdt etc
|
|
// car pour d'autre déformation, par exemple sfe ou plaque, la méthode Deformation::Cal_explicit_tdt
|
|
// est surchargée car différentes, par contre les méthodes Cal_explicit_Almansi_tdt etc sont les mêmes
|
|
const Met_abstraite::Expli_t_tdt& ex =
|
|
metrique->Cal_explicit_tdt(*tabnoeud,gradV_instantane,(*tabDphi)(numInteg),
|
|
nbNoeud,(*tabPhi)(numInteg),premier_calcul);
|
|
|
|
// ici il y a le choix entre les différents types de calcul de la déformation (Almansi, Green-Lagrange ..
|
|
switch (type_deformation)
|
|
{ case DEFORMATION_STANDART :
|
|
{Cal_explicit_Almansi_tdt
|
|
(gradV_instantane,epsBB_tdt,d_epsBB,DepsBB,delta_epsBB_tdt,premier_calcul,ex);
|
|
break;
|
|
}
|
|
case DEFORMATION_LOGARITHMIQUE:
|
|
{Cal_explicit_logarithmique_tdt
|
|
(gradV_instantane,epsBB_tdt,d_epsBB,DepsBB,delta_epsBB_tdt,premier_calcul,ex);
|
|
break;
|
|
}
|
|
// case DEFORMATION_CUMU_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEF_CUMUL_ROTATION_PROPRE :
|
|
// {Cal_explicit_def_cumule_tdt
|
|
// (gradV_instantane,epsBB_tdt,d_epsBB,DepsBB,delta_epsBB_tdt,premier_calcul,ex);
|
|
// break;
|
|
// }
|
|
default :
|
|
cout << "\nErreur : type de deformation ( " << Nom_type_deformation(type_deformation)
|
|
<< " ) non traite !\n";
|
|
cout << "Deformation::Cal_explicit_tdt(... \n";
|
|
Sortie(1);
|
|
};
|
|
// sauvegarde des infos à 0 éventuellement et init par recopie des grandeurs sur t
|
|
if (premier_calcul) saveDefResul->MiseAJourGrandeurs_a_0(metrique);
|
|
// sauvegarde des infos à t à chaque passage
|
|
saveDefResul->MiseAJourGrandeurs_a_tdt(metrique,DepsBB);
|
|
// --- on calcul la déformation cumulée
|
|
{TenseurBH * delta_epsBH = NevezTenseurBH(delta_epsBB_tdt.Dimension(), 0.);
|
|
*delta_epsBH = delta_epsBB_tdt * (*ex.gijHH_tdt);
|
|
double delta_eps_equi = sqrt(2./3. * ( ((*delta_epsBH) && (*delta_epsBH)) - Sqr(delta_epsBH->Trace()) /3. ));
|
|
def_equi(1) = def_equi_t(1) + delta_eps_equi;
|
|
def_equi(4) = delta_eps_equi;
|
|
delete delta_epsBH;
|
|
};
|
|
|
|
{TenseurBH * epsBH = NevezTenseurBH(epsBB_tdt.Dimension(), 0.);
|
|
*epsBH = epsBB_tdt * (*ex.gijHH_tdt);
|
|
def_equi(2) = sqrt(2./3. * ( ((*epsBH) && (*epsBH)) - Sqr(epsBH->Trace()) /3. ));
|
|
delete epsBH;
|
|
if (def_equi(2) > def_equi_t(3))
|
|
def_equi(3) = def_equi(2);
|
|
};
|
|
|
|
// *** pour supprimer les warnings à la compilation *** mais on ne doit jamais passer ici
|
|
// const Met_abstraite::Expli_t_tdt& toto = * (new Met_abstraite::Expli_t_tdt()); return toto;
|
|
return ex;
|
|
};
|
|
|
|
// calcul et récupération de la dérivée de la vitesse de déformation virtuelle à tdt
|
|
// dans le cas d'une discrétisation classique simple, ce calcul est indépendant des coordonnées
|
|
// donc peut être effectué indépendament du reste, il dépend cependant du point d'intégration
|
|
// dans le cas de discrétisation complexe, il faut s'assurer que les autres grandeurs utiles de la métrique
|
|
// sont déjà calculé (cf. D2_gijBB_tdt() )
|
|
// total = true : indique que le calcul est complet, à partir des données de base
|
|
// c-a-d calcul de la variation de vecteur de base puis calcul de la variation seconde
|
|
// = false: le calcul est simplifié, on considère que la variation des vecteurs de base vient
|
|
// juste d'être calculé, dans un calcul implicit, on ne calcul alors que la variation seconde
|
|
void Deformation::Cal_var_def_virtuelle(bool total,Tableau2 <TenseurBB *>& d2_epsBB_tdt)
|
|
{ const Tableau2 <TenseurBB * > & d2_gijBB_tdt
|
|
= metrique->CalVar2GijBBtdt(total, (*tabDphi)(numInteg),nbNoeud,(*tabPhi)(numInteg));
|
|
int d2_epsBB_tdtTaille1 = d2_epsBB_tdt.Taille1();
|
|
for (int i=1; i<= d2_epsBB_tdtTaille1; i++)
|
|
for (int j=1; j<= i; j++) // symétrie du tableau et du tenseur
|
|
{ *(d2_epsBB_tdt(i,j)) = 0.5 * (*((d2_gijBB_tdt)(i,j))) ;
|
|
*(d2_epsBB_tdt(j,i)) = *(d2_epsBB_tdt(i,j)) ;
|
|
};
|
|
};
|
|
|
|
// cas implicite : tous les parametres sont de resultats
|
|
//const Met_abstraite::Impli& Deformation::Cal_implicit( bool gradV_instantane
|
|
// ,TenseurBB & epsBB_tdt,Tableau <TenseurBB *> & d_epsBB_tdt
|
|
// ,TenseurBB& DepsBB,TenseurBB& delta_epsBB,bool premier_calcul)
|
|
const Met_abstraite::Impli& Deformation::Cal_implicit(const Tableau <double>& def_equi_t
|
|
,TenseurBB & epsBB_tdt,Tableau <TenseurBB *> & d_epsBB_tdt
|
|
,Tableau <double>& def_equi,TenseurBB& DepsBB,TenseurBB& delta_epsBB,bool premier_calcul)
|
|
{ bool gradV_instantane = false; // ************ pour l'instant figé
|
|
// appel de la metrique: on le fait ici et non dans les méthodes Cal_explicit_Almansi_tdt etc
|
|
// car pour d'autre déformation, par exemple sfe ou plaque, la méthode Deformation::Cal_explicit_tdt
|
|
// est surchargée car différentes, par contre les méthodes Cal_explicit_Almansi_tdt etc sont les mêmes
|
|
// toutes les variables de passage a metrique apres l'appel
|
|
// pointeront sur des variables deja dimensionnees
|
|
// pour les Tableau <> il y a dim
|
|
//------debug
|
|
//premier_calcul=true;
|
|
//---- fin debug
|
|
const Met_abstraite::Impli& ex =metrique->Cal_implicit
|
|
( *tabnoeud,gradV_instantane,(*tabDphi)(numInteg),nbNoeud,(*tabPhi)(numInteg)
|
|
,premier_calcul);
|
|
// ici il y a le choix entre les différents types de calcul de la déformation (Almansi, Green-Lagrange ..
|
|
switch (type_deformation)
|
|
{ case DEFORMATION_STANDART :
|
|
{Cal_implicit_Almansi
|
|
(gradV_instantane,epsBB_tdt,d_epsBB_tdt,DepsBB,delta_epsBB,premier_calcul,ex);
|
|
break;
|
|
}
|
|
case DEFORMATION_LOGARITHMIQUE:
|
|
{Cal_implicit_Logarithmique
|
|
(gradV_instantane,epsBB_tdt,d_epsBB_tdt,DepsBB,delta_epsBB,premier_calcul,ex);
|
|
break;
|
|
}
|
|
case DEFORMATION_CUMU_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEF_CUMUL_ROTATION_PROPRE :
|
|
{Cal_implicit_def_cumule
|
|
(gradV_instantane,epsBB_tdt,d_epsBB_tdt,DepsBB,delta_epsBB,premier_calcul,ex);
|
|
break;
|
|
}
|
|
default :
|
|
cout << "\nErreur : type de deformation ( " << Nom_type_deformation(type_deformation)
|
|
<< " ) non traite !\n";
|
|
cout << "Deformation::Cal_implicit(... \n";
|
|
Sortie(1);
|
|
};
|
|
// sauvegarde des infos à 0 et à t
|
|
// *** non car dans le cas d'un restart ce n'est pas vrai !!!! // éventuellement et init par recopie des grandeurs sur t
|
|
if (premier_calcul) saveDefResul->MiseAJourGrandeurs_a_0(metrique);
|
|
// sauvegarde des infos à tdt à chaque passage
|
|
saveDefResul->MiseAJourGrandeurs_a_tdt(metrique,DepsBB);
|
|
// *** pour supprimer les warnings à la compilation *** mais on ne doit jamais passer ici
|
|
// const Met_abstraite::Impli& toto = * (new Met_abstraite::Impli()); return toto;
|
|
|
|
// --- on calcul la déformation cumulée
|
|
{TenseurBH * delta_epsBH = NevezTenseurBH(epsBB_tdt.Dimension(), 0.);
|
|
*delta_epsBH = delta_epsBB * (*ex.gijHH_tdt);
|
|
double x_inter = (2./3. * ( ((*delta_epsBH) && (*delta_epsBH)) - Sqr(delta_epsBH->Trace()) /3. ));
|
|
if (x_inter < 0)
|
|
{if (Dabs(x_inter) < ConstMath::trespetit)
|
|
{ //debug
|
|
//cout << "\n **************** x_inter= "<<x_inter<<endl;
|
|
//fin debug
|
|
x_inter = 0.;
|
|
}
|
|
else
|
|
{ if (ParaGlob::NiveauImpression() > 0)
|
|
cout << "\n erreur calcul def equi: delta_def_equi2 est negatif ("<<x_inter<<") la racine -> nan! "
|
|
<< " on met a 0, mais ce n'est pas normal !! ";
|
|
if (ParaGlob::NiveauImpression() > 5)
|
|
cout << "\n Deformation::Cal_implicit(.." << endl;
|
|
};
|
|
};
|
|
double delta_eps_equi = sqrt(x_inter);
|
|
def_equi(1) = def_equi_t(1) + delta_eps_equi;
|
|
def_equi(4) = delta_eps_equi;
|
|
delete delta_epsBH;
|
|
};
|
|
|
|
{TenseurBH * epsBH = NevezTenseurBH(epsBB_tdt.Dimension(), 0.);
|
|
*epsBH = epsBB_tdt * (*ex.gijHH_tdt);
|
|
|
|
double y_inter = 2./3. * ( ((*epsBH) && (*epsBH)) - Sqr(epsBH->Trace()) /3. );
|
|
if (y_inter < 0)
|
|
{if (Dabs(y_inter) < ConstMath::trespetit)
|
|
{ //debug
|
|
//cout << "\n **************** x_inter= "<<x_inter<<endl;
|
|
//fin debug
|
|
y_inter = 0.;
|
|
}
|
|
else
|
|
{ if (ParaGlob::NiveauImpression() > 0)
|
|
cout << "\n erreur calcul def equi: sqr(def_dual_mises est negatif) ("<<y_inter<<") la racine -> nan! "
|
|
<< " on met a 0, mais ce n'est pas normal !! ";
|
|
if (ParaGlob::NiveauImpression() > 5)
|
|
cout << "\n Deformation::Cal_implicit(.." << endl;
|
|
};
|
|
};
|
|
def_equi(2) = sqrt(y_inter);
|
|
delete epsBH;
|
|
if (def_equi(2) > def_equi_t(3))
|
|
def_equi(3) = def_equi(2);
|
|
};
|
|
|
|
return ex;
|
|
};
|
|
|
|
// ------------------------ flambage linéaire ------------------------------
|
|
const Met_abstraite::flambe_lin& Deformation::Cal_flambe_lin
|
|
// ( bool gradV_instantane,TenseurBB & epsBB_tdt,Tableau <TenseurBB *> & d_epsBB_tdt,Tableau2 <TenseurBB *>& d2_epsBB_tdt
|
|
// ,TenseurBB& DepsBB,TenseurBB& delta_epsBB,bool premier_calcul)
|
|
( const Tableau <double>& def_equi_t,TenseurBB & epsBB_tdt,Tableau <TenseurBB *> & d_epsBB_tdt
|
|
,Tableau <double>& def_equi,TenseurBB& DepsBB,TenseurBB& delta_epsBB,bool premier_calcul)
|
|
{ bool gradV_instantane = false; // ************ pour l'instant figé
|
|
|
|
// --- le calcul est identique au cas implicite sauf que
|
|
// l'on doit absolument calculer la dérivée seconde de la déformation
|
|
|
|
// appel de la metrique: on le fait ici et non dans les méthodes Cal_explicit_Almansi_tdt etc
|
|
// car pour d'autre déformation, par exemple sfe ou plaque, la méthode Deformation::Cal_explicit_tdt
|
|
// est surchargée car différentes, par contre les méthodes Cal_explicit_Almansi_tdt etc sont les mêmes
|
|
// toutes les variables de passage a metrique apres l'appel
|
|
// pointeront sur des variables deja dimensionnees
|
|
// pour les Tableau <> il y a dimensionnement auto a l'affectation
|
|
const Met_abstraite::Impli& ex =metrique->Cal_implicit
|
|
( *tabnoeud,gradV_instantane,(*tabDphi)(numInteg),nbNoeud,(*tabPhi)(numInteg)
|
|
,premier_calcul);
|
|
// ici il y a le choix entre les différents types de calcul de la déformation (Almansi, Green-Lagrange ..
|
|
switch (type_deformation)
|
|
{ case DEFORMATION_STANDART :
|
|
{Cal_implicit_Almansi(gradV_instantane,epsBB_tdt,d_epsBB_tdt,DepsBB,delta_epsBB,premier_calcul,ex);
|
|
break;
|
|
}
|
|
case DEFORMATION_LOGARITHMIQUE:
|
|
{Cal_implicit_Logarithmique(gradV_instantane,epsBB_tdt,d_epsBB_tdt,DepsBB,delta_epsBB,premier_calcul,ex);
|
|
break;
|
|
}
|
|
// case DEFORMATION_CUMU_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEF_CUMUL_ROTATION_PROPRE :
|
|
// {Cal_implicit_def_cumule
|
|
// (gradV_instantane,epsBB_tdt,d_epsBB_tdt,DepsBB,delta_epsBB,premier_calcul,ex);
|
|
// break;
|
|
// }
|
|
default :
|
|
cout << "\nErreur : type de deformation ( " << Nom_type_deformation(type_deformation)
|
|
<< " ) non traite !\n";
|
|
cout << "Deformation::Cal_flambe_lin(... \n";
|
|
Sortie(1);
|
|
};
|
|
|
|
// --- on calcul la déformation cumulée
|
|
{TenseurBH * delta_epsBH = NevezTenseurBH(epsBB_tdt.Dimension(), 0.);
|
|
*delta_epsBH = delta_epsBB * (*ex.gijHH_tdt);
|
|
double delta_eps_equi = sqrt(2./3. * ( ((*delta_epsBH) && (*delta_epsBH)) - Sqr(delta_epsBH->Trace()) /3. ));
|
|
def_equi(1) = def_equi_t(1) + delta_eps_equi;
|
|
def_equi(4) = delta_eps_equi;
|
|
delete delta_epsBH;
|
|
};
|
|
|
|
{TenseurBH * epsBH = NevezTenseurBH(epsBB_tdt.Dimension(), 0.);
|
|
*epsBH = epsBB_tdt * (*ex.gijHH_tdt);
|
|
def_equi(2) = sqrt(2./3. * ( ((*epsBH) && (*epsBH)) - Sqr(epsBH->Trace()) /3. ));
|
|
delete epsBH;
|
|
if (def_equi(2) > def_equi_t(3))
|
|
def_equi(3) = def_equi(2);
|
|
};
|
|
|
|
// sauvegarde des infos à 0 éventuellement et init par recopie des grandeurs sur t
|
|
if (premier_calcul) saveDefResul->MiseAJourGrandeurs_a_0(metrique);
|
|
// sauvegarde des infos à tdt à chaque passage
|
|
saveDefResul->MiseAJourGrandeurs_a_tdt(metrique,DepsBB);
|
|
// *** pour supprimer les warnings à la compilation *** mais on ne doit jamais passer ici
|
|
// const Met_abstraite::flambe_lin& toto = * (new Met_abstraite::flambe_lin()); return toto;
|
|
return (Met_abstraite::flambe_lin&) ex;
|
|
};
|
|
|
|
// ------------------------- cas de la dilatation thermique ------------------------
|
|
// l'objectif est de calculer la déformation d'origine thermique et la déformation d'origine mécanique
|
|
// temperature_tdt,temperature_t : températures, temperature_0: température initiale
|
|
// atdt : booléen qui indique si les grandeurs à tdt sont disponible ou pas
|
|
// avec_repercution_sur_def_meca: si oui on met à jour la déformation méca, sinon, on ne calcul que les def thermiques
|
|
void Deformation::DeformationThermoMecanique(const double& temperature_0,const TenseurBB& gijBB,const ThermoDonnee& dTP
|
|
,const TenseurBB & epsBB_totale
|
|
,TenseurBB & epsBB_therm,const double& temperature_tdt,TenseurBB & epsBB_meca
|
|
,const double& temperature_t
|
|
,TenseurBB & DepsBB_totale,TenseurBB & DepsBB_therm,TenseurBB & DepsBB_meca, bool atdt
|
|
, bool avec_repercution_sur_def_meca)
|
|
{ // la dilatation est déterminée par l'élévation de température
|
|
double coef_dila_global = dTP.Dilatation() * (temperature_tdt-temperature_0);
|
|
// -- cas de la déformation
|
|
epsBB_therm = coef_dila_global * gijBB;
|
|
// -- 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
|
|
{ // 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;
|
|
};
|
|
if (atdt)
|
|
{ // cas d'un calcul avec les grandeurs à tdt disponibles
|
|
double coef_dila_t_tdt = dTP.Dilatation() * (temperature_tdt-temperature_t);
|
|
DepsBB_therm = coef_dila_t_tdt * gijBB * unSurDeltat;
|
|
}
|
|
else
|
|
{ // cas où les valeurs à tdt ne sont pas dispo, on considère un coef moyen sur toute la durée
|
|
// recup de l'incrément du temps global
|
|
double ttemps=ParaGlob::Variables_de_temps().TempsCourant();
|
|
double unSurttemps=0;
|
|
if (Abs(ttemps) >= ConstMath::trespetit)
|
|
{unSurttemps = 1./ttemps;}
|
|
else
|
|
// si l'incrément de temps est tres petit on remplace 1/ttemps par un nombre tres grand
|
|
{ // un pas de temps doit être positif !! or certaine fois il peut y avoir des pb
|
|
if (unSurttemps < 0)
|
|
{ cout << "\n le pas de temps est négatif !! "; };
|
|
unSurttemps = ConstMath::tresgrand;
|
|
};
|
|
DepsBB_therm = coef_dila_global * gijBB * unSurttemps;
|
|
};
|
|
|
|
|
|
// switch (abs(epsBB_meca.Dimension()))
|
|
// { case 1: epsBB_therm = coef_dila * IdBB1;
|
|
// case 2: epsBB_therm = coef_dila * IdBB2;
|
|
// case 3: epsBB_therm = coef_dila * IdBB3;
|
|
// }
|
|
if (avec_repercution_sur_def_meca)
|
|
{ epsBB_meca = epsBB_totale - epsBB_therm; // pour la déformation
|
|
DepsBB_meca = DepsBB_totale - DepsBB_therm; // pour la vitesse de déformation
|
|
};
|
|
//// -- debug
|
|
//cout << "\n debug Deformation::DeformationThermoMecanique( ";
|
|
//cout << "\n coef_dila_global= " << coef_dila_global << " epsBB_therm(1,1)= "<< epsBB_therm(1,1)
|
|
// << " delta_temp= "<< (temperature_tdt-temperature_0)
|
|
// << " epsBB_meca(1,1)= " << epsBB_meca(1,1) << endl;
|
|
//// -- fin debug
|
|
|
|
};
|
|
|
|
// ========== remontee aux informations =========================
|
|
|
|
// cas sortie d'un calcul implicit
|
|
// Aa(i,a) = Aa^i_{.a}, avec g^i = Aa^i_{.a} * Ip^a
|
|
// tout ce passe comme si Ip^a est la nouvelle base vers laquelle on veut évoluer
|
|
const Met_abstraite::InfoImp Deformation::RemontImp(bool absolue,Mat_pleine& Aa0,Mat_pleine& Aafin)
|
|
{ Met_abstraite::InfoImp ex = metrique->Cal_InfoImp
|
|
( *tabnoeud,(*tabDphi)(numInteg),(*tabPhi)(numInteg),nbNoeud);
|
|
// determination des matrices de transformation de base
|
|
BaseB & giB0 = *(ex.giB_0);
|
|
BaseB & giB = *(ex.giB_tdt);
|
|
BaseH & giH0 = *(ex.giH_0);
|
|
BaseH & giH = *(ex.giH_tdt);
|
|
BasePassage(absolue,giB0,giB,giH0,giH,Aa0,Aafin);
|
|
return ex;
|
|
};
|
|
|
|
// cas sortie d'un calcul implicit
|
|
// sans le calcul des matrices de passage
|
|
const Met_abstraite::InfoImp Deformation::RemontImp()
|
|
{ Met_abstraite::InfoImp ex = metrique->Cal_InfoImp
|
|
( *tabnoeud,(*tabDphi)(numInteg),(*tabPhi)(numInteg),nbNoeud);
|
|
// determination des matrices de transformation de base
|
|
BaseB & giB0 = *(ex.giB_0);
|
|
BaseB & giB = *(ex.giB_tdt);
|
|
BaseH & giH0 = *(ex.giH_0);
|
|
BaseH & giH = *(ex.giH_tdt);
|
|
return ex;
|
|
};
|
|
|
|
// cas sortie d'un calcul explicit à t
|
|
// Aa(i,a) = Aa^i_{.a}, avec g^i = Aa^i_{.a} * Ip^a
|
|
// tout ce passe comme si Ip^a est la nouvelle base vers laquelle on veut évoluer
|
|
const Met_abstraite::InfoExp_t Deformation::RemontExp_t(bool absolue,Mat_pleine& Aa0,Mat_pleine& Aafin)
|
|
{ Met_abstraite::InfoExp_t ex = metrique->Cal_InfoExp_t
|
|
( *tabnoeud,(*tabDphi)(numInteg),(*tabPhi)(numInteg),nbNoeud);
|
|
// determination des matrices de transformation de base
|
|
BaseB & giB0 = *(ex.giB_0);
|
|
BaseB & giB = *(ex.giB_t);
|
|
BaseH & giH0 = *(ex.giH_0);
|
|
BaseH & giH = *(ex.giH_t);
|
|
BasePassage(absolue,giB0,giB,giH0,giH,Aa0,Aafin);
|
|
return ex;
|
|
};
|
|
|
|
// cas sortie d'un calcul explicit à t
|
|
// sans le calcul des matrices de passage
|
|
const Met_abstraite::InfoExp_t Deformation::RemontExp_t()
|
|
{ Met_abstraite::InfoExp_t ex = metrique->Cal_InfoExp_t
|
|
( *tabnoeud,(*tabDphi)(numInteg),(*tabPhi)(numInteg),nbNoeud);
|
|
// determination des matrices de transformation de base
|
|
BaseB & giB0 = *(ex.giB_0);
|
|
BaseB & giB = *(ex.giB_t);
|
|
BaseH & giH0 = *(ex.giH_0);
|
|
BaseH & giH = *(ex.giH_t);
|
|
return ex;
|
|
};
|
|
|
|
// cas sortie d'un calcul explicit à tdt
|
|
// Aa(i,a) = Aa^i_{.a}, avec g^i = Aa^i_{.a} * Ip^a
|
|
// tout ce passe comme si Ip^a est la nouvelle base vers laquelle on veut évoluer
|
|
const Met_abstraite::InfoExp_tdt Deformation::RemontExp_tdt(bool absolue,Mat_pleine& Aa0,Mat_pleine& Aafin)
|
|
{ Met_abstraite::InfoExp_tdt ex = metrique->Cal_InfoExp_tdt
|
|
( *tabnoeud,(*tabDphi)(numInteg),(*tabPhi)(numInteg),nbNoeud);
|
|
// determination des matrices de transformation de base
|
|
BaseB & giB0 = *(ex.giB_0);
|
|
BaseB & giB = *(ex.giB_tdt);
|
|
BaseH & giH0 = *(ex.giH_0);
|
|
BaseH & giH = *(ex.giH_tdt);
|
|
BasePassage(absolue,giB0,giB,giH0,giH,Aa0,Aafin);
|
|
return ex;
|
|
};
|
|
|
|
// cas sortie d'un calcul explicit à tdt
|
|
// sans le calcul des matrices de passage
|
|
const Met_abstraite::InfoExp_tdt Deformation::RemontExp_tdt()
|
|
{ Met_abstraite::InfoExp_tdt ex = metrique->Cal_InfoExp_tdt
|
|
( *tabnoeud,(*tabDphi)(numInteg),(*tabPhi)(numInteg),nbNoeud);
|
|
// determination des matrices de transformation de base
|
|
BaseB & giB0 = *(ex.giB_0);
|
|
BaseB & giB = *(ex.giB_tdt);
|
|
BaseH & giH0 = *(ex.giH_0);
|
|
BaseH & giH = *(ex.giH_tdt);
|
|
return ex;
|
|
};
|
|
|
|
// cas sortie d'un calcul à 0, t et tdt
|
|
// Aa(i,a) = Aa^i_{.a}, avec g^i = Aa^i_{.a} * Ip^a
|
|
// tout ce passe comme si Ip^a est la nouvelle base vers laquelle on veut évoluer
|
|
const Met_abstraite::Info0_t_tdt Deformation::Remont0_t_tdt(bool absolue,Mat_pleine& Aa0,Mat_pleine& Aat,Mat_pleine& Aatdt)
|
|
{ Met_abstraite::Info0_t_tdt ex = metrique->Cal_Info0_t_tdt
|
|
( *tabnoeud,(*tabDphi)(numInteg),(*tabPhi)(numInteg),nbNoeud);
|
|
// determination des matrices de transformation de base
|
|
BaseB & giB0 = *(ex.giB_0);
|
|
BaseB & giBt = *(ex.giB_t);
|
|
BaseB & giBtdt = *(ex.giB_tdt);
|
|
BaseH & giH0 = *(ex.giH_0);
|
|
BaseH & giHt = *(ex.giH_t);
|
|
BaseH & giHtdt = *(ex.giH_tdt);
|
|
BasePassage(absolue,giB0,giBt,giBtdt,giH0,giHt,giHtdt,Aa0,Aat,Aatdt);
|
|
return ex;
|
|
};
|
|
|
|
// cas sortie d'un calcul à 0, t et tdt
|
|
// sans le calcul des matrices de passage
|
|
const Met_abstraite::Info0_t_tdt Deformation::Remont0_t_tdt()
|
|
{ Met_abstraite::Info0_t_tdt ex = metrique->Cal_Info0_t_tdt
|
|
( *tabnoeud,(*tabDphi)(numInteg),(*tabPhi)(numInteg),nbNoeud);
|
|
// determination des matrices de transformation de base
|
|
BaseB & giB0 = *(ex.giB_0);
|
|
BaseB & giBt = *(ex.giB_t);
|
|
BaseB & giBtdt = *(ex.giB_tdt);
|
|
BaseH & giH0 = *(ex.giH_0);
|
|
BaseH & giHt = *(ex.giH_t);
|
|
BaseH & giHtdt = *(ex.giH_tdt);
|
|
return ex;
|
|
};
|
|
|
|
// cas sortie d'un calcul implicit
|
|
// mêmes fct que précédemment mais dans le cas où les éléments de métrique viennent justes
|
|
// d'être calculés, donc les seules grandeurs qui sont réellement calculées sont les matrices
|
|
// Aa0 et Aafin
|
|
// Aa(i,a) = Aa^i_{.a}, avec g^i = Aa^i_{.a} * Ip^a
|
|
// tout ce passe comme si Ip^a est la nouvelle base vers laquelle on veut évoluer
|
|
const Met_abstraite::InfoImp Deformation::RemontImpSansCalMet(bool absolue,Mat_pleine& Aa0,Mat_pleine& Aafin)
|
|
{ Met_abstraite::InfoImp ex = metrique->Recup_InfoImp();
|
|
// determination des matrices de transformation de base
|
|
BaseB & giB0 = *(ex.giB_0);
|
|
BaseB & giB = *(ex.giB_tdt);
|
|
BaseH & giH0 = *(ex.giH_0);
|
|
BaseH & giH = *(ex.giH_tdt);
|
|
BasePassage(absolue,giB0,giB,giH0,giH,Aa0,Aafin);
|
|
return ex;
|
|
};
|
|
|
|
// cas sortie d'un calcul explicit à t
|
|
// mêmes fct que précédemment mais dans le cas où les éléments de métrique viennent justes
|
|
// d'être calculés, donc les seules grandeurs qui sont réellement calculées sont les matrices
|
|
// Aa0 et Aafin
|
|
// Aa(i,a) = Aa^i_{.a}, avec g^i = Aa^i_{.a} * Ip^a
|
|
// tout ce passe comme si Ip^a est la nouvelle base vers laquelle on veut évoluer
|
|
const Met_abstraite::InfoExp_t Deformation::RemontExp_tSansCalMet(bool absolue,Mat_pleine& Aa0,Mat_pleine& Aafin)
|
|
{ Met_abstraite::InfoExp_t ex = metrique->Recup_InfoExp_t();
|
|
// determination des matrices de transformation de base
|
|
BaseB & giB0 = *(ex.giB_0);
|
|
BaseB & giB = *(ex.giB_t);
|
|
BaseH & giH0 = *(ex.giH_0);
|
|
BaseH & giH = *(ex.giH_t);
|
|
BasePassage(absolue,giB0,giB,giH0,giH,Aa0,Aafin);
|
|
return ex;
|
|
};
|
|
|
|
// cas sortie d'un calcul explicit à tdt
|
|
// mêmes fct que précédemment mais dans le cas où les éléments de métrique viennent justes
|
|
// d'être calculés, donc les seules grandeurs qui sont réellement calculées sont les matrices
|
|
// Aa0 et Aafin
|
|
// Aa(i,a) = Aa^i_{.a}, avec g^i = Aa^i_{.a} * Ip^a
|
|
// tout ce passe comme si Ip^a est la nouvelle base vers laquelle on veut évoluer
|
|
const Met_abstraite::InfoExp_tdt Deformation::RemontExp_tdtSansCalMet(bool absolue,Mat_pleine& Aa0,Mat_pleine& Aafin)
|
|
{ Met_abstraite::InfoExp_tdt ex = metrique->Recup_InfoExp_tdt();
|
|
// determination des matrices de transformation de base
|
|
BaseB & giB0 = *(ex.giB_0);
|
|
BaseB & giB = *(ex.giB_tdt);
|
|
BaseH & giH0 = *(ex.giH_0);
|
|
BaseH & giH = *(ex.giH_tdt);
|
|
BasePassage(absolue,giB0,giB,giH0,giH,Aa0,Aafin);
|
|
return ex;
|
|
};
|
|
|
|
// cas sortie d'un calcul à 0, t et tdt
|
|
// mêmes fct que précédemment mais dans le cas où les éléments de métrique viennent justes
|
|
// d'être calculés, donc les seules grandeurs qui sont réellement calculées sont les matrices
|
|
// Aa0 et Aafin
|
|
// Aa(i,a) = Aa^i_{.a}, avec g^i = Aa^i_{.a} * Ip^a
|
|
// tout ce passe comme si Ip^a est la nouvelle base vers laquelle on veut évoluer
|
|
const Met_abstraite::Info0_t_tdt Deformation::Remont0_t_tdtSansCalMet(bool absolue,Mat_pleine& Aa0,Mat_pleine& Aat,Mat_pleine& Aatdt)
|
|
{ Met_abstraite::Info0_t_tdt ex = metrique->Recup_Info0_t_tdt();
|
|
// determination des matrices de transformation de base
|
|
BaseB & giB0 = *(ex.giB_0);
|
|
BaseB & giBt = *(ex.giB_t);
|
|
BaseB & giBtdt = *(ex.giB_tdt);
|
|
BaseH & giH0 = *(ex.giH_0);
|
|
BaseH & giHt = *(ex.giH_t);
|
|
BaseH & giHtdt = *(ex.giH_tdt);
|
|
BasePassage(absolue,giB0,giBt,giBtdt,giH0,giHt,giHtdt,Aa0,Aat,Aatdt);
|
|
return ex;
|
|
};
|
|
|
|
// cas sortie d'un calcul à 0, t et tdt avec tous les métriques associées
|
|
// mêmes fct que précédemment mais dans le cas où les éléments de métrique viennent justes
|
|
// d'être calculés, donc les seules grandeurs qui sont réellement calculées sont les matrices
|
|
// Aa0 et Aafin
|
|
// Aa(i,a) = Aa^i_{.a}, avec g^i = Aa^i_{.a} * Ip^a
|
|
// tout ce passe comme si Ip^a est la nouvelle base vers laquelle on veut évoluer
|
|
const Met_abstraite::Info_et_metrique_0_t_tdt Deformation::Remont_et_metrique_0_t_tdtSansCalMet(bool absolue,Mat_pleine& Aa0,Mat_pleine& Aat,Mat_pleine& Aatdt)
|
|
{ Met_abstraite::Info_et_metrique_0_t_tdt ex = metrique->Recup_Info_et_metrique_0_t_tdt();
|
|
// determination des matrices de transformation de base
|
|
BaseB & giB0 = *(ex.giB_0);
|
|
BaseB & giBt = *(ex.giB_t);
|
|
BaseB & giBtdt = *(ex.giB_tdt);
|
|
BaseH & giH0 = *(ex.giH_0);
|
|
BaseH & giHt = *(ex.giH_t);
|
|
BaseH & giHtdt = *(ex.giH_tdt);
|
|
BasePassage(absolue,giB0,giBt,giBtdt,giH0,giHt,giHtdt,Aa0,Aat,Aatdt);
|
|
return ex;
|
|
};
|
|
|
|
// cas où l'on veut les matrices de passages à 0 et final
|
|
// voir Deformation.h pour plus d'info
|
|
// Aa(i,a) = Aa^i_{.a}, avec g^i = Aa^i_{.a} * Ip^a
|
|
// tout ce passe comme si Ip^a est la nouvelle base vers laquelle on veut évoluer
|
|
// (voir Deformation.h pour un descriptif plus complet)
|
|
// si absolue = true: on fait un passage vers la base absolue
|
|
// si = false : on fait un passage vers une base ad hoc
|
|
void Deformation::BasePassage
|
|
(bool absolue,const BaseB & giB0,const BaseB & giB,const BaseH & giH0,const BaseH & giH,
|
|
Mat_pleine& Aa0,Mat_pleine& Aafin)
|
|
{ // determination des matrices de transformation de base
|
|
int dim = giB0.NbVecteur();
|
|
|
|
// dim_espace X nb_vecteur X taille_matrice
|
|
|
|
// cas d'une sortie en globale
|
|
// 1X1X1 ou 2X2X2 ou 3X3X3
|
|
if ((dim == ParaGlob::Dimension()) && (Aa0.Nb_ligne() == dim))
|
|
{ // --- ici il n'y a pas a priori de repère ad hoc, donc le calcul ne dépend pas de "absolue"
|
|
|
|
// petite vérif
|
|
#ifdef MISE_AU_POINT
|
|
if ((Aa0.Nb_ligne() != dim) && (Aa0.Nb_colonne() !=dim)
|
|
&& (Aafin.Nb_ligne() != dim) && (Aafin.Nb_colonne() !=dim))
|
|
{ cout << "\nErreur1 : les matrices Aa0 et /ou Aafin ne sont pas correctement"
|
|
<< " dimensionnees ! \n";
|
|
cout << "\n Aa0= "; Aa0.Affiche();
|
|
cout << "\n Aafin= "; Aafin.Affiche();
|
|
cout << "void Deformation::BasePassage( \n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
for (int i=1;i<=dim;i++)
|
|
for (int j=1;j<=dim;j++)
|
|
{Aa0 (i,j) = giH0(i)(j);
|
|
Aafin(i,j) =giH(i)(j);
|
|
};
|
|
}
|
|
else if ((dim==2)&&(ParaGlob::Dimension()==3))
|
|
// cela comprend les cas: 3X2X2 -> un repère local ad hoc en 2D
|
|
// 3X2X3 -> un repère local ad hoc en 3D
|
|
// ==== cas d'élément de membrane en 3D ====
|
|
{// 1) si absolue = false: l'objectif est de determiner un repere pertinant dans le cas de membrane .
|
|
// choix : un repere qui appartiend a la facette, obtenu apres projection
|
|
// du repere global
|
|
//------ cas de la config initiale, on regarde si la projection de I1 n'est pas trop petite
|
|
// def de la normale a la facette
|
|
// 2) si absolue = true; on complète le repère des gi avec la normale et la matrice de passage
|
|
// correspond au passage des gi complètés -> I_a
|
|
|
|
Coordonnee N = (Util::ProdVec_coorBN(giB0(1),giB0(2))).Normer();
|
|
Coordonnee ve(0.,-N(3),N(2)); // = ProdVec(N,I1)
|
|
double norve = ve.Norme();
|
|
Tableau <Coordonnee> vi(2); // les vecteurs plans orthonormes de la facette
|
|
if (!absolue)
|
|
{Coordonnee ve(0.,-N(3),N(2)); // = ProdVec(N,I1)
|
|
double norve = ve.Norme();
|
|
Tableau <Coordonnee> vi(2); // les vecteurs plans orthonormes de la facette
|
|
if (norve >= 0.01)
|
|
{ vi(2) = ve.Normer();
|
|
vi(1) = Util::ProdVec_coor(vi(2),N);
|
|
}
|
|
else
|
|
{ ve.Change_Coordonnee(3,N(3),0.,-N(1)); // = ProdVec(I2,N)
|
|
vi(1) = ve.Normer();
|
|
vi(2) = Util::ProdVec_coor(N,vi(1));
|
|
};
|
|
for (int al=1 ;al<=2;al++)
|
|
{Aa0(1,al) = giH0.Coordo(1) * vi(al) ;
|
|
Aa0(2,al) = giH0.Coordo(2) * vi(al) ;
|
|
};
|
|
// si on veut une matrice 3x3, il faut complèter la matrice avec un troisième vecteur
|
|
// comme les vi sont normaux à N, le troisième vecteur est le vecteur N
|
|
// qui ne peut pas s'exprimer dans le repère local des gi donc on considère qu'il s'exprime vis-à-vis
|
|
// du troisième vecteur qui n'est autre que N
|
|
if (Aa0.Nb_ligne()==3)
|
|
// ici on a Ip_3 == N et également g_3=g^3=N
|
|
{for (int al=1 ;al<=2;al++)
|
|
{Aa0(3,al) = N * vi(al) ;
|
|
Aa0(al,3) = giH0.Coordo(al) * N ;
|
|
};
|
|
Aa0(3,3)= 1.; // == N . N
|
|
};
|
|
}
|
|
else // cas on l'on veut le passage des gi et N vers I_a
|
|
{// g^i = Aa^i_{.a} * I^a -> donc Aa^i_{.a} c'est directement les coordonnées de g^i
|
|
for (int al=1 ;al < 4;al++)
|
|
{Aa0(1,al) = giH0.Coordo(1)(al) ;
|
|
Aa0(2,al) = giH0.Coordo(2)(al) ;
|
|
};
|
|
// pour le troisième: N = Aa^3_{.a} * I^a -> c'est aussi directement les coordonnées de N
|
|
Aa0.RemplaceLigneSpe(3,N.Vect());
|
|
};
|
|
|
|
|
|
//------ cas de la config finale,
|
|
N = (Util::ProdVec_coorBN(giB(1),giB(2))).Normer();
|
|
if (!absolue)
|
|
{ve.Change_Coordonnee(3,0.,-N(3),N(2)); // = ProdVec(N,I1)
|
|
norve = ve.Norme();
|
|
Tableau <Coordonnee> Aa(2);
|
|
if (norve >= ConstMath::petit)
|
|
{ Aa(2) = ve.Normer();
|
|
Aa(1) = Util::ProdVec_coor(Aa(2),N);
|
|
}
|
|
else
|
|
{ ve.Change_Coordonnee(3,N(3),0.,-N(1)); // = ProdVec(I2,N)
|
|
Aa(1) = ve.Normer();
|
|
Aa(2) = Util::ProdVec_coor(N,Aa(1));
|
|
};
|
|
|
|
for (int be=1;be<=2;be++)
|
|
{ Aafin(1,be) = giH.Coordo(1) * Aa(be);
|
|
Aafin(2,be) = giH.Coordo(2) * Aa(be);
|
|
};
|
|
// si on veut une matrice 3x3, il faut complèter la matrice avec un troisième vecteur
|
|
// comme les vi sont normaux à N, le troisième vecteur est le vecteur N
|
|
// qui ne peut pas s'exprimer dans le repère local des gi donc on considère qu'il s'exprime vis-à-vis
|
|
// du troisième vecteur qui n'est autre que N
|
|
if (Aafin.Nb_ligne()==3)
|
|
// ici on a Ip_3 == N et également g_3=g^3=N
|
|
{for (int al=1 ;al<=2;al++)
|
|
{Aafin(3,al) = N * vi(al) ;
|
|
Aafin(al,3) = giH.Coordo(al) * N ;
|
|
};
|
|
Aafin(3,3)= 1.; // == N . N
|
|
};
|
|
}
|
|
else // cas on l'on veut le passage des gi et N vers I_a
|
|
{// g^i = Aa^i_{.a} * I^a -> donc Aa^i_{.a} c'est directement les coordonnées de g^i
|
|
for (int al=1 ;al < 4;al++)
|
|
{Aafin(1,al) = giH.Coordo(1)(al) ;
|
|
Aafin(2,al) = giH.Coordo(2)(al) ;
|
|
};
|
|
// pour le troisième: N = Aa^3_{.a} * I^a -> c'est aussi directement les coordonnées de N
|
|
Aafin.RemplaceLigneSpe(3,N.Vect());
|
|
};
|
|
}
|
|
else if (dim==1)
|
|
// ==== cas des éléments 1D en espace 1D, 2D ou 3D ====
|
|
{ if (!absolue)
|
|
{switch (ParaGlob::Dimension())
|
|
{ case 1: // normalement on ne devrait pas passer ici !! car ce cas est déjà traité au début
|
|
{cout << "\nErreur : bug!! on ne devrait pas passer ici \n";
|
|
cout << "void Deformation::BasePassage( \n";
|
|
Sortie(1);
|
|
break;
|
|
}
|
|
case 3: // on est dans un espace 3D, ici on ne fait que le particulier à 3D et le reste est
|
|
// fait dans le case 2: qui suit
|
|
// 3X1X1 ou 3X1X2 ou 3X1X3, 2X1X1 , 2X1X2
|
|
if (Aa0.Nb_ligne() == 3 )
|
|
// 3X1X3
|
|
{ // tous les tenseurs vont utiliser que le premier vecteur, donc le troisième peut être quelconque
|
|
// et l'expression de giH(3) n'existant pas on dit que par défaut (et par simplicité)
|
|
// giH(3) = 1 * IP(3) d'où
|
|
Aa0 (3,3) = Aafin(3,3) = 1.;
|
|
// et on initialise les autres composantes au cas où
|
|
Aa0 (1,3) = Aa0 (3,1) = Aafin(1,3) = Aafin(3,1) = 0.;
|
|
Aa0 (2,3) = Aa0 (3,2) = Aafin(2,3) = Aafin(3,2) = 0.;
|
|
// pas de break, on continue sur le 2D
|
|
};
|
|
case 2: // on est dans un espace 2D, 3X1X1 ou 3X1X2 ou 3X1X3
|
|
{ // le premier vecteur intéressant c'est le vecteur collinéaire avec gH(1), mais normé
|
|
double norme0 = giH0(1).Norme();
|
|
double norme = giH(1).Norme();
|
|
Aa0 (1,1) = norme0;
|
|
Aafin(1,1) = norme;
|
|
// fin du cas 3X1X1 et 2X1X1
|
|
if (Aa0.Nb_ligne() > 1)
|
|
// 3X1X2 , 3X1X3 , 2X1X2
|
|
// tous les tenseurs vont utiliser que le premier vecteur, donc le second peut être quelconque
|
|
// et l'expression de giH(2) n'existant pas on dit que par défaut (et par simplicité)
|
|
// giH(2) = 1 * IP(2) d'où
|
|
{Aa0 (2,2) = Aafin(2,2) = 1.;
|
|
// et on initialise les autres composantes au cas où
|
|
Aa0 (1,2) = Aa0 (2,1) = Aafin(1,2) = Aafin(2,1) = 0.;
|
|
};
|
|
break;
|
|
}
|
|
default: cout << "\n erreur grossiere de dimension !! \n Deformation::BasePassage(.. ";
|
|
Sortie(1);
|
|
};
|
|
}
|
|
else // sinon on veut arriver en Ia
|
|
{ // On ne connait que le premier vecteur et normalement c'est seulement celui-là qui est
|
|
// utilisé, par contre il faut complèter la matrice pour qu'elle ne soit pas singulière
|
|
Aa0.Initialise(0.);Aafin.Initialise(0.);
|
|
switch (ParaGlob::Dimension())
|
|
{ case 1: // normalement on ne devrait pas passer ici !! car ce cas est déjà traité au début
|
|
{cout << "\nErreur : bug!! on ne devrait pas passer ici \n";
|
|
cout << "void Deformation::BasePassage( \n";
|
|
Sortie(1);
|
|
break;
|
|
}
|
|
case 3: // on est dans un espace 3D,
|
|
{CoordonneeH V02(3); CoordonneeH V03(3);
|
|
// on calcule deux vecteurs arbitraires normaux, avec un résultat orthonormé V2,V3
|
|
// mais pas giH0(1) !
|
|
MathUtil2::Def_vecteurs_plan(giH0(1),V02,V03);
|
|
// idem pour le final
|
|
CoordonneeH V2(3); CoordonneeH V3(3);
|
|
MathUtil2::Def_vecteurs_plan(giH(1),V2,V3);
|
|
int bornesup = ParaGlob::Dimension() +1;
|
|
for (int al=1 ;al < bornesup;al++)
|
|
{Aa0(1,al) = giH0.Coordo(1)(al) ;
|
|
Aafin(1,al) = giH.Coordo(1)(al);
|
|
Aa0(2,al) = V02(al) ;
|
|
Aafin(2,al) = V2(al) ;
|
|
Aa0(3,al) = V03(al) ;
|
|
Aafin(3,al) = V3(al) ;
|
|
};
|
|
break;
|
|
}
|
|
case 2: // on est dans un espace 2D,
|
|
{CoordonneeH V02(2);
|
|
// on calcule le vecteur normal,
|
|
// mais pas giH0(1) !
|
|
MathUtil2::Def_vecteurs_plan(giH0(1),V02);
|
|
// idem pour le final
|
|
CoordonneeH V2(2);
|
|
MathUtil2::Def_vecteurs_plan(giH(1),V2);
|
|
int bornesup = ParaGlob::Dimension() +1;
|
|
for (int al=1 ;al < bornesup;al++)
|
|
{Aa0(1,al) = giH0.Coordo(1)(al) ;
|
|
Aafin(1,al) = giH.Coordo(1)(al);
|
|
Aa0(2,al) = V02(al) ;
|
|
Aafin(2,al) = V2(al) ;
|
|
};
|
|
break;
|
|
}
|
|
default: cout << "\n erreur2 grossiere de dimension !! \n Deformation::BasePassage(.. ";
|
|
Sortie(1);
|
|
};
|
|
};
|
|
}
|
|
else
|
|
{// pour les autres cas on ramene la matrice identite
|
|
#ifdef MISE_AU_POINT
|
|
if ((Aa0.Nb_ligne() != dim) && (Aa0.Nb_colonne() !=dim) &&
|
|
(Aafin.Nb_ligne() != dim) && (Aafin.Nb_colonne() !=dim))
|
|
{ cout << "\nErreur : les matrices Aa0 et /ou Aafin ne sont pas correctement"
|
|
<< " dimensionnees !\n";
|
|
cout << "void Deformation::BasePassage( \n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
for (int i=1;i<=dim;i++)
|
|
{ for (int j=1;j<=dim;j++)
|
|
{Aa0 (i,j) = 0.;Aafin(i,j) = 0.;}
|
|
Aa0 (i,i) = 1.; Aafin(i,i) = 1.;
|
|
};
|
|
};
|
|
// retour
|
|
return;
|
|
};
|
|
|
|
// cas où l'on veut les matrices de passages à 0 t et tdt
|
|
// voir Deformation.h pour plus d'info
|
|
// Aa(i,a) = Aa^i_{.a}, avec g^i = Aa^i_{.a} * Ip^a
|
|
// tout ce passe comme si Ip^a est la nouvelle base vers laquelle on veut évoluer
|
|
// (voir Deformation.h pour un descriptif plus complet)
|
|
void Deformation::BasePassage(bool absolue,const BaseB & giB0,const BaseB & giB_t,const BaseB & giB_tdt
|
|
,const BaseH & giH0,const BaseH & giH_t,const BaseH & giH_tdt
|
|
,Mat_pleine& Aa0,Mat_pleine& Aa_t,Mat_pleine& Aa_tdt)
|
|
{
|
|
// determination des matrices de transformation de base
|
|
int dim = giB0.NbVecteur();
|
|
|
|
// dim_espace X nb_vecteur X taille_matrice
|
|
|
|
// cas d'une sortie en globale
|
|
// 1X1X1 ou 2X2X2 ou 3X3X3
|
|
if ((dim == ParaGlob::Dimension()) && (Aa0.Nb_ligne() == dim))
|
|
{ // --- ici il n'y a pas a priori de repère ad hoc, donc le calcul ne dépend pas de "absolue"
|
|
|
|
// petite vérif
|
|
#ifdef MISE_AU_POINT
|
|
if ((Aa0.Nb_ligne() != dim) && (Aa0.Nb_colonne() !=dim)
|
|
&& (Aa_t.Nb_ligne() != dim) && (Aa_t.Nb_colonne() !=dim)
|
|
&& (Aa_tdt.Nb_ligne() != dim) && (Aa_tdt.Nb_colonne() !=dim))
|
|
{ cout << "\nErreur1 : les matrices Aa0 et /ou Aa_t et / ou Aa_tdt ne sont pas correctement"
|
|
<< " dimensionnees ! \n";
|
|
cout << "\n Aa0= "; Aa0.Affiche();
|
|
cout << "\n Aa_t= "; Aa_t.Affiche();
|
|
cout << "\n Aa_tdt= "; Aa_tdt.Affiche();
|
|
cout << "void Deformation::BasePassage( \n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
for (int i=1;i<=dim;i++)
|
|
for (int j=1;j<=dim;j++)
|
|
{Aa0 (i,j) = giH0(i)(j);
|
|
Aa_t(i,j) =giH_t(i)(j);
|
|
Aa_tdt(i,j) =giH_tdt(i)(j);
|
|
};
|
|
}
|
|
else if ((dim==2)&&(ParaGlob::Dimension()==3))
|
|
// cela comprend les cas: 3X2X2 -> un repère local ad hoc en 2D
|
|
// 3X2X3 -> un repère local ad hoc en 3D
|
|
// ==== cas d'élément de membrane en 3D ====
|
|
{// 1) si absolue = false: l'objectif est de determiner un repere pertinant dans le cas de membrane .
|
|
// choix : un repere qui appartiend a la facette, obtenu apres projection
|
|
// du repere global
|
|
//------ cas de la config initiale, on regarde si la projection de I1 n'est pas trop petite
|
|
// def de la normale a la facette
|
|
// 2) si absolue = true; on complète le repère des gi avec la normale et la matrice de passage
|
|
// correspond au passage des gi complètés -> I_a
|
|
|
|
Coordonnee N = (Util::ProdVec_coorBN(giB0(1),giB0(2))).Normer();
|
|
Coordonnee ve(0.,-N(3),N(2)); // = ProdVec(N,I1), donc normal à N
|
|
double norve = ve.Norme();
|
|
Tableau <Coordonnee> vi(2); // les vecteurs plans orthonormes de la facette
|
|
if (!absolue)
|
|
{if (norve >= 0.01)
|
|
{ vi(2) = ve.Normer();
|
|
vi(1) = Util::ProdVec_coor(vi(2),N);// donc normal à N
|
|
}
|
|
else
|
|
{ ve.Change_Coordonnee(3,N(3),0.,-N(1)); // = ProdVec(I2,N), donc normal à N
|
|
vi(1) = ve.Normer();
|
|
vi(2) = Util::ProdVec_coor(N,vi(1));// donc normal à N
|
|
};
|
|
// maintenant expression dans le repère local
|
|
// Aa^i_{.a} = g^i . Ip_a avec les Ip_a == vi(a)
|
|
for (int al=1 ;al<=2;al++)
|
|
{Aa0(1,al) = giH0.Coordo(1) * vi(al) ;
|
|
Aa0(2,al) = giH0.Coordo(2) * vi(al) ;
|
|
};
|
|
// si on veut une matrice 3x3, il faut complèter la matrice avec un troisième vecteur
|
|
// comme les vi sont normaux à N, le troisième vecteur est le vecteur N
|
|
// qui ne peut pas s'exprimer dans le repère local des gi donc on considère qu'il s'exprime vis-à-vis
|
|
// du troisième vecteur qui n'est autre que N
|
|
if (Aa0.Nb_ligne()==3)
|
|
// ici on a Ip_3 == N et également g_3=g^3=N
|
|
{for (int al=1 ;al<=2;al++)
|
|
{Aa0(3,al) = N * vi(al) ;
|
|
Aa0(al,3) = giH0.Coordo(al) * N ;
|
|
};
|
|
Aa0(3,3)= 1.; // == N . N
|
|
};
|
|
}
|
|
else // cas on l'on veut le passage des gi et N vers I_a
|
|
{// g^i = Aa^i_{.a} * I^a -> donc Aa^i_{.a} c'est directement les coordonnées de g^i
|
|
for (int al=1 ;al < 4;al++)
|
|
{Aa0(1,al) = giH0.Coordo(1)(al) ;
|
|
Aa0(2,al) = giH0.Coordo(2)(al) ;
|
|
};
|
|
// pour le troisième: N = Aa^3_{.a} * I^a -> c'est aussi directement les coordonnées de N
|
|
Aa0.RemplaceLigneSpe(3,N.Vect());
|
|
};
|
|
|
|
//------ cas de la config à t,
|
|
N = (Util::ProdVec_coorBN(giB_t(1),giB_t(2))).Normer();
|
|
Tableau <Coordonnee> Aa(2);
|
|
if (!absolue)
|
|
{ve.Change_Coordonnee(3,0.,-N(3),N(2)); // = ProdVec(N,I1)
|
|
norve = ve.Norme();
|
|
if (norve >= 0.01)
|
|
{ Aa(2) = ve.Normer();
|
|
Aa(1) = Util::ProdVec_coor(Aa(2),N);
|
|
}
|
|
else
|
|
{ ve.Change_Coordonnee(3,N(3),0.,-N(1)); // = ProdVec(I2,N)
|
|
Aa(1) = ve.Normer();
|
|
Aa(2) = Util::ProdVec_coor(N,Aa(1));
|
|
};
|
|
|
|
for (int be=1;be<=2;be++)
|
|
{ Aa_t(1,be) = giH_t.Coordo(1) * Aa(be);
|
|
Aa_t(2,be) = giH_t.Coordo(2) * Aa(be);
|
|
};
|
|
// si on veut une matrice 3x3, il faut complèter la matrice avec un troisième vecteur
|
|
// comme les vi sont normaux à N, le troisième vecteur est le vecteur N
|
|
// qui ne peut pas s'exprimer dans le repère local des gi donc on considère qu'il s'exprime vis-à-vis
|
|
// du troisième vecteur qui n'est autre que N
|
|
if (Aa_t.Nb_ligne()==3)
|
|
// ici on a Ip_3 == N et également g_3=g^3=N
|
|
{for (int al=1 ;al<=2;al++)
|
|
{Aa_t(3,al) = N * vi(al) ;
|
|
Aa_t(al,3) = giH_t.Coordo(al) * N ;
|
|
};
|
|
Aa_t(3,3)= 1.; // == N . N
|
|
};
|
|
}
|
|
else // cas on l'on veut le passage des gi et N vers I_a
|
|
{// g^i = Aa^i_{.a} * I^a -> donc Aa^i_{.a} c'est directement les coordonnées de g^i
|
|
for (int al=1 ;al < 4;al++)
|
|
{Aa_t(1,al) = giH_t.Coordo(1)(al) ;
|
|
Aa_t(2,al) = giH_t.Coordo(2)(al) ;
|
|
};
|
|
// pour le troisième: N = Aa^3_{.a} * I^a -> c'est aussi directement les coordonnées de N
|
|
Aa_t.RemplaceLigneSpe(3,N.Vect());
|
|
};
|
|
|
|
//// ---- vérification que le déterminant n'est pas nul
|
|
//{double det = Aa_t(1,1) * Aa_t(2,2) - Aa_t(1,2) * Aa_t(2,1);
|
|
// if (Abs(det) < 0.00001)
|
|
// cout << "\n erreur det0 null " << det << " dans Deformation::BasePassage( ";
|
|
//};
|
|
//// ---- fin vérification
|
|
//------ cas de la config finale à tdt,
|
|
N = (Util::ProdVec_coorBN(giB_tdt(1),giB_tdt(2))).Normer();
|
|
if (!absolue)
|
|
{ve.Change_Coordonnee(3,0.,-N(3),N(2)); // = ProdVec(N,I1)
|
|
norve = ve.Norme();
|
|
if (norve >= 0.01)
|
|
{ Aa(2) = ve.Normer();
|
|
Aa(1) = Util::ProdVec_coor(Aa(2),N);
|
|
}
|
|
else
|
|
{ ve.Change_Coordonnee(3,N(3),0.,-N(1)); // = ProdVec(I2,N)
|
|
Aa(1) = ve.Normer();
|
|
Aa(2) = Util::ProdVec_coor(N,Aa(1));
|
|
};
|
|
|
|
for (int be=1;be<=2;be++)
|
|
{ Aa_tdt(1,be) = giH_tdt.Coordo(1) * Aa(be);
|
|
Aa_tdt(2,be) = giH_tdt.Coordo(2) * Aa(be);
|
|
};
|
|
// si on veut une matrice 3x3, il faut complèter la matrice avec un troisième vecteur
|
|
// comme les vi sont normaux à N, le troisième vecteur est le vecteur N
|
|
// qui ne peut pas s'exprimer dans le repère local des gi donc on considère qu'il s'exprime vis-à-vis
|
|
// du troisième vecteur qui n'est autre que N
|
|
if (Aa_tdt.Nb_ligne()==3)
|
|
// ici on a Ip_3 == N et également g_3=g^3=N
|
|
{for (int al=1 ;al<=2;al++)
|
|
{Aa_tdt(3,al) = N * vi(al) ;
|
|
Aa_tdt(al,3) = giH_tdt.Coordo(al) * N ;
|
|
};
|
|
Aa_tdt(3,3)= 1.; // == N . N
|
|
};
|
|
}
|
|
else // cas on l'on veut le passage des gi et N vers I_a
|
|
{// g^i = Aa^i_{.a} * I^a -> donc Aa^i_{.a} c'est directement les coordonnées de g^i
|
|
for (int al=1 ;al < 4;al++)
|
|
{Aa_tdt(1,al) = giH_tdt.Coordo(1)(al) ;
|
|
Aa_tdt(2,al) = giH_tdt.Coordo(2)(al) ;
|
|
};
|
|
// pour le troisième: N = Aa^3_{.a} * I^a -> c'est aussi directement les coordonnées de N
|
|
Aa_tdt.RemplaceLigneSpe(3,N.Vect());
|
|
};
|
|
|
|
//// ---- vérification que le déterminant n'est pas nul
|
|
//{double det = Aa_tdt(1,1) * Aa_tdt(2,2) - Aa_tdt(1,2) * Aa_tdt(2,1);
|
|
// if (Abs(det) < 0.00001)
|
|
// cout << "\n erreur det0 null " << det << " dans Deformation::BasePassage( ";
|
|
//};
|
|
//// ---- fin vérification
|
|
}
|
|
else if (dim==1)
|
|
// ==== cas des éléments 1D en espace 1D, 2D ou 3D ====
|
|
{ if (!absolue)
|
|
{switch (ParaGlob::Dimension())
|
|
{ case 1: // normalement on ne devrait pas passer ici !! car ce cas est déjà traité au début
|
|
{cout << "\nErreur : bug!! on ne devrait pas passer ici \n";
|
|
cout << "void Deformation::BasePassage( \n";
|
|
Sortie(1);
|
|
break;
|
|
}
|
|
case 3: // on est dans un espace 3D, ici on ne fait que le particulier à 3D et le reste est
|
|
// fait dans le case 2: qui suit
|
|
// 3X1X1 ou 3X1X2 ou 3X1X3, 2X1X1 , 2X1X2
|
|
if (Aa0.Nb_ligne() == 3 )
|
|
// 3X1X3
|
|
{ // tous les tenseurs vont utiliser que le premier vecteur, donc le troisième peut être quelconque
|
|
// et l'expression de giH(3) n'existant pas on dit que par défaut (et par simplicité)
|
|
// giH(3) = 1 * IP(3) d'où
|
|
Aa0 (3,3) = Aa_t(3,3)= Aa_tdt(3,3) = 1.;
|
|
// et on initialise les autres composantes au cas où
|
|
Aa0 (1,3) = Aa0 (3,1) = Aa_t(1,3) = Aa_t(3,1) = Aa_tdt(1,3) = Aa_tdt(3,1) = 0.;
|
|
Aa0 (2,3) = Aa0 (3,2) = Aa_t(2,3) = Aa_t(3,2) = Aa_tdt(2,3) = Aa_tdt(3,2) = 0.;
|
|
// pas de break, on continue sur le 2D
|
|
}
|
|
case 2: // on est dans un espace 2D, 3X1X1 ou 3X1X2 ou 3X1X3
|
|
{ // le premier vecteur intéressant c'est le vecteur collinéaire avec gH(1), mais normé
|
|
double norme0 = giH0(1).Norme();
|
|
double normet = giH_t(1).Norme();
|
|
double normetdt = giH_tdt(1).Norme();
|
|
Aa0 (1,1) = norme0;
|
|
Aa_t(1,1) = normet;
|
|
Aa_tdt(1,1) = normetdt;
|
|
// fin du cas 3X1X1 et 2X1X1
|
|
if (Aa0.Nb_ligne() > 1)
|
|
// 3X1X2 , 3X1X3 , 2X1X2
|
|
// tous les tenseurs vont utiliser que le premier vecteur, donc le second peut être quelconque
|
|
// et l'expression de giH(2) n'existant pas on dit que par défaut (et par simplicité)
|
|
// giH(2) = 1 * IP(2) d'où
|
|
{Aa0 (2,2) = Aa_t(2,2) = Aa_tdt(2,2)= 1.;
|
|
// et on initialise les autres composantes au cas où
|
|
Aa0 (1,2) = Aa0 (2,1) = Aa_t(1,2) = Aa_t(2,1)= Aa_tdt(1,2) = Aa_tdt(2,1) = 0.;
|
|
};
|
|
break;
|
|
}
|
|
default: cout << "\n erreur grossiere de dimension !! \n Deformation::BasePassage(.. ";
|
|
Sortie(1);
|
|
};
|
|
}
|
|
else // sinon on veut arriver en Ia
|
|
{ // On ne connait que le premier vecteur et normalement c'est seulement celui-là qui est
|
|
// utilisé, par contre il faut complèter la matrice pour qu'elle ne soit pas singulière
|
|
Aa0.Initialise(0.);Aa_t.Initialise(0.);Aa_tdt.Initialise(0.);
|
|
switch (ParaGlob::Dimension())
|
|
{ case 1: // normalement on ne devrait pas passer ici !! car ce cas est déjà traité au début
|
|
{cout << "\nErreur : bug!! on ne devrait pas passer ici \n";
|
|
cout << "void Deformation::BasePassage( \n";
|
|
Sortie(1);
|
|
break;
|
|
}
|
|
case 3: // on est dans un espace 3D,
|
|
{CoordonneeH V02(3); CoordonneeH V03(3);
|
|
// on calcule deux vecteurs arbitraires normaux, avec un résultat orthonormé V2,V3
|
|
// mais pas giH0(1) !
|
|
MathUtil2::Def_vecteurs_plan(giH0(1),V02,V03);
|
|
// idem pour t et tdt
|
|
CoordonneeH V2_t(3); CoordonneeH V3_t(3);
|
|
MathUtil2::Def_vecteurs_plan(giH_t(1),V2_t,V3_t);
|
|
CoordonneeH V2_tdt(3); CoordonneeH V3_tdt(3);
|
|
MathUtil2::Def_vecteurs_plan(giH_tdt(1),V2_tdt,V3_tdt);
|
|
int bornesup = ParaGlob::Dimension() +1;
|
|
for (int al=1 ;al < bornesup;al++)
|
|
{Aa0(1,al) = giH0.Coordo(1)(al) ;
|
|
Aa_t(1,al) = giH_t.Coordo(1)(al) ;
|
|
Aa_tdt(1,al) = giH_tdt.Coordo(1)(al) ;
|
|
Aa0(2,al) = V02(al) ;
|
|
Aa_t(2,al) = V2_t(al) ;
|
|
Aa_tdt(2,al) = V2_tdt(al) ;
|
|
Aa0(3,al) = V03(al) ;
|
|
Aa_t(3,al) = V3_t(al) ;
|
|
Aa_tdt(3,al) = V3_tdt(al) ;
|
|
};
|
|
break;
|
|
}
|
|
case 2: // on est dans un espace 2D,
|
|
{CoordonneeH V02(2);
|
|
// on calcule le vecteur normal,
|
|
// mais pas giH0(1) !
|
|
MathUtil2::Def_vecteurs_plan(giH0(1),V02);
|
|
// idem pour t et tdt
|
|
CoordonneeH V2_t(3);
|
|
MathUtil2::Def_vecteurs_plan(giH_t(1),V2_t);
|
|
CoordonneeH V2_tdt(3);
|
|
MathUtil2::Def_vecteurs_plan(giH_tdt(1),V2_tdt);
|
|
int bornesup = ParaGlob::Dimension() +1;
|
|
for (int al=1 ;al < bornesup;al++)
|
|
{Aa0(1,al) = giH0.Coordo(1)(al) ;
|
|
Aa_t(1,al) = giH_t.Coordo(1)(al) ;
|
|
Aa_tdt(1,al) = giH_tdt.Coordo(1)(al) ;
|
|
Aa0(2,al) = V02(al) ;
|
|
Aa_t(2,al) = V2_t(al) ;
|
|
Aa_tdt(2,al) = V2_tdt(al) ;
|
|
};
|
|
break;
|
|
}
|
|
default: cout << "\n erreur2 grossiere de dimension !! \n Deformation::BasePassage(.. ";
|
|
Sortie(1);
|
|
};
|
|
};
|
|
}
|
|
else
|
|
{// pour les autres cas on ramene la matrice identite
|
|
#ifdef MISE_AU_POINT
|
|
if ((Aa0.Nb_ligne() != dim) && (Aa0.Nb_colonne() !=dim) &&
|
|
(Aa_t.Nb_ligne() != dim) && (Aa_t.Nb_colonne() !=dim) &&
|
|
(Aa_tdt.Nb_ligne() != dim) && (Aa_tdt.Nb_colonne() !=dim))
|
|
{ cout << "\nErreur : les matrices Aa0 et /ou Aa_t et /ou Aa_tdt ne sont pas correctement"
|
|
<< " dimensionnees !\n";
|
|
cout << "void Deformation::RemontImp( \n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
for (int i=1;i<=dim;i++)
|
|
{ for (int j=1;j<=dim;j++)
|
|
{Aa0 (i,j) = 0.;Aa_t(i,j) = 0.;Aa_tdt(i,j) = 0.;}
|
|
Aa0 (i,i) = 1.; Aa_t(i,i) = 1.;Aa_tdt(i,i) = 1.;
|
|
};
|
|
};
|
|
// retour
|
|
return;
|
|
};
|
|
|
|
// cas où l'on veut la matrice de passage à 0 uniquement
|
|
// Aa(i,a) = Aa^i_{.a}, avec g^i = Aa^i_{.a} * Ip^a
|
|
// tout ce passe comme si Ip^a est la nouvelle base vers laquelle on veut évoluer
|
|
// (voir Deformation.h pour un descriptif plus complet)
|
|
void Deformation::BasePassage(bool absolue,const BaseB & giB0,const BaseH & giH0,Mat_pleine& Aa0)
|
|
{
|
|
// determination des matrices de transformation de base
|
|
int dim = giB0.NbVecteur();
|
|
|
|
// dim_espace X nb_vecteur X taille_matrice
|
|
|
|
// cas d'une sortie en globale
|
|
// 1X1X1 ou 2X2X2 ou 3X3X3
|
|
if ((dim == ParaGlob::Dimension()) && (Aa0.Nb_ligne() == dim))
|
|
{ // petite vérif
|
|
#ifdef MISE_AU_POINT
|
|
if ((Aa0.Nb_ligne() != dim) && (Aa0.Nb_colonne() !=dim))
|
|
{ cout << "\nErreur1 : la matrice Aa0 n'est pas correctement"
|
|
<< " dimensionnee ! \n";
|
|
cout << "\n Aa0= "; Aa0.Affiche();
|
|
cout << "void Deformation::BasePassage( \n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
for (int i=1;i<=dim;i++)
|
|
for (int j=1;j<=dim;j++)
|
|
{Aa0 (i,j) = giH0(i)(j);
|
|
};
|
|
}
|
|
else if ((dim==2)&&(ParaGlob::Dimension()==3))
|
|
// cela comprend les cas: 3X2X2 -> un repère local ad hoc en 2D
|
|
// 3X2X3 -> un repère local ad hoc en 3D
|
|
// ==== cas d'élément de membrane en 3D ====
|
|
{// 1) si absolue = false: l'objectif est de determiner un repere pertinant dans le cas de membrane .
|
|
// choix : un repere qui appartiend a la facette, obtenu apres projection
|
|
// du repere global
|
|
//------ cas de la config initiale, on regarde si la projection de I1 n'est pas trop petite
|
|
// def de la normale a la facette
|
|
// 2) si absolue = true; on complète le repère des gi avec la normale et la matrice de passage
|
|
// correspond au passage des gi complètés -> I_a
|
|
|
|
Coordonnee N ( (Util::ProdVec_coorBN(giB0(1),giB0(2))).Normer() );
|
|
Coordonnee ve(0.,-N(3),N(2)); // = ProdVec(N,I1), donc normal à N
|
|
double norve = ve.Norme();
|
|
Tableau <Coordonnee> vi(2); // les vecteurs plans orthonormes de la facette
|
|
if (!absolue)
|
|
{if (norve >= 0.01)
|
|
{ vi(2) = ve.Normer();
|
|
vi(1) = Util::ProdVec_coor(vi(2),N);// donc normal à N
|
|
}
|
|
else
|
|
{ ve.Change_Coordonnee(3,N(3),0.,-N(1)); // = ProdVec(I2,N), donc normal à N
|
|
vi(1) = ve.Normer();
|
|
vi(2) = Util::ProdVec_coor(N,vi(1));// donc normal à N
|
|
};
|
|
// maintenant expression dans le repère local
|
|
for (int al=1 ;al<=2;al++)
|
|
{Aa0(1,al) = giH0.Coordo(1) * vi(al) ;
|
|
Aa0(2,al) = giH0.Coordo(2) * vi(al) ;
|
|
};
|
|
// si on veut une matrice 3x3, il faut complèter la matrice avec un troisième vecteur
|
|
// comme les vi sont normaux à N, le troisième vecteur est le vecteur N
|
|
// qui ne peut pas s'exprimer dans le repère local des gi donc on considère qu'il s'exprime vis-à-vis
|
|
// du troisième vecteur qui n'est autre que N
|
|
if (Aa0.Nb_ligne()==3)
|
|
// ici on a Ip_3 == N et également g_3=g^3=N
|
|
{for (int al=1 ;al<=2;al++)
|
|
{Aa0(3,al) = N * vi(al) ;
|
|
Aa0(al,3) = giH0.Coordo(al) * N ;
|
|
};
|
|
Aa0(3,3)= 1.; // == N . N
|
|
};
|
|
}
|
|
else // cas on l'on veut le passage des gi et N vers I_a
|
|
{// g^i = Aa^i_{.a} * I^a -> donc Aa^i_{.a} c'est directement les coordonnées de g^i
|
|
for (int al=1 ;al < 4;al++)
|
|
{Aa0(1,al) = giH0.Coordo(1)(al) ;
|
|
Aa0(2,al) = giH0.Coordo(2)(al) ;
|
|
};
|
|
// pour le troisième: N = Aa^3_{.a} * I^a -> c'est aussi directement les coordonnées de N
|
|
Aa0.RemplaceLigneSpe(3,N.Vect());
|
|
};
|
|
|
|
//// ---- vérification que le déterminant n'est pas nul
|
|
//{double det = Aa0(1,1) * Aa0(2,2) - Aa0(1,2) * Aa0(2,1);
|
|
// if (Abs(det) < 0.00001)
|
|
// cout << "\n erreur det0 null " << det << " dans Deformation::BasePassage( ";
|
|
//};
|
|
//// ---- fin vérification
|
|
|
|
}
|
|
else if (dim==1)
|
|
// ==== cas des éléments 1D en espace 1D, 2D ou 3D ====
|
|
{ if (!absolue)
|
|
{switch (ParaGlob::Dimension())
|
|
{ case 1: // normalement on ne devrait pas passer ici !! car ce cas est déjà traité au début
|
|
{cout << "\nErreur : bug!! on ne devrait pas passer ici \n";
|
|
cout << "void Deformation::BasePassage( \n";
|
|
Sortie(1);
|
|
break;
|
|
}
|
|
case 3: // on est dans un espace 3D, ici on ne fait que le particulier à 3D et le reste est
|
|
// fait dans le case 2: qui suit
|
|
// 3X1X1 ou 3X1X2 ou 3X1X3, 2X1X1 , 2X1X2
|
|
if (Aa0.Nb_ligne() == 3 )
|
|
// 3X1X3
|
|
{ // tous les tenseurs vont utiliser que le premier vecteur, donc le troisième peut être quelconque
|
|
// et l'expression de giH(3) n'existant pas on dit que par défaut (et par simplicité)
|
|
// giH(3) = 1 * IP(3) d'où
|
|
Aa0 (3,3) = 1.;
|
|
// et on initialise les autres composantes au cas où
|
|
Aa0 (1,3) = Aa0 (3,1) = 0.;
|
|
Aa0 (2,3) = Aa0 (3,2) = 0.;
|
|
// pas de break, on continue sur le 2D
|
|
}
|
|
case 2: // on est dans un espace 2D, 3X1X1 ou 3X1X2 ou 3X1X3
|
|
{ // le premier vecteur intéressant c'est le vecteur collinéaire avec gH(1), mais normé
|
|
double norme0 = giH0(1).Norme();
|
|
Aa0 (1,1) = norme0;
|
|
// fin du cas 3X1X1 et 2X1X1
|
|
if (Aa0.Nb_ligne() > 1)
|
|
// 3X1X2 , 3X1X3 , 2X1X2
|
|
// tous les tenseurs vont utiliser que le premier vecteur, donc le second peut être quelconque
|
|
// et l'expression de giH(2) n'existant pas on dit que par défaut (et par simplicité)
|
|
// giH(2) = 1 * IP(2) d'où
|
|
{Aa0 (2,2) = 1.;
|
|
// et on initialise les autres composantes au cas où
|
|
Aa0 (1,2) = Aa0 (2,1) = 0.;
|
|
};
|
|
break;
|
|
}
|
|
default: cout << "\n erreur grossiere de dimension !! \n Deformation::BasePassage(.. ";
|
|
Sortie(1);
|
|
};
|
|
}
|
|
else // sinon on veut arriver en Ia
|
|
{ // On ne connait que le premier vecteur et normalement c'est seulement celui-là qui est
|
|
// utilisé, par contre il faut complèter la matrice pour qu'elle ne soit pas singulière
|
|
Aa0.Initialise(0.);
|
|
switch (ParaGlob::Dimension())
|
|
{ case 1: // normalement on ne devrait pas passer ici !! car ce cas est déjà traité au début
|
|
{cout << "\nErreur : bug!! on ne devrait pas passer ici \n";
|
|
cout << "void Deformation::BasePassage( \n";
|
|
Sortie(1);
|
|
break;
|
|
}
|
|
case 3: // on est dans un espace 3D,
|
|
{CoordonneeH V02(3); CoordonneeH V03(3);
|
|
// on calcule deux vecteurs arbitraires normaux, avec un résultat orthonormé V2,V3
|
|
// mais pas giH0(1) !
|
|
MathUtil2::Def_vecteurs_plan(giH0(1),V02,V03);
|
|
int bornesup = ParaGlob::Dimension() +1;
|
|
for (int al=1 ;al < bornesup;al++)
|
|
{Aa0(1,al) = giH0.Coordo(1)(al) ;
|
|
Aa0(2,al) = V02(al) ;
|
|
Aa0(3,al) = V03(al) ;
|
|
};
|
|
break;
|
|
}
|
|
case 2: // on est dans un espace 2D,
|
|
{CoordonneeH V02(2);
|
|
// on calcule le vecteur normal,
|
|
// mais pas giH0(1) !
|
|
MathUtil2::Def_vecteurs_plan(giH0(1),V02);
|
|
int bornesup = ParaGlob::Dimension() +1;
|
|
for (int al=1 ;al < bornesup;al++)
|
|
{Aa0(1,al) = giH0.Coordo(1)(al) ;
|
|
Aa0(2,al) = V02(al) ;
|
|
};
|
|
break;
|
|
}
|
|
default: cout << "\n erreur2 grossiere de dimension !! \n Deformation::BasePassage(.. ";
|
|
Sortie(1);
|
|
};
|
|
int bornesup = ParaGlob::Dimension() +1;
|
|
for (int al=1 ;al < bornesup;al++)
|
|
{Aa0(1,al) = giH0.Coordo(1)(al) ;
|
|
if (al!=1)
|
|
{Aa0 (al,al) = 1.;};
|
|
};
|
|
};
|
|
}
|
|
else
|
|
{// pour les autres cas on ramene la matrice identite
|
|
#ifdef MISE_AU_POINT
|
|
if ((Aa0.Nb_ligne() != dim) && (Aa0.Nb_colonne() !=dim) )
|
|
{ cout << "\nErreur : la matrices Aa0 n'est pas correctement"
|
|
<< " dimensionnee !\n";
|
|
cout << "void Deformation::RemontImp( \n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
for (int i=1;i<=dim;i++)
|
|
{ for (int j=1;j<=dim;j++)
|
|
{Aa0 (i,j) = 0.;}
|
|
Aa0 (i,i) = 1.;
|
|
};
|
|
};
|
|
// retour
|
|
return;
|
|
};
|
|
|
|
// on suppose que gijHH et gijBB ont déjà été calculé et sont donc transmis
|
|
// on suppose que gijHH et gijBB ont déjà été calculé à t=0, et à temps
|
|
void Deformation::Cal_deformation (Enum_dure temps, TenseurBB & epsBB)
|
|
{ // ici il y a le choix entre les différents types de calcul de la déformation (Almansi, Green-Lagrange ..
|
|
switch (type_deformation)
|
|
{ case DEFORMATION_STANDART :
|
|
{return Cal_Almansi_auTemps(temps,epsBB);
|
|
break;
|
|
}
|
|
case DEFORMATION_LOGARITHMIQUE:
|
|
{return Cal_logarithmique_auTemps(temps,epsBB);
|
|
break;
|
|
}
|
|
case DEFORMATION_CUMU_LOGARITHMIQUE : case DEF_CUMUL_CORROTATIONNEL : case DEF_CUMUL_ROTATION_PROPRE :
|
|
{return Cal_def_cumule_auTemps(temps,epsBB);
|
|
break;
|
|
}
|
|
default :
|
|
cout << "\nErreur : type de deformation ( " << Nom_type_deformation(type_deformation)
|
|
<< " ) non traite !\n";
|
|
cout << "Deformation::Cal_deformation (... \n";
|
|
Sortie(1);
|
|
};
|
|
};
|
|
|
|
// calcul de la deformation au temps donné dans le cas d'une déformation d'Almansi
|
|
// on suppose que les métriques en HH ou BB sont définis à 0 et au temps
|
|
void Deformation::Cal_def_cumule_auTemps (Enum_dure , TenseurBB & )
|
|
{ cout << "\n methode pas encore implante (dommage!) "
|
|
<< "\n Deformation::Cal_def_cumule_auTemps (..";
|
|
Sortie(1);
|
|
};
|
|
|
|
// gestion du parcours de tous les points d'integration
|
|
void Deformation::PremierPtInteg()
|
|
{ sauve_numInteg = numInteg; numInteg = 1; };
|
|
bool Deformation::DernierPtInteg()
|
|
{ sauve_numInteg = numInteg; // sauvegarde
|
|
if (numInteg <= tabPhi->Taille())
|
|
return true;
|
|
else
|
|
return false;
|
|
};
|
|
void Deformation::NevezPtInteg()
|
|
{ sauve_numInteg = numInteg; // sauvegarde
|
|
numInteg++;
|
|
};
|
|
|
|
// méthode pour revenir au pti précédant
|
|
void Deformation::Retour_pti_precedant()
|
|
{numInteg=sauve_numInteg;};
|
|
|
|
//==================================== méthodes protégées ===============================
|
|
|
|
|
|
|
|
// calcul implicite dans le cas d'une déformation tensorielle cumulée
|
|
const Met_abstraite::Impli& Deformation::Cal_implicit_def_cumule (bool
|
|
,TenseurBB & epsBB_tdt,Tableau <TenseurBB *> & d_epsBB_tdt
|
|
,TenseurBB& DepsBB,TenseurBB& delta_epsBB,bool premier_calcul
|
|
,const Met_abstraite::Impli& ex)
|
|
{
|
|
// dans le cas où ce n'est pas le premier calcul on récupère les datas qui ne sont pas recalculée
|
|
if (!premier_calcul)
|
|
{ Deformation::Stmet& a_0 = saveDefResul->meti_00; // pour simplifier
|
|
Deformation::Stmet& a_t = saveDefResul->meti_t; // pour simplifier
|
|
metrique->Recup_grandeur_0_t(*a_0.giB_,*a_0.giH_,*a_t.giB_,*a_t.giH_
|
|
,*a_0.gijBB_,*a_0.gijHH_,*a_t.gijBB_,*a_t.gijHH_
|
|
,*a_t.gradVmoyBB_,*a_t.jacobien_,*a_0.jacobien_);
|
|
};
|
|
// 1- calcul de la base duale et de la métrique à t=0, utiliser en 3-
|
|
// non déjà fait dans le calcul actuel de la métrique
|
|
// const Met_abstraite::gijHH_0_et_giH_0& ex1 = metrique->Cal_gijHH_0_et_giH_0_apres_im_expli();
|
|
// 2- calcul de l'opérateur gradient F(a,b)=d Xc^a/d X0^b, stockage sous forme d'un spseudo-tenseur
|
|
// alors que c'est un bi-tenseur !! permet ainsi une manipulation aisée
|
|
int dim = ParaGlob::Dimension();
|
|
TenseurHB * ftHB = NevezTenseurHB(dim);
|
|
for (int i=1;i<=dim;i++)
|
|
{ TenseurHB * interHB = Produit_tensorielHB((*ex.giH_0)(i),(*ex.giB_tdt)(i));
|
|
*ftHB += *interHB; delete interHB;
|
|
};
|
|
// 3- calcul du gradient de vitesse
|
|
// plusieurs possibilités,
|
|
// 1) . soit on calcul le gradient à partir du champ de vitesse au temps finale
|
|
// 2) . soit on calcul le gradient à partir d'une hypothèse de vitesse contante sur le pas de temps
|
|
// avec la vitesse = delta X / delta t, le gradient étant déterminé à t+ (deltat/2)
|
|
// 3) . soit on calcul le gradient à partir d'une hypothèse de vitesse moyenne au temps t+ (deltat/2)
|
|
// c-a-d en utilisant la vitesse moyenne entre t et t+dt, ceci dans le cas de l'utilisation
|
|
// directe des ddl vitesse
|
|
|
|
/* switch (type_gradient_vitesse) // traitement en fonction du cas
|
|
{ case GRADVITESSE_V_TDT : // le gradient est déterminé à partir de ddl de vitesse à t+dt
|
|
#ifdef MISE_AU_POINT
|
|
// on vérifie que le gradient a été calculé dans l'appel de la métrique
|
|
if (pas_de_gradV)
|
|
{ cout << "\nErreur : le gradient de vitesse n'a pas ete calcule dans la metrique"
|
|
<< " ce qui est contraire au type de calcul de gradient demande";
|
|
cout << "\n Deformation::Cal_implicit_def_cumule(... \n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
// donc ici le gradient est dans (*ex.gradVBB_tdt)
|
|
break;
|
|
case GRADVITESSE_VCONST : // calcul en considérant V constant =delta X/delta t
|
|
// dans la config à t+(delta t)/2
|
|
|
|
// // 2) calcul du gradient à partir du champ de vitesse au temps final
|
|
// if (!pas_de_gradV)
|
|
// {// cas où le gradient a été calculé
|
|
// DepsBB = 0.5 * ((*ex.gradVBB_tdt) + ex.gradVBB_tdt->Transpose());}
|
|
// else
|
|
// {
|
|
// }
|
|
break;
|
|
case GRADVITESSE_VT_VTDT : //calcul à partir des ddl de vitesse : moyenne de t et t+dt,
|
|
//dans la config à t+(delta t)/2
|
|
break;
|
|
};*/
|
|
|
|
|
|
|
|
/* // epsBB_tdt et delta_epsBB est dimensionne auparavant
|
|
epsBB_tdt = 0.5 * (*(ex.gijBB_tdt) - *(ex.gijBB_0));
|
|
delta_epsBB = 0.5 * (*(ex.gijBB_tdt) - *(ex.gijBB_t));
|
|
if (pas_de_gradV)
|
|
{ // on choisit une vitesse de déformation pour l'instant identique à deltaeps/t
|
|
const VariablesTemps& vartemps = ParaGlob::Variables_de_temps();
|
|
// dans le cas où l'incrément de temps est nul on garde la vitesse actuelle
|
|
double deltat=vartemps.IncreTempsCourant();
|
|
if (deltat >= ConstMath::trespetit)
|
|
DepsBB = delta_epsBB/deltat;
|
|
}
|
|
else // cas où le gradient a été calculé
|
|
DepsBB = 0.5 * ((*ex.gradVBB_tdt) + ex.gradVBB_tdt->Transpose());
|
|
// variation de la déformation / au ddl
|
|
int d_epsBB_tdtTaille = d_epsBB_tdt.Taille();
|
|
for (int i=1; i<= d_epsBB_tdtTaille; i++)
|
|
*(d_epsBB_tdt(i)) = 0.5 * (*((*(ex.d_gijBB_tdt))(i)));
|
|
// calcul éventuelle de la dérivée seconde de la déformation
|
|
if (pa.Var_D())
|
|
{// recup des variations secondes de la déformation
|
|
int d2_epsBB_tdtTaille1 = d2_epsBB_tdt.Taille1();
|
|
for (int i=1; i<= d2_epsBB_tdtTaille1; i++)
|
|
for (int j=1; j<= i; j++) // symétrie du tableau et du tenseur
|
|
{ *(d2_epsBB_tdt(i,j)) = 0.5 * (*((*(ex.d2_gijBB_tdt))(i,j))) ;
|
|
*(d2_epsBB_tdt(j,i)) = *(d2_epsBB_tdt(i,j)) ;
|
|
}
|
|
} */
|
|
// vérification éventuelle
|
|
// VerifCal_implicit( ex);
|
|
// suppression des tenseurs de travail
|
|
delete ftHB;
|
|
// retour
|
|
return ex;
|
|
};
|
|
|
|
// calcul d'une vitesse de rotation cohérente avec un référentiel objectif particulier
|
|
void Deformation::Cal_vite_rota_objectif(EnumTypeViteRotat type_rotation,bool variation
|
|
,const TenseurBB& gradVBB,const Tableau <TenseurBB * >& d_gradVBB
|
|
,const TenseurBH& gij_HH_0,const TenseurBB& gij_BB,Tableau <TenseurBB *> & d_gijBB
|
|
,const TenseurHH& gij_HH,Tableau <TenseurHH *> & d_gijHH
|
|
,const TenseurBB& D_BB, Tableau <TenseurBB *> & d_D_BB
|
|
,TenseurBB& OmegaBB,Tableau <TenseurBB* > & d_OmegaBB)
|
|
{ // on calcul le pseudo vecteur W représentant le tenseur anti-symétrique: rotation du gradient de vitesse
|
|
// TenseurBB W_BB = 0.5 * (gradVBB - gradVBB.Transpose());
|
|
int dima=Abs(gradVBB.Dimension());
|
|
/* CoordonneeB W_B(dima);
|
|
switch (dima) { case 3: W_B(1) = W_BB(3,2);W_B(2) = W_BB(1,3);W_B(3) = W_BB(2,1);break;
|
|
case 2: W_B(1) = W_BB(1,2);W_B(2) = 0.;break; // en attente
|
|
case 1: W_B(1) = 0.;break;}; // en attente*/
|
|
int dimddl=d_gradVBB.Taille(); // dimension pour les variations
|
|
switch (type_rotation)
|
|
{ case R_CORROTATIONNEL:
|
|
OmegaBB =0.5 * (gradVBB - gradVBB.Transpose());
|
|
// dans le cas où l'on veut également des variations
|
|
if (variation)
|
|
{ for (int i=1;i<=dimddl;i++) (*(d_OmegaBB(i))) = 0.5*( (*(d_gradVBB(i))) - (d_gradVBB(i))->Transpose()); }
|
|
break;
|
|
case R_REF_ROT_PROPRE: case R_ROT_LOGARITHMIQUE:
|
|
// calcul des projections propres
|
|
switch (dima)
|
|
{ case 3:
|
|
{// simplification et transformation en tenseur de dim 3 (optimisation des calculs)
|
|
const Tenseur3HH & gijHH_0 = (const Tenseur3HH &) gij_HH_0;
|
|
const Tenseur3BB & gijBB = (const Tenseur3BB &) gij_BB;
|
|
const Tenseur3HH & gijHH = (const Tenseur3HH &) gij_HH;
|
|
// def des grandeurs de travail
|
|
DimensionementVarLog(dima,variation,dimddl);
|
|
// def du tenseur B_BH (cauchy_green gauche)
|
|
(*B_BH_tr) = gijBB * gijHH_0; Tenseur3BH& B_BH= *((Tenseur3BH*) B_BH_tr);
|
|
// calcul des valeurs propres et projection propres du tenseur B_BH
|
|
Tableau <Tenseur3BH * >& d_B_BH=*((Tableau <Tenseur3BH * >*) d_B_BH_tr);
|
|
if (variation) // dans le cas de variation, calcul des variation de B_BH
|
|
{ for (int ic=1;ic<=dimddl;ic++) {(*(*d_B_BH_tr)(ic))= (*(d_gijBB(ic))) * gijHH_0;};};
|
|
// def des grandeurs de travail
|
|
Tableau <Tenseur3BH* >& Palpha_BH=*((Tableau <Tenseur3BH* >*) Palpha_BH_tr); // les projections propres
|
|
Tableau <Tableau <Tenseur3BH* > >& d_Palpha_BH
|
|
=*((Tableau <Tableau <Tenseur3BH* > >*) d_Palpha_BH_tr); // variation des projections propres
|
|
// appel de la méthode calculant les grandeurs de travail
|
|
int cas_ki; // indique le cas des valeurs propres traitées (cf TenseurBH)
|
|
Val_et_projection_prop_tenseur(*B_BH_tr,*d_B_BH_tr,ki,*Palpha_BH_tr,variation,*d_ki,*d_Palpha_BH_tr,cas_ki);
|
|
// -- calcul de la rotation
|
|
// calcul de la vitesse de rotation en mixte
|
|
Tenseur3BH D_BH(D_BB * gijHH);
|
|
// tout d'abord: calcul de tenseurs intermédiaires
|
|
Tableau <Tenseur3BH> P_i_D_BH(3); Tableau <Tenseur3BH> D_P_i_BH(3);
|
|
P_i_D_BH(1)=((*Palpha_BH(1)) * D_BH); Tenseur3BH P_1_D_P_2_BH(P_i_D_BH(1) * (*Palpha_BH(2)));
|
|
P_i_D_BH(2)=((*Palpha_BH(2)) * D_BH); Tenseur3BH P_2_D_P_1_BH(P_i_D_BH(2) * (*Palpha_BH(1)));
|
|
D_P_i_BH(1)=(D_BH * (*Palpha_BH(1))); Tenseur3BH P_1_D_P_3_BH(P_i_D_BH(1) * (*Palpha_BH(3)));
|
|
P_i_D_BH(3)=((*Palpha_BH(3)) * D_BH); Tenseur3BH P_3_D_P_1_BH(P_i_D_BH(3) * (*Palpha_BH(1)));
|
|
D_P_i_BH(2)=(D_BH * (*Palpha_BH(2))); Tenseur3BH P_2_D_P_3_BH(P_i_D_BH(2) * (*Palpha_BH(3)));
|
|
D_P_i_BH(3)=(D_BH * (*Palpha_BH(3))); Tenseur3BH P_3_D_P_2_BH(P_i_D_BH(3) * (*Palpha_BH(2)));
|
|
|
|
double F_rot_1sur2= F_pour_rotat_objectif(type_rotation,ki(1)/ki(2));
|
|
double F_rot_1sur3= F_pour_rotat_objectif(type_rotation,ki(1)/ki(3));
|
|
double F_rot_2sur1= F_pour_rotat_objectif(type_rotation,ki(2)/ki(1));
|
|
double F_rot_3sur1= F_pour_rotat_objectif(type_rotation,ki(3)/ki(1));
|
|
double F_rot_2sur3= F_pour_rotat_objectif(type_rotation,ki(2)/ki(3));
|
|
double F_rot_3sur2= F_pour_rotat_objectif(type_rotation,ki(3)/ki(2));
|
|
|
|
OmegaBB =0.5 * (gradVBB - gradVBB.Transpose());
|
|
Tenseur3BH sup_OmegaBH ( F_rot_1sur2 * P_1_D_P_2_BH + F_rot_2sur1 * P_2_D_P_1_BH
|
|
+ F_rot_1sur3 * P_1_D_P_3_BH + F_rot_3sur1 * P_3_D_P_1_BH
|
|
+ F_rot_2sur3 * P_2_D_P_3_BH + F_rot_3sur2 * P_3_D_P_2_BH );
|
|
OmegaBB += sup_OmegaBH* gijBB ;
|
|
|
|
// calcul éventuel des variations
|
|
if (variation)
|
|
{ // mise sous forme indicée suivant l'ordre 1->12 2->21 3->13 4->31 5->23 6->32 à partir de 6 nombres
|
|
Tableau <Tenseur3BH*> P_i_D_j_BH(6);
|
|
P_i_D_j_BH(1)=&P_1_D_P_2_BH; P_i_D_j_BH(2)=&P_2_D_P_1_BH; P_i_D_j_BH(3)=&P_1_D_P_3_BH;
|
|
P_i_D_j_BH(4)=&P_3_D_P_1_BH; P_i_D_j_BH(5)=&P_2_D_P_3_BH; P_i_D_j_BH(6)=&P_3_D_P_2_BH;
|
|
Tableau <double *> F_rot_isurj(6);
|
|
F_rot_isurj(1)=&F_rot_1sur2; F_rot_isurj(2)=&F_rot_2sur1; F_rot_isurj(3)=&F_rot_1sur3;
|
|
F_rot_isurj(4)=&F_rot_3sur1; F_rot_isurj(5)=&F_rot_2sur3; F_rot_isurj(6)=&F_rot_3sur2;
|
|
// boucle sur les ddl
|
|
for (int ici=1;ici<=dimddl;ici++)
|
|
{ const Tenseur3BB & dgijBB = *((Tenseur3BB*)(d_gijBB(ici))) ; // pour simplifier l'ecriture
|
|
const Tenseur3HH & dgijHH = *((Tenseur3HH*)(d_gijHH(ici))) ; // pour simplifier l'ecriture
|
|
const Tenseur3BB & dD_BB = *((Tenseur3BB*)(d_D_BB(ici))) ; // pour simplifier l'ecriture
|
|
|
|
// variation du tenseur vitesse de déformation en mixte
|
|
Tenseur3BH dD_BH(dD_BB * gijHH + D_BB * dgijHH);
|
|
// variation du tenseur de rotation
|
|
Tenseur3BB & dOmegaBB = *((Tenseur3BB* ) (d_OmegaBB(ici))); // pour simplifier l'ecriture
|
|
dOmegaBB = 0.5*( (*(d_gradVBB(ici))) - (d_gradVBB(ici))->Transpose());
|
|
for (int m=1;m<=6;m++)
|
|
{ int i1=ccdex.iii(m); int i2=ccdex.jjj(m);
|
|
dOmegaBB += (( Fprime_pour_rotat_objectif(type_rotation,ki(i1)/ki(i2))
|
|
/ (ki(i2)*ki(i2)) * (ki(i2) * ((*d_ki)(ici))(i1) - ki(i1) * ((*d_ki)(ici))(i2)) ) * (* P_i_D_j_BH(m))
|
|
+ (*F_rot_isurj(m)) * ( (*d_Palpha_BH(ici)(i2)) * D_P_i_BH(i2) + (*Palpha_BH(i1)) * dD_BH * (*Palpha_BH(i2))
|
|
+ P_i_D_BH(i1) * (*d_Palpha_BH(ici)(i2)) )) * gijBB
|
|
+ sup_OmegaBH * dgijBB;
|
|
};
|
|
};
|
|
}; // -- fin du grand "if variation "
|
|
// effacement des tenseurs de travail
|
|
for (int it=1;it<=dima;it++) delete Palpha_BH(it);
|
|
if (variation) for (int ic=1;ic<=dimddl;ic++) for (int it=1;it<=dima;it++)
|
|
delete d_Palpha_BH(ic)(it);
|
|
break;
|
|
}
|
|
default:
|
|
cout << "\n dimension (premier) non encore pris en compte: " << dima
|
|
<< "\n Deformation::Cal_vite_rota_objectif(...";
|
|
Sortie(1);
|
|
}
|
|
break;
|
|
default:
|
|
cout << "\n type de rotation non encore pris en compte"
|
|
<< "\n Deformation::Cal_vite_rota_objectif(...";
|
|
Sortie(1);
|
|
};
|
|
// liberation des tenseurs intermediaires
|
|
LibereTenseur();
|
|
};
|
|
|
|
// fonction f et f' utilisé dans la méthode Cal_vite_rota_objectif:
|
|
double Deformation::F_pour_rotat_objectif(EnumTypeViteRotat type_rotation,const double& x)
|
|
{switch (type_rotation)
|
|
{ case R_CORROTATIONNEL: return 0.; break;
|
|
case R_REF_ROT_PROPRE: return (1.-sqrt(x))/(1.+sqrt(x)); break;
|
|
case R_ROT_LOGARITHMIQUE: return (1.+x)/(1.-x) + 2./log(x); break;
|
|
default:
|
|
cout << "\n type de rotation non encore pris en compte: " << Nom_TypeViteRotat(type_rotation)
|
|
<< "\n Deformation::F_pour_rotat_objectif(...";
|
|
Sortie(1);
|
|
}
|
|
return 0.; // pour éviter le warning du retour
|
|
};
|
|
double Deformation::Fprime_pour_rotat_objectif(EnumTypeViteRotat type_rotation,const double& x)
|
|
{switch (type_rotation)
|
|
{ case R_CORROTATIONNEL: return 0.; break;
|
|
case R_REF_ROT_PROPRE: return 1./(2.*x+sqrt(x)*(x+1.)); break;
|
|
case R_ROT_LOGARITHMIQUE:
|
|
{double logx = log(x); double log2_x=logx*logx;
|
|
return 2.*(x*log2_x-x*x+2.*x-1.)/((x*x*x-2.*x*x+x)*log2_x); break;}
|
|
default:
|
|
cout << "\n type de rotation non encore pris en compte: " << Nom_TypeViteRotat(type_rotation)
|
|
<< "\n Deformation::Fprime_pour_rotat_objectif(...";
|
|
Sortie(1);
|
|
}
|
|
return 0.; // pour éviter le warning du retour
|
|
};
|
|
|
|
// ----------------- méthodes de vérifications------- ----
|
|
|
|
void Deformation::VerifCal_implicit(bool gradV_instantane,const Met_abstraite::Impli & ex,TenseurBB& )
|
|
{ // l'idée est de faire une vérification des dérivées à l'aide d'une méthode de différence finie
|
|
int dim = ParaGlob::Dimension();
|
|
// dans le cas du premier passage on indique qu'il y a vérification
|
|
if (indic_VerifCal_implicit == 0)
|
|
{ cout << "\n ****vérification du calcul de la déformation et des éléments de la métrique associé****";
|
|
cout << "\n Deformation::VerifCal_implicit \n";
|
|
}
|
|
indic_VerifCal_implicit++;
|
|
|
|
// on cré une seconde métrique pour éviter de détruire la métrique originale
|
|
Met_abstraite metrique_bis(*metrique);
|
|
// ici on considère que l'on a même nombre de ddl par noeud = dim
|
|
// on va modifier chaque ddl de chaque noeud systématiquement
|
|
int nbnoeud = tabnoeud->Taille();
|
|
// le deltat pour les différences finis
|
|
double delta = ConstMath::unpeupetit;
|
|
double mini_val = ConstMath::pasmalpetit;
|
|
int numddl = 1; // le compteur de ddl
|
|
bool erreur = false; // indicateur d'erreur
|
|
bool premier_calcul=true;
|
|
for (int inoeud=1;inoeud<=nbnoeud;inoeud++)
|
|
{// on récupère les coordonnées du noeud
|
|
Coordonnee coordtdt = (*tabnoeud)(inoeud)->Coord2();
|
|
for (int ix= 1;ix<=dim;ix++,numddl++)
|
|
{ Coordonnee X(dim); X(ix) += delta;
|
|
(*tabnoeud)(inoeud)->Ajout_coord2(X);
|
|
// appel de la métrique
|
|
Met_abstraite::Expli_t_tdt ex_n =metrique_bis.Cal_explicit_tdt
|
|
(*tabnoeud,premier_calcul,(*tabDphi)(numInteg),nbNoeud,(*tabPhi)(numInteg),gradV_instantane);
|
|
premier_calcul=false;
|
|
|
|
// calcul des dérivées numériques et vérification
|
|
for (int j=1;j<=dim;j++)
|
|
{ // variation des vecteurs giB_tdt
|
|
CoordonneeB dgiB = ((*ex_n.giB_tdt)(j) -(*ex.giB_tdt)(j))/delta;
|
|
for (int i=1;i<=dim;i++)
|
|
if (diffpourcent(dgiB(i),(*ex.d_giB_tdt)(numddl)(j)(i),MaX(Dabs(dgiB(i)),Dabs((*ex.d_giB_tdt)(numddl)(j)(i))),0.05))
|
|
{if (MiN(Dabs(dgiB(i)),Dabs((*ex.d_giB_tdt)(numddl)(j)(i))) <= mini_val)
|
|
{if ( MaX(Dabs(dgiB(i)),Dabs((*ex.d_giB_tdt)(numddl)(j)(i))) > 50.*delta) erreur = true;}
|
|
else erreur = true;
|
|
};
|
|
// variation des vecteurs giH_tdt
|
|
CoordonneeH dgiH = ((*ex_n.giH_tdt)(j) - (*ex.giH_tdt)(j))/delta;
|
|
for (int i=1;i<=dim;i++)
|
|
if (diffpourcent(dgiH(i),(*ex.d_giH_tdt)(numddl)(j)(i),MaX(Dabs(dgiH(i)),Dabs((*ex.d_giH_tdt)(numddl)(j)(i))),0.05))
|
|
{if (MiN(Dabs(dgiH(i)),Dabs((*ex.d_giH_tdt)(numddl)(j)(i))) <= mini_val)
|
|
{if ( MaX(Dabs(dgiH(i)),Dabs((*ex.d_giH_tdt)(numddl)(j)(i))) > 50.*delta) erreur = true;}
|
|
else erreur = true;
|
|
};
|
|
}
|
|
// variation du tenseur gijBB_tdt
|
|
TenseurBB * gijBB = NevezTenseurBB(*ex_n.gijBB_tdt);
|
|
*gijBB = (*ex_n.gijBB_tdt - *ex.gijBB_tdt) / delta;
|
|
for (int i1=1;i1<=dim;i1++)
|
|
for (int j1=1;j1<=dim;j1++)
|
|
if (diffpourcent((*gijBB)(i1,j1),(*(*ex. d_gijBB_tdt)(numddl))(i1,j1),
|
|
MaX(Dabs((*gijBB)(i1,j1)),Dabs((*(*ex. d_gijBB_tdt)(numddl))(i1,j1))),0.05))
|
|
{if (MiN(Dabs((*gijBB)(i1,j1)),Dabs((*(*ex. d_gijBB_tdt)(numddl))(i1,j1))) <= mini_val)
|
|
{if( MaX(Dabs((*gijBB)(i1,j1)),Dabs((*(*ex. d_gijBB_tdt)(numddl))(i1,j1))) > 50.*delta) erreur = true;}
|
|
else erreur = true;
|
|
};
|
|
// variation du tenseur gijHH_tdt
|
|
TenseurHH * gijHH = NevezTenseurHH(*ex_n.gijHH_tdt);
|
|
*gijHH = (*ex_n.gijHH_tdt - *ex.gijHH_tdt) / delta;
|
|
for (int i1=1;i1<=dim;i1++)
|
|
for (int j1=1;j1<=dim;j1++)
|
|
if (diffpourcent((*gijHH)(i1,j1),(*(*ex. d_gijHH_tdt)(numddl))(i1,j1),
|
|
MaX(Dabs((*gijHH)(i1,j1)),Dabs((*(*ex. d_gijHH_tdt)(numddl))(i1,j1))),0.05))
|
|
{if (MiN(Dabs((*gijHH)(i1,j1)),Dabs((*(*ex. d_gijHH_tdt)(numddl))(i1,j1))) <= mini_val)
|
|
{if( MaX(Dabs((*gijHH)(i1,j1)),Dabs((*(*ex. d_gijHH_tdt)(numddl))(i1,j1))) > 50.*delta) erreur = true;}
|
|
else erreur = true;
|
|
};
|
|
// variation du jacobien
|
|
double djaco = ((*ex_n.jacobien_tdt) - (*ex.jacobien_tdt))/delta;
|
|
if (diffpourcent(djaco,(*ex.d_jacobien_tdt)(numddl),MaX(Dabs(djaco),Dabs((*ex.d_jacobien_tdt)(numddl))),0.05))
|
|
if (MiN(Dabs(djaco),Dabs((*ex.d_jacobien_tdt)(numddl))) <= mini_val)
|
|
{if( MaX(Dabs(djaco),Dabs((*ex.d_jacobien_tdt)(numddl))) > 50.*delta) erreur = true;
|
|
else erreur = true;
|
|
};
|
|
// effacement des tenseurs intermédiaires
|
|
delete gijBB; delete gijHH;
|
|
// maintenant on remet les coordonnées du noeud à l'état initial
|
|
(*tabnoeud)(inoeud)->Change_coord2(coordtdt);
|
|
} // fin de boucle sur la dimension de coordonnée
|
|
} // fin de boucle sur les noeuds
|
|
// message d'erreur si besoin
|
|
if (erreur)
|
|
{ cout << "\n erreur dans le calcul analytique des dérivees de la metrique";
|
|
cout << "\n Deformation::VerifCal_implicit(.."
|
|
<< " , numero d'increment = " << indic_VerifCal_implicit;
|
|
Sortie(1);
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|