1032 lines
46 KiB
C++
1032 lines
46 KiB
C++
|
|
|
|
// This file is part of the Herezh++ application.
|
|
//
|
|
// The finite element software Herezh++ is dedicated to the field
|
|
// of mechanics for large transformations of solid structures.
|
|
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
|
|
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
|
|
//
|
|
// Herezh++ is distributed under GPL 3 license ou ultérieure.
|
|
//
|
|
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
|
|
// AUTHOR : Gérard Rio
|
|
// E-MAIL : gerardrio56@free.fr
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License,
|
|
// or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
// See the GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
//
|
|
// For more information, please consult: <https://herezh.irdl.fr/>.
|
|
|
|
#include "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);
|
|
}
|
|
};
|