2202 lines
96 KiB
C++
2202 lines
96 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& 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;
|
|
};
|
|
|
|
// Lecture des paramètre specifique sur fichier (exe: regularisation sortie_post...
|
|
Hyper3D::LectParaSpecifiques(entreePrinc,lesCourbes1D,lesFonctionsnD);
|
|
|
|
// 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 2 parametres specifiques de limite inf "
|
|
<< "\n# limite_inf_Qeps_ : si Qeps < limite_inf_Qeps on considere que l'angle de phase et ses derivees sont nulles "
|
|
<< "\n# limite_inf_bIIb_ : si Dabs(inv.bIIb) < limite_inf_bIIb "
|
|
<< "\n# les derivees du potentiel sont calculees pas difference fini, sauf ceux relatif a la phase qui sont mises a 0 "
|
|
<< "\n# les mots cle limite_inf_Qeps_ suivi du facteur voulu et limite_inf_bIIb_ suivi du facteur "
|
|
<< "\n# doivent etre dans cet ordre "
|
|
<< "\n# ex: "
|
|
<< "\n# limite_inf_Qeps_ 8.5e-5 limite_inf_bIIb_ 36.e-10 "
|
|
<< "\n# ces mots cle doivent se situer avant le mot cle avec_regularisation_ "
|
|
<< "\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;
|
|
};
|
|
// prise en compte éventuelle de paramètres particulier: ex: régularisation
|
|
// géré par HyperD et Hyper3D
|
|
Hyper3D::Lecture_para_specifiques(ent,cas);
|
|
// 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;
|
|
};
|
|
// prise en compte éventuelle de paramètres particulier: ex: régularisation
|
|
// géré par HyperD et Hyper3D
|
|
Hyper3D::Ecriture_para_specifiques(sort,cas);
|
|
// 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);
|
|
}
|
|
};
|