// 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-2021 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
};