Herezh_dev/Elements/Mecanique/SFE/DeformationSfe1.cc
2023-05-03 17:23:49 +02:00

1041 lines
48 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-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 "DeformationSfe1.h"
# include "Met_Sfe1.h"
#include "ConstMath.h"
#include "ParaGlob.h"
#include "Util.h"
// -------------------------- variables static -------------------
//int DeformationSfe1::numInteg_total = 0;
// indicateur utilisé par VerifCal_def et VerifCal_implicit
int DeformationSfe1::indic_VerifCal_implicitSfe1 = 0;
// ---------- constructeur----------------------------------------
DeformationSfe1::DeformationSfe1 () // constructeur ne devant pas etre utilise
{
#ifdef MISE_AU_POINT
{ cout << "\nErreur : le constructeur par defaut ne doit pa etre utilise !\n";
cout << "DeformationSfe1::DeformationSfe1 () \n";
Sortie(1);
};
#endif
};
// constructeur normal dans le cas d'un ou de plusieurs pt d'integration
DeformationSfe1::DeformationSfe1 (Met_abstraite & a,Tableau<Noeud *>& tabnoeud
,Tableau <Mat_pleine> const & tDphS,Tableau <Vecteur> const & tPhS
,Tableau <Mat_pleine> const & tDphH,Tableau <Vecteur> const & tPhH
):
Deformation (a,tabnoeud,tDphS,tPhS )
,epais(NULL),tabTypeCL(NULL),vplan(NULL)
,numInteg_ep(0),numInteg_surf(0),sauve_numInteg_ep(0),sauve_numInteg_surf(0)
{ tabDphiH = &(tDphH);
tabPhiH = &(tPhH);
// on regarde s'il s'agit de 2D ou 3D c-a-d s'il faut stocker une épaisseur ou non
if (a.Nbvec_des_bases() == 2)
epais = new Epai();
};
// constructeur de copie
DeformationSfe1::DeformationSfe1 (const DeformationSfe1& a) :
Deformation(a)
,epais(NULL)
,tabTypeCL(a.tabTypeCL),vplan(a.vplan)
,numInteg_ep(a.numInteg_ep),numInteg_surf(a.numInteg_surf)
,sauve_numInteg_ep(a.sauve_numInteg_ep),sauve_numInteg_surf(a.sauve_numInteg_surf)
{ tabDphiH = a.tabDphiH;
tabPhiH = a.tabPhiH;
// on regarde s'il s'agit de 2D ou 3D c-a-d s'il faut stocker une épaisseur ou non
if (a.epais != NULL)
epais = new Epai(*(a.epais));
};
DeformationSfe1::~DeformationSfe1 ()
{ if (epais != NULL) delete epais;};
// ============ METHODES PUBLIQUES : ==================
// change le numero d'integration courant
void DeformationSfe1::ChangeNumInteg(int ni)
{ int nbptSur = tabPhi->Taille();
int nbptEpa = tabPhiH->Taille();
sauve_numInteg_surf=numInteg_surf;
sauve_numInteg_ep = numInteg_ep;
sauve_numInteg = numInteg;
numInteg_surf = (ni-1) / nbptEpa +1; // division entière
numInteg_ep = ni - (numInteg_surf-1) * nbptEpa ;
// numInteg_total = ni;
} ;
// change les numeros d'integration de surface et d'epaisseur courant
void DeformationSfe1::ChangeNumIntegSfe1
(int nisurf, int niepaiss)
{ sauve_numInteg_surf=numInteg_surf;
sauve_numInteg_ep = numInteg_ep;
sauve_numInteg = numInteg;
numInteg_ep = niepaiss; numInteg = numInteg_surf = nisurf;
// on fait les changements dus aux nouveaux pts integ
// numInteg_total = (tabPhiH->Taille()) * (numInteg_surf-1) + numInteg_ep;
} ;
// affichage des informations
void DeformationSfe1::Affiche() const
{ cout << "\n -- deformation SFE : --- "
<< "\n nb noeud concerne = "<< tabnoeud->Taille()
<< " numInteg_surf= "<< numInteg_surf
<< " numInteg_ep= "<< numInteg_ep;
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;
};
// calcul explicit:tous les parametres sont de resultats cas d'un calcul à t
const Met_abstraite::Expli& DeformationSfe1::Cal_explicit_t
( 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
bool pas_de_gradV=false; // indique que l'on veut a priori le calcul du gradient de vitesse
Met_Sfe1* met_Sfe1 = (Met_Sfe1*) metrique;
const Met_abstraite::Expli* ex; // le retour
// on effectue un calcul simplifié si ce n'est pas un premier calcul et si ce n'est pas le premier ptinteg
if ((numInteg_ep == 1)||(premier_calcul)) // cas ou l'on doit calculer tous les elements de la facette
ex = &(met_Sfe1->CalSfe1_explicit_t(*tabnoeud,gradV_instantane,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),premier_calcul,(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais,*tabTypeCL,*vplan));
else // cas d'un calcul simplifie
ex = &(met_Sfe1->CalSfe1_explicit_simple_t(*tabnoeud,gradV_instantane,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),premier_calcul,(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais));
// 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);
};
// sauvegarde des infos à 0 éventuellement
//$$$$$$$$$$$$ en fait je crois bien que ça ne sert à rien de sauvegarder le saveDefResul du sfe,
// car le seul qui est utiliser dans Almansi par exemple, c'est le général, donc relatif aux gi (et non au ai),
// celui qui est spécifique au cas SFE contient en plus les infos de la facette, mais qui ne servent pas donc
// alourdisses le stockage !!!!
// --- 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);
};
if (premier_calcul) saveDefResul->MiseAJourGrandeurs_a_0(metrique);
return *ex;
};
// calcul explicit:tous les parametres sont de resultats cas d'un calcul à tdt
const Met_abstraite::Expli_t_tdt& DeformationSfe1::Cal_explicit_tdt
( 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
Met_Sfe1* met_Sfe1 = (Met_Sfe1*) metrique;
const Met_abstraite::Expli_t_tdt* ex; // le retour
// appel de la metrique
// on effectue un calcul simplifié si ce n'est pas un premier calcul et si ce n'est pas le premier ptinteg
if ((numInteg_ep == 1)||(premier_calcul)) // cas ou l'on doit calculer tous les elements de la facette
ex = &(met_Sfe1->CalSfe1_explicit_tdt(*tabnoeud,gradV_instantane,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),premier_calcul,(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais,*tabTypeCL,*vplan));
else // cas d'un calcul simplifie
ex = &(met_Sfe1->CalSfe1_explicit_simple_tdt(*tabnoeud,gradV_instantane,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),premier_calcul,(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais));
// 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
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);
};
return *ex;
};
// cas implicite : tous les parametres sont de resultats
const Met_abstraite::Impli& DeformationSfe1::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é
// recup d'un pointeur sur la metrique sfe1
Met_Sfe1* met_Sfe1 = (Met_Sfe1*) metrique;
const Met_abstraite::Impli* ex; // la sortie
// 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
// appel de la metrique
// on effectue un calcul simplifié si ce n'est pas un premier calcul et si ce n'est pas le premier ptinteg
if ((numInteg_ep == 1)||(premier_calcul)) // cas ou l'on doit calculer tous les elements de la facette
// dans le cas du premier calcul il y a calcul des grandeurs à 0 et à t, pas dans les autres cas
ex =&(met_Sfe1->CalSfe1_implicit ( *tabnoeud,gradV_instantane,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),premier_calcul,(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais,*tabTypeCL,*vplan));
else // cas d'un calcul simplifie
// dans ce cas ci, les infos relatives à la facette, à la courbure, sont issue du calcul du premier pt d'integ
// il n'y a pas de sauvegarde particulière, simplement, on considère que les infos n'ont pas été écrasées entre temps
ex =&(met_Sfe1->CalSfe1_implicit_simple ( *tabnoeud,gradV_instantane,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),premier_calcul,(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais));
// 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);
};
//............... debug vérification ...................
// // vérification éventuelle
// VerifCal_implicit(gradV_instantane, *ex);
//............... debug vérification ...................
// --- 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:
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;
return *ex;
};
// ---------------- calcul des variables primaires autre que pour la mécanique --------
// ------------ donc pas de retour relatif aux déformations
// calcul explicit à t :tous les parametres sont de resultats
const Met_abstraite::Expli& DeformationSfe1::Cal_explicit_t(bool premier_calcul)
{ bool gradV_instantane = false; // ************ pour l'instant figé
// appel de la metrique
Met_Sfe1* met_Sfe1 = (Met_Sfe1*) metrique;
const Met_abstraite::Expli* ex; // le retour
// appel de la metrique
// on effectue un calcul simplifié si ce n'est pas un premier calcul et si ce n'est pas le premier ptinteg
if ((numInteg_ep == 1)||(premier_calcul)) // cas ou l'on doit calculer tous les elements de la facette
ex = &(met_Sfe1->CalSfe1_explicit_t(*tabnoeud,gradV_instantane,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),premier_calcul,(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais,*tabTypeCL,*vplan));
else // cas d'un calcul simplifie
ex = &(met_Sfe1->CalSfe1_explicit_simple_t(*tabnoeud,gradV_instantane,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),premier_calcul,(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais));
return *ex;
};
// calcul explicit à tdt :tous les parametres sont de resultats
const Met_abstraite::Expli_t_tdt& DeformationSfe1::Cal_explicit_tdt(bool premier_calcul)
{ bool gradV_instantane = false; // ************ pour l'instant figé
// appel de la metrique
Met_Sfe1* met_Sfe1 = (Met_Sfe1*) metrique;
const Met_abstraite::Expli_t_tdt* ex; // le retour
// appel de la metrique
// on effectue un calcul simplifié si ce n'est pas un premier calcul et si ce n'est pas le premier ptinteg
if ((numInteg_ep == 1)||(premier_calcul)) // cas ou l'on doit calculer tous les elements de la facette
ex = &(met_Sfe1->CalSfe1_explicit_tdt(*tabnoeud,gradV_instantane,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),premier_calcul,(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais,*tabTypeCL,*vplan));
else // cas d'un calcul simplifie
ex = &(met_Sfe1->CalSfe1_explicit_simple_tdt(*tabnoeud,gradV_instantane,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),premier_calcul,(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais));
return *ex;
};
// cas implicite : tous les parametres sont de resultats
const Met_abstraite::Impli& DeformationSfe1::Cal_implicit(bool premier_calcul)
{ bool gradV_instantane = false; // ************ pour l'instant figé
// recup d'un pointeur sur la metrique sfe1
Met_Sfe1* met_Sfe1 = (Met_Sfe1*) metrique;
const Met_abstraite::Impli* ex; // la sortie
// 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
// appel de la metrique
// on effectue un calcul simplifié si ce n'est pas un premier calcul et si ce n'est pas le premier ptinteg
if ((numInteg_ep == 1)||(premier_calcul)) // cas ou l'on doit calculer tous les elements de la facette
ex = &(met_Sfe1->CalSfe1_implicit (*tabnoeud,gradV_instantane,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),premier_calcul,(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais,*tabTypeCL,*vplan));
else // cas d'un calcul simplifie
ex = &(met_Sfe1->CalSfe1_implicit_simple (*tabnoeud,gradV_instantane,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),premier_calcul,(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais));
return *ex;
};
// ========== remontee aux informations =========================
// cas sortie d'un calcul implicit
// Aa(i,a) = Aa^i_{.a}, avec g^i = Aa^i_{.a} * I^a
// tout ce passe comme si I^a est la nouvelle base vers laquelle on veut évoluer
const Met_abstraite::InfoImp DeformationSfe1::RemontImp(bool absolue,Mat_pleine& Aa0,Mat_pleine& Aafin)
{ // recup d'un pointeur sur la metrique sfe1
Met_Sfe1* met_Sfe1 = (Met_Sfe1*) metrique;
Met_abstraite::InfoImp ex = met_Sfe1->CalSfe1_InfoImp( *tabnoeud,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais,*tabTypeCL,*vplan);
// 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 calcul de matrices de passage
const Met_abstraite::InfoImp DeformationSfe1::RemontImp()
{ // recup d'un pointeur sur la metrique sfe1
Met_Sfe1* met_Sfe1 = (Met_Sfe1*) metrique;
Met_abstraite::InfoImp ex = met_Sfe1->CalSfe1_InfoImp( *tabnoeud,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais,*tabTypeCL,*vplan);
// 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} * I^a
// tout ce passe comme si I^a est la nouvelle base vers laquelle on veut évoluer
const Met_abstraite::InfoExp_t DeformationSfe1::RemontExp_t(bool absolue,Mat_pleine& Aa0,Mat_pleine& Aafin)
{ // recup d'un pointeur sur la metrique sfe1
Met_Sfe1* met_Sfe1 = (Met_Sfe1*) metrique;
Met_abstraite::InfoExp_t ex = met_Sfe1->CalSfe1_InfoExp_t( *tabnoeud,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais,*tabTypeCL,*vplan);
// 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 calcul de matrice de passage
const Met_abstraite::InfoExp_t DeformationSfe1::RemontExp_t()
{ // recup d'un pointeur sur la metrique sfe1
Met_Sfe1* met_Sfe1 = (Met_Sfe1*) metrique;
Met_abstraite::InfoExp_t ex = met_Sfe1->CalSfe1_InfoExp_t( *tabnoeud,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais,*tabTypeCL,*vplan);
// 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} * I^a
// tout ce passe comme si I^a est la nouvelle base vers laquelle on veut évoluer
const Met_abstraite::InfoExp_tdt DeformationSfe1::RemontExp_tdt(bool absolue,Mat_pleine& Aa0,Mat_pleine& Aafin)
{ // recup d'un pointeur sur la metrique sfe1
Met_Sfe1* met_Sfe1 = (Met_Sfe1*) metrique;
Met_abstraite::InfoExp_tdt ex = met_Sfe1->CalSfe1_InfoExp_tdt( *tabnoeud,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais,*tabTypeCL,*vplan);
// 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 calcul de matrice de passage
const Met_abstraite::InfoExp_tdt DeformationSfe1::RemontExp_tdt()
{ // recup d'un pointeur sur la metrique sfe1
Met_Sfe1* met_Sfe1 = (Met_Sfe1*) metrique;
Met_abstraite::InfoExp_tdt ex = met_Sfe1->CalSfe1_InfoExp_tdt( *tabnoeud,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais,*tabTypeCL,*vplan);
// 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} * I^a
// tout ce passe comme si I^a est la nouvelle base vers laquelle on veut évoluer
const Met_abstraite::Info0_t_tdt DeformationSfe1::Remont0_t_tdt(bool absolue,Mat_pleine& Aa0,Mat_pleine& Aat,Mat_pleine& Aatdt)
{ // recup d'un pointeur sur la metrique sfe1
Met_Sfe1* met_Sfe1 = (Met_Sfe1*) metrique;
Met_abstraite::Info0_t_tdt ex = met_Sfe1->CalSfe1_Info0_t_tdt( *tabnoeud,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais,*tabTypeCL,*vplan);
// 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 calcul de matrice de passage
const Met_abstraite::Info0_t_tdt DeformationSfe1::Remont0_t_tdt()
{ // recup d'un pointeur sur la metrique sfe1
Met_Sfe1* met_Sfe1 = (Met_Sfe1*) metrique;
Met_abstraite::Info0_t_tdt ex = met_Sfe1->CalSfe1_Info0_t_tdt( *tabnoeud,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais,*tabTypeCL,*vplan);
// 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;
};
// gestion du parcours de tous les points d'integration
void DeformationSfe1::PremierPtInteg()
{ sauve_numInteg_surf=numInteg_surf;
sauve_numInteg_ep = numInteg_ep;
sauve_numInteg = numInteg;
numInteg = 1 ; numInteg_ep = 1; numInteg_surf = 1;
};
bool DeformationSfe1::DernierPtInteg()
{ sauve_numInteg_surf=numInteg_surf;
sauve_numInteg_ep = numInteg_ep;
sauve_numInteg = numInteg;
// on ne contrôle que le numéro de surface vue le fonctionnement de NevezPtInteg
if (numInteg_surf <= (tabPhi->Taille()) )
return true;
else
return false;
};
void DeformationSfe1::NevezPtInteg()
{ sauve_numInteg_surf=numInteg_surf;
sauve_numInteg_ep = numInteg_ep;
sauve_numInteg = numInteg;
// les pt varient d'abord en épaisseurs pour ensuite en surface, ce qui permet d'optimiser
// le calcul de la courbure qui n'est fait que pour le premier pt d'épaisseur
if (numInteg_ep < Nb_pt_int_epai())
numInteg_ep++;
else
{ numInteg_surf++;numInteg++;
numInteg_ep = 1;
}
};
// méthode pour revenir au pti précédant
void DeformationSfe1::Retour_pti_precedant()
{numInteg=sauve_numInteg;
numInteg_surf = sauve_numInteg_surf;
numInteg_ep = sauve_numInteg_ep;
};
// Aa(i,a) = Aa^i_{.a}, avec g^i = Aa^i_{.a} * I^a
// tout ce passe comme si I^a est la nouvelle base vers laquelle on veut évoluer
// si absolue = true: on fait un passage vers la base absolue
// si = false : on fait un passage vers une base ad hoc
void DeformationSfe1::BasePassage
(bool absolue,const BaseB & giB0,const BaseB & giB,const BaseH & giH0,const BaseH & giH,
Mat_pleine& Aa0,Mat_pleine& Aafin)
{
// *********$ sans doute à faire évoluer : (16 sept 2019) vers les cas généraux de Deformation
// car 1) c'est compliquer, et 2) je pense qu'il y a des cas qui manquent ici et donc que cela
// va -> des erreurs en sortie
// **** donc à voir si pb à venir
// determination des matrices de transformation de base
// l'objectif est de determiner un repere pertinant
// 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
Coordonnee N = (Util::ProdVec_coorBN(giB0(1),giB0(2))).Normer();
Coordonnee ve(0.,-N(3),N(2)); // = ProdVec(N,I1)
double norve = ve.Norme();
int tail_Aa0 = Aa0.Nb_ligne(); // pour tenir compte d'une dim = 2 ou 3
Tableau <Coordonnee> vi(tail_Aa0); // 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));
};
if (tail_Aa0 == 3)
vi(3) = N;
if(giH0.NbVecteur()==tail_Aa0)
{for (int al=1 ;al<=tail_Aa0;al++)
for (int bl = 1;bl<=tail_Aa0;bl++)
Aa0(bl,al) = giH0.Coordo(bl) * vi(al) ;
}
else // sinon cela signifie que le nombre est < donc à 3, car on traîte de repère pour facette
{for (int al=1 ;al<=tail_Aa0;al++)
{for (int bl = 1;bl<=2;bl++)
Aa0(bl,al) = giH0.Coordo(bl) * vi(al) ;
Aa0(3,al) = N * vi(al) ; // on considère que le 3ième vecteur c'est la normale
};
};
// for (int al=1 ;al<=2;al++)
// {Aa0(1,al) = giH0.Coordo(1) * vi(al) ;
// Aa0(2,al) = giH0.Coordo(2) * vi(al) ;
// }
// ---- 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 DeformationSfe1::BasePassage( ";
//};
// ---- fin vérification
//------ cas de la config finale,
N = (Util::ProdVec_coorBN(giB(1),giB(2))).Normer();
ve.Change_Coordonnee(3,0.,-N(3),N(2)); // = ProdVec(N,I1)
norve = ve.Norme();
int tail_Aa = Aafin.Nb_ligne(); // pour tenir compte d'une dim = 2 ou 3
Tableau <Coordonnee> Aa(tail_Aa);
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));
};
if (tail_Aa == 3)
Aa(3) = N;
if(giH.NbVecteur()==tail_Aa)
{for (int be=1 ;be<=tail_Aa;be++)
for (int bl = 1;bl<=tail_Aa;bl++)
Aafin(bl,be) = giH.Coordo(bl) * Aa(be) ;
}
else // sinon cela signifie que le nombre est < donc à 3, car on traîte de repère pour facette
{for (int be=1 ;be<=tail_Aa;be++)
{for (int bl = 1;bl<=2;bl++)
Aafin(bl,be) = giH.Coordo(bl) * Aa(be) ;
Aafin(3,be) = N * Aa(be) ; // on considère que le 3ième vecteur c'est la normale
};
};
// for (int be=1;be<=2;be++)
// { Aafin(1,be) = giH.Coordo(1) * Aa(be);
// Aafin(2,be) = giH.Coordo(2) * Aa(be);
// };
// ---- vérification que le déterminant n'est pas nul
//{double det = Aafin(1,1) * Aafin(2,2) - Aafin(1,2) * Aafin(2,1);
// if (Abs(det) < 0.00001)
// cout << "\n erreur det null " << det << " dans DeformationSfe1::BasePassage( ";
//};
// ---- fin vérification
return;
};
// cas où l'on veut les matrices de passages à 0 t et tdt
// Aa(i,a) = Aa^i_{.a}, avec g^i = Aa^i_{.a} * I^a
// tout ce passe comme si I^a est la nouvelle base vers laquelle on veut évoluer
void DeformationSfe1::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)
{
// *********$ sans doute à faire évoluer : (16 sept 2019) vers les cas généraux de Deformation
// car 1) c'est compliquer, et 2) je pense qu'il y a des cas qui manquent ici et donc que cela
// va -> des erreurs en sortie
// **** donc à voir si pb à venir
// determination des matrices de transformation de base
// l'objectif est de determiner un repere pertinant
// 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
Coordonnee N = (Util::ProdVec_coorBN(giB0(1),giB0(2))).Normer();
Coordonnee ve(0.,-N(3),N(2)); // = ProdVec(N,I1)
double norve = ve.Norme();
int tail_Aa0 = Aa0.Nb_ligne(); // pour tenir compte d'une dim = 2 ou 3
Tableau <Coordonnee> vi(tail_Aa0); // les vecteurs plans orthonormes de la facette
if (norve >= ConstMath::petit)
{ 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));
};
if (tail_Aa0 == 3)
vi(3) = N;
if(giH0.NbVecteur()==tail_Aa0)
{for (int al=1 ;al<=tail_Aa0;al++)
for (int bl = 1;bl<=tail_Aa0;bl++)
Aa0(bl,al) = giH0.Coordo(bl) * vi(al) ;
}
else // sinon cela signifie que le nombre est < donc à 3, car on traîte de repère pour facette
{for (int al=1 ;al<=tail_Aa0;al++)
{for (int bl = 1;bl<=2;bl++)
Aa0(bl,al) = giH0.Coordo(bl) * vi(al) ;
Aa0(3,al) = N * vi(al) ; // on considère que le 3ième vecteur c'est la normale
};
};
// for (int al=1 ;al<=2;al++)
// {Aa0(1,al) = giH0.Coordo(1) * vi(al) ;
// Aa0(2,al) = giH0.Coordo(2) * vi(al) ;
// }
//------ cas de la config à t ,
N = (Util::ProdVec_coorBN(giB_t(1),giB_t(2))).Normer();
ve.Change_Coordonnee(3,0.,-N(3),N(2)); // = ProdVec_coor(N,I1)
norve = ve.Norme();
int tail_jtB = Aa_t.Nb_ligne(); // pour tenir compte d'une dim = 2 ou 3
Tableau <Coordonnee> jtB(tail_jtB);
if (norve >= ConstMath::petit)
{ jtB(2) = ve.Normer();
jtB(1) = Util::ProdVec_coor(jtB(2),N);
}
else
{ ve.Change_Coordonnee(3,N(3),0.,-N(1)); // = ProdVec_coor(I2,N)
jtB(1) = ve.Normer();
jtB(2) = Util::ProdVec_coor(N,jtB(1));
};
if (tail_jtB == 3)
jtB(3) = N;
if(giH_t.NbVecteur()==tail_jtB)
{for (int be=1 ;be<=tail_jtB;be++)
for (int bl = 1;bl<=tail_jtB;bl++)
Aa_t(bl,be) = giH_t.Coordo(bl) * jtB(be) ;
}
else // sinon cela signifie que le nombre est < donc à 3, car on traîte de repère pour facette
{for (int be=1 ;be<=tail_jtB;be++)
{for (int bl = 1;bl<=2;bl++)
Aa_t(bl,be) = giH_t.Coordo(bl) * jtB(be) ;
Aa_t(3,be) = N * jtB(be) ; // on considère que le 3ième vecteur c'est la normale
};
};
// for (int be=1;be<=2;be++)
// { Aa_t(1,be) = giH_t.Coordo(1) * jtB(be);
// Aa_t(2,be) = giH_t.Coordo(2) * jtB(be);
// }
//------ cas de la config tdt,
N = (Util::ProdVec_coorBN(giB_tdt(1),giB_tdt(2))).Normer();
ve.Change_Coordonnee(3,0.,-N(3),N(2)); // = ProdVec_coor(N,I1)
norve = ve.Norme();
int tail_jtdtB = Aa_tdt.Nb_ligne(); // pour tenir compte d'une dim = 2 ou 3
Tableau <Coordonnee> jtdtB(tail_jtdtB);
if (norve >= ConstMath::petit)
{ jtdtB(2) = ve.Normer();
jtdtB(1) = Util::ProdVec_coor(jtdtB(2),N);
}
else
{ ve.Change_Coordonnee(3,N(3),0.,-N(1)); // = ProdVec_coor(I2,N)
jtdtB(1) = ve.Normer();
jtdtB(2) = Util::ProdVec_coor(N,jtdtB(1));
};
if (tail_jtdtB == 3)
jtdtB(3) = N;
if(giH_tdt.NbVecteur()==tail_jtdtB)
{for (int be=1 ;be<=tail_jtdtB;be++)
for (int bl = 1;bl<=tail_jtdtB;bl++)
Aa_tdt(bl,be) = giH_tdt.Coordo(bl) * jtdtB(be) ;
}
else // sinon cela signifie que le nombre est < donc à 3, car on traîte de repère pour facette
{for (int be=1 ;be<=tail_jtdtB;be++)
{for (int bl = 1;bl<=2;bl++)
Aa_tdt(bl,be) = giH_tdt.Coordo(bl) * jtdtB(be) ;
Aa_tdt(3,be) = N * jtdtB(be) ; // on considère que le 3ième vecteur c'est la normale
};
};
// for (int be=1;be<=2;be++)
// { Aa_tdt(1,be) = giH_tdt.Coordo(1) * jtdtB(be);
// Aa_tdt(2,be) = giH_tdt.Coordo(2) * jtdtB(be);
// }
return;
};
// ------------------------ METHODES PROTEGEES : -------------------------------
// ----------------- méthodes de vérifications------- ----
void DeformationSfe1::VerifCal_def(bool gradV_instantane,const Met_abstraite::Impli & ,TenseurBB& epsBB_tdt
,Tableau <TenseurBB *> & d_epsBB_tdt)
{ // 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_implicitSfe1 == 0)
{ cout << "\n ****vérification du calcul de la déformation et des éléments de la métrique associé****";
cout << "\n DeformationSfe1::VerifCal_def(... \n";
}
indic_VerifCal_implicitSfe1++;
// on cré une seconde métrique pour éviter de détruire la métrique originale
Met_Sfe1 metrique_bis(*((Met_Sfe1*)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 metrique
const Met_abstraite::Expli_t_tdt& ex_n =
metrique_bis.Cal_explicit_tdt(*tabnoeud,premier_calcul,(*tabDphi)(numInteg),
nbNoeud,(*tabPhi)(numInteg),gradV_instantane);
TenseurBB * epsBB_tdt_n = NevezTenseurBB(epsBB_tdt);
// calcul de la base duale et de la métrique à t=0
const Met_abstraite::gijHH_0_et_giH_0& ex1_n = metrique_bis.Cal_gijHH_0_et_giH_0_apres_im_expli();
bool variation = false; // pour la variation de B et Palpha_BH
Tableau <TenseurBB *> d_epsBB_tdt_n(d_epsBB_tdt);
for (int i=1;i<= d_epsBB_tdt_n.Taille();i++) d_epsBB_tdt_n(i)=NevezTenseurBB(*d_epsBB_tdt(1));
// appel pour le calcul de la déformation logarithmique et de sa variation
// Cal_Logarithmique (*ex_n.gijBB_0,*ex1_n.gijHH_0,d_epsBB_tdt_n,*ex_n.gijBB_tdt,*ex_n.gijHH_tdt,*epsBB_tdt_n
// ,*ex_n.d_gijBB_tdt,variation);
// 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 epsBB_tdt
TenseurBB * ddepsBB = NevezTenseurBB(epsBB_tdt);
*ddepsBB = (*epsBB_tdt_n - epsBB_tdt) / delta; // la dérivée numérique
for (int i1=1;i1<=dim;i1++)
for (int j1=1;j1<=dim;j1++)
if (diffpourcent((*ddepsBB)(i1,j1),(*(d_epsBB_tdt(numddl)))(i1,j1),
MaX(Dabs((*ddepsBB)(i1,j1)),Dabs((*(d_epsBB_tdt(numddl)))(i1,j1))),0.05))
{if (MiN(Dabs((*ddepsBB)(i1,j1)),Dabs((*(d_epsBB_tdt(numddl)))(i1,j1))) <= mini_val)
{if( MaX(Dabs((*ddepsBB)(i1,j1)),Dabs((*(d_epsBB_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 DeformationSfe1::VerifCal_def(.."
<< " , numero d'increment = " << indic_VerifCal_implicitSfe1;
Sortie(1);
}
};
void DeformationSfe1::VerifCal_implicit(bool gradV_instantane,const Met_abstraite::Impli & ex)
{ // 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_implicitSfe1 == 0)
{ cout << "\n ****verification du calcul de la deformation et des elements de la metrique associe****";
cout << "\n DeformationSfe1::VerifCal_implicit \n";
}
indic_VerifCal_implicitSfe1++;
// on cré une seconde métrique pour éviter de détruire la métrique originale
Met_Sfe1 metrique_bis(*((Met_Sfe1*)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
int nberr = 10;
Tableau<int> erreur(nberr);
double diff_admi = 0.1;
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
const Met_abstraite::Expli_t_tdt& ex_n = metrique_bis.CalSfe1_explicit_tdt
(*tabnoeud,gradV_instantane,(*tabDphi)(numInteg_surf),nbNoeud
,(*tabPhi)(numInteg_surf),premier_calcul,(*tabDphiH)(numInteg_ep),(*tabPhiH)(numInteg_ep)
,epais,*tabTypeCL,*vplan);
premier_calcul=false;
// calcul des dérivées numériques et vérification
int nb_vecteur = 2;
for (int j=1;j<=nb_vecteur;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))),diff_admi))
{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(1) += 1;}
else
{erreur(2) += 1;
cout << "\ndgiB("<<i<<")="<<dgiB(i)<<",(*ex.d_giB_tdt)("<<numddl<<")("<<j<<")("<<i<<")="<< (*ex.d_giB_tdt)(numddl)(j)(i);
}
};
// 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))),diff_admi))
{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(3) += 1;}
else erreur(4) += 1;
};
};
// 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<=nb_vecteur;i1++)
for (int j1=1;j1<=nb_vecteur;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))),diff_admi))
{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(5) += 1;}
else erreur(6) += 1;
};
// 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<=nb_vecteur;i1++)
for (int j1=1;j1<=nb_vecteur;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))),diff_admi))
{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(7) += 1;}
else erreur(8) += 1;
};
// 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))),diff_admi))
{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(9) += 1; //(*ex.d_jacobien_tdt)(numddl) = djaco; // pour voir l'implication d'une bonne dérivée de jacobien
}
}
else erreur(10) += 1;
};
// 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
bool une_erreur=false;
for (int l=1;l<=nberr;l++) if (erreur(l) != 0) une_erreur=true;
if (une_erreur)
{ cout << "\n erreur dans le calcul analytique des derivees de la metrique";
cout << "\n DeformationSfe1::VerifCal_implicit(.."
<< " , numero d'increment = " << indic_VerifCal_implicitSfe1 << " erreur = " << erreur << endl;
// Sortie(1);
}
};