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

897 lines
42 KiB
C++

// FICHIER : Loi_de_Tait.cp
// CLASSE : Loi_de_Tait
// 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 "Debug.h"
# include <iostream>
using namespace std; //introduces namespace std
#include <math.h>
#include <stdlib.h>
#include "Sortie.h"
#include "TypeConsTens.h"
#include "ConstMath.h"
#include "TypeQuelconqueParticulier.h"
#include "CharUtil.h"
#include "Loi_de_Tait.h"
//==================== cas de la class de sauvegarde SaveResul ===================
// constructeur par défaut à ne pas utiliser
Loi_de_Tait::SaveResul_Loi_de_Tait::SaveResul_Loi_de_Tait() :
stockParaInt(NULL), saveCrista(NULL)
{ };
// le constructeur courant
// sCrista s'il est NULL, on en tient pas compte
// s'il est non NULL, on cré l'instances saveCrista par défaut
Loi_de_Tait::SaveResul_Loi_de_Tait::SaveResul_Loi_de_Tait
(CompThermoPhysiqueAbstraite::StockParaInt* stock
,CristaliniteAbstraite::SaveCrista* sCrista):
stockParaInt(NULL),saveCrista(NULL)
{if (sCrista != NULL)
saveCrista = sCrista->Nevez_SaveCrista();
if (stock != NULL)
{ stockParaInt = new CompThermoPhysiqueAbstraite::StockParaInt(*stock);
};
};
// constructeur de copie
Loi_de_Tait::SaveResul_Loi_de_Tait::SaveResul_Loi_de_Tait
(const Loi_de_Tait::SaveResul_Loi_de_Tait& sav ):
stockParaInt(NULL),saveCrista(NULL)
{if (sav.saveCrista != NULL)
saveCrista = sav.saveCrista->Nevez_SaveCrista();
if (sav.stockParaInt != NULL)
{ stockParaInt = new CompThermoPhysiqueAbstraite::StockParaInt(*(sav.stockParaInt));
};
};
// destructeur
Loi_de_Tait::SaveResul_Loi_de_Tait::~SaveResul_Loi_de_Tait()
{if (saveCrista != NULL) delete saveCrista;
if (stockParaInt != NULL) delete stockParaInt;
};
// affectation
CompThermoPhysiqueAbstraite::SaveResul &
Loi_de_Tait::SaveResul_Loi_de_Tait::operator = ( const CompThermoPhysiqueAbstraite::SaveResul & a)
{ Loi_de_Tait::SaveResul_Loi_de_Tait& sav = *((Loi_de_Tait::SaveResul_Loi_de_Tait*) &a);
if (sav.saveCrista != NULL)
{ if (saveCrista == NULL)
saveCrista = sav.saveCrista->Nevez_SaveCrista();
else
(*saveCrista) = *(sav.saveCrista);
}
else
delete saveCrista;
if (sav.stockParaInt != NULL)
{ if (stockParaInt == NULL)
stockParaInt = new CompThermoPhysiqueAbstraite::StockParaInt(*(sav.stockParaInt));
else
(*stockParaInt) = *(sav.stockParaInt);
}
else
delete stockParaInt;
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 Loi_de_Tait::SaveResul_Loi_de_Tait::Lecture_base_info
(ifstream& ent,const int cas)
{ // ici toutes les données sont toujours a priori variables
// ou en tout cas pour les méthodes appelées, elles sont gérées par le paramètre: cas
string toto; ent >> toto;
#ifdef MISE_AU_POINT
if (toto != "S_R_LoiTait")
{ cout << "\n erreur en lecture du conteneur pour la loi thermo physique de Tait"
<< " \n Loi_de_Tait::SaveResul_Loi_de_Tait::Lecture_base_info(..";
Sortie(1);
}
#endif
bool test=false;ent >> test;
if (test)
{// on regarde si les pointeurs existent sinon erreur
if (stockParaInt == NULL)
{ cout << "\n erreur en lecture du conteneur pour la loi thermo physique de Tait"
<< " on a detecte qu'il faut lire un conteneur de StockParaInt, mais "
<< " le conteneur resultat n'a pas ete aloue !! "
<< " \n Loi_de_Tait::SaveResul_Loi_de_Tait::Lecture_base_info(..";
Sortie(1);
}
else // sinon on peut lire
{ ent >> stockParaInt->pression >> stockParaInt->temperature ;};
};
test=false; ent >> test;
if (test)
{// on regarde si les pointeurs existent sinon erreur
if (saveCrista == NULL)
{ cout << "\n erreur en lecture du conteneur pour la loi thermo physique de Tait"
<< " on a detecte qu'il faut lire un conteneur de cristalinite, mais "
<< " le conteneur resultat n'a pas ete aloue !! "
<< " \n Loi_de_Tait::SaveResul_Loi_de_Tait::Lecture_base_info(..";
Sortie(1);
}
else // sinon on peut lire
{ saveCrista->Lecture_base_info (ent,cas);};
};
};
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void Loi_de_Tait::SaveResul_Loi_de_Tait::Ecriture_base_info
(ofstream& sort,const int cas)
{ // ici toutes les données sont toujours a priori variables
// ou en tout cas pour les méthodes appelées, elles sont gérées par le paramètre: cas
sort << "\n S_R_LoiTait ";
if (stockParaInt == NULL)
{sort << " 0 ";} // on sort un indicateur disant qu'il n'y a pas de pointeur
else
{sort << " 1 " << stockParaInt->pression<< " "<< " " << stockParaInt->temperature<< " ";
};
if (saveCrista == NULL)
{sort << " 0 ";} // on sort un indicateur disant qu'il n'y a pas de pointeur
else
{sort << " 1 "; saveCrista->Ecriture_base_info(sort,cas);};
};
// affichage des infos
void Loi_de_Tait::SaveResul_Loi_de_Tait::Affiche()
{ cout << "\n S_R_LoiTait ";
if (stockParaInt != NULL)
{ cout << " pression= " << stockParaInt->pression
<< " temperature= " << stockParaInt->temperature << " ";
};
if (saveCrista != NULL)
{ cout << " cristalinite : "; saveCrista->Affiche();};
};
// idem sur un ofstream
void Loi_de_Tait::SaveResul_Loi_de_Tait::Affiche(ofstream& sort)
{ sort << "\n S_R_LoiTait ";
if (stockParaInt != NULL)
{ sort << " pression= " << stockParaInt->pression
<< " temperature= " << stockParaInt->temperature << " ";
};
if (saveCrista != NULL)
{ sort << " cristalinite : "; saveCrista->Affiche(sort);};
};
// mise à jour des informations transitoires en définitif s'il y a convergence
// par exemple (pour la plasticité par exemple)
void Loi_de_Tait::SaveResul_Loi_de_Tait::TdtversT()
{ if (saveCrista != NULL)
saveCrista->TdtversT();
};
void Loi_de_Tait::SaveResul_Loi_de_Tait::TversTdt()
{ if (saveCrista != NULL)
saveCrista->TversTdt();
};
// def d'une instance de données spécifiques, et initialisation
Loi_de_Tait::SaveResul * Loi_de_Tait::New_et_Initialise()
{ Loi_de_Tait::SaveResul * cont=NULL; // conteneur de retour
if (sortie_post || (crista != NULL))
// cas où il faut un conteneur
{if (sortie_post && (crista == NULL))
// cas sans cristalinité
{ // il faut quand même dimensionner stock, car ensuite on peut vouloir la pression
double pres=0; double temper=0.;
CompThermoPhysiqueAbstraite::StockParaInt* stock =
new CompThermoPhysiqueAbstraite::StockParaInt(pres,temper);
cont = new Loi_de_Tait::SaveResul_Loi_de_Tait(stock ,NULL );
delete stock;
}
else // sinon c'est soit (sortie_post && (crista != NULL))
// ou (!sortie_post && (crista != NULL))
{ CristaliniteAbstraite::SaveCrista* interr = crista->New_et_Initialise();
double pres=0; double temper=0.;
CompThermoPhysiqueAbstraite::StockParaInt* stock =
new CompThermoPhysiqueAbstraite::StockParaInt(pres,temper);
cont = new Loi_de_Tait::SaveResul_Loi_de_Tait(stock , interr);
delete interr;
delete stock;
};
};
return cont;
};
//==================== fin du cas de la class de sauvegarde SaveResul ============
Loi_de_Tait::Loi_de_Tait () : // Constructeur par defaut
CompThermoPhysiqueAbstraite(LOI_DE_TAIT,CAT_THERMO_PHYSIQUE,4),alphaT(0.)
,compressibilite(0.),lambda(0.),lambda_temperature(NULL),cp(0.),cp_temperature(NULL)
,b1s(0.),b2s(0.),b3s(0.),b4s(0.),b1m(0.),b2m(0.),b3m(0.),b4m(0.),b5(0.),b6(0.),b7(0.),b8(0.),b9(0.)
,sortie_post(false),type_de_calcul(0),crista(NULL)
{ };
// Constructeur de copie
Loi_de_Tait::Loi_de_Tait (const Loi_de_Tait& loi) :
CompThermoPhysiqueAbstraite(loi),alphaT(loi.alphaT)
,compressibilite(loi.compressibilite)
,lambda(loi.lambda),lambda_temperature(loi.lambda_temperature)
,cp(loi.cp),cp_temperature(loi.cp_temperature)
,b1s(loi.b1s),b2s(loi.b2s),b3s(loi.b3s),b4s(loi.b4s),b1m(loi.b1m),b2m(loi.b2m),b3m(loi.b3m)
,b4m(loi.b4m),b5(loi.b5),b6(loi.b6),b7(loi.b7),b8(loi.b8),b9(loi.b9)
,sortie_post(loi.sortie_post),type_de_calcul(loi.type_de_calcul),crista(loi.crista)
{
if (lambda_temperature != NULL)
if (lambda_temperature->NomCourbe() == "_")
lambda_temperature = Courbe1D::New_Courbe1D(*(loi.lambda_temperature));
if (cp_temperature != NULL)
if (cp_temperature->NomCourbe() == "_")
cp_temperature = Courbe1D::New_Courbe1D(*(loi.cp_temperature));
if (crista != NULL)
crista = CristaliniteAbstraite::New_Cristalinite(*(loi.crista));
};
Loi_de_Tait::~Loi_de_Tait ()
// Destructeur
{ if (lambda_temperature != NULL)
if (lambda_temperature->NomCourbe() == "_") delete lambda_temperature;
if (cp_temperature != NULL)
if (cp_temperature->NomCourbe() == "_") delete cp_temperature;
if (crista != NULL)
delete crista;
};
// Lecture des donnees de la classe sur fichier
void Loi_de_Tait::LectureDonneesParticulieres
(UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D ,LesFonctions_nD& lesFonctionsnD)
{ // ------------ lecture du coefficient de dilatation
string nom; *(entreePrinc->entree) >> nom;
if (nom != "coefficients_bi")
{ cout << "\n erreur en lecture des coefficients bi, on attendait le mot cle coefficients_bi"
<< " et on a lue " << nom;
entreePrinc->MessageBuffer("**erreur1** Loi_de_Tait::LectureDonneesParticulieres (... ");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// lecture des coefficients bis
string nom_b1,nom_b2,nom_b3,nom_b4;
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
*(entreePrinc->entree) >> nom_b1 >> b1s >> nom_b2 >> b2s >> nom_b3 >> b3s >> nom_b4 >> b4s;
if ((nom_b1 != "b1s=") || (nom_b2 != "b2s=") || (nom_b3 != "b3s=") || (nom_b4 != "b4s=") )
{ cout << "\n erreur en lecture des coefficients bis, un des labels de coefficients n'est pas correcte,"
<< " on a lue " << nom_b1 << " " << b1s << " " << nom_b2 << " " << b2s << " "<< " "
<< nom_b3 << " " << b3s << " "<< " " << nom_b4 << " " << b4s << " "<< " ";
entreePrinc->MessageBuffer("**erreur2** Loi_de_Tait::LectureDonneesParticulieres (... ");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// lecture des coefficients bim
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
*(entreePrinc->entree) >> nom_b1 >> b1m >> nom_b2 >> b2m >> nom_b3 >> b3m >> nom_b4 >> b4m;
if ((nom_b1 != "b1m=") || (nom_b2 != "b2m=") || (nom_b3 != "b3m=") || (nom_b4 != "b4m=") )
{ cout << "\n erreur en lecture des coefficients bim, un des labels de coefficients n'est pas correcte,"
<< " on a lue " << nom_b1 << " " << b1m << " " << nom_b2 << " " << b2m << " "
<< nom_b3 << " " << b3m << " "<< nom_b4 << " " << b4m << " ";
entreePrinc->MessageBuffer("**erreur3** Loi_de_Tait::LectureDonneesParticulieres (... ");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// lecture des coefficients bi
string nom_b9;
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
*(entreePrinc->entree) >> nom_b1 >> b5 >> nom_b2 >> b6 >> nom_b3 >> b7 >> nom_b4 >> b8
>> nom_b9 >> b9 ;;
if ((nom_b1 != "b5=") || (nom_b2 != "b6=") || (nom_b3 != "b7=") || (nom_b4 != "b8=") || (nom_b9 != "b9="))
{ cout << "\n erreur2 en lecture des coefficients bi, un des labels de coefficients n'est pas correcte,"
<< " on a lue " << nom_b1 << " " << b5 << " " << nom_b2 << " " << b6 << " "
<< nom_b3 << " " << b7 << " "<< nom_b4 << " " << b8 << " "<< nom_b9 << " " << b9 << " ";
entreePrinc->MessageBuffer("**erreur4** Loi_de_Tait::LectureDonneesParticulieres (... ");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// ---------- lecture de la conductivité
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
*(entreePrinc->entree) >> nom;
if (nom != "lambda=")
{ cout << "\n erreur en lecture de la conductivite, on attendait le mot cle lambda=";
entreePrinc->MessageBuffer("**erreur5** Loi_de_Tait::LectureDonneesParticulieres (... ");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
// on regarde si le coeff est thermo dépendant
if(strstr(entreePrinc->tablcar,"lambda_thermo_dependant_")!=0)
{ thermo_dependant=true;
*(entreePrinc->entree) >> nom;
if (nom != "lambda_thermo_dependant_")
{ cout << "\n erreur en lecture de la thermodependance, on aurait du lire le mot cle lambda_thermo_dependant_"
<< " suivi du nom d'une courbe de charge ou de la courbe elle meme ";
entreePrinc->MessageBuffer("**erreur6** Loi_de_Tait::LectureDonneesParticulieres (... ");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
// lecture de la loi d'évolution du coefficient en fonction de la température
*(entreePrinc->entree) >> nom;
// on regarde si la courbe existe, si oui on récupère la référence
if (lesCourbes1D.Existe(nom))
{ lambda_temperature = lesCourbes1D.Trouve(nom);
}
else
{ // sinon il faut la lire maintenant
string non_courbe("_");
lambda_temperature = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
// lecture de la courbe
lambda_temperature->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
}
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
}
else
{ // lecture du coefficient
*(entreePrinc->entree) >> lambda ;
};
// ---------- lecture de la capacité calorifique
*(entreePrinc->entree) >> nom;
if (nom != "cp=")
{ cout << "\n erreur en lecture de la capacite calorifique, on attendait le mot cle cp=";
entreePrinc->MessageBuffer("**erreur7** Loi_de_Tait::LectureDonneesParticulieres (... ");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
// on regarde si le coeff est thermo dépendant
if(strstr(entreePrinc->tablcar,"cp_thermo_dependant_")!=0)
{ thermo_dependant=true;
*(entreePrinc->entree) >> nom;
if (nom != "cp_thermo_dependant_")
{ cout << "\n erreur en lecture de la thermodependance, on aurait du lire le mot cle cp_thermo_dependant_"
<< " suivi du nom d'une courbe de charge ou de la courbe elle meme ";
entreePrinc->MessageBuffer("**erreur8** Loi_de_Tait::LectureDonneesParticulieres (... ");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
// lecture de la loi d'évolution du coefficient en fonction de la température
*(entreePrinc->entree) >> nom;
// on regarde si la courbe existe, si oui on récupère la référence
if (lesCourbes1D.Existe(nom))
{ cp_temperature = lesCourbes1D.Trouve(nom);
}
else
{ // sinon il faut la lire maintenant
string non_courbe("_");
cp_temperature = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
// lecture de la courbe
cp_temperature->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
}
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
}
else
{ // lecture du coefficient
*(entreePrinc->entree) >> cp ;
};
// lecture éventuelle du paramètre sortie_post
if(strstr(entreePrinc->tablcar,"prepa_sortie_post=")!=0)
{*(entreePrinc->entree) >> nom >> sortie_post;
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
}
else
{entreePrinc->NouvelleDonnee(); }; // prepa du flot de lecture
// lecture éventuelle de la cristalinité
if(strstr(entreePrinc->tablcar,"type_de_calcul_=")!=0)
{*(entreePrinc->entree) >> nom >> type_de_calcul;
if (type_de_calcul != 0)
{ // lecture de loi de cristalinité
string non_crista;
*(entreePrinc->entree) >> nom >> non_crista;
// on crée la loi
crista = CristaliniteAbstraite::New_Cristalinite(Id_nom_Enum_crista(non_crista.c_str()));
// on lit les données spécifiques à la loi
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
crista->LectureDonneesLoiCrista(entreePrinc,lesCourbes1D,lesFonctionsnD);
}
else
while (strstr(entreePrinc->tablcar,"fin_loi_tait")==0)
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
};
// prepa du flot de lecture
if(strstr(entreePrinc->tablcar,"fin_loi_tait")!=0)
{entreePrinc->NouvelleDonnee(); }
else
{ cout << "\n erreur on ne trouve pas le mot cle fin_loi_tait, verifiez les donnes de la loi !";
entreePrinc->MessageBuffer("**erreur9** Loi_de_Tait::LectureDonneesParticulieres (... ");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
};
// affichage de la loi
void Loi_de_Tait::Affiche() const
{ cout << " \n loi de comportement thermique isotrope avec le comportement d'etat de Tait ";
cout << "\n b1s= " << b1s << " b2s= " << b2s << " b3s= " << b3s << " b4s= " << b4s << " "
<< "\n b1m= " << b1m << " b2m= " << b2m << " b3m= " << b3m << " b4m= " << b4m << " "
<< "\n b5= " << b5 << " b6= " << b6 << " b7= " << b7 << " b8= " << b8 << " b9= " << b9 << " \n";
if ( lambda_temperature != NULL) { cout << " conductivite thermo dependante "
<< " courbe lambda=f(T): " << lambda_temperature->NomCourbe() <<" ";}
else { cout << " conductivite lambda= " << lambda ;}
if ( cp_temperature != NULL) { cout << " capacite calorifique thermo dependante "
<< " courbe cp=f(T): " << cp_temperature->NomCourbe() <<" ";}
else { cout << " capacite calorifique cp= " << cp ;}
cout << " \n prepa_sortie_post=" << sortie_post << " ";
if (type_de_calcul != 0)
{ cout << "\n calcul avec cristalinite: type_de_calcul= " << type_de_calcul;
crista->Affiche();
};
cout << endl;
};
// affichage et definition interactive des commandes particulières à chaques lois
void Loi_de_Tait::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");
if (lambda == 0.) { lambda = 10.;}; // on initialise à une valeur arbitraire
if (cp == 0.) { cp = 1.;}; // on initialise à une valeur arbitraire
sort << "\n#-------- debut cas d'une loi thermo physique --------"
<< "\n \n poly_therm2 LOI_DE_TAIT ";
sort << "\n# ----- loi de comportement thermique isotrope avec le comportement d'etat de Tait ---------"
<< "\n# | la loi necessite 13 coefficients qui permettent le calcul du volume specifique Vspe |"
<< "\n# | Vspe = V0(T)*(1.-C*log(1.+P/B(T))) + Vt(T,P) avec les relations |"
<< "\n# | C = 0.0894, Ttrans = b5 + b6 * P |"
<< "\n# | si T < Ttrans: V0(T) = b1s+b2s*(T-b5), B(T) = b3s*exp(-b4s*(T-b5)) |"
<< "\n# | si T >= Ttrans: V0(T) = b1m+b2m*(T-b5), B(T) = b3m*exp(-b4m*(T-b5)) |"
<< "\n# | Vt(T,P) = b7*exp(-b8(T-b5)-b9*P) |"
<< "\n# | En fonction du volume specifique on obtient la masse volumique ro=1./ Vspe |"
<< "\n# | le coefficient de dilatation lineaire : alpha = 1./(3*ro) * d ro / d T |"
<< "\n# | et le coefficient de compressibilite: ksi = -1./ro * d ro / d p |"
<< "\n# ------------------------------------------------------------------------------------------";
sort << "\n# definition des coefficients "
<< "\n coefficients_bi "
<< "\n b1s= " << b1s << " b2s= " << b2s << " b3s= " << b3s << " b4s= " << b4s << " "
<< "\n b1m= " << b1m << " b2m= " << b2m << " b3m= " << b3m << " b4m= " << b4m << " "
<< "\n b5= " << b5 << " b6= " << b6 << " b7= " << b7 << " b8= " << b8 << " b9= " << b9 << " "
<< "\n # puis on definit la conductivite et la capacite calorifique \n";
sort << "\n# ......................................................."
<< "\n# | conductivite | capacite calorifique | "
<< "\n# | | | "
<< "\n# | lambda | cp | "
<< "\n#........................................................"
<< "\n lambda= " << setprecision(8) << lambda << " cp= " << setprecision(8) << cp << " ";
if ((rep != "o") && (rep != "O" ) && (rep != "0") )
{ sort << "\n# \n# chaque parametre peut etre remplace par une fonction dependante de la temperature "
<< "\n# pour ce faire on utilise un mot cle puis une nom de courbe ou la courbe directement comme avec "
<< "\n# les autre loi de comportement "
<< "\n# exemple pour la conductivite: mlambda= lambda_thermo_dependant_ courbe2 "
<< "\n# exemple pour la capacite calorifique: cp= cp_thermo_dependant_ courbe3 "
<< "\n# IMPORTANT: a chaque fois qu'il y a une thermodependence, il faut passer une ligne apres la description"
<< "\n# de la grandeur thermodependante, mais pas de passage a la ligne si se n'est pas thermo dependant "
<< "\n#"
<< "\n# ensuite une variable booleenne qui indique si oui ou non on sauvegarde des donnees intermediaires"
<< "\n# pour le post-traitement, pour ensuite pouvoir afficher : temperature de transition, volume specifique"
<< "\n# pression, dilatation, conditivité, capacite calorifique, coeff de compressibilite"
<< " prepa_sortie_post= 0 # valeur par defaut -> pas de sauvegarde "
<< "\n#"
<< "\n#---- prise en compte de la cristalinite ---------"
<< "\n# il est possible de tenir compte d'un tau de cristalinite de la maniere suivante: "
<< "\n# tout d'abord un indicateur (faculatatif) indiquant le type de calcul voulu, par defaut = 0"
<< "\n# type_de_calcul : =1 -> calcul du taux de cristalinite, mais pas de dependance des variables "
<< "\n# de ThermoDonnee(alpha, lambda, compressibilite) avec la cristalinite "
<< "\n# : =2 -> calcul du taux de cristalinité, avec dépendance des variables de ThermoDonnee "
<< "\n# Dans le cas ou le type_de_calcul n'est pas nul, il faut ensuite definir la methode de calcul de la cristalinite"
<< "\n# ex: pour la loi d'hoffman1 "
<< "\n type_de_calcul_= 2 Cristalinite_= HOFFMAN1 "
<< "\n#";
};
// appel de la cristalinité
crista->Info_commande_LoisCrista(entreePrinc);
// appel de la classe mère
CompThermoPhysiqueAbstraite::Info_commande_don_LoisDeComp(entreePrinc);
sort << "\n fin_loi_tait \n ";
if ((rep != "o") && (rep != "O" ) && (rep != "0") )
{ sort << "\n# la derniere ligne doit contenir uniquement le mot cle: fin_loi_tait ";};
sort << endl;
};
// test si la loi est complete
int Loi_de_Tait::TestComplet()
{ int ret = LoiAbstraiteGeneral::TestComplet();
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 Loi_de_Tait::Grandeur_particuliere
(bool absolue, List_io<TypeQuelconque>& liTQ,CompThermoPhysiqueAbstraite::SaveResul * saveDon,list<int>& )
{// on passe en revue la liste
List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end();
// on accède aux grandeurs que si sortie_post=true
if(sortie_post)
for (itq=liTQ.begin();itq!=itqfin;itq++)
{TypeQuelconque& tipParticu = (*itq); // pour simplifier
if (tipParticu.EnuTypeQuelconque().Nom_vide()) // veut dire que c'est un enum pur
{ EnumTypeQuelconque enuTQ = tipParticu.EnuTypeQuelconque().EnumTQ();
// 1) -----cas des contraintes individuelles à chaque loi à t et courantes
if (enuTQ == TEMPERATURE_LOI_THERMO_PHYSIQUE)
{ SaveResul_Loi_de_Tait & save_resul = *((SaveResul_Loi_de_Tait*) saveDon);
Grandeur_scalaire_double& tyTQ= *((Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
tyTQ=save_resul.stockParaInt->temperature;
}
else if (enuTQ == PRESSION_LOI_THERMO_PHYSIQUE)
{ SaveResul_Loi_de_Tait & save_resul = *((SaveResul_Loi_de_Tait*) saveDon);
Grandeur_scalaire_double& tyTQ= *((Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
tyTQ=save_resul.stockParaInt->pression;
}
else if ( (enuTQ == TEMPERATURE_TRANSITION)
|| (enuTQ == VOLUME_SPECIFIQUE)
|| (enuTQ == COEFF_DILATATION_LINEAIRE)
|| (enuTQ == CONDUCTIVITE)
|| (enuTQ == CAPACITE_CALORIFIQUE)
|| (enuTQ == COEFF_COMPRESSIBILITE)
|| (enuTQ == CRISTALINITE))
{ // dans ce cas il faut recalculer les grandeurs
SaveResul_Loi_de_Tait & save_resul = *((SaveResul_Loi_de_Tait*) saveDon);
Grandeur_scalaire_double& tyTQ= *((Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
// appel fonction interne
double& P=save_resul.stockParaInt->pression; // récup des valeurs sauvegardées
temperature = save_resul.stockParaInt->temperature; // "
double temp_trans;double vol_spec; // def des valeurs de sorties
// !! a priori on sort les valeurs pour tdt, car sinon ça ne fonctionne pas pour l'instant
Calcul_diff_valeurs(P,temp_trans,vol_spec);
// choix pour les retours
if (enuTQ == TEMPERATURE_TRANSITION) {tyTQ=temp_trans;}
else if (enuTQ == VOLUME_SPECIFIQUE) {tyTQ=vol_spec;}
else if (enuTQ == COEFF_DILATATION_LINEAIRE) {tyTQ=alphaT;}
else if (enuTQ == CONDUCTIVITE) {tyTQ=lambda;}
else if (enuTQ == CAPACITE_CALORIFIQUE) {tyTQ=cp;}
else if (enuTQ == COEFF_COMPRESSIBILITE) {tyTQ=compressibilite;}
else if ((enuTQ == CRISTALINITE)
|| (crista != NULL)) {tyTQ=tyTQ = crista->Cristalinite(save_resul.saveCrista,P,temperature);}
// cout << "\n " << temp_trans <<" " << vol_spec << " " <<alphaT << " ";
};
};
};
};
// 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 Loi_de_Tait::ListeGrandeurs_particulieres(bool absolue,List_io<TypeQuelconque>& liTQ)
{Grandeur_scalaire_double grand_courant; // def d'une grandeur courante
// def d'un type quelconque représentatif à chaque grandeur
// a priori ces grandeurs sont défini aux points d'intégration identique à la contrainte par exemple
// enu_ddl_type_pt est définit dans la loi Abtraite générale
// on n'ajoute que si sortie_post est vraie, sinon aucune grandeur n'est sauvegardé, donc on ne peut
// plus y accèder
if(sortie_post)
{// a) $$$ cas de TEMPERATURE_LOI_THERMO_PHYSIQUE
{TypeQuelconque typQ1(TEMPERATURE_LOI_THERMO_PHYSIQUE,enu_ddl_type_pt,grand_courant);
liTQ.push_back(typQ1);
};
// b) $$$ cas de PRESSION_LOI_THERMO_PHYSIQUE
{TypeQuelconque typQ2(PRESSION_LOI_THERMO_PHYSIQUE,enu_ddl_type_pt,grand_courant);
liTQ.push_back(typQ2);
};
// c) $$$ cas de TEMPERATURE_TRANSITION
{TypeQuelconque typQ3(TEMPERATURE_TRANSITION,enu_ddl_type_pt,grand_courant);
liTQ.push_back(typQ3);
};
// d) $$$ cas de VOLUME_SPECIFIQUE
{TypeQuelconque typQ4(VOLUME_SPECIFIQUE,enu_ddl_type_pt,grand_courant);
liTQ.push_back(typQ4);
};
// e) $$$ cas de COEFF_DILATATION_LINEAIRE
{TypeQuelconque typQ5(COEFF_DILATATION_LINEAIRE,enu_ddl_type_pt,grand_courant);
liTQ.push_back(typQ5);
};
// f) $$$ cas de CONDUCTIVITE
{TypeQuelconque typQ6(CONDUCTIVITE,enu_ddl_type_pt,grand_courant);
liTQ.push_back(typQ6);
};
// g) $$$ cas de CAPACITE_CALORIFIQUE
{TypeQuelconque typQ7(CAPACITE_CALORIFIQUE,enu_ddl_type_pt,grand_courant);
liTQ.push_back(typQ7);
};
// h) $$$ cas de COEFF_COMPRESSIBILITE
{TypeQuelconque typQ8(COEFF_COMPRESSIBILITE,enu_ddl_type_pt,grand_courant);
liTQ.push_back(typQ8);
};
// i) $$$ cas de CRISTALINITE
if (crista != NULL)
{TypeQuelconque typQ8(CRISTALINITE,enu_ddl_type_pt,grand_courant);
liTQ.push_back(typQ8);
};
}; //-- fin du cas sortie_post=true
};
//----- 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 Loi_de_Tait::Lecture_base_info_loi(ifstream& ent,const int cas,LesReferences& lesRef,LesCourbes1D& lesCourbes1D
,LesFonctions_nD& lesFonctionsnD)
{ string nom; bool test;
if (cas == 1)
{ ent >> nom;
if (nom != "LOI_DE_TAIT")
{ cout << "\n erreur en lecture de la loi : LOI_DE_TAIT, on attendait le mot cle : LOI_DE_TAIT "
<< "\n Loi_de_Tait::Lecture_base_info_loi(...";
Sortie(1);
};
// lecture des coefficients bi
ent >> nom >> b1s >> nom >> b2s >> nom >> b3s >> nom >> b4s;
ent >> nom >> b1m >> nom >> b2m >> nom >> b3m >> nom >> b4m;
ent >> nom >> b5 >> nom >> b6 >> nom >> b7 >> nom >> b8 >> nom >> b9 ;
// lambda
ent >> nom >> test;
if (!test)
{ ent >> lambda;
if (lambda_temperature != NULL)
{if (lambda_temperature->NomCourbe() == "_") delete lambda_temperature; lambda_temperature = NULL;};
}
else
{ ent >> nom; lambda_temperature = lesCourbes1D.Lecture_pour_base_info(ent,cas,lambda_temperature); };
// cp
ent >> nom >> test;
if (!test)
{ ent >> cp;
if (cp_temperature != NULL)
{if (cp_temperature->NomCourbe() == "_") delete cp_temperature; cp_temperature = NULL;};
}
else
{ ent >> nom; cp_temperature = lesCourbes1D.Lecture_pour_base_info(ent,cas,cp_temperature); };
// cas du post-traitement
ent >> nom >> sortie_post ;
// cas de la cristalinité
ent >> nom >> type_de_calcul;
if (type_de_calcul != 0)
{ Enum_crista enuCrista;
ent >> nom >> enuCrista;
// création s'il le faut de l'instance de calcul de la cristalinité
if (crista != NULL)
{ // cas où une instance existe déjà
if (crista->Type_Crista() != enuCrista)
{ // cas où l'instance n'est pas a doc
delete crista;
// on crée une loi conforme
crista = CristaliniteAbstraite::New_Cristalinite(enuCrista);
};
}
else // sinon l'instance n'existe pas, il faut donc la créer
{ crista = CristaliniteAbstraite::New_Cristalinite(enuCrista);
};
// on lit les données spécifiques à la loi
crista->Lecture_don_base_info(ent,cas,lesCourbes1D,lesFonctionsnD);
};
}
CompThermoPhysiqueAbstraite::Lecture_don_base_info(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD);
};
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void Loi_de_Tait::Ecriture_base_info_loi(ofstream& sort,const int cas)
{ if (cas == 1)
{ sort << " LOI_DE_TAIT " ;
sort << "\n b1s= " << b1s << " b2s= " << b2s << " b3s= " << b3s << " b4s= " << b4s << " "
<< "\n b1m= " << b1m << " b2m= " << b2m << " b3m= " << b3m << " b4m= " << b4m << " "
<< "\n b5= " << b5 << " b6= " << b6 << " b7= " << b7 << " b8= " << b8 << " b9= " << b9 << " \n";
sort << "\n lambda= ";
if (lambda_temperature == NULL)
{ sort << false << " " << lambda << " ";}
else
{ sort << true << " fonction_lambda_temperature ";
LesCourbes1D::Ecriture_pour_base_info(sort,cas,lambda_temperature);
};
sort << "\n cp= ";
if (cp_temperature == NULL)
{ sort << false << " " << cp << " ";}
else
{ sort << true << " fonction_cp_temperature ";
LesCourbes1D::Ecriture_pour_base_info(sort,cas,cp_temperature);
};
// cas du post-traitement
sort << "\n prepa_sortie_post= " << sortie_post << " ";
// cas de la cristalinité
sort << "\n type_de_calcul= " << type_de_calcul;
if (type_de_calcul != 0)
{ sort << " id_crista= " << crista->Type_Crista() << " ";
crista->Ecriture_don_base_info(sort,cas);
};
}
// appel de la classe mère
CompThermoPhysiqueAbstraite::Ecriture_don_base_info(sort,cas);
};
// ========== codage des METHODES VIRTUELLES :================
// ramène les données thermiques défnies au point
// P: la pression à l'énuméré temps, et P_t la pression au temps t
// taux_cris n'est calculé que si crista est non NULL
void Loi_de_Tait::Cal_donnees_thermiques(const double& P_t,CompThermoPhysiqueAbstraite::SaveResul * saveDon
,const Deformation & def,const double& P_e,Enum_dure temps, ThermoDonnee& donneeThermique)
{ saveResul = saveDon; // association pour les méthodes dérivées
// calcul de la température
temperature = def.DonneeInterpoleeScalaire(TEMP,temps);
double temperature_t = NULL; // par défaut
if (crista != NULL)
{if (temps == TEMPS_tdt)
{ // dans ce cas on doit disposer des températures et pression à t
temperature_t = def.DonneeInterpoleeScalaire(TEMP,TEMPS_t);
}
else // on prend la température déjà calculée (car c'est o ou t)
{ temperature_t = temperature;}
};
// 1) récup de la pression
double P = P_e;
// l'idée est que les lois de tait ne sont plausibles que pour des pressions positives.
// or pendant des itérations de Newton, au niveau de l'équilibre global, on peut avoir l'apparition
// de condition non physique qui conduisent à des pressions (relatives) négatives, dans ce cas
// on met la pression à 0 (on limite la pression)
if (P < 0.) P = 0.;
// appel fonction interne
double temp_trans;double vol_spec;
double taux_cris = 0.;
Calcul_diff_valeurs(P,temp_trans,vol_spec);
// la cristalinité indépendante si nécessaire
if (crista != NULL)
{ Loi_de_Tait::SaveResul_Loi_de_Tait* saveRes = ((Loi_de_Tait::SaveResul_Loi_de_Tait*) saveResul);
taux_cris = crista->Cristalinite(P_t,temperature_t,saveRes->saveCrista,P,temperature,temps);
};
// retour des données thermiques
donneeThermique.ChangeAlphaTLambdaCp(alphaT,lambda,cp);
donneeThermique.ChangeCompressibilite(compressibilite);
// la cristalinité si nécessaire
if (crista != NULL)
donneeThermique.ChangeTauxCrista(taux_cris);
// les données particulière a enregistrer si nécessaire
if(sortie_post)
{ SaveResul_Loi_de_Tait & save_resul = *((SaveResul_Loi_de_Tait*) saveDon);
save_resul.stockParaInt->pression=P;
save_resul.stockParaInt->temperature=temperature;
};
};
// remontée aux différentes variables
// taux_cris n'est calculé que si crista est non NULL
void Loi_de_Tait::Calcul_diff_valeurs(const double& P, double& temp_trans, double & vol_spec)
{ double T=temperature; // pour simplifier les notations pour la suite
// maintenant on s'occupe du calcul du volume spécifique
// 1) calcul de la température de transition
const double C=0.0894;double v0T,bT,der_v0T_T,der_bT_T;
temp_trans=b5+b6*P;
// init à 0, correspond au cas où l'on est haut dessus de la température
// de transition
double vT=0.; double der_vT_T = 0.; double der_vT_P = 0.;
if (temperature < temp_trans)
{v0T = b1s+b2s*(T-b5);
der_v0T_T = b2s;
bT = b3s*exp(-b4s*(T-b5));
der_bT_T = -b4s*b3s*exp(-b4s*(T-b5));
// ici les termes suivants sont non nuls
vT=b7*exp(-b8*(T-b5)-b9*P);
der_vT_T = -b8*b7*exp(-b8*(T-b5)-b9*P);
der_vT_P = -b9*b7*exp(-b8*(T-b5)-b9*P);
}
else
{v0T = b1m+b2m*(T-b5);
der_v0T_T = b2m;
bT = b3m*exp(-b4m*(T-b5));
der_bT_T = -b4s*b3s*exp(-b4s*(T-b5));
};
// si l'on voulait limiter les pressions négatives on pourrait par exemple prendre une fonction du type
// ((tanh(P+beta)+1)/2)*P : tend vers P lorsque P>-beta
#ifdef MISE_AU_POINT
if ( Abs(bT) <= ConstMath::trespetit)
{ cout << "\n erreur le coef B(T) de la loi de Tait est egal a zero " << bT
<< " il y aura des divisions par zero donc arret ! ";
Sortie(1);
}
#endif
// 3) le volume spécifique (l'inverse de la masse volumique)
double unPlusPsurbT = 1.+P/bT;
#ifdef MISE_AU_POINT
if ( unPlusPsurbT <= 0.)
{ cout << "\n erreur dans la loi de Tait 1.+P/bT est <= a zero " << unPlusPsurbT
<< " on ne peut pas calculer son log donc arret ! " << " P= " << P << ", bT= " << bT;
Sortie(1);
}
#endif
#ifdef MISE_AU_POINT
if ( Abs(unPlusPsurbT) <= ConstMath::trespetit)
{ cout << "\n erreur dans la loi de Tait 1.+P/bT est nulle " << unPlusPsurbT
<< " il y aura des divisions par zero donc arret ! ";
Sortie(1);
}
#endif
vol_spec = v0T*(1.- C*log(unPlusPsurbT)) + vT;
#ifdef MISE_AU_POINT
if ( Abs(vol_spec) <= ConstMath::trespetit)
{ cout << "\n erreur dans la loi de Tait le volume specifique est nulle " << vol_spec
<< " il y aura des divisions par zero donc arret ! ";
Sortie(1);
}
#endif
// 2) la variation par rapport à T
double der_vol_spec_T = der_v0T_T*(1.- C*log(unPlusPsurbT)) + der_vT_T
+ v0T * (C*(1./unPlusPsurbT)*(- der_bT_T)/(bT*bT));
// 3) la variation de la masse volumique
double der_ro_T = - der_vol_spec_T/(vol_spec*vol_spec);
// 4) calcul du coefficient de dilatation linéaire
alphaT = (- der_ro_T * vol_spec)/3.; // divisé par 3 pour avoir le coefficient de dilatation linéaire
// et non volumique
// calcul des deux autres coefficients
if (lambda_temperature != NULL) {lambda= lambda_temperature->Valeur(temperature);}
if (cp_temperature != NULL) {cp= cp_temperature->Valeur(temperature);}
// 5) calcul de la compressibilité
// 5-1) variation par rapport à P
double der_vol_spec_P = v0T * (-C/(P+bT))+der_vT_P;
// 5-2) compressibilité
compressibilite = - der_vol_spec_P/v0T;
};
// calcul du flux et ses variations par rapport aux ddl a t+dt: stockage dans ptIntegThermi et dans d_flux
// calcul également des paramètres thermiques dTP ainsi que des énergies mises en jeux
// calcul des énergies thermiques
// en entrée: température, gradient de temp, et grandeurs associées, métrique
void Loi_de_Tait::Calcul_DfluxH_tdt
(const double & P_t,PtIntegThermiInterne& ptIntegThermi, const double & P,DdlElement & tab_ddl
,const Deformation & def // prévue pour servir pour l'interpolation
, Tableau <CoordonneeB >& d_gradTB,Tableau <CoordonneeH >& d_flux,ThermoDonnee& dTP
,EnergieThermi & energ,const EnergieThermi & energ_t,const Met_abstraite::Impli& ex)
{ cout << "\n *** erreur, methode non implantee actuellement: "
<< "\n Loi_de_Tait::Calcul_DfluxH_tdt(.. "<<endl;
Sortie(1);
};