// 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) . // // 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 . // // For more information, please consult: . //#include "Debug.h" # include using namespace std; //introduces namespace std #include #include #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& liTQ,CompThermoPhysiqueAbstraite::SaveResul * saveDon,list& ) {// on passe en revue la liste List_io::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 << " " <& 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 & d_gradTB,Tableau & 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(.. "<