// 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 "CompThermoPhysiqueAbstraite.h" #include "ExceptionsLoiComp.h" // CONSTRUCTEURS : CompThermoPhysiqueAbstraite::CompThermoPhysiqueAbstraite () : // Constructeur par defaut LoiAbstraiteGeneral(),saveResul(NULL),comp_tangent_simplifie(false) ,thermo_dependant(false),temperature(-1.) { }; // Constructeur utile si l'identificateur du nom de la loi // de comportement et la dimension sont connus CompThermoPhysiqueAbstraite::CompThermoPhysiqueAbstraite (Enum_comp id_compor,Enum_categorie_loi_comp id_categorie ,int dimension) : LoiAbstraiteGeneral(id_compor,dimension,id_categorie) ,saveResul(NULL),comp_tangent_simplifie(false) ,thermo_dependant(false),temperature(-1) { }; // Constructeur utile si l'identificateur du nom de la loi // de comportement et la dimension sont connus CompThermoPhysiqueAbstraite::CompThermoPhysiqueAbstraite (char* nom,Enum_categorie_loi_comp id_categorie ,int dimension) : LoiAbstraiteGeneral(nom,dimension,id_categorie) ,saveResul(NULL),comp_tangent_simplifie(false) ,thermo_dependant(false),temperature(-1) { }; // Constructeur de copie CompThermoPhysiqueAbstraite::CompThermoPhysiqueAbstraite (const CompThermoPhysiqueAbstraite & a ) : LoiAbstraiteGeneral(a),comp_tangent_simplifie(false) ,saveResul(a.saveResul->Nevez_SaveResul()) ,thermo_dependant(a.thermo_dependant),temperature(-1) {} ; // DESTRUCTEUR VIRTUEL : CompThermoPhysiqueAbstraite::~CompThermoPhysiqueAbstraite () { }; // =============== methode de calcul ====================== // activation des données des noeuds et/ou elements nécessaires au fonctionnement de la loi // exemple: mise en service des ddl de température aux noeuds // méthode appelée par Activation_donnees principal, ou des classes dérivées void CompThermoPhysiqueAbstraite::Activ_donnees(Tableau& tabnoeud) { if (thermo_dependant) { // dans le cas où la loi est thermo dépendante on active les ddl de thermique int nbnoeud = tabnoeud.Taille(); for (int i=1;i<=nbnoeud;i++) { // on vérifie que la variable TEMP existe sinon erreur if (tabnoeud(i)->Existe_ici(TEMP)) {tabnoeud(i)->Met_en_service(TEMP);} else { cout << "\n erreur: la variable temperature n'existe pas " << " il n'est pas possible d'utiliser une loi thermodependante " << " il manque sans doute des donnees !!! " << "\n CompThermoPhysiqueAbstraite::Activ_donnees(..."; Sortie(1); } } } }; // calcul de toutes les grandeurs associées à la température (mais pas le flux), qui sont stockées // dans le point d'intégration : ptIntegThermi void CompThermoPhysiqueAbstraite::Cal_cinematique_thermique (bool premier_calcul,PtIntegThermiInterne& ptIntegThermi ,Tableau & d_gradTB ,Deformation & def, const Met_abstraite::Impli& ex) { // calcul de la température au point d'intégration if (premier_calcul) { // calcul de la température initiale interpolée saveResul->temperature_0 = def.DonneeInterpoleeScalaire(TEMP,TEMPS_0); ptIntegThermi.Temperature_t() = def.DonneeInterpoleeScalaire(TEMP,TEMPS_t); } ptIntegThermi.Temperature() = temperature = def.DonneeInterpoleeScalaire(TEMP,TEMPS_tdt); // calcul du gradient thermique au temps actuel et au temps t CoordonneeB interB(ptIntegThermi.GradTB()); // un vecteur de travail def.GradDonneeInterpoleeScalaire(interB,TEMP,TEMPS_t); def.GradDonneeInterpoleeScalaire(ptIntegThermi.GradTB(),TEMP,TEMPS_tdt); ptIntegThermi.DeltaGradTB() = ptIntegThermi.GradTB() - interB; // -- cas de la vitesse du gradient // recup de l'incrément de temps double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant(); double unSurDeltat=0; if (Abs(deltat) >= ConstMath::trespetit) { unSurDeltat = 1./deltat;} else // si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand { // un pas de temps doit être positif !! or certaine fois il peut y avoir des pb if (unSurDeltat < 0) { cout << "\n le pas de temps est négatif !! "; }; unSurDeltat = ConstMath::tresgrand; }; ptIntegThermi.DgradTB() = ptIntegThermi.DeltaGradTB() * unSurDeltat; // la variation du gradient / au ddl de thermique def.DerGradDonneeInterpoleeScalaire(d_gradTB,TEMP); // les invariants: ptIntegThermi.Norme_gradT() = ptIntegThermi.GradTB() * (*ex.gijHH_tdt) * ptIntegThermi.GradTB(); ptIntegThermi.Norme_DGradT() = ptIntegThermi.DgradTB() * (*ex.gijHH_tdt) * ptIntegThermi.DgradTB(); }; // schema implicit // P et P_t : pression actuelle et pression à t const Met_abstraite::Impli& CompThermoPhysiqueAbstraite::Cal_implicit (const double & P_t,CompThermoPhysiqueAbstraite::SaveResul * saveTP , const double & P,Deformation & def,DdlElement & tab_ddl ,PtIntegThermiInterne& ptIntegThermi, Tableau & d_gradTB ,Tableau & d_fluxH,const ParaAlgoControle & pa ,CompThermoPhysiqueAbstraite* loiTP ,bool dilat,EnergieThermi & energ,const EnergieThermi & energ_t,bool premier_calcul ) { Temps_CPU_HZpp& temps_cpu_loi = ptIntegThermi.Tps_cpu_loi_comp(); temps_cpu_loi.Mise_en_route_du_comptage(); // spécifique pti temps_loi.Mise_en_route_du_comptage(); // spécifique loi // passage des infos specifiques aux classes derivantes saveResul = saveTP ; // récup des flux et gradients /* CoordonneeH & fluxH = (ptIntegThermi.FluxH()); // ici _tdt est la grandeur finale CoordonneeH & fluxH_t = (ptIntegThermi.FluxH_t()); // ici _tdt est la grandeur finale CoordonneeB & gradTB_tdt = (ptIntegThermi.GradTB()); CoordonneeB & DgradTB_ = (ptIntegThermi.DgradTB()); CoordonneeB & delta_gradTB = (ptIntegThermi.DeltaGradTB()); // dilatation=dilat; // pour l'instant je ne sais pas si c'est utile */ // calcul de : epsBB_tdt, delta_epsBB,gijBB_tdt, gijHH_tdt, d_gijBB_tdt, // d_gijHH_tdt,jacobien,d_jacobien_tdt Temps_CPU_HZpp& temps_cpu_metrique = ptIntegThermi.TpsMetrique(); temps_cpu_metrique.Mise_en_route_du_comptage(); // cpu // bool calcul_varD_ddl = false;// a priori on ne veut pas de vitesse de def // appel de la métrique pour un calcul autre que mécanique // bool avec_var_Xi = false; const Met_abstraite::Impli& ex = def.Cal_implicit(premier_calcul,false); temps_cpu_metrique.Arret_du_comptage(); // cpu // calcul des grandeurs associées à la température (mais pas le flux), qui sont stockées // dans le point d'intégration // calcul de toutes les grandeurs associées à la température (mais pas le flux), qui sont stockées // dans le point d'intégration : ptIntegThermi // et de la variation du gradient thermique / au ddl Cal_cinematique_thermique(premier_calcul,ptIntegThermi,d_gradTB,def,ex); // // demande dans les classes dérivées du calcul de grandeurs spécifiques si besoin est // ThermoDonnee dTP; // init à 0 par défaut // loiTP->Cal_donnees_thermiques(P_t,saveTP,def,P,TEMPS_tdt,dTP); // demande dans les classes dérivées du calcul de grandeurs spécifiques si besoin est CalculGrandeurTravail(ptIntegThermi,def,TEMPS_tdt); // calcul du flux et de sa variation / aux ddl, calcul également des paramètres thermiques dTP // ainsi que des énergies mises en jeux ThermoDonnee dTP; // init à 0 par défaut // on gère les exceptions éventuelles en mettant le bloc sous surveillance try { Calcul_DfluxH_tdt(P_t,ptIntegThermi,P,tab_ddl,def, d_gradTB, d_fluxH,dTP, energ, energ_t,ex); } catch (ErrSortieFinale) // cas d'une direction voulue vers la sortie // on relance l'interuption pour le niveau supérieur { ErrSortieFinale toto; throw (toto); } catch ( ... ) // cas d'une erreur dans la recherche de la contrainte { throw ErrNonConvergence_loiDeComportement(); if (ParaGlob::NiveauImpression() >= 1) {cout << "\n warning: exception generee par la loi de comportement "; if (ParaGlob::NiveauImpression() >= 4) cout << "\n Loi_comp_abstraite::Cal_implicit(.."; }; }; temps_cpu_loi.Arret_du_comptage(); // cpu spécifique pti temps_loi.Arret_du_comptage(); // cpu spécifique loi // retour return ex; // retour de la métrique };