// 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) . // // 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 . // // For more information, please consult: . //#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& tabnoeud ,Tableau const & tDphS,Tableau const & tPhS ,Tableau const & tDphH,Tableau 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 & def_equi_t,TenseurBB & epsBB_t,Tableau & d_epsBB ,Tableau & 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 & def_equi_t,TenseurBB & epsBB_tdt,Tableau & d_epsBB ,Tableau & 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 & def_equi_t,TenseurBB & epsBB_tdt,Tableau & d_epsBB_tdt ,Tableau & 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 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 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 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 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 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 & 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 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 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("< 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); } };