Herezh_dev/herezh_pp/comportement/Loi_comp_abstraite.cc

3788 lines
195 KiB
C++
Executable file

// 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 "Loi_comp_abstraite.h"
#include "Def_Umat.h"
#include "ExceptionsLoiComp.h"
#include "Util.h"
#include "TypeQuelconqueParticulier.h"
#include "CharUtil.h"
#include "TypeConsTens.h"
// CONSTRUCTEURS :
Loi_comp_abstraite::Loi_comp_abstraite () : // Constructeur par defaut
LoiAbstraiteGeneral(),saveResul(NULL),comp_tangent_simplifie(false)
,utilise_vitesse_deformation(false),type_de_deformation(DEFORMATION_STANDART)
,thermo_dependant(false),temperature_tdt(-1.),temperature_0(-1.),temperature_t(-1.)
,temperature(NULL),dilatation(false),def_en_cours(NULL)
,temps_loi()
,epsBB_totale(NULL),epsBB_therm(NULL)
,DepsBB_totale(NULL),DepsBB_therm(NULL),DepsBB_umat(NULL)
,listQuelc_mis_en_acces_localement(),listdeTouslesQuelc_dispo_localement()
,ptintmeca_en_cours(NULL),permet_affich_loi(0)
,permet_affich_loi_nD(NULL),li_quelconque(),tab_pt_li_quelconque()
{ };
// Constructeur utile si l'identificateur du nom de la loi
// de comportement et la dimension sont connus
Loi_comp_abstraite::Loi_comp_abstraite (Enum_comp id_compor,Enum_categorie_loi_comp categorie_comp
,int dimension,bool vit_def) :
LoiAbstraiteGeneral(id_compor,dimension,categorie_comp)
,saveResul(NULL),comp_tangent_simplifie(false)
,utilise_vitesse_deformation(vit_def),type_de_deformation(DEFORMATION_STANDART)
,thermo_dependant(false),temperature_tdt(-1.),temperature_0(-1.),temperature_t(-1.)
,temperature(NULL),dilatation(false),def_en_cours(NULL)
,temps_loi()
,epsBB_totale(NULL),epsBB_therm(NULL)
,DepsBB_totale(NULL),DepsBB_therm(NULL),DepsBB_umat(NULL)
,listQuelc_mis_en_acces_localement(),listdeTouslesQuelc_dispo_localement()
,ptintmeca_en_cours(NULL),permet_affich_loi(0)
,permet_affich_loi_nD(NULL),li_quelconque(),tab_pt_li_quelconque()
{ };
// Constructeur utile si l'identificateur du nom de la loi
// de comportement et la dimension sont connus
Loi_comp_abstraite::Loi_comp_abstraite (char* nom,Enum_categorie_loi_comp categorie_comp
,int dimension,bool vit_def) :
LoiAbstraiteGeneral(nom,dimension,categorie_comp)
,saveResul(NULL),comp_tangent_simplifie(false)
,utilise_vitesse_deformation(vit_def),type_de_deformation(DEFORMATION_STANDART)
,thermo_dependant(false),temperature_tdt(-1.),temperature_0(-1.),temperature_t(-1.)
,temperature(NULL),dilatation(false),def_en_cours(NULL)
,temps_loi()
,epsBB_totale(NULL),epsBB_therm(NULL)
,DepsBB_totale(NULL),DepsBB_therm(NULL),DepsBB_umat(NULL)
,listQuelc_mis_en_acces_localement(),listdeTouslesQuelc_dispo_localement()
,ptintmeca_en_cours(NULL),permet_affich_loi(0)
,permet_affich_loi_nD(NULL),li_quelconque(),tab_pt_li_quelconque()
{ };
// Constructeur de copie
Loi_comp_abstraite::Loi_comp_abstraite (const Loi_comp_abstraite & a ) :
LoiAbstraiteGeneral(a),comp_tangent_simplifie(false)
,utilise_vitesse_deformation(a.utilise_vitesse_deformation)
// ,saveResul(a.saveResul->Nevez_SaveResul()),type_de_deformation(a.type_de_deformation)
,saveResul(a.saveResul),type_de_deformation(a.type_de_deformation)
,thermo_dependant(a.thermo_dependant),dilatation(a.dilatation)
,def_en_cours(a.def_en_cours)
,temps_loi(a.temps_loi)
,temperature_tdt(-1.),temperature_0(-1.),temperature_t(-1.),temperature(NULL)
,epsBB_totale(NULL),epsBB_therm(NULL)
,DepsBB_totale(NULL),DepsBB_therm(NULL),DepsBB_umat(NULL)
,listQuelc_mis_en_acces_localement(a.listQuelc_mis_en_acces_localement)
,listdeTouslesQuelc_dispo_localement(a.listdeTouslesQuelc_dispo_localement)
,ptintmeca_en_cours(NULL),permet_affich_loi(a.permet_affich_loi)
,permet_affich_loi_nD(a.permet_affich_loi_nD)
,li_quelconque(a.li_quelconque),tab_pt_li_quelconque()
{ // idem pour les fonctions nD
if (permet_affich_loi_nD != NULL)
{if (permet_affich_loi_nD->NomFonction() == "_")
{// comme il s'agit d'une fonction locale on la redéfinie (sinon pb lors du destructeur de loi)
string non_courbe("_");
permet_affich_loi_nD = Fonction_nD::New_Fonction_nD(*a.permet_affich_loi_nD);
};
// on s'occupe maintenant des stockages des grandeurs complètement quelconques
// qui seront nécessaire pour utiliser la fonction nD
// !! on considère que a.li_quelconque a bien été dimensionné en fonction de
// permet_affich_loi_nD, donc on ne fait que bien définir les pointeurs
if (li_quelconque.size())
{tab_pt_li_quelconque.Change_taille(li_quelconque.size());
List_io <TypeQuelconque >::iterator ili,ilifin = li_quelconque.end();
int i=1; // init
for (ili= li_quelconque.begin();ili != ilifin; ili++,i++)
tab_pt_li_quelconque(i) = &(*ili);
};
};
} ;
// DESTRUCTEUR VIRTUEL :
Loi_comp_abstraite::~Loi_comp_abstraite ()
{ if (epsBB_totale != NULL) delete epsBB_totale;
if (epsBB_therm != NULL) delete epsBB_therm;
if (DepsBB_totale != NULL) delete DepsBB_totale;
if (DepsBB_therm != NULL) delete DepsBB_therm;
if (DepsBB_umat != NULL) delete DepsBB_umat;
if (permet_affich_loi_nD != NULL)
if (permet_affich_loi_nD->NomFonction() == "_") delete permet_affich_loi_nD;
};
// =============== methode de calcul ======================
// définition du type de calcul de déformation sur une instance de déformation passée en paramètre
void Loi_comp_abstraite::Def_type_deformation(Deformation & def)
{ def.Change_type_de_deformation(type_de_deformation);
};
// schema de calcul explicite à t
const Met_abstraite::Expli& Loi_comp_abstraite::Cal_explicit_t
(Loi_comp_abstraite::SaveResul * saveDon
,Deformation & def,DdlElement & tab_ddl,PtIntegMecaInterne& ptintmeca,Tableau <TenseurBB *> & d_epsBB
,double& jacobien,CompThermoPhysiqueAbstraite::SaveResul * saveTP,CompThermoPhysiqueAbstraite* loiTP
,bool dilat,EnergieMeca & energ,const EnergieMeca & energ_t,bool premier_calcul
)
{
Temps_CPU_HZpp& temps_cpu_loi = ptintmeca.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 = saveDon;
def_en_cours = &def;
// récup des contraintes
TenseurHH & sigHH_t = *(ptintmeca.SigHH_t());
TenseurHH & sigHH = *(ptintmeca.SigHH());
TenseurBB & epsBB_t = *(ptintmeca.EpsBB());
TenseurBB & DepsBB_ = *(ptintmeca.DepsBB());
TenseurBB & DeltaEpsBB_ = *(ptintmeca.DeltaEpsBB());
double& module_compressibilite = ptintmeca.ModuleCompressibilite();
double& module_cisaillement = ptintmeca.ModuleCisaillement();
Tableau <double>& def_equi = ptintmeca.Deformation_equi();
const Tableau <double>& def_equi_t = ptintmeca.Deformation_equi_t_const();
dilatation=dilat;
ptintmeca_en_cours = &ptintmeca; // pour les méthodes internes
// calcul de : epsBB_t,gijBB_t, gijHH_t,d_epsBB,jacobien
Temps_CPU_HZpp& temps_cpu_metrique = ptintmeca.TpsMetrique();
temps_cpu_metrique.Mise_en_route_du_comptage(); // cpu
const Met_abstraite::Expli& ex = def.Cal_explicit_t(def_equi_t,epsBB_t,d_epsBB,def_equi,DepsBB_,DeltaEpsBB_,premier_calcul);
// on récupère les positions des points
if (premier_calcul)
{ptintmeca.M_0() = def.Position_0();
ptintmeca.M_t() = def.Position_t();
};
ptintmeca.M_tdt() = def.Position_tdt();
temps_cpu_metrique.Arret_du_comptage(); // cpu
// dans le cas d'une loi thermo dépendante, calcul de la température
if ((thermo_dependant) || dilatation)
{temperature_0 = def.DonneeInterpoleeScalaire(TEMP,TEMPS_0);
temperature_t = def.DonneeInterpoleeScalaire(TEMP,TEMPS_t);
temperature = &temperature_t;
};
// dans le cas ou l'on tiens compte de la dilatation on modifie les différents tenseurs de déformation
ThermoDonnee dTP; // init à 0 par défaut
if (dilatation)
{ // attention ici ça peut donner 0 car le pas précédent c'est peut-être 0
// comme on n'en sait rien on fait comme si il y a une valeur déjà enregistrée: pas terrible !!!
// vu que sigma suivant dépend de epsméca et que epsmeca dépend de sigma !!!
double P = -(sigHH_t * (*(ex.gijBB_t))).Trace()/Abs(sigHH_t.Dimension()); // calcul de la pression
loiTP->Cal_donnees_thermiques(P,saveTP,def,P,TEMPS_t,dTP);
// modification de la déformation mécanique et calcul de la déformation thermique
// a- dimensionnement des tenseurs intermédiaires qui pour l'instant ne servent qu'ici
int dim_tens = epsBB_t.Dimension();
// -- cas de la déformation
if (epsBB_totale == NULL) { epsBB_totale = NevezTenseurBB(dim_tens);}
else if (epsBB_totale->Dimension() != dim_tens) { delete epsBB_totale;epsBB_totale = NevezTenseurBB(dim_tens);};
*epsBB_totale = epsBB_t;
if (epsBB_therm == NULL) { epsBB_therm = NevezTenseurBB(dim_tens);}
else if (epsBB_therm->Dimension() != dim_tens) { delete epsBB_therm;epsBB_therm = NevezTenseurBB(dim_tens);};
// -- cas de la vitesse de déformation
if (DepsBB_totale == NULL) { DepsBB_totale = NevezTenseurBB(dim_tens);}
else if (DepsBB_totale->Dimension() != dim_tens) { delete DepsBB_totale;DepsBB_totale = NevezTenseurBB(dim_tens);};
*DepsBB_totale = DepsBB_;
if (DepsBB_therm == NULL) { DepsBB_therm = NevezTenseurBB(dim_tens);}
else if (DepsBB_therm->Dimension() != dim_tens) { delete DepsBB_therm;DepsBB_totale = NevezTenseurBB(dim_tens);};
// -- calcul du partage entre thermique et mécanique
bool avec_repercution_sur_def_meca = true;
def.DeformationThermoMecanique(temperature_0,*(ex.gijBB_t),dTP,*epsBB_totale
,*epsBB_therm,temperature_t,epsBB_t,temperature_t
,*DepsBB_totale,*DepsBB_therm,DepsBB_,false,avec_repercution_sur_def_meca);
};
if ((thermo_dependant) || dilatation) // répercussion éventuelle du changement de température dans les classes dérivées
{ RepercuteChangeTemperature(TEMPS_t); };
// calcul éventuel des invariants liés à la cinématique
CalculInvariants_cinematique(ptintmeca,*(ex.gijBB_t),*(ex.gijHH_t));
// demande dans les classes dérivées du calcul de grandeurs spécifiques si besoin est
// opération de transmission de la métrique
const Met_abstraite::Impli* ex_impli = NULL;
const Met_abstraite::Expli_t_tdt inter_ex_tdt = ex.T_dans_tdt();
const Met_abstraite::Expli_t_tdt* ex_expli_tdt = &inter_ex_tdt;
const Met_abstraite::Umat_cont* ex_expli = NULL;
CalculGrandeurTravail(ptintmeca,def,TEMPS_t,dTP,ex_impli,ex_expli_tdt,ex_expli,NULL,NULL);
// calcul de : sigHH
// on utilise la fonction qui calcul à t+dt en mettant les grandeur à t de l'appel idem ceux à t+dt
// pour l'instant (si pb on verra)
// on utilise lafonction T_dans_tdt pour passer avec une grandeur Expli_t_tdt au lieu de Expli
// c'est clair que ce n'est pas très cohérent, pour l'instant on laisse car cette fonction ne sert pas
// on gère les exceptions éventuelles en mettant le bloc sous surveillance
try
{ Calcul_SigmaHH (sigHH_t,DepsBB_,tab_ddl,*(ex.gijBB_t),*(ex.gijHH_t),*(ex.giB_t),*(ex.giH_t),
epsBB_t,DeltaEpsBB_,*(ex.gijBB_t),*(ex.gijHH_t),*(ex.d_gijBB_t),
(*ex.jacobien_0),(*ex.jacobien_t),sigHH,energ,energ_t
,module_compressibilite,module_cisaillement,ex.T_dans_tdt());
}
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_explicit_t(..";
};
jacobien = (*ex.jacobien_t);
// calcul éventuel des invariants de contraintes
CalculInvariants_contraintes(ptintmeca,*(ex.gijBB_t),*(ex.gijHH_t));
// en sortie il nous faut définir d_epsBB qui doit être égale à D*, donc pas forcément la dérivée
// de epsBB (par exemple dans le cas de la déformation logarithmique ou cumulée)
// variation de la déformation / au ddl
if (type_de_deformation != DEFORMATION_STANDART)
{ int d_epsBBTaille = d_epsBB.Taille();
for (int i=1; i<= d_epsBBTaille; i++)
*(d_epsBB(i)) = 0.5 * (*((*(ex.d_gijBB_t))(i)));
};
def_en_cours=NULL; // plus d'accès possible à la sortie
ptintmeca_en_cours = NULL; // plus d'accès possible à la sortie
temps_cpu_loi.Arret_du_comptage(); // cpu spécifique pti
temps_loi.Arret_du_comptage(); // cpu spécifique loi
return ex; // retour de la métrique
};
// schema de calcul explicite à tdt
const Met_abstraite::Expli_t_tdt& Loi_comp_abstraite::Cal_explicit_tdt
(Loi_comp_abstraite::SaveResul * saveDon,Deformation & def
,DdlElement & tab_ddl
,PtIntegMecaInterne& ptintmeca,Tableau <TenseurBB *> & d_epsBB,double& jacobien
,CompThermoPhysiqueAbstraite::SaveResul * saveTP,CompThermoPhysiqueAbstraite* loiTP
,bool dilat,EnergieMeca & energ,const EnergieMeca & energ_t,bool premier_calcul
)
{
Temps_CPU_HZpp& temps_cpu_loi = ptintmeca.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 = saveDon;
def_en_cours = &def;
// récup des contraintes
TenseurHH & sigHH = *(ptintmeca.SigHH()); // ici _tdt est la grandeur finale
TenseurHH & sigHH_t = *(ptintmeca.SigHH_t()); // ici _tdt est la grandeur finale
TenseurBB & epsBB_tdt = *(ptintmeca.EpsBB());
TenseurBB & DepsBB_ = *(ptintmeca.DepsBB());
TenseurBB & delta_epsBB = *(ptintmeca.DeltaEpsBB());
double& module_compressibilite = ptintmeca.ModuleCompressibilite();
double& module_cisaillement = ptintmeca.ModuleCisaillement();
Tableau <double>& def_equi = ptintmeca.Deformation_equi();
Tableau <double>& def_equi_t = ptintmeca.Deformation_equi_t();
dilatation=dilat;
ptintmeca_en_cours = &ptintmeca; // pour les méthodes internes
// calcul de : epsBB_t,gijBB_tdt, gijHH_tdt,d_epsBB,jacobien
Temps_CPU_HZpp& temps_cpu_metrique = ptintmeca.TpsMetrique();
temps_cpu_metrique.Mise_en_route_du_comptage(); // cpu
const Met_abstraite::Expli_t_tdt& ex = def.Cal_explicit_tdt(def_equi_t,epsBB_tdt,d_epsBB,def_equi,DepsBB_,delta_epsBB,premier_calcul);
// on récupère les positions des points
if (premier_calcul)
{ptintmeca.M_0() = def.Position_0();
ptintmeca.M_t() = def.Position_t();
};
ptintmeca.M_tdt() = def.Position_tdt();
temps_cpu_metrique.Arret_du_comptage(); // cpu
// dans le cas d'une loi thermo dépendante, calcul de la température
if ((thermo_dependant) || dilatation)
{temperature_0 = def.DonneeInterpoleeScalaire(TEMP,TEMPS_0);
temperature_t = def.DonneeInterpoleeScalaire(TEMP,TEMPS_t);
temperature_tdt = def.DonneeInterpoleeScalaire(TEMP,TEMPS_tdt);
temperature = &temperature_tdt;
};
// dans le cas ou l'on tiens compte de la dilatation on modifie les différents tenseurs de déformation
ThermoDonnee dTP; // init à 0 par défaut
if (dilatation)
{ // attention ici la seule valeur disponible est la contrainte du temps précédent
// donc pour des questions d'erreur de transport de la contrainte, on utilise également la métrique au pas précédent
double P = -(sigHH_t * (*(ex.gijBB_t))).Trace()/Abs(sigHH_t.Dimension()); // calcul de la pression
loiTP->Cal_donnees_thermiques(P,saveTP,def,P,TEMPS_tdt,dTP);
// modification de la déformation mécanique et calcul de la déformation thermique
// a- dimensionnement des tenseurs intermédiaires qui pour l'instant ne servent qu'ici
int dim_tens = epsBB_tdt.Dimension();
// -- cas de la déformation
if (epsBB_totale == NULL) { epsBB_totale = NevezTenseurBB(dim_tens);}
else if (epsBB_totale->Dimension() != dim_tens) { delete epsBB_totale;epsBB_totale = NevezTenseurBB(dim_tens);};
*epsBB_totale = epsBB_tdt;
if (epsBB_therm == NULL) { epsBB_therm = NevezTenseurBB(dim_tens);}
else if (epsBB_therm->Dimension() != dim_tens) { delete epsBB_therm;epsBB_therm = NevezTenseurBB(dim_tens);};
// -- cas de la vitesse de déformation
if (DepsBB_totale == NULL) { DepsBB_totale = NevezTenseurBB(dim_tens);}
else if (DepsBB_totale->Dimension() != dim_tens) { delete DepsBB_totale;DepsBB_totale = NevezTenseurBB(dim_tens);};
*DepsBB_totale = DepsBB_;
if (DepsBB_therm == NULL) { DepsBB_therm = NevezTenseurBB(dim_tens);}
else if (DepsBB_therm->Dimension() != dim_tens) { delete DepsBB_therm;DepsBB_totale = NevezTenseurBB(dim_tens);};
// -- calcul du partage entre thermique et mécanique
bool avec_repercution_sur_def_meca = true;
def.DeformationThermoMecanique(temperature_0,*(ex.gijBB_tdt),dTP,*epsBB_totale
,*epsBB_therm,temperature_tdt,epsBB_tdt,temperature_t
,*DepsBB_totale,*DepsBB_therm,DepsBB_,true,avec_repercution_sur_def_meca);
};
if ((thermo_dependant) || dilatation) // répercussion éventuelle du changement de température dans les classes dérivées
{ RepercuteChangeTemperature(TEMPS_tdt); };
// calcul éventuel des invariants liés à la cinématique
CalculInvariants_cinematique(ptintmeca,*(ex.gijBB_t),*(ex.gijHH_t));
// demande dans les classes dérivées du calcul de grandeurs spécifiques si besoin est
const Met_abstraite::Impli* ex_impli = NULL;
const Met_abstraite::Expli_t_tdt* ex_expli_tdt = &ex;
const Met_abstraite::Umat_cont* ex_expli = NULL;
CalculGrandeurTravail(ptintmeca,def,TEMPS_tdt,dTP,ex_impli,ex_expli_tdt,ex_expli,NULL,NULL);
// calcul de : sigHH
// on gère les exceptions éventuelles en mettant le bloc sous surveillance
try
{ Calcul_SigmaHH (sigHH_t,DepsBB_,tab_ddl,*(ex.gijBB_t),*(ex.gijHH_t),*(ex.giB_tdt),*(ex.giH_tdt),
epsBB_tdt,delta_epsBB,*(ex.gijBB_tdt),*(ex.gijHH_tdt),*(ex.d_gijBB_tdt),
(*ex.jacobien_0),(*ex.jacobien_tdt),sigHH,energ,energ_t
,module_compressibilite,module_cisaillement,ex);
//--- debug
//cout << "\n sigHH.MaxiComposante() "<<sigHH.MaxiComposante();
//if (sigHH.MaxiComposante() > 20.)
// { cout << "\n debug .... Loi_comp_abstraite::Cal_explicit_tdt "
// << "\n **** sigHH.MaxiComposante() > 20. ";
//
// TenseurBB* ptBB = NevezTenseurBB(epsBB_tdt);
// epsBB_tdt.BaseAbsolue(*ptBB,*(ex.giH_tdt));
// cout << "\n eps: ";
// ptBB->Ecriture(cout);
// delta_epsBB.BaseAbsolue(*ptBB,*(ex.giH_tdt));
// cout << "\n delta eps: ";
// ptBB->Ecriture(cout);
// TenseurHH* ptHH = NevezTenseurHH(sigHH);
// sigHH.BaseAbsolue(*ptHH,*(ex.giB_tdt));
// cout << "\n sigma: ";
// ptHH->Ecriture(cout);
// delete ptBB; delete ptHH;
//
//
// // on recalcule pour le debug le vecteur résidu
// Calcul_SigmaHH (sigHH_t,DepsBB_,tab_ddl,*(ex.gijBB_t),*(ex.gijHH_t),*(ex.giB_tdt),*(ex.giH_tdt),
// epsBB_tdt,delta_epsBB,*(ex.gijBB_tdt),*(ex.gijHH_tdt),*(ex.d_gijBB_tdt),
// (*ex.jacobien_0),(*ex.jacobien_tdt),sigHH,energ,energ_t
// ,module_compressibilite,module_cisaillement,ex);
// };
//--- fin debug
}
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_explicit_tdt(..";
};
jacobien = (*ex.jacobien_tdt);
// calcul éventuel des invariants de contraintes
CalculInvariants_contraintes(ptintmeca,*(ex.gijBB_tdt),*(ex.gijHH_tdt));
// en sortie il nous faut définir d_epsBB qui doit être égale à D*, donc pas forcément la dérivée
// de epsBB (par exemple dans le cas de la déformation logarithmique ou cumulée)
// variation de la déformation / au ddl
if (type_de_deformation != DEFORMATION_STANDART)
{ int d_epsBBTaille = d_epsBB.Taille();
for (int i=1; i<= d_epsBBTaille; i++)
*(d_epsBB(i)) = 0.5 * (*((*(ex.d_gijBB_tdt))(i)));
};
def_en_cours=NULL; // plus d'accès possible à la sortie
ptintmeca_en_cours = NULL; // plus d'accès possible à la sortie
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
};
// schema implicit
const Met_abstraite::Impli& Loi_comp_abstraite::Cal_implicit
(Loi_comp_abstraite::SaveResul * saveDon
,Deformation & def,DdlElement & tab_ddl,PtIntegMecaInterne & ptintmeca
, Tableau <TenseurBB *>& d_epsBB_tdt,double& jacobien,Vecteur& d_jacobien_tdt
,Tableau <TenseurHH *>& d_sigHH,const ParaAlgoControle &
,CompThermoPhysiqueAbstraite::SaveResul * saveTP,CompThermoPhysiqueAbstraite* loiTP
,bool dilat,EnergieMeca & energ,const EnergieMeca & energ_t,bool premier_calcul
)
{
Temps_CPU_HZpp& temps_cpu_loi = ptintmeca.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 = saveDon;
def_en_cours=&def;
// récup des contraintes
TenseurHH & sigHH = *(ptintmeca.SigHH()); // ici _tdt est la grandeur finale
TenseurHH & sigHH_t = *(ptintmeca.SigHH_t()); // ici _tdt est la grandeur finale
TenseurBB & epsBB_tdt = *(ptintmeca.EpsBB());
TenseurBB & DepsBB_ = *(ptintmeca.DepsBB());
TenseurBB & delta_epsBB = *(ptintmeca.DeltaEpsBB());
double& module_compressibilite = ptintmeca.ModuleCompressibilite();
double& module_cisaillement = ptintmeca.ModuleCisaillement();
Tableau <double>& def_equi = ptintmeca.Deformation_equi();
const Tableau <double>& def_equi_t = ptintmeca.Deformation_equi_t_const();
dilatation=dilat;
ptintmeca_en_cours = &ptintmeca; // pour les méthodes internes
// 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 = ptintmeca.TpsMetrique();
temps_cpu_metrique.Mise_en_route_du_comptage(); // cpu
bool calcul_varD_ddl = utilise_vitesse_deformation;
const Met_abstraite::Impli& ex = def.Cal_implicit(def_equi_t,epsBB_tdt,d_epsBB_tdt,def_equi,DepsBB_
,delta_epsBB,premier_calcul);
//------- affichage d'erreurs éventuelles ----
bool sortie_metrique = false; // pour ne pas afficher 2 fois
if (Permet_affichage() > 2)
{ // on regarde la taille des déformations
double maxgijBB = ex.gijBB_tdt->MaxiComposante();
if (( maxgijBB > ConstMath::grand)
|| (!isfinite(maxgijBB)) || (isnan(maxgijBB))
)
sortie_metrique = true;
double maxepsBB_tdt = epsBB_tdt.MaxiComposante();
if (( maxepsBB_tdt > ConstMath::grand)
|| (!isfinite(maxepsBB_tdt)) || (isnan(maxepsBB_tdt))
)
sortie_metrique = true;
double maxgijHH = ex.gijHH_tdt->MaxiComposante();
if (( maxgijHH > ConstMath::grand)
|| (!isfinite(maxgijHH)) || (isnan(maxgijHH))
)
sortie_metrique = true;
if (!sortie_metrique) // on peut donc tester une division
{ double maxgijBB_0 = ex.gijBB_0->MaxiComposante();
double ratio1 = maxgijBB/maxgijBB_0;
if ( (ratio1 > 1000.) || (ratio1 < 0.001))
sortie_metrique = true;
double maxgijHH_0 = ex.gijHH_0->MaxiComposante();
double ratio2 = maxgijHH/maxgijHH_0;
if ( (ratio2 > 1000.) || (ratio2 < 0.001))
sortie_metrique = true;
};
if ((sortie_metrique) || (Permet_affichage() > 8))
def.Affiche();
};
// on récupère les positions des points
if (premier_calcul)
{ptintmeca.M_0() = def.Position_0();
ptintmeca.M_t() = def.Position_t();
};
ptintmeca.M_tdt() = def.Position_tdt();
temps_cpu_metrique.Arret_du_comptage(); // cpu
// dans le cas d'une loi thermo dépendante, calcul de la température
if ((thermo_dependant) || dilatation)
{temperature_0 = def.DonneeInterpoleeScalaire(TEMP,TEMPS_0);
temperature_t = def.DonneeInterpoleeScalaire(TEMP,TEMPS_t);
temperature_tdt = def.DonneeInterpoleeScalaire(TEMP,TEMPS_tdt);
temperature = &temperature_tdt;
};
// demande dans les classes dérivées du calcul de grandeurs spécifiques si besoin est
// dans le cas ou l'on tiens compte de la dilatation on modifie les différents tenseurs de déformation
ThermoDonnee dTP; // init à 0 par défaut
if (dilatation)
{ // attention ici on utilise la contrainte du temps précédent, il pourrait y avoir des oscillations
// vu que sigma suivant dépend de epsméca et que epsmeca dépend de sigma !!!
// double P = -(sigHH_t * (*(ex.gijBB_tdt))).Trace()/Abs(sigHH_t.Dimension()); // calcul de la pression
// on utilise la valeur à tdt, qui est donc celle calculée à l'itération précédente en implicite
double P = -(sigHH * (*(ex.gijBB_tdt))).Trace()/Abs(sigHH.Dimension()); // calcul de la pression
// et celle du pas précédent
double P_t = -(sigHH_t * (*(ex.gijBB_t))).Trace()/Abs(sigHH_t.Dimension()); // calcul de la pression à t
loiTP->Cal_donnees_thermiques(P_t,saveTP,def,P,TEMPS_tdt,dTP);
// modification de la déformation mécanique et calcul de la déformation thermique
// a- dimensionnement des tenseurs intermédiaires qui pour l'instant ne servent qu'ici
int dim_tens = epsBB_tdt.Dimension();
// -- cas de la déformation
if (epsBB_totale == NULL) { epsBB_totale = NevezTenseurBB(dim_tens);}
else if (epsBB_totale->Dimension() != dim_tens) { delete epsBB_totale;epsBB_totale = NevezTenseurBB(dim_tens);};
*epsBB_totale = epsBB_tdt;
if (epsBB_therm == NULL) { epsBB_therm = NevezTenseurBB(dim_tens);}
else if (epsBB_therm->Dimension() != dim_tens) { delete epsBB_therm;epsBB_therm = NevezTenseurBB(dim_tens);};
// -- cas de la vitesse de déformation
if (DepsBB_totale == NULL) { DepsBB_totale = NevezTenseurBB(dim_tens);}
else if (DepsBB_totale->Dimension() != dim_tens) { delete DepsBB_totale;DepsBB_totale = NevezTenseurBB(dim_tens);};
*DepsBB_totale = DepsBB_;
if (DepsBB_therm == NULL) { DepsBB_therm = NevezTenseurBB(dim_tens);}
else if (DepsBB_therm->Dimension() != dim_tens) { delete DepsBB_therm;DepsBB_totale = NevezTenseurBB(dim_tens);};
// -- calcul du partage entre thermique et mécanique
bool avec_repercution_sur_def_meca = true;
def.DeformationThermoMecanique(temperature_0,*(ex.gijBB_tdt),dTP,*epsBB_totale
,*epsBB_therm,temperature_tdt,epsBB_tdt,temperature_t
,*DepsBB_totale,*DepsBB_therm,DepsBB_,true,avec_repercution_sur_def_meca);
};
if ((thermo_dependant) || dilatation) // répercussion éventuelle du changement de température dans les classes dérivées
{ RepercuteChangeTemperature(TEMPS_tdt); };
// calcul éventuel des invariants liés à la cinématique
CalculInvariants_cinematique(ptintmeca,*(ex.gijBB_t),*(ex.gijHH_t));
// demande dans les classes dérivées du calcul de grandeurs spécifiques si besoin est
const Met_abstraite::Impli* ex_impli = &ex;
const Met_abstraite::Expli_t_tdt* ex_expli_tdt = NULL;
const Met_abstraite::Umat_cont* ex_expli = NULL;
CalculGrandeurTravail(ptintmeca,def,TEMPS_tdt,dTP,ex_impli,ex_expli_tdt,ex_expli,NULL,NULL);
// calcul de : sigHH, d_sigHH
// on gère les exceptions éventuelles en mettant le bloc sous surveillance
try
{ Calcul_DsigmaHH_tdt (sigHH_t,DepsBB_,tab_ddl,*(ex.giB_t),*(ex.gijBB_t), *(ex.gijHH_t),
*(ex.giB_tdt),*(ex.d_giB_tdt),*(ex.giH_tdt),*(ex.d_giH_tdt),
epsBB_tdt,d_epsBB_tdt,delta_epsBB, *(ex.gijBB_tdt), *(ex.gijHH_tdt),
*(ex.d_gijBB_tdt), *(ex.d_gijHH_tdt),(*ex.jacobien_0), (*ex.jacobien_tdt),
*(ex.d_jacobien_tdt),sigHH, d_sigHH,energ,energ_t,module_compressibilite,module_cisaillement,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(..";
};
};
jacobien = (*ex.jacobien_tdt);
d_jacobien_tdt = *(ex.d_jacobien_tdt);
// calcul éventuel des invariants de contraintes
CalculInvariants_contraintes(ptintmeca,*(ex.gijBB_tdt),*(ex.gijHH_tdt));
// en sortie il nous faut définir d_epsBB qui doit être égale à D*, donc pas forcément la dérivée
// de epsBB (par exemple dans le cas de la déformation logarithmique ou cumulée)
// variation de la déformation / au ddl
if (type_de_deformation != DEFORMATION_STANDART)
{ int d_epsBB_tdtTaille = d_epsBB_tdt.Taille();
for (int i=1; i<= d_epsBB_tdtTaille; i++)
*(d_epsBB_tdt(i)) = 0.5 * (*((*(ex.d_gijBB_tdt))(i)));
};
//------- affichage d'erreurs éventuelles ----
if (Permet_affichage() > 2)
{ // on regarde la taille des déformations
double maxsig = sigHH.MaxiComposante();
if (( maxsig > ConstMath::grand)
|| (!isfinite(maxsig)) || (isnan(maxsig))
)
if (!sortie_metrique)
{cout << "\n *** pb sur le calcul de la contrainte: le resultat est "
<< " soit infini soit un nan ";
Signature_pti_encours(cout);
def.Affiche();
};
};
#ifdef MISE_AU_POINT
if (Permet_affichage() > 5)
{cout << "\n Loi_comp_abstraite::Cal_implicit: sigHH_tdt ";
sigHH.Ecriture(cout);
cout << "\n jacobien= "<< jacobien << ", d_jacobien_tdt:";
d_jacobien_tdt.Affiche();
if (Permet_affichage() > 4)
for (int i = 1; i<= d_epsBB_tdt.Taille(); i++)
{ cout << "\n d_sigHH("<<i<<") ";
d_sigHH(i)->Ecriture(cout);
cout << "\n d_epsBB_tdt("<<i<<") ";
d_epsBB_tdt(i)->Ecriture(cout);
};
};
#endif
def_en_cours=NULL; // plus d'accès possible à la sortie
ptintmeca_en_cours = NULL; // plus d'accès possible à la sortie
temps_cpu_loi.Arret_du_comptage(); // cpu spécifique pti
temps_loi.Arret_du_comptage(); // cpu spécifique loi
////debug
//if (temps_cpu_loi.Temps_CPU_User() == 0)
// { cout << "\n Loi_comp_abstraite::Cal_implicit: sigHH_tdt ";
// cout << " *** étrange, le temps loi de comp est nul ! " << endl;
// };
//// fin debug
// retour
return ex; // retour de la métrique
};
// schema pour le flambage linéaire
void Loi_comp_abstraite::Cal_flamb_lin
(SaveResul * saveDon,Deformation & def,DdlElement & tab_ddl
,PtIntegMecaInterne & ptintmeca, Tableau <TenseurBB *>& d_epsBB_tdt
,double& jacobien,Vecteur& d_jacobien_tdt,Tableau <TenseurHH *>& d_sigHH,const ParaAlgoControle &
,CompThermoPhysiqueAbstraite::SaveResul * saveTP,CompThermoPhysiqueAbstraite* loiTP
,bool dilat,EnergieMeca & energ,const EnergieMeca & energ_t,bool premier_calcul
)
{
Temps_CPU_HZpp& temps_cpu_loi = ptintmeca.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 = saveDon;
def_en_cours=&def;
// récup des contraintes
TenseurHH & sigHH = *(ptintmeca.SigHH()); // ici _tdt est la grandeur finale
TenseurHH & sigHH_t = *(ptintmeca.SigHH_t()); // ici _tdt est la grandeur finale
TenseurBB & epsBB_tdt = *(ptintmeca.EpsBB());
TenseurBB & DepsBB_ = *(ptintmeca.DepsBB());
TenseurBB & delta_epsBB = *(ptintmeca.DeltaEpsBB());
double& module_compressibilite = ptintmeca.ModuleCompressibilite();
double& module_cisaillement = ptintmeca.ModuleCisaillement();
Tableau <double>& def_equi = ptintmeca.Deformation_equi();
const Tableau <double>& def_equi_t = ptintmeca.Deformation_equi_t_const();
dilatation=dilat;
ptintmeca_en_cours = &ptintmeca; // pour les méthodes internes
// calcul des éléments de métrique
Temps_CPU_HZpp& temps_cpu_metrique = ptintmeca.TpsMetrique();
temps_cpu_metrique.Mise_en_route_du_comptage(); // cpu
const Met_abstraite::flambe_lin& ex = def.Cal_flambe_lin
(def_equi_t,epsBB_tdt,d_epsBB_tdt,def_equi,DepsBB_,delta_epsBB,premier_calcul);
// on récupère les positions des points
if (premier_calcul)
{ptintmeca.M_0() = def.Position_0();
ptintmeca.M_t() = def.Position_t();
};
ptintmeca.M_tdt() = def.Position_tdt();
temps_cpu_metrique.Arret_du_comptage(); // cpu
// dans le cas d'une loi thermo dépendante, calcul de la température
if ((thermo_dependant) || dilatation)
{temperature_0 = def.DonneeInterpoleeScalaire(TEMP,TEMPS_0);
temperature_t = def.DonneeInterpoleeScalaire(TEMP,TEMPS_t);
temperature_tdt = def.DonneeInterpoleeScalaire(TEMP,TEMPS_tdt);
temperature=&temperature_tdt;
};
// dans le cas ou l'on tiens compte de la dilatation on modifie les différents tenseurs de déformation
ThermoDonnee dTP; // init à 0 par défaut
if (dilatation)
{ // attention ici on utilise la contrainte du temps précédent, il pourrait y avoir des oscillations
// vu que sigma suivant dépend de epsméca et que epsmeca dépend de sigma !!!
// double P = -(sigHH_t * (*(ex.gijBB_tdt))).Trace()/Abs(sigHH_t.Dimension()); // calcul de la pression
// on utilise la valeur à tdt, qui est donc celle calculée à l'itération précédente en implicite
// en espérant que cela veuille dire quelque chose ici !!
double P = -(sigHH * (*(ex.gijBB_tdt))).Trace()/Abs(sigHH.Dimension()); // calcul de la pression
// et celle du pas précédent
double P_t = -(sigHH_t * (*(ex.gijBB_t))).Trace()/Abs(sigHH_t.Dimension()); // calcul de la pression à t
loiTP->Cal_donnees_thermiques(P_t,saveTP,def,P,TEMPS_tdt,dTP);
// modification de la déformation mécanique et calcul de la déformation thermique
// a- dimensionnement des tenseurs intermédiaires qui pour l'instant ne servent qu'ici
int dim_tens = epsBB_tdt.Dimension();
// -- cas de la déformation
if (epsBB_totale == NULL) { epsBB_totale = NevezTenseurBB(dim_tens);}
else if (epsBB_totale->Dimension() != dim_tens) { delete epsBB_totale;epsBB_totale = NevezTenseurBB(dim_tens);};
*epsBB_totale = epsBB_tdt;
if (epsBB_therm == NULL) { epsBB_therm = NevezTenseurBB(dim_tens);}
else if (epsBB_therm->Dimension() != dim_tens) { delete epsBB_therm;epsBB_therm = NevezTenseurBB(dim_tens);};
// -- cas de la vitesse de déformation
if (DepsBB_totale == NULL) { DepsBB_totale = NevezTenseurBB(dim_tens);}
else if (DepsBB_totale->Dimension() != dim_tens) { delete DepsBB_totale;DepsBB_totale = NevezTenseurBB(dim_tens);};
*DepsBB_totale = DepsBB_;
if (DepsBB_therm == NULL) { DepsBB_therm = NevezTenseurBB(dim_tens);}
else if (DepsBB_therm->Dimension() != dim_tens) { delete DepsBB_therm;DepsBB_totale = NevezTenseurBB(dim_tens);};
// -- calcul du partage entre thermique et mécanique
bool avec_repercution_sur_def_meca = true;
def.DeformationThermoMecanique(temperature_0,*(ex.gijBB_tdt),dTP,*epsBB_totale
,*epsBB_therm,temperature_tdt,epsBB_tdt,temperature_tdt
,*DepsBB_totale,*DepsBB_therm,DepsBB_,true,avec_repercution_sur_def_meca);
};
if ((thermo_dependant) || dilatation) // répercussion éventuelle du changement de température dans les classes dérivées
{ RepercuteChangeTemperature(TEMPS_tdt); };
// calcul éventuel des invariants liés à la cinématique
CalculInvariants_cinematique(ptintmeca,*(ex.gijBB_t),*(ex.gijHH_t));
// demande dans les classes dérivées du calcul de grandeurs spécifiques si besoin est
const Met_abstraite::Impli* ex_impli = &ex;
const Met_abstraite::Expli_t_tdt* ex_expli_tdt = NULL;
const Met_abstraite::Umat_cont* ex_expli = NULL;
CalculGrandeurTravail(ptintmeca,def,TEMPS_tdt,dTP,ex_impli,ex_expli_tdt,ex_expli,NULL,NULL);
// calcul de : sigHH, d_sigHH
// on gère les exceptions éventuelles en mettant le bloc sous surveillance
try
{ Calcul_DsigmaHH_tdt (sigHH_t,DepsBB_,tab_ddl,*(ex.giB_t),*(ex.gijBB_t), *(ex.gijHH_t),*(ex.giB_tdt)
,*(ex.d_giB_tdt),*(ex.giH_tdt),*(ex.d_giH_tdt)
,epsBB_tdt,d_epsBB_tdt,delta_epsBB, *(ex.gijBB_tdt), *(ex.gijHH_tdt)
,*(ex.d_gijBB_tdt), *(ex.d_gijHH_tdt),(*ex.jacobien_0), (*ex.jacobien_tdt)
,*(ex.d_jacobien_tdt),sigHH, d_sigHH,energ,energ_t,module_compressibilite,module_cisaillement,
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_flamb_lin(..";
};
jacobien = (*ex.jacobien_tdt);
d_jacobien_tdt = *(ex.d_jacobien_tdt);
// calcul éventuel des invariants de contraintes
CalculInvariants_contraintes(ptintmeca,*(ex.gijBB_tdt),*(ex.gijHH_tdt));
// en sortie il nous faut définir d_epsBB qui doit être égale à D*, donc pas forcément la dérivée
// de epsBB (par exemple dans le cas de la déformation logarithmique ou cumulée)
// variation de la déformation / au ddl
if (type_de_deformation != DEFORMATION_STANDART)
{ int d_epsBB_tdtTaille = d_epsBB_tdt.Taille();
for (int i=1; i<= d_epsBB_tdtTaille; i++)
*(d_epsBB_tdt(i)) = 0.5 * (*((*(ex.d_gijBB_tdt))(i)));
};
def_en_cours=NULL; // plus d'accès possible à la sortie
ptintmeca_en_cours = NULL; // plus d'accès possible à la sortie
temps_cpu_loi.Arret_du_comptage(); // cpu spécifique pti
temps_loi.Arret_du_comptage(); // cpu spécifique loi
// retour
};
// schema pour le calcul de la loi de comportement dans le cas de l'umat
void Loi_comp_abstraite::ComportementUmat
(Loi_comp_abstraite::SaveResul * saveDon
,Deformation & def,PtIntegMecaInterne& ptintmeca,ParaAlgoControle & para
,CompThermoPhysiqueAbstraite::SaveResul * saveTP,CompThermoPhysiqueAbstraite* loiTP
,bool dilat,UmatAbaqus& umatAbaqusqus,bool premier_calcul)
{
Temps_CPU_HZpp& temps_cpu_loi = ptintmeca.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 = saveDon;
dilatation=dilat;
def_en_cours=&def;
ptintmeca_en_cours = &ptintmeca; // pour les méthodes internes
// on calcul les éléments de la métrique dans le cas particulier de l'umat d'où d'une métrique
// Met_ElemPoint et d'une déformation particulière Def_Umat
Def_Umat& defUmat = *((Def_Umat*) &def); // récup
// on regarde si c'est le premier incrément ou pas (d'où le calcul du premier pas)
// bool premier_calcul=false;
// if (umatAbaqusqus.nb_increment <= 1) premier_calcul = true;
Temps_CPU_HZpp& temps_cpu_metrique = ptintmeca.TpsMetrique();
temps_cpu_metrique.Mise_en_route_du_comptage(); // cpu
const Met_abstraite::Umat_cont& ex= defUmat.Cal_defUmat(premier_calcul);
// on récupère les positions des points
if (premier_calcul)
{ptintmeca.M_0() = def.Position_0();
ptintmeca.M_t() = def.Position_t();
};
ptintmeca.M_tdt() = def.Position_tdt();
umatAbaqusqus.coor_pt = ptintmeca.M_tdt();// on met à jour les coordonnées absolues du pti temps_cpu_metrique.Arret_du_comptage(); // cpu
// -- modification du pas de temps: on part du principe que le pas de temps est géré par le programme appelant donc ici on ne fait que répercuter
// -- le pas de temps et le temps courant au niveau des paramètres globaux du calcul, qui normalement ne sont (et ne doivent être)
// -- utilisées que pour la loi de comportement Umat. Les autres cas ne sont pas prévus
para.Modif_temps(umatAbaqusqus.temps_tdt,umatAbaqusqus.delta_t);
// // modif le 21 avril 2016 -> on passe les infos via des paramètres de passage
// // double deltat = umatAbaqusqus.delta_t;
// // VariablesTemps tempo_umat(para.Variables_de_temps());
// // ici on accède directement car c'est loi_comp_abstraite est friend de Variables Temps
// tempo_umat.temps = umatAbaqusqus.temps_tdt;
// tempo_umat.deltat = umatAbaqusqus.delta_t;
// dans le cas d'une loi thermo dépendante, calcul de la température
if ((thermo_dependant) || dilatation)
{temperature_0 = 0.; // a priori pour l'instant
temperature_t = umatAbaqusqus.temper_t;
temperature_tdt = umatAbaqusqus.temper_t+umatAbaqusqus.delta_temper;
temperature=&temperature_tdt;
};
#ifdef MISE_AU_POINT
if ( Permet_affichage() > 5)
{cout << "\n temperature_0= "<< temperature_0
<< " temperature_t= "<< temperature_t
<< " temperature= "<< temperature
<< "\n thermo_dependant= "<<thermo_dependant
<< " dilatation= "<< dilatation
<< flush;
};
#endif
// -- cas de la vitesse de déformation à la umat
// construction du tenseur vitesse de déformation, constant sur le pas de temps
// = delta epsilonBB /delta t
if (DepsBB_umat == NULL) // cas du premier passage, on cré le tenseur
{ DepsBB_umat = NevezTenseurBB(*(umatAbaqusqus.delta_eps_meca));}
else if (DepsBB_umat->Dimension() != (umatAbaqusqus.delta_eps_meca)->Dimension()) // tenseur inadapté, on change
{ delete DepsBB_umat;DepsBB_umat = NevezTenseurBB(*(umatAbaqusqus.delta_eps_meca));}
else // cas courant on récupère la valeur de delta_epsilon_BB
{ *DepsBB_umat = *(umatAbaqusqus.delta_eps_meca); };
// puis on divise par l'incrément de temsp
if (Abs(umatAbaqusqus.delta_t) >= ConstMath::trespetit)
{(*DepsBB_umat) /= umatAbaqusqus.delta_t;}
else {DepsBB_umat->Inita(0.);}; // si trop petit on met à 0
ThermoDonnee dTP; // init à 0 par défaut
if (dilatation)
{ // attention ici on utilise la contrainte du temps précédent, car a priori on ne dispose pas de la nouvelle valeur
// il pourrait y avoir des oscillations
// dans le cas de l'umat, le tenseur initial sigma est en orthonormée
double P=0.;
for (int i=1;i<=umatAbaqusqus.dim_tens;i++) P += (*umatAbaqusqus.t_sigma)(i,i);
P /= umatAbaqusqus.dim_tens; // pression
loiTP->Cal_donnees_thermiques(P,saveTP,def,P,TEMPS_tdt,dTP);
// Dans le cas de la procédure Umat, la déformation récupérée est directement la déformation mécanique
// l'influence de la dilatation thermique s'effectue éventullement au sein de la loi de comportement
// comme par exemple Hysteresis_bulk, quand on utilise pas directement les deformations méca
// a- dimensionnement des tenseurs intermédiaires qui pour l'instant ne servent qu'ici
// epsBB_totale et DepsBB_totale ne servent à rien en fait ... l'objectif est uniquement de satifaire
// les variables de passages dans DeformationThermoMecanique, car comme avec_repercution_sur_def_meca = false
// on ne change pas les tenseurs de déformation et de vitesse de déformation
// par contre : epsBB_therm et DepsBB_therm sont calculées dans DeformationThermoMecanique
int dim_tens = 3; // a priori on est en dimension 3
// -- cas de la déformation
if (epsBB_totale == NULL) { epsBB_totale = NevezTenseurBB(dim_tens);}
else if (epsBB_totale->Dimension() != dim_tens) { delete epsBB_totale;epsBB_totale = NevezTenseurBB(dim_tens);};
if (epsBB_therm == NULL) { epsBB_therm = NevezTenseurBB(dim_tens);}
else if (epsBB_therm->Dimension() != dim_tens) { delete epsBB_therm;epsBB_therm = NevezTenseurBB(dim_tens);};
// -- cas de la vitesse de déformation
if (DepsBB_totale == NULL) { DepsBB_totale = NevezTenseurBB(dim_tens);}
else if (DepsBB_totale->Dimension() != dim_tens) { delete DepsBB_totale;DepsBB_totale = NevezTenseurBB(dim_tens);};
if (DepsBB_therm == NULL) { DepsBB_therm = NevezTenseurBB(dim_tens);}
else if (DepsBB_therm->Dimension() != dim_tens) { delete DepsBB_therm;DepsBB_totale = NevezTenseurBB(dim_tens);};
// -- calcul du partage entre thermique et mécanique
bool avec_repercution_sur_def_meca = false;
def.DeformationThermoMecanique(temperature_0,*(ex.gijBB_tdt),dTP,*epsBB_totale
,*epsBB_therm,temperature_tdt,*(umatAbaqusqus.eps_meca),temperature_t
,*DepsBB_totale,*DepsBB_therm,*DepsBB_umat,true,avec_repercution_sur_def_meca);
};
// cas des énergie méca
// tout d'abord celles précédentes
EnergieMeca ener_t(umatAbaqusqus.energie_elastique,umatAbaqusqus.dissipation_plastique
,umatAbaqusqus.dissipation_visqueuse);
EnergieMeca ener; // la sortie initialisée à 0
// transfert de l'Umat vers les pt d'integ avant le calcul de la contrainte donc à t
umatAbaqusqus.Transfert_Umat_ptInteg_t(ptintmeca);
*(ptintmeca.DepsBB())=*DepsBB_umat; // stockage de vitesse de déformation
// calcul des def équivalentes
// - récup des infos
TenseurBB & epsBB_tdt = *(ptintmeca.EpsBB());
TenseurBB & DepsBB_ = *(ptintmeca.DepsBB());
TenseurBB & delta_epsBB = *(ptintmeca.DeltaEpsBB());
Tableau <double>& def_equi = ptintmeca.Deformation_equi();
const Tableau <double>& def_equi_t = ptintmeca.Deformation_equi_t_const();
// - calcul
defUmat.CalDefEqui(def_equi_t,epsBB_tdt,def_equi,DepsBB_,delta_epsBB,ex,premier_calcul);
if ((thermo_dependant) || dilatation) // répercussion éventuelle du changement de température dans les classes dérivées
{ RepercuteChangeTemperature(TEMPS_tdt); };
// calcul éventuel des invariants liés à la cinématique
CalculInvariants_cinematique(ptintmeca,*(ex.gijBB_t),*(ex.gijHH_t));
// calcul éventuel préalable avant le calcul de la contrainte
const Met_abstraite::Impli* ex_impli = NULL;
const Met_abstraite::Expli_t_tdt* ex_expli_tdt = NULL;
const Met_abstraite::Umat_cont* ex_expli = &ex;
CalculGrandeurTravail(ptintmeca,defUmat,TEMPS_tdt,dTP,ex_impli,ex_expli_tdt,ex_expli,NULL,NULL);
// affichage de certaines données de def d'entrée du calcul Calcul_dsigma_deps
// car elles sont différentes (car calculées) en fonction des entrées
#ifdef MISE_AU_POINT
if (((ParaGlob::NiveauImpression() > 8) && (Permet_affichage() == 0))
|| (Permet_affichage() > 4)
)
{ cout << "\n affichage des def avant appel de Calcul_dsigma_deps \n ";
int dim = ParaGlob::Dimension();
// def en orthonormee
TenseurBB* epsBB_inter= (NevezTenseurBB(dim)) ;
(umatAbaqusqus.eps_meca)->BaseAbsolue(*epsBB_inter,*(ex.giH_tdt));
cout << "\n epsBB meca d'entree =en orthonormee ";epsBB_inter->Ecriture(cout);
delete epsBB_inter;
// Deps
TenseurBB* DepsBB_inter= (NevezTenseurBB(dim)) ;
DepsBB_umat->BaseAbsolue(*DepsBB_inter,*(ex.giH_tdt));
cout << "\n DepsBB meca d'entree =en orthonormee "; DepsBB_inter->Ecriture(cout);
delete DepsBB_inter;
// Delta eps
TenseurBB* delta_epsBB_inter= (NevezTenseurBB(dim)) ;
(umatAbaqusqus.delta_eps_meca)->BaseAbsolue(*delta_epsBB_inter,*(ex.giH_tdt));
cout << "\n delta eps meca d'entree =en orthonormee "; delta_epsBB_inter->Ecriture(cout);
delete delta_epsBB_inter;
cout << endl;
};
#endif
// calcul de : sigHH, d_sigHH
bool en_base_orthonormee=true; // ici les tenseurs sont en orthonormee a priori
// on gère les exceptions éventuelles en mettant le bloc sous surveillance
try
{ Calcul_dsigma_deps(en_base_orthonormee, *(umatAbaqusqus.t_sigma),*DepsBB_umat
,*(umatAbaqusqus.eps_meca),*(umatAbaqusqus.delta_eps_meca)
,(*ex.jacobien_0),(*ex.jacobien_tdt)
,*(umatAbaqusqus.t_sigma),*(umatAbaqusqus.d_sigma_deps)
,ener,ener_t,ptintmeca.ModuleCompressibilite(),ptintmeca.ModuleCisaillement(),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::ComportementUmat(..";
};
umatAbaqusqus.energie_elastique = ener.EnergieElastique();
umatAbaqusqus.dissipation_plastique = ener.DissipationPlastique();
umatAbaqusqus.dissipation_visqueuse= ener.DissipationVisqueuse();
// dans le cas où il s'agit d'une loi de contrainte plane, on met à jour les normales finales
// ce qui permettra de transmettre la variation d'épaisseur
if ((Comp_3D_CP_DP_1D(this->Id_comport()) == COMP_CONTRAINTES_PLANES)
&& (ParaGlob::Dimension() == 3))
{ umatAbaqusqus.N_tdt(3) = HsurH0(saveDon);
};
// transfert de l'Umat vers les pt d'integ
// umatAbaqusqus.Transfert_Umat_ptInteg_t(ptintmeca); // correction erreur le 7/sept/ 2013
umatAbaqusqus.Transfert_Umat_ptInteg_tdt(ptintmeca); // correction erreur le 7/sept/ 2013
// calcul éventuel des invariants de contraintes
CalculInvariants_contraintes(ptintmeca,*(ex.gijBB_tdt),*(ex.gijHH_tdt));
def_en_cours=NULL; // plus d'accès possible à la sortie
ptintmeca_en_cours = NULL; // plus d'accès possible à la sortie
temps_cpu_loi.Arret_du_comptage(); // cpu spécifique pti
temps_loi.Arret_du_comptage(); // cpu spécifique loi
};
// calcul d'un module d'young équivalent à la loi, ceci pour un
// chargement nul
double Loi_comp_abstraite::Module_young_equivalent(Enum_dure ,const Deformation & ,SaveResul * )
{ cout << "\n erreur , aucun module d'young equivalent n'est defini pour cette loi ";
this->Affiche();
Sortie(1);
return 0.; // pour éviter le warning à la compil
};
// récupération d'un module de compressibilité équivalent à la loi pour un chargement nul
// il s'agit ici de la relation -pression = sigma_trace/3. = module de compressibilité * I_eps
double Loi_comp_abstraite::Module_compressibilite_equivalent(Enum_dure ,const Deformation & ,SaveResul * )
{ cout << "\n erreur , aucun module de compressibilite equivalent n'est defini pour cette loi ";
this->Affiche();
Sortie(1);
return 0.; // pour éviter le warning à la compil
};
// récupération de la dernière déformation d'épaisseur calculée: cette déformaion n'est utile que pour des lois en contraintes planes ou doublement planes
// - pour les lois 3D : retour d'un nombre très grand, indiquant que cette fonction est invalide
// - pour les lois 2D def planes: retour de 0
// les infos nécessaires à la récupération de la def, sont stockées dans saveResul
// qui est le conteneur spécifique au point où a été calculé la loi
double Loi_comp_abstraite::Eps33BH(SaveResul * saveResul) const
{ cout << "\n erreur , la methode Eps33BH() n'est defini pour cette loi ";
this->Affiche();
Sortie(1);
return 0.; // pour éviter le warning à la compil
};
// récupération de la dernière déformation de largeur calculée: cette déformaion n'est utile que pour des lois en contraintes doublement planes
// - pour les lois 3D et 2D : retour d'un nombre très grand, indiquant que cette fonction est invalide
// les infos nécessaires à la récupération de la def, sont stockées dans saveResul
// qui est le conteneur spécifique au point où a été calculé la loi
double Loi_comp_abstraite::Eps22BH(SaveResul * saveResul) const
{ cout << "\n erreur , la methode Eps22BH() n'est defini pour cette loi ";
this->Affiche();
Sortie(1);
return 0.; // pour éviter le warning à la compil
};
// récupération de la variation relative d'épaisseur calculée: h/h0
// et de sa variation par rapport aux ddls la concernant: d_hsurh0
// cette variation n'est utile que pour des lois en contraintes planes
// - pour les lois 3D : retour d'un nombre très grand, indiquant que cette fonction est invalide
// - pour les lois 2D def planes: retour de 0
// les infos nécessaires à la récupération , sont stockées dans saveResul
// qui est le conteneur spécifique au point où a été calculé la loi
double Loi_comp_abstraite::d_HsurH0(SaveResul * saveResul,Vecteur & d_hsurh0) const
{ cout << "\n erreur , la methode d_HsurH0() n'est defini pour cette loi ";
this->Affiche();
Sortie(1);
return 0.; // pour éviter le warning à la compil
};
// récupération de la variation relative de largeur calculée: b/b0
// cette variation n'est utile que pour des lois en contraintes planes double
// - pour les lois 3D et 2D : retour d'un nombre très grand, indiquant que cette fonction est invalide
// les infos nécessaires à la récupération , sont stockées dans saveResul
// qui est le conteneur spécifique au point où a été calculé la loi
double Loi_comp_abstraite::BsurB0(SaveResul * saveResul) const
{ cout << "\n erreur , la methode BsurB0() n'est defini pour cette loi ";
this->Affiche();
Sortie(1);
return 0.; // pour éviter le warning à la compil
};
// récupération de la variation relative de largeur calculée: b/b0
// et de sa variation par rapport aux ddls la concernant: d_bsurb0
// cette variation n'est utile que pour des lois en contraintes planes
// - pour les lois 3D et 2D : retour d'un nombre très grand, indiquant que cette fonction est invalide
// les infos nécessaires à la récupération , sont stockées dans saveResul
// qui est le conteneur spécifique au point où a été calculé la loi
double Loi_comp_abstraite::d_BsurB0(SaveResul * saveResul,Vecteur & d_bsurb0) const
{ cout << "\n erreur , la methode d_BsurB0() n'est defini pour cette loi ";
this->Affiche();
Sortie(1);
return 0.; // pour éviter le warning à la compil
};
// mise à jour des températures d'une manière unilatérale: sert par exemple pour
// le calcul du module d'young équivalent, quand il est calculé en dehors du calcul des contraintes
void Loi_comp_abstraite::Mise_a_jour_temperature(Enum_dure temps,Deformation & def)
{
if (thermo_dependant)
{switch (temps)
{ case TEMPS_0:
temperature_0 = def.DonneeInterpoleeScalaire(TEMP,TEMPS_0);
temperature = &temperature_0;
break;
case TEMPS_t:
temperature_t = def.DonneeInterpoleeScalaire(TEMP,TEMPS_t);
temperature = &temperature_t;
break;
case TEMPS_tdt:
temperature_tdt = def.DonneeInterpoleeScalaire(TEMP,TEMPS_tdt);
temperature = &temperature_tdt;
break;
default :
cout << "\n cas du temps non implante temps= " << Nom_dure(temps)
<< "\n Loi_comp_abstraite::Mise_a_jour_temperature(Enum_dure temps...";
Sortie(1);
};
// puis on répercute la température
RepercuteChangeTemperature(temps);
};
};
// lecture éventuelle du type de déformation et du niveau de commentaire
void Loi_comp_abstraite::Lecture_type_deformation_et_niveau_commentaire
(UtilLecture& entreePrinc,LesFonctions_nD& lesFonctionsnD
,bool avec_passage_nouvelle_donnee)
{
string nom_class_methode("Loi_comp_abstraite::Lecture_type_deformation_et_niveau_commentaire(..");
// recherche du mot clé éventuel indiquant le type de déformation
if (avec_passage_nouvelle_donnee)
entreePrinc.NouvelleDonnee();
// on note ce qu'il faut lire
int a_lire_type_deformation = 0;
if (strstr(entreePrinc.tablcar,"type_de_deformation")!= NULL)
a_lire_type_deformation = 1;
int a_lire_permet_affichage = 0;
if (strstr(entreePrinc.tablcar,"permet_affichage_")!= NULL)
a_lire_permet_affichage = 1;
// on initialise par défaut: la déformation standart
type_de_deformation = DEFORMATION_STANDART;
// le niveau de commentaire local
// on ne l'initialise pas car il peut déjà avoir une valeur
// via une lecture de paramètres particuliers permet_affichage = 0;
if ( a_lire_type_deformation || a_lire_permet_affichage)
{while ( a_lire_type_deformation || a_lire_permet_affichage)
{ // on lit le mot clé
string nom;
*(entreePrinc.entree) >> nom;
if (nom == "type_de_deformation")
{ *(entreePrinc.entree) >> nom ;
type_de_deformation=Id_nom_type_deformation(nom.c_str());
a_lire_type_deformation = 0;
entreePrinc.NouvelleDonnee();
if (strstr(entreePrinc.tablcar,"permet_affichage_")!= NULL)
a_lire_permet_affichage = 1;
}
else if (nom == "permet_affichage_")
{Loi_comp_abstraite::Lecture_permet_affichage(&entreePrinc,lesFonctionsnD);
a_lire_permet_affichage = 0;
entreePrinc.NouvelleDonnee();
if (strstr(entreePrinc.tablcar,"type_de_deformation")!= NULL)
a_lire_type_deformation = 1;
}
else
{cout << "\n erreur*** : on a lue " << nom
<< " et on attendait un des deux mots clefs suivant: "
<< " type_de_deformation ou permet_affichage_ "
<< "\n Loi_comp_abstraite::Lecture_type_deformation_et_niveau_commentaire(.. "
<< endl;
Sortie(1);
};
};
};
};
// affichage des données de la classe comp_abstraite
void Loi_comp_abstraite::Affiche_don_classe_abstraite() const
{ cout << "\n type_de_deformation: " << Nom_type_deformation(type_de_deformation);
{cout << "\n list_grandeur_particuliere_dispo_localement:taille= "
<< listdeTouslesQuelc_dispo_localement.size()<<" ";
list <EnumTypeQuelconque >::const_iterator il,ilfin=listdeTouslesQuelc_dispo_localement.end();
for (il=listdeTouslesQuelc_dispo_localement.begin();il != ilfin;il++)
cout << NomTypeQuelconque(*il) << " ";
};
{cout << "\n list_grandeur_particuliere_demandee_localement:taille= "
<< listQuelc_mis_en_acces_localement.size()<<" ";
list <EnumTypeQuelconque >::const_iterator il,ilfin=listQuelc_mis_en_acces_localement.end();
for (il=listQuelc_mis_en_acces_localement.begin();il != ilfin;il++)
cout << NomTypeQuelconque(*il) << " ";
};
cout << endl;
};
// affichage et definition interactive des commandes particulières à la classe loi_comp_abstraite
void Loi_comp_abstraite::Info_commande_don_LoisDeComp(UtilLecture& entreePrinc) const
{ ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier
cout << "\n definition standart de la deformation (rep o (defaut) ou n) ? ";
string rep = "_";
// procédure de lecture avec prise en charge d'un retour chariot
rep = lect_return_defaut(true,"o");
if ((Minuscules(rep) != "f")&&(Minuscules(rep) != "0")&&(Minuscules(rep) != "o"))
{rep = "_";
while ((Minuscules(rep) != "f")&&(Minuscules(rep) != "0")&&(Minuscules(rep) != "o")
&&(Minuscules(rep) != "1")&&(Minuscules(rep) != "2"))
{try
{
cout << "\n -- definition du type de mesure de deformation : --- "
<< "\n (0 ou f) (fin) "
<< "\n (1) Almansi (defaut) "
<< "\n (2) Logarithmique (experimental) "
<< "\n ";
// procédure de lecture avec prise en charge d'un retour chariot
rep = lect_return_defaut(true,"1");
if ((Minuscules(rep) != "f")&&(Minuscules(rep) != "0")&&(Minuscules(rep) != "o")
&&(Minuscules(rep) != "1"))
{ if (Minuscules(rep) == "2")
{cout << "\n choix de la deformation Logarithmique ";
sort << "\n# -- definition du type de deformation (par defaut: DEFORMATION_STANDART) -- "
<< "\n type_de_deformation DEFORMATION_LOGARITHMIQUE ";
}
else { cout << "\n Erreur on attendait un entier entre 0 et 2 !!, "
<< "\n redonnez une bonne valeur"
<< "\n ou taper f ou 0 pour stoper la definition de la deformation ";
};
}
}
catch (ErrSortieFinale)
// cas d'une direction voulue vers la sortie
// on relance l'interuption pour le niveau supérieur
{ ErrSortieFinale toto;
throw (toto);
}
catch (...)//(UtilLecture::ErrNouvelleDonnee erreur)
{ cout << "\n Erreur on attendait un des mots cles proposes !!, "
<< "\n redonnez une bonne valeur"
<< "\n ou taper f ou 0 pour sortir ";
};
}; //-- fin du while
}; // fin du cas ou on veut une définition non standart
// sort << "\n# -- definition du type de deformation (par defaut: DEFORMATION_STANDART) -- "
// << "\n type_de_deformation DEFORMATION_STANDART ";
};
//----- lecture écriture de restart spécifique aux données de la classe -----
// 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_comp_abstraite::Lecture_don_base_info(ifstream& ent,const int cas,LesReferences& lesRef
,LesCourbes1D& lesCourbes1D
,LesFonctions_nD& lesFonctionsnD)
{ string toto;
if (cas == 1)
{ // tout d'abord appel de la classe mère
LoiAbstraiteGeneral::Lect_base_info_loi(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD);
// puis les infos propres
// le type de déformation
ent >> toto ;
if (toto != "type_deformation")
{ cout << "\n erreur en lecture du type de deformation, nom lu: " << toto
<< "\n Loi_comp_abstraite::Lecture_don_base_info(...";
Sortie(1);
};
// lecture des infos
ent >> toto; type_de_deformation=Id_nom_type_deformation(toto.c_str());
// lecture concernant les grandeurs particulières de liaison
{int taille=0;string nom;
ent >> toto >> taille;
listdeTouslesQuelc_dispo_localement.clear();
for (int i=1;i<=taille;i++)
{ ent >> nom;listdeTouslesQuelc_dispo_localement.push_back(Id_nomTypeQuelconque(nom));};
};
{int taille=0;string nom;
listQuelc_mis_en_acces_localement.clear();
ent >> toto >> taille;
for (int i=1;i<=taille;i++)
{ ent >> nom;listQuelc_mis_en_acces_localement.push_back(Id_nomTypeQuelconque(nom));};
};
};
ent >> toto >> temps_loi;
};
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void Loi_comp_abstraite::Ecriture_don_base_info(ofstream& sort,const int cas) const
{ if (cas == 1)
{ // tout d'abord appel de la classe mère
LoiAbstraiteGeneral::Ecrit_base_info_loi(sort,cas);
// puis les infos propres
// le type de déformation
sort << " \n type_deformation " << Nom_type_deformation(type_de_deformation) << " ";
{sort << "\n list_grandeur_particuliere_dispo_localement:taille= "
<< listdeTouslesQuelc_dispo_localement.size() << " ";
list <EnumTypeQuelconque >::const_iterator il,ilfin=listdeTouslesQuelc_dispo_localement.end();
for (il=listdeTouslesQuelc_dispo_localement.begin();il != ilfin;il++)
sort << NomTypeQuelconque(*il) << " ";
};
{sort << "\n list_grandeur_particuliere_demandee_localement:taille= "
<< listQuelc_mis_en_acces_localement.size() << " ";
list <EnumTypeQuelconque >::const_iterator il,ilfin=listQuelc_mis_en_acces_localement.end();
for (il=listQuelc_mis_en_acces_localement.begin();il != ilfin;il++)
sort << NomTypeQuelconque(*il) << " ";
};
};
sort << "\n tps_cumule_loi: "<<temps_loi;
};
// 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 Loi_comp_abstraite::Activ_donnees(Tableau<Noeud *>& tabnoeud,bool dilatation,LesPtIntegMecaInterne& lesPtMecaInt)
{ if ((thermo_dependant)|| (dilatation))
{ // 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 Loi_comp_abstraite::Activ_donnees(...";
Sortie(1);
}
}
};
// cas de l'utilisation d'une fonction nD pour l'affichage
if (permet_affich_loi_nD != NULL)
{// l'objectif ici est de définir les conteneurs de grandeurs totalement quelconques
// qui seront ensuite nécessaire pour appeler la fonction
// on ne fait qu'une fois l'opération, car la fonction est appelée à chaque pti
// 1) on récupère le tableau des énumérés de quelconques de la fonction
const Tableau <EnumTypeQuelconque>& tqi = permet_affich_loi_nD->Tab_enu_quelconque();
if (tqi.Taille() != li_quelconque.size())
{// on initialise la liste
li_quelconque.clear();
// on va boucler sur les énumérés quelconque et
// créer les conteneurs de retour
int nb_tqi = tqi.Taille();
for (int i_tqi = 1;i_tqi <= nb_tqi;i_tqi++ )
// on crée les conteneurs
{EnumTypeQuelconque& enuconq = tqi(i_tqi);
switch (enuconq)
{
case CONTRAINTE_MISES :
{Grandeur_scalaire_double grand_courant(0.);
TypeQuelconque typQ1(CONTRAINTE_MISES,SIG11,grand_courant);
li_quelconque.push_back(typQ1);
break;
}
case CONTRAINTE_TRESCA :
{Grandeur_scalaire_double grand_courant(0.);
TypeQuelconque typQ1(CONTRAINTE_TRESCA,SIG11,grand_courant);
li_quelconque.push_back(typQ1);
break;
}
case CONTRAINTE_MISES_T :
{Grandeur_scalaire_double grand_courant(0.);
TypeQuelconque typQ1(CONTRAINTE_MISES_T,SIG11,grand_courant);
li_quelconque.push_back(typQ1);
break;
}
case CONTRAINTE_TRESCA_T :
{Grandeur_scalaire_double grand_courant(0.);
TypeQuelconque typQ1(CONTRAINTE_TRESCA_T,SIG11,grand_courant);
li_quelconque.push_back(typQ1);
break;
}
case NUM_ELEMENT:
{Grandeur_scalaire_entier grand_courant(0);
TypeQuelconque typQ1(NUM_ELEMENT,NU_DDL,grand_courant);
li_quelconque.push_back(typQ1);
break;
}
case NUM_MAIL_ELEM:
{Grandeur_scalaire_entier grand_courant(0);
TypeQuelconque typQ1(NUM_MAIL_ELEM,NU_DDL,grand_courant);
li_quelconque.push_back(typQ1);
break;
}
case NUM_PTI:
{Grandeur_scalaire_entier grand_courant(0);
TypeQuelconque typQ1(NUM_PTI,NU_DDL,grand_courant);
li_quelconque.push_back(typQ1);
break;
}
case REPERE_LOCAL_ORTHO :
{Coordonnee v_rep(ParaGlob::Dimension()); // un vecteur intermédiaire
Tab_Grandeur_Coordonnee gr(v_rep,3); // def d'une grandeur intermédiaire
// stockage
TypeQuelconque typQ6(REPERE_LOCAL_ORTHO,SIG11,gr);
li_quelconque.push_back(typQ6);
break;
}
case REPERE_LOCAL_H :
{Coordonnee v_rep(ParaGlob::Dimension()); // un vecteur intermédiaire
Tab_Grandeur_Coordonnee gr(v_rep,3); // def d'une grandeur intermédiaire
// stockage
TypeQuelconque typQ6(REPERE_LOCAL_H,SIG11,gr);
li_quelconque.push_back(typQ6);
break;
}
case REPERE_LOCAL_B :
{Coordonnee v_rep(ParaGlob::Dimension()); // un vecteur intermédiaire
Tab_Grandeur_Coordonnee gr(v_rep,3); // def d'une grandeur intermédiaire
// stockage
TypeQuelconque typQ6(REPERE_LOCAL_B,SIG11,gr);
li_quelconque.push_back(typQ6);
break;
}
default :
{ cout << "\n erreur dans la definition du stockage inter pour la fonction nD "
<< " d'affichage : "<< permet_affich_loi_nD->NomFonction()
<< " cas non traite: "
<< NomTypeQuelconque(enuconq) << "!\n";
cout << "\n Loi_comp_abstraite::Activ_donnees(....";
Sortie(1);
};
};
};
// on s'occupe maintenant des pointeurs
// qui seront nécessaire pour utiliser la fonction nD
if (li_quelconque.size())
{tab_pt_li_quelconque.Change_taille(li_quelconque.size());
List_io <TypeQuelconque >::iterator ili,ilifin = li_quelconque.end();
int i=1; // init
for (ili= li_quelconque.begin();ili != ilifin; ili++,i++)
tab_pt_li_quelconque(i) = &(*ili);
};
};
};
};
// ***** a supprimer à terme, -> écriture d'un message d'erreur ******
// calcul des contraintes et ses variations par rapport aux déformations a t+dt
// en_base_orthonormee: le tenseur de contrainte en entrée est en orthonormeee
// le tenseur de déformation et son incrémentsont également en orthonormees
// si = false: les bases transmises sont utilisées
// ex: contient les éléments de métrique relativement au paramétrage matériel = X_(0)^a
void Loi_comp_abstraite::Calcul_dsigma_deps
(bool en_base_orthonormee, TenseurHH & ,TenseurBB&
,TenseurBB & ,TenseurBB & ,double& ,double&
,TenseurHH& ,TenseurHHHH&
,EnergieMeca & ,const EnergieMeca & ,double& , double& ,const Met_abstraite::Umat_cont&
)
{ cout << "\n ERREUR: methode non encore implante !!!!"
<< "\n methode Loi_comp_abstraite::Calcul_dsigma_deps (...";
Affiche();
Sortie(1);
};
// calcul éventuel des invariants liés aux contraintes
void Loi_comp_abstraite::CalculInvariants_contraintes
(PtIntegMecaInterne& ptIntegMeca, TenseurBB & gijBB,TenseurHH & gijHH)
{ // def de la dimension des tenseurs
int dimT = ptIntegMeca.EpsBB()->Dimension();
int caas=0; // pour la gestion d'erreur éventuelle
// on calcul maintenant systématiquement les contraintes de Mises et Tresca
TenseurHB& sigHB = *(NevezTenseurHB(dimT)) ;
sigHB = (*(ptIntegMeca.SigHH()) * gijBB);
// calcul de Mises et Tresca
Coordonnee valPropreSig(sigHB.ValPropre(caas));
if (caas == -1)
{cout << "\n *** erreur dans le calcul des valeurs propres de sigma "
<< " pb eventuel si on doit ensuite les utiliser (dans une fonction nD par exemple) "
<< " on continue neanmoins ...";
cout << "\n Loi_comp_abstraite::CalculInvariants_contraintes(..." << flush;
};
Tableau <double>& tab_sig_equi = ptIntegMeca.Sig_equi();
Coordonnee& vv = valPropreSig; int dimvec=vv.Dimension();// pour condenser l'écriture
double& sig_mises = tab_sig_equi(1); // pour être plus explicite
double& Tresca = tab_sig_equi(2); // "
switch (dimvec) // dans le cas où dimvec=0 on ne fait rien, cas ou on n'a pas besoin de mises
{ case 1: sig_mises = Dabs(vv(1)); Tresca=0.5 * vv(1);
break;
case 2: sig_mises = sqrt( ((vv(1)-vv(2))*(vv(1)-vv(2)) + vv(1) * vv(1)
+ vv(2) * vv(2)) * 0.5);
Tresca=0.5 * (vv(1)-vv(2));
break;
case 3: sig_mises = sqrt( ((vv(1)-vv(2))*(vv(1)-vv(2)) + (vv(1)-vv(3))*(vv(1)-vv(3))
+ (vv(3)-vv(2))*(vv(3)-vv(2))) * 0.5);
Tresca=0.5 * (vv(1)-vv(3));
break;
default: cout << "\n erreur de dimension, ne doit pas arriver ?? "
<< "\n Loi_comp_abstraite::CalculInvariants_contraintes(..." << flush;
Sortie(1);
};
// calcul éventuel des invariants
if (ptIntegMeca.Statut_Invariants_contrainte())
{ Vecteur & invariant = ptIntegMeca.SigInvar();
invariant.Change_taille(Abs(dimT));
switch (abs(dimT))
{case 3: invariant(3)= sigHB.Det();
case 2: invariant(2)= sigHB.II();
case 1: invariant(1)= sigHB.Trace();
};
////----- debug
////if ((invariant(1) > 0.) && ((*(ptIntegMeca.SigHH()))(1,1) < 0.))
// { cout << "\n Loi_comp_abstraite::CalculInvariants "
// << " invariant(1)= "<<invariant(1)<< ", (*(ptIntegMeca.SigHH()))(1,1)= "<< (*(ptIntegMeca.SigHH()))(1,1)
// << endl;
// };
////--- fin debug
};
TenseurHB * ptHB = &sigHB; delete ptHB;
};
// calcul éventuel des invariants liés uniquement à la cinématique
void Loi_comp_abstraite::CalculInvariants_cinematique
(PtIntegMecaInterne& ptIntegMeca, TenseurBB & gijBB,TenseurHH & gijHH)
{ // def de la dimension des tenseurs
int dimT = ptIntegMeca.EpsBB()->Dimension();
int caas=0; // pour la gestion d'erreur éventuelle
if (ptIntegMeca.Statut_Invariants_deformation())
{ TenseurHB& epsHB = *(NevezTenseurHB(dimT)) ;
epsHB = gijHH * (*(ptIntegMeca.EpsBB()));
Vecteur & invariant = ptIntegMeca.EpsInvar();
invariant.Change_taille(Abs(dimT));
switch (abs(dimT))
{case 3: invariant(3)= epsHB.Det();
case 2: invariant(2)= epsHB.II();
case 1: invariant(1)= epsHB.Trace();
};
// ptIntegMeca.EpsInvar() = epsHB.ValPropre(caas);
// if (caas == -1)
// { cout << "\n warning *** erreur dans le calcul des valeurs propres de la deformation";
// if (ParaGlob::NiveauImpression() >= 7) {epsHB.Ecriture(cout); cout << "\nLoi_comp_abstraite::CalculInvariants(...";};
// cout << endl;
// };
TenseurHB * ptHB = &epsHB; delete ptHB;
};
if (ptIntegMeca.Statut_Invariants_vitesseDeformation())
{ TenseurHB& DepsHB = *(NevezTenseurHB(dimT)) ;
DepsHB = gijHH * (*(ptIntegMeca.DepsBB()));
Vecteur & invariant = ptIntegMeca.DepsInvar();
invariant.Change_taille(Abs(dimT));
switch (abs(dimT))
{case 3: invariant(3)= DepsHB.Det();
case 2: invariant(2)= DepsHB.II();
case 1: invariant(1)= DepsHB.Trace();
};
TenseurHB * ptHB = &DepsHB; delete ptHB;
// ptIntegMeca.DepsInvar() = DepsHB.ValPropre(caas);
// if (caas == -1)
// { cout << "\n warning *** erreur dans le calcul des valeurs propres de la vitesse de deformation";
// if (ParaGlob::NiveauImpression() >= 7) {DepsHB.Ecriture(cout); cout << "\nLoi_comp_abstraite::CalculInvariants(...";};
// cout << endl;
// };
};
};
// récupération de valeurs interpolées pour les grandeur enu ou directement calculées
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
// une seule des 3 métriques doit-être renseigné, les autres doivent être un pointeur nul
// exclure_dd_etend: donne une liste de Ddl_enum_etendu à exclure de la recherche
// parce que par exemple, ils sont calculés par ailleurs
// on peut également ne pas définir de métrique, dans ce cas on ne peut pas calculer certaines grandeurs
// -> il y a vérification
Tableau <double> Loi_comp_abstraite::Valeur_multi_interpoler_ou_calculer
(bool absolue, Enum_dure temps,const List_io<Ddl_enum_etendu>& enu
,const Met_abstraite::Impli* ex_impli
,const Met_abstraite::Expli_t_tdt* ex_expli_tdt
,const Met_abstraite::Umat_cont* ex_umat
,const List_io<Ddl_enum_etendu>* exclure_dd_etend
)
{ // on a besoin a priori de ptintmeca_en_cours, donc s'il n'est pas définit -> erreur
#ifdef MISE_AU_POINT
if (ptintmeca_en_cours == NULL)
{cout << "\n *** cas non prevu : aucun conteneur de point d'integration transmis "
<< "\n Loi_comp_abstraite::Valeur_multi_interpoler_ou_calculer(..." << endl;
Sortie(1);
};
if (def_en_cours == NULL)
{cout << "\n *** cas non prevu : la deformation n'est pas transmise "
<< "\n Loi_comp_abstraite::Valeur_multi_interpoler_ou_calculer(..." << endl;
Sortie(1);
};
#endif
// 2) le fait que l'on veut une sortie dans une base ad hoc ou pas
int dim = ptintmeca_en_cours->EpsBB_const().Dimension();
int dim_sortie_tenseur = dim;
// dans le cas ou l'on veut une sortie en base absolue, il faut que dim_sortie_tenseur = la dimension de la base absolue
if (absolue)
dim_sortie_tenseur = ParaGlob::Dimension();
// --- pour ne faire qu'un seul test ensuite
bool prevoir_change_dim_tenseur = false;
if (absolue)
// mais en fait, quand on sort en absolu on est obligé d'utiliser un tenseur intermédiaire
// car BaseAbsolue(.. modifie tenseur passé en paramètre, donc dans tous les cas de sortie absolue
// il faut un tenseur intermédiaire qui a ou non une dimension différente
prevoir_change_dim_tenseur = true;
// 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;
};
// -- def des tenseurs locaux
Coordonnee* Mtdt = NULL; // coordonnées finales éventuelles du point d'intégration considéré
Coordonnee* Mt=NULL; // coordonnées à t
Coordonnee* M0 = NULL; // coordonnées initiales éventuelles du point d'intégration considéré
Coordonnee* N_surf = NULL; // coordonnée d'un vecteur normal actuel si c'est adéquate
Coordonnee* N_surf_t = NULL; // coordonnée d'un vecteur normal à t si c'est adéquate
Coordonnee* N_surf_t0 = NULL; // coordonnée d'un vecteur normal à t0 si c'est adéquate
Coordonnee* Vitesse = NULL; // cas des vitesses
Tableau <double> tab_ret (enu.size());
// éléments de métrique et matrices de passage
TenseurHH* gijHH;TenseurBB* gijBB;BaseB* giB; BaseH* giH_0;BaseH* giH;
BaseB* giB_0;BaseB* giB_t;
Mat_pleine jB0(dim,dim),jBfin(dim,dim);
bool pas_de_metrique_dispo = false; // init
if (ex_impli != NULL)
{ gijHH = ex_impli->gijHH_tdt;gijBB = ex_impli->gijBB_tdt;
giB = ex_impli->giB_tdt; giH_0 = ex_impli->giH_0;giH = ex_impli->giH_tdt;
giB_0 = ex_impli->giB_0;giB_t = ex_impli->giB_t;
}
else if (ex_expli_tdt != NULL)
{gijHH = ex_expli_tdt->gijHH_tdt;gijBB = ex_expli_tdt->gijBB_tdt;
giB = ex_expli_tdt->giB_tdt; giH_0 = ex_expli_tdt->giH_0;giH = ex_expli_tdt->giH_tdt;
giB_0 = ex_expli_tdt->giB_0; giB_t = ex_expli_tdt->giB_t;
}
else if (ex_umat != NULL)
{gijHH = ex_umat->gijHH_t;gijBB = ex_umat->gijBB_t;
giB = giB_t = ex_umat->giB_t; giH_0 = ex_umat->giH_0;giH = ex_umat->giH_t;
giB_0 = ex_umat->giB_0;
}
else
{ pas_de_metrique_dispo = true;
// cout << "\n *** cas non prevu : aucune metrique transmise "
// << "\n Loi_comp_abstraite::Valeur_multi_interpoler_ou_calculer(..." << endl;
// Sortie(1);
};
// on définie des indicateurs pour ne pas faire plusieurs fois le même calcul
List_io<Ddl_enum_etendu>::const_iterator ie,iefin=enu.end();
bool besoin_coordonnees = false; bool besoin_deplacements = false;
bool besoin_coordonnees_t = false;bool besoin_coordonnees_t0 = false;
for (ie=enu.begin(); ie!=iefin;ie++)
{ int posi = (*ie).Position()-NbEnum_ddl();
switch (posi)
{
case 114: case 115: case 116: // le vecteur normal
{ N_surf = new Coordonnee(ParaGlob::Dimension()); break;}
case 117: case 118: case 119: // le vecteur normal à t
{ N_surf_t = new Coordonnee(ParaGlob::Dimension()); break;}
case 120: case 121: case 122: // le vecteur normal à t0
{ N_surf_t0 = new Coordonnee(ParaGlob::Dimension()); break;}
case 123: case 124: case 125: // la position à t
{ Mt = new Coordonnee(ParaGlob::Dimension());
besoin_coordonnees_t = true;
break;
}
case 126: case 127: case 128: // la position à t0
{ M0 = new Coordonnee(ParaGlob::Dimension());
besoin_coordonnees_t0 = true;
break;
}
default:
break;
};
};
// définition des tenseurs si nécessaire
// ----- maintenant on calcule les grandeurs nécessaires -----
if (besoin_coordonnees)
{Mtdt = new Coordonnee(ParaGlob::Dimension());
*Mtdt = def_en_cours->Position_tdt();
};
if (besoin_coordonnees_t )
{*Mt = def_en_cours->Position_tdt();
};
if (besoin_deplacements || besoin_coordonnees_t0)
{if (M0 == NULL)
M0 = new Coordonnee(ParaGlob::Dimension());
(*M0) = def_en_cours->Position_0();
};
if (Vitesse != NULL)
{Vitesse = new Coordonnee(ParaGlob::Dimension());
(*Vitesse) = def_en_cours->VitesseM_tdt();
};
// def éventuelle du vecteur normal: ceci n'est correct qu'avec une métrique 2D
if (N_surf != NULL)
{ if (pas_de_metrique_dispo)
{ cout << "\n ***erreur, la grandeur N_surf necessite la donnee de la metrique "
<< " or elle n'est pas ici disponible !! ";
Sortie(1);
};
// on vérifie que la métrique est correcte
if (giB->NbVecteur() != 2)
{if (ParaGlob::NiveauImpression() > 0)
{cout << "\n *** attention il ne s'agit pas d'une metrique 2D 2D,"
<< " le vecteur normal ne sera pas correctement calcule";
if (ParaGlob::NiveauImpression() > 2)
cout << "\n Loi_comp_abstraite::Valeur_multi_interpoler_ou_calculer(... ";
};
cout << endl;
}
else // sinon c'est ok
{// la normale vaut le produit vectoriel des 2 premiers vecteurs
(*N_surf) = Util::ProdVec_coorBN( (*giB)(1), (*giB)(2));
N_surf->Normer(); // que l'on norme
};
};
// idem à l'instant t
if (N_surf_t != NULL)
{ if (pas_de_metrique_dispo)
{ cout << "\n ***erreur, la grandeur N_surf_t necessite la donnee de la metrique "
<< " or elle n'est pas ici disponible !! ";
Sortie(1);
};
// on vérifie que la métrique est correcte
if (giB_t->NbVecteur() != 2)
{if (ParaGlob::NiveauImpression() > 0)
{cout << "\n *** attention il ne s'agit pas d'une metrique 2D 2D,"
<< " le vecteur normal ne sera pas correctement calcule";
if (ParaGlob::NiveauImpression() > 2)
cout << "\n Loi_comp_abstraite::Valeur_multi_interpoler_ou_calculer(... ";
};
cout << endl;
}
else // sinon c'est ok
{// la normale vaut le produit vectoriel des 2 premiers vecteurs
(*N_surf_t) = Util::ProdVec_coorBN( (*giB_t)(1), (*giB_t)(2));
N_surf_t->Normer(); // que l'on norme
};
};
// idem à l'instant t0
if (N_surf_t0 != NULL)
{ if (pas_de_metrique_dispo)
{ cout << "\n ***erreur, la grandeur N_surf_0 necessite la donnee de la metrique "
<< " or elle n'est pas ici disponible !! ";
Sortie(1);
};
// on vérifie que la métrique est correcte
if (giB_0->NbVecteur() != 2)
{if (ParaGlob::NiveauImpression() > 0)
{cout << "\n *** attention il ne s'agit pas d'une metrique 2D 2D,"
<< " le vecteur normal ne sera pas correctement calcule";
if (ParaGlob::NiveauImpression() > 2)
cout << "\n Loi_comp_abstraite::Valeur_multi_interpoler_ou_calculer(... ";
};
cout << endl;
}
else // sinon c'est ok
{// la normale vaut le produit vectoriel des 2 premiers vecteurs
(*N_surf_t0) = Util::ProdVec_coorBN( (*giB_0)(1), (*giB_0)(2));
N_surf_t0->Normer(); // que l'on norme
};
// on n'arrête pas l'exécution, car on pourrait vouloir sortir les normales pour un ensemble
// d'éléments contenant des volumes, des surfaces, des lignes: bon... il y aura quand même des
// pb au niveau des iso par exemple, du au fait que l'on va faire des moyennes sur des éléments
// de type différents (à moins de grouper par type du coup on n'aura pas le warning
};
//----- fin du calcul des grandeurs nécessaires -----
// init pour l'utilisation de la liste d'exclusion
List_io<Ddl_enum_etendu>::const_iterator itt_deb;
List_io<Ddl_enum_etendu>::const_iterator itt_fin;
if (exclure_dd_etend != NULL)
{ itt_deb = exclure_dd_etend->begin();
itt_fin = exclure_dd_etend->end();
};
// on balaie maintenant la liste des grandeurs à sortir
int it; // it est l'indice dans le tableau de retour
for (it=1,ie=enu.begin(); ie!=iefin;ie++,it++)
{ if ((Meme_famille((*ie).Enum(),SIG11)) || (Meme_famille((*ie).Enum(),EPS11))
|| (Meme_famille((*ie).Enum(),DEPS11)) || (Meme_famille((*ie).Enum(),X1))
|| (Meme_famille((*ie).Enum(),UX)) )
{ // on recherche en générale une interpolation en fonction des noeuds: il faut donc que la grandeur soit
// présente aux noeuds !!
// def du numéro de référence du ddl_enum_etendue
int posi = (*ie).Position()-NbEnum_ddl();
// récupération des informations en fonction des différents cas
// **** 1 >>>>> -- cas des ddl pur, que l'on sort dans le repère global par défaut
// cas des contraintes
if ((Meme_famille((*ie).Enum(),SIG11)) && ((*ie).Nom_vide()))
{ tab_ret(it)= def_en_cours->DonneeInterpoleeScalaire((*ie).Enum(),temps);
}
else if ((Meme_famille((*ie).Enum(),EPS11)) && ((*ie).Nom_vide()))
{ tab_ret(it)= def_en_cours->DonneeInterpoleeScalaire((*ie).Enum(),temps);
}
else if ((Meme_famille((*ie).Enum(),DEPS11)) && ((*ie).Nom_vide()))
{ tab_ret(it)= def_en_cours->DonneeInterpoleeScalaire((*ie).Enum(),temps);
}
else if ((Meme_famille((*ie).Enum(),X1)) && ((*ie).Nom_vide()))
{ tab_ret(it)= (*Mtdt)((*ie).Enum() - X1 +1);
}
else if ((Meme_famille((*ie).Enum(),UX)) && ((*ie).Nom_vide()))
{ int i_cor = (*ie).Enum() - UX +1; // l'indice de coordonnée
tab_ret(it)= (*Mtdt)(i_cor) - (*M0)(i_cor);
}
else if ((Meme_famille((*ie).Enum(),V1)) && ((*ie).Nom_vide()))
{ int i_cor = (*ie).Enum() - V1 +1; // l'indice de coordonnée
tab_ret(it)= (*Vitesse)(i_cor);
}
// --- a complèter ----
else
{// **** 2 >>>>> -- cas des grandeurs déduites des ddl pures
switch (posi)
{ case 31: /*contrainte_mises*/
tab_ret(it)=ptintmeca_en_cours->Sig_equi_const()(1);break;
case 32: /* contrainte_tresca */
tab_ret(it)=ptintmeca_en_cours->Sig_equi_const()(2);break;
case 77: /*def_duale_mises*/ tab_ret(it)=ptintmeca_en_cours->Deformation_equi_const()(2);break;
case 87: /*def_equivalente*/ tab_ret(it)=ptintmeca_en_cours->Deformation_equi_const()(1);break;
case 88: /*def_duale_mises_maxi*/ tab_ret(it)=ptintmeca_en_cours->Deformation_equi_const()(3);break;
case 89: /*vitesse_def_equivalente*/ tab_ret(it)=ptintmeca_en_cours->Deformation_equi_const()(4) * unSurDeltat;break;
case 114: // le vecteur normal N_surf_1
{tab_ret(it)= (*N_surf)(1);break;}
case 115: // le vecteur normal N_surf_2
{tab_ret(it)= (*N_surf)(2);break;}
case 116: // le vecteur normal N_surf_3
{tab_ret(it)= (*N_surf)(3);break;}
case 117: // le vecteur normal N_surf_1_t
{tab_ret(it)= (*N_surf_t)(1);break;}
case 118: // le vecteur normal N_surf_2_t
{tab_ret(it)= (*N_surf_t)(2);break;}
case 119: // le vecteur normal N_surf_3_t
{tab_ret(it)= (*N_surf_t)(3);break;}
case 120: // le vecteur normal N_surf_1_t0
{tab_ret(it)= (*N_surf_t0)(1);break;}
case 121: // le vecteur normal N_surf_2_t0
{tab_ret(it)= (*N_surf_t0)(2);break;}
case 122: // le vecteur normal N_surf_3_t0
{tab_ret(it)= (*N_surf_t0)(3);break;}
case 123: // la position géométrique Mt
{tab_ret(it)= (*Mt)(1);break;}
case 124: // la position géométrique Mt
{tab_ret(it)= (*Mt)(2);break;}
case 125: // la position géométrique Mt
{tab_ret(it)= (*Mt)(3);break;}
case 126: // la position géométrique M0
{tab_ret(it)= (*M0)(1);break;}
case 127: // la position géométrique M0
{tab_ret(it)= (*M0)(2);break;}
case 128: // la position géométrique M0
{tab_ret(it)= (*M0)(3);break;}
default :
{// on regarde si la grandeur en fait n'est pas à calculer
bool a_atraiter = true;
if (exclure_dd_etend != NULL)
if (find(itt_deb,itt_fin,(*ie)) != itt_fin)
a_atraiter = false;
if (a_atraiter)
{cout << "\n cas de ddl actuellement non traite "
<< "\n pas de ddl " << (*ie).Nom() << " dans l'element "
<< "\n ou cas non implante pour l'instant"
<< "\n Loi_comp_abstraite::Valeur_multi_interpoler_ou_calculer(...";
tab_ret(it) = 0.;
};
};
} // fin cas **** 2 >>>>>
} // " " "
} // -- fin
else if (( (*ie).Enum() == TEMP) && ((*ie).Nom_vide()))
{tab_ret(it)= def_en_cours->DonneeInterpoleeScalaire(TEMP,temps);
}
else
{ tab_ret(it) = 0.;
cout << "\n cas de ddl actuellement non traite "
<< "\n pas de ddl " << (*ie).Nom() << " dans l'element "
<< "\n ou cas non implante pour l'instant, on retourne 0"
<< "\n Loi_comp_abstraite::Valeur_multi_interpoler_ou_calculer(...";
};
};// -- fin de la boucle sur la liste de Ddl_enum_etendu
// delet e des tenseurs
if (Mtdt != NULL) delete Mtdt; // coordonnée du point à tdt
if (Mt != NULL ) delete Mt; // la position à t
if (M0 != NULL ) delete M0; // coordonnée du point à 0
if (N_surf != NULL) delete N_surf; // vecteur normal à la surface
if (N_surf_t != NULL) delete N_surf_t; // vecteur normal à t à la surface
if (N_surf_t0 != NULL) delete N_surf_t0; // vecteur normal à la surface
if (Vitesse != NULL) delete Vitesse; // vitesse
// liberation des tenseurs intermediaires
LibereTenseur();
return tab_ret;
};
// affichage de la liste des grandeurs possible à calculer avec Valeur_multi_interpoler_ou_calculer
void Loi_comp_abstraite::Affichage_grandeurs_Valeur_multi_interpoler_ou_calculer()
{ cout << "\n grandeurs scalaires disponibles :";
cout << "\n Mtdt(i) -> X1, X2 ..., Mt(i) -> X1_t, X2_t ..., M0(i) -> X1_t0, X2_t0..,"
<< "\n si pertinent: N_surf(i) -> N_surf_1.., N_surf_t(i) -> N_surf_1_t.., N_surf_t0(i) -> N_surf_1_t0..."
<< "\n SIG11 SIG12 ..., EPS11, EPS12 ..., UX, UY, UZ , V1,V2,V3"
<< "\n def_duale_mises, def_equivalente, def_duale_mises_maxi, vitesse_def_equivalente"
<< "\n contrainte de Mises, contrainte de Tresca"
<< "\n temperature -> TEMP "
;
};
// récupération de valeurs interpolées pour les grandeur enu
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
// une seule des 3 métriques doit-être renseigné, les autres doivent être un pointeur nul
// exclure_Q: donne une liste de grandeur quelconque à exclure de la recherche
// parce que par exemple, ils sont calculés par ailleurs
// on peut également ne pas définir de métrique, dans ce cas on ne peut pas calculer certaines grandeurs
// -> il y a vérification
void Loi_comp_abstraite::Valeurs_Tensorielles_interpoler_ou_calculer
(bool absolue, Enum_dure temps,List_io<TypeQuelconque>& enu
,const Met_abstraite::Impli* ex_impli
,const Met_abstraite::Expli_t_tdt* ex_expli_tdt
,const Met_abstraite::Umat_cont* ex_umat
,const List_io<EnumTypeQuelconque>* exclure_Q
)
// la dimension des tenseurs de retour est obligatoirement celle de l'espace
// Dans le cas ou on veut une base ad hoc, on calcule dans la base ad hoc et on
// transfert dans le conteneur: ainsi dans ce cas seule les composantes de la base
// ad hoc sont alimentées:
// exemple: base ad hoc : dim 1, espace 3 -> eps11 sera stocké dans le conteneur
// en 11, les autres seront nulles
{ // on a besoin a priori de ptintmeca_en_cours, donc s'il n'est pas définit -> erreur
#ifdef MISE_AU_POINT
if (ptintmeca_en_cours == NULL)
{cout << "\n *** cas non prevu : aucun conteneur de point d'integration transmis "
<< "\n Loi_comp_abstraite::Valeurs_Tensorielles_interpoler_ou_calculer(..." << endl;
Sortie(1);
};
if (def_en_cours == NULL)
{cout << "\n *** cas non prevu : la deformation n'est pas transmise "
<< "\n Loi_comp_abstraite::Valeurs_Tensorielles_interpoler_ou_calculer(..." << endl;
Sortie(1);
};
#endif
// ----- def de grandeurs de travail
// def de la dimension des tenseurs
// il y a deux pb a gérer: 1) le fait que la dimension absolue peut-être différente de la dimension actuelle des tenseurs calculés
// 2) le fait que l'on veut une sortie dans une base ad hoc ou pas
// 3) le fait que les conteneurs de retour peuvent ne pas avoir la dimension voulue
int dim = ptintmeca_en_cours->EpsBB_const().Dimension(); // == a dimension actuelle des tenseurs calculés
int dim_sortie_tenseur = dim; // init
// dans le cas ou l'on veut une sortie en base absolue, il faut que dim_sortie_tenseur = la dimension de la base absolue
int dim_espace = ParaGlob::Dimension();
if (absolue)
dim_sortie_tenseur = dim_espace;
// pour ne faire qu'un seul test ensuite
bool prevoir_change_dim_tenseur = false;
// initialement on faisait le test suivant,
// if ((absolue) && (dim != dim_sortie_tenseur))
if (absolue)
// mais en fait, quand on sort en absolu on est obligé d'utiliser un tenseur intermédiaire
// car BaseAbsolue(.. modifie tenseur passé en paramètre, donc dans tous les cas de sortie absolue
// il faut un tenseur intermédiaire qui a ou non une dimension différente
prevoir_change_dim_tenseur = true;
// si on n'est pas en absolue, donc on est en ad hoc (c'est l'un ou l'autre)
// et si la dim ad hoc est différente de dim_espace, alors il faut aussi
// un tenseur intermédiaire mais de dim ad hoc
bool transfert_tenseur = false;
if ((!absolue)&&(dim != dim_espace))
{dim_sortie_tenseur = dim; // la dimension des tenseurs intermédiaires créés
transfert_tenseur = true;
}
// éléments de métrique et matrices de passage
TenseurHH* gijHH;TenseurBB* gijBB;BaseB* giB; BaseH* giH_0;BaseH* giH;
Mat_pleine jB0(dim,dim),jBfin(dim,dim);
BaseB* giB_0;BaseB* giB_t;
bool pas_de_metrique_dispo = false; // init
if (ex_impli != NULL)
{ gijHH = ex_impli->gijHH_tdt;gijBB = ex_impli->gijBB_tdt;
giB = ex_impli->giB_tdt; giH_0 = ex_impli->giH_0;giH = ex_impli->giH_tdt;
giB_t = ex_impli->giB_t; giB_0 = ex_impli->giB_0;
}
else if (ex_expli_tdt != NULL)
{gijHH = ex_expli_tdt->gijHH_tdt;gijBB = ex_expli_tdt->gijBB_tdt;
giB = ex_expli_tdt->giB_tdt; giH_0 = ex_expli_tdt->giH_0;giH = ex_expli_tdt->giH_tdt;
giB_t = ex_expli_tdt->giB_t; giB_0 = ex_expli_tdt->giB_0;
}
else if (ex_umat != NULL)
{gijHH = ex_umat->gijHH_t;gijBB = ex_umat->gijBB_t;
giB = giB_t = ex_umat->giB_t; giH_0 = ex_umat->giH_0;giH = ex_umat->giH_t;
giB_0 = ex_umat->giB_0;
}
else
{ pas_de_metrique_dispo = true;
};
// def de tenseurs pour la sortie
// les tenseurs restants en locale
TenseurHH* sigHH=NULL;TenseurBB* epsBB=NULL;TenseurBB* epslogBB=NULL;
TenseurBB* epsAlmBB=NULL;TenseurBB* eps0BB=NULL;TenseurBB* DepsBB = NULL;
TenseurBB* epsAlmTotalBB=NULL;TenseurBB* epsGLTotalBB=NULL;TenseurBB* epsLogTotalBB=NULL;
TenseurBB* DeltaEpsBB = NULL;
Coordonnee* Mtdt=NULL; // coordonnées éventuelles du point d'intégration considéré
Coordonnee* Mt=NULL; // coordonnées à t
Coordonnee* M0=NULL; // coordonnées à t0
Coordonnee* N_surf = NULL; // coordonnée d'un vecteur normal si c'est adéquate
Coordonnee* N_surf_t = NULL; // coordonnée d'un vecteur normal à t si c'est adéquate
Coordonnee* N_surf_t0 = NULL; // coordonnée d'un vecteur normal à t0 si c'est adéquate
Coordonnee* Vitesse = NULL; // cas des vitesses
Coordonnee* Deplacement = NULL; // cas du déplacement
// pour les valeurs propres
Coordonnee* valPropreSig=NULL;Coordonnee* valPropreEps=NULL;
Coordonnee* valPropreDeps=NULL;
// pour les vecteurs propres
Tableau <Coordonnee *> base_propre_sigma , base_propre_eps , base_propre_D;
// pour les bases
Tableau <Coordonnee *> base_ad_hoc , base_giH , base_giB;
// grandeurs scalaires
// grandeurs scalaires
double* Mises = NULL; double* defDualMises = NULL; double* Tresca = NULL;
double* erreur = NULL;double* erreur_rel = NULL;
double* spherique_eps=NULL,* Q_eps=NULL,* cos3phi_eps=NULL;
double* spherique_sig=NULL,* Q_sig=NULL,* cos3phi_sig=NULL;
double* spherique_Deps=NULL,* Q_Deps=NULL,* cos3phi_Deps=NULL;
double* def_equivalente=NULL, * defDualMisesMaxi=NULL;
double* sig_mises= NULL; // *** peut-être en trop
double* sig_tresca = NULL; // *** peut-être en trop
// --- dev d'un ensemble de variable booléenne pour gérer les sorties en une passe -----
// on se réfère au informations définit dans la méthode: Les_type_evolues_internes()
bool deformationCourante=false; bool vitesseDeformationCourante=false;
bool almansi=false; bool greenLagrange=false;
bool logarithmique=false; bool deltaDef=false;
bool almansiTotal=false; bool greenLagrangeTotale=false;
bool logarithmiqueTotale=false; bool contrainteCourante=false;
bool defPrincipales=false; bool sigmaPrincipales=false;
bool vitPrincipales=false; bool contrainteMises=false;
// bool contraintesTresca=false; bool erreurQ=false;
// bool erreurRel = false;
bool defPlastiqueCumulee=false; bool def_duale_mises=false;
bool besoin_des_contraintes=false; bool besoin_des_deformation=false;
bool besoin_des_contraintes_barre=false; bool besoin_des_deformation_barre=false;
bool besoin_des_vitesses_deformation=false; bool besoin_des_vitesses_deformation_barre=false;
bool besoin_des_valpropre_sigma=false;
bool besoin_des_valpropre_deformation = false; bool besoin_des_valpropre_vitdef = false;
bool besoin_coordonnees = false;
bool besoin_coordonnees_t = false;bool besoin_coordonnees_t0 = false;
bool besoin_dir_princ_sig = false; bool besoin_dir_princ_eps = false;
bool besoin_dir_princ_D = false;
bool besoin_rep_local_ortho=false;
bool besoin_rep_giH = false; bool besoin_rep_giB = false;
bool def_SPHERIQUE_EPS = false; bool def_Q_EPS = false; bool def_COS3PHI_EPS = false;
bool def_SPHERIQUE_SIG = false; bool def_Q_SIG = false; bool def_COS3PHI_SIG = false;
bool def_SPHERIQUE_DEPS = false; bool def_Q_DEPS = false; bool def_COS3PHI_DEPS = false;
bool def_def_equivalente = false; bool def_duale_mises_maxi = false;
// --- dev d'un ensemble de variable booléenne pour gérer les sorties en une passe -----
// on se réfère au informations définit dans la méthode: Les_type_evolues_internes()
bool def_sig_mises= false; // *** peut-être en trop
bool def_sig_tresca= false; // *** peut-être en trop
// init pour l'utilisation de la liste d'exclusion
List_io<EnumTypeQuelconque>::const_iterator itt_deb;
List_io<EnumTypeQuelconque>::const_iterator itt_fin;
if (exclure_Q != NULL)
{ itt_deb = exclure_Q->begin();
itt_fin = exclure_Q->end();
};
// on initialise ces variables booléennes et les conteneurs
List_io<TypeQuelconque>::iterator ipq,ipqfin=enu.end();
for (ipq=enu.begin();ipq!=ipqfin;ipq++)
{EnumTypeQuelconque enuconq = (*ipq).EnuTypeQuelconque().EnumTQ();
switch (enuconq)
{ case CONTRAINTE_COURANTE : {contrainteCourante=true; besoin_des_contraintes=true;
Grandeur_TenseurHH& gr= *((Grandeur_TenseurHH*) ((*ipq).Grandeur_pointee()));
sigHH = gr.ConteneurTenseur();
break;}
case DEFORMATION_COURANTE : {deformationCourante=true; besoin_des_deformation=true;
Grandeur_TenseurBB& gr= *((Grandeur_TenseurBB*) ((*ipq).Grandeur_pointee()));
epsBB = gr.ConteneurTenseur(); break;}
case VITESSE_DEFORMATION_COURANTE : {vitesseDeformationCourante=true;
Grandeur_TenseurBB& gr= *((Grandeur_TenseurBB*) ((*ipq).Grandeur_pointee()));
DepsBB = gr.ConteneurTenseur(); besoin_des_vitesses_deformation=true; break;}
case ALMANSI : {almansi=true; besoin_des_deformation=true;
Grandeur_TenseurBB& gr= *((Grandeur_TenseurBB*) ((*ipq).Grandeur_pointee()));
epsAlmBB = gr.ConteneurTenseur(); break;}
case GREEN_LAGRANGE : {greenLagrange=true; besoin_des_deformation=true;
Grandeur_TenseurBB& gr= *((Grandeur_TenseurBB*) ((*ipq).Grandeur_pointee()));
eps0BB = gr.ConteneurTenseur(); break;}
case LOGARITHMIQUE : {logarithmique=true; besoin_des_deformation=true;
Grandeur_TenseurBB& gr= *((Grandeur_TenseurBB*) ((*ipq).Grandeur_pointee()));
epslogBB = gr.ConteneurTenseur(); break;}
case DELTA_DEF : {deltaDef=true; besoin_des_deformation=true;
Grandeur_TenseurBB& gr= *((Grandeur_TenseurBB*) ((*ipq).Grandeur_pointee()));
DeltaEpsBB = gr.ConteneurTenseur(); break;}
case ALMANSI_TOTAL : {almansiTotal=true; besoin_des_deformation=true;
Grandeur_TenseurBB& gr= *((Grandeur_TenseurBB*) ((*ipq).Grandeur_pointee()));
epsAlmTotalBB = gr.ConteneurTenseur(); break;}
case GREEN_LAGRANGE_TOTAL : {greenLagrangeTotale=true; besoin_des_deformation=true;
Grandeur_TenseurBB& gr= *((Grandeur_TenseurBB*) ((*ipq).Grandeur_pointee()));
epsGLTotalBB = gr.ConteneurTenseur(); break;}
case LOGARITHMIQUE_TOTALE : {logarithmiqueTotale=true; besoin_des_deformation=true;
Grandeur_TenseurBB& gr= *((Grandeur_TenseurBB*) ((*ipq).Grandeur_pointee()));
epsLogTotalBB = gr.ConteneurTenseur(); break;}
case DEF_PRINCIPALES : {defPrincipales=true; besoin_des_deformation=true;
besoin_des_valpropre_deformation=true;
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) ((*ipq).Grandeur_pointee()));
valPropreEps = gr.ConteneurCoordonnee(); break;}
case SIGMA_PRINCIPALES : {sigmaPrincipales=true; besoin_des_contraintes=true;
besoin_des_valpropre_sigma=true;
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) ((*ipq).Grandeur_pointee()));
valPropreSig = gr.ConteneurCoordonnee(); break;}
case VIT_PRINCIPALES : {vitPrincipales=true; besoin_des_vitesses_deformation=true;
besoin_des_valpropre_vitdef=true;
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) ((*ipq).Grandeur_pointee()));
valPropreDeps = gr.ConteneurCoordonnee(); break;}
case DEF_DUALE_MISES : {def_duale_mises=true;
Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*ipq).Grandeur_pointee()));
defDualMises = gr.ConteneurDouble();
//besoin_des_valpropre_deformation=true; // non car maintenant on utilise directement ce qui est stocké au pt d'integ
break;}
case DEF_EQUIVALENTE : {def_def_equivalente=true;
Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*ipq).Grandeur_pointee()));
def_equivalente = gr.ConteneurDouble(); break;}
case DEF_DUALE_MISES_MAXI : {def_duale_mises_maxi=true;
Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*ipq).Grandeur_pointee()));
defDualMisesMaxi = gr.ConteneurDouble(); break;}
case CONTRAINTE_MISES : {def_sig_mises=true;
Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*ipq).Grandeur_pointee()));
sig_mises = gr.ConteneurDouble(); break;}
case CONTRAINTE_TRESCA : {def_sig_tresca=true;
Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*ipq).Grandeur_pointee()));
sig_tresca = gr.ConteneurDouble(); break;}
case POSITION_GEOMETRIQUE : {besoin_coordonnees=true;
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) ((*ipq).Grandeur_pointee()));
Mtdt = gr.ConteneurCoordonnee(); break;}
case POSITION_GEOMETRIQUE_t : {besoin_coordonnees_t=true;
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) ((*ipq).Grandeur_pointee()));
Mt = gr.ConteneurCoordonnee(); break;}
case POSITION_GEOMETRIQUE_t0 : {besoin_coordonnees_t0=true;
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) ((*ipq).Grandeur_pointee()));
M0 = gr.ConteneurCoordonnee(); break;}
case SPHERIQUE_EPS : {def_SPHERIQUE_EPS=true; besoin_des_deformation=true;
Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*ipq).Grandeur_pointee()));
spherique_eps = gr.ConteneurDouble(); break;}
case Q_EPS : {def_Q_EPS=true; besoin_des_deformation=true;besoin_des_deformation_barre=true;
Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*ipq).Grandeur_pointee()));
Q_eps = gr.ConteneurDouble(); break;}
case COS3PHI_EPS : {def_COS3PHI_EPS=true; besoin_des_deformation=true;besoin_des_deformation_barre=true;
Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*ipq).Grandeur_pointee()));
cos3phi_eps = gr.ConteneurDouble(); besoin_des_valpropre_deformation=true; break;}
case SPHERIQUE_SIG : {def_SPHERIQUE_SIG=true; besoin_des_contraintes=true;
Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*ipq).Grandeur_pointee()));
spherique_sig = gr.ConteneurDouble(); besoin_des_valpropre_sigma=true; break;}
case Q_SIG : {def_Q_SIG=true; besoin_des_contraintes=true;besoin_des_contraintes_barre=true;
Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*ipq).Grandeur_pointee()));
Q_sig = gr.ConteneurDouble(); break;}
case COS3PHI_SIG : {def_COS3PHI_SIG=true; besoin_des_contraintes=true;besoin_des_contraintes_barre=true;
Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*ipq).Grandeur_pointee()));
cos3phi_sig = gr.ConteneurDouble(); break;}
case SPHERIQUE_DEPS : {def_SPHERIQUE_DEPS=true; besoin_des_vitesses_deformation=true;
Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*ipq).Grandeur_pointee()));
spherique_Deps = gr.ConteneurDouble(); break;}
case Q_DEPS : {def_Q_DEPS=true; besoin_des_vitesses_deformation=true;besoin_des_vitesses_deformation_barre=true;
Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*ipq).Grandeur_pointee()));
Q_Deps = gr.ConteneurDouble(); break;}
case COS3PHI_DEPS : {def_COS3PHI_DEPS=true; besoin_des_vitesses_deformation=true;besoin_des_vitesses_deformation_barre=true;
Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*ipq).Grandeur_pointee()));
cos3phi_Deps = gr.ConteneurDouble(); break;}
case REPERE_LOCAL_ORTHO : {besoin_rep_local_ortho=true;
Tab_Grandeur_Coordonnee& gr= *((Tab_Grandeur_Coordonnee*) ((*ipq).Grandeur_pointee()));
if (pas_de_metrique_dispo)
{ cout << "\n ***erreur, la grandeur REPERE_LOCAL_ORTHO necessite la donnee de la metrique "
<< " or elle n'est pas ici disponible !! ";
Sortie(1);
};
base_ad_hoc.Change_taille(dim_espace);
switch (dim_espace) {case 3: gr(3).Zero(); case 2: gr(2).Zero(); default:break;};//init
switch (dim_espace) {case 3: base_ad_hoc(3) = &(gr(3));
case 2: base_ad_hoc(2) = &(gr(2));
case 1: base_ad_hoc(1) = &(gr(1));
default:break;
};
break;}
case REPERE_LOCAL_H :
{besoin_rep_giH=true;
Tab_Grandeur_Coordonnee& gr= *((Tab_Grandeur_Coordonnee*) ((*ipq).Grandeur_pointee()));
if (pas_de_metrique_dispo)
{ cout << "\n ***erreur, la grandeur REPERE_LOCAL_H necessite la donnee de la metrique "
<< " or elle n'est pas ici disponible !! ";
Sortie(1);
};
base_giH.Change_taille(dim);
switch (dim_espace) {case 3: gr(3).Zero(); case 2: gr(2).Zero(); default:break;};//init
switch (dim) {case 3: base_giH(3) = &(gr(3));
case 2: base_giH(2) = &(gr(2));
case 1: base_giH(1) = &(gr(1));
default:break;
};
break;
}
case REPERE_LOCAL_B :
{besoin_rep_giB=true;
Tab_Grandeur_Coordonnee& gr= *((Tab_Grandeur_Coordonnee*) ((*ipq).Grandeur_pointee()));
if (pas_de_metrique_dispo)
{ cout << "\n ***erreur, la grandeur REPERE_LOCAL_B necessite la donnee de la metrique "
<< " or elle n'est pas ici disponible !! ";
Sortie(1);
};
base_giB.Change_taille(dim);
switch (dim_espace) {case 3: gr(3).Zero(); case 2: gr(2).Zero(); default:break;};//init
switch (dim) {case 3: base_giB(3) = &(gr(3));
case 2: base_giB(2) = &(gr(2));
case 1: base_giB(1) = &(gr(1));
default:break;
};
break;
}
case DIRECTIONS_PRINC_SIGMA : {besoin_des_contraintes=true;
besoin_des_valpropre_sigma=true;besoin_dir_princ_sig=true;
Tab_Grandeur_Coordonnee& gr= *((Tab_Grandeur_Coordonnee*) ((*ipq).Grandeur_pointee()));
if (pas_de_metrique_dispo)
{ cout << "\n ***erreur, la grandeur DIRECTIONS_PRINC_SIGMA necessite la donnee de la metrique "
<< " or elle n'est pas ici disponible !! ";
Sortie(1);
};
switch (dim_espace) {case 3: gr(3).Zero(); case 2: gr(2).Zero(); default:break;};//init
base_propre_sigma.Change_taille(dim);
switch (dim) {case 3: base_propre_sigma(3) = &(gr(3));
case 2: base_propre_sigma(2) = &(gr(2));
case 1: base_propre_sigma(1) = &(gr(1));
default:break;
};
break;}
case DIRECTIONS_PRINC_DEF : {besoin_des_deformation=true;
besoin_des_valpropre_deformation=true;besoin_dir_princ_eps=true;
Tab_Grandeur_Coordonnee& gr= *((Tab_Grandeur_Coordonnee*) ((*ipq).Grandeur_pointee()));
if (pas_de_metrique_dispo)
{ cout << "\n ***erreur, la grandeur DIRECTIONS_PRINC_DEF necessite la donnee de la metrique "
<< " or elle n'est pas ici disponible !! ";
Sortie(1);
};
switch (dim_espace) {case 3: gr(3).Zero(); case 2: gr(2).Zero(); default:break;};//init
base_propre_eps.Change_taille(dim);
switch (dim) {case 3: base_propre_eps(3) = &(gr(3));
case 2: base_propre_eps(2) = &(gr(2));
case 1: base_propre_eps(1) = &(gr(1));
default:break;
};
break;}
case DIRECTIONS_PRINC_D : {vitesseDeformationCourante=true;besoin_des_vitesses_deformation=true;
besoin_des_valpropre_deformation=true;besoin_dir_princ_D=true;
Tab_Grandeur_Coordonnee& gr= *((Tab_Grandeur_Coordonnee*) ((*ipq).Grandeur_pointee()));
if (pas_de_metrique_dispo)
{ cout << "\n ***erreur, la grandeur DIRECTIONS_PRINC_D necessite la donnee de la metrique "
<< " or elle n'est pas ici disponible !! ";
Sortie(1);
};
switch (dim_espace) {case 3: gr(3).Zero(); case 2: gr(2).Zero(); default:break;};//init
base_propre_D.Change_taille(dim);
switch (dim) {case 3: base_propre_D(3) = &(gr(3));
case 2: base_propre_D(2) = &(gr(2));
case 1: base_propre_D(1) = &(gr(1));
default:break;
};
break;}
case NN_SURF:{
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) ((*ipq).Grandeur_pointee()));
N_surf = gr.ConteneurCoordonnee(); break;}
case NN_SURF_t:{
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) ((*ipq).Grandeur_pointee()));
N_surf_t = gr.ConteneurCoordonnee(); break;}
case NN_SURF_t0:{
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) ((*ipq).Grandeur_pointee()));
N_surf_t0 = gr.ConteneurCoordonnee(); break;}
case DEPLACEMENT:{besoin_coordonnees=true;
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) ((*ipq).Grandeur_pointee()));
Deplacement = gr.ConteneurCoordonnee(); break;}
case VITESSE:{
Grandeur_coordonnee& gr= *((Grandeur_coordonnee*) ((*ipq).Grandeur_pointee()));
Vitesse = gr.ConteneurCoordonnee(); break;}
// dans le cas des numéros, traitement direct ici
case NUM_ELEMENT:
{if (ptintmeca_en_cours != NULL)
{*((Grandeur_scalaire_entier*) ((*ipq).Grandeur_pointee()))= ptintmeca_en_cours->Nb_ele();}
// sinon on le laisse à 0
break;
}
case NUM_MAIL_ELEM:
{ if (ptintmeca_en_cours != NULL)
*((Grandeur_scalaire_entier*) ((*ipq).Grandeur_pointee()))= ptintmeca_en_cours->Nb_mail();
break;
}
case NUM_PTI:
{ if (ptintmeca_en_cours != NULL)
*((Grandeur_scalaire_entier*) ((*ipq).Grandeur_pointee()))= ptintmeca_en_cours->Nb_pti();
break;
}
default :
{ // on regarde si la grandeur en fait n'est pas à calculer
bool a_atraiter = true;
if (exclure_Q != NULL)
if (find(itt_deb,itt_fin,enuconq) != itt_fin)
a_atraiter = false;
if (a_atraiter)
// cas où ce n'est pas à exclure, donc cela manque
{// on initialise la grandeur pour éviter d'avoir des valeurs aléatoires
((*ipq).Grandeur_pointee())->InitParDefaut();
if (ParaGlob::NiveauImpression() > 0)
{cout << "\nWarning : attention cas non traite: "
<< (*ipq).EnuTypeQuelconque().NomPlein() << "!\n";
if (ParaGlob::NiveauImpression() > 5)
cout << "\n Loi_comp_abstraite::Valeurs_Tensorielles_interpoler_ou_calculer(....";
};
}; // sinon on ne fait rien, car les grandeurs exclues sont sensées
// être calculés par ailleurs
}
};
};
// on complète les définitions de tenseurs si besoin
// les tenseurs restants en locale
TenseurHB* sigHB = NULL ;TenseurHB* sig_barreHB = NULL ;
TenseurHB* epsHB = NULL ;TenseurHB* eps_barreHB = NULL ;
TenseurHB* DepsHB = NULL ; TenseurHB* Deps_barreHB = NULL ;
if ((besoin_des_contraintes && !contrainteCourante)
|| (besoin_des_valpropre_sigma && !sigmaPrincipales)
)
{sigHH = NevezTenseurHH(dim_sortie_tenseur) ;
sigHB = (NevezTenseurHB(dim)) ;
sig_barreHB = (NevezTenseurHB(dim)) ;
}
else if (besoin_des_contraintes
|| (besoin_des_valpropre_sigma && !sigmaPrincipales)
)
// là il s'agit uniquement des tenseurs locaux
{sigHB = (NevezTenseurHB(dim)) ;
sig_barreHB = (NevezTenseurHB(dim)) ;
};
if ((besoin_des_deformation && !deformationCourante)
|| (besoin_des_valpropre_deformation && !defPrincipales)
)
{epsBB = NevezTenseurBB(dim_sortie_tenseur) ;
epsHB = (NevezTenseurHB(dim)) ;
eps_barreHB = (NevezTenseurHB(dim)) ;
}
else if (besoin_des_deformation
|| (besoin_des_valpropre_deformation && !defPrincipales)
)
// là il s'agit uniquement des tenseurs locaux
{epsHB = (NevezTenseurHB(dim)) ;
eps_barreHB = (NevezTenseurHB(dim)) ;
};
if ((besoin_des_vitesses_deformation && !vitesseDeformationCourante)
|| (besoin_des_valpropre_vitdef && !vitPrincipales)
)
{DepsBB = NevezTenseurBB(dim_sortie_tenseur);
DepsHB = (NevezTenseurHB(dim));
Deps_barreHB = (NevezTenseurHB(dim)) ;
}
else if(besoin_des_vitesses_deformation
|| (besoin_des_valpropre_vitdef && !vitPrincipales)
)
// là il s'agit uniquement des tenseurs locaux
{DepsHB = (NevezTenseurHB(dim));
Deps_barreHB = (NevezTenseurHB(dim)) ;
};
if (besoin_des_valpropre_deformation && !defPrincipales) valPropreEps = new Coordonnee(dim_sortie_tenseur);
if (besoin_des_valpropre_vitdef && !vitPrincipales) valPropreDeps = new Coordonnee(dim_sortie_tenseur);
if (besoin_des_valpropre_sigma && !sigmaPrincipales) valPropreSig = new Coordonnee(dim_sortie_tenseur);
// on statut sur le fait d'avoir besoin ou non des chgt de base
bool besoin_matrice_chg_base = false;
if ( besoin_des_contraintes
|| besoin_des_deformation
|| besoin_des_vitesses_deformation
|| besoin_rep_local_ortho
)
{besoin_matrice_chg_base = true;};
// on ne change pas le numéro de point d'intégration courant
// on considère ici que c'est déjà le bon, puisque c'est appelé par un élément
// a priori ...
// matrices de passage
int dim_effective = dim; // init
if (absolue) dim_effective = ParaGlob::Dimension();
Mat_pleine* Aa0 = NULL;Mat_pleine* Aafin = NULL;
Mat_pleine* gamma0 = NULL;Mat_pleine* gammafin = NULL;
Mat_pleine* beta0 = NULL;Mat_pleine* betafin = NULL;
if (besoin_matrice_chg_base)
// dans le cas où on n'est pas en absolue => on sort dans un repère ad hoc donc
// il a la dimension locale
// sinon on sort dans le repère globale => il a la dimension globale
{Aa0 = new Mat_pleine(dim_effective,dim_effective);
Aafin = new Mat_pleine(dim_effective,dim_effective);
gamma0 = new Mat_pleine(dim_effective,dim_effective);
gammafin = new Mat_pleine(dim_effective,dim_effective);
beta0 = new Mat_pleine(dim_effective,dim_effective);
betafin = new Mat_pleine(dim_effective,dim_effective);
};
// on considère que les métriques sont directement utilisables
// si elles sont disponibles
if (besoin_matrice_chg_base)
{if (pas_de_metrique_dispo)
{cout << "\n *** erreur : on a besoin de matrices de changement de base et il n'y a pas "
<< " de metrique disponible: impossible de continuer"
<< "\n Loi_comp_abstraite::Valeurs_Tensorielles_interpoler_ou_calculer..." << endl;
Sortie(1);
}
else if (def_en_cours== NULL)
{cout << "\n *** erreur : on a besoin de l'objet Deformation et il n'y a pas "
<< " de pointeur de deformation disponible: impossible de continuer"
<< "\n Loi_comp_abstraite::Valeurs_Tensorielles_interpoler_ou_calculer..." << endl;
Sortie(1);
}
else
// on peut calculer
{Mat_pleine Aat(dim_effective,dim_effective);
// a priori Aat ne sert pas par la suite, mais est nécessaire pour le passage de par
const Met_abstraite::Info_et_metrique_0_t_tdt ex
= def_en_cours->Remont_et_metrique_0_t_tdtSansCalMet(absolue,*Aa0,Aat,*Aafin);
// pour les formules de passage de repère il nous faut :
// Ip_a = beta_a^{.j} g_j et Ip^b = gamma^b_{.j} g^j
// on a: [beta_a^{.j}] = [Aa^j_{.a}]^T
// et [gamma^b_{.j}] = [beta_a^{.j}]^{-1T} = [Aa^j_{.a}]^{-1}
(*gamma0) = (Aa0->Inverse());
(*gammafin) = (Aafin->Inverse());
// on détermine également les matrices beta
(*beta0) = (Aa0->Transpose());
(*betafin) = (Aafin->Transpose());
};
};
// récup des bases si besoin
if (besoin_rep_local_ortho)
{if ((!absolue)&&(dim_espace==3)&&(dim==2))
// cas d'éléments 2D, pour lesquels on veut un repère local ad hoc
// on ramène une base à 3 vecteurs
{ *(base_ad_hoc(1)) = jBfin(1,1) * giB->Coordo(1) + jBfin(2,1) * giB->Coordo(2);
*(base_ad_hoc(2)) = jBfin(1,2) * giB->Coordo(1) + jBfin(2,2) * giB->Coordo(2);
*(base_ad_hoc(3)) = Util::ProdVec_coor(*(base_ad_hoc(1)),*(base_ad_hoc(2)));
}
else if((!absolue)&&(dim_espace>1)&&(dim==1))
// cas d'éléments 1D, dans un espace 2D ou 3D
// on ramène un seul vecteur non nul, les autres ne peuvent être calculé sans info supplémentaire
{ *(base_ad_hoc(1)) = jBfin(1,1) * giB->Coordo(1);
(base_ad_hoc(2))->Zero(); (base_ad_hoc(3))->Zero(); // init à 0 par défaut
}
else // dans tous les autres cas
{ switch (dim_espace) // on se contente de ramener le repère identité
{case 3: (base_ad_hoc(3))->Zero();(*(base_ad_hoc(3)))(3)=1.;
case 2: (base_ad_hoc(2))->Zero();(*(base_ad_hoc(2)))(2)=1.;
case 1: (base_ad_hoc(1))->Zero();(*(base_ad_hoc(1)))(1)=1.;
default:break;
};
};
};
if (besoin_rep_giH)
{switch (dim) {case 3: *(base_giH(3)) = giH->Coordo(3);
case 2: *(base_giH(2)) = giH->Coordo(2);
case 1: *(base_giH(1)) = giH->Coordo(1);
default:break;
};
};
if (besoin_rep_giB)
{switch (dim) {case 3: *(base_giB(3)) = giB->Coordo(3);
case 2: *(base_giB(2)) = giB->Coordo(2);
case 1: *(base_giB(1)) = giB->Coordo(1);
default:break;
};
};
// ----- calcul des grandeurs à sortir
// calcul des tenseurs initiaux
bool plusZero = true; // s'il faut rajouter des termes, on met des 0
if (besoin_des_contraintes)
{(*sigHB) = (ptintmeca_en_cours->SigHH_const()) * (*gijBB);
if (contrainteCourante) // on n'intervient ici que si on veut une sortie des contraintes courantes
{if (absolue) {(ptintmeca_en_cours->SigHH_const()).BaseAbsolue(*sigHH,*giB);}// changement de base finale
else if (transfert_tenseur)
{ TenseurHH* sigHH_inter = NevezTenseurHH(dim) ;
*sigHH_inter = (ptintmeca_en_cours->SigHH_const()); sigHH_inter->ChBase(*gammafin);
sigHH->Affectation_trans_dimension(*sigHH_inter,false);
delete sigHH_inter;
}
else
{ *sigHH = (ptintmeca_en_cours->SigHH_const());sigHH->ChBase(*gammafin);};
};
};
if (besoin_des_deformation)
{// cas de delta_eps
if(DeltaEpsBB != NULL)
{if (absolue)// changement de base finale
{(ptintmeca_en_cours->DeltaEpsBB_const()).BaseAbsolue(*DeltaEpsBB,*giH);}
else if (transfert_tenseur)
{ TenseurBB* DeltaEpsBB_inter = NevezTenseurBB(dim) ;
*DeltaEpsBB_inter = (ptintmeca_en_cours->DeltaEpsBB_const()); DeltaEpsBB_inter->ChBase(*betafin);
DeltaEpsBB->Affectation_trans_dimension(*DeltaEpsBB_inter,false);
delete DeltaEpsBB_inter;
}
else {*DeltaEpsBB = (ptintmeca_en_cours->DeltaEpsBB_const());DeltaEpsBB->ChBase(*betafin);};
};
// cas de la déformation
(*epsHB) = (*gijHH) * ((ptintmeca_en_cours->EpsBB_const()));
if (deformationCourante)// on n'intervient ici que si on veut une sortie des déformations courantes
{if (absolue)// changement de base finale
{(ptintmeca_en_cours->EpsBB_const()).BaseAbsolue(*epsBB,*giH);}
else if (transfert_tenseur)
{ TenseurBB* epsBB_inter = NevezTenseurBB(dim) ;
*epsBB_inter = (ptintmeca_en_cours->EpsBB_const()); epsBB_inter->ChBase(*betafin);
epsBB->Affectation_trans_dimension(*epsBB_inter,false);
delete epsBB_inter;
}
else {*epsBB = (ptintmeca_en_cours->EpsBB_const());epsBB->ChBase(*betafin);};
};
switch (def_en_cours->Type_de_deformation())
{case DEFORMATION_STANDART : // c'est à dire almansi
{if (greenLagrange)
{if (absolue)
{(ptintmeca_en_cours->EpsBB_const()).BaseAbsolue(*eps0BB,*giH_0);}// changement de base finale
else if (transfert_tenseur)
{ TenseurBB* eps0BB_inter = NevezTenseurBB(dim) ;
*eps0BB_inter = (ptintmeca_en_cours->EpsBB_const()); eps0BB_inter->ChBase(*beta0);
eps0BB->Affectation_trans_dimension(*eps0BB_inter,false);
delete eps0BB_inter;
}
else {eps0BB->ChBase(*beta0);};
};
if (almansi) *epsAlmBB = *epsBB;// le changement de base a été fait juste plus haut
if (almansiTotal) // cas avec dilatation et demande de def Almansi totale
{TenseurBB* epsAlmTotal_local_BB = epsAlmTotalBB; // par défaut
if ((prevoir_change_dim_tenseur)|| transfert_tenseur)
epsAlmTotal_local_BB = NevezTenseurBB(dim);
def_en_cours->Cal_deformation (temps,*epsAlmTotal_local_BB);
if (absolue)// changement de base finale
{epsAlmTotal_local_BB->BaseAbsolue(*epsAlmTotalBB,*giH);}
else if (transfert_tenseur)
{ epsAlmTotal_local_BB->ChBase(*betafin);
epsAlmTotalBB->Affectation_trans_dimension(*epsAlmTotal_local_BB,false);
}
else {epsAlmTotalBB->ChBase(*betafin);}; // ici epsAlmTotal_local_BB == epsAlmTotalBB
if ((prevoir_change_dim_tenseur)|| transfert_tenseur) delete epsAlmTotal_local_BB; // car pas utilisé ensuite
};
if (greenLagrangeTotale) // cas avec dilatation et demande de def Green_Lagrange totale
{TenseurBB* epsGLTotal_local_BB = epsGLTotalBB; // par défaut
if ((prevoir_change_dim_tenseur)|| transfert_tenseur)
epsGLTotal_local_BB = NevezTenseurBB(dim);
def_en_cours->Cal_deformation (temps,*epsGLTotal_local_BB);
if (absolue)// changement de base finale
{epsGLTotal_local_BB->BaseAbsolue(*epsGLTotalBB,*giH_0);}
else if (transfert_tenseur)
{ epsGLTotal_local_BB->ChBase(*beta0);
epsGLTotalBB->Affectation_trans_dimension(*epsGLTotal_local_BB,false);
}
else {epsGLTotalBB->ChBase(*beta0);}; // ici epsGLTotal_local_BB == epsGLTotalBB
if ((prevoir_change_dim_tenseur)|| transfert_tenseur) delete epsGLTotal_local_BB; // car pas utilisé ensuite
};
// si l'on veut sortir la déformation logarithmique le plus simple est de la calculer
if (logarithmiqueTotale || logarithmique)
{def_en_cours->Change_type_de_deformation(DEFORMATION_LOGARITHMIQUE);
if (logarithmique) // cas du calcul de la def logarithmique
{TenseurBB* epslog_local_BB = epslogBB; // par défaut
if ((prevoir_change_dim_tenseur)|| transfert_tenseur)
epslog_local_BB = NevezTenseurBB(dim);
def_en_cours->Cal_deformation (temps,*epslog_local_BB);
if (absolue)// changement de base finale
{epslog_local_BB->BaseAbsolue(*epslogBB,*giH);}
else if (transfert_tenseur)
{ epslog_local_BB->ChBase(*betafin);
epslogBB->Affectation_trans_dimension(*epslog_local_BB,false);
}
else {epslogBB->ChBase(*betafin);}; // ici epslog_local_BB == epslogBB
if ((prevoir_change_dim_tenseur)|| transfert_tenseur) delete epslog_local_BB; // car pas utilisé ensuite
};
if (logarithmiqueTotale) // cas avec dilatation et demande de def log totale
{TenseurBB* epsLogTotal_local_BB = epsLogTotalBB; // par défaut
if ((prevoir_change_dim_tenseur)|| transfert_tenseur)
epsLogTotal_local_BB = NevezTenseurBB(dim);
def_en_cours->Cal_deformation (temps,*epsLogTotal_local_BB);
if (absolue)// changement de base finale
{epsLogTotal_local_BB->BaseAbsolue(*epsLogTotalBB,*giH);}
else if (transfert_tenseur)
{ epsLogTotal_local_BB->ChBase(*betafin);
epsLogTotalBB->Affectation_trans_dimension(*epsLogTotal_local_BB,false);
}
else {epsLogTotalBB->ChBase(*betafin);}; // ici epsLogTotal_local_BB == epsLogTotalBB
if ((prevoir_change_dim_tenseur)|| transfert_tenseur) delete epsLogTotal_local_BB; // car pas utilisé ensuite
};
def_en_cours->Change_type_de_deformation(DEFORMATION_STANDART); // on revient au type initial
};
break;
}
case DEFORMATION_LOGARITHMIQUE :
{ if (logarithmique) *epslogBB=*epsBB;
if (logarithmiqueTotale) // cas avec dilatation et demande de def log totale
{TenseurBB* epsLogTotal_local_BB = epsLogTotalBB; // par défaut
if ((prevoir_change_dim_tenseur)|| transfert_tenseur)
epsLogTotal_local_BB = NevezTenseurBB(dim);
def_en_cours->Cal_deformation (temps,*epsLogTotal_local_BB);
if (absolue)// changement de base finale
{epsLogTotal_local_BB->BaseAbsolue(*epsLogTotalBB,*giH);}
else if (transfert_tenseur)
{ epsLogTotal_local_BB->ChBase(*betafin);
epsLogTotalBB->Affectation_trans_dimension(*epsLogTotal_local_BB,false);
}
else {epsLogTotalBB->ChBase(*betafin);}; // ici epsLogTotal_local_BB == epsLogTotalBB
if ((prevoir_change_dim_tenseur)|| transfert_tenseur) delete epsLogTotal_local_BB; // car pas utilisé ensuite
};
// si l'on veut sortir la déformation d'Almansi ou de green-lagrange le plus simple est de les calculer
if (almansi || greenLagrangeTotale || almansiTotal)
{def_en_cours->Change_type_de_deformation(DEFORMATION_STANDART);
if (almansi) // cas de la def d'almansi
{ TenseurBB* eps_local_BB = epsAlmBB; // par défaut
if ((prevoir_change_dim_tenseur)|| transfert_tenseur)
eps_local_BB = NevezTenseurBB(dim);
def_en_cours->Cal_deformation (temps,*eps_local_BB);
if (absolue)// changement de base finale
{eps_local_BB->BaseAbsolue(*epsAlmBB,*giH);}
else if (transfert_tenseur)
{ eps_local_BB->ChBase(*betafin);
epsAlmBB->Affectation_trans_dimension(*eps_local_BB,false);
}
else {epsAlmBB->ChBase(*betafin);};// ici eps_local_BB == epsAlmBB
if(greenLagrange)
{if (absolue)// changement de base finale
{eps_local_BB->BaseAbsolue(*eps0BB,*giH_0);}
else if (transfert_tenseur)
{ eps_local_BB->ChBase(*beta0);
eps0BB->Affectation_trans_dimension(*eps_local_BB,false);
}
else {eps0BB->ChBase(*beta0);}; // ici eps_local_BB == eps0BB
};
if ((prevoir_change_dim_tenseur)|| transfert_tenseur) delete eps_local_BB; // car pas utilisé ensuite
};
if (almansiTotal) // cas avec dilatation et demande de def Almansi totale
{TenseurBB* epsAlmTotal_local_BB = epsAlmTotalBB; // par défaut
if ((prevoir_change_dim_tenseur)|| transfert_tenseur)
epsAlmTotal_local_BB = NevezTenseurBB(dim);
def_en_cours->Cal_deformation (temps,*epsAlmTotal_local_BB);
if (absolue)// changement de base finale
{epsAlmTotal_local_BB->BaseAbsolue(*epsAlmTotalBB,*giH);}
else if (transfert_tenseur)
{ epsAlmTotal_local_BB->ChBase(*betafin);
epsAlmTotalBB->Affectation_trans_dimension(*epsAlmTotal_local_BB,false);
}
else {epsAlmTotalBB->ChBase(*betafin);}; // ici epsAlmTotal_local_BB == epsAlmTotalBB
if ((prevoir_change_dim_tenseur)|| transfert_tenseur) delete epsAlmTotal_local_BB; // car pas utilisé ensuite
};
if (greenLagrangeTotale) // cas avec dilatation et demande de def Green_Lagrange totale
{TenseurBB* epsGLTotal_local_BB = epsGLTotalBB; // par défaut
if ((prevoir_change_dim_tenseur)|| transfert_tenseur)
epsGLTotal_local_BB = NevezTenseurBB(dim);
def_en_cours->Cal_deformation (temps,*epsGLTotal_local_BB);
if (absolue)// changement de base finale
{epsGLTotal_local_BB->BaseAbsolue(*epsGLTotalBB,*giH_0);}
else if (transfert_tenseur)
{ epsGLTotal_local_BB->ChBase(*beta0);
epsGLTotalBB->Affectation_trans_dimension(*epsGLTotal_local_BB,false);
}
else {epsGLTotalBB->ChBase(*beta0);}; // ici epsGLTotal_local_BB == epsGLTotalBB
if ((prevoir_change_dim_tenseur)|| transfert_tenseur) delete epsGLTotal_local_BB; // car pas utilisé ensuite
};
def_en_cours->Change_type_de_deformation(DEFORMATION_LOGARITHMIQUE); // on revient au type initial
};
break;
}
default:
cout << "\n cas de deformation non encore implante en sortie de visualisation "
<< Nom_type_deformation(def_en_cours->Type_de_deformation())
<< " affichage donc errone des valeurs !!!";
};
}; //-- fin de if (besoin_des_deformation)
if (besoin_des_vitesses_deformation)
{ *DepsHB = (*gijHH) * ((ptintmeca_en_cours->DepsBB_const()));
if (absolue)// changement de base finale
{(ptintmeca_en_cours->DepsBB_const()).BaseAbsolue(*DepsBB,*giH);}
else if (transfert_tenseur)
{ TenseurBB* DepsBB_inter = NevezTenseurBB(dim) ;
*DepsBB_inter = (ptintmeca_en_cours->DepsBB_const()); DepsBB_inter->ChBase(*betafin);
DepsBB->Affectation_trans_dimension(*DepsBB_inter,false);
delete DepsBB_inter;
}
else {*DepsBB = (ptintmeca_en_cours->DepsBB_const());DepsBB->ChBase(*betafin);};
};
if (besoin_des_contraintes_barre)
{double Isig = sigHB->Trace(); // trace de la déformation
*sig_barreHB = (*sigHB) - (Isig/dim_espace) * (*Id_dim_HB(dim));
};
if (besoin_des_deformation_barre)
{double Ieps = epsHB->Trace(); // trace de la déformation
*eps_barreHB = (*epsHB) - (Ieps/dim_espace) * (*Id_dim_HB(dim));
};
if (besoin_des_vitesses_deformation_barre)
{double IDeps = DepsHB->Trace(); // trace de la déformation
*Deps_barreHB = (*DepsHB) - (IDeps/dim_espace) * (*Id_dim_HB(dim));
};
// cas des valeurs propres et éventuellement des vecteurs propres
{int caas=0;
////----- debug
//cout << "\n besoin_des_valpropre_sigma= "<< besoin_des_valpropre_sigma
// << " besoin_dir_princ_sig= "<< besoin_dir_princ_sig << endl;
////--- fin debug
if (besoin_des_valpropre_sigma && besoin_dir_princ_sig)// on veut les directions et les valeurs propres
{ Mat_pleine mat(dim,dim); // contiendra par colonne les vecteurs principaux, exprimé en giH
Coordonnee inter(sigHB->ValPropre(caas,mat));
inter.Change_dim(dim_sortie_tenseur); // on étant la taille éventuellement
*valPropreSig = inter; // sauvegarde des valeurs propres
// puis des directions principales, que l'on doit exprimer dans le repère absolue
Tableau <CoordonneeH > tab = mat.CoordonneeH_Base_associee(); // récup en tab de coor
// on regarde le cas particulier ou les valeurs propres sont toutes nulles
// si c'est le cas, on ne fait rien, en sortie on aura des vecteurs propres nulles
if (inter.Max_val_abs() > ConstMath::petit)
// et s'il y a eu un pb dans le calcul des valeurs propres ou vecteurs propres on évite
{if (caas != -1)
{switch (dim)
{case 3: giB->BaseAbsolue( *(base_propre_sigma(3)),tab(3));(base_propre_sigma(3))->Normer();
giB->BaseAbsolue( *(base_propre_sigma(2)),tab(2));(base_propre_sigma(2))->Normer();
case 1: giB->BaseAbsolue( *(base_propre_sigma(1)),tab(1));(base_propre_sigma(1))->Normer();
break;
case 2: // en 2D le premier vecteur en giB et le second en giH !!
giB->BaseAbsolue( *(base_propre_sigma(1)),tab(1));(base_propre_sigma(1))->Normer();
giH->BaseAbsolue( *(base_propre_sigma(2)),mat.CoordonneeB_Base_associee(2));
(base_propre_sigma(2))->Normer();
break;
default:break;
};
};
};
}
else if (besoin_dir_princ_sig) // cas où on ne veut que les directions principales
{ Mat_pleine mat(dim,dim); // contiendra par colonne les vecteurs principaux, exprimé en giH
Coordonnee inter(sigHB->ValPropre(caas,mat));
// sauvegarde des directions principales
Tableau <CoordonneeH > tab = mat.CoordonneeH_Base_associee(); // récup en tab de coor
// on regarde le cas particulier ou les valeurs propres sont toutes nulles
// si c'est le cas, on ne fait rien, en sortie on aura des vecteurs propres nulles
if (inter.Max_val_abs() > ConstMath::petit)
// et s'il y a eu un pb dans le calcul des valeurs propres ou vecteurs propres on évite
{if (caas != -1)
{switch (dim)
{case 3: giB->BaseAbsolue( *(base_propre_sigma(3)),tab(3));(base_propre_sigma(3))->Normer();
giB->BaseAbsolue( *(base_propre_sigma(2)),tab(2));(base_propre_sigma(2))->Normer();
case 1: giB->BaseAbsolue( *(base_propre_sigma(1)),tab(1));(base_propre_sigma(1))->Normer();
break;
case 2: // en 2D le premier vecteur en en giB et le second en giH !!
giB->BaseAbsolue( *(base_propre_sigma(1)),tab(1));(base_propre_sigma(1))->Normer();
giH->BaseAbsolue( *(base_propre_sigma(2)),mat.CoordonneeB_Base_associee(2));
(base_propre_sigma(2))->Normer();
break;
default:break;
};
};
};
}
else if (besoin_des_valpropre_sigma)// on ne veut que les valeurs propres
{ Coordonnee inter(sigHB->ValPropre(caas));
inter.Change_dim(dim_sortie_tenseur); // on étend la taille éventuellement
*valPropreSig = inter; // sauvegarde des valeurs propres
};
// gestion d'une erreur éventuelle
if (caas == -1)
{ cout << "\n warning *** erreur dans le calcul des valeurs propres et-ou vecteurs propres de la contrainte ";
if (ParaGlob::NiveauImpression() > 5) {sigHB->Ecriture(cout);cout << "\n cas = "<< caas ;
cout << "\Loi_comp_abstraite::Valeurs_Tensorielles_interpoler_ou_calculer(...";};
cout << endl;
};
}; // -- fin de l'encapsulation du cas des contraintes
{int caas=0;
if (besoin_des_valpropre_deformation && besoin_dir_princ_eps)// on veut les directions et les valeurs propres
{ Mat_pleine mat(dim,dim); // contiendra par colonne les vecteurs principaux, exprimé en giH
// 1) calcul des valeurs propres dans un vecteur de travail inter, et des vecteurs propres stockés
Coordonnee inter(epsHB->ValPropre(caas,mat)); // dans la matrice mat
inter.Change_dim(dim_sortie_tenseur); // on étend la taille, dans le cas ou le nb de valeurs
// propre est inférieur à la dimension de l'espace
*valPropreEps = inter; // sauvegarde des valeurs propres
// 2) puis des directions principales, que l'on doit exprimer dans le repère absolue
Tableau <CoordonneeH > tab = mat.CoordonneeH_Base_associee(); // récup en tab de coor
// on regarde le cas particulier ou les valeurs propres sont toutes nulles
// si c'est le cas, on ne fait rien, en sortie on aura des vecteurs propres nulles
if (inter.Max_val_abs() > ConstMath::petit)
// et s'il y a eu un pb dans le calcul des valeurs propres ou vecteurs propres on évite
{if (caas != -1)
{switch (dim)
{case 3: giB->BaseAbsolue( *(base_propre_eps(3)),tab(3));(base_propre_eps(3))->Normer();
giB->BaseAbsolue( *(base_propre_eps(2)),tab(2));(base_propre_eps(2))->Normer();
case 1: giB->BaseAbsolue( *(base_propre_eps(1)),tab(1));(base_propre_eps(1))->Normer();
break;
case 2: // en 2D le premier vecteur en en giB et le second en giH !!
giB->BaseAbsolue( *(base_propre_eps(1)),tab(1));(base_propre_eps(1))->Normer();
giH->BaseAbsolue( *(base_propre_eps(2)),mat.CoordonneeB_Base_associee(2));
(base_propre_eps(2))->Normer();
break;
default:break;
};
};
};
}
else if (besoin_dir_princ_eps) // cas où on ne veut que les directions principales
{ Mat_pleine mat(dim,dim); // contiendra par colonne les vecteurs principaux, exprimé en giH
Coordonnee inter(epsHB->ValPropre(caas,mat)); // dans la matrice mat
// puis des directions principales, que l'on doit exprimer dans le repère absolue
Tableau <CoordonneeH > tab = mat.CoordonneeH_Base_associee(); // récup en tab de coor
// on regarde le cas particulier ou les valeurs propres sont toutes nulles
// si c'est le cas, on ne fait rien, en sortie on aura des vecteurs propres nulles
if (inter.Max_val_abs() > ConstMath::petit)
// et s'il y a eu un pb dans le calcul des valeurs propres ou vecteurs propres on évite
{if (caas != -1)
{switch (dim)
{case 3: giB->BaseAbsolue( *(base_propre_eps(3)),tab(3));(base_propre_eps(3))->Normer();
giB->BaseAbsolue( *(base_propre_eps(2)),tab(2));(base_propre_eps(2))->Normer();
case 1: giB->BaseAbsolue( *(base_propre_eps(1)),tab(1));(base_propre_eps(1))->Normer();
break;
case 2: // en 2D le premier vecteur en en giB et le second en giH !!
giB->BaseAbsolue( *(base_propre_eps(1)),tab(1));(base_propre_eps(1))->Normer();
giH->BaseAbsolue( *(base_propre_eps(2)),mat.CoordonneeB_Base_associee(2));
(base_propre_eps(2))->Normer();
break;
default:break;
};
};
};
}
else if (besoin_des_valpropre_deformation)// on ne veut que les valeurs propres
{ Coordonnee inter(epsHB->ValPropre(caas));
inter.Change_dim(dim_sortie_tenseur); // on étant la taille éventuellement
*valPropreEps = inter; // sauvegarde des valeurs propres
};
// gestion d'une erreur éventuelle
if (caas == -1)
{ cout << "\n warning *** erreur dans le calcul des valeurs propres et-ou vecteurs propres de la deformation";
if (ParaGlob::NiveauImpression() >= 7) {epsHB->Ecriture(cout);cout << "\n cas = "<< caas ;
cout << "\Loi_comp_abstraite::Valeurs_Tensorielles_interpoler_ou_calculer(...";};
cout << endl;
};
}; // -- fin de l'encapsulation du cas des déformations
{int caas=0; // il faut l'initialiser sinon il peut prendre la valeur du cas précédant
if (besoin_des_valpropre_vitdef && besoin_dir_princ_D)// on veut les directions et les valeurs propres
{ Mat_pleine mat(dim,dim); // contiendra par colonne les vecteurs principaux, exprimé en giH
// 1) calcul des valeurs propres dans un vecteur de travail inter, et des vecteurs propres stockés
Coordonnee inter(DepsHB->ValPropre(caas,mat)); // dans la matrice mat
inter.Change_dim(dim_sortie_tenseur); // on étend la taille, dans le cas ou le nb de valeurs
// propre est inférieur à la dimension de l'espace
*valPropreDeps = inter; // sauvegarde des valeurs propres
// 2) puis des directions principales, que l'on doit exprimer dans le repère absolue
Tableau <CoordonneeH > tab = mat.CoordonneeH_Base_associee(); // récup en tab de coor
// on regarde le cas particulier ou les valeurs propres sont toutes nulles
// si c'est le cas, on ne fait rien, en sortie on aura des vecteurs propres nulles
if (inter.Max_val_abs() > ConstMath::petit)
// et s'il y a eu un pb dans le calcul des valeurs propres ou vecteurs propres on évite
{if (caas != -1)
{switch (dim)
{case 3: giB->BaseAbsolue( *(base_propre_D(3)),tab(3));(base_propre_D(3))->Normer();
giB->BaseAbsolue( *(base_propre_D(2)),tab(2));(base_propre_D(2))->Normer();
case 1: giB->BaseAbsolue( *(base_propre_D(1)),tab(1));(base_propre_D(1))->Normer();
break;
case 2: // en 2D le premier vecteur en en giB et le second en giH !!
giB->BaseAbsolue( *(base_propre_D(1)),tab(1));(base_propre_D(1))->Normer();
giH->BaseAbsolue( *(base_propre_D(2)),mat.CoordonneeB_Base_associee(2));
(base_propre_D(2))->Normer();
break;
default:break;
};
};
};
}
else if (besoin_dir_princ_D) // cas où on ne veut que les directions principales
{ Mat_pleine mat(dim,dim); // contiendra par colonne les vecteurs principaux, exprimé en giH
Coordonnee inter(DepsHB->ValPropre(caas,mat)); // dans la matrice mat
// puis des directions principales, que l'on doit exprimer dans le repère absolue
Tableau <CoordonneeH > tab = mat.CoordonneeH_Base_associee(); // récup en tab de coor
// on regarde le cas particulier ou les valeurs propres sont toutes nulles
// si c'est le cas, on ne fait rien, en sortie on aura des vecteurs propres nulles
if (inter.Max_val_abs() > ConstMath::petit)
// et s'il y a eu un pb dans le calcul des valeurs propres ou vecteurs propres on évite
{if (caas != -1)
{switch (dim)
{case 3: giB->BaseAbsolue( *(base_propre_D(3)),tab(3));(base_propre_D(3))->Normer();
giB->BaseAbsolue( *(base_propre_D(2)),tab(2));(base_propre_D(2))->Normer();
case 1: giB->BaseAbsolue( *(base_propre_D(1)),tab(1));(base_propre_D(1))->Normer();
break;
case 2: // en 2D le premier vecteur en en giB et le second en giH !!
giB->BaseAbsolue( *(base_propre_D(1)),tab(1));(base_propre_D(1))->Normer();
giH->BaseAbsolue( *(base_propre_D(2)),mat.CoordonneeB_Base_associee(2));
(base_propre_D(2))->Normer();
break;
default:break;
};
};
};
}
else if (besoin_des_valpropre_vitdef)// on ne veut que les valeurs propres
{ Coordonnee inter(DepsHB->ValPropre(caas));
inter.Change_dim(dim_sortie_tenseur); // on étant la taille
*valPropreDeps = inter; // sauvegarde des valeurs propres
};
// gestion d'une erreur éventuelle
if (caas == -1)
{ cout << "\n warning *** erreur dans le calcul des valeurs propres et-ou vecteurs propres de la vitesse de deformation";
if (ParaGlob::NiveauImpression() >= 7) {DepsHB->Ecriture(cout);cout << "\n cas = "<< caas ;
cout << "\Loi_comp_abstraite::Valeurs_Tensorielles_interpoler_ou_calculer(...";};
cout << endl;
};
}; // -- fin de l'encapsulation du cas des vitesses de déformations
if (besoin_coordonnees)
(*Mtdt) = def_en_cours->Position_tdt();
if (besoin_coordonnees_t)
(*Mt) = def_en_cours->Position_t();
if (besoin_coordonnees_t0)
(*M0) = def_en_cours->Position_0();
// def éventuelle du vecteur normal: ceci n'est correct qu'avec une métrique 2D
if (N_surf != NULL)
{ if (pas_de_metrique_dispo)
{ cout << "\n ***erreur, la grandeur N_surf necessite la donnee de la metrique "
<< " or elle n'est pas ici disponible !! ";
Sortie(1);
};
// on vérifie que la métrique est correcte
if (giB->NbVecteur() != 2)
{if (ParaGlob::NiveauImpression() > 0)
{cout << "\n *** attention il ne s'agit pas d'un element 2D,"
<< " le vecteur normal ne sera pas disponible";
if (ParaGlob::NiveauImpression() > 2)
cout << "\n Loi_comp_abstraite::Valeurs_Tensorielles_interpoler_ou_calculer(... ";
};
cout << endl;
}
else // sinon c'est ok
{// la normale vaut le produit vectoriel des 2 premiers vecteurs
(*N_surf) = Util::ProdVec_coorBN( (*giB)(1), (*giB)(2));
N_surf->Normer(); // que l'on norme
};
// on n'arrête pas l'exécution, car on pourrait vouloir sortir les normales pour un ensemble
// d'éléments contenant des volumes, des surfaces, des lignes: bon... il y aura quand même des
// pb au niveau des iso par exemple, du au fait que l'on va faire des moyennes sur des éléments
// de type différents (à moins de grouper par type du coup on n'aura pas le warning
};
// idem à l'instant t
if (N_surf_t != NULL)
{ if (pas_de_metrique_dispo)
{ cout << "\n ***erreur, la grandeur N_surf_t necessite la donnee de la metrique "
<< " or elle n'est pas ici disponible !! ";
Sortie(1);
};
// on vérifie que la métrique est correcte
if (giB_t->NbVecteur() != 2)
{if (ParaGlob::NiveauImpression() > 0)
{cout << "\n *** attention il ne s'agit pas d'une metrique 2D 2D,"
<< " le vecteur normal ne sera pas correctement calcule";
if (ParaGlob::NiveauImpression() > 2)
cout << "\n Loi_comp_abstraite::Valeurs_Tensorielles_interpoler_ou_calculer(... ";
};
cout << endl;
}
else // sinon c'est ok
{// la normale vaut le produit vectoriel des 2 premiers vecteurs
(*N_surf_t) = Util::ProdVec_coorBN( (*giB_t)(1), (*giB_t)(2));
N_surf_t->Normer(); // que l'on norme
};
};
// idem à l'instant t0
if (N_surf_t0 != NULL)
{ if (pas_de_metrique_dispo)
{ cout << "\n ***erreur, la grandeur N_surf_0 necessite la donnee de la metrique "
<< " or elle n'est pas ici disponible !! ";
Sortie(1);
};
// on vérifie que la métrique est correcte
if (giB_0->NbVecteur() != 2)
{if (ParaGlob::NiveauImpression() > 0)
{cout << "\n *** attention il ne s'agit pas d'une metrique 2D 2D,"
<< " le vecteur normal ne sera pas correctement calcule";
if (ParaGlob::NiveauImpression() > 2)
cout << "\n Loi_comp_abstraite::Valeurs_Tensorielles_interpoler_ou_calculer(... ";
};
cout << endl;
}
else // sinon c'est ok
{// la normale vaut le produit vectoriel des 2 premiers vecteurs
(*N_surf_t0) = Util::ProdVec_coorBN( (*giB_0)(1), (*giB_0)(2));
N_surf_t0->Normer(); // que l'on norme
};
};
// cas du déplacement et de la vitesse
if (Deplacement != NULL)
(*Deplacement) = (*Mtdt) - def_en_cours->Position_0();
if (Vitesse != NULL)
(*Vitesse) = def_en_cours->VitesseM_tdt();
// cas de la deformation équivalente cumulée
if (def_def_equivalente) {*def_equivalente = ptintmeca_en_cours->Deformation_equi_const()(1);};
// cas de la deformation duale au sens de mises,
if (def_duale_mises) {*defDualMises = ptintmeca_en_cours->Deformation_equi_const()(2);};
// cas de la deformation maxi duale au sens de mises,
if (def_duale_mises_maxi) {*defDualMisesMaxi = ptintmeca_en_cours->Deformation_equi_const()(3);};
// cas des contraintes: mises et tresca
if (def_sig_mises) {*sig_mises = ptintmeca_en_cours->Sig_equi_const()(1);};
if (def_sig_tresca) {*sig_tresca = ptintmeca_en_cours->Sig_equi_const()(2);};
// //contrainte_tresca
// if (contraintesTresca)
// { switch (dim) {case 1: *Tresca=0.5 * (*valPropreSig)(1);break;
// case 2: *Tresca=0.5 * ((*valPropreSig)(1)-(*valPropreSig)(2));break;
// case 3: *Tresca=0.5 * ((*valPropreSig)(1)-(*valPropreSig)(3));break;
// };
// };
// --- cas des grandeurs de la décomposition polaire
// cas de la déformation
if (def_SPHERIQUE_EPS) {*spherique_eps = epsHB->Trace()/3.;}; //ParaGlob::Dimension();}; modif 5/2/2012
double mini_Q = 5.e-5;
if (def_Q_EPS) {*Q_eps = sqrt(eps_barreHB->II());};
if (cos3phi_eps)
{ double Qepsilon = ( def_Q_EPS ? *Q_eps : sqrt(eps_barreHB->II()));
double Qepsilon3 = Qepsilon * Qepsilon * Qepsilon;
if (Qepsilon > mini_Q )
{ // on peut calculer un cos3phi pas débile
double bIIIb = eps_barreHB->III() / 3.;
*cos3phi_eps = 3. * sqrt(6.) * bIIIb/ Qepsilon3;
}
else *cos3phi_eps=0.; // sinon on le met à 0
};
// cas de la contrainte
if (def_SPHERIQUE_SIG) {*spherique_sig = sigHB->Trace()/3.;}; //ParaGlob::Dimension();}; modif 5/2/2012
if (def_Q_SIG) {*Q_sig = sqrt(sig_barreHB->II());};
if (cos3phi_sig)
{ double Qsig = ( def_Q_SIG ? *Q_sig : sqrt(sig_barreHB->II()));
double Qsig3 = Qsig * Qsig * Qsig;
if (Qsig > mini_Q )
{ // on peut calculer un cos3phi pas débile
double bIIIb = sig_barreHB->III() / 3.;
*cos3phi_sig = 3. * sqrt(6.) * bIIIb/ Qsig3;
}
else *cos3phi_sig=0.; // sinon on le met à 0
};
// cas de la vitesse de déformation
if (def_SPHERIQUE_DEPS) {*spherique_Deps = DepsHB->Trace()/3.;}; //ParaGlob::Dimension();}; modif 5/2/2012
if (def_Q_DEPS) {*Q_Deps = sqrt(Deps_barreHB->II());};
if (cos3phi_Deps)
{ double QDepsilon = ( def_Q_DEPS ? *Q_Deps : sqrt(Deps_barreHB->II()));
double QDepsilon3 = QDepsilon * QDepsilon * QDepsilon;
if (QDepsilon > mini_Q )
{ // on peut calculer un cos3phi pas débile
double bIIIb = Deps_barreHB->III() / 3.;
*cos3phi_Deps = 3. * sqrt(6.) * bIIIb/ QDepsilon3;
}
else *cos3phi_Deps=0.; // sinon on le met à 0
};
// delete des tenseurs
if (sigHB != NULL) delete sigHB;
if (epsHB != NULL) delete epsHB;
if (DepsHB != NULL) delete DepsHB;
if (eps_barreHB != NULL) delete eps_barreHB;
if (Deps_barreHB != NULL) delete Deps_barreHB;
if (sig_barreHB != NULL) delete sig_barreHB;
// effacement conditionnel
if (besoin_des_contraintes && !contrainteCourante) delete sigHH;
if (besoin_des_deformation && !deformationCourante) delete epsBB;
if (vitesseDeformationCourante && !vitesseDeformationCourante) delete DepsBB;
if (besoin_des_valpropre_deformation && !defPrincipales) delete valPropreEps;
if (besoin_des_valpropre_vitdef && !vitPrincipales) delete valPropreDeps ;
if (besoin_des_valpropre_sigma && !sigmaPrincipales) delete valPropreSig;
// pointeurs de matrice
if (Aa0 != NULL) delete Aa0;
if (Aafin != NULL) delete Aafin;
if (gamma0 != NULL) delete gamma0;
if (gammafin != NULL) delete gammafin;
if (beta0 != NULL) delete beta0;
if (betafin != NULL) delete betafin;
// liberation des tenseurs intermediaires
LibereTenseur();
};
// affichage de la liste des grandeurs possible à calculer avec Valeur_multi_interpoler_ou_calculer
void Loi_comp_abstraite::Affichage_grandeurs_Valeurs_Tensorielles_interpoler_ou_calculer()
{ cout << "\n grandeurs tensorielles ou evoluees disponibles :";
cout << "\n CONTRAINTE_COURANTE, DEFORMATION_COURANTE, VITESSE_DEFORMATION_COURANTE "
<< "\n ALMANSI, GREEN_LAGRANGE, LOGARITHMIQUE, DELTA_DEF, ALMANSI_TOTAL"
<< "\n GREEN_LAGRANGE_TOTAL, LOGARITHMIQUE_TOTALE, DEF_PRINCIPALES"
<< "\n SIGMA_PRINCIPALES, VIT_PRINCIPALES, SPHERIQUE_EPS, Q_EPS, COS3PHI_EPS"
<< "\n SPHERIQUE_SIG, Q_SIG, COS3PHI_SIG, SPHERIQUE_DEPS, Q_DEPS"
<< "\n COS3PHI_DEPS, DIRECTIONS_PRINC_SIGMA, DIRECTIONS_PRINC_DEF"
<< "\n DIRECTIONS_PRINC_D, NUM_ELEMENT, NUM_MAIL_ELEM, NUM_PTI"
<< "\n POSITION_GEOMETRIQUE, POSITION_GEOMETRIQUE_t, POSITION_GEOMETRIQUE_t0, "
<< "\n si pertinent: REPERE_LOCAL_ORTHO, REPERE_LOCAL_H, REPERE_LOCAL_B"
<< "\n si pertinent: NN_SURF, NN_SURF_t, NN_SURF_t0, DEPLACEMENT, VITESSE"
<< "\n DEF_DUALE_MISES, DEF_EQUIVALENTE, DEF_DUALE_MISES_MAXI "
<< "\n ,CONTRAINTE_MISES,CONTRAINTE_TRESCA"
;
};
// récupération de valeurs interpolées pour les grandeur ici considéré quelconque enu
// ces grandeurs ne sont pas définies dans la liste des Ddl_enum_etendu : ex mises à t
// ou le numéro de l'élément etc.
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
// une seule des 3 métriques doit-être renseigné, les autres doivent être un pointeur nul
// exclure_Q: donne une liste de grandeur quelconque à exclure de la recherche
// parce que par exemple, ils sont calculés par ailleurs
// on peut également ne pas définir de métrique, dans ce cas on ne peut pas calculer certaines grandeurs
// -> il y a vérification
// retour: la list li_quelc qui en entrée doit avoir la même dimension que tqi
void Loi_comp_abstraite::Valeurs_quelconque_interpoler_ou_calculer
(bool absolue, Enum_dure temps
,const Tableau <EnumTypeQuelconque>& tqi
,List_io<TypeQuelconque>& li_quelc
,const Met_abstraite::Impli* ex_impli
,const Met_abstraite::Expli_t_tdt* ex_expli_tdt
,const Met_abstraite::Umat_cont* ex_umat
,const List_io<EnumTypeQuelconque>* exclure_Q
)
{ // on a besoin a priori de ptintmeca_en_cours, donc s'il n'est pas définit -> erreur
#ifdef MISE_AU_POINT
if (ptintmeca_en_cours == NULL)
{cout << "\n *** cas non prevu : aucun conteneur de point d'integration transmis "
<< "\n Loi_comp_abstraite::Valeurs_quelconque_interpoler_ou_calculer(..." << endl;
Sortie(1);
};
if (def_en_cours == NULL)
{cout << "\n *** cas non prevu : la deformation n'est pas transmise "
<< "\n Loi_comp_abstraite::Valeurs_quelconque_interpoler_ou_calculer(..." << endl;
Sortie(1);
};
#endif
// ----- def de grandeurs de travail
// def de la dimension des tenseurs
// il y a deux pb a gérer: 1) le fait que la dimension absolue peut-être différente de la dimension des tenseurs
// 2) le fait que l'on veut une sortie dans une base ad hoc ou pas
int dim = ptintmeca_en_cours->EpsBB_const().Dimension();
int dim_sortie_tenseur = dim;
// dans le cas ou l'on veut une sortie en base absolue, il faut que dim_sortie_tenseur = la dimension de la base absolue
int dim_espace = ParaGlob::Dimension();
if (absolue)
dim_sortie_tenseur = dim_espace;
// pour ne faire qu'un seul test ensuite
bool prevoir_change_dim_tenseur = false;
// initialement on faisait le test suivant,
// if ((absolue) && (dim != dim_sortie_tenseur))
if (absolue)
// mais en fait, quand on sort en absolu on est obligé d'utiliser un tenseur intermédiaire
// car BaseAbsolue(.. modifie tenseur passé en paramètre, donc dans tous les cas de sortie absolue
// il faut un tenseur intermédiaire qui a ou non une dimension différente
prevoir_change_dim_tenseur = true;
// éléments de métrique et matrices de passage
TenseurHH* gijHH;TenseurBB* gijBB;BaseB* giB; BaseH* giH_0;BaseH* giH;
Mat_pleine jB0(dim,dim),jBfin(dim,dim);
BaseB* giB_0;BaseB* giB_t;
bool pas_de_metrique_dispo = false; // init
if (ex_impli != NULL)
{ gijHH = ex_impli->gijHH_tdt;gijBB = ex_impli->gijBB_tdt;
giB = ex_impli->giB_tdt; giH_0 = ex_impli->giH_0;giH = ex_impli->giH_tdt;
giB_t = ex_impli->giB_t; giB_0 = ex_impli->giB_0;
}
else if (ex_expli_tdt != NULL)
{gijHH = ex_expli_tdt->gijHH_tdt;gijBB = ex_expli_tdt->gijBB_tdt;
giB = ex_expli_tdt->giB_tdt; giH_0 = ex_expli_tdt->giH_0;giH = ex_expli_tdt->giH_tdt;
giB_t = ex_expli_tdt->giB_t; giB_0 = ex_expli_tdt->giB_0;
}
else if (ex_umat != NULL)
{gijHH = ex_umat->gijHH_t;gijBB = ex_umat->gijBB_t;
giB = giB_t = ex_umat->giB_t; giH_0 = ex_umat->giH_0;giH = ex_umat->giH_t;
giB_0 = ex_umat->giB_0;
}
else
{ pas_de_metrique_dispo = true;
// cout << "\n *** cas non prevu : aucune metrique transmise "
// << "\n Loi_comp_abstraite::Valeurs_quelconque_interpoler_ou_calculer(..." << endl;
// Sortie(1);
};
// def de tenseurs pour la sortie
// les tenseurs restants en locale
// pour les valeurs propres
// pour les vecteurs propres
// pour les bases
Tableau <Coordonnee *> base_ad_hoc , base_giH , base_giB;
// --- dev d'un ensemble de variable booléenne pour gérer les sorties en une passe -----
// on se réfère au informations définit dans la méthode: Les_type_evolues_internes()
bool besoin_rep_local_ortho=false;
bool besoin_rep_giH = false; bool besoin_rep_giB = false;
// init pour l'utilisation de la liste d'exclusion
List_io<EnumTypeQuelconque>::const_iterator itt_deb;
List_io<EnumTypeQuelconque>::const_iterator itt_fin;
if (exclure_Q != NULL)
{ itt_deb = exclure_Q->begin();
itt_fin = exclure_Q->end();
};
// on va boucler sur les énumérés quelconque
int nb_tqi = tqi.Taille();
List_io <TypeQuelconque >::iterator ipq=li_quelc.begin();
for (int i_tqi = 1;i_tqi <= nb_tqi;i_tqi++,ipq++ )
// on initialise ces variables booléennes et les conteneurs
{EnumTypeQuelconque& enuconq = tqi(i_tqi);
switch (enuconq)
{
case CONTRAINTE_MISES :
{Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*ipq).Grandeur_pointee()));
(*gr.ConteneurDouble()) = ptintmeca_en_cours->Sig_equi_const()(1);
break;
}
case CONTRAINTE_TRESCA :
{Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*ipq).Grandeur_pointee()));
(*gr.ConteneurDouble()) = ptintmeca_en_cours->Sig_equi_const()(2);
break;
}
case CONTRAINTE_MISES_T :
{Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*ipq).Grandeur_pointee()));
(*gr.ConteneurDouble()) = ptintmeca_en_cours->Sig_equi_t_const()(1);
break;
}
case CONTRAINTE_TRESCA_T :
{Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*ipq).Grandeur_pointee()));
(*gr.ConteneurDouble()) = ptintmeca_en_cours->Sig_equi_t_const()(2);
break;
}
case NUM_ELEMENT:
{Grandeur_scalaire_entier& gr= *((Grandeur_scalaire_entier*) ((*ipq).Grandeur_pointee()));
(*gr.ConteneurEntier())=ptintmeca_en_cours->Nb_ele();
break;
}
case NUM_MAIL_ELEM:
{Grandeur_scalaire_entier& gr= *((Grandeur_scalaire_entier*) ((*ipq).Grandeur_pointee()));
(*gr.ConteneurEntier())=ptintmeca_en_cours->Nb_mail();
break;
}
case NUM_PTI:
{Grandeur_scalaire_entier& gr= *((Grandeur_scalaire_entier*) ((*ipq).Grandeur_pointee()));
(*gr.ConteneurEntier())=ptintmeca_en_cours->Nb_pti();
break;
}
case REPERE_LOCAL_ORTHO :
{base_ad_hoc.Change_taille(dim_espace);
Tab_Grandeur_Coordonnee& gr= *((Tab_Grandeur_Coordonnee*) ((*ipq).Grandeur_pointee()));
if (pas_de_metrique_dispo)
{ cout << "\n ***erreur, la grandeur REPERE_LOCAL_ORTHO necessite la donnee de la metrique "
<< " or elle n'est pas ici disponible !! ";
Sortie(1);
};
// calcul de la base
switch (dim_espace) {case 3: gr(3).Zero(); case 2: gr(2).Zero(); default:break;};//init
switch (dim_espace) {case 3: base_ad_hoc(3) = &(gr(3));
case 2: base_ad_hoc(2) = &(gr(2));
case 1: base_ad_hoc(1) = &(gr(1));
default:break;
};
if ((!absolue)&&(dim_espace==3)&&(dim==2))
// cas d'éléments 2D, pour lesquels on veut un repère local ad hoc
// on ramène une base à 3 vecteurs
{ *(base_ad_hoc(1)) = jBfin(1,1) * giB->Coordo(1) + jBfin(2,1) * giB->Coordo(2);
*(base_ad_hoc(2)) = jBfin(1,2) * giB->Coordo(1) + jBfin(2,2) * giB->Coordo(2);
*(base_ad_hoc(3)) = Util::ProdVec_coor(*(base_ad_hoc(1)),*(base_ad_hoc(2)));
}
else if((!absolue)&&(dim_espace>1)&&(dim==1))
// cas d'éléments 1D, dans un espace 2D ou 3D
// on ramène un seul vecteur non nul, les autres ne peuvent être calculé sans info supplémentaire
{ *(base_ad_hoc(1)) = jBfin(1,1) * giB->Coordo(1);
(base_ad_hoc(2))->Zero(); (base_ad_hoc(3))->Zero(); // init à 0 par défaut
}
else // dans tous les autres cas
{ switch (dim_espace) // on se contente de ramener le repère identité
{case 3: (base_ad_hoc(3))->Zero();(*(base_ad_hoc(3)))(3)=1.;
case 2: (base_ad_hoc(2))->Zero();(*(base_ad_hoc(2)))(2)=1.;
case 1: (base_ad_hoc(1))->Zero();(*(base_ad_hoc(1)))(1)=1.;
default:break;
};
};
break;
}
case REPERE_LOCAL_H :
{base_giH.Change_taille(dim);
Tab_Grandeur_Coordonnee& gr= *((Tab_Grandeur_Coordonnee*) ((*ipq).Grandeur_pointee()));
if (pas_de_metrique_dispo)
{ cout << "\n ***erreur, la grandeur REPERE_LOCAL_H necessite la donnee de la metrique "
<< " or elle n'est pas ici disponible !! ";
Sortie(1);
};
switch (dim_espace) {case 3: gr(3).Zero(); case 2: gr(2).Zero(); default:break;};//init
switch (dim) {case 3: base_giH(3) = &(gr(3));
case 2: base_giH(2) = &(gr(2));
case 1: base_giH(1) = &(gr(1));
default:break;
};
// calcul de la base
switch (dim) {case 3: *(base_giH(3)) = giH->Coordo(3);
case 2: *(base_giH(2)) = giH->Coordo(2);
case 1: *(base_giH(1)) = giH->Coordo(1);
default:break;
};
// stockage
TypeQuelconque typQ6(REPERE_LOCAL_H,SIG11,gr);
li_quelc.push_back(typQ6);
break;
}
case REPERE_LOCAL_B :
{base_giB.Change_taille(dim);
Tab_Grandeur_Coordonnee& gr= *((Tab_Grandeur_Coordonnee*) ((*ipq).Grandeur_pointee()));
if (pas_de_metrique_dispo)
{ cout << "\n ***erreur, la grandeur REPERE_LOCAL_B necessite la donnee de la metrique "
<< " or elle n'est pas ici disponible !! ";
Sortie(1);
};
switch (dim_espace) {case 3: gr(3).Zero(); case 2: gr(2).Zero(); default:break;};//init
switch (dim) {case 3: base_giB(3) = &(gr(3));
case 2: base_giB(2) = &(gr(2));
case 1: base_giB(1) = &(gr(1));
default:break;
};
// calcul de la base
switch (dim) {case 3: *(base_giB(3)) = giB->Coordo(3);
case 2: *(base_giB(2)) = giB->Coordo(2);
case 1: *(base_giB(1)) = giB->Coordo(1);
default:break;
};
// stockage
TypeQuelconque typQ6(REPERE_LOCAL_B,SIG11,gr);
li_quelc.push_back(typQ6);
break;
}
default :
{ // on regarde si la grandeur en fait n'est pas à calculer
bool a_atraiter = true;
if (exclure_Q != NULL)
if (find(itt_deb,itt_fin,enuconq) != itt_fin)
a_atraiter = false;
if (a_atraiter)
// cas où ce n'est pas à exclure, donc cela manque
{if (ParaGlob::NiveauImpression() > 0)
{cout << "\n warning : attention cas non traite: "
<< NomTypeQuelconque(enuconq) << "!\n";
if (ParaGlob::NiveauImpression() > 5)
cout << "\n Loi_comp_abstraite::Valeurs_quelconque_interpoler_ou_calculer(....";
Sortie(1);
};
};
}
};
};
// delete des tenseurs
// liberation des tenseurs intermediaires
LibereTenseur();
};
// affichage de la liste des grandeurs possible à calculer avec Valeur_multi_interpoler_ou_calculer
void Loi_comp_abstraite::Affichage_grandeurs_Valeurs_quelconque_interpoler_ou_calculer()
{ cout << "\n grandeurs quelconques disponibles :";
cout << "\n si pertinent: REPERE_LOCAL_ORTHO, REPERE_LOCAL_H, REPERE_LOCAL_B"
<< "\n ,CONTRAINTE_MISES_T,CONTRAINTE_TRESCA_T"
;
};
// calcul de la valeur et retour dans tab_ret d'une fonction nD
// à l'aide des grandeurs disponibles pour la loi de comportement
// nb_retour: nombre de composantes attendues en retour, si > 0
// deja_calculer: donne une liste de grandeur Ddl_enum_etendu et quelconque
// à exclure de la recherche car ils doivent avoir été calculés par ailleurs
// c'est une donnée d'entrée qui peut-être utilisée pour l'appel de la fonction nD
// list_save : est censé contenir la ou les save_result à consulter pour avoir
// des infos supplémentaires
Tableau <double> & Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(Fonction_nD* fct,int nb_retour
,const Met_abstraite::Impli* ex_impli
,const Met_abstraite::Expli_t_tdt* ex_expli_tdt
,const Met_abstraite::Umat_cont* ex_umat
,const List_io<Ddl_etendu>* deja_calculer_etend
,const List_io<const TypeQuelconque *>* deja_calculer_Q
,list <SaveResul*>* list_save
)
{ // ici on utilise les variables connues aux pti, ou calculées à partir de
// on commence par récupérer les conteneurs des grandeurs à fournir
// 1) la partie grandeurs évoluées
List_io <Ddl_enum_etendu>& li_enu_scal = fct->Li_enu_etendu_scalaire();
List_io <TypeQuelconque >& li_quelc = fct->Li_equi_Quel_evolue();
// on récupère le type d'expression des tenseurs
bool absolue = fct->Absolue();
// --- on s'occupe des Ddl_enum_etendu nécessaires pour l'appel de la fonction nD
List_io<Ddl_enum_etendu> exclure_dd_etend;
// --> on rempli la liste à exclure
if (deja_calculer_etend != NULL)
{ List_io<Ddl_etendu>::const_iterator ik,ikfin=deja_calculer_etend->end();
for (ik= deja_calculer_etend->begin(); ik != ikfin;ik++)
exclure_dd_etend.push_back((*ik).Const_DdlEnumEtendu());
};
// on va utiliser la méhode Valeur_multi_interpoler_ou_calculer
// pour les grandeurs strictement scalaire
Tableau <double> val_ddl_enum(Valeur_multi_interpoler_ou_calculer
(absolue,TEMPS_tdt,li_enu_scal,ex_impli,ex_expli_tdt,ex_umat,&exclure_dd_etend));
// on va récupérer les infos qui ont été exclus
int index = 1;
if (deja_calculer_etend != NULL)
{ List_io<Ddl_etendu>::const_iterator ik,ikfin=deja_calculer_etend->end();
List_io <Ddl_enum_etendu>::iterator il,ilfin=li_enu_scal.end();
for (il = li_enu_scal.begin(); il != ilfin; il++,index++)
{// on parcours la liste: normalement il n'y a pas beaucoup d'éléments ...
// donc ce n'est "peut-être" pas trop couteux
for (ik= deja_calculer_etend->begin(); ik != ikfin;ik++)
{if ((*ik).Const_DdlEnumEtendu() == (*il))
// on a trouvé
{val_ddl_enum(index) = (*ik).ConstValeur();
break;
};
};
};
};
// pour les grandeurs quelconque, on va exclure certaines grandeurs de l'appel de
// Valeur_multi_interpoler_ou_calculer(..)
// pour cela on se sert d'une liste locale que l'on abonde ensuite avec la liste passée
// en paramètre si elle existe
List_io<EnumTypeQuelconque> exclure_local;
if (list_save != NULL)
{// on essaie de récupérer les types quelconques
// récupération des type quelconque sous forme d'un arbre pour faciliter la recherche
list <SaveResul*>::iterator isave=list_save->begin(); // pour les saveResul des lois
list <SaveResul*>::iterator isavedebut=list_save->begin(); // pour les saveResul des lois
list <SaveResul*>::iterator isavefin=list_save->end(); // pour les saveResul des lois
List_io <TypeQuelconque>::iterator it,itfin = li_quelc.end();
for (it = li_quelc.begin(); it != itfin; it++)
{bool valeur_recuperer = false; // pour savoir s'il y a eu récupération
EnumTypeQuelconque enu=(*it).EnuTypeQuelconque().EnumTQ();
// on boucle sur les save_results pour récupérer les types quelconques
for (isave = isavedebut; isave != isavefin;isave++)
// l'idée ici est de regarder si on ne trouve pas une des grandeurs demandées dans la map
{const map < EnumTypeQuelconque , TypeQuelconque, std::less < EnumTypeQuelconque> >*
map_quelcon = (*isave)->Map_type_quelconque();
map < EnumTypeQuelconque , TypeQuelconque, std::less < EnumTypeQuelconque> >::const_iterator imap;
if (map_quelcon != NULL) // sinon il n'y a pas de map
{imap = map_quelcon->find(enu);
if (imap != map_quelcon->end())
{ // on a trouvé la grandeur
switch (Type_de_grandeur_associee(enu))
{ case SCALAIRE_DOUBLE:
{ const Grandeur_scalaire_double& tyTQ= *((Grandeur_scalaire_double*)
(*imap).second.Const_Grandeur_pointee());
// on renseigne l'argument
(*(*it).Grandeur_pointee()) = tyTQ;
valeur_recuperer = true;
break;
}
case SCALAIRE_ENTIER:
{ const Grandeur_scalaire_entier& tyTQ= *((Grandeur_scalaire_entier*)
(*imap).second.Const_Grandeur_pointee());
// on renseigne l'argument
(*(*it).Grandeur_pointee()) = tyTQ;
valeur_recuperer = true;
break;
}
default:
{cout << "\n erreur fatale dans l'utilisation de la grandeur locale,"
<< NomTypeQuelconque(enu)
<< " necessaire pour le calcul de la ponderation "
<< " cette grandeur n'est pas un scalaire, pour l'instant "
<< " on ne sait pas comment l'utiliser !! "
<< "\n Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee(... ";
Sortie(1);
};
break;
};
// on sort de la boucle
break;
};
// si la grandeur a été récupérée, on l'exclue de la liste à transmettre
// à la méthode Valeurs_Tensorielles_interpoler_ou_calculer
if (valeur_recuperer)
exclure_local.push_back(enu);
};
// on merge les des deux exclure
if (deja_calculer_Q != NULL)
{List_io <const TypeQuelconque *>::const_iterator iv,ivfin = deja_calculer_Q->end();
for (iv=deja_calculer_Q->begin();iv != ivfin;iv++)
{ if (*iv != NULL)
{EnumTypeQuelconque enutq = (*iv)->EnuTypeQuelconque().EnumTQ();
exclure_local.push_back(enutq);
}
}
};
exclure_local.sort();
exclure_local.unique();
};
};
};
// on utilise la méthode Valeurs_Tensorielles_interpoler_ou_calculer
// pour les Coordonnees et Tenseur
Valeurs_Tensorielles_interpoler_ou_calculer
(absolue,TEMPS_tdt,li_quelc,ex_impli,ex_expli_tdt,ex_umat,&exclure_local);
// arrivée ici toutes les grandeurs évoluées de la fonction sont connues
// 2) on s'occupe maintenant des grandeurs quelconques autres qu'évoluées
// celles-ci , si elles ne sont pas déjà connues via la liste d'exclusion
// sont supposées être uniquement dans la map
// -> si on ne les trouve pas ==> pb !
const Tableau <EnumTypeQuelconque>& tqi = fct->Tab_enu_quelconque();
int taille_tqi = tqi.Taille();
Tableau < const TypeQuelconque * > tquelc(taille_tqi);
// on réutilise la map qui est aussi sensé contenir les quelconques autres
if (taille_tqi != 0)
{if(list_save == NULL)
{cout << "\n erreur fatale dans l'utilisation de grandeurs quelconque,"
<< " necessaire pour le calcul de la fonction nD "
<< " les grandeurs ne sont pas disponibles, a priori ??? "
<< "\n Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee(... ";
Sortie(1);
}
else
{ // on essaie de récupérer les types quelconques
// --- préparation pour les grandeurs déjà calculées et passée en paramètre
List_io<const TypeQuelconque *>::const_iterator ik,ikfin,ikdebut;
if (deja_calculer_Q != NULL)
{ ikfin = deja_calculer_Q->end();
ikdebut = deja_calculer_Q->begin();
};
// récupération des type quelconque sous forme d'un arbre pour faciliter la recherche
list <SaveResul*>::iterator isave=list_save->begin(); // pour les saveResul des lois
list <SaveResul*>::iterator isavedebut=list_save->begin(); // pour les saveResul des lois
list <SaveResul*>::iterator isavefin=list_save->end(); // pour les saveResul des lois
for (int i = 1; i <= taille_tqi; i++)
{bool valeur_recuperer = false; // pour savoir s'il y a eu récupération
EnumTypeQuelconque enu= tqi(i);
//a) on regarde si la grandeur ne fait pas partie des grandeurs déjà connues
// via l'exclusion passée en paramètre
if (deja_calculer_Q != NULL)
{// on parcours la liste: normalement il n'y a pas beaucoup d'éléments ...
// donc ce n'est "peut-être" pas trop couteux
for (ik= ikdebut; ik != ikfin;ik++)
{if ((*ik)->EnuTypeQuelconque().EnumTQ() == enu)
// on a trouvé
{tquelc(i) = (*ik);
valeur_recuperer = true;
break;
};
};
};
// on continue si on n'a pas récupéré
// on boucle sur les save_results pour récupérer les types quelconques
if (!valeur_recuperer)
for (isave = isavedebut; isave != isavefin;isave++)
// l'idée ici est de regarder si on ne trouve pas une des grandeurs demandées dans la map
{const map < EnumTypeQuelconque , TypeQuelconque, std::less < EnumTypeQuelconque> >*
map_quelcon = (*isave)->Map_type_quelconque();
map < EnumTypeQuelconque , TypeQuelconque, std::less < EnumTypeQuelconque> >::const_iterator imap;
if (map_quelcon != NULL) // sinon il n'y a pas de map
{imap = map_quelcon->find(enu);
if (imap != map_quelcon->end())
{ // on a trouvé la grandeur
tquelc(i) = &(*imap).second;
valeur_recuperer = true;
break;
};
};
};
if (!valeur_recuperer)// si on n'a pas trouvé, pb car on ne pourra pas fournir l'info nécessaire
// pour la fonction nD
{cout << "\n erreur fatale dans l'utilisation de la grandeur locale,"
<< NomTypeQuelconque(enu)
<< " necessaire pour le calcul de la fonction nD "
<< " cette grandeur n'est pas disponible, a priori ??? "
<< "\n Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee(... ";
Sortie(1);
};
};
};
};
try
{// maintenant calcul de la valeur et retour dans tab_ret
// sauf les valeurs à exclure
Tableau <double> & tab_val = fct->Valeur_FnD_Evoluee(&val_ddl_enum,&li_enu_scal,&li_quelc,&tquelc,NULL);
#ifdef MISE_AU_POINT
if (nb_retour > 0)
{if (tab_val.Taille() != nb_retour)
{ cout << "\nErreur : la fonction nD relative " << fct->NomFonction()
<< " doit calculer "<< nb_retour << " or le tableau de retour est de taille "
<< tab_val.Taille() << " ce n'est pas normal !\n";
cout << "\n **** erreur: Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee \n";
Sortie(1);
};
};
#endif
// on retourne les infos
return tab_val;
}
catch(ErrCalculFct_nD &e)
{ cout << "\n Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee \n";
cout << "\n ** erreur dans l'appel de la fonction " << fct->NomFonction();
//cout << "\n pour debug Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee \n";
//Tableau <double> & tab_val = fct->Valeur_FnD_Evoluee(&val_ddl_enum,&li_enu_scal,&li_quelc,&tquelc,NULL);
throw e;
Sortie(1);
}
};
// calcul l'affichage, si celui-ci dépend d'une fonction nD
// ne doit être appelé que si la fonction nD existe (pas de vérification)
// en fait est utilisé uniquement par la méthode inline: Permet_affichage()
int Loi_comp_abstraite::Cal_permet_affichage()
{
// il faut calculer la fonction nD
// ici on utilise les variables connues aux pti, ou calculées à partir de
// on commence par récupérer les conteneurs des grandeurs à fournir
List_io <Ddl_enum_etendu>& li_enu_scal = permet_affich_loi_nD->Li_enu_etendu_scalaire();
List_io <TypeQuelconque >& li_quelc = permet_affich_loi_nD->Li_equi_Quel_evolue();
bool absolue = true; // on se place systématiquement en absolu
// on va utiliser la méhode Valeur_multi_interpoler_ou_calculer
// pour les grandeurs strictement scalaire
// ici toutes les métriques sont NULL (les 3 premiers NULL)
// pas d'exclusion de Ddl_enum_etendu (le dernier NULL)
Tableau <double> val_ddl_enum(Valeur_multi_interpoler_ou_calculer
(absolue,TEMPS_tdt,li_enu_scal,NULL,NULL,NULL,NULL));
// on utilise la méthode Valeurs_Tensorielles_interpoler_ou_calculer
// pour les Coordonnees et Tenseur
Valeurs_Tensorielles_interpoler_ou_calculer
(absolue,TEMPS_tdt,li_quelc,NULL,NULL,NULL,NULL);
// arrivée ici toutes les grandeurs évoluées de la fonction sont connues
// 2) on s'occupe maintenant des grandeurs quelconques autres qu'évoluées
const Tableau <EnumTypeQuelconque>& tqi = permet_affich_loi_nD->Tab_enu_quelconque();
Valeurs_quelconque_interpoler_ou_calculer
(absolue,TEMPS_tdt,tqi,li_quelconque,NULL,NULL,NULL,NULL);
// calcul de la valeur et retour dans tab_ret
Tableau <double> & tab_val
= permet_affich_loi_nD->Valeur_FnD_Evoluee(&val_ddl_enum,&li_enu_scal,&li_quelc,&tab_pt_li_quelconque,NULL);
#ifdef MISE_AU_POINT
if (tab_val.Taille() != 1)
{ cout << "\nErreur : la fonction nD relative a l'affichage dans la loi de comportement "
<< " doit calculer un vecteur de dimention 1 or le tableau de retour est de taille "
<< tab_val.Taille() << " ce n'est pas normal !\n";
cout << " Loi_comp_abstraite::Cal_permet_affichage()\n";
Sortie(1);
};
#endif
// on récupère les valeurs du tableau
permet_affich_loi= tab_val(1);
// retour
return permet_affich_loi;
};
// sortie du niveau d'affichage
void Loi_comp_abstraite::Affiche_niveau_affichage()const
{ cout << " niveau_affichage_local= ";
if (permet_affich_loi_nD == NULL)
{ cout << permet_affich_loi; }
else
{ cout << " controle via la fonction nD: "<< permet_affich_loi_nD->NomFonction()
<< " (derniere valeur: "<<permet_affich_loi << ") ";
};
};
void Loi_comp_abstraite::Affiche_niveau_affichage(ofstream& sort,const int cas)
{ // on traite en fonction de l'existance ou non d'une fonction nD
if (permet_affich_loi_nD != NULL)
{sort << " 1 permet_affich_loi_nD: ";
LesFonctions_nD::Ecriture_pour_base_info(sort,cas,permet_affich_loi_nD);
}
else
{sort << " 0 " << permet_affich_loi ; };
};
void Loi_comp_abstraite::Lecture_permet_affichage
(ifstream& ent,const int cas,LesFonctions_nD& lesFonctionsnD)
{
// on traite en fonction de l'existance ou non d'une fonction nD
int test =0;string nom;
ent >> test;
if (test)
{ent >> nom;
if (nom != " permet_affich_loi_nD: ")
{ cout << "\n erreur en lecture de la fonction nD, on attendait "
<< " permet_affich_loi_nD: et on a lue " << nom
<< "\n Loi_comp_abstraite::Lecture_permet_affichage(...";
Sortie(1);
};
permet_affich_loi_nD = lesFonctionsnD.Lecture_pour_base_info
( ent,cas,permet_affich_loi_nD);
}
else
{ent >> permet_affich_loi;
if (permet_affich_loi_nD != NULL)
if (permet_affich_loi_nD->NomFonction() == "_") delete permet_affich_loi_nD;
permet_affich_loi_nD = NULL;
};
};
// lecture de l'affichage avec éventuellement une fonction nD
void Loi_comp_abstraite::Lecture_permet_affichage(UtilLecture * entreePrinc,LesFonctions_nD& lesFonctionsnD)
{// il faut voir s'il s'agit d'un niveau paramétrée par une fonction nD ou pas
string nom_class_methode("Loi_comp_abstraite::Lecture_permet_affichage(..");
if (strstr(entreePrinc->tablcar,"affichage_fonction_nD:")!= NULL)
{ string nom;
string mot_cle2="affichage_fonction_nD:";
string nom_fonct;
bool lec = entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle2,nom_fonct);
if (!lec )
{ entreePrinc->MessageBuffer("**erreur en lecture** "+mot_cle2);
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// maintenant on définit la fonction
if (lesFonctionsnD.Existe(nom_fonct))
{permet_affich_loi_nD = lesFonctionsnD.Trouve(nom_fonct);
}
else
{// sinon il faut la lire maintenant
string non("_");
permet_affich_loi_nD = Fonction_nD::New_Fonction_nD(non, Id_Nom_Fonction_nD(nom_fonct));
// lecture de la courbe
permet_affich_loi_nD->LectDonnParticulieres_Fonction_nD (non,entreePrinc);
// maintenant on vérifie que la fonction est utilisable
if (permet_affich_loi_nD->NbComposante() != 1 )
{ cout << "\n erreur en lecture, la fonction " << nom_fonct
<< " est une fonction vectorielle a " << permet_affich_loi_nD->NbComposante()
<< " composante alors qu'elle devrait etre scalaire ! "
<< " elle n'est donc pas utilisable !! ";
string message("\n**erreur03** \n"+nom_class_methode+"(...");
entreePrinc->MessageBuffer(message);
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// on regarde si la fonction nD intègre la température
const Tableau <Ddl_enum_etendu>& tab_enu = permet_affich_loi_nD->Tab_enu_etendu();
if (tab_enu.Contient(TEMP))
thermo_dependant=true;
};
}
else // sinon il s'agit d'un simple entier
{*(entreePrinc->entree) >> permet_affich_loi;
// gestion du pointeur de fonction
if (permet_affich_loi_nD != NULL)
if (permet_affich_loi_nD->NomFonction() == "_")
delete permet_affich_loi_nD;
};
};