211 lines
10 KiB
C++
211 lines
10 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-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 <https://www.gnu.org/licenses/>.
|
|
//
|
|
// For more information, please consult: <https://herezh.irdl.fr/>.
|
|
|
|
#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<Noeud *>& 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 <CoordonneeB >& 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 <CoordonneeB >& d_gradTB
|
|
,Tableau <CoordonneeH >& 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
|
|
};
|
|
|