Herezh_dev/herezh_pp/comportement/Hyper_elastique/IsoHyper3DFavier3.cc

1033 lines
46 KiB
C++
Raw Normal View History

// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.
#include "IsoHyper3DFavier3.h"
#include "ComLoi_comp_abstraite.h"
# include <iostream>
using namespace std; //introduces namespace std
#include <math.h>
#include <stdlib.h>
#include "Sortie.h"
#include "ConstMath.h"
#include "CharUtil.h"
//================== initialisation des variables static ======================
// indicateur utilisé par Verif_Potentiel_et_var
int IsoHyper3DFavier3::indic_Verif_PoGrenoble_et_var = 0;
double IsoHyper3DFavier3::limite_co2=700.; // limite à partir de laquelle on considère que cosh(co2) = infini
// ici cosh(700.) = 5.0712e+303 !!
//================== fin d'initialisation des variables static ================
IsoHyper3DFavier3::IsoHyper3DFavier3 () : // Constructeur par defaut
Hyper3D(ISOHYPER3DFAVIER3,CAT_MECANIQUE,false),K(ConstMath::trespetit),Qor(ConstMath::trespetit)
,mur(ConstMath::trespetit),mu_inf(ConstMath::trespetit)
,nQor(ConstMath::trespetit),gammaQor(ConstMath::trespetit)
,n_mu_inf(ConstMath::trespetit),gamma_mu_inf(ConstMath::trespetit)
{};
// Constructeur de copie
IsoHyper3DFavier3::IsoHyper3DFavier3 (const IsoHyper3DFavier3& loi) :
Hyper3D (loi),K(loi.K),Qor(loi.Qor),mur(loi.mur),mu_inf(loi.mu_inf)
,nQor(loi.nQor),gammaQor(loi.gammaQor)
,n_mu_inf(loi.n_mu_inf),gamma_mu_inf(loi.gamma_mu_inf)
{};
// Lecture des donnees de la classe sur fichier
void IsoHyper3DFavier3::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCourbes1D&
,LesFonctions_nD& lesFonctionsnD)
{ // lecture des quatres coefficients de la loi
*(entreePrinc->entree) >> K >> Qor >> mur >> mu_inf ;
// on regarde ensuite s'il y a la phase
if (strstr(entreePrinc->tablcar,"avec_phase")!=NULL)
{ // lecture des 4 paramètres de phase
entreePrinc->NouvelleDonnee(); // passage d'une ligne
*(entreePrinc->entree) >> nQor >> gammaQor >> n_mu_inf >> gamma_mu_inf ;
avec_phase=true;
};
// cas avec régularisation (variable stockée dans Hyper3D.h)
string nom1;
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 cles "
<< " avec_regularisation_ on a lue: " << nom1 ;
entreePrinc->MessageBuffer("**9--IsoHyper3DOrgeas1::LectureDonneesParticulieres(.....**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
*(entreePrinc->entree) >> fact_regularisation;
avec_regularisation=true;
};
// lecture de l'indication du post traitement
string nom_class_methode = "IsoHyper3DFavier3";string le_mot_cle = "sortie_post_";
entreePrinc->Lecture_un_parametre_int(0,nom_class_methode,0,1,le_mot_cle,sortie_post);
// appel au niveau de la classe mère
Loi_comp_abstraite::Lecture_type_deformation_et_niveau_commentaire
(*entreePrinc,lesFonctionsnD);
};
// affichage de la loi
void IsoHyper3DFavier3::Affiche() const
{ cout << " \n loi de comportement 3D hyperelastique isotrope favier3 : " << Nom_comp(id_comp)
<< " paramètres : \n";
cout << " K= " << K << " ; Qor = " << Qor << " ; mur = " << mur << " ; mu_inf = " << mu_inf ;
if (avec_phase)
{ cout << "\n cas de la loi avec phase, parametre de la phase: "
<< " nQor= " << nQor << " gammaQor= " << gammaQor << " n_mu_inf= "
<< n_mu_inf << " gamma_mu_inf= " << gamma_mu_inf;
}
cout << endl;
// appel de la classe mère
Loi_comp_abstraite::Affiche_don_classe_abstraite();
};
// affichage et definition interactive des commandes particulières à chaques lois
void IsoHyper3DFavier3::Info_commande_LoisDeComp(UtilLecture& entreePrinc)
{ ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier
cout << "\n definition standart (rep o) ou exemples exhaustifs (rep n'importe quoi) ? ";
string rep = "_";
// procédure de lecture avec prise en charge d'un retour chariot
rep = lect_return_defaut(true,"o");
sort << "\n# ....... loi de comportement 3D hyperelastique isotrope favier3 ........";
if ((rep != "o") && (rep != "O" ) && (rep != "0") )
{ sort
<< "\n# **** exemple de cas AVEC la phase :"
<< "\n#------------------------------------------------------------------------------------"
<< "\n# K | Qor | mur | mu_inf | avec_phase(falculatif) |"
<< "\n#------------------------------------------------------------------------------------"
<< "\n 160000 150 17000 220 avec_phase"
<< "\n#-------------------------------------------------"
<< "\n# n_Q | gamma_Q | n_mu | gamma_mu |"
<< "\n#-------------------------------------------------"
<< "\n 0.25 0.4 0.25 0.4 "
<< "\n# **** exemple de cas SANS la phase :"
<< "\n#------------------------------------------------------------------------------------"
<< "\n# il est possible d'indiquer un facteur de regularisation qui permet d'eviter "
<< "\n# de potentiels problemes de NaN, de type division par 0 par exemple "
<< "\n# 1/a est remplace par 1/(a+fact_regularisation), par defaut fact_regularisation = 1.e-12 "
<< "\n# pour indiquer un facteur de regulation non nul on indique en dernier parametre "
<< "\n# le mot cle avec_regularisation_ suivi du facteur voulu "
<< "\n# ex: "
<< "\n# avec_regularisation_ 1.e-12 "
<< "\n# ce mot cle doit se situer avant le mot cle sortie_post_ "
<< "\n#------------------------------------------------------------------------------------"
<< "\n# il est possible de recuperer differentes grandeurs de travail par exemple "
<< "\n# l'intensite du potentiel, comme ces grandeurs sont calculees au moment de la resolution "
<< "\n# et ne sont pas stockees, il faut indiquer le mot cle sortie_post_ suivi de 1 (par defaut = 0) "
<< "\n# ensuite au moment de la constitution du .CVisu on aura acces aux grandeurs de travail "
<< "\n# ex: "
<< "\n# sortie_post_ 1 "
<< "\n# ce mot cle est le dernier des parametres specifiques de la loi il doit se situe "
<< "\n# a la fin de la derniere ligne de donnees "
<< "\n#"
<< "\n#------------------------------------------------------------------------------------";
};
sort << "\n#------------------------------------------------------------------------------------"
<< "\n# K | Qor | mur | mu_inf | avec_phase(falculatif) |"
<< "\n#------------------------------------------------------------------------------------"
<< "\n 160000 150 17000 220 "
<< endl;
// appel de la classe Hyper3D
Hyper3D::Info_commande_LoisDeComp_hyper3D(entreePrinc);
// appel de la classe mère
Loi_comp_abstraite::Info_commande_don_LoisDeComp(entreePrinc);
};
// test si la loi est complete
int IsoHyper3DFavier3::TestComplet()
{ int ret = LoiAbstraiteGeneral::TestComplet();
if ((K == ConstMath::trespetit) || (Qor == ConstMath::trespetit)
|| (mur == ConstMath::trespetit) || (mu_inf == ConstMath::trespetit))
{ cout << " \n Les paramètres ne sont pas défini pour la loi " << Nom_comp(id_comp)
<< '\n';
Affiche();
ret = 0;
}
if (avec_phase)
if ((nQor == ConstMath::trespetit) || (gammaQor == ConstMath::trespetit)
|| (n_mu_inf == ConstMath::trespetit) || (gamma_mu_inf == ConstMath::trespetit))
{ cout << " \n Les paramètres de la phase ne sont pas défini pour la loi " << Nom_comp(id_comp)
<< '\n';
Affiche();
ret = 0;
}
return ret;
};
//----- lecture écriture de restart -----
// cas donne le niveau de la récupération
// = 1 : on récupère tout
// = 2 : on récupère uniquement les données variables (supposées comme telles)
void IsoHyper3DFavier3::Lecture_base_info_loi(ifstream& ent,const int cas,LesReferences& lesRef
,LesCourbes1D& lesCourbe1D,LesFonctions_nD& lesFonctionsnD)
{ string toto;
if (cas == 1)
{ ent >> toto >> K >> toto >> Qor >> toto >> mur >> toto >> mu_inf >> avec_phase;
if (avec_phase)
{ ent >> toto >> nQor >> toto >> gammaQor >> toto
>> n_mu_inf >> toto >> gamma_mu_inf;
};
// gestion du post-traitement
ent >> toto >> sortie_post ;
};
// appel class mère
Loi_comp_abstraite::Lecture_don_base_info(ent,cas,lesRef,lesCourbe1D,lesFonctionsnD);
};
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void IsoHyper3DFavier3::Ecriture_base_info_loi(ofstream& sort,const int cas)
{ if (cas == 1)
{ sort << " module_dilatation " << K << " seuil " << Qor
<< " pente_origine " << mur << " pente_infini " << mu_inf << " avec_phase " << avec_phase;
if (avec_phase)
{ sort << "\n nQor= " << nQor << " gammaQor= " << gammaQor << " n_mu_inf= "
<< n_mu_inf << " gamma_mu_inf= " << gamma_mu_inf;
};
// gestion du post-traitement
sort << " sortie_post= "<< sortie_post << " ";
};
// appel de la classe mère
Loi_comp_abstraite::Ecriture_don_base_info(sort,cas);
};
// =========== METHODES Protégées dérivant de virtuelles : ==============
// METHODES internes spécifiques à l'hyperélasticité isotrope découlant de
// méthodes virtuelles de Hyper3D
// calcul du potentiel tout seul sans la phase car Qeps est nul
// ou très proche de 0
double IsoHyper3DFavier3::PoGrenoble
(const double & Qeps,const Invariant & inv)
{ // des variables intermédiaires
double a = Qor/2./mur;
double co1 = Qor*a;
double co2 = Qeps/a ;
double A = cosh(co2);
double log_A=0.;
if ((Dabs(co2) > limite_co2) || (!isfinite(A))) // en fait A est "toujours" très grand, donc c'est normal, et il vaut mieux regarder
{// si co2 est grand (par exemple > 800 uniquement !!) ou très petit, comme cosh(co2) = (exp(co2) + exp(-co2))/2, on a exp(co2) = inf
// ou exp(-co2) = inf
// mais en fait on n'utilise que le log(A) donc on peut faire une approximation
// soit co2 est grand
// on fait l'approximation que expo(-co2) est pratiquement nulle d'où cosh(co2) =(environ)= exp(co2)/2
// d'où log(A) =(environ)= co2-log(2)
log_A = MaX(0.,Dabs(co2)-log(2.));
}
else
{ log_A = log(A);};
double logV = log(inv.V);
// le potentiel et ses dérivées
double E = K/6. * (logV)*(logV)
+ co1*log_A + mu_inf * Qeps * Qeps;
// retour
return E;
};
// calcul du potentiel tout seul avec la phase donc dans le cas où Qeps est non nul
double IsoHyper3DFavier3::PoGrenoble
(const Invariant0QepsCosphi & inv_spec,const Invariant & inv)
{ // dans le cas de l'existence de la phase, on modifie Qr et muinf
double bmuinf,bQr,muinfF,Qr;
if (avec_phase)
{bmuinf = (1.+gamma_mu_inf*inv_spec.cos3phi);
bQr = (1.+gammaQor*inv_spec.cos3phi);
muinfF = mu_inf/ pow(bmuinf,n_mu_inf);
Qr = Qor/pow(bQr,nQor);
}
else
{bmuinf = 1.;
bQr = 1.;
muinfF = mu_inf;
Qr = Qor;
}
// des variables intermédiaires
double a = Qr/2./mur;
double co1 = Qr*a;
double co2 = inv_spec.Qeps/a ;
double A = cosh(co2);
double log_A=0.;
if ((Dabs(co2) > limite_co2) || (!isfinite(A))) // en fait A est "toujours" très grand, donc c'est normal, et il vaut mieux regarder s'il est // if (Dabs(A)>ConstMath::tresgrand)
{// si co2 est grand (par exemple > 800 uniquement !!) ou très petit, comme cosh(co2) = (exp(co2) + exp(-co2))/2, on a exp(co2) = inf
// ou exp(-co2) = inf
// mais en fait on n'utilise que le log(A) donc on peut faire une approximation
// soit co2 est grand
// on fait l'approximation que expo(-co2) est pratiquement nulle d'où cosh(co2) =(environ)= exp(co2)/2
// d'où log(A) =(environ)= co2-log(2)
log_A = MaX(0.,Dabs(co2)-log(2.));
}
else
{ log_A = log(A);};
double logV = log(inv.V);
// le potentiel et ses dérivées
double E = K/6. * (logV)*(logV)
+ co1*log_A + muinfF * inv_spec.Qeps * inv_spec.Qeps;
// retour
return E;
};
// calcul du potentiel tout seul sans la phase car Qeps est nul
// ou très proche de 0, et de sa variation suivant V uniquement
Hyper3D::PoGrenoble_V IsoHyper3DFavier3::PoGrenoble_et_V
(const double & Qeps,const Invariant & inv)
{ PoGrenoble_V ret;
// des variables intermédiaires
double a = Qor/2./mur;
double co1 = Qor*a;
double co2 = Qeps/a ;
double A = cosh(co2);
double log_A=0.;
if ((Dabs(co2) > limite_co2) || (!isfinite(A))) // en fait A est "toujours" très grand, donc c'est normal, et il vaut mieux regarder s'il est // if (Dabs(A)>ConstMath::tresgrand)
{// si co2 est grand (par exemple > 800 uniquement !!) ou très petit, comme cosh(co2) = (exp(co2) + exp(-co2))/2, on a exp(co2) = inf
// ou exp(-co2) = inf
// mais en fait on n'utilise que le log(A) donc on peut faire une approximation
// soit co2 est grand
// on fait l'approximation que expo(-co2) est pratiquement nulle d'où cosh(co2) =(environ)= exp(co2)/2
// d'où log(A) =(environ)= co2-log(2)
log_A = MaX(0.,Dabs(co2)-log(2.));
}
else
{ log_A = log(A);};
double logV = log(inv.V);
// le potentiel et ses dérivées
ret.E = K/6. * (logV)*(logV)
+ co1*log_A + mu_inf * Qeps * Qeps;
ret.EV = K/3.*logV/inv.V;
ret.Ks = K / 3. *(logV/2. + 1.);
// retour
return ret;
};
// calcul du potentiel et de sa variation suivant V uniquement
Hyper3D::PoGrenoble_V IsoHyper3DFavier3::PoGrenoble_et_V
(const Invariant0QepsCosphi & inv_spec,const Invariant & inv)
{ Hyper3D::PoGrenoble_V ret;
// dans le cas de l'existence de la phase, on modifie Qr et muinf
double bmuinf,bQr,muinfF,Qr;
if (avec_phase)
{bmuinf = (1.+gamma_mu_inf*inv_spec.cos3phi);
bQr = (1.+gammaQor*inv_spec.cos3phi);
muinfF = mu_inf/ pow(bmuinf,n_mu_inf);
Qr = Qor/pow(bQr,nQor);
}
else
{bmuinf = 1.;
bQr = 1.;
muinfF = mu_inf;
Qr = Qor;
}
// des variables intermédiaires
double a = Qr/2./mur;
double co1 = Qr*a;
double co2 = inv_spec.Qeps/a ;
double A = cosh(co2);
double log_A=0.;
if ((Dabs(co2) > limite_co2) || (!isfinite(A))) // en fait A est "toujours" très grand, donc c'est normal, et il vaut mieux regarder s'il est // if (Dabs(A)>ConstMath::tresgrand)
{// si co2 est grand (par exemple > 800 uniquement !!) ou très petit, comme cosh(co2) = (exp(co2) + exp(-co2))/2, on a exp(co2) = inf
// ou exp(-co2) = inf
// mais en fait on n'utilise que le log(A) donc on peut faire une approximation
// soit co2 est grand
// on fait l'approximation que expo(-co2) est pratiquement nulle d'où cosh(co2) =(environ)= exp(co2)/2
// d'où log(A) =(environ)= co2-log(2)
log_A = MaX(0.,Dabs(co2)-log(2.));
}
else
{ log_A = log(A);};
double logV = log(inv.V);
// le potentiel et ses dérivées
ret.E = K/6. * (logV)*(logV)
+ co1*log_A + muinfF * inv_spec.Qeps * inv_spec.Qeps;
ret.EV = K/3.*logV/inv.V;
ret.Ks = K / 3. *(logV/2. + 1.);
// retour
return ret;
};
// calcul du potentiel tout seul sans la phase car Qeps est nul
// ou très proche de 0, et de ses variations première et seconde suivant V uniquement
Hyper3D::PoGrenoble_VV IsoHyper3DFavier3::PoGrenoble_et_VV
(const double & Qeps,const Invariant & inv)
{ PoGrenoble_VV ret;
// des variables intermédiaires
double a = Qor/2./mur;
double co1 = Qor*a;
double co2 = Qeps/a ;
double A = cosh(co2);
double log_A=0.;
if ((Dabs(co2) > limite_co2) || (!isfinite(A))) // en fait A est "toujours" très grand, donc c'est normal, et il vaut mieux regarder s'il est // if (Dabs(A)>ConstMath::tresgrand)
{// si co2 est grand (par exemple > 800 uniquement !!) ou très petit, comme cosh(co2) = (exp(co2) + exp(-co2))/2, on a exp(co2) = inf
// ou exp(-co2) = inf
// mais en fait on n'utilise que le log(A) donc on peut faire une approximation
// soit co2 est grand
// on fait l'approximation que expo(-co2) est pratiquement nulle d'où cosh(co2) =(environ)= exp(co2)/2
// d'où log(A) =(environ)= co2-log(2)
log_A = MaX(0.,Dabs(co2)-log(2.));
}
else
{ log_A = log(A);};
double logV = log(inv.V);
// le potentiel et ses dérivées premières
ret.E = K/6. * (logV)*(logV)
+ co1*log_A + mu_inf * Qeps * Qeps;
ret.EV = K/3.*logV/inv.V;
// dérivées secondes
ret.EVV = K/3. * (1.-logV) / (inv.V * inv.V);
ret.Ks = K / 3. *(logV/2. + 1.);
// retour
return ret;
};
// calcul du potentiel et de sa variation première et seconde suivant V uniquement
Hyper3D::PoGrenoble_VV IsoHyper3DFavier3::PoGrenoble_et_VV
(const Invariant0QepsCosphi & inv_spec,const Invariant & inv)
{ Hyper3D::PoGrenoble_VV ret;
// dans le cas de l'existence de la phase, on modifie Qr et muinf
double bmuinf,bQr,muinfF,Qr;
if (avec_phase)
{bmuinf = (1.+gamma_mu_inf*inv_spec.cos3phi);
bQr = (1.+gammaQor*inv_spec.cos3phi);
muinfF = mu_inf/ pow(bmuinf,n_mu_inf);
Qr = Qor/pow(bQr,nQor);
}
else
{bmuinf = 1.;
bQr = 1.;
muinfF = mu_inf;
Qr = Qor;
}
// des variables intermédiaires
double a = Qr/2./mur;
double co1 = Qr*a;
double co2 = inv_spec.Qeps/a ;
double A = cosh(co2);
double log_A=0.;
if ((Dabs(co2) > limite_co2) || (!isfinite(A))) // en fait A est "toujours" très grand, donc c'est normal, et il vaut mieux regarder s'il est // if (Dabs(A)>ConstMath::tresgrand)
{// si co2 est grand (par exemple > 800 uniquement !!) ou très petit, comme cosh(co2) = (exp(co2) + exp(-co2))/2, on a exp(co2) = inf
// ou exp(-co2) = inf
// mais en fait on n'utilise que le log(A) donc on peut faire une approximation
// soit co2 est grand
// on fait l'approximation que expo(-co2) est pratiquement nulle d'où cosh(co2) =(environ)= exp(co2)/2
// d'où log(A) =(environ)= co2-log(2)
log_A = MaX(0.,Dabs(co2)-log(2.));
}
else
{ log_A = log(A);};
double logV = log(inv.V);
// le potentiel et ses dérivées premières
ret.E = K/6. * (logV)*(logV)
+ co1*log_A + muinfF * inv_spec.Qeps * inv_spec.Qeps;
ret.EV = K/3.*logV/inv.V;
// dérivées secondes
ret.EVV = K/3. * (1.-logV) / (inv.V * inv.V);
ret.Ks = K / 3. *(logV/2. + 1.);
// retour
return ret;
};
// calcul du potentiel et de ses dérivées non compris la phase
Hyper3D::PoGrenobleSansPhaseSansVar IsoHyper3DFavier3::PoGrenoble
(const InvariantQeps & inv_spec,const Invariant & inv)
{ PoGrenobleSansPhaseSansVar ret;
// des variables intermédiaires
double a = Qor/2./mur;
double co1 = Qor*a;
double co2 = inv_spec.Qeps/a ;
double A = cosh(co2);
double log_A=0.;
if ((Dabs(co2) > limite_co2) || (!isfinite(A))) // en fait A est "toujours" très grand, donc c'est normal, et il vaut mieux regarder s'il est // if (Dabs(A)>ConstMath::tresgrand)
{// si co2 est grand (par exemple > 800 uniquement !!) ou très petit, comme cosh(co2) = (exp(co2) + exp(-co2))/2, on a exp(co2) = inf
// ou exp(-co2) = inf
// mais en fait on n'utilise que le log(A) donc on peut faire une approximation
// soit co2 est grand
// on fait l'approximation que expo(-co2) est pratiquement nulle d'où cosh(co2) =(environ)= exp(co2)/2
// d'où log(A) =(environ)= co2-log(2)
log_A = MaX(0.,Dabs(co2)-log(2.));
}
else
{ log_A = log(A);};
double logV = log(inv.V);
// le potentiel et ses dérivées
ret.E = K/6. * (logV)*(logV)
+ co1*log_A + mu_inf * inv_spec.Qeps * inv_spec.Qeps;
ret.EV = K/3.*logV/inv.V;
// // dans le cas où l'on est très près de l'origine (voir nul)
// // il faut un traitement particulier
// if (co2 > ConstMath::unpeupetit)
// cas normal
ret.EQ = Qor * tanh(co2) + 2.* mu_inf * inv_spec.Qeps;
/* else
// cas ou Qeps est très proche de zéro, on utilise un développement
// limité
ret.EQ = (Qor/a + mu_inf)* inv_spec.Qeps
- 1./3. * Qor/(a*a*a)
* inv_spec.Qeps * inv_spec.Qeps * inv_spec.Qeps; */
ret.Ks = K / 3. *(logV/2. + 1.);
// retour
return ret;
};
// calcul du potentiel et de ses dérivées avec la phase
Hyper3D::PoGrenobleAvecPhaseSansVar IsoHyper3DFavier3::PoGrenoblePhase
(const InvariantQepsCosphi& inv_spec,const Invariant & inv)
{ PoGrenobleAvecPhaseSansVar ret;
// dans le cas de l'existence de la phase, on modifie Qr et muinf
double bmuinf,bQr,muinfF,Qr;
if (avec_phase)
{bmuinf = (1.+gamma_mu_inf*inv_spec.cos3phi);
bQr = (1.+gammaQor*inv_spec.cos3phi);
muinfF = mu_inf/ pow(bmuinf,n_mu_inf);
Qr = Qor/pow(bQr,nQor);
}
else
{bmuinf = 1.;
bQr = 1.;
muinfF = mu_inf;
Qr = Qor;
}
// des variables intermédiaires
double a = Qr/2./mur;
double co1 = Qr*a;
double co2 = inv_spec.Qeps/a ;
double A = cosh(co2);
double log_A=0.;
if ((Dabs(co2) > limite_co2) || (!isfinite(A))) // en fait A est "toujours" très grand, donc c'est normal, et il vaut mieux regarder s'il est // if (Dabs(A)>ConstMath::tresgrand)
{// si co2 est grand (par exemple > 800 uniquement !!) ou très petit, comme cosh(co2) = (exp(co2) + exp(-co2))/2, on a exp(co2) = inf
// ou exp(-co2) = inf
// mais en fait on n'utilise que le log(A) donc on peut faire une approximation
// soit co2 est grand
// on fait l'approximation que expo(-co2) est pratiquement nulle d'où cosh(co2) =(environ)= exp(co2)/2
// d'où log(A) =(environ)= co2-log(2)
log_A = MaX(0.,Dabs(co2)-log(2.));
}
else
{ log_A = log(A);};
double logV = log(inv.V);
// le potentiel et ses dérivées
ret.E = K/6. * (logV)*(logV)
+ co1*log_A + muinfF * inv_spec.Qeps * inv_spec.Qeps;
ret.EV = K/3.*logV/inv.V;
// // dans le cas où l'on est très près de l'origine (voir nul)
// // il faut un traitement particulier
// if (co2 > ConstMath::unpeupetit)
// cas normal
ret.EQ = Qr * tanh(co2) + 2.* muinfF * inv_spec.Qeps;
/* else
// cas ou Qeps est très proche de zéro, on utilise un développement
// limité
ret.EQ = (Qor/a + mu_inf)* inv_spec.Qeps
- 1./3. * Qor/(a*a*a)
* inv_spec.Qeps * inv_spec.Qeps * inv_spec.Qeps; */
// cas de la variation faisant intervenir la phase
double dEdmuinf= inv_spec.Qeps * inv_spec.Qeps;
double dmuinf_dcos3phi = (- n_mu_inf * gamma_mu_inf * muinfF/bmuinf);
double dQdcos3phi = (- nQor * gammaQor * Qr / bQr);
ret.Ecos3phi = dEdmuinf * dmuinf_dcos3phi + ret.EQ * dQdcos3phi;
ret.Ks = K / 3. *(logV/2. + 1.);
// retour
return ret;
};
// calcul du potentiel sans phase et dérivées avec ses variations par rapport aux invariants
Hyper3D::PoGrenobleSansPhaseAvecVar IsoHyper3DFavier3::PoGrenoble_et_var
(const Invariant2Qeps& inv_spec,const Invariant & inv)
{ PoGrenobleSansPhaseAvecVar ret;
// des variables intermédiaires
double a = Qor/2./mur;
double co1 = Qor*a;
double co2 = inv_spec.Qeps/a ;
double A = cosh(co2);
double log_A=0.;
double tanhco2 = 1.; // init par défaut
if ((Abs(co2) > limite_co2) || (!isfinite(A))) // en fait A est "toujours" très grand, donc c'est normal, et il vaut mieux regarder s'il est // if (Dabs(A)>ConstMath::tresgrand)
{// si co2 est grand (par exemple > 800 uniquement !!) ou très petit, comme cosh(co2) = (exp(co2) + exp(-co2))/2, on a exp(co2) = inf
// ou exp(-co2) = inf
// mais en fait on n'utilise que le log(A) donc on peut faire une approximation
// soit co2 est grand
// on fait l'approximation que expo(-co2) est pratiquement nulle d'où cosh(co2) =(environ)= exp(co2)/2
// d'où log(A) =(environ)= co2-log(2)
log_A = MaX(0.,Dabs(co2)-log(2.));
tanhco2 = 1.; // et dans ce cas on est à la limite : th(A) =(environ)= exp(co2)/exp(co2) = 1
}
else
{ log_A = log(A);
tanhco2 = tanh(co2);
};
double logV = log(inv.V);
// le potentiel et ses dérivées premières
ret.E = K/6. * (logV)*(logV)
+ co1*log_A + mu_inf * inv_spec.Qeps * inv_spec.Qeps;
ret.EV = K/3.*logV/inv.V;
// dérivées secondes
ret.EVV = K/3. * (1.-logV) / (inv.V * inv.V);
ret.EQV = 0.;
// dans le cas où l'on est très près de l'origine (voir nul)
// il faut un traitement particulier
// if (co2 > ConstMath::unpeupetit)
// cas normal
{ ret.EQ = Qor * tanhco2 + 2.* mu_inf * inv_spec.Qeps;
// dérivée seconde
ret.EQQ = 2.*mur*(1. - tanhco2 * tanhco2) + 2.* mu_inf;
}
/* else
// cas ou Qeps est très proche de zéro, on utilise un développement
// limité
{ ret.EQ = (Qor/a + mu_inf)* inv_spec.Qeps
- 1./3. * Qor/(a*a*a)
* inv_spec.Qeps * inv_spec.Qeps * inv_spec.Qeps;
// dérivée seconde
ret.EQQ = (Qor/a + mu_inf)
- Qor/(a*a*a)
* inv_spec.Qeps * inv_spec.Qeps * inv_spec.Qeps;
}*/
// vérif des dérivées du potentiels par rapport aux invariants, ceci par différences finies
// --- Verif_PoGrenoble_et_var(inv_spec.Qeps,inv,ret );
//--- débug: autre vérification à décommenter si on veut vérifier un nan événtuel !! --------------------
// if ((Dabs(ret.E) > ConstMath::tresgrand) || (Dabs(ret.EV) > ConstMath::tresgrand)
// || (Dabs(ret.EVV) > ConstMath::tresgrand) || (Dabs(ret.EQV) > ConstMath::tresgrand)
// || (Dabs(ret.EQQ) > ConstMath::tresgrand) || (Dabs(ret.EQ) > ConstMath::tresgrand) )
// { cout << "\n attention *** on a detecter un comportement bizarre sur le potentiel de la loi Favier3D "
// << " potentiel= " << ret.E << " var/V= " << ret.EV << " var/Q= " << ret.EQ
// << " var/VV= " << ret.EVV << " var/QQ= " << ret.EQQ << " var/QV= " << ret.EQV << endl;
// };
//---- fin débug -----------------------------------------------------------------------------------------
ret.Ks = K / 3. *(logV/2. + 1.);
// retour
return ret;
};
// calcul du potentiel avec phase et dérivées avec ses variations par rapport aux invariants
Hyper3D::PoGrenobleAvecPhaseAvecVar IsoHyper3DFavier3::PoGrenoblePhase_et_var
(const Invariant2QepsCosphi& inv_spec,const Invariant & inv)
{ Hyper3D::PoGrenobleAvecPhaseAvecVar ret;
// dans le cas de l'existence de la phase, on modifie Qr et muinf
double bmuinf,bQr,muinfF,Qr;
if (avec_phase)
{bmuinf = (1.+gamma_mu_inf*inv_spec.cos3phi);
bQr = (1.+gammaQor*inv_spec.cos3phi);
muinfF = mu_inf/ pow(bmuinf,n_mu_inf);
Qr = Qor/pow(bQr,nQor);
}
else
{bmuinf = 1.;
bQr = 1.;
muinfF = mu_inf;
Qr = Qor;
}
//debug
//cout << "\n debug: IsoHyper3DFavier3::PoGrenoblePhase_et_var "
// << " Qr="<<Qr << " Qor=" << Qor << " muinfF="<<muinfF <<" mu_inf="<<mu_inf<<endl;
//fin debug
// des variables intermédiaires
double a = Qr/2./mur;
double co1 = Qr*a;
double co2 = inv_spec.Qeps/a ;
double A = cosh(co2);
double log_A=0.;
double tanhco2 = 1.; // init par défaut
if ((Dabs(co2) > limite_co2) || (!isfinite(A))) // en fait A est "toujours" très grand, donc c'est normal, et il vaut mieux regarder s'il est infini
// if ((Dabs(A)>ConstMath::pasmalgrand)||(!isfinite(A)))
// if (Dabs(A)>ConstMath::tresgrand)
{// si co2 est grand (par exemple > 800 uniquement !!) ou très petit, comme cosh(co2) = (exp(co2) + exp(-co2))/2, on a exp(co2) = inf
// ou exp(-co2) = inf
// mais en fait on n'utilise que le log(A) donc on peut faire une approximation
// soit co2 est grand
// on fait l'approximation que expo(-co2) est pratiquement nulle d'où cosh(co2) =(environ)= exp(co2)/2
// d'où log(A) =(environ)= co2-log(2)
log_A = MaX(0.,Dabs(co2)-log(2.));
tanhco2 = 1.; // et dans ce cas on est à la limite : th(A) =(environ)= exp(co2)/exp(co2) = 1
}
else
{ log_A = log(A);
tanhco2 = tanh(co2);
};
//debug
//cout << "\n debug: 3DFavier3::Po..ePhase_et_var "
// << " A="<< A << " co2="<< co2<< " log_A="<<log_A << " log(A)=" << log(A) << " tanhco2="<<tanhco2 <<" tanh(co2)="<<tanh(co2) <<endl;
//fin debug
double logV = log(inv.V);
double logCosh = log_A;
double unsurmur=1./mur;
// le potentiel et ses dérivées premières
ret.E = K/6. * (logV)*(logV)
+ co1*logCosh + muinfF * inv_spec.Qeps * inv_spec.Qeps;
ret.EV = K/3.*logV/inv.V;
// dérivées secondes
ret.EVV = K/3. * (1.-logV) / (inv.V * inv.V);
ret.EQV = 0.;
// dans le cas où l'on est très près de l'origine (voir nul)
// il faut un traitement particulier
// if (co2 > ConstMath::unpeupetit)
// cas normal
{ ret.EQ = Qr * tanhco2 + 2.* muinfF * inv_spec.Qeps;
// dérivée seconde
ret.EQQ = 2.*mur*(1. - tanhco2 * tanhco2) + 2.* muinfF;
}
/* else
// cas ou Qeps est très proche de zéro, on utilise un développement
// limité
{ ret.EQ = (Qr/a + muinfF)* inv_spec.Qeps
- 1./3. * Qr/(a*a*a)
* inv_spec.Qeps * inv_spec.Qeps * inv_spec.Qeps;
// dérivée seconde
ret.EQQ = (Qr/a + muinfF)
- Qr/(a*a*a)
* inv_spec.Qeps * inv_spec.Qeps * inv_spec.Qeps;
}*/
// cas de la variation première par rapport à la phase
double dEdQr= Qr*unsurmur * logCosh - inv_spec.Qeps * tanhco2;
double QepsSurQr = inv_spec.Qeps/Qr;
double tanhco2_2=tanhco2*tanhco2;
double dEdmuinf= inv_spec.Qeps * inv_spec.Qeps;
double dmuinf_dcos3phi = (- n_mu_inf * gamma_mu_inf * muinfF/bmuinf);
double dQdcos3phi = (- nQor * gammaQor * Qr / bQr);
ret.Ecos3phi = dEdmuinf * dmuinf_dcos3phi + dEdQr * dQdcos3phi;
// cas des variations seconde faisant intervenir la phase la phase
double d2EdQr2=unsurmur*logCosh-2.* QepsSurQr * tanhco2 + co2*QepsSurQr*(1.-tanhco2_2);
double d2muinf_dcos3phi_2 = n_mu_inf*(1.+n_mu_inf)* muinfF*gamma_mu_inf*gamma_mu_inf/bmuinf/bmuinf;
double d2Qr_dcos3phi_2 = nQor*(1.+nQor)*Qr*gammaQor*gammaQor/bQr/bQr;
double d2E_dQ_dmuinf = 2. * inv_spec.Qeps ;
double d2E_dQ_dQr = tanhco2 - co2 * (1.-tanhco2_2);
ret.EVcos3phi= 0.;
ret.EQcos3phi= d2E_dQ_dmuinf * dmuinf_dcos3phi + d2E_dQ_dQr * dQdcos3phi;
ret.Ecos3phi2= d2EdQr2 * ret.Ecos3phi * ret.Ecos3phi + dEdmuinf * d2muinf_dcos3phi_2
+ dEdQr * d2Qr_dcos3phi_2;
/* ret.EVcos3phi= 0.;
ret.EQcos3phi= 0.;
ret.Ecos3phi2= 0.;
ret.Ecos3phi = 0.;*/
// vérif des dérivées du potentiels par rapport aux invariants, ceci par différences finies
// --- Verif_PoGrenoble_et_var(inv_spec.Qeps,inv,inv_spec.cos3phi,ret );
// --- Invariant2Qeps toto(inv_spec.Qeps,inv_spec.dQepsdbIIb,inv_spec.dQepsdbIIb2);
// --- Hyper3D::PoGrenobleSansPhaseAvecVar truc = PoGrenoble_et_var(toto,inv);
ret.Ks = K / 3. *(logV/2. + 1.);
// retour
return ret;
};
///=============== 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 IsoHyper3DFavier3::Verif_PoGrenoble_et_var
(const double & Qeps,const Invariant & inv
,const PoGrenobleSansPhaseAvecVar& potret )
{ // dans le cas du premier passage on indique qu'il y a vérification
if (indic_Verif_PoGrenoble_et_var == 0)
{ cout << "\n ****vérification des dérivées du potentiels par rapport aux invariants****";
cout << "\n IsoHyper3DFavier3::Verif_PoGrenoble_et_var \n";
}
indic_Verif_PoGrenoble_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 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 = ConstMath::unpeupetit;
double Qeps_et_dQeps = Qeps+delta;
double E_et_dQeps = PoGrenoble(Qeps_et_dQeps,inv_n0);
double Qeps_et_dQeps2 = Qeps + 2.*delta;
double E_et_dQeps2 = PoGrenoble(Qeps_et_dQeps2,inv_n0);
Invariant inv_et_dV = inv_n0;inv_et_dV.V += delta;
double E_et_dV = PoGrenoble(Qeps,inv_et_dV);
Invariant inv_et_dV2 = inv_n0;inv_et_dV2.V += 2. * delta;
double E_et_dV2 = PoGrenoble(Qeps,inv_et_dV2);
Invariant inv_et_dVdQeps = inv_n0;
inv_et_dVdQeps.V += delta;
double Qeps_et_dVdQeps = Qeps+delta;
double E_et_dVdQeps = PoGrenoble(Qeps_et_dVdQeps,inv_et_dVdQeps);
// calcul des dérivées premières
double E_V = (E_et_dV - E_n)/delta;
double E_Qeps = (E_et_dQeps - E_n)/delta;
// calcul des dérivées secondes
double E_V2 = (E_et_dV2 - 2.*E_et_dV + E_n ) /(delta * delta);
double E_Qeps2 = (E_et_dQeps2 - 2.*E_et_dQeps + E_n)/(delta * delta);
double E_V_a_dQeps = (E_et_dVdQeps - E_et_dQeps )/delta;
double E_VQeps = ( E_V_a_dQeps - E_V)/delta;
// comparaison avec les valeurs de dérivées analytiques
bool erreur = false;
if (diffpourcent(potret.EV,E_V,MaX(Dabs(E_V),Dabs(potret.EV)),0.05))
{if (MiN(Dabs(E_V),Dabs(potret.EV)) == 0.)
{if ( MaX(Dabs(E_V),Dabs(potret.EV)) > 50.*delta) erreur = true;}
else
erreur = true;}
if (diffpourcent(potret.EQ,E_Qeps,MaX(Dabs(E_Qeps),Dabs(potret.EQ)),0.05))
{if (MiN(Dabs(E_Qeps),Dabs(potret.EQ)) == 0.)
{if ( MaX(Dabs(E_Qeps),Dabs(potret.EQ)) > 50.*delta) erreur = true;}
else
erreur = true;}
if (diffpourcent(potret.EQQ,E_Qeps2,MaX(Dabs(E_Qeps2),Dabs(potret.EQQ)),0.05))
{if (MiN(Dabs(E_Qeps2),Dabs(potret.EQQ)) == 0.)
{if ( MaX(Dabs(E_Qeps2),Dabs(potret.EQQ)) > 50.*delta) erreur = true;}
else
erreur = true;}
if (diffpourcent(potret.EVV,E_V2,MaX(Dabs(E_V2),Dabs(potret.EVV)),0.05))
{if (MiN(Dabs(E_V2),Dabs(potret.EVV)) == 0.)
{if ( MaX(Dabs(E_V2),Dabs(potret.EVV)) > 50.*delta) erreur = true;}
else
erreur = true;}
if (diffpourcent(potret.EQV,E_VQeps,MaX(Dabs(E_VQeps),Dabs(potret.EQV)),0.05))
{if (MiN(Dabs(E_VQeps),Dabs(potret.EQV)) == 0.)
{if (Dabs(potret.EQV) == 0.)
// si la valeur de la dérivée numérique est nulle cela signifie peut-être
// que l'on est à un extréma, la seule chose que le l'on peut faire est de
// vérifier que l'on tend numériquement vers cette extréma ici un minima
{
Invariant inv_et_ddVddQeps = inv_n0;
inv_et_ddVddQeps.V += delta/10.;
double Qeps_et_ddVddQeps = Qeps+delta/10.;
double E_et_ddVddQeps = PoGrenoble(Qeps_et_ddVddQeps,inv_et_ddVddQeps);
double Qeps_et_ddQeps = Qeps+delta/10.;
double E_et_ddQeps = PoGrenoble(Qeps_et_ddQeps,inv_n0);
double E_V_a_ddQeps = (E_et_ddVddQeps - E_et_ddQeps )/(delta*10.);
if (10.* Dabs(E_V_a_ddQeps) > Dabs(E_V_a_dQeps)) erreur = true;
}
else
if ( MaX(Dabs(E_VQeps),Dabs(potret.EQV)) > 150.*delta) erreur = true;
}
else
erreur = true;
}
if (erreur)
{ cout << "\n erreur dans le calcul analytique des derivees du potentiel";
cout << "\n IsoHyper3DFavier3::Verif_PoGrenoble_et_var(.."
<< " , numero d'increment = " << indic_Verif_PoGrenoble_et_var;
Sortie(1);
}
};
// vérif des dérivées du potentiels par rapport aux invariants, ceci par différences finies
void IsoHyper3DFavier3::Verif_PoGrenoble_et_var
(const double & Qeps,const Invariant & inv,const double& cos3phi
,const PoGrenobleAvecPhaseAvecVar& potret )
{ // dans le cas du premier passage on indique qu'il y a vérification
if (indic_Verif_PoGrenoble_et_var == 0)
{ cout << "\n ****vérification des dérivées du potentiels par rapport aux invariants****";
cout << "\n IsoHyper3DFavier3::Verif_PoGrenoble_et_var \n";
}
indic_Verif_PoGrenoble_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 invcos3phi(Qeps,cos3phi);
double E_n = PoGrenoble(invcos3phi,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 = 10.*ConstMath::unpeupetit;
double Qeps_et_dQeps = Qeps+delta;
Invariant0QepsCosphi invcos3phi1(Qeps_et_dQeps,cos3phi);
double E_et_dQeps = PoGrenoble(invcos3phi1,inv_n0);
double Qeps_moins_dQeps = Qeps - delta;
Invariant0QepsCosphi invcos3phi2(Qeps_moins_dQeps,cos3phi);
double E_moins_dQeps = PoGrenoble(invcos3phi2,inv_n0);
Invariant inv_et_dV = inv_n0;inv_et_dV.V += delta;
double E_et_dV = PoGrenoble(invcos3phi,inv_et_dV);
Invariant inv_moins_dV = inv_n0;inv_moins_dV.V -= delta;
double E_moins_dV = PoGrenoble(invcos3phi,inv_moins_dV);
Invariant inv_et_dVdQeps = inv_n0;
inv_et_dVdQeps.V += delta;
double Qeps_et_dVdQeps = Qeps+delta;
Invariant0QepsCosphi invcos3phi3(Qeps_et_dVdQeps,cos3phi);
double E_et_dVdQeps = PoGrenoble(invcos3phi3,inv_et_dVdQeps);
// cas des variations avec cos3phi
double cos3phi_et_dcos3phi = cos3phi+delta;
Invariant0QepsCosphi invcos3phi_et_dcos3phi(Qeps,cos3phi_et_dcos3phi);
double E_et_dcos3phi = PoGrenoble(invcos3phi_et_dcos3phi,inv_n0);
double cos3phi_moins_dcos3phi = cos3phi-delta;
Invariant0QepsCosphi invcos3phi_moins_dcos3phi(Qeps,cos3phi_moins_dcos3phi);
double E_moins_dcos3phi = PoGrenoble(invcos3phi_moins_dcos3phi,inv_n0);
Invariant0QepsCosphi invcos3phi_et_dcos3phi_a_dQeps(Qeps_et_dQeps,cos3phi_et_dcos3phi);
double E_et_dcos3phi_a_dQeps = PoGrenoble(invcos3phi_et_dcos3phi_a_dQeps,inv_n0);
double E_et_dcos3phi_a_dV = PoGrenoble(invcos3phi_et_dcos3phi,inv_et_dV);
// calcul des dérivées premières
double E_V = (E_et_dV - E_n)/delta;
double E_Qeps = (E_et_dQeps - E_n)/delta;
double E_cos3phi = (E_et_dcos3phi -E_n)/delta;
// calcul des dérivées secondes
double E_V2 = (E_et_dV - 2.*E_n + E_moins_dV ) /(delta * delta);
double E_Qeps2 = (E_et_dQeps - 2.*E_n + E_moins_dQeps)/(delta * delta);
double E_V_a_dQeps = (E_et_dVdQeps - E_et_dQeps )/delta;
double E_VQeps = ( E_V_a_dQeps - E_V)/delta;
double E_cos3phi_2 = (E_et_dcos3phi - 2.*E_n + E_moins_dcos3phi ) /(delta * delta);
double E_dQeps_a_dcos3phi = (E_et_dcos3phi_a_dQeps - E_et_dcos3phi )/delta;
double E_dcos3phi_dQeps = (E_dQeps_a_dcos3phi - E_Qeps )/delta;
double E_dV_a_dcos3phi = (E_et_dcos3phi_a_dV - E_et_dcos3phi )/delta;
double E_dcos3phi_dV = (E_dV_a_dcos3phi - E_V )/delta;
// dans les dérivées secondes par rapport à cos3phi on a des erreurs, sans doute à cause des petites valeurs ??
// comparaison avec les valeurs de dérivées analytiques
int erreur = 0;
if (diffpourcent(potret.EV,E_V,MaX(Dabs(E_V),Dabs(potret.EV)),0.05))
{if (MiN(Dabs(E_V),Dabs(potret.EV)) == 0.)
{if ( MaX(Dabs(E_V),Dabs(potret.EV)) > 50.*delta) erreur = 1;}
else
erreur = 2; }
if (diffpourcent(potret.EQ,E_Qeps,MaX(Dabs(E_Qeps),Dabs(potret.EQ)),0.05))
{if (MiN(Dabs(E_Qeps),Dabs(potret.EQ)) == 0.)
{if ( MaX(Dabs(E_Qeps),Dabs(potret.EQ)) > 50.*delta) erreur = 3;}
else
erreur = 4;}
if (diffpourcent(potret.Ecos3phi,E_cos3phi,MaX(Dabs(E_cos3phi),Dabs(potret.Ecos3phi)),0.05))
{if (MiN(Dabs(E_cos3phi),Dabs(potret.Ecos3phi)) == 0.)
{if ( MaX(Dabs(E_cos3phi),Dabs(potret.Ecos3phi)) > 50.*delta) erreur = 31;}
else
erreur = 41;}
if (diffpourcent(potret.EQQ,E_Qeps2,MaX(Dabs(E_Qeps2),Dabs(potret.EQQ)),0.05))
{if (MiN(Dabs(E_Qeps2),Dabs(potret.EQQ)) == 0.)
{if ( MaX(Dabs(E_Qeps2),Dabs(potret.EQQ)) > 50.*delta) erreur = 5;}
else
erreur = 6;}
if (diffpourcent(potret.EVV,E_V2,MaX(Dabs(E_V2),Dabs(potret.EVV)),0.05))
{if (MiN(Dabs(E_V2),Dabs(potret.EVV)) == 0.)
{if ( MaX(Dabs(E_V2),Dabs(potret.EVV)) > 50.*delta) erreur = 7;}
else
erreur = 8;}
if (diffpourcent(potret.Ecos3phi2,E_cos3phi_2,MaX(Dabs(E_cos3phi_2),Dabs(potret.Ecos3phi2)),0.05))
{if (MiN(Dabs(E_cos3phi_2),Dabs(potret.Ecos3phi2)) == 0.)
{if ( MaX(Dabs(E_cos3phi_2),Dabs(potret.Ecos3phi2)) > 50.*delta) erreur = 71;}
else
erreur = 81;}
if (diffpourcent(potret.EQV,E_VQeps,MaX(Dabs(E_VQeps),Dabs(potret.EQV)),0.05))
{if (MiN(Dabs(E_VQeps),Dabs(potret.EQV)) == 0.)
{if (Dabs(potret.EQV) == 0.)
// si la valeur de la dérivée numérique est nulle cela signifie peut-être
// que l'on est à un extréma, la seule chose que le l'on peut faire est de
// vérifier que l'on tend numériquement vers cette extréma ici un minima
{
Invariant inv_et_ddVddQeps = inv_n0;
inv_et_ddVddQeps.V += delta/10.;
double Qeps_et_ddVddQeps = Qeps+delta/10.;
double E_et_ddVddQeps = PoGrenoble(Qeps_et_ddVddQeps,inv_et_ddVddQeps);
double Qeps_et_ddQeps = Qeps+delta/10.;
double E_et_ddQeps = PoGrenoble(Qeps_et_ddQeps,inv_n0);
double E_V_a_ddQeps = (E_et_ddVddQeps - E_et_ddQeps )/(delta*10.);
if (10.* Dabs(E_V_a_ddQeps) > Dabs(E_V_a_dQeps)) erreur = 9;
}
else
if ( MaX(Dabs(E_VQeps),Dabs(potret.EQV)) > 150.*delta) erreur = 10;
}
else
erreur = 11;
}
if (diffpourcent(potret.EVcos3phi,E_dcos3phi_dV,MaX(Dabs(E_dcos3phi_dV),Dabs(potret.EVcos3phi)),0.05))
{if (MiN(Dabs(E_dcos3phi_dV),Dabs(potret.EVcos3phi)) == 0.)
{if (Dabs(potret.EVcos3phi) == 0.)
// si la valeur de la dérivée numérique est nulle cela signifie peut-être
// que l'on est à un extréma, la seule chose que le l'on peut faire est de
// vérifier que l'on tend numériquement vers cette extréma ici un minima
{
/*Invariant inv_et_ddVddQeps = inv_n0;
inv_et_ddVddQeps.V += delta/10.;
double Qeps_et_ddVddQeps = Qeps+delta/10.;
double E_et_ddVddQeps = PoGrenoble(Qeps_et_ddVddQeps,inv_et_ddVddQeps);
double Qeps_et_ddQeps = Qeps+delta/10.;
double E_et_ddQeps = PoGrenoble(Qeps_et_ddQeps,inv_n0);
double E_V_a_ddQeps = (E_et_ddVddQeps - E_et_ddQeps )/(delta*10.);
if (10.* Dabs(E_V_a_ddQeps) > Dabs(E_V_a_dQeps))*/ erreur = 91;
}
else
if ( MaX(Dabs(E_dcos3phi_dV),Dabs(potret.EVcos3phi)) > 150.*delta) erreur = 101;
}
else
erreur = 111;
}
if (diffpourcent(potret.EQcos3phi,E_dcos3phi_dQeps,MaX(Dabs(E_dcos3phi_dQeps),Dabs(potret.EQcos3phi)),0.05))
{if (MiN(Dabs(E_dcos3phi_dQeps),Dabs(potret.EQcos3phi)) == 0.)
{if (Dabs(potret.EQcos3phi) == 0.)
// si la valeur de la dérivée numérique est nulle cela signifie peut-être
// que l'on est à un extréma, la seule chose que le l'on peut faire est de
// vérifier que l'on tend numériquement vers cette extréma ici un minima
{
/*Invariant inv_et_ddVddQeps = inv_n0;
inv_et_ddVddQeps.V += delta/10.;
double Qeps_et_ddVddQeps = Qeps+delta/10.;
double E_et_ddVddQeps = PoGrenoble(Qeps_et_ddVddQeps,inv_et_ddVddQeps);
double Qeps_et_ddQeps = Qeps+delta/10.;
double E_et_ddQeps = PoGrenoble(Qeps_et_ddQeps,inv_n0);
double E_V_a_ddQeps = (E_et_ddVddQeps - E_et_ddQeps )/(delta*10.);
if (10.* Dabs(E_V_a_ddQeps) > Dabs(E_V_a_dQeps))*/ erreur = 92;
}
else
if ( MaX(Dabs(E_dcos3phi_dQeps),Dabs(potret.EQcos3phi)) > 150.*delta) erreur = 102;
}
else
erreur = 112;
}
if (erreur > 0)
{ cout << "\n erreur dans le calcul analytique des derivees du potentiel";
cout << "\n IsoHyper3DFavier3::Verif_PoGrenoble_et_var(.."
<< " , numero d'increment = " << indic_Verif_PoGrenoble_et_var
<< " , numero d'erreur : " << erreur ;
// Sortie(1);
}
};