// 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-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 . // // For more information, please consult: . #include "Hyper3D.h" //#include "ComLoi_comp_abstraite.h" # include using namespace std; //introduces namespace std #include #include #include "Sortie.h" //================== initialisation des variables static ====================== // ---------- classe Hyper3D --------- Hyper3D::Hyper3D () : // Constructeur par defaut HyperD(RIEN_COMP,RIEN_CATEGORIE_LOI_COMP,3,false) ,indic_Verif_Potentiel_et_var(0),limite_inf_Qeps(sqrt(2)*6.e-5) ,limite_inf_bIIb(36.e-10) {}; // Constructeur utile si l'identificateur du nom de la loi // de comportement et le paramètre phase sont connus Hyper3D::Hyper3D (Enum_comp id_compor,Enum_categorie_loi_comp categorie_comp,bool avec_ph) : HyperD(id_compor,categorie_comp,3,avec_ph) ,indic_Verif_Potentiel_et_var(0),limite_inf_Qeps(sqrt(2)*6.e-5) ,limite_inf_bIIb(36.e-10) {} ; // Constructeur utile si l'identificateur du nom de la loi // de comportement et le paramètre phase sont connus Hyper3D::Hyper3D (char* nom,Enum_categorie_loi_comp categorie_comp,bool avec_ph) : HyperD(nom,categorie_comp,3,avec_ph) ,indic_Verif_Potentiel_et_var(0),limite_inf_Qeps(sqrt(2)*6.e-5) ,limite_inf_bIIb(36.e-10) {} ; // Constructeur de copie Hyper3D::Hyper3D (const Hyper3D& loi) : HyperD (loi) ,indic_Verif_Potentiel_et_var(loi.indic_Verif_Potentiel_et_var) ,limite_inf_Qeps(loi.limite_inf_Qeps) ,limite_inf_bIIb(loi.limite_inf_bIIb) {}; // =========== METHODES Protégées dérivant de virtuelles : ============== // Calcul des invariants, de epsBH, // retour de IdGBH qui pointe sur le bon tenseur //++ TensBH * Invariants (TenseurBB& epsBB_t,TenseurBB& gijBB_t, TenseurBH * Hyper3D::Invariants (const TenseurBB& epsBB_t,const TenseurBB& , const TenseurHH & gijHH_t,const double& jacobien_0,const double& jacobien_t, //++ Invariant & invariant,TensBH & epsBH); Invariant & inv,TenseurBH & epsBH_t) { const Tenseur3BB & epsBB = *((Tenseur3BB*) &epsBB_t); // passage en dim 3 Tenseur3BH & epsBH = *((Tenseur3BH*) &epsBH_t); // passage en dim 3 const Tenseur3HH & gijHH = *((Tenseur3HH*) &gijHH_t); // passage en dim 3 epsBH = epsBB * gijHH; // deformation en mixte inv.Ieps = epsBH.Trace(); // trace de la déformation Tenseur3BH eps_barreBH = epsBH - (inv.Ieps/3.) * IdBH3; inv.V = (jacobien_t/jacobien_0); // dans le cas de la prise en compte de la dilatation il faut changer V if (dilatation) // on considère que la variation de volume thermique = la trace du tenseur de def thermique {double var_vol_thermique = (gijHH * (*epsBB_therm)).Trace(); inv.V -= var_vol_thermique; }; double inv_V = inv.V; // init pour être éventuellement modifié // s'il n'y a pas de régularisation : fact_regularisation = 0. if (Dabs(inv_V) < Dabs(fact_regularisation)) inv_V += fact_regularisation; inv.bIIb = eps_barreBH.II() / 2.; // second invariant // la première méthode de calcul est la méthode traditionnelle, mais elle nécessite beaucoup // plus de calcul que la seconde (qui donne le même résultat à 10^{-18} près environ // une fois que V est calculé // inv.bIIIb = eps_barreBH.III() / 3.; // troisième invariant inv.bIIIb = -0.125/(inv_V * inv_V ) +0.125 - 0.25*inv.Ieps + 1./6. * inv.Ieps * inv.Ieps - inv.Ieps*inv.Ieps*inv.Ieps/27. - 0.5*inv.bIIb +1./3. * inv.bIIb * inv.Ieps; // troisième invariant // if (avec_regularisation) // {// inv.V += fact_regularisation; // inv.bIIb += fact_regularisation; // inv.bIIIb += fact_regularisation; // }; return & IdBH3; }; // calcul des invariants et de leurs variations, de epsBH, // et de sa variation, puis retour de IdGBH qui pointe sur le bon tenseur //++ TensBH * Invariants_et_var (TenseurBB& epsBB_tdt, TenseurBH * Hyper3D::Invariants_et_var (const TenseurBB& epsBB_tdt, const TenseurBB& ,const Tableau & d_gijBB_tdt, const TenseurHH & gijHH_tdt,const Tableau & d_gijHH_tdt, const double& jacobien_0,const double& jacobien_tdt,const Vecteur& d_jacobien_tdt, InvariantVarDdl& inv, //++ TensBH & epsBH_tdt,Tableau & depsBH_tdt); TenseurBH & epsBH_tdt,Tableau & depsBH_tdt) { const Tenseur3BB & epsBB = *((Tenseur3BB*) &epsBB_tdt); // passage en dim 3 Tenseur3BH & epsBH = *((Tenseur3BH*) &epsBH_tdt); // passage en dim 3 const Tenseur3HH & gijHH = *((Tenseur3HH*) &gijHH_tdt); // passage en dim 3 epsBH = epsBB * gijHH; // deformation en mixte inv.Ieps = epsBH.Trace(); // trace de la déformation Tenseur3BH eps_barreBH = epsBH - (inv.Ieps/3.) * IdBH3; inv.V = (jacobien_tdt/jacobien_0); // dans le cas de la prise en compte de la dilatation il faut changer V if (dilatation) // on considère que la variation de volume thermique = la trace du tenseur de def thermique {double var_vol_thermique = (gijHH_tdt * (*epsBB_therm)).Trace(); inv.V -= var_vol_thermique; }; double inv_V = inv.V; // init pour être éventuellement modifié // s'il n'y a pas de régularisation : fact_regularisation = 0. if (Dabs(inv_V) < Dabs(fact_regularisation)) inv_V += fact_regularisation; inv.bIIb = eps_barreBH.II() / 2.; // second invariant // la première méthode de calcul est la méthode traditionnelle, mais elle nécessite beaucoup // plus de calcul que la seconde (qui donne le même résultat à 10^{-18} près environ // une fois que V est calculé // inv.bIIIb = eps_barreBH.III() / 3.; // troisième invariant // cout << "\n inv.bIIIb= "<< inv.bIIIb; inv.bIIIb = -0.125/(inv_V * inv_V ) +0.125 - 0.25*inv.Ieps + 1./6. * inv.Ieps * inv.Ieps - inv.Ieps*inv.Ieps*inv.Ieps/27. - 0.5*inv.bIIb +1./3. * inv.bIIb * inv.Ieps; // troisième invariant // cout << " , "<< inv.bIIIb << " debug Hyper3D::Invariants_et_var " << endl; // if (avec_regularisation) // { //inv.V += fact_regularisation; // inv.bIIb += fact_regularisation; // inv.bIIIb += fact_regularisation; // }; // --- debug /// pour info la bonne expression de bIIIb est donnée par tutu !! // mais le résultat est identique (au erreur de calcul près) avec titi (c'est d'après la formule de denis // thèse chapitre, II.2.3, formule 2.19 // et idem avec toto1 , en fait il n'y a que toto2 qui est complètement faux // // double toto2 = inv.bIIIb - (-1./(8.*inv.V * inv.V ) +1./8. - 0.25*inv.Ieps // + 1./3. * inv.Ieps * inv.Ieps - inv.Ieps*inv.Ieps*inv.Ieps*11/54. // -0.5*inv.bIIb + inv.bIIb * inv.Ieps); // // double je = 1.-2./3.* inv.Ieps; // double je3=je*je*je; // double titi = 1./(inv.V*inv.V) - (je3 - 4.*inv.bIIb*je-8.*inv.bIIIb); // double tutu = 1./(8.*inv.V*inv.V) - 1./8.+1./4.*inv.Ieps-1./6.*inv.Ieps*inv.Ieps // +1./27.*inv.Ieps*inv.Ieps*inv.Ieps // + 0.5*inv.bIIb*1.-1./3.*inv.bIIb* inv.Ieps+inv.bIIIb; // double toto1 = inv.bIIIb -( -1./(8.*inv.V * inv.V ) +1./8. - 0.25*inv.Ieps // + 1./6. * inv.Ieps * inv.Ieps - inv.Ieps*inv.Ieps*inv.Ieps/27. // - 0.5*inv.bIIb +1./3. * inv.bIIb * inv.Ieps); // // if ((Abs(toto1)>ConstMath::petit) || (Abs(toto2)>ConstMath::petit)|| (Abs(titi)>ConstMath::petit)) // cout << "\n ** toto1= " << toto1 << " toto2= " << toto2 << " titi= " << titi<< " tutu= " << tutu; // //// -- fin debug // // cas le la variation int nbddl = d_gijBB_tdt.Taille(); Tenseur3BH deps_barreBH; // grandeurs intermédiaires for (int i = 1; i<= nbddl; i++) {const Tenseur3HH & dgijHH = *((Tenseur3HH*)(d_gijHH_tdt(i))) ; // pour simplifier l'ecriture const Tenseur3BB & dgijBB = *((Tenseur3BB*)(d_gijBB_tdt(i))); // passage en dim 3 Tenseur3BH & depsBH = *((Tenseur3BH*)(depsBH_tdt(i))); // passage en dim 3 depsBH = 0.5 * dgijBB * gijHH_tdt + epsBB * dgijHH; double dIeps = (depsBH).Trace();inv.dIeps(i) = dIeps; deps_barreBH = depsBH - (dIeps/3.) * IdBH3; // en mixte les coordonnées de IdBH3 sont fixes double dbIIb = inv.dbIIb(i) = deps_barreBH && eps_barreBH; double dV = inv.dV(i) = (d_jacobien_tdt(i)/jacobien_0) ; // Pour minimiser le temps de calcul on calcul la dérivée à l'aide de la formule scalaire // inv.dbIIIb(i) = (deps_barreBH * eps_barreBH) && eps_barreBH; // -- formule scalaire de base // inv.bIIIb = -0.125/(inv.V * inv.V ) +0.125 - 0.25*inv.Ieps // + 1./6. * inv.Ieps * inv.Ieps - inv.Ieps*inv.Ieps*inv.Ieps/27. // - 0.5*inv.bIIb +1./3. * inv.bIIb * inv.Ieps; // troisième invariant // d'où la variation inv.dbIIIb(i) = 0.25*dV/(inv_V * inv_V * inv_V) - 0.25*dIeps + 1./3. * dIeps * inv.Ieps - dIeps*inv.Ieps*inv.Ieps/9. - 0.5*dbIIb +1./3. * ( dbIIb * inv.Ieps + inv.bIIb * dIeps ) ; // troisième invariant }; // --- debug // affichage des invariants pour comparer // cout << "\n Hyper3D::Invariants_et_var ( V:" << inv.V <<" Ieps:" << inv.Ieps // << " bIIb:" << inv.bIIb << " bIIIb:" << inv.bIIIb // << "\n dV:" << inv.dV <<"\n dIeps:" << inv.dIeps // << "\n dbIIb:" << inv.dbIIb << "\n dbIIIb:" << inv.dbIIIb // << endl; // //// -- fin debug return & IdBH3; }; // calcul des invariants et de leurs variations par rapport aux déformations // et de sa variation, puis retour de IdGBH qui pointe sur le bon tenseur TenseurBH * Hyper3D::Invariants_et_varEps (const TenseurBB& epsBB_tdt, const TenseurBB& ,const TenseurHH & gijHH_tdt, const double& jacobien_0,const double& jacobien_tdt, InvariantVarEps& inv,TenseurBH & epsBH_tdt) { const Tenseur3BB & epsBB = *((Tenseur3BB*) &epsBB_tdt); // passage en dim 3 Tenseur3BH & epsBH = *((Tenseur3BH*) &epsBH_tdt); // passage en dim 3 const Tenseur3HH & gijHH = *((Tenseur3HH*) &gijHH_tdt); // passage en dim 3 epsBH = epsBB * gijHH; // deformation en mixte inv.Ieps = epsBH.Trace(); // trace de la déformation Tenseur3BH eps_barreBH = epsBH - (inv.Ieps/3.) * IdBH3; inv.V = (jacobien_tdt/jacobien_0); // dans le cas de la prise en compte de la dilatation il faut changer V if (dilatation) // on considère que la variation de volume thermique = la trace du tenseur de def thermique {double var_vol_thermique = (gijHH * (*epsBB_therm)).Trace(); inv.V -= var_vol_thermique; }; double inv_V = inv.V; // init pour être éventuellement modifié // s'il n'y a pas de régularisation : fact_regularisation = 0. if (Dabs(inv_V) < Dabs(fact_regularisation)) inv_V += fact_regularisation; inv.bIIb = eps_barreBH.II() / 2.; // second invariant // la première méthode de calcul est la méthode traditionnelle, mais elle nécessite beaucoup // plus de calcul que la seconde (qui donne le même résultat à 10^{-18} près environ // une fois que V est calculé inv.bIIIb = eps_barreBH.III() / 3.; // troisième invariant // cout << "\n inv.bIIIb= "<< inv.bIIIb; inv.bIIIb = -0.125/(inv_V * inv_V ) +0.125 - 0.25*inv.Ieps + 1./6. * inv.Ieps * inv.Ieps - inv.Ieps*inv.Ieps*inv.Ieps/27. - 0.5*inv.bIIb +1./3. * inv.bIIb * inv.Ieps; // troisième invariant // cout << " , "<< inv.bIIIb << " debug Hyper3D::Invariants_et_varEps " << endl; // if (avec_regularisation) // { //inv.V += fact_regularisation; // inv.bIIb += fact_regularisation; // inv.bIIIb += fact_regularisation; // }; // cas le la variation Tenseur3HH epsHH = gijHH_tdt * epsBH; inv.dIeps_deps_HH = gijHH_tdt - 2. * epsHH; // on a : bIIb = bII - 1/6 Ieps^2 ; et dbII = epsHH - 2. * epsHH * epsBH Tenseur3HH d_bII_HH = epsHH - 2. * epsHH * epsBH ; inv.dbIIb_deps_HH = d_bII_HH - (inv.Ieps/3.) * inv.dbIIb_deps_HH; // on a = bIIIb = bIII - 2/3 (I * bII - I^3/9) : thèse denis, page II.2.1 Tenseur3HH d_bIII = epsHH * epsBH - 2. * epsHH * epsBH * epsBH; inv.dbIIIb_deps_HH = d_bIII + ((inv.Ieps * inv.Ieps / 3.)- (2.*inv.bIIb/3.) ) // mise en facteur du coeff * inv.dIeps_deps_HH // scalaire - (2.*inv.Ieps/3.) * inv.dbIIb_deps_HH; // formule identique au cas de Mooney Rivlin , voir document de synthèse sur les lois hyper-élastiques chap 9 inv.dV_deps_HH = inv.V * gijHH_tdt; // on libère les tenseurs LibereTenseur();LibereTenseurQ(); return & IdBH3; }; // calcul du potentiel et de ses dérivées non compris la phase Hyper3D::PotenSansPhaseSansVar Hyper3D::Potentiel(const Invariant & inv,const double& jacobien0) { // en fait il s'agit du transfert du calcul du potentiel de la forme grenobloise à la forme standard // mais ce transfert n'est possible que si bIIb est non nulle, dans le cas contraire on utilise ` // directement une technique de différence finie pour obtenir une dérivée numérique // def du retour PotenSansPhaseSansVar potret; // récup du conteneur spécifique du point, pour sauvegarde éventuelle SaveResulHyperD & save_resulHyperD = *((SaveResulHyperD*) saveResul); // if ((Dabs(inv.bIIb) > limite_inf_bIIb)||(avec_regularisation)) if (Dabs(inv.bIIb) > limite_inf_bIIb) { // calcul du nouvel invariant sous la nouvelle forme InvariantQeps inv_spes = InvariantSpecifSansPhase(inv); // calcul du potentiel sous la forme polaire PoGrenobleSansPhaseSansVar pot = PoGrenoble(inv_spes,inv); // calcul de potret potret.E = pot.E * inv.V * jacobien0; potret.Ks = pot.Ks; potret.EV = jacobien0 * (inv.V * pot.EV + pot.E); potret.EbIIb = jacobien0 * inv.V * pot.EQ * inv_spes.dQepsdbIIb; // stockage éventuel des invariants et du potentiel if (sortie_post) { save_resulHyperD.invP->V= inv.V; save_resulHyperD.invP->Qeps= inv_spes.Qeps; save_resulHyperD.invP->cos3phi= 0.; save_resulHyperD.invP->potentiel= pot.E; }; } else // cas d'un calcul par différence finie { // calcul des invariants sous la nouvelle forme double Qeps = Invariant0Qeps(inv); // calcul du potentiel sous la forme polaire au point actuel // ainsi que la variation suivant V, la phase ne peut pas être prise en compte // car Qeps est nulle PoGrenoble_V pot = PoGrenoble_et_V(Qeps,inv); // calcul du potentiel pour une petite variation suivant bIIb Invariant inv_n = inv; inv_n.bIIb += limite_inf_bIIb; double Qeps_n = Invariant0Qeps(inv_n); double delta = limite_inf_bIIb; double unsurdelta = 1./delta; // stockage éventuel des invariants et potentiel if (sortie_post) { save_resulHyperD.invP->V= inv_n.V; save_resulHyperD.invP->Qeps= Qeps_n; save_resulHyperD.invP->cos3phi= 0.; save_resulHyperD.invP->potentiel= pot.E; }; double E_n = PoGrenoble(Qeps_n,inv_n); // calcul de potret potret.E = pot.E * inv.V * jacobien0; potret.Ks = pot.Ks; potret.EV = jacobien0 * (inv.V * pot.EV + pot.E); {double inter = (E_n - pot.E ); // on est obligé de faire ainsi car sinon on a des erreurs d'arrondi // le potentiel doit-être croissant, on doit donc avoir toujours inter > 0 if (inter < ConstMath::trespetit) { potret.EbIIb = 0.; } else {potret.EbIIb = jacobien0 * inv.V * inter * unsurdelta;}; }; } return potret; }; // calcul du potentiel et de ses dérivées avec la phase Hyper3D::PotenAvecPhaseSansVar Hyper3D::PotentielPhase(const Invariant& inv,const double& jacobien0) { // en fait il s'agit du transfert du calcul du potentiel de la forme grenobloise à la forme standard // mais ce transfert n'est possible que si bIIb est non nulle, dans le cas contraire on utilise ` // directement une technique de différence finie pour obtenir une dérivée numérique // def du retour PotenAvecPhaseSansVar potret; // récup du conteneur spécifique du point, pour sauvegarde éventuelle SaveResulHyperD & save_resulHyperD = *((SaveResulHyperD*) saveResul); // if ((Dabs(inv.bIIb) > limite_inf_bIIb)||(avec_regularisation)) if (Dabs(inv.bIIb) > limite_inf_bIIb) { // calcul des invariants sous la nouvelle forme InvariantQepsCosphi inv_spes = InvariantSpecif(inv); // calcul du potentiel sous la forme polaire PoGrenobleAvecPhaseSansVar pot = PoGrenoblePhase(inv_spes,inv); // stockage éventuel des invariants et potentiel if (sortie_post) { save_resulHyperD.invP->V= inv.V; save_resulHyperD.invP->Qeps= inv_spes.Qeps; save_resulHyperD.invP->cos3phi= inv_spes.cos3phi; save_resulHyperD.invP->potentiel= pot.E; }; // calcul de potret potret.E = pot.E * inv.V * jacobien0; potret.Ks = pot.Ks; potret.EV = jacobien0 * (inv.V * ( pot.EV + pot.Ecos3phi * inv_spes.dcos3phidV) + pot.E); potret.EIeps = jacobien0 * inv.V * (pot.Ecos3phi * inv_spes.dcos3phidIeps); potret.EbIIb = jacobien0 * inv.V * (pot.EQ * inv_spes.dQepsdbIIb + pot.Ecos3phi * inv_spes.dcos3phidbIIb); } else // cas d'un calcul par différence finie, on considère que toute les dérivées suivant la phase // sont nulles dans ce cas { // calcul des invariants sous la nouvelle forme double Qeps = Invariant0Qeps(inv); // calcul du potentiel sous la forme polaire au point actuel // ainsi que la variation suivant V PoGrenoble_V pot = PoGrenoble_et_V(Qeps,inv); // calcul du potentiel pour une petite variation suivant bIIb Invariant inv_n = inv; inv_n.bIIb += limite_inf_bIIb; Invariant0QepsCosphi inv_spes_n = Invariant0Specif(inv_n); double E_n = PoGrenoble(inv_spes_n,inv_n); double delta = limite_inf_bIIb; double unsurdelta = 1./delta; // stockage éventuel des invariants et du potentiel if (sortie_post) { save_resulHyperD.invP->V= inv.V; save_resulHyperD.invP->Qeps= inv_spes_n.Qeps; save_resulHyperD.invP->cos3phi= inv_spes_n.cos3phi; save_resulHyperD.invP->potentiel= pot.E; }; // calcul de potret potret.E = pot.E * inv.V * jacobien0; potret.Ks = pot.Ks; potret.EV = jacobien0 * (inv.V * pot.EV + pot.E); potret.EIeps = 0.; // potret.EbIIb = jacobien0 * inv.V * (-pot.E + E_n)/limite_inf_bIIb; {double inter = (E_n-pot.E ); // on est obligé de faire ainsi car sinon on a des erreurs d'arrondi // le potentiel doit-être croissant, on doit donc avoir toujours inter > 0 if (inter < ConstMath::trespetit) { potret.EbIIb = 0.; } else {potret.EbIIb = jacobien0 * inv.V * inter *unsurdelta;}; }; } return potret; }; // calcul du potentiel sans phase et dérivées avec ses variations par rapport aux invariants Hyper3D::PotenSansPhaseAvecVar Hyper3D::Potentiel_et_var(const Invariant& inv,const double& jacobien0 ) { // en fait il s'agit du transfert du calcul du potentiel de la forme grenobloise à la forme standard // mais ce transfert n'est possible que si bIIb est non nulle, dans le cas contraire on utilise ` // directement une technique de différence finie pour obtenir une dérivée numérique // def du retour PotenSansPhaseAvecVar potret; // récup du conteneur spécifique du point, pour sauvegarde éventuelle SaveResulHyperD & save_resulHyperD = *((SaveResulHyperD*) saveResul); // if ((Dabs(inv.bIIb) > ConstMath::petit)||(avec_regularisation)) if (Dabs(inv.bIIb) > limite_inf_bIIb) { // calcul des invariants sous la nouvelle forme Invariant2Qeps inv_spes = Invariant2SpecifSansPhase(inv); // calcul du potentiel sous la forme polaire PoGrenobleSansPhaseAvecVar pot = PoGrenoble_et_var(inv_spes,inv); //debug //cout << "\n debug: Hyper3D::" // << " E="<V= inv.V; save_resulHyperD.invP->Qeps= inv_spes.Qeps; save_resulHyperD.invP->cos3phi= 0.; save_resulHyperD.invP->potentiel= pot.E; }; // appel d'une vérification éventuelle //+++verif*** Verif_Potentiel_et_var(inv,jacobien0,potret); } else // cas d'un calcul par différence finie, on considère que toute les dérivées suivant la phase // sont nulles dans ce cas { // calcul des invariants sous la nouvelle forme Invariant inv_n0(inv.Ieps,inv.V,inv.bIIb,inv.bIIIb); double Qeps = Invariant0Qeps(inv_n0); // calcul du potentiel sous la forme polaire au point actuel // ainsi que la variation première et seconde suivant V PoGrenoble_VV pot = PoGrenoble_et_VV(Qeps,inv_n0); // calcul du potentiel pour une petite variation suivant bIIb Invariant inv_n = inv_n0; inv_n.bIIb += limite_inf_bIIb; double delta = limite_inf_bIIb; double unsurdelta = 1./delta; double Qeps_n = Invariant0Qeps(inv_n); // stockage éventuel des invariants et du potentiel if (sortie_post) { save_resulHyperD.invP->V= inv.V; save_resulHyperD.invP->Qeps= Qeps_n; save_resulHyperD.invP->cos3phi= 0.; save_resulHyperD.invP->potentiel= pot.E; }; PoGrenoble_V pot_V = PoGrenoble_et_V(Qeps_n,inv_n); // et pour la dérivée seconde de nouveau une petite variation inv_n.bIIb += limite_inf_bIIb; Qeps_n = Invariant0Qeps(inv_n); double E_n = PoGrenoble(Qeps_n,inv_n); // calcul de potret potret.E = pot.E * inv.V * jacobien0; potret.Ks = pot.Ks; potret.EV = jacobien0 * (inv.V * pot.EV + pot.E); {double inter = (pot_V.E - pot.E); // on est obligé de faire ainsi car sinon on a des erreurs d'arrondi // le potentiel doit-être croissant, on doit donc avoir toujours inter > 0 if (inter < ConstMath::trespetit) { potret.EbIIb = 0.; } else {potret.EbIIb = jacobien0 * inv.V * inter *unsurdelta;}; }; // potret.EbIIb = jacobien0 * inv.V * (pot_V.E - pot.E)/limite_inf_bIIb; // dérivées secondes potret.EVV = jacobien0 * (2. * pot.EV + inv.V * pot.EVV ); {double inter = ((E_n + pot.E) - 2.*pot_V.E ); // on est obligé de faire ainsi car sinon on a des erreurs d'arrondi // la dérivée seconde du potentiel doit-être elle aussi > 0 (au moins à l'origine) if (inter < ConstMath::trespetit) { potret.EbIIb2 = 0.; } else {potret.EbIIb2 = jacobien0 * inv.V * inter * unsurdelta * unsurdelta;}; //cout << "\n debug ((E_n + pot.E) - 2.*pot_V.E )= " << ((E_n + pot.E) - 2.*pot_V.E ) << endl; }; // pour la variation de la dérivée / V, a priori on peut avoir les deux signes // donc on ne fait pas de filtrage // {double inter = (pot_V.EV - pot.EV); // // on est obligé de faire ainsi car sinon on a des erreurs d'arrondi // if (inter < ConstMath::trespetit) // { potret.EbIIbV = potret.EbIIb / inv.V; } // else // {potret.EbIIbV = potret.EbIIb / inv.V // + jacobien0 * inv.V * inter * unsurdelta;}; // }; potret.EbIIbV = potret.EbIIb / inv.V + jacobien0 * inv.V * (pot_V.EV - pot.EV) * unsurdelta; // potret.EbIIbV = potret.EbIIb / inv.V // + jacobien0 * inv.V * (pot_V.EV - pot.EV) / limite_inf_bIIb; // appel d'une vérification éventuelle //+++verif*** Verif_Potentiel_et_var(inv,jacobien0,potret); } // retour return potret; }; // calcul du potentiel avec phase et dérivées avec ses variations par rapport aux invariants Hyper3D::PotenAvecPhaseAvecVar Hyper3D::PotentielPhase_et_var(const Invariant& inv,const double& jacobien0) { // en fait il s'agit du transfert du calcul du potentiel de la forme grenobloise à la forme standard // mais ce transfert n'est possible que si bIIb est non nulle, dans le cas contraire on utilise ` // directement une technique de différence finie pour obtenir une dérivée numérique // def du retour PotenAvecPhaseAvecVar potret; // mise à 0 de tous les termes // récup du conteneur spécifique du point, pour sauvegarde éventuelle SaveResulHyperD & save_resulHyperD = *((SaveResulHyperD*) saveResul); // cout << "\n " << potret.E; // pour avoir a cces en debug ?? // if ((Dabs(inv.bIIb) > limite_inf_bIIb)||avec_regularisation) if (Dabs(inv.bIIb) > limite_inf_bIIb) // if (Dabs(inv.bIIb) > limite_inf_Qeps*limite_inf_Qeps) { // calcul des invariants sous la nouvelle forme Invariant2QepsCosphi inv_spes = Invariant2Specif(inv); // calcul du potentiel sous la forme polaire PoGrenobleAvecPhaseAvecVar pot = PoGrenoblePhase_et_var(inv_spes,inv); // stockage éventuel des invariants et du potentiel if (sortie_post) { save_resulHyperD.invP->V= inv.V; save_resulHyperD.invP->Qeps= inv_spes.Qeps; save_resulHyperD.invP->cos3phi= inv_spes.cos3phi; save_resulHyperD.invP->potentiel= pot.E; }; //cout << "\n calcul normal"; //debug //cout << "\n debug: Hyper3D::" // << " E="< ConstMath::petit) { // ici on calcul comme si on n'avait pas de phase // calcul des invariants sous la nouvelle forme Invariant2Qeps inv_spes = Invariant2SpecifSansPhase(inv); // calcul du potentiel sous la forme polaire PoGrenobleSansPhaseAvecVar pot = PoGrenoble_et_var(inv_spes,inv); // cout << "\n cas analytique sans phase "; // calcul de potret //dérivées premières potret.E = pot.E * inv.V * jacobien0; potret.EV = jacobien0 * (inv.V * pot.EV + pot.E); potret.EbIIb = jacobien0 * inv.V * pot.EQ * inv_spes.dQepsdbIIb; // dérivées secondes potret.EVV = jacobien0 * (2. * pot.EV + inv.V * pot.EVV ); potret.EbIIb2 = jacobien0 * inv.V * ( pot.EQQ * inv_spes.dQepsdbIIb * inv_spes.dQepsdbIIb + pot.EQ * inv_spes.dQepsdbIIb2 ); potret.EbIIbV = jacobien0 * ((pot.EQ + inv.V * pot.EQV) * inv_spes.dQepsdbIIb); // appel d'une vérification éventuelle //+++verif*** Verif_Potentiel_et_var(inv,jacobien0,potret); }*/ else // dernier cas avec un inv.bIIb vraiment petit // cas d'un calcul par différence finie, on considère que toute les dérivées suivant la phase // sont nulles dans ce cas, car de toutes manière on ne peut pas calculer la phase { // calcul des invariants sous la nouvelle forme // cout << "\n cas difference fini sans phase "; Invariant inv_n0(inv.Ieps,inv.V,inv.bIIb,inv.bIIIb); double Qeps = Invariant0Qeps(inv_n0); // calcul du potentiel sous la forme polaire au point actuel // ainsi que la variation première et seconde suivant V PoGrenoble_VV pot = PoGrenoble_et_VV(Qeps,inv_n0); // calcul du potentiel pour une petite variation suivant bIIb Invariant inv_n = inv_n0; double delta = limite_inf_bIIb; double unsurdelta = 1./delta; inv_n.bIIb += delta; Invariant0QepsCosphi inv_spes_n = Invariant0Specif(inv_n); // stockage éventuel des invariants et du potentiel if (sortie_post) { save_resulHyperD.invP->V= inv.V; save_resulHyperD.invP->Qeps= inv_spes_n.Qeps; save_resulHyperD.invP->cos3phi= inv_spes_n.cos3phi; save_resulHyperD.invP->potentiel= pot.E; }; PoGrenoble_V pot_V = PoGrenoble_et_V(inv_spes_n,inv_n); // et pour la dérivée seconde de nouveau une petite variation inv_n.bIIb += delta; inv_spes_n = Invariant0Specif(inv_n); double E_n = PoGrenoble(inv_spes_n,inv_n); // calcul de potret potret.E = pot.E * inv.V * jacobien0; potret.Ks = pot.Ks; // dérivées premières potret.EV = jacobien0 * (inv.V * pot.EV + pot.E); potret.EbIIb = jacobien0 * inv.V * ( pot_V.E - pot.E)*unsurdelta; {double inter = (pot_V.E - pot.E); // on est obligé de faire ainsi car sinon on a des erreurs d'arrondi // le potentiel doit-être croissant, on doit donc avoir toujours inter > 0 if (inter < ConstMath::trespetit) { potret.EbIIb = 0.; } else {potret.EbIIb = jacobien0 * inv.V * inter * unsurdelta;}; }; // dérivées secondes potret.EVV = jacobien0 * (2. * pot.EV + inv.V * pot.EVV ); {double inter = ((E_n + pot.E) - 2.*pot_V.E ); //(E_n - 2.*pot_V.E + pot.E) // on est obligé de faire ainsi car sinon on a des erreurs d'arrondi // la dérivée seconde du potentiel doit-être elle aussi > 0 (au moins à l'origine) if (inter < ConstMath::trespetit) { potret.EbIIb2 = 0.; } else {potret.EbIIb2 = jacobien0 * inv.V * inter * unsurdelta * unsurdelta;}; //cout << "\n debug ((E_n + pot.E) - 2.*pot_V.E )= " << ((E_n + pot.E) - 2.*pot_V.E ) << endl; } // pour la variation de la dérivée / V, a priori on peut avoir les deux signes // donc on ne fait pas de filtrage potret.EbIIbV = potret.EbIIb / inv.V + jacobien0 * inv.V * (pot_V.EV - pot.EV) *unsurdelta; // pour les dérivées selon l'angle tous les termes sont considéré nul potret.EIeps = 0.; potret.EIeps2 = 0.; potret.EIepsV = 0.; potret.EbIIbIeps = 0.; // appel d'une vérification éventuelle // Verif_Potentiel_et_var(inv,jacobien0,potret); }; // retour // --- debug -------- //cout << "\n E= " << potret.E << " EV= " << potret.EV << " EbIIb= " << potret.EbIIb << " EIeps= " << potret.EIeps // << "\n EVV= " << potret.EVV << " EbIIb2= " << potret.EbIIb2 << " EIeps2= " << potret.EIeps2 // << "\n EbIIbIeps = " << potret.EbIIbIeps << " EIepsV= " << potret.EIepsV << " EbIIbV= " << potret.EbIIbV << endl; // ---- fin débug ------- return potret; }; // calcul de l'invariant Qeps seul valable même si Qeps est nul double Hyper3D::Invariant0Qeps(const Invariant & inv) { // les nouveaux invariants double Qeps = sqrt(2. * inv.bIIb); // if (avec_regularisation) // {Qeps += fact_regularisation;} return Qeps; }; // calcul des invariants Qeps,cos3phi seuls Hyper3D::Invariant0QepsCosphi Hyper3D::Invariant0Specif(const Invariant & inv) { Hyper3D::Invariant0QepsCosphi inv_ret; // def du retour // les nouveaux invariants inv_ret.Qeps = sqrt(2. * inv.bIIb); double inv_ret_Qeps = inv_ret.Qeps; // init pour être éventuellement modifié // ensuite avec la régularisation if (avec_regularisation) {inv_ret_Qeps += fact_regularisation;} double unsurQeps = 1./inv_ret_Qeps; // pour simplifier // --- angle de phase double unsurQeps3 = unsurQeps * unsurQeps * unsurQeps; double troisracine6 = 3. * sqrt(6.); inv_ret.cos3phi = troisracine6 * inv.bIIIb * unsurQeps3; if (inv_ret.cos3phi > 1.) inv_ret.cos3phi=1.; if (inv_ret.cos3phi < -1.) inv_ret.cos3phi=-1.; //debug //cout << "\n inv_ret.cos3phi= "< 1.) { inv_ret.cos3phi = 1.;} else if (inv_ret.cos3phi < -1.) { inv_ret.cos3phi = -1.;}; //debug //cout << "\n inv_ret.cos3phi= "<= limite_inf_Qeps)||(avec_regularisation)) if (inv_ret.Qeps >= limite_inf_Qeps) { double unsurQeps3 = unsurQeps * unsurQeps * unsurQeps; double unsurQeps5 = unsurQeps3 * unsurQeps * unsurQeps; double troisracine6 = 3. * sqrt(6.); double neufracine6 = 3. * troisracine6; inv_ret.cos3phi = troisracine6 * inv.bIIIb * unsurQeps3; if (inv_ret.cos3phi > 1.) inv_ret.cos3phi=1.; if (inv_ret.cos3phi < -1.) inv_ret.cos3phi=-1.; // puis les variations inv_ret.dcos3phidV = troisracine6 / 4. * unsurQeps3 /(inv_V * inv_V * inv_V); inv_ret.dcos3phidIeps = troisracine6 * unsurQeps3 * (-0.25 + inv.bIIb*untiers + inv.Ieps*untiers - inv.Ieps * inv.Ieps/9.); inv_ret.dcos3phidbIIb = - neufracine6 * unsurQeps5 * inv.bIIIb + troisracine6 * unsurQeps3 * (inv.Ieps*untiers - 0.5); }; //debug //cout << "\n inv_ret.cos3phi= "<= limite_inf_Qeps)||(avec_regularisation)) if (inv_ret.Qeps >= limite_inf_Qeps) { double unsurQeps5 = unsurQeps3 * unsurQeps * unsurQeps; double unsurQeps7 = unsurQeps5 * unsurQeps * unsurQeps; double racine6=sqrt(6.); double troisracine6 = 3. * racine6; double neufracine6 = 3. * troisracine6; inv_ret.cos3phi = troisracine6 * inv.bIIIb * unsurQeps3; if (inv_ret.cos3phi > 1.) inv_ret.cos3phi=1.; if (inv_ret.cos3phi < -1.) inv_ret.cos3phi=-1.; double unsurV3 = 1. / (inv_V * inv_V * inv_V); // maintenant les variations inv_ret.dcos3phidV = troisracine6 * unsurQeps3 * unsurV3 / 4. ; inv_ret.dcos3phidIeps = troisracine6 * unsurQeps3 * (-0.25 + inv.bIIb*untiers + inv.Ieps*untiers - inv.Ieps * inv.Ieps/9.); inv_ret.dcos3phidbIIb = - neufracine6 * unsurQeps5 * inv.bIIIb + troisracine6 * unsurQeps3 * (inv.Ieps*untiers - 0.5); // les variations secondes inv_ret.dcos3phidV2 = - neufracine6 * unsurQeps3 * unsurV3 / (4. * inv_V); inv_ret.dcos3phidIeps2 = troisracine6 * unsurQeps3 * (1./3. - 2./9. * inv.Ieps); inv_ret.dcos3phidbIIb2 = 15. * troisracine6 * inv.bIIIb * unsurQeps7 - 2.*neufracine6 * unsurQeps5 * (untiers * inv.Ieps - 0.5); inv_ret.dcos3phidVdbIIb = - neufracine6 * unsurQeps5 * unsurV3 * 0.25; inv_ret.dcos3phidIepsdbIIb = racine6 * unsurQeps3 - neufracine6 * unsurQeps5 * (-0.25 + inv.bIIb*untiers + untiers * inv.Ieps - 1./9. * inv.Ieps * inv.Ieps ); }; //debug //cout << "\n inv_ret.cos3phi= "<tablcar,"limite_inf_Qeps_")!=NULL) { *(entreePrinc->entree) >> nom1 ; if (nom1 != "limite_inf_Qeps_") { cout << "\n erreur en lecture du drapeau de limite_inf_Qeps, on attendait le mot cle " << " limite_inf_Qeps_ on a lue: " << nom1 ; entreePrinc->MessageBuffer("**Hyper3D::LectParaSpecifiques((.....**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; *(entreePrinc->entree) >> limite_inf_Qeps; }; // cas limite_inf_Qeps (variable stockée dans Hyper3D.h) if (strstr(entreePrinc->tablcar,"limite_inf_bIIb_")!=NULL) { *(entreePrinc->entree) >> nom1 ; if (nom1 != "limite_inf_bIIb_") { cout << "\n erreur en lecture du drapeau de limite_inf_bIIb, on attendait le mot cle " << " limite_inf_bIIb_ on a lue: " << nom1 ; entreePrinc->MessageBuffer("**Hyper3D::LectParaSpecifiques((.....**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; *(entreePrinc->entree) >> limite_inf_bIIb; }; // cas avec régularisation (variable stockée dans Hyper3D.h) avec_regularisation = false; // par défaut if (strstr(entreePrinc->tablcar,"avec_regularisation_")!=NULL) { *(entreePrinc->entree) >> nom1 ; if (nom1 != "avec_regularisation_") { cout << "\n erreur en lecture du drapeau de regularisation, on attendait le mot cle " << " avec_regularisation_ on a lue: " << nom1 ; entreePrinc->MessageBuffer("**Hyper3D::LectParaSpecifiques((.....**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; *(entreePrinc->entree) >> fact_regularisation; avec_regularisation=true; }; // lecture de l'indication éventuelle du post traitement string le_mot_cle = "sortie_post_"; entreePrinc->Lecture_un_parametre_int(0,nom_class_methode,0,1,le_mot_cle,sortie_post); }; // I/O des paramètres spécifiques: ex: régularisation, limite inf ... void Hyper3D::Ecriture_para_specifiques(ofstream& sort,const int cas) { if (cas == 1) {// la régularisation éventuelle if (avec_regularisation) sort << " avec_regularisation " << fact_regularisation; else sort << " sans_regularisation "; // limites sort << " limite_inf_Qeps= " << limite_inf_Qeps << " limite_inf_bIIb= " << limite_inf_bIIb << " " ; }; }; void Hyper3D::Lecture_para_specifiques(ifstream& ent,const int cas) { if (cas == 1) {// la régularisation éventuelle string nom; ent >> nom; if (nom == "avec_regularisation") {ent >> fact_regularisation;avec_regularisation=true;} else if (nom == "sans_regularisation") avec_regularisation=false; else {cout << "\n erreur en lecture du facteur de regularisation (loi hyperelastique) " << " on a lue: " << nom << " au lieu du mot cle: avec_regularisation ou sans_regularisation"; Sortie(1); }; // limites ent >> nom; if (nom == "limite_inf_Qeps=") ent >> limite_inf_Qeps; else {cout << "\n erreur en lecture de limite_inf_Qeps (loi hyperelastique) " << " on a lue: " << nom << " au lieu du mot cle: limite_inf_Qeps= "; Sortie(1); }; ent >> nom; if (nom == "limite_inf_bIIb=") ent >> limite_inf_bIIb; else {cout << "\n erreur en lecture de limite_inf_bIIb (loi hyperelastique) " << " on a lue: " << nom << " au lieu du mot cle: limite_inf_bIIb= "; Sortie(1); }; }; }; ///=============== fonctions pour la vérification et la mise au point =============== // vérif des dérivées du potentiels par rapport aux invariants, ceci par différences finies void Hyper3D::Verif_Potentiel_et_var(const InvariantVarDdl& inv,const double& jacobien0 ,const PotenSansPhaseAvecVar& potret ) { // dans le cas du premier passage on indique qu'il y a vérification if (indic_Verif_Potentiel_et_var == 0) { cout << "\n ****verification des derivees du potentiels par rapport aux invariants****"; cout << "\n Hyper3D::Verif_Potentiel_et_var \n"; } indic_Verif_Potentiel_et_var++; // potret contiend le potentiel et ses variations première et seconde // on va calculer ces mêmes variations par différences finies et comparer les deux résultats // calcul des invariants sous la nouvelle forme double toto = potret.E; // pour que le débugger affiche potret Invariant inv_n0(inv.Ieps,inv.V,inv.bIIb,inv.bIIIb); // recopie des invariants sans les varddl double Qeps = Invariant0Qeps(inv_n0); double E_n = PoGrenoble(Qeps,inv_n0); // la valeur du potentiel de référence // ici on est sans phase donc deux invariants indépendant V et Qeps, // pour calculer les variations on définit des points distants d'un incrément puis de deux incréments // pour les dérivées premières et secondes double delta = limite_inf_bIIb; double mini_val = ConstMath::pasmalpetit; Invariant inv_et_dbIIb = inv_n0;inv_et_dbIIb.bIIb += delta; double Qeps_et_dbIIb = Invariant0Qeps(inv_et_dbIIb); double E_et_dbIIb = PoGrenoble(Qeps_et_dbIIb,inv_et_dbIIb); Invariant inv_et_dbIIb2 = inv_n0;inv_et_dbIIb2.bIIb += 2. * delta; double Qeps_et_dbIIb2 = Invariant0Qeps(inv_et_dbIIb2); double E_et_dbIIb2 = PoGrenoble(Qeps_et_dbIIb2,inv_et_dbIIb2); Invariant inv_et_dV = inv_n0;inv_et_dV.V += delta; double Qeps_et_dV = Invariant0Qeps(inv_et_dV); double E_et_dV = PoGrenoble(Qeps_et_dV,inv_et_dV); Invariant inv_et_dV2 = inv_n0;inv_et_dV2.V += 2. * delta; double Qeps_et_dV2 = Invariant0Qeps(inv_et_dV2); double E_et_dV2 = PoGrenoble(Qeps_et_dV2,inv_et_dV2); Invariant inv_et_dVdbIIb = inv_n0; inv_et_dVdbIIb.V += delta; inv_et_dVdbIIb.bIIb += delta; double Qeps_et_dVdbIIb = Invariant0Qeps(inv_et_dVdbIIb); double E_et_dVdbIIb = PoGrenoble(Qeps_et_dVdbIIb,inv_et_dVdbIIb); // calcul des dérivées premières double E_V = jacobien0 *(E_et_dV * inv_et_dV.V - E_n * inv.V)/delta; double E_bIIb = (jacobien0 * inv.V)*(E_et_dbIIb - E_n)/delta; // calcul des dérivées secondes double E_V2 = jacobien0 *(E_et_dV2 * inv_et_dV2.V - 2.*E_et_dV * inv_et_dV.V + E_n * inv.V) /(delta * delta); double E_bIIb2 = (jacobien0 * inv.V)*(E_et_dbIIb2 - 2.*E_et_dbIIb + E_n) /(delta * delta); double E_V_a_dbIIb = jacobien0 * (E_et_dVdbIIb * inv_et_dVdbIIb.V - E_et_dbIIb * inv.V) /delta; double E_VbIIb = ( E_V_a_dbIIb - E_V)/delta; // comparaison avec les valeurs de dérivées analytiques int erreur = 0; if (diffpourcent(potret.EV,E_V,E_V,0.05)) { if (MiN(Dabs(potret.EV),Dabs(E_V)) <= mini_val) {if( MaX(Dabs(potret.EV),Dabs(E_V)) > 50.*delta) if (Dabs(potret.EV) == 0.) // on regarde si la dérivée numérique tend vers zéro lorque l'incrément tend vers 0 { Invariant inv_et_ddV = inv_n0;inv_et_ddV.V += delta/10.; double Qeps_et_ddV = Invariant0Qeps(inv_et_ddV); double E_et_ddV = PoGrenoble(Qeps_et_ddV,inv_et_ddV); double E_ddV = jacobien0 *(E_et_ddV * inv_et_ddV.V - E_n * inv.V)/(delta*10.); if (10.* Dabs(E_ddV) > Dabs(E_V)) erreur = 5; } else {erreur = 5;cout << " \n err5: potret.EV= " << potret.EV << " E_V= " << E_V;} else {erreur = 52;cout << " \n err52: potret.EV= " << potret.EV << " E_V= " << E_V;}; } else {erreur = 53;cout << " \n err53: potret.EV= " << potret.EV << " E_V= " << E_V;}; }; // cout << " \n info: potret.EV= " << potret.EV << " E_V= " << E_V; if (diffpourcent(potret.EbIIb,E_bIIb,E_bIIb,0.05)) {if (MiN(Dabs(potret.EbIIb),Dabs(E_bIIb)) <= mini_val) {if( MaX(Dabs(potret.EbIIb),Dabs(E_bIIb)) > 50.*delta) {erreur = 1;cout << " \n err 1: potret.EbIIb= " << potret.EbIIb << " E_bIIb= " << E_bIIb;} } else {erreur = 11;cout << " \n err11: potret.EbIIbV= " << potret.EbIIbV << " E_VbIIb= " << E_VbIIb;}; }; if (diffpourcent(potret.EbIIb2,E_bIIb2,E_bIIb2,0.05)) {if (MiN(Dabs(potret.EbIIb2),Dabs(E_bIIb2)) <= mini_val) {if( MaX(Dabs(potret.EbIIb2),Dabs(E_bIIb2)) > 50.*delta) {erreur = 2;cout << " \n err 2: potret.EbIIb2= " << potret.EbIIb2 << " E_bIIb2= " << E_bIIb2;} } else {erreur = 21;cout << " \n err21: potret.EbIIb2= " << potret.EbIIb2 << " E_bIIb2= " << E_bIIb2;}; }; if (diffpourcent(potret.EVV,E_V2,E_V2,0.05)) {if (MiN(Dabs(potret.EVV),Dabs(E_V2)) <= mini_val) {if( MaX(Dabs(potret.EVV),Dabs(E_V2)) > 50.*delta) {erreur = 3;cout << " \n err 3: potret.EVV= " << potret.EVV << " E_V2= " << E_V2;} } else {erreur = 31;cout << " \n err31: potret.EVV= " << potret.EVV << " E_V2= " << E_V2;}; }; if (diffpourcent(potret.EbIIbV,E_VbIIb,E_VbIIb,0.05)) {if (MiN(Dabs(potret.EbIIbV),Dabs(E_VbIIb)) <= mini_val) {if( MaX(Dabs(potret.EbIIbV),Dabs(E_VbIIb)) > 50.*delta) {erreur = 4;cout << " \n err 4: potret.EbIIbV= " << potret.EbIIbV << " E_VbIIb= " << E_VbIIb;} } else {erreur = 41;cout << " \n err41: potret.EbIIbV= " << potret.EbIIbV << " E_VbIIb= " << E_VbIIb;}; }; // if (erreur) // { cout << "\n erreur dans le calcul analytique des dérivées du potentiel"; // cout << "\n Hyper3D::Verif_Potentiel_et_var, numéro d'appel = " // << indic_Verif_Potentiel_et_var; // Sortie(1); // } }; // vérif des dérivées du potentiels par rapport aux invariants, ceci par différences finies // cas avec la phase void Hyper3D::Verif_Potentiel_et_var(const InvariantVarDdl& inv,const double& jacobien0 ,const PotenAvecPhaseAvecVar& potret ) { // dans le cas du premier passage on indique qu'il y a vérification if (indic_Verif_Potentiel_et_var == 0) { cout << "\n ****verification des derivees du potentiels par rapport aux invariants****"; cout << "\n Hyper3D::Verif_Potentiel_et_var \n"; } indic_Verif_Potentiel_et_var++; // potret contiend le potentiel et ses variations première et seconde // on va calculer ces mêmes variations par différences finies et comparer les deux résultats // calcul des invariants sous la nouvelle forme double toto = potret.E; // pour que le débugger affiche potret Invariant inv_n0(inv.Ieps,inv.V,inv.bIIb,inv.bIIIb); // recopie des invariants sans les varddl Invariant0QepsCosphi is_sp0 = Invariant0Specif(inv_n0); double E_n = PoGrenoble(is_sp0,inv_n0); // la valeur du potentiel de référence // ici on est avec phase donc trois invariants indépendant V et Qeps et cos3phi, // pour calculer les variations on définit des points distants d'un incrément puis de deux incréments // pour les dérivées premières et secondes double delta = limite_inf_bIIb; double mini_val = ConstMath::pasmalpetit; Invariant inv_et_dbIIb = inv_n0;inv_et_dbIIb.bIIb += delta; Invariant0QepsCosphi is_et_dbIIb = Invariant0Specif(inv_et_dbIIb); double E_et_dbIIb = PoGrenoble(is_et_dbIIb,inv_et_dbIIb); Invariant inv_et_dbIIb2 = inv_n0;inv_et_dbIIb2.bIIb += 2. * delta; Invariant0QepsCosphi is_et_dbIIb2 = Invariant0Specif(inv_et_dbIIb2); double E_et_dbIIb2 = PoGrenoble(is_et_dbIIb2,inv_et_dbIIb2); Invariant inv_et_dV = inv_n0;inv_et_dV.V += delta; Invariant0QepsCosphi is_et_dV = Invariant0Specif(inv_et_dV); double E_et_dV = PoGrenoble(is_et_dV,inv_et_dV); Invariant inv_et_dV2 = inv_n0;inv_et_dV2.V += 2. * delta; Invariant0QepsCosphi is_et_dV2 = Invariant0Specif(inv_et_dV2); double E_et_dV2 = PoGrenoble(is_et_dV2,inv_et_dV2); Invariant inv_et_dVdbIIb = inv_n0; inv_et_dVdbIIb.V += delta; inv_et_dVdbIIb.bIIb += delta; Invariant0QepsCosphi is_et_dVdbIIb = Invariant0Specif(inv_et_dVdbIIb); double E_et_dVdbIIb = PoGrenoble(is_et_dVdbIIb,inv_et_dVdbIIb); // cas avec Ieps Invariant inv_et_dIeps = inv_n0;inv_et_dIeps.Ieps += delta; Invariant0QepsCosphi is_et_dIeps = Invariant0Specif(inv_et_dIeps); double E_et_dIeps = PoGrenoble(is_et_dIeps,inv_et_dIeps); Invariant inv_et_dIeps2 = inv_n0;inv_et_dIeps2.Ieps += 2. * delta; Invariant0QepsCosphi is_et_dIeps2 = Invariant0Specif(inv_et_dIeps2); double E_et_dIeps2 = PoGrenoble(is_et_dIeps2,inv_et_dIeps2); Invariant inv_et_dIepsdbIIb = inv_n0; inv_et_dIepsdbIIb.Ieps += delta; inv_et_dIepsdbIIb.bIIb += delta; Invariant0QepsCosphi is_et_dIepsdbIIb = Invariant0Specif(inv_et_dIepsdbIIb); double E_et_dIepsdbIIb = PoGrenoble(is_et_dIepsdbIIb,inv_et_dIepsdbIIb); Invariant inv_et_dIepsdV = inv_n0; inv_et_dIepsdV.Ieps += delta; inv_et_dIepsdV.V += delta; Invariant0QepsCosphi is_et_dIepsdV = Invariant0Specif(inv_et_dIepsdV); double E_et_dIepsdV = PoGrenoble(is_et_dIepsdV,inv_et_dIepsdV); // calcul des dérivées premières // calcul des dérivées premières double E_V = jacobien0 *(E_et_dV * inv_et_dV.V - E_n * inv.V)/delta; double E_bIIb = (jacobien0 * inv.V)*(E_et_dbIIb - E_n)/delta; double E_Ieps = (jacobien0 * inv.V)*(E_et_dIeps - E_n )/delta; // calcul des dérivées secondes hors phases double E_V2 = jacobien0 *(E_et_dV2 * inv_et_dV2.V - 2.*E_et_dV * inv_et_dV.V + E_n * inv.V) /(delta * delta); double E_bIIb2 = (jacobien0 * inv.V)*(E_et_dbIIb2 - 2.*E_et_dbIIb + E_n) /(delta * delta); double E_Ieps2 = (jacobien0 * inv.V) *(E_et_dIeps2 - 2.*E_et_dIeps + E_n )/(delta * delta); double E_V_a_dbIIb = jacobien0 * (E_et_dVdbIIb * inv_et_dVdbIIb.V - E_et_dbIIb * inv_et_dbIIb.V) /delta; double E_VbIIb = ( E_V_a_dbIIb - potret.EV)/delta; double E_Ieps_a_dbIIb = (jacobien0 * inv.V) * (E_et_dIepsdbIIb - E_et_dbIIb) /delta; double E_bIIbIeps = ( E_Ieps_a_dbIIb - potret.EIeps)/delta; double E_Ieps_a_dV = jacobien0 * (E_et_dIepsdV * inv_et_dIepsdV.V - E_et_dV * inv.V) /delta; double E_IepsV = ( E_Ieps_a_dV - potret.EIeps)/delta; // comparaison avec les valeurs de dérivées analytiques int erreur = 0; if (diffpourcent(potret.EV,E_V,E_V,0.05)) {if (MiN(Dabs(potret.EV),Dabs(E_V)) <= mini_val) {if( MaX(Dabs(potret.EV),Dabs(E_V)) > 50.*delta) if (Dabs(potret.EV) == 0.) // on regarde si la dérivée numérique tend vers zéro lorque l'incrément tend vers 0 { Invariant inv_et_ddV = inv_n0;inv_et_ddV.V += delta/10.; double Qeps_et_ddV = Invariant0Qeps(inv_et_ddV); double E_et_ddV = PoGrenoble(Qeps_et_ddV,inv_et_ddV); double E_ddV = jacobien0 *(E_et_ddV * inv_et_ddV.V - E_n * inv.V)/(delta*10.); if (10.* Dabs(E_ddV) > Dabs(E_V)) erreur = 5; } else {erreur = 5;cout << " \n err5: potret.EV= " << potret.EV << " E_V= " << E_V;} else {erreur = 52;cout << " \n err52: potret.EV= " << potret.EV << " E_V= " << E_V;}; } else {erreur = 53;cout << " \n err53: potret.EV= " << potret.EV << " E_V= " << E_V;}; }; if (diffpourcent(potret.EbIIb,E_bIIb,E_bIIb,0.05)) {if (MiN(Dabs(potret.EbIIb),Dabs(E_bIIb)) <= mini_val) {if( MaX(Dabs(potret.EbIIb),Dabs(E_bIIb)) > 50.*delta) {erreur = 1;cout << " \n err 1: potret.EbIIb= " << potret.EbIIb << " E_bIIb= " << E_bIIb;} } else {erreur = 11;cout << " \n err 11: potret.EbIIbV= " << potret.EbIIbV << " E_VbIIb= " << E_VbIIb;}; }; if (diffpourcent(potret.EbIIb2,E_bIIb2,E_bIIb2,0.05)) {if (MiN(Dabs(potret.EbIIb2),Dabs(E_bIIb2)) <= mini_val) {if( MaX(Dabs(potret.EbIIb2),Dabs(E_bIIb2)) > 50.*delta) {erreur = 2;cout << " \n err 2: potret.EbIIb2= " << potret.EbIIb2 << " E_bIIb2= " << E_bIIb2;} } else {erreur = 21;cout << " \n err 21: potret.EbIIb2= " << potret.EbIIb2 << " E_bIIb2= " << E_bIIb2;}; }; if (diffpourcent(potret.EVV,E_V2,E_V2,0.05)) {if (MiN(Dabs(potret.EVV),Dabs(E_V2)) <= mini_val) {if( MaX(Dabs(potret.EVV),Dabs(E_V2)) > 50.*delta) {erreur = 3;cout << " \n err 3: potret.EVV= " << potret.EVV << " E_V2= " << E_V2;} } else {erreur = 31;cout << " \n err 31: potret.EVV= " << potret.EVV << " E_V2= " << E_V2;}; }; if (diffpourcent(potret.EbIIbV,E_VbIIb,E_VbIIb,0.05)) {if (MiN(Dabs(potret.EbIIbV),Dabs(E_VbIIb)) <= mini_val) {if( MaX(Dabs(potret.EbIIbV),Dabs(E_VbIIb)) > 50.*delta) {erreur = 4;cout << " \n err 4: potret.EbIIbV= " << potret.EbIIbV << " E_VbIIb= " << E_VbIIb;} } else {erreur = 41;cout << " \n err 41: potret.EbIIbV= " << potret.EbIIbV << " E_VbIIb= " << E_VbIIb;}; }; if (diffpourcent(potret.EIeps,E_Ieps,E_Ieps,0.05)) {if (MiN(Dabs(potret.EIeps),Dabs(E_Ieps)) <= mini_val) {if( MaX(Dabs(potret.EIeps),Dabs(E_Ieps)) > 50.*delta) {erreur = 6;cout << " \n err 6: potret.EIeps= " << potret.EIeps << " E_Ieps= " << E_Ieps;} } else {erreur = 61;cout << " \n err 61: potret.EIeps= " << potret.EIeps << " E_Ieps= " << E_Ieps;}; }; if (diffpourcent(potret.EIeps2,E_Ieps2,E_Ieps2,0.05)) {if (MiN(Dabs(potret.EIeps2),Dabs(E_Ieps2)) <= mini_val) {if( MaX(Dabs(potret.EIeps2),Dabs(E_Ieps2)) > 50.*delta) {erreur = 7;cout << " \n err 7: potret.EIeps2= " << potret.EIeps2 << " E_Ieps2= " << E_Ieps2;} } else {erreur = 71;cout << " \n err 71: potret.EIeps2= " << potret.EIeps2 << " E_Ieps2= " << E_Ieps2;}; }; if (diffpourcent(potret.EbIIbIeps,E_bIIbIeps,E_bIIbIeps,0.05)) {if (MiN(Dabs(potret.EbIIbIeps),Dabs(E_bIIbIeps)) <= mini_val) {if( MaX(Dabs(potret.EbIIbIeps),Dabs(E_bIIbIeps)) > 50.*delta) {erreur = 8;cout << " \n err 8: potret.EbIIbIeps= " << potret.EbIIbIeps << " E_bIIbIeps= " << E_bIIbIeps;} } else {erreur = 81;cout << " \n err 81: potret.EbIIbIeps= " << potret.EbIIbIeps << " E_bIIbIeps= " << E_bIIbIeps;}; }; if (diffpourcent(potret.EIepsV,E_IepsV,E_IepsV,0.05)) {if (MiN(Dabs(potret.EIepsV),Dabs(E_IepsV)) <= mini_val) {if( MaX(Dabs(potret.EIepsV),Dabs(E_IepsV)) > 50.*delta) {erreur = 9;cout << " \n err 9: potret.EIepsV= " << potret.EIepsV << " E_IepsV= " << E_IepsV;} } else {erreur = 91;cout << " \n err 91: potret.EIepsV= " << potret.EIepsV << " E_IepsV= " << E_IepsV;}; }; /* if (erreur) { cout << "\n erreur dans le calcul analytique des derivees du potentiel"; cout << "\n Hyper3D::Verif_Potentiel_et_var, numero d'appel = " << indic_Verif_Potentiel_et_var << " erreur = " << erreur << endl; Sortie(1); }*/ };