Herezh_dev/comportement/Hyper_elastique/IsoHyper3DFavier3.cc
2023-05-03 17:23:49 +02:00

2199 lines
95 KiB
C++

// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.
#include "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"
#include "Enum_TypeQuelconque.h"
#include "TypeQuelconqueParticulier.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 ================
//================== stockage particulier SaveResul ================
IsoHyper3DFavier3::SaveResulIsoHyper3DFavier3::SaveResulIsoHyper3DFavier3(bool avec_para): // constructeur par défaut :
SaveResulHyperD(),para_loi(NULL),para_loi_t(NULL)
{if (avec_para)
{para_loi = new Vecteur(4,-ConstMath::trespetit);
para_loi_t = new Vecteur(4,-ConstMath::trespetit);
};
};
IsoHyper3DFavier3::SaveResulIsoHyper3DFavier3::SaveResulIsoHyper3DFavier3(const SaveResulIsoHyper3DFavier3& sav): // de copie
SaveResulHyperD(sav),para_loi(NULL),para_loi_t(NULL)
{if (sav.para_loi != NULL)
{para_loi = new Vecteur(*sav.para_loi);
para_loi_t = new Vecteur(*sav.para_loi_t);
};
};
IsoHyper3DFavier3::SaveResulIsoHyper3DFavier3::~SaveResulIsoHyper3DFavier3() // destructeur
{ if (para_loi != NULL) delete para_loi;
if (para_loi_t != NULL) delete para_loi_t;
};
// affectation
Loi_comp_abstraite::SaveResul & IsoHyper3DFavier3::SaveResulIsoHyper3DFavier3
::operator = ( const Loi_comp_abstraite::SaveResul & a)
{ SaveResulHyperD::operator=(a);
SaveResulIsoHyper3DFavier3& sav = *((SaveResulIsoHyper3DFavier3*) &a);
if (sav.para_loi != NULL)
{if (para_loi == NULL)
{para_loi = new Vecteur(4,-ConstMath::trespetit);
para_loi_t = new Vecteur(4,-ConstMath::trespetit);
};
*para_loi = *(sav.para_loi);
*para_loi_t = *(sav.para_loi_t);
};
map_type_quelconque = sav.map_type_quelconque;
return *this;
};
//============= lecture écriture dans base info ==========
// 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::SaveResulIsoHyper3DFavier3::Lecture_base_info (ifstream& ent,const int cas)
{SaveResulHyperD::Lecture_base_info (ent,cas);
string toto;
ent >> toto;
if (toto == "sans_para")
{if (para_loi != NULL)
{delete para_loi;para_loi=NULL;
delete para_loi_t;para_loi_t=NULL;
};
}
else
{if (para_loi == NULL)
{para_loi = new Vecteur(4);
para_loi_t = new Vecteur(4);
};
ent >> *para_loi;
*para_loi_t=*para_loi;
};
};
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void IsoHyper3DFavier3::SaveResulIsoHyper3DFavier3::Ecriture_base_info(ofstream& sort,const int cas)
{SaveResulHyperD::Ecriture_base_info (sort,cas);
if (para_loi == NULL)
{sort << " sans_para ";}
else
{sort << " avec_para ";
sort << *para_loi;
};
};
// mise à jour des informations transitoires
void IsoHyper3DFavier3::SaveResulIsoHyper3DFavier3::TdtversT()
{SaveResulHyperD::TdtversT();
if (para_loi != NULL)
{*para_loi_t = *para_loi;};
// mise à jour de la liste des grandeurs quelconques internes
Mise_a_jour_map_type_quelconque();
};
void IsoHyper3DFavier3::SaveResulIsoHyper3DFavier3::TversTdt()
{SaveResulHyperD::TversTdt();
if (para_loi != NULL)
{*para_loi = *para_loi_t;};
// mise à jour de la liste des grandeurs quelconques internes
Mise_a_jour_map_type_quelconque();
};
// affichage à l'écran des infos
void IsoHyper3DFavier3::SaveResulIsoHyper3DFavier3::Affiche() const
{SaveResulHyperD::Affiche();
if (para_loi == NULL)
{cout << " sans_para ";}
else
{cout << " avec_para ";
cout << *para_loi;
};
};
//================== fin stockage particulier SaveResul ================
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)
// dépendance nD éventuelle
,K_nD(NULL),Qor_nD(NULL),mur_nD(NULL),mu_inf_nD(NULL)
{};
// 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)
// dépendance nD éventuelle
,K_nD(loi.K_nD),Qor_nD(loi.Qor_nD),mur_nD(loi.mur_nD),mu_inf_nD(loi.mu_inf_nD)
{// on regarde s'il s'agit d'une fonction locale ou d'une fonction globale
if (K_nD != NULL) // 1)
if (K_nD->NomFonction() == "_")
{// comme il s'agit d'une fonction locale on la redéfinie (sinon pb lors du destructeur de loi)
string non_courbe("_");
K_nD = Fonction_nD::New_Fonction_nD(*loi.K_nD);
};
if (Qor_nD != NULL) // 2)
if (Qor_nD->NomFonction() == "_")
{// comme il s'agit d'une fonction locale on la redéfinie (sinon pb lors du destructeur de loi)
string non_courbe("_");
Qor_nD = Fonction_nD::New_Fonction_nD(*loi.Qor_nD);
};
if (mur_nD != NULL) // 3)
if (mur_nD->NomFonction() == "_")
{// comme il s'agit d'une fonction locale on la redéfinie (sinon pb lors du destructeur de loi)
string non_courbe("_");
mur_nD = Fonction_nD::New_Fonction_nD(*loi.mur_nD);
};
if (mu_inf_nD != NULL) // 4)
if (mu_inf_nD->NomFonction() == "_")
{// comme il s'agit d'une fonction locale on la redéfinie (sinon pb lors du destructeur de loi)
string non_courbe("_");
mu_inf_nD = Fonction_nD::New_Fonction_nD(*loi.mu_inf_nD);
};
// --- on remplit avec les grandeurs succeptible d'être utilisées
// // acces à listdeTouslesQuelc_dispo_localement
// list <EnumTypeQuelconque >& list_tousQuelc = ListdeTouslesQuelc_dispo_localement();
// list_tousQuelc.push_back(E_YOUNG);
// list_tousQuelc.push_back(NU_YOUNG);
// // on supprime les doublons localement
// list_tousQuelc.sort(); // on ordonne la liste
// list_tousQuelc.unique(); // suppression des doublons
};
// Lecture des donnees de la classe sur fichier
void IsoHyper3DFavier3::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCourbes1D&
,LesFonctions_nD& lesFonctionsnD)
{ // --- lecture des quatres coefficients de la loi
string nom_class_methode("IsoHyper3DFavier3::LectureDonneesParticulieres");
// on regarde si K dépend d'une fonction nD
if(strstr(entreePrinc->tablcar,"K_fonction_nD:")!=0)
{ string nom;
string mot_cle2="K_fonction_nD:";
// on lit le nom de la fonction
string nom_fonct;
bool lec = entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle2,nom_fonct);
if (!lec )
{ entreePrinc->MessageBuffer("**erreur01 en lecture** "+mot_cle2);
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// maintenant on définit la fonction
if (lesFonctionsnD.Existe(nom_fonct))
{K_nD = lesFonctionsnD.Trouve(nom_fonct);
}
else
{// sinon il faut la lire maintenant
string non("_");
K_nD = Fonction_nD::New_Fonction_nD(non, Id_Nom_Fonction_nD(nom_fonct));
// lecture de la courbe
K_nD->LectDonnParticulieres_Fonction_nD (non,entreePrinc);
// maintenant on vérifie que la fonction est utilisable
if (K_nD->NbComposante() != 1 )
{ cout << "\n erreur en lecture, la fonction " << nom_fonct
<< " est une fonction vectorielle a " << K_nD->NbComposante()
<< " composante alors qu'elle devrait etre scalaire ! "
<< " elle n'est donc pas utilisable !! ";
string message("\n**erreur02** \n"+nom_class_methode+"(...");
entreePrinc->MessageBuffer(message);
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
};
// on regarde si la fonction nD intègre la température
const Tableau <Ddl_enum_etendu>& tab_enu = K_nD->Tab_enu_etendu();
if (tab_enu.Contient(TEMP))
thermo_dependant=true;
}
// sinon si le module K n'a pas été lue, on le récupère en version scalaire
else
{ // lecture du module
*(entreePrinc->entree) >> K ;
};
// idem si Qor dépend d'une fonction nD
if(strstr(entreePrinc->tablcar,"Qor_fonction_nD:")!=0)
{ string nom;
string mot_cle2="Qor_fonction_nD:";
// on lit le nom de la fonction
string nom_fonct;
bool lec = entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle2,nom_fonct);
if (!lec )
{ entreePrinc->MessageBuffer("**erreur03 en lecture** "+mot_cle2);
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// maintenant on définit la fonction
if (lesFonctionsnD.Existe(nom_fonct))
{Qor_nD = lesFonctionsnD.Trouve(nom_fonct);
}
else
{// sinon il faut la lire maintenant
string non("_");
Qor_nD = Fonction_nD::New_Fonction_nD(non, Id_Nom_Fonction_nD(nom_fonct));
// lecture de la courbe
Qor_nD->LectDonnParticulieres_Fonction_nD (non,entreePrinc);
// maintenant on vérifie que la fonction est utilisable
if (Qor_nD->NbComposante() != 1 )
{ cout << "\n erreur en lecture, la fonction " << nom_fonct
<< " est une fonction vectorielle a " << Qor_nD->NbComposante()
<< " composante alors qu'elle devrait etre scalaire ! "
<< " elle n'est donc pas utilisable !! ";
string message("\n**erreur04** \n"+nom_class_methode+"(...");
entreePrinc->MessageBuffer(message);
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
};
// on regarde si la fonction nD intègre la température
const Tableau <Ddl_enum_etendu>& tab_enu = Qor_nD->Tab_enu_etendu();
if (tab_enu.Contient(TEMP))
thermo_dependant=true;
}
// sinon si le module Qor n'a pas été lue, on le récupère en version scalaire
else
{ // lecture du module
*(entreePrinc->entree) >> Qor ;
};
// idem si mur dépend d'une fonction nD
if(strstr(entreePrinc->tablcar,"mur_fonction_nD:")!=0)
{ string nom;
string mot_cle2="mur_fonction_nD:";
// on lit le nom de la fonction
string nom_fonct;
bool lec = entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle2,nom_fonct);
if (!lec )
{ entreePrinc->MessageBuffer("**erreur05 en lecture** "+mot_cle2);
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// maintenant on définit la fonction
if (lesFonctionsnD.Existe(nom_fonct))
{mur_nD = lesFonctionsnD.Trouve(nom_fonct);
}
else
{// sinon il faut la lire maintenant
string non("_");
mur_nD = Fonction_nD::New_Fonction_nD(non, Id_Nom_Fonction_nD(nom_fonct));
// lecture de la courbe
mur_nD->LectDonnParticulieres_Fonction_nD (non,entreePrinc);
// maintenant on vérifie que la fonction est utilisable
if (mur_nD->NbComposante() != 1 )
{ cout << "\n erreur en lecture, la fonction " << nom_fonct
<< " est une fonction vectorielle a " << mur_nD->NbComposante()
<< " composante alors qu'elle devrait etre scalaire ! "
<< " elle n'est donc pas utilisable !! ";
string message("\n**erreur06** \n"+nom_class_methode+"(...");
entreePrinc->MessageBuffer(message);
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
};
// on regarde si la fonction nD intègre la température
const Tableau <Ddl_enum_etendu>& tab_enu = mur_nD->Tab_enu_etendu();
if (tab_enu.Contient(TEMP))
thermo_dependant=true;
}
// sinon si le module mur n'a pas été lue, on le récupère en version scalaire
else
{ // lecture du module
*(entreePrinc->entree) >> mur ;
};
// idem si mu_inf dépend d'une fonction nD
if(strstr(entreePrinc->tablcar,"mu_inf_fonction_nD:")!=0)
{ string nom;
string mot_cle2="mu_inf_fonction_nD:";
// on lit le nom de la fonction
string nom_fonct;
bool lec = entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle2,nom_fonct);
if (!lec )
{ entreePrinc->MessageBuffer("**erreur07 en lecture** "+mot_cle2);
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// maintenant on définit la fonction
if (lesFonctionsnD.Existe(nom_fonct))
{mu_inf_nD = lesFonctionsnD.Trouve(nom_fonct);
}
else
{// sinon il faut la lire maintenant
string non("_");
mu_inf_nD = Fonction_nD::New_Fonction_nD(non, Id_Nom_Fonction_nD(nom_fonct));
// lecture de la courbe
mu_inf_nD->LectDonnParticulieres_Fonction_nD (non,entreePrinc);
// maintenant on vérifie que la fonction est utilisable
if (mu_inf_nD->NbComposante() != 1 )
{ cout << "\n erreur en lecture, la fonction " << nom_fonct
<< " est une fonction vectorielle a " << mu_inf_nD->NbComposante()
<< " composante alors qu'elle devrait etre scalaire ! "
<< " elle n'est donc pas utilisable !! ";
string message("\n**erreur08** \n"+nom_class_methode+"(...");
entreePrinc->MessageBuffer(message);
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
};
// on regarde si la fonction nD intègre la température
const Tableau <Ddl_enum_etendu>& tab_enu = mu_inf_nD->Tab_enu_etendu();
if (tab_enu.Contient(TEMP))
thermo_dependant=true;
}
// sinon si le module mu_inf n'a pas été lue, on le récupère en version scalaire
else
{ // lecture du module
*(entreePrinc->entree) >> mu_inf ;
};
// *(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
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";
if (K_nD != NULL)
{cout << "\n K fonction nD: ";
cout << "K_fonction_nD:" << " ";
if (K_nD->NomFonction() != "_")
cout << K_nD->NomFonction();
else
K_nD->Affiche();
}
else
{ cout << " K= " << K ;};
if (Qor_nD != NULL)
{cout << "\n Qor fonction nD: ";
cout << "Qor_fonction_nD:" << " ";
if (Qor_nD->NomFonction() != "_")
cout << Qor_nD->NomFonction();
else
Qor_nD->Affiche();
}
else
{ cout << " Qor= " << Qor ;};
if (mur_nD != NULL)
{cout << "\n mur fonction nD: ";
cout << "mur_fonction_nD:" << " ";
if (mur_nD->NomFonction() != "_")
cout << mur_nD->NomFonction();
else
mur_nD->Affiche();
}
else
{ cout << " mur_nD= " << mur_nD ;};
if (mu_inf_nD != NULL)
{cout << "\n mu_inf fonction nD: ";
cout << "mu_inf_fonction_nD:" << " ";
if (mu_inf_nD->NomFonction() != "_")
cout << mu_inf_nD->NomFonction();
else
mu_inf_nD->Affiche();
}
else
{ cout << " mu_inf= " << mu_inf ;};
// 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 AVEC utilisation de fonction nD :"
<< "\n#------------------------------------------------------------------------------------"
<< "\n# K | Qor | mur | mu_inf | avec_phase(falculatif) |"
<< "\n#------------------------------------------------------------------------------------"
<< "\n# 16000 Qor_fonction_nD: fct1 17000 mu_inf_fonction_nD: fct2"
<< "\n#"
<< "\n# une fonction nD est possible pour chacun des 4 coefficients, via les mots cle "
<< "\n# K_fonction_nD: "
<< "\n# Qor_fonction_nD: "
<< "\n# mur_fonction_nD: "
<< "\n# mu_inf_fonction_nD: "
<< "\n# on peut utiliser 1 ou 2 ou 3 ou 4 fct nD, au choix "
<< "\n# ( bien noter que la loi obtenue peut-etre quelconque, en particulier plus du tout "
<< "\n# hyperelastique, tout depend des choix de fct nD !) "
<< "\n#"
<< "\n#------------------------------------------------------------------------------------"
<< "\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# **** exemple de cas SANS la phase :"
<< "\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) && (K_nD == NULL))
{ cout << " \n Le parametre K n'est pas defini pour la loi " << Nom_comp(id_comp)
<< '\n';
Affiche();
ret = 0;
}
if ((Qor == ConstMath::trespetit) && (Qor_nD == NULL))
{ cout << " \n Le parametre Qor n'est pas defini pour la loi " << Nom_comp(id_comp)
<< '\n';
Affiche();
ret = 0;
}
if ((mur == ConstMath::trespetit) && (mur_nD == NULL))
{ cout << " \n Le parametre mur n'est pas defini pour la loi " << Nom_comp(id_comp)
<< '\n';
Affiche();
ret = 0;
}
if ((mu_inf == ConstMath::trespetit) && (mu_inf_nD == NULL))
{ cout << " \n Le parametre mu_inf n'est pas defini 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;
};
// récupération des grandeurs particulière (hors ddl )
// correspondant à liTQ
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
void IsoHyper3DFavier3::Grandeur_particuliere
(bool absolue,List_io<TypeQuelconque>& liTQ,Loi_comp_abstraite::SaveResul * saveDon,list<int>& decal) const
{ // tout d'abord on appelle la class mère
HyperD::Grandeur_particuliere(absolue,liTQ,saveDon,decal);
// --- puis la loi elle-même
// on passe en revue la liste
List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end();
list<int>::iterator idecal=decal.begin();
for (itq=liTQ.begin();itq!=itqfin;itq++,idecal++)
{TypeQuelconque& tipParticu = (*itq); // pour simplifier
if (tipParticu.EnuTypeQuelconque().Nom_vide()) // veut dire que c'est un enum pur
switch (tipParticu.EnuTypeQuelconque().EnumTQ())
{case PARA_LOI_FAVIER:
// ----- cas des paramètres de la loi
{ SaveResulIsoHyper3DFavier3 & save_resul = *((SaveResulIsoHyper3DFavier3*) saveDon);
Tab_Grandeur_Vecteur& tyTQ= *((Tab_Grandeur_Vecteur*) (*itq).Grandeur_pointee()); // pour simplifier
if (save_resul.para_loi != NULL)
{tyTQ(1+(*idecal))= *(save_resul.para_loi);}
else {tyTQ(1+(*idecal)).Zero();};
(*idecal)++; break;
}
default: ;// on ne fait rien
};
};
};
// récupération et création de la liste de tous les grandeurs particulières
// ces grandeurs sont ajoutées à la liste passées en paramètres
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
void IsoHyper3DFavier3::ListeGrandeurs_particulieres(bool absolue,List_io<TypeQuelconque>& liTQ) const
{ // tout d'abord on appelle la class mère
HyperD::ListeGrandeurs_particulieres(absolue,liTQ);
// --- puis la loi elle-même
// $$$ cas des paramètres de la loi de comportement
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == PARA_LOI_FAVIER)
{Tab_Grandeur_Vecteur& tyTQ= *((Tab_Grandeur_Vecteur*) (*itq).Grandeur_pointee()); // pour simplifier
int taille = tyTQ.Taille()+1;
tyTQ.Change_taille(taille); nexistePas = false;
};
if (nexistePas)
{Vecteur tens(4); // les 4 paramètres
Tab_Grandeur_Vecteur gr_vec_para(tens,1);
// def d'un type quelconque représentatif
TypeQuelconque typQ(PARA_LOI_FAVIER,SIG11,gr_vec_para);
liTQ.push_back(typQ);
};
};
};
//----- 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,nom;
if (cas == 1)
{ ent >> toto >> thermo_dependant >> toto;
// tout d'abord la lecture de K
int type =0;
ent >> type;
switch (type)
{ case 1 :
{ent >> nom;
if (nom != " K_fonction_nD: ")
{ cout << "\n erreur en lecture de la fonction nD, on attendait "
<< " K_fonction_nD: et on a lue " << nom
<< "\n IsoHyper3DFavier3::Lecture_base_info_loi(...";
Sortie(1);
};
K_nD = lesFonctionsnD.Lecture_pour_base_info(ent,cas,K_nD);
// on regarde si la fonction nD intègre la température
// car l'utilisateur peut éventuellement lors d'un restart changer
// de paramètres pour la fonction nD
const Tableau <Ddl_enum_etendu>& tab_enu = K_nD->Tab_enu_etendu();
if (tab_enu.Contient(TEMP))
thermo_dependant=true;
break;
};
case 2 :
{ent >> K;
break;
};
default: cout << "\n erreur type " << type << " non prevu, pour l'instant, les types "
<< " reconnus sont uniquement: 1 c-a-d K fonction nD, "
<< " 2 K une valeur fixe "
<< "\n IsoHyper3DFavier3::Lecture_base_info_loi(...";
Sortie(1);
break;
};
// puis lecture de Qor
type =0;
ent >> toto >> type;
switch (type)
{ case 1 :
{ent >> nom;
if (nom != " Qor_fonction_nD: ")
{ cout << "\n erreur en lecture de la fonction nD, on attendait "
<< " Qor_fonction_nD: et on a lue " << nom
<< "\n IsoHyper3DFavier3::Lecture_base_info_loi(...";
Sortie(1);
};
Qor_nD = lesFonctionsnD.Lecture_pour_base_info(ent,cas,Qor_nD);
// on regarde si la fonction nD intègre la température
// car l'utilisateur peut éventuellement lors d'un restart changer
// de paramètres pour la fonction nD
const Tableau <Ddl_enum_etendu>& tab_enu = Qor_nD->Tab_enu_etendu();
if (tab_enu.Contient(TEMP))
thermo_dependant=true;
break;
};
case 2 :
{ent >> Qor;
break;
};
default: cout << "\n erreur type " << type << " non prevu, pour l'instant, les types "
<< " reconnus sont uniquement: 1 c-a-d Qor fonction nD, "
<< " 2 Qor une valeur fixe "
<< "\n IsoHyper3DFavier3::Lecture_base_info_loi(...";
Sortie(1);
break;
};
// puis lecture de mur
type =0;
ent >> toto >> type;
switch (type)
{ case 1 :
{ent >> nom;
if (nom != " mur_fonction_nD: ")
{ cout << "\n erreur en lecture de la fonction nD, on attendait "
<< " mur_fonction_nD: et on a lue " << nom
<< "\n IsoHyper3DFavier3::Lecture_base_info_loi(...";
Sortie(1);
};
mur_nD = lesFonctionsnD.Lecture_pour_base_info(ent,cas,mur_nD);
// on regarde si la fonction nD intègre la température
// car l'utilisateur peut éventuellement lors d'un restart changer
// de paramètres pour la fonction nD
const Tableau <Ddl_enum_etendu>& tab_enu = mur_nD->Tab_enu_etendu();
if (tab_enu.Contient(TEMP))
thermo_dependant=true;
break;
};
case 2 :
{ent >> mur;
break;
};
default: cout << "\n erreur type " << type << " non prevu, pour l'instant, les types "
<< " reconnus sont uniquement: 1 c-a-d mur fonction nD, "
<< " 2 mur une valeur fixe "
<< "\n IsoHyper3DFavier3::Lecture_base_info_loi(...";
Sortie(1);
break;
};
// puis lecture de mu_inf
type =0;
ent >> toto >> type;
switch (type)
{ case 1 :
{ent >> nom;
if (nom != " mu_inf_fonction_nD: ")
{ cout << "\n erreur en lecture de la fonction nD, on attendait "
<< " mu_inf_fonction_nD: et on a lue " << nom
<< "\n IsoHyper3DFavier3::Lecture_base_info_loi(...";
Sortie(1);
};
mu_inf_nD = lesFonctionsnD.Lecture_pour_base_info(ent,cas,mu_inf_nD);
// on regarde si la fonction nD intègre la température
// car l'utilisateur peut éventuellement lors d'un restart changer
// de paramètres pour la fonction nD
const Tableau <Ddl_enum_etendu>& tab_enu = mu_inf_nD->Tab_enu_etendu();
if (tab_enu.Contient(TEMP))
thermo_dependant=true;
break;
};
case 2 :
{ent >> mu_inf;
break;
};
default: cout << "\n erreur type " << type << " non prevu, pour l'instant, les types "
<< " reconnus sont uniquement: 1 c-a-d mu_inf fonction nD, "
<< " 2 mu_inf une valeur fixe "
<< "\n IsoHyper3DFavier3::Lecture_base_info_loi(...";
Sortie(1);
break;
};
// ent >> toto >> K >> toto >> Qor >> toto >> mur >> toto >> mu_inf >> avec_phase;
// avec phase éventuelle
ent >> 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 << " ISOHYPER3DFAVIER3,thermodependance= " << thermo_dependant ;
sort << " module_K ";
if (K_nD != NULL)
{sort << " 1 K_fonction_nD: " << " ";
LesFonctions_nD::Ecriture_pour_base_info(sort, cas,K_nD);
}
else
{ sort << " 2 " << K ; };
sort << " seuil ";
if (Qor_nD != NULL)
{sort << " 1 Qor_fonction_nD: " << " ";
LesFonctions_nD::Ecriture_pour_base_info(sort, cas,Qor_nD);
}
else
{ sort << " 2 " << Qor ; };
sort << " pente_origine ";
if (mur_nD != NULL)
{sort << " 1 mur_fonction_nD: " << " ";
LesFonctions_nD::Ecriture_pour_base_info(sort, cas,mur_nD);
}
else
{ sort << " 2 " << mur ; };
sort << " pente_infini ";
if (mu_inf_nD != NULL)
{sort << " 1 mu_inf_fonction_nD: " << " ";
LesFonctions_nD::Ecriture_pour_base_info(sort, cas,mu_inf_nD);
}
else
{ sort << " 2 " << mu_inf ; };
// sort << " module_dilatation " << K << " seuil " << Qor
// << " pente_origine " << mur << " pente_infini " << mu_inf << " avec_phase " << avec_phase;
sort << " 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);
};
// calcul d'un module d'young équivalent à la loi, ceci pour un
// chargement nul si rien n'est calculé, sinon c'est
// une valeur correspondante au dernier calcul
double IsoHyper3DFavier3::Module_young_equivalent(Enum_dure temps,const Deformation & def,SaveResul * saveDon)
{ // compte tenu du fait que l'on ne connait pas la métrique etc... on ramène le module en cours
// on récupère le conteneur
SaveResulIsoHyper3DFavier3 & save_resul = *((SaveResulIsoHyper3DFavier3*) saveResul);
double K_sortie=K; // init
double mur_sortie=mur; // init
double mu_inf_sortie=mu_inf; // init
// traitement du cas particulier de l'existence de fct nD
if (save_resul.para_loi != NULL)
{bool recup = false;
switch (temps)
{
case TEMPS_t : // on utilise les grandeurs stockées à t
if ((*save_resul.para_loi_t)(1) != (-ConstMath::trespetit))
{K_sortie= (*save_resul.para_loi_t)(1);recup = true;}
break;
case TEMPS_tdt : // on utilise les grandeurs stockées à tdt
if ((*save_resul.para_loi)(1) != (-ConstMath::trespetit))
{K_sortie= (*save_resul.para_loi)(1);recup = true;}
break;
case TEMPS_0 : // rien n'a été calculé
recup = false;
};
// dans tous les autres cas on utilise soit les fonctions
// si elles existent sinon on concerve les valeurs par défaut
if (!recup)
{//on essaie un calcul
// cas des courbes d'évolution
if (K_nD != NULL)
// là il faut calcul la fonction nD
{
// ici on utilise les variables connues aux pti, ou calculées à partir de
// on commence par récupérer les conteneurs des grandeurs à fournir
List_io <Ddl_enum_etendu>& li_enu_scal = K_nD->Li_enu_etendu_scalaire();
List_io <TypeQuelconque >& li_quelc = K_nD->Li_equi_Quel_evolue();
// on initialise les grandeurs du tableau pour les valeurs numériques
Tableau <double> val_ddl_enum(li_enu_scal.size(),0.);
// init par défaut des types quelconques
List_io <TypeQuelconque >::iterator il,ilfin=li_quelc.end();
for (il = li_quelc.begin();il != ilfin; il++)
(*il).Grandeur_pointee()->InitParDefaut();
// calcul de la valeur et retour dans tab_ret
Tableau <double> & tab_val
= K_nD->Valeur_FnD_Evoluee(&val_ddl_enum,&li_enu_scal,&li_quelc,NULL,NULL);
#ifdef MISE_AU_POINT
if (tab_val.Taille() != 1)
{ cout << "\nErreur : la fonction nD relative au module d'Young "
<< " doit calculer un scalaire or le tableau de retour est de taille "
<< tab_val.Taille() << " ce n'est pas normal !\n";
cout << " IsoHyper3DFavier3::Module_compressibilite_equivalent(..\n";
Sortie(1);
};
#endif
// on récupère le premier élément du tableau uniquement
K_sortie = tab_val(1);
};
};
// -- idem pour mur
recup = false;
switch (temps)
{
case TEMPS_t : // on utilise les grandeurs stockées à t
if ((*save_resul.para_loi_t)(3) != (-ConstMath::trespetit))
{mur_sortie= (*save_resul.para_loi_t)(3);recup = true;}
break;
case TEMPS_tdt : // on utilise les grandeurs stockées à tdt
if ((*save_resul.para_loi)(3) != (-ConstMath::trespetit))
{mur_sortie= (*save_resul.para_loi)(3);recup = true;}
break;
case TEMPS_0 : // rien n'a été calculé
recup = false;
};
// dans tous les autres cas on utilise soit les fonctions
// si elles existent sinon on concerve les valeurs par défaut
if (!recup)
{//on essaie un calcul
// cas des courbes d'évolution
if (mur_nD != NULL)
// là il faut calcul la fonction nD
{
// ici on utilise les variables connues aux pti, ou calculées à partir de
// on commence par récupérer les conteneurs des grandeurs à fournir
List_io <Ddl_enum_etendu>& li_enu_scal = mur_nD->Li_enu_etendu_scalaire();
List_io <TypeQuelconque >& li_quelc = mur_nD->Li_equi_Quel_evolue();
// on initialise les grandeurs du tableau pour les valeurs numériques
Tableau <double> val_ddl_enum(li_enu_scal.size(),0.);
// init par défaut des types quelconques
List_io <TypeQuelconque >::iterator il,ilfin=li_quelc.end();
for (il = li_quelc.begin();il != ilfin; il++)
(*il).Grandeur_pointee()->InitParDefaut();
// calcul de la valeur et retour dans tab_ret
Tableau <double> & tab_val
= mur_nD->Valeur_FnD_Evoluee(&val_ddl_enum,&li_enu_scal,&li_quelc,NULL,NULL);
#ifdef MISE_AU_POINT
if (tab_val.Taille() != 1)
{ cout << "\nErreur : la fonction nD relative au module d'Young "
<< " doit calculer un scalaire or le tableau de retour est de taille "
<< tab_val.Taille() << " ce n'est pas normal !\n";
cout << " IsoHyper3DFavier3::Module_compressibilite_equivalent(..\n";
Sortie(1);
};
#endif
// on récupère le premier élément du tableau uniquement
mur_sortie = tab_val(1);
};
};
// -- idem pour mu_inf
recup = false;
switch (temps)
{
case TEMPS_t : // on utilise les grandeurs stockées à t
if ((*save_resul.para_loi_t)(4) != (-ConstMath::trespetit))
{mu_inf_sortie= (*save_resul.para_loi_t)(4);recup = true;}
break;
case TEMPS_tdt : // on utilise les grandeurs stockées à tdt
if ((*save_resul.para_loi)(4) != (-ConstMath::trespetit))
{mu_inf_sortie= (*save_resul.para_loi)(4);recup = true;}
break;
case TEMPS_0 : // rien n'a été calculé
recup = false;
};
// dans tous les autres cas on utilise soit les fonctions
// si elles existent sinon on concerve les valeurs par défaut
if (!recup)
{//on essaie un calcul
// cas des courbes d'évolution
if (mu_inf_nD != NULL)
// là il faut calcul la fonction nD
{
// ici on utilise les variables connues aux pti, ou calculées à partir de
// on commence par récupérer les conteneurs des grandeurs à fournir
List_io <Ddl_enum_etendu>& li_enu_scal = mu_inf_nD->Li_enu_etendu_scalaire();
List_io <TypeQuelconque >& li_quelc = mu_inf_nD->Li_equi_Quel_evolue();
// on initialise les grandeurs du tableau pour les valeurs numériques
Tableau <double> val_ddl_enum(li_enu_scal.size(),0.);
// init par défaut des types quelconques
List_io <TypeQuelconque >::iterator il,ilfin=li_quelc.end();
for (il = li_quelc.begin();il != ilfin; il++)
(*il).Grandeur_pointee()->InitParDefaut();
// calcul de la valeur et retour dans tab_ret
Tableau <double> & tab_val
= mu_inf_nD->Valeur_FnD_Evoluee(&val_ddl_enum,&li_enu_scal,&li_quelc,NULL,NULL);
#ifdef MISE_AU_POINT
if (tab_val.Taille() != 1)
{ cout << "\nErreur : la fonction nD relative au module d'Young "
<< " doit calculer un scalaire or le tableau de retour est de taille "
<< tab_val.Taille() << " ce n'est pas normal !\n";
cout << " IsoHyper3DFavier3::Module_compressibilite_equivalent(..\n";
Sortie(1);
};
#endif
// on récupère le premier élément du tableau uniquement
mu_inf_sortie = tab_val(1);
};
};
};
// retour du module
double module = (9.*K_sortie*(mur_sortie+mu_inf_sortie)/((mur_sortie+mu_inf_sortie)+3.*K_sortie));
return module;
};
// récupération d'un module de compressibilité équivalent à la loi, ceci pour un chargement nul
// si rien n'est calculé, sinon c'est
// une valeur correspondante au dernier calcul
double IsoHyper3DFavier3::Module_compressibilite_equivalent(Enum_dure temps,const Deformation & def,SaveResul * saveDon)
{ // compte tenu du fait que l'on ne connait pas la métrique etc... on ramène le module en cours
// on récupère le conteneur
SaveResulIsoHyper3DFavier3 & save_resul = *((SaveResulIsoHyper3DFavier3*) saveResul);
double K_sortie=K; // init
// traitement du cas particulier de l'existence de fct nD
if (save_resul.para_loi != NULL)
{bool recup = false;
switch (temps)
{
case TEMPS_t : // on utilise les grandeurs stockées à t
if ((*save_resul.para_loi_t)(1) != (-ConstMath::trespetit))
{K_sortie= (*save_resul.para_loi_t)(1);recup = true;}
break;
case TEMPS_tdt : // on utilise les grandeurs stockées à tdt
if ((*save_resul.para_loi)(1) != (-ConstMath::trespetit))
{K_sortie= (*save_resul.para_loi)(1);recup = true;}
break;
case TEMPS_0 : // rien n'a été calculé
recup = false;
};
// dans tous les autres cas on utilise soit les fonctions
// si elles existent sinon on concerve les valeurs par défaut
if (!recup)
{//on essaie un calcul
// cas des courbes d'évolution
if (K_nD != NULL)
// là il faut calcul la fonction nD
{
// ici on utilise les variables connues aux pti, ou calculées à partir de
// on commence par récupérer les conteneurs des grandeurs à fournir
List_io <Ddl_enum_etendu>& li_enu_scal = K_nD->Li_enu_etendu_scalaire();
List_io <TypeQuelconque >& li_quelc = K_nD->Li_equi_Quel_evolue();
// on initialise les grandeurs du tableau pour les valeurs numériques
Tableau <double> val_ddl_enum(li_enu_scal.size(),0.);
// init par défaut des types quelconques
List_io <TypeQuelconque >::iterator il,ilfin=li_quelc.end();
for (il = li_quelc.begin();il != ilfin; il++)
(*il).Grandeur_pointee()->InitParDefaut();
// calcul de la valeur et retour dans tab_ret
Tableau <double> & tab_val
= K_nD->Valeur_FnD_Evoluee(&val_ddl_enum,&li_enu_scal,&li_quelc,NULL,NULL);
#ifdef MISE_AU_POINT
if (tab_val.Taille() != 1)
{ cout << "\nErreur : la fonction nD relative au module d'Young "
<< " doit calculer un scalaire or le tableau de retour est de taille "
<< tab_val.Taille() << " ce n'est pas normal !\n";
cout << " IsoHyper3DFavier3::Module_compressibilite_equivalent(..\n";
Sortie(1);
};
#endif
// on récupère le premier élément du tableau uniquement
K_sortie = tab_val(1);
};
};
};
// retour du module
double K= K_sortie/3.;
return K;
};
// =========== 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)
{ // calcul éventuelle des paramètres de la loi
if (K_nD != NULL)
{K = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(K_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (Qor_nD != NULL)
{Qor = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(Qor_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mur_nD != NULL)
{mur = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mur_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mu_inf_nD != NULL)
{mu_inf = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mu_inf_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
// sauvegarde éventuelle des paramètres matériau
SaveResulIsoHyper3DFavier3 & save_resul = *((SaveResulIsoHyper3DFavier3*) saveResul);
if (save_resul.para_loi != NULL)
{(*save_resul.para_loi)(1) = K;
(*save_resul.para_loi)(2) = Qor;
(*save_resul.para_loi)(3) = mur;
(*save_resul.para_loi)(4) = mu_inf;
};
// 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)
{ // calcul éventuelle des paramètres de la loi
if (K_nD != NULL)
{K = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(K_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (Qor_nD != NULL)
{Qor = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(Qor_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mur_nD != NULL)
{mur = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mur_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mu_inf_nD != NULL)
{mu_inf = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mu_inf_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
// sauvegarde éventuelle des paramètres matériau
SaveResulIsoHyper3DFavier3 & save_resul = *((SaveResulIsoHyper3DFavier3*) saveResul);
if (save_resul.para_loi != NULL)
{(*save_resul.para_loi)(1) = K;
(*save_resul.para_loi)(2) = Qor;
(*save_resul.para_loi)(3) = mur;
(*save_resul.para_loi)(4) = mu_inf;
};
// 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)
{ // calcul éventuelle des paramètres de la loi
if (K_nD != NULL)
{K = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(K_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (Qor_nD != NULL)
{Qor = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(Qor_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mur_nD != NULL)
{mur = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mur_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mu_inf_nD != NULL)
{mu_inf = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mu_inf_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
// sauvegarde éventuelle des paramètres matériau
SaveResulIsoHyper3DFavier3 & save_resul = *((SaveResulIsoHyper3DFavier3*) saveResul);
if (save_resul.para_loi != NULL)
{(*save_resul.para_loi)(1) = K;
(*save_resul.para_loi)(2) = Qor;
(*save_resul.para_loi)(3) = mur;
(*save_resul.para_loi)(4) = mu_inf;
};
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)
{ // calcul éventuelle des paramètres de la loi
if (K_nD != NULL)
{K = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(K_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (Qor_nD != NULL)
{Qor = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(Qor_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mur_nD != NULL)
{mur = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mur_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mu_inf_nD != NULL)
{mu_inf = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mu_inf_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
// sauvegarde éventuelle des paramètres matériau
SaveResulIsoHyper3DFavier3 & save_resul = *((SaveResulIsoHyper3DFavier3*) saveResul);
if (save_resul.para_loi != NULL)
{(*save_resul.para_loi)(1) = K;
(*save_resul.para_loi)(2) = Qor;
(*save_resul.para_loi)(3) = mur;
(*save_resul.para_loi)(4) = mu_inf;
};
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)
{ // calcul éventuelle des paramètres de la loi
if (K_nD != NULL)
{K = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(K_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (Qor_nD != NULL)
{Qor = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(Qor_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mur_nD != NULL)
{mur = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mur_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mu_inf_nD != NULL)
{mu_inf = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mu_inf_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
// sauvegarde éventuelle des paramètres matériau
SaveResulIsoHyper3DFavier3 & save_resul = *((SaveResulIsoHyper3DFavier3*) saveResul);
if (save_resul.para_loi != NULL)
{(*save_resul.para_loi)(1) = K;
(*save_resul.para_loi)(2) = Qor;
(*save_resul.para_loi)(3) = mur;
(*save_resul.para_loi)(4) = mu_inf;
};
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)
{ // calcul éventuelle des paramètres de la loi
if (K_nD != NULL)
{K = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(K_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (Qor_nD != NULL)
{Qor = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(Qor_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mur_nD != NULL)
{mur = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mur_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mu_inf_nD != NULL)
{mu_inf = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mu_inf_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
// sauvegarde éventuelle des paramètres matériau
SaveResulIsoHyper3DFavier3 & save_resul = *((SaveResulIsoHyper3DFavier3*) saveResul);
if (save_resul.para_loi != NULL)
{(*save_resul.para_loi)(1) = K;
(*save_resul.para_loi)(2) = Qor;
(*save_resul.para_loi)(3) = mur;
(*save_resul.para_loi)(4) = mu_inf;
};
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)
{ // calcul éventuelle des paramètres de la loi
if (K_nD != NULL)
{K = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(K_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (Qor_nD != NULL)
{Qor = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(Qor_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mur_nD != NULL)
{mur = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mur_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mu_inf_nD != NULL)
{mu_inf = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mu_inf_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
// sauvegarde éventuelle des paramètres matériau
SaveResulIsoHyper3DFavier3 & save_resul = *((SaveResulIsoHyper3DFavier3*) saveResul);
if (save_resul.para_loi != NULL)
{(*save_resul.para_loi)(1) = K;
(*save_resul.para_loi)(2) = Qor;
(*save_resul.para_loi)(3) = mur;
(*save_resul.para_loi)(4) = mu_inf;
};
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)
{ // calcul éventuelle des paramètres de la loi
if (K_nD != NULL)
{K = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(K_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (Qor_nD != NULL)
{Qor = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(Qor_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mur_nD != NULL)
{mur = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mur_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mu_inf_nD != NULL)
{mu_inf = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mu_inf_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
// sauvegarde éventuelle des paramètres matériau
SaveResulIsoHyper3DFavier3 & save_resul = *((SaveResulIsoHyper3DFavier3*) saveResul);
if (save_resul.para_loi != NULL)
{(*save_resul.para_loi)(1) = K;
(*save_resul.para_loi)(2) = Qor;
(*save_resul.para_loi)(3) = mur;
(*save_resul.para_loi)(4) = mu_inf;
};
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)
{ // calcul éventuelle des paramètres de la loi
if (K_nD != NULL)
{K = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(K_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (Qor_nD != NULL)
{Qor = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(Qor_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mur_nD != NULL)
{mur = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mur_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mu_inf_nD != NULL)
{mu_inf = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mu_inf_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
// sauvegarde éventuelle des paramètres matériau
SaveResulIsoHyper3DFavier3 & save_resul = *((SaveResulIsoHyper3DFavier3*) saveResul);
if (save_resul.para_loi != NULL)
{(*save_resul.para_loi)(1) = K;
(*save_resul.para_loi)(2) = Qor;
(*save_resul.para_loi)(3) = mur;
(*save_resul.para_loi)(4) = mu_inf;
};
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)
{ // calcul éventuelle des paramètres de la loi
if (K_nD != NULL)
{K = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(K_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (Qor_nD != NULL)
{Qor = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(Qor_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mur_nD != NULL)
{mur = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mur_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mu_inf_nD != NULL)
{mu_inf = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mu_inf_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
// sauvegarde éventuelle des paramètres matériau
SaveResulIsoHyper3DFavier3 & save_resul = *((SaveResulIsoHyper3DFavier3*) saveResul);
if (save_resul.para_loi != NULL)
{(*save_resul.para_loi)(1) = K;
(*save_resul.para_loi)(2) = Qor;
(*save_resul.para_loi)(3) = mur;
(*save_resul.para_loi)(4) = mu_inf;
};
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 )
{ // calcul éventuelle des paramètres de la loi
if (K_nD != NULL)
{K = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(K_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (Qor_nD != NULL)
{Qor = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(Qor_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mur_nD != NULL)
{mur = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mur_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mu_inf_nD != NULL)
{mu_inf = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mu_inf_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
// sauvegarde éventuelle des paramètres matériau
SaveResulIsoHyper3DFavier3 & save_resul = *((SaveResulIsoHyper3DFavier3*) saveResul);
if (save_resul.para_loi != NULL)
{(*save_resul.para_loi)(1) = K;
(*save_resul.para_loi)(2) = Qor;
(*save_resul.para_loi)(3) = mur;
(*save_resul.para_loi)(4) = mu_inf;
};
// 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 )
{ // calcul éventuelle des paramètres de la loi
if (K_nD != NULL)
{K = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(K_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (Qor_nD != NULL)
{Qor = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(Qor_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mur_nD != NULL)
{mur = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mur_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
if (mu_inf_nD != NULL)
{mu_inf = (Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(mu_inf_nD,1,ex_impli_hyper,ex_expli_tdt_hyper,ex_umat_hyper))(1);
};
// sauvegarde éventuelle des paramètres matériau
SaveResulIsoHyper3DFavier3 & save_resul = *((SaveResulIsoHyper3DFavier3*) saveResul);
if (save_resul.para_loi != NULL)
{(*save_resul.para_loi)(1) = K;
(*save_resul.para_loi)(2) = Qor;
(*save_resul.para_loi)(3) = mur;
(*save_resul.para_loi)(4) = mu_inf;
};
// 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);
}
};