Herezh_dev/comportement/lois_combinees/LoiDesMelangesEnSigma.cc
2023-05-03 17:23:49 +02:00

2678 lines
139 KiB
C++

// FICHIER : LoiDesMelangesEnSigma.cp
// CLASSE : LoiDesMelangesEnSigma
// 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-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.
//#include "Debug.h"
#include "LesLoisDeComp.h"
# include <iostream>
using namespace std; //introduces namespace std
#include <math.h>
#include <stdlib.h>
#include "Sortie.h"
#include "TypeQuelconqueParticulier.h"
#include "TypeConsTens.h"
#include "NevezTenseurQ.h"
#include "CharUtil.h"
#include "LoiDesMelangesEnSigma.h"
//==================== cas de la class de sauvegarde SaveResul ===================
// constructeur par défaut à ne pas utiliser
LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma() :
liste_des_SaveResul() ,l_sigoHH(),l_sigoHH_t(),l_energ(),l_energ_t()
,J_sigoHH(),J_sigoHH_t(),proportion(1.),proportion_t(1.),type_evolution_proportion(0)
,deja_actif_sur_iter1(false),deja_actif_sur_iter2(false)
{ cout << "\n erreur, le constructeur par defaut ne doit pas etre utilise !"
<< "\n LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma()";
Sortie(1);
};
// le constructeur courant
LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma
(list <SaveResul*>& l_des_SaveResul
,list <TenseurHH* >& l_siHH,list <TenseurHH* >& l_siHH_t
,list <TenseurHH* >& J_siHH,list <TenseurHH* >& J_siHH_t
,list <EnergieMeca >& l_energ_,list <EnergieMeca >& l_energ_t_
,int type_evol_proportion):
liste_des_SaveResul() ,l_sigoHH(),l_sigoHH_t(),l_energ(l_energ_),l_energ_t(l_energ_t_)
,J_sigoHH(),J_sigoHH_t(),proportion(1.),proportion_t(1.)
,type_evolution_proportion(type_evol_proportion)
,deja_actif_sur_iter1(false),deja_actif_sur_iter2(false)
{ list <SaveResul *>::const_iterator ili,ilifin=l_des_SaveResul.end();
list <TenseurHH* >::const_iterator isig,isig_t,jsig,jsig_t;
for (ili=l_des_SaveResul.begin(),isig = l_siHH.begin(),isig_t = l_siHH_t.begin()
,jsig = J_siHH.begin(),jsig_t = J_siHH_t.begin();
ili!=ilifin;ili++,isig++,isig_t++,jsig++,jsig_t++)
{ SaveResul * nevez_save_result=NULL;
if ((*ili) != NULL) nevez_save_result = (*ili)->Nevez_SaveResul();
liste_des_SaveResul.push_back(nevez_save_result);
TenseurHH * interHH=NULL;
// dans le cas où le tenseur passé en paramètre est non null on s'en sert
if ((*isig) != NULL) {interHH=NevezTenseurHH(*(*isig));};
l_sigoHH.push_back(interHH);
TenseurHH * interHH_t=NULL;
// idem interHH, dans le cas où le tenseur passé en paramètre est non null on s'en sert
if ((*isig_t) != NULL) {interHH_t =NevezTenseurHH(*(*isig_t));};
l_sigoHH_t.push_back(interHH_t);
TenseurHH * jnterHH=NULL;
// dans le cas où le tenseur passé en paramètre est non null on s'en sert
if ((*jsig) != NULL) {jnterHH=NevezTenseurHH(*(*jsig));};
J_sigoHH.push_back(jnterHH);
TenseurHH * jnterHH_t=NULL;
// idem interHH, dans le cas où le tenseur passé en paramètre est non null on s'en sert
if ((*jsig_t) != NULL) {jnterHH_t =NevezTenseurHH(*(*jsig_t));};
J_sigoHH_t.push_back(jnterHH_t);
};
//---debug
//cout << "\n constructeur: taille_l_energ= " << l_energ.size() << " taille_l_energ_t= " << l_energ_t.size()<< endl;
//---fin debug
};
// constructeur de copie
LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma
(const LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma& sav ):
liste_des_SaveResul() ,l_sigoHH(),l_sigoHH_t(),J_sigoHH(),J_sigoHH_t()
,l_energ(sav.l_energ),l_energ_t(sav.l_energ_t)
,proportion(sav.proportion),proportion_t(sav.proportion_t)
,type_evolution_proportion(sav.type_evolution_proportion)
,deja_actif_sur_iter1(sav.deja_actif_sur_iter1),deja_actif_sur_iter2(sav.deja_actif_sur_iter2)
{ list <SaveResul *>::const_iterator ili,ilifin=sav.liste_des_SaveResul.end();
list <TenseurHH* >::const_iterator isig,isig_t,jsig,jsig_t;
for (ili=sav.liste_des_SaveResul.begin(),isig = sav.l_sigoHH.begin(),isig_t = sav.l_sigoHH_t.begin()
,jsig = sav.J_sigoHH.begin(),jsig_t = sav.J_sigoHH_t.begin();
ili!=ilifin;ili++,isig++,isig_t++,jsig++,jsig_t++)
{ SaveResul * nevez_save_result = NULL;
if ((*ili) != NULL) nevez_save_result=(*ili)->Nevez_SaveResul();
liste_des_SaveResul.push_back(nevez_save_result);
TenseurHH * interHH=NULL;
// dans le cas où le tenseur passé en paramètre est non null on s'en sert
if ((*isig) != NULL) {interHH=NevezTenseurHH(*(*isig));};
l_sigoHH.push_back(interHH);
TenseurHH * interHH_t=NULL;
// idem interHH, dans le cas où le tenseur passé en paramètre est non null on s'en sert
if ((*isig_t) != NULL) {interHH_t =NevezTenseurHH(*(*isig_t));};
l_sigoHH_t.push_back(interHH_t);
TenseurHH * jnterHH=NULL;
// dans le cas où le tenseur passé en paramètre est non null on s'en sert
if ((*jsig) != NULL) {jnterHH=NevezTenseurHH(*(*jsig));};
J_sigoHH.push_back(jnterHH);
TenseurHH * jnterHH_t=NULL;
// idem interHH, dans le cas où le tenseur passé en paramètre est non null on s'en sert
if ((*jsig_t) != NULL) {jnterHH_t =NevezTenseurHH(*(*jsig_t));};
J_sigoHH_t.push_back(jnterHH_t);
};
//---debug
//cout << "\n constructeur_copie: taille_l_energ= " << l_energ.size() << " taille_l_energ_t= " << l_energ_t.size()<< endl;
//this->Affiche(); cout << "\n" << endl;
//---fin debug
};
// destructeur
LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::~SaveResul_LoiDesMelangesEnSigma()
{ list <SaveResul *>::iterator ili,ilifin=liste_des_SaveResul.end();
list <TenseurHH* >::iterator isig,isig_t,jsig,jsig_t;
for (ili=liste_des_SaveResul.begin(),isig = l_sigoHH.begin(),isig_t = l_sigoHH_t.begin()
,jsig = J_sigoHH.begin(),jsig_t = J_sigoHH_t.begin();
ili!=ilifin;ili++,isig++,isig_t++,jsig++,jsig_t++)
{if ((*ili) != NULL) delete (*ili); //liste_des_SaveResul.erase(ili);
if((*isig) != NULL) delete (*isig); if((*isig_t) != NULL) delete (*isig_t);
if((*jsig) != NULL) delete (*jsig); if((*jsig_t) != NULL) delete (*jsig_t);
};
};
// affectation
Loi_comp_abstraite::SaveResul &
LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::operator = ( const Loi_comp_abstraite::SaveResul & a)
{ LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma& sav
= *((LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma*) &a);
// on regarde si les listes sont de même tailles, si oui on considère qu'elle sont des conteneurs identiques
// sinon on les crée
list <SaveResul *>::const_iterator ili,ilifin=sav.liste_des_SaveResul.end();
list <TenseurHH* >::const_iterator isig = sav.l_sigoHH.begin();
list <TenseurHH* >::const_iterator isig_t = sav.l_sigoHH_t.begin();
list <TenseurHH* >::const_iterator kisig = sav.J_sigoHH.begin();
list <TenseurHH* >::const_iterator kisig_t = sav.J_sigoHH_t.begin();
if (liste_des_SaveResul.size() != sav.liste_des_SaveResul.size())
{// 1) on vide la liste
list <SaveResul *>::iterator jli,jlifin=liste_des_SaveResul.end();
list <TenseurHH* >::iterator jsig = l_sigoHH.begin();
list <TenseurHH* >::iterator jsig_t = l_sigoHH_t.begin();
list <TenseurHH* >::iterator ksig = J_sigoHH.begin();
list <TenseurHH* >::iterator ksig_t = J_sigoHH_t.begin();
// on supprime les grandeurs pointées
for (jli=liste_des_SaveResul.begin();jli!=jlifin;
jli++,jsig++,jsig_t++,ksig++,ksig_t++)
{if ((*jli) != NULL) delete (*jli); //liste_des_SaveResul.erase(ili);
if((*jsig) != NULL) delete (*jsig); if((*jsig_t) != NULL) delete (*jsig_t);
if((*ksig) != NULL) delete (*ksig); if((*ksig_t) != NULL) delete (*ksig_t);
};
// on vide les listes
liste_des_SaveResul.clear();l_sigoHH.clear();l_sigoHH_t.clear();
J_sigoHH.clear();J_sigoHH_t.clear();
// 2) on recrée à la bonne taille
for (ili=sav.liste_des_SaveResul.begin();
ili!=ilifin;ili++,isig++,isig_t++,kisig++,kisig_t++)
{ SaveResul * nevez_save_result = NULL;
if ((*ili) != NULL) nevez_save_result = (*ili)->Nevez_SaveResul();
liste_des_SaveResul.push_back(nevez_save_result);
TenseurHH * interHH=NULL;
// dans le cas où le tenseur passé en paramètre est non null on s'en sert
if ((*isig) != NULL) {interHH=NevezTenseurHH(*(*isig));};
l_sigoHH.push_back(interHH);
TenseurHH * interHH_t=NULL;
// idem interHH, dans le cas où le tenseur passé en paramètre est non null on s'en sert
if ((*isig_t) != NULL) {interHH_t =NevezTenseurHH(*(*isig_t));};
l_sigoHH_t.push_back(interHH_t);
// idem pour kisig
if ((*kisig) != NULL) {interHH_t =NevezTenseurHH(*(*kisig));};
J_sigoHH.push_back(interHH_t);
// idem pour kisig_t
if ((*kisig_t) != NULL) {interHH_t =NevezTenseurHH(*(*kisig_t));};
J_sigoHH_t.push_back(interHH_t);
};
}
else // sinon on affecte les conteneurs
{
list <SaveResul *>::iterator jli=liste_des_SaveResul.begin();
list <TenseurHH* >::iterator jsig=l_sigoHH.begin();
list <TenseurHH* >::iterator jsig_t=l_sigoHH_t.begin();
list <TenseurHH* >::iterator ksig=J_sigoHH.begin();
list <TenseurHH* >::iterator ksig_t=J_sigoHH_t.begin();
for (ili=sav.liste_des_SaveResul.begin();
ili!=ilifin;ili++,isig++,isig_t++,kisig++,kisig_t++
,jli++,jsig++,jsig_t++,ksig++,ksig_t++)
{ (*(*jli))=(*(*ili)); (*(*isig))=(*(*jsig));(*(*isig_t))=(*(*jsig_t));
(*(*ksig))=(*(*kisig));(*(*ksig_t))=(*(*kisig_t));
};
};
// puis les grandeurs qui ne posent pas de pb
proportion = sav.proportion;
proportion_t = sav.proportion_t;
type_evolution_proportion = sav.type_evolution_proportion;
l_energ = sav.l_energ;
l_energ_t = sav.l_energ_t;
deja_actif_sur_iter1 = sav.deja_actif_sur_iter1;
deja_actif_sur_iter2 = sav.deja_actif_sur_iter2;
return *this;
};
//============= lecture écriture dans base info ==========
// cas donne le niveau de la récupération
// = 1 : on récupère tout
// = 2 : on récupère uniquement les données variables (supposées comme telles)
void LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::Lecture_base_info
(ifstream& ent,const int cas)
{// ici toutes les données sont toujours a priori variables
// ou en tout cas pour les méthodes appelées, elles sont gérées par le paramètre: cas
string toto; ent >> toto;
#ifdef MISE_AU_POINT
if (toto != "S_R_LoiMeSig")
{ cout << "\n erreur en lecture du conteneur pour la loi additive"
<< " \n LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::Lecture_base_info(..";
Sortie(1);
};
#endif
// la proportion
ent >> toto >> proportion_t ; //proportion = proportion_t;
if (cas == 1)
ent >> toto >> type_evolution_proportion; // le type d'évolution
ent >> toto >> deja_actif_sur_iter1 >> deja_actif_sur_iter2;
// lecture du nombre de loi
int nb_loi; ent >> nb_loi;
// Dans le cas où le nombre de loi n'est pas identique au cas actuel
// cela signifie que l'instance est mal déclaré -> pb on arrête
// sinon on lit uniquement
#ifdef MISE_AU_POINT
if (nb_loi != liste_des_SaveResul.size())
{ cout << "\n erreur en lecture du conteneur pour la loi additive, cas des infos specifiques a chaque loi"
<< "\n le nombre de loi definit est different de celui lu donc il y a un pb d'initialisation"
<< " \n LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::Lecture_base_info(..";
Sortie(1);
};
#endif
// on itère sur ces grandeurs
list <SaveResul *>::iterator ili,ilifin=liste_des_SaveResul.end();
list <TenseurHH* >::iterator isig_t,jsig_t;
list <EnergieMeca >::iterator ienerg_t=l_energ_t.begin();
for (ili=liste_des_SaveResul.begin(),isig_t = l_sigoHH_t.begin(),jsig_t = J_sigoHH_t.begin();
ili!=ilifin;ili++,isig_t++,ienerg_t++)
{ // données de chaque loi
if((*ili) != NULL) (*ili)->Lecture_base_info(ent,cas);
// lecture de la contrainte sauvegardée
(*isig_t)->Lecture(ent); // lecture du tenseur
// lecture de la contrainte sauvegardée
(*jsig_t)->Lecture(ent); // lecture du tenseur
// lecture des énergies
ent >> (*ienerg_t);
};
// on met les grandeurs de t vers tdt
TversTdt();
};
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::Ecriture_base_info
(ofstream& sort,const int cas)
{ // ici la majorité des données sont toujours a priori variables
// ou en tout cas pour les méthodes appelées, elles sont gérées par le paramètre: cas
sort << "\n S_R_LoiMeSig ";
// la proportion
sort << " prop= " << proportion_t << " ";
if (cas == 1)
sort << " type_evol_prop= " << type_evolution_proportion << " ";
// deja_actif_sur_iter
sort << " deja_actif_sur_iter= "<<deja_actif_sur_iter1<<" "<<deja_actif_sur_iter2<<" ";
// on sort enfin le nombre de grandeur à sauvegarde
sort << liste_des_SaveResul.size() << " ";
// on itère sur ces grandeurs
list <SaveResul *>::iterator ili,ilifin=liste_des_SaveResul.end();
list <TenseurHH* >::iterator isig_t,jsig_t;
list <EnergieMeca >::iterator ienerg_t=l_energ_t.begin();
for (ili=liste_des_SaveResul.begin(),isig_t = l_sigoHH_t.begin(),jsig_t = J_sigoHH_t.begin();
ili!=ilifin;ili++,isig_t++,ienerg_t++)
{ // données de chaque loi
if ((*ili) != NULL)
(*ili)->Ecriture_base_info(sort,cas);sort << " ";
// la contrainte sauvegardée est celle stable uniquement
(*isig_t)->Ecriture(sort); sort << " " ;// écriture du tenseur
// la contrainte sauvegardée est celle stable uniquement
(*jsig_t)->Ecriture(sort); // écriture du tenseur
sort << " " << (*ienerg_t); // écriture des énergies
};
};
// mise à jour des informations transitoires en définitif s'il y a convergence
// par exemple (pour la plasticité par exemple)
void LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::TdtversT()
{ list <SaveResul *>::iterator ili,ilifin=liste_des_SaveResul.end();
list <TenseurHH* >::iterator isig_t,isig,jsig_t,jsig;
list <EnergieMeca >::iterator ienerg,ienerg_t;
for (ili=liste_des_SaveResul.begin(),isig_t = l_sigoHH_t.begin(),isig = l_sigoHH.begin()
,jsig_t = J_sigoHH_t.begin(),jsig = J_sigoHH.begin()
,ienerg=l_energ.begin(),ienerg_t=l_energ_t.begin();
ili!=ilifin;ili++,isig_t++,isig++,jsig_t++,jsig++,ienerg++,ienerg_t++)
{if ((*ili) != NULL) (*ili)->TdtversT();
(*(*isig_t)) = (*(*isig));(*(*jsig_t)) = (*(*jsig));
(*ienerg_t)=(*ienerg);
};
// la proportion
proportion_t = proportion;
//non, ce n'est pas la bonne solution dans le cas général proportion = 1.; // on démarre à priori sur la première loi
// cas où la proportion démarrre à 1 et ne fait que diminuer sur chaque incrément
// pour le premier incrément, la proportion est initialisée à la valeur par défaut
if (type_evolution_proportion == 2)
proportion = 1.;
// deja_actif_sur_iter: pour l'instant on remet à false car
// c'est présumé travailler uniquement sur un incrément
deja_actif_sur_iter1 = deja_actif_sur_iter2 = false;
};
void LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::TversTdt()
{ list <SaveResul *>::iterator ili,ilifin=liste_des_SaveResul.end();
list <TenseurHH* >::iterator isig_t,isig,jsig_t,jsig;
list <EnergieMeca >::iterator ienerg,ienerg_t;
for (ili=liste_des_SaveResul.begin(),isig_t = l_sigoHH_t.begin(),isig = l_sigoHH.begin()
,jsig_t = J_sigoHH_t.begin(),jsig = J_sigoHH.begin()
,ienerg=l_energ.begin(),ienerg_t=l_energ_t.begin();
ili!=ilifin;ili++,isig_t++,isig++,jsig_t++,jsig++,ienerg++,ienerg_t++)
{if ((*ili) != NULL) (*ili)->TversTdt();
(*(*isig)) = (*(*isig_t));(*(*jsig)) = (*(*jsig_t));
(*ienerg)=(*ienerg_t);
};
// la proportion
proportion = proportion_t;
// cas où la proportion démarrre à 1 et ne fait que diminuer sur chaque incrément
// pour le premier incrément, la proportion est initialisée à la valeur par défaut
if (type_evolution_proportion == 2)
proportion = 1.;
// deja_actif_sur_iter: pour l'instant on remet à false car
// c'est présumé travailler uniquement sur un incrément
deja_actif_sur_iter1 = deja_actif_sur_iter2 = false;
};
// affichage à l'écran des infos
void LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::Affiche() const
{ cout << "\n SaveResul_LoiDesMelangesEnSigma: " ;
list <SaveResul *>::const_iterator ili,ilifin=liste_des_SaveResul.end();
list <TenseurHH* >::const_iterator isig,isigfin=l_sigoHH.end();
list <TenseurHH* >::const_iterator isig_t,isig_tfin=l_sigoHH_t.end();
list <TenseurHH* >::const_iterator jsig,jsigfin=J_sigoHH.end();
list <TenseurHH* >::const_iterator jsig_t,jsig_tfin=J_sigoHH_t.end();
list <EnergieMeca >::const_iterator ienerg,ienergfin = l_energ.end();
list <EnergieMeca >::const_iterator ienerg_t,ienerg_tfin = l_energ_t.end();
cout << "\n liste_des_SaveResul: ";
for (ili=liste_des_SaveResul.begin();ili!=ilifin;ili++)
{if ((*ili) != NULL) { cout << "\n "; (*ili)->Affiche();};};
cout << "\n l_sigoHH: ";
for (isig = l_sigoHH.begin();isig!=isigfin;isig++)
{ (*isig)->Ecriture(cout);};
cout << "\n l_sigoHH_t: ";
for (isig_t = l_sigoHH_t.begin();isig_t!=isig_tfin;isig_t++)
{ (*isig_t)->Ecriture(cout);};
cout << "\n J_sigoHH: ";
for (jsig = J_sigoHH.begin();jsig!=jsigfin;jsig++)
{ (*jsig)->Ecriture(cout);};
cout << "\n J_sigoHH_t: ";
for (jsig_t = J_sigoHH_t.begin();jsig_t!=jsig_tfin;jsig_t++)
{ (*jsig_t)->Ecriture(cout);};
cout << "\n l_energ: ";
for (ienerg = l_energ.begin();ienerg!=ienergfin;ienerg++)
{ cout << (*ienerg);};
cout << "\n l_energ_t: ";
for (ienerg_t = l_energ_t.begin();ienerg_t!=ienerg_tfin;ienerg_t++)
{ cout << (*ienerg_t);};
cout << "\n proportion= " << proportion << " proportion_t= " << proportion_t << " ";
cout << "\n deja_actif_sur_iter(1 et 2)= " << deja_actif_sur_iter1 <<" "<<deja_actif_sur_iter2<<" ";
cout << "\n .. fin SaveResul_LoiDesMelangesEnSigma:.. \n" ;
};
//changement de base de toutes les grandeurs internes tensorielles stockées
// beta(i,j) represente les coordonnees de la nouvelle base naturelle gpB dans l'ancienne gB
// gpB(i) = beta(i,j) * gB(j), i indice de ligne, j indice de colonne
// gpH(i) = gamma(i,j) * gH(j)
void LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::ChBase_des_grandeurs(const Mat_pleine& beta,const Mat_pleine& gamma)
{ // on ne s'intéresse qu'aux grandeurs tensorielles
// encapsulage pour utiliser deux fois les mêmes itérators
{ List_io <SaveResul*>::iterator lit(liste_des_SaveResul.begin()),
lend(liste_des_SaveResul.end());
for(;lit!=lend;++lit) // ici les bornes ne changent pas
if ((*lit) != NULL) // s'il y a un conteneur non nul
(*lit)->ChBase_des_grandeurs(beta,gamma);
};
{ List_io <TenseurHH*>::iterator lit(l_sigoHH.begin()),
lend(l_sigoHH.end());
for(;lit!=lend;++lit) // ici les bornes ne changent pas
(*lit)->ChBase(gamma);
};
{ List_io <TenseurHH*>::iterator lit(l_sigoHH_t.begin()),
lend(l_sigoHH_t.end());
for(;lit!=lend;++lit) // ici les bornes ne changent pas
(*lit)->ChBase(gamma);
};
{ List_io <TenseurHH*>::iterator lit(J_sigoHH.begin()),
lend(J_sigoHH.end());
for(;lit!=lend;++lit) // ici les bornes ne changent pas
(*lit)->ChBase(gamma);
};
{ List_io <TenseurHH*>::iterator lit(J_sigoHH_t.begin()),
lend(J_sigoHH_t.end());
for(;lit!=lend;++lit) // ici les bornes ne changent pas
(*lit)->ChBase(gamma);
};
};
// procedure permettant de completer éventuellement les données particulières
// de la loi stockées
// au niveau du point d'intégration par exemple: exemple: un repère d'anisotropie
// completer est appelé apres sa creation avec les donnees du bloc transmis
// peut etre appeler plusieurs fois
Loi_comp_abstraite::SaveResul* LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma
::Complete_SaveResul(const BlocGen & bloc, const Tableau <Coordonnee>& tab_coor
,const Loi_comp_abstraite* loi)
{// on transmet au conteneur 3D interne
const LoiDesMelangesEnSigma * loi_CP = (const LoiDesMelangesEnSigma*) loi;
// récup des conteneurs relatifs à chaque loi
list <SaveResul*>::iterator ia = liste_des_SaveResul.begin();
// traitement de la première loi
(*ia)->Complete_SaveResul(bloc,tab_coor,loi_CP->lois_internes1);
// traitement de la seconde loi
ia++;
(*ia)->Complete_SaveResul(bloc,tab_coor,loi_CP->lois_internes2);
return this;
};
// ---- récupération d'information: spécifique à certaine classe dérivée
double LoiDesMelangesEnSigma::SaveResul_LoiDesMelangesEnSigma::Deformation_plastique()
{ cout << "\n pour l'instant cette option n'est pas implante dans le cas d'une loi"
<< "\n additive en contrainte"
<< "\n double Loi_comp_abstraite::SaveResul_LoiDesMelangesEnSigma::Deformation_plastique()";
Sortie(1);
return 0.; // pour taire le warning, mais on ne passe jamais là
};
//==================== fin du cas de la class de sauvegarde SaveResul ============
LoiDesMelangesEnSigma::LoiDesMelangesEnSigma () : // Constructeur par defaut
Loi_comp_abstraite(LOI_DES_MELANGES_EN_SIGMA,RIEN_CATEGORIE_LOI_COMP,0)
,lois_internes1(NULL),lois_internes2(NULL)
,calcule_si_prop_non_nulle(),d_sigtotalHH()
,type_grandeur(NU_DDL),proportion(1.),d_sigma_deps_inter(NULL)
,type_melange(1),valeur_aux_noeuds(true),c_proport(NULL),aA(1.)
,niveauF_grandeurND(NULL),niveauF_grandeurConsultable(NULL)
,niveauF_ddlEtendu(NULL),niveauF_temps(NULL)
{};
// Constructeur de copie
LoiDesMelangesEnSigma::LoiDesMelangesEnSigma (const LoiDesMelangesEnSigma& loi) :
Loi_comp_abstraite(loi),type_grandeur(loi.type_grandeur),proportion(loi.proportion)
,lois_internes1(NULL),lois_internes2(NULL),calcule_si_prop_non_nulle(loi.calcule_si_prop_non_nulle)
,d_sigma_deps_inter(NULL),d_sigtotalHH()
,type_melange(loi.type_melange),valeur_aux_noeuds(loi.valeur_aux_noeuds)
,c_proport(loi.c_proport),aA(loi.aA)
,niveauF_grandeurND(loi.niveauF_grandeurND)
,niveauF_grandeurConsultable(NULL)
,niveauF_ddlEtendu(NULL),niveauF_temps(NULL)
{ lois_internes1 = loi.lois_internes1->Nouvelle_loi_identique();
lois_internes2 = loi.lois_internes2->Nouvelle_loi_identique();
// on regarde s'il s'agit d'une courbe locale ou d'une courbe globale
if (c_proport != NULL)
if (c_proport->NomCourbe() == "_")
{// comme il s'agit d'une courbe locale on la redéfinie (sinon pb lors du destructeur de loi)
string non_courbe("_");
c_proport = Courbe1D::New_Courbe1D(*loi.c_proport);
};
// traitement des pondérations
if (loi.niveauF_grandeurND != NULL)
if (loi.niveauF_grandeurND->NomFonction() == "_")
niveauF_grandeurND = Fonction_nD::New_Fonction_nD(*(loi.niveauF_grandeurND));
if (loi.niveauF_ddlEtendu != NULL)
niveauF_ddlEtendu = new Ponderation(*(loi.niveauF_ddlEtendu));
if (loi.niveauF_temps != NULL)
niveauF_temps = new Ponderation_temps(*(loi.niveauF_temps));;
if (loi.niveauF_grandeurConsultable != NULL)
niveauF_grandeurConsultable = new Ponderation_Consultable(*(loi.niveauF_grandeurConsultable));
};
LoiDesMelangesEnSigma::~LoiDesMelangesEnSigma ()
// Destructeur
{ if (lois_internes1 != NULL) delete lois_internes1;
if (lois_internes2 != NULL) delete lois_internes2;
if (d_sigma_deps_inter != NULL) delete d_sigma_deps_inter;
if (d_sigtotalHH.Taille() != 0)
{ int taille = d_sigtotalHH.Taille();
for (int i=1; i<= taille; i++)
if (d_sigtotalHH(i) != NULL) delete d_sigtotalHH(i);
};
if (c_proport != NULL)
if (c_proport->NomCourbe() == "_") delete c_proport;
// cas des pondérations
if (niveauF_grandeurND != NULL)
if (niveauF_grandeurND->NomFonction() == "_") delete niveauF_grandeurND;
if (niveauF_ddlEtendu != NULL)
delete niveauF_ddlEtendu;
if (niveauF_temps != NULL)
delete niveauF_temps;
if (niveauF_grandeurConsultable != NULL)
delete niveauF_grandeurConsultable;
};
// def d'une instance de données spécifiques, et initialisation
// valable une fois que les différentes lois internes sont définit
LoiDesMelangesEnSigma::SaveResul * LoiDesMelangesEnSigma::New_et_Initialise()
{ // on crée les différentes listes
list <SaveResul*> liste_des_SaveResul; // data pour chaque loi
list <TenseurHH* > l_sigoHH,l_sigoHH_t; // gestion des contraintes pour chaque loi
list <TenseurHH* > J_sigoHH,J_sigoHH_t; // gestion des contraintes pour chaque loi
list <EnergieMeca > l_energ,l_energ_t; // idem pour les énergies
list <TenseurHH* >::iterator isig,isig_t;
// on balaie les deux lois
{ SaveResul * nevez_save_result=NULL;
if (lois_internes1 != NULL) nevez_save_result = lois_internes1->New_et_Initialise();
liste_des_SaveResul.push_back(nevez_save_result);
// pour l'instant on définit des pointeurs de tenseurs qui ont la dimension de la loi,
// ensuite au moment de l'utilisation on les initialisera correctement si besoin
TenseurHH * interHH = NevezTenseurHH(dim,0.);l_sigoHH.push_back(interHH);
TenseurHH * interHH_t = NevezTenseurHH(dim,0.);l_sigoHH_t.push_back(interHH_t);
TenseurHH * jnterHH = NevezTenseurHH(dim,0.);J_sigoHH.push_back(jnterHH);
TenseurHH * jnterHH_t = NevezTenseurHH(dim,0.);J_sigoHH_t.push_back(jnterHH_t);
// on définit les conteneurs pour les énergies
l_energ.push_back(EnergieMeca());l_energ_t.push_back(EnergieMeca());
}
{ SaveResul * nevez_save_result=NULL;
if (lois_internes2 != NULL) nevez_save_result = lois_internes2->New_et_Initialise();
liste_des_SaveResul.push_back(nevez_save_result);
// pour l'instant on définit des pointeurs de tenseurs qui ont la dimension de la loi,
// ensuite au moment de l'utilisation on les initialisera correctement si besoin
TenseurHH * interHH = NevezTenseurHH(dim,0.);l_sigoHH.push_back(interHH);
TenseurHH * interHH_t = NevezTenseurHH(dim,0.);l_sigoHH_t.push_back(interHH_t);
TenseurHH * jnterHH = NevezTenseurHH(dim,0.);J_sigoHH.push_back(jnterHH);
TenseurHH * jnterHH_t = NevezTenseurHH(dim,0.);J_sigoHH_t.push_back(jnterHH_t);
// on définit les conteneurs pour les énergies
l_energ.push_back(EnergieMeca());l_energ_t.push_back(EnergieMeca());
}
// on regarde le type de progressivité de la proportion éventuelle
int type_evol_proportion = 0; // init par défaut
if (calcule_si_prop_non_nulle.Taille() == 2)
{if ((calcule_si_prop_non_nulle(1) == 2) || (calcule_si_prop_non_nulle(2) == 2))
type_evol_proportion = 1;
else if ((calcule_si_prop_non_nulle(1) == 3) || (calcule_si_prop_non_nulle(2) == 3))
type_evol_proportion = 2;
};
// on ramène la bonne instance
LoiDesMelangesEnSigma::SaveResul * retour = new SaveResul_LoiDesMelangesEnSigma
(liste_des_SaveResul,l_sigoHH,l_sigoHH_t
,J_sigoHH,J_sigoHH_t,l_energ,l_energ_t,type_evol_proportion);
// on supprime les grandeurs locales qui ont été crées par des new
list <SaveResul*>::iterator ils, ilsfin= liste_des_SaveResul.end();
list <TenseurHH* >::iterator isib = l_sigoHH.begin();
list <TenseurHH* >::iterator isib_t = l_sigoHH_t.begin();
list <TenseurHH* >::iterator jsib = J_sigoHH.begin();
list <TenseurHH* >::iterator jsib_t = J_sigoHH_t.begin();
for (ils=liste_des_SaveResul.begin();ils!=ilsfin;ils++,isib++,isib_t++,jsib++,jsib_t++)
{ if ((*ils) != NULL) delete (*ils);
if ((*isib) != NULL) delete (*isib);
if ((*isib_t) != NULL) delete (*isib_t);
if ((*jsib) != NULL) delete (*jsib);
if ((*jsib_t) != NULL) delete (*jsib_t);
};
// retour
return retour;
};
// Lecture des donnees de la classe sur fichier
void LoiDesMelangesEnSigma::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D
,LesFonctions_nD& lesFonctionsnD)
{ // lecture jusque l'on trouve le mot clé signalant la fin de la liste des loi élémentaires
bool premier_lecture = true;
// on lit tout d'abord la grandeur qui servira a établir la proportion entre la première loi et la
// seconde
string nom; *(entreePrinc->entree) >> nom;
bool passer_une_ligne = true;
// choix entre grandeur_proportion= et les_grandeurs_de_controle_=
if ((nom != "grandeur_proportion=") && (nom != "les_grandeurs_de_controle_="))
{ cout << "\n erreur en lecture de la loi des melanges en sigma,"
<< " on attendait le mot cle grandeur_proportion= "
<< " et un identificateur de grandeur, ou les_grandeurs_de_controle_= "
<< " alors que l'on a lue: " << nom;
entreePrinc->MessageBuffer("**erreur1 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
if (nom == "grandeur_proportion=")
{ *(entreePrinc->entree) >> type_grandeur; // lecture du type enumere de la grandeur
// on regarde s'il faut lire le type de mélange
if (strstr(entreePrinc->tablcar,"type_melange=")!=NULL)
{ *(entreePrinc->entree) >> nom;
if (nom != "type_melange=")
{ cout << "\n erreur en lecture de la loi des melanges en sigma, on attendait le mot cle type_melange="
<< " alors que l'on a lue " << nom;
entreePrinc->MessageBuffer("**erreur11 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
*(entreePrinc->entree) >> type_melange;
if ((type_melange!= 1) && (type_melange != 2))
{ cout << "\n erreur en lecture du type de melange , il doit etre egale a 1 ou 2 alors que l'on a lu "
<< type_melange;
entreePrinc->MessageBuffer("**erreur12 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
}
else
{ type_melange = 1.;};
// on regarde s'il faut lire l'indicateur "valeur_aux_noeuds"
if (strstr(entreePrinc->tablcar,"valeur_aux_noeuds=")!=NULL)
{ *(entreePrinc->entree) >> nom;
if (nom != "valeur_aux_noeuds=")
{ cout << "\n erreur en lecture de la loi des melanges en sigma,"
<< " on attendait le mot cle valeur_aux_noeuds="
<< " alors que l'on a lue " << nom;
entreePrinc->MessageBuffer("**erreur13 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
*(entreePrinc->entree) >> valeur_aux_noeuds;
}
else
{ valeur_aux_noeuds = 1;};
// **** pour l'instant on ne considère que des grandeurs ddl aux noeuds, mais cela peut-être étendu sans pb
if (valeur_aux_noeuds && (!type_grandeur.Nom_vide()))
{ cout << "\n erreur en lecture de la loi des melanges en sigma, dans le cas d'une proportion en fonction"
<< " de grandeur aux noeuds pour l'instant seul les ddl de base sont autorises " ;
entreePrinc->MessageBuffer("**erreur14 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// --- on regarde le cas d'une somme étendue
aA=1.; //par défaut
if (strstr(entreePrinc->tablcar,"somme_pondere_etendue_")!=NULL)
{string nom;
*(entreePrinc->entree) >> nom; // lecture d'un identificateur
if(nom != "somme_pondere_etendue_")
{ cout << "\n erreur en lecture du mot cle somme_pondere_etendue_ "
<< " on attendait la chaine : somme_pondere_etendue_ et on a lue " << nom;
entreePrinc->MessageBuffer("**erreur15 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
entreePrinc->NouvelleDonnee(); // on passe une ligne
*(entreePrinc->entree) >> nom; // lecture de aA
if(nom != "A=")
{ cout << "\n erreur en lecture du mot cle A= "
<< " on attendait la chaine : A= et on a lue " << nom;
entreePrinc->MessageBuffer("**erreur16 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
*(entreePrinc->entree) >> aA;
};
// --- on regarde s'il y a une fonction d'interface
if (strstr(entreePrinc->tablcar,"avec_fonction_proportion_")!=NULL)
{string nom;
*(entreePrinc->entree) >> nom; // lecture d'un identificateur
if(nom != "avec_fonction_proportion_")
{ cout << "\n erreur en lecture du mot cle avec_fonction_proportion_ "
<< " on attendait la chaine : avec_fonction_proportion_ et on a lue " << nom;
entreePrinc->MessageBuffer("**erreur17 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
entreePrinc->NouvelleDonnee(); // on passe une ligne
*(entreePrinc->entree) >> nom; // lecture du mot cle
if(nom != "fonction_prop=")
{ cout << "\n erreur en lecture du mot cle fonction_prop= "
<< " on attendait la chaine : fonction_prop= et on a lue " << nom;
entreePrinc->MessageBuffer("**erreur18 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
*(entreePrinc->entree) >> nom; // lecture de l'identificateur de la courbe
// on regarde si la courbe existe, si oui on récupère la référence
if (lesCourbes1D.Existe(nom))
{ c_proport = lesCourbes1D.Trouve(nom);
}
else
{ // sinon il faut la lire maintenant
string non_courbe("_");
c_proport = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
// lecture de la courbe
c_proport->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
};
};
}
else if (nom == "les_grandeurs_de_controle_=")
{ Ponderation ponder; // un élément courant
// on initialise
string mot_cle, st1,st2;
string nom_class_methode="LoiDesMelangesEnSigma::LectureDonneesParticulieres (.";
List_io < Ddl_enum_etendu > listddlenum;
List_io <bool> listbool;
// on lit les grandeurs pour l'instant en string
List_io <string> list_id_grand; //liste de travail de toutes les grandeurs
List_io <string> list_id_grand_glob; //liste des grandeurs globales
List_io <string> list_id_ddl_etendu; //liste des ddl étendus
int nb_grandeurs_globales = 0; // init
while (st1 != "fin_grandeurs_")
{*(entreePrinc->entree) >> st1 ;
if (st1 == "fin_grandeurs_") break; // pas terrible mais c'est ce qui me vient à l'idée !
// on vérifie que le mot clé lu est exploitable
string minus = Minuscules(st1); // la forme minuscules
if ((st1=="TEMPS") || (Ddl_enum_etendu::VerifExistence(st1))
|| EstUneGrandeurGlobale(minus)
)
{list_id_grand.push_back(st1);
if (EstUneGrandeurGlobale(minus)) // si c'est une grandeur globale on cumule le compteur
nb_grandeurs_globales++;
}
else
{ cout << "\n erreur en lecture, le type de grandeur lu" << st1
<< " n'est pas acceptable "
<< "\n LoiDesMelangesEnSigma::LectureDonneesParticulieres (...";
entreePrinc->MessageBuffer("**erreur05**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// on rempli les listes spécifiques
if (Ddl_enum_etendu::VerifExistence(st1))
list_id_ddl_etendu.push_back(st1);
if (EstUneGrandeurGlobale(minus))
list_id_grand_glob.push_back(st1);
};
// --- maintenant on va lire les fonctions
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
mot_cle="deb_fonct_="; // le début des fonctions
entreePrinc->Lecture_et_verif_mot_cle(nom_class_methode,mot_cle);
List_io <string>::iterator ili,ilifin = list_id_grand.end();
List_io <Courbe1D*> li_courbe_globale; // inter
List_io <bool> val_aux_noeuds; // inter
int nb_GGlob=0;int nb_enum_etendu = 0; // compteur pour le dimensionnement
// premier passage on crée les fonctions
for (ili=list_id_grand.begin();ili != ilifin;ili++)
{string minus = Minuscules(*ili); // la forme minuscules
if ((*ili)=="TEMPS") // cas de la fonction du temps
{ // lecture de la loi d'évolution
val_aux_noeuds.push_back(false); // sert à rien, mais permet
// de garder le même ordre de rangement que list_id_grand
if (niveauF_temps == NULL)
niveauF_temps = new Ponderation_temps;
// lecture de la pondération
niveauF_temps->LectureDonneesPonderation(entreePrinc, lesCourbes1D);
}
else if (EstUneGrandeurGlobale(minus))
{ val_aux_noeuds.push_back(false); // sert à rien, mais permet
nb_GGlob++; // de garder le même ordre de rangement que list_id_grand
// pour le premier élément de la liste on lit la fonction
// pour les autres, on ne fait rien (la fct est déjà lue)
if (nb_GGlob == 1)
{// création de la pondération si nécessaire
string nom_fonction;
// lecture du nom de la fonction nD
*(entreePrinc->entree) >> nom_fonction;
// on regarde si la fonction existe, si oui on récupère la référence
if (lesFonctionsnD.Existe(nom_fonction))
{ niveauF_grandeurND = lesFonctionsnD.Trouve(nom_fonction);
}
else
{ // sinon il faut la lire maintenant
string non_fonction("_");
niveauF_grandeurND = Fonction_nD::New_Fonction_nD(non_fonction,Id_Nom_Fonction_nD (non_fonction.c_str()));
// lecture de la fonction
niveauF_grandeurND->LectDonnParticulieres_Fonction_nD (non_fonction,entreePrinc);
};
};
}
else if (Ddl_enum_etendu::VerifExistence(*ili))
{ nb_enum_etendu++;
// pour le premier élément de la liste on lit la pondération
// pour les autres, on ne fait rien (la pondération est déjà lue)
if (nb_enum_etendu == 1)
{ if (niveauF_ddlEtendu==NULL) // on le crée
niveauF_ddlEtendu = new Ponderation;
// lecture
niveauF_ddlEtendu->LectureDonneesPonderation
(list_id_ddl_etendu,entreePrinc,lesCourbes1D);
};
};
};
// on passe le mot clé de fin
mot_cle="fin_fonct_"; // la fin des fonctions
entreePrinc->Lecture_et_verif_mot_cle(nom_class_methode,mot_cle);
// *** à changer en fonction de l'utilisation
// deuxième passage on met à jour les conteneurs
// niveauF_grandeurND->type_grandeur_GGlob.Change_taille(nb_GGlob);
// niveauF_grandeurND->c_proport.Change_taille(nb_GGlob);
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
passer_une_ligne = false;
// on regarde s'il faut lire le type de mélange
if (strstr(entreePrinc->tablcar,"type_melange=")!=NULL)
{ *(entreePrinc->entree) >> nom;
if (nom != "type_melange=")
{ cout << "\n erreur en lecture de la loi des melanges en sigma, on attendait le mot cle type_melange="
<< " alors que l'on a lue " << nom;
entreePrinc->MessageBuffer("**erreur11 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
*(entreePrinc->entree) >> type_melange;
if ((type_melange!= 1) && (type_melange != 2))
{ cout << "\n erreur en lecture du type de melange , il doit etre egale a 1 ou 2 alors que l'on a lu "
<< type_melange;
entreePrinc->MessageBuffer("**erreur12 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
// on ajoute 2 au type de mélange car ce sera l'indicateur qui permettra de savoir si on est
// dans la mise en donnée historique ou la nouvelle mise en donnée
type_melange += 2;
}
else
{ type_melange = 3;};
};
// maintenant lecture des 2 lois
if (passer_une_ligne)
entreePrinc->NouvelleDonnee();
calcule_si_prop_non_nulle.Change_taille(0); // init au cas où
int dim_lois=0; int nb_loi = 0;Enum_categorie_loi_comp categ=RIEN_CATEGORIE_LOI_COMP;
while (strstr(entreePrinc->tablcar,"fin_liste_lois_elementaires")==NULL)
{ // lecture du nom de la loi
string st2,nom3;
*(entreePrinc->entree) >> st2;
// on regarde si on est dans le cas d'une proportion exclusive (cf. info_commande_LoisDeComp)
if ( (strstr(entreePrinc->tablcar,"calcule_si_prop_non_nulle_")!=NULL)
|| (strstr(entreePrinc->tablcar,"demarre_a_prop_non_nulle_puis_strictement_decroissante_")!=NULL)
|| (strstr(entreePrinc->tablcar,"demarre_a_prop_non_nulle_puis_strictement_decroissante_sur_chaque_incre_")!=NULL))
{ *(entreePrinc->entree) >> nom3;
if (calcule_si_prop_non_nulle.Taille() == 0)
calcule_si_prop_non_nulle.Change_taille(2,0);
if(nom3 == "calcule_si_prop_non_nulle_")
{calcule_si_prop_non_nulle(nb_loi+1)=1;}
else if(nom3 == "demarre_a_prop_non_nulle_puis_strictement_decroissante_") // sinon cas demarre_a_prop_non_nulle_puis_strictement_decroissante_
{calcule_si_prop_non_nulle(nb_loi+1)=2;}
else if(nom3 == "demarre_a_prop_non_nulle_puis_strictement_decroissante_sur_chaque_incre_") // sinon cas idem prec mais
// sur chaque incrément
{calcule_si_prop_non_nulle(nb_loi+1)=3;}
else
{ cout << "\n erreur en lecture des lois constitutives elementaire d'une loi LoiDesMelangesEnSigma"
<< "\n le mot cle lue: " << nom3
<< " devrait etre soit calcule_si_prop_non_nulle_ ou soit demarre_a_prop_non_nulle_puis_strictement_decroissante_ ";
entreePrinc->MessageBuffer("**erreur LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
};
// definition de la loi
LoiAbstraiteGeneral * pt = LesLoisDeComp::Def_loi(st2);
if (nb_loi==0) // la première fois que l'on passe ici le nombre de loi = 0
{lois_internes1 = (Loi_comp_abstraite*) LesLoisDeComp::Def_loi(st2);
pt = lois_internes1;}
else
{lois_internes2 = (Loi_comp_abstraite*) LesLoisDeComp::Def_loi(st2);
pt = lois_internes2;}
// --- lecture des informations particulières propres à la loi
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
pt->LectureDonneesParticulieres (entreePrinc,lesCourbes1D,lesFonctionsnD);
// ---- dans le cas de la première loi on enregistre la dimension ----
// on s'occupe de la catégorie et de la dimension de la loi, après la lecture des informations particulières
// pour le cas où ce serait une loi additive, car dans ce dernier cas, c'est après la lecture que l'on peut
// définir la catégorie dans le cas de la première loi on enregistre la dimension
if (premier_lecture)
{ premier_lecture=false;
dim_lois=pt->Dimension_loi();categ = pt->Id_categorie();
// on met à jour la dimension
dim = dim_lois;categorie_loi_comp = categ;
if (!GroupeMecanique(categorie_loi_comp))
{ cout << "\n erreur1 en lecture des lois constitutives elementaire d'une loi LoiDesMelangesEnSigma"
<< "\n la loi lue: " << pt->Nom_comport() << " n'est pas une loi mecanique, elle fait partie "
<< " de la categorie: "<< Nom_categorie_loi_comp(categorie_loi_comp);
entreePrinc->MessageBuffer("**erreur LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
}
else // sinon on vérifie que les lois ont la bonne dimension et la bonne catégorie
{ if (pt->Dimension_loi() != dim_lois)
{ cout << "\n erreur en lecture des lois constitutives elementaire d'une LoiDesMelangesEnSigma"
<< "\n la loi lue: " << pt->Nom_comport() << " n'a pas la meme dimension que la premier loi lue";
entreePrinc->MessageBuffer("**erreur2 lecture LoiDesMelangesEnSigma");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
if (!GroupeMecanique(pt->Id_categorie()))
{ cout << "\n erreur en lecture des lois constitutives elementaire d'une loi LoiDesMelangesEnSigma"
<< "\n la loi lue: " << pt->Nom_comport() << " n'est pas une loi mecanique, elle fait partie "
<< " de la categorie: "<< Nom_categorie_loi_comp(categorie_loi_comp);
entreePrinc->MessageBuffer("**erreur2 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// on enregistre la catégorie la plus complète
categorie_loi_comp = Categorie_loi_comp_la_plus_complete(categorie_loi_comp,pt->Id_categorie());
};
// si la loi est thermo dépendante on indique que la loi additive l'est aussi
if (((Loi_comp_abstraite*)pt)->ThermoDependante()) this->thermo_dependant = true;
nb_loi++;
if (nb_loi > 2 )
{ cout << "\n erreur en lecture de la loi des melanges en sigma,"
<< " vous avez defini plus de deux lois internes !";
entreePrinc->MessageBuffer("**erreur3 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
};
// vérification que l'on a bien lu deux lois
if (nb_loi != 2 )
{ cout << "\n erreur en lecture de la loi des melanges en sigma,"
<< " vous n'avez pas defini deux lois internes !";
entreePrinc->MessageBuffer("**erreur4 LoiDesMelangesEnSigma::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// appel au niveau de la classe mère, avec preparation du flot de lecture
Loi_comp_abstraite::Lecture_type_deformation_et_niveau_commentaire
(*entreePrinc,lesFonctionsnD,true);
};
// affichage de la loi
void LoiDesMelangesEnSigma::Affiche() const
{ cout << "\n ....... loi de comportement LoiDesMelangesEnSigma ........";
cout << "\n type de melange: "<<type_melange << " ";
cout << "\n grandeur utiliser pour controler le melange: " ;
if (type_melange < 3) // mise en donnée historique
{ if (type_grandeur.Nom_vide()) {cout << Nom_ddl(type_grandeur.Enum()) << " ";}
else {cout << type_grandeur.Nom() << " ";};
if (valeur_aux_noeuds)
{ cout << " , venant des noeuds par interpolation ";}
else
{ cout << " , venant directement du point d'integration ";};
// extension éventuelle
if (aA != 1.)
cout << " cas d'une somme ponderee etendue A= " << aA ;
// courbe d'interface
if ( c_proport != NULL) { cout << " courbe d'interface "
<< " courbe c_proport=f(): " << c_proport->NomCourbe() <<" ";};
cout << " \n ";
}
else // deuxième mise en donnée
{ cout << "niveauF_grandeurND" << " ";
if (niveauF_grandeurND->NomFonction() != "_")
{ cout << niveauF_grandeurND->NomFonction();}
else
{ niveauF_grandeurND->Affiche();};
if (niveauF_ddlEtendu!= NULL)
niveauF_ddlEtendu->Affiche();
if (niveauF_temps!= NULL)
niveauF_temps->Affiche();
};
if (calcule_si_prop_non_nulle.Taille() == 2)
{ cout << " calcule_si_prop_non_nulle1= " << calcule_si_prop_non_nulle(1)
<< " calcule_si_prop_non_nulle2= " << calcule_si_prop_non_nulle(2) << " \n";
};
cout << "\n -- partie relative aux lois internes: ";
lois_internes1->Affiche();
lois_internes2->Affiche();
cout << "\n ....... fin de la loi de comportement LoiDesMelangesEnSigma ........";
};
// affichage et definition interactive des commandes particulières à chaques lois
void LoiDesMelangesEnSigma::Info_commande_LoisDeComp(UtilLecture& entreePrinc)
{ ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier
cout << "\n definition standart (rep o) ou exemples exhaustifs (rep n'importe quoi) ? ";
string rep = "_";
// procédure de lecture avec prise en charge d'un retour chariot
rep = lect_return_defaut(true,"o");
sort << "\n# ....... loi de comportement LoiDesMelangesEnSigma ........"
<< "\n# deux types de mises en donnees sont proposees "
<< "\n# ";
if (rep == "o")
{//--------- cas de la première mise en donnée (historique) -------
{
sort << "\n# "
<< "\n# $$$ === premier type possible de mise en donnees ===$$$ "
<< "\n# "
<< "\n# sur la premiere ligne on indique successivement : "
<< "\n# a) obligatoirement: le type de grandeur (mot cle: grandeur_proportion= ) qui regle la proportion entre "
<< "\n# les deux lois, on peut utiliser n'importe quelle grandeur definie (mais qui doit exister par ailleurs) "
<< "\n# aux noeuds par exemple, cf. documentation "
<< "\n# b) optionnellement: le type de melange (mot cle: type_melange= ) (1 ou 2) cf. expli qui suit "
<< "\n# c) optionnellement: si la proportion provient des noeuds ou du pt d'integ directement "
<< "\n# (mot cle: valeur_aux_noeuds= ) (1 ou 0) la valeur par defaut est 1 (en fait tout nb diff de 0), "
<< "\n# dans le cas de 0, pour l'instant les cas implantes sont relatif a PROP_CRISTA, def_duale_mises, "
<< "\n# Spherique_eps, def_duale_mises_maxi, Spherique_sig"
<< "\n# --> ex: grandeur_proportion= PROP_CRISTA type_melange= 2 valeur_aux_noeuds= 0 "
<< "\n# d) optionnellement: l'extension a une somme ponderee etendue mot cle: somme_pondere_etendue_ "
<< "\n# si oui, on passe une ligne et sur la ligne suivante on a le mot cle A= "
<< "\n# suivit du coeff multiplicatif de la somme ponderee (cf explication qui suit) "
<< "\n# "
<< "\n# e) optionnellement: une fonction permettant le calcul de la proportion en fonction de la grandeur"
<< "\n# qui regle la proportion mot cle: avec_fonction_proportion_ "
<< "\n# dans ce cas, on passe une ligne et la fonction est decrite avec le mot cle: fonction_prop= "
<< "\n# suivit du nom de la fonction (si elle existe deja) ou de la definition de la fonction "
<< "\n# "
<< "\n# f) puis on passe une ligne pour decrire les 2 lois individuelles"
<< "\n# "
<< "\n# ---- explications complementaires ------ "
<< "\n# en fait il y a deux type de loi des melanges possible: "
<< "\n# soit : sigma = grandeur * sigma(loi1) + (1.-grandeur) * sigma(loi2) , ce qui est le type 1 (par defaut) "
<< "\n# soit : delta sigma = grandeur * delta sigma(loi1) + (1.-grandeur) * delta sigma(loi2) , ce qui est le type 2"
<< "\n# en tenant compte que les contraintes sont cumulees dans le type 2. "
<< "\n# le type 1 est par defaut, mais on peut indiquer le type 2 apres le mot cle type_melange= "
<< "\n# puis il faut donner le nom de chaque loi (2 maxi) suivi des parametres sur les lignes suivantes"
<< "\n# "
<< "\n# Dans le cas d'une somme ponderee etendue, la contrainte est calculee suivant la formule suivante: "
<< "\n# sigma = A*(grandeur * sigma(loi1) + (1-grandeur) * sigma(loi2)) "
<< "\n# ou : delta sigma = A*(grandeur * delta sigma(loi1) + (1-grandeur) * delta sigma(loi2)) "
<< "\n# ainsi A peut etre different de 1, par exemple si A=2, on peut tendre vers la somme non ponderee des deux lois "
<< "\n# "
<< "\n# ------------ cas d'une proportion exclusive --------------- "
<< "\n# g) optionnellement: apres chaque loi, on peut indiquer le mot cle: calcule_si_prop_non_nulle_ "
<< "\n# cela indique que la loi n'est calculee que si son coefficient est non nul, "
<< "\n# bien noter que dans ce cas il n'y a pas accumulation de l'historique du comportement "
<< "\n# donc c'est une option qui est raisonnable que pour une loi non incrementale"
<< "\n# dans le cas contraire, il faut avoir conscience de ce que l'on impose"
<< "\n# "
<< "\n# ----- exemple de deux lois elastiques -----"
<< "\n# "
<< "\n grandeur_proportion= PROP_CRISTA type_melange= 2 valeur_aux_noeuds= 1 ";
// definition de la loi
string internom("ISOELAS");
LoiAbstraiteGeneral * pt = LesLoisDeComp::Def_loi(internom);
sort << "\n ISOELAS # premiere loi isoelas 3D";
pt->Info_commande_LoisDeComp(entreePrinc);
sort << "\n ISOELAS # seconde loi isoelas 3D";
pt->Info_commande_LoisDeComp(entreePrinc);
sort << "\n fin_liste_lois_elementaires # ----- fin de LoiDesMelangesEnSigma" << endl;
sort << "\n# "
<< "\n# ------ exemple d'une somme etendue avec fonction d'interface (partie avant les lois) ------"
<< "\n# "
<< "\n# grandeur_proportion= def_equivalente type_melange= 1 valeur_aux_noeuds= 0 somme_pondere_etendue_ "
<< "\n# A= 2. avec_fonction_proportion_ "
<< "\n# fonction_prop= courbe1 "
<< "\n# ..... "
<< "\n# ";
};
//--------- cas de la deuxième mise en donnée -------
{
sort << "\n# "
<< "\n# $$$ === second type possible de mise en donnees ===$$$ "
<< "\n# "
<< "\n# ce second type permet d'utiliser un plus large choix de fonctions de ponderation, par contre"
<< "\n# son utilisation est peut-etre un peu plus complexe (?) "
<< "\n# Plus precisemment, la ponderation peut-etre un assemblage multiplicatif de: "
<< "\n# - une fonction nD de grandeurs globales (ex: precision d'equilibre globale, num d'iteration, etc.)"
<< "\n# - avec le produit d'un ensemble de courbes 1D , chacune fonction d'un ddl etendu. Ici c'est le cas "
<< "\n# identique au premier type de mise en donnees"
<< "\n# - avec le produit d'une courbe 1D fonction du temps"
<< "\n# "
<< "\n# sur la premiere ligne on indique successivement : "
<< "\n# a) le mot cle: les_grandeurs_de_controle_= "
<< "\n# b) ensuite on donne la liste des grandeurs que l'on va utiliser, ces grandeurs peuvent etre"
<< "\n# - le temps (mot cle: TEMPS ) "
<< "\n# - un ddl primaire (ex: U1 ou X1 au noeud) ou secondaire (SIG11 ou EPS11 au pti)"
<< "\n# - un ddl etendue "
<< "\n# - une grandeur globale"
<< "\n# l'ensemble des grandeurs doit se terminer par le mot cle : fin_grandeurs_"
<< "\n# c) ensuite sur la ligne suivante: on donne la liste des fonctions que l'on va utiliser "
<< "\n# - mot cle deb_fonct_= "
<< "\n# la liste doit suivre le meme ordre que celui des grandeurs, cependant "
<< "\n# 1) dans le cas des grandeurs globales (sauf le temps), il y a une seule fonction pour toutes les grandeurs"
<< "\n# c'est donc la place de la premiere grandeur globale qui est consideree "
<< "\n# IMPORTANT: les grandeurs globales qui vont etre utilisees sont celles indiquees dans la definition"
<< "\n# de la fonction nD, aussi dans la def de la proportion, il suffit d'indiquer une seule grandeur "
<< "\n# globale pour ensuite definir une fonction nD. Par contre dans la definition de la fonction nD "
<< "\n# on peut introduire d'autres grandeurs, en particulier des grandeurs non locales. "
<< "\n# La fonction nD permet donc d'introduire tout type de grandeur, elle fait donc"
<< "\n# double emploi avec les autres courbes. Cependant on laisse les autres courbes "
<< "\n# pour des raisons historiques et pour des cas simples, on l'utilisation d'une courbe "
<< "\n# peut-etre plus explicite qu'une fonction nD. "
<< "\n# 2) pour les ddl et ddl etendue il faut indiquer apres chaque fonction d'un ddl s'il s'agit "
<< "\n# a) d'une grandeur au pti avec le mot cle AuPti_ "
<< "\n# b) d'une grandeur au noeud avec le mot cle AuxNoeuds_ "
<< "\n# l'ensemble de la liste des fonctions doit se terminer par le mot cle: fin_fonct_ "
<< "\n# e) puis sur la ligne suivante, optionnellement: "
<< "\n# le type de melange (mot cle: type_melange= ) (1 ou 2) "
<< "\n# l'explication est identique au cas de la premiere mise en donnees "
<< "\n# "
<< "\n# f) puis on passe une ligne pour decrire les 2 lois individuelles"
<< "\n# On peut comme dans le cas de la premiere mise en donnee, utiliser"
<< "\n# une proportion exclusive, la syntaxe est identique au cas de la premiere "
<< "\n# mise en donnee "
<< "\n# "
<< "\n# ----- exemple de deux lois elastiques -----"
<< "\n# "
<< "\n# les_grandeurs_de_controle_= TEMPS \\ "
<< "\n# compteur_increment_charge_algo_global\\ "
<< "\n# compteur_iteration_algo_global\\ "
<< "\n# def_equivalente X1 \\ "
<< "\n# fin_grandeurs_ "
<< "\n# deb_fonct_= f_temps fonction1 \\ "
<< "\n# f_const AuPti_ \\ "
<< "\n# f_const AuxNoeuds_ \\ "
<< "\n# fin_fonct_ ";
// definition de la loi
string internom("ISOELAS");
LoiAbstraiteGeneral * pt = LesLoisDeComp::Def_loi(internom);
sort << "\n ISOELAS # premiere loi isoelas 3D";
pt->Info_commande_LoisDeComp(entreePrinc);
sort << "\n ISOELAS # seconde loi isoelas 3D";
pt->Info_commande_LoisDeComp(entreePrinc);
sort << "\n fin_liste_lois_elementaires # ----- fin de LoiDesMelangesEnSigma" << endl;
sort << "\n# ";
sort << "\n#a la suite du mot cle qui definit une loi interne on peut choisir entre 4 "
<< "types de fonctionnement. Pour simplifier et expliciter la presentation,"
<< " on suppose que la premiere loi est une simple loi de Hooke. Les 4 types"
<< " de fonctionnement sont alors les suivants:"
<< "\n# ISOELAS -> aucune particularite ,"
<< "\n# ISOELAS calcule_si_prop_non_nulle_ -> le mot cle est utilise"
<< " pour indiquer que la loi ne doit-être calculee que si la proportion"
<< " la concernant (c-a-c alpha pour la première loi, et (1.-alpha) pour "
<< " la seconde loi) est non nulle. Si elle est nulle, la loi n'est pas calculee."
<< "\n# ISOELAS demarre_a_prop_non_nulle_puis_strictement_decroissante_} "
<< " -> le fonctionnement est semblable au cas precedent avec en plus la "
<< " particularite supplementaire suivante: on interdit a la proportion d'augmenter."
<< " Ainsi, si entre deux appels consecutifs de la loi de comportement, la valeur d'alpha"
<< " tente d'augmente au travers d'un calcul via une fonction de ponderation,"
<< " c'est la valeur la plus faible qui est retenue, et ceci tout au long du calcul. "
<< " Ce comportement tres particulier, est construit en particulier pour être utilise"
<< " via une fonction de ponderation qui depend de la precision de l'equilibre globale."
<< " On force ainsi l'evolution d'alpha a etre strictement decroissante a mesure "
<< " que la precision augmente."
<< "\n# ISOELAS demarre_a_prop_non_nulle_puis_strictement_decroissante_sur_chaque_incre_"
<< " -> le fonctionnement est un peu semblable au cas precedent mais avec la particularite"
<< " supplementaire suivante: l'evolution est strictement decroissante sur un increment."
<< " Par contre au debut de chaque increment, on initialise la valeur d'alpha"
<< " via les fonctions de proportion."
<< endl;
};
}
else // cas simplifié, on ne donne que les exemples
{//--------- cas de la première mise en donnée (historique) -------
{
sort << "\n# "
<< "\n# $$$ === premier type possible de mise en donnees ===$$$ "
<< "\n# "
<< "\n# ----- exemple de deux lois elastiques -----"
<< "\n# "
<< "\n grandeur_proportion= PROP_CRISTA type_melange= 2 valeur_aux_noeuds= 1 ";
// definition de la loi
string internom("ISOELAS");
LoiAbstraiteGeneral * pt = LesLoisDeComp::Def_loi(internom);
sort << "\n ISOELAS # premiere loi isoelas 3D";
pt->Info_commande_LoisDeComp(entreePrinc);
sort << "\n ISOELAS # seconde loi isoelas 3D";
pt->Info_commande_LoisDeComp(entreePrinc);
sort << "\n fin_liste_lois_elementaires # ----- fin de LoiDesMelangesEnSigma" << endl;
};
//--------- cas de la deuxième mise en donnée -------
{
sort << "\n# "
<< "\n# $$$ === second type possible de mise en donnees ===$$$ "
<< "\n# "
<< "\n# ----- exemple de deux lois elastiques -----"
<< "\n# "
<< "\n# les_grandeurs_de_controle_= TEMPS \\ "
<< "\n# compteur_increment_charge_algo_global\\ "
<< "\n# compteur_iteration_algo_global\\ "
<< "\n# def_equivalente X1 \\ "
<< "\n# fin_grandeurs_ "
<< "\n# deb_fonct_= f_temps fonction1 \\ "
<< "\n# f_const AuPti_ \\ "
<< "\n# f_const AuxNoeuds_ \\ "
<< "\n# fin_fonct_ ";
// definition de la loi
string internom("ISOELAS");
LoiAbstraiteGeneral * pt = LesLoisDeComp::Def_loi(internom);
sort << "\n ISOELAS # premiere loi isoelas 3D";
pt->Info_commande_LoisDeComp(entreePrinc);
sort << "\n ISOELAS # seconde loi isoelas 3D";
pt->Info_commande_LoisDeComp(entreePrinc);
sort << "\n fin_liste_lois_elementaires # ----- fin de LoiDesMelangesEnSigma" << endl;
};
}
};
// test si la loi est complete
int LoiDesMelangesEnSigma::TestComplet()
{ int ret = LoiAbstraiteGeneral::TestComplet();
ret *=lois_internes1->TestComplet();
ret *=lois_internes2->TestComplet();
// puis les proportions
if (type_melange < 3) // mise en donnée historique
{ // courbe d'interface
if ( c_proport != NULL)
c_proport->Complet_courbe();
}
else // deuxième mise en donnée
{ //if (niveauF_grandeurND != NULL)
// niveauF_grandeurND->Verif_complet();
if (niveauF_ddlEtendu!= NULL)
niveauF_ddlEtendu->Verif_complet();
if (niveauF_temps!= NULL)
niveauF_temps->Verif_complet();
};
return ret;
};
// calcul d'un module d'young équivalent à la loi, ceci pour un
// chargement nul
double LoiDesMelangesEnSigma::Module_young_equivalent(Enum_dure temps,const Deformation & def ,SaveResul * saveResul_ex)
{ double E=0.;
// on récupère les infos de chaque loi
SaveResul_LoiDesMelangesEnSigma & save_resul = *((SaveResul_LoiDesMelangesEnSigma*) saveResul_ex);
list <SaveResul*>::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois
// on utilise les proportions sauvegardées qui peuvent éventuellement ne pas avoir été déjà calculées
// dans ce cas la proportion = 1
E +=save_resul.proportion * lois_internes1->Module_young_equivalent(temps,def,*isave);
isave++;
E +=(1.-save_resul.proportion) * lois_internes2->Module_young_equivalent(temps,def,*isave);
return E;
};
// récupération d'un module de compressibilité équivalent à la loi, ceci pour un chargement nul
// il s'agit ici de la relation -pression = sigma_trace/3. = module de compressibilité * I_eps
double LoiDesMelangesEnSigma::Module_compressibilite_equivalent(Enum_dure temps,const Deformation & def ,SaveResul * saveResul_ex)
{ double module_compressibilite=0.;
// on récupère les infos de chaque loi
SaveResul_LoiDesMelangesEnSigma & save_resul = *((SaveResul_LoiDesMelangesEnSigma*) saveResul_ex);
list <SaveResul*>::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois
// on utilise les proportions sauvegardées qui peuvent éventuellement ne pas avoir été déjà calculées
// dans ce cas la proportion = 1
module_compressibilite +=save_resul.proportion * lois_internes1->Module_compressibilite_equivalent(temps,def,*isave);
isave++;
module_compressibilite +=(1.-save_resul.proportion) * lois_internes2->Module_compressibilite_equivalent(temps,def,*isave);
return module_compressibilite;
};
// 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
// ici la grandeur qui sert de proportion entre la première loi et la seconde
void LoiDesMelangesEnSigma::Activation_donnees(Tableau<Noeud *>& tabnoeud,bool dilatation,LesPtIntegMecaInterne& lesPtMecaInt)
{ if (type_melange < 3) // cas de la loi historique
{ // dans le cas d'une proportion venant des noeuds par interpolation
// on active les ddl correspondant à la grandeur qui règle la proportion
if (valeur_aux_noeuds)
{ int nbnoeud = tabnoeud.Taille();
for (int i=1;i<=nbnoeud;i++)
{ // on vérifie que la variable type_grandeur existe sinon erreur
if (tabnoeud(i)->Existe_ici(type_grandeur.Enum()))
{tabnoeud(i)->Met_en_service(type_grandeur.Enum());}
else
// { cout << "\n erreur: la grandeur " << Nom_ddl(type_grandeur) << " n'existe pas "
{ cout << "\n erreur: la grandeur " << type_grandeur << " n'existe pas "
<< " il n'est pas possible d'utiliser une loi des melanges avec cette grandeur "
<< " il manque sans doute des donnees !!! "
<< "\n LoiDesMelangesEnSigma::Activation_donnees(...";
Sortie(1);
};
}
}
else
{// cas d'un vrai ddl étendue
// on commence par regarder si les pt meca int existent
if ( ((LesPtIntegMecaInterne*) &lesPtMecaInt) == NULL)
{ cout << "\n *** erreur la loi des melanges ne peut pas s'utiliser ici telle quelle ***"
<< " demander une modification ! ";
cout << "\n LoiDesMelangesEnSigma::Activation_donnees(.. " << endl;
Sortie(1);
};
// cas normal
switch (type_grandeur.Position()-NbEnum_ddl())
{case 77: case 78: case 87: case 88: // cas de "def_duale_mises", cas de "Spherique_eps", cas de "def_duale_mises_maxi"
{// il faut que l'on active le calcul des invariants de déformations
int nbpti = lesPtMecaInt.NbPti();
for (int i= 1;i<= nbpti;i++)
lesPtMecaInt(i).Change_statut_Invariants_deformation (true);
break;
}
case 81: // cas de "Spherique_sig"
{// il faut que l'on active le calcul des invariants des contraintes
int nbpti = lesPtMecaInt.NbPti();
for (int i= 1;i<= nbpti;i++)
lesPtMecaInt(i).Change_statut_Invariants_contrainte (true);
break;
}
default:
cout << "\n erreur, le type de proportion " << type_grandeur << " n'est pas disponible "
<< " pour l'instant au point d'integration ! "
<< "\n LoiDesMelangesEnSigma::Activation_donnees(.... ";
Sortie(1);
break;
};
};
}
else // cas type_melange = 3 ou 4: -> fonctions complexes
{if (niveauF_ddlEtendu != NULL)
niveauF_ddlEtendu->Activation_donnees(tabnoeud, dilatation, lesPtMecaInt);
};
// appel des lois élémentaires
lois_internes1->Activation_donnees(tabnoeud,dilatation,lesPtMecaInt);
lois_internes2->Activation_donnees(tabnoeud,dilatation,lesPtMecaInt);
// appel de la méthode de la classe mère
Loi_comp_abstraite::Activ_donnees(tabnoeud,dilatation,lesPtMecaInt);
};
// récupération des grandeurs particulière (hors ddl )
// correspondant à liTQ
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
void LoiDesMelangesEnSigma::Grandeur_particuliere
(bool absolue,List_io<TypeQuelconque>& liTQ,Loi_comp_abstraite::SaveResul * saveDon,list<int>& decal) const
{ // tout d'abord on récupère le conteneur
SaveResul_LoiDesMelangesEnSigma & save_resul = *((SaveResul_LoiDesMelangesEnSigma*) saveDon);
int dim = ParaGlob::Dimension();
// maintenant on s'occupe des grandeurs de la loi additive elle même,
List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end();
list<int>::iterator idecal=decal.begin();
for (itq=liTQ.begin();itq!=itqfin;itq++,idecal++)
{TypeQuelconque& tipParticu = (*itq); // pour simplifier
if (tipParticu.EnuTypeQuelconque().Nom_vide()) // veut dire que c'est un enum pur
{ EnumTypeQuelconque enuTQ = tipParticu.EnuTypeQuelconque().EnumTQ();
SaveResul_LoiDesMelangesEnSigma & save_resul = *((SaveResul_LoiDesMelangesEnSigma*) saveDon);
// 1) -----cas des contraintes individuelles à chaque loi à t et courantes
if ((enuTQ) == CONTRAINTE_INDIVIDUELLE_A_CHAQUE_LOI_A_T_SANS_PROPORTION)
{ Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier
// on boucle sur les lois
list <TenseurHH* >::iterator isig_t;
// première loi
isig_t = save_resul.l_sigoHH_t.begin();
// en fait on utilise systématiquement un tenseur d'ordre le + élevé, car c'est le conteneur le plus générique
// et Tab_Grandeur_TenseurHH ne supporte que des tenseurs du même ordre donc s'il y a un tenseur élevé
// interne il faut que tous les tenseurs soient du même ordre
TenseurHH* sigHH = (*(isig_t)); // pour simplifier
if (Dabs(sigHH->Dimension()) != dim)
{tyTQ(1+(*idecal)).Affectation_trans_dimension(*sigHH,true);
}
else // cas même dimension
{tyTQ(1+(*idecal)) = *(*(isig_t));
};
(*idecal)++;
// seconde loi
isig_t++;
sigHH = (*(isig_t)); // pour simplifier
if (Dabs(sigHH->Dimension()) != dim)
{tyTQ(1+(*idecal)).Affectation_trans_dimension(*sigHH,true);
}
else // cas même dimension
{tyTQ(1+(*idecal)) = *(*(isig_t));
};
(*idecal)++;
};
// 2) -----cas des contraintes individuelles à chaque loi à t uniquement
if (enuTQ == CONTRAINTE_INDIVIDUELLE_A_CHAQUE_LOI_A_T)
{ Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier
// on boucle sur les lois
list <TenseurHH* >::iterator jsig_t;
// première loi
jsig_t = save_resul.J_sigoHH_t.begin();
// en fait on utilise systématiquement un tenseur d'ordre le + élevé, car c'est le conteneur le plus générique
// et Tab_Grandeur_TenseurHH ne supporte que des tenseurs du même ordre donc s'il y a un tenseur élevé
// interne il faut que tous les tenseurs soient du même ordre
TenseurHH* sigHH = (*(jsig_t)); // pour simplifier
if (Dabs(sigHH->Dimension()) != dim)
{tyTQ(1+(*idecal)).Affectation_trans_dimension((*sigHH) * aA*save_resul.proportion_t,true);
}
else // cas même dimension
{tyTQ(1+(*idecal)) = (*(*(jsig_t))) * aA*save_resul.proportion_t;
};
(*idecal)++;
//debug
//cout << "\n (*(*(jsig_t))) * save_resul.proportion_t= ";
//((*(*(jsig_t))) * save_resul.proportion_t).Ecriture(cout);
//cout << "\n debug LoiDesMelangesEnSigma::Grandeur_particuliere" << endl;
//findebug
// seconde loi
jsig_t++;
sigHH = (*(jsig_t)); // pour simplifier
if (Dabs(sigHH->Dimension()) != dim)
{tyTQ(1+(*idecal)).Affectation_trans_dimension((*sigHH) * aA*(1.-save_resul.proportion_t),true);
}
else // cas même dimension
{tyTQ(1+(*idecal)) = (*(*(jsig_t))) * aA*(1.-save_resul.proportion_t);
};
(*idecal)++;
//debug
//cout << "\n (*(*(jsig_t))) * save_resul.proportion_t= ";
//((*(*(jsig_t))) * save_resul.proportion_t).Ecriture(cout);
//cout << "\n debug LoiDesMelangesEnSigma::Grandeur_particuliere" << endl;
//findebug
};
// 3) -----cas de l'énergie élastique individuelles à chaque loi à t
if (enuTQ == ENERGIE_ELASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T)
{ Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
// on boucle sur les lois
list <EnergieMeca >::iterator ienerg_t;
ienerg_t = save_resul.l_energ_t.begin();
tyTQ(1+(*idecal)) = (*ienerg_t).EnergieElastique(); (*idecal)++;
ienerg_t++;
tyTQ(1+(*idecal)) = (*ienerg_t).EnergieElastique(); (*idecal)++;
};
// 4) -----cas de l'énergie plastique individuelles à chaque loi à t
if (enuTQ == ENERGIE_PLASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T)
{ Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
// on boucle sur les lois
list <EnergieMeca >::iterator ienerg_t;
ienerg_t = save_resul.l_energ_t.begin();
tyTQ(1+(*idecal)) = (*ienerg_t).DissipationPlastique(); (*idecal)++;
ienerg_t++;
tyTQ(1+(*idecal)) = (*ienerg_t).DissipationPlastique(); (*idecal)++;
};
// 5) -----cas de l'énergie visqueuse individuelles à chaque loi à t
if (enuTQ == ENERGIE_VISQUEUSE_INDIVIDUELLE_A_CHAQUE_LOI_A_T)
{ Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
// on boucle sur les lois
list <EnergieMeca >::iterator ienerg_t;
ienerg_t = save_resul.l_energ_t.begin();
tyTQ(1+(*idecal)) = (*ienerg_t).DissipationVisqueuse(); (*idecal)++;
ienerg_t++;
tyTQ(1+(*idecal)) = (*ienerg_t).DissipationVisqueuse(); (*idecal)++;
};
// 6) -----cas de la proportion relative entre les deux lois
if (enuTQ == PROPORTION_LOI_MELANGE)
{ Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
tyTQ(1+(*idecal)) = save_resul.proportion_t; (*idecal)++;
// *(tyTQ.ConteneurDouble()) = save_resul.proportion_t;
};
};
};
// puis appel des lois élémentaires
list <SaveResul*>::iterator ill = save_resul.liste_des_SaveResul.begin();
lois_internes1->Grandeur_particuliere(absolue,liTQ,*ill,decal); ill++;
lois_internes2->Grandeur_particuliere(absolue,liTQ,*ill,decal);
};
// récupération de la liste de tous les grandeurs particulières
// ces grandeurs sont ajoutées à la liste passées en paramètres
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
void LoiDesMelangesEnSigma::ListeGrandeurs_particulieres(bool absolue,List_io<TypeQuelconque>& liTQ) const
{ // tout d'abord on passe en revue les grandeurs des lois associées
// ** au niveau de l'exécution ce sera l'inverse de cette ordre: on s'occupera d'abord de this puis les lois internes
// ** mais a priori cela n'a pas d'importance
// appel des lois élémentaires
int nb_loi = 2; // pour être identique pour la loi additive !!
lois_internes1->ListeGrandeurs_particulieres(absolue,liTQ);
lois_internes2->ListeGrandeurs_particulieres(absolue,liTQ);
// ... maintenant on s'occupe des grandeurs de la loi additive elle même,
// 1) -----cas des contraintes individuelles à chaque loi à t et courantes
// ici il s'agit du tenseur des contraintes du pas précédent ou du pas actuel
//on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == CONTRAINTE_INDIVIDUELLE_A_CHAQUE_LOI_A_T_SANS_PROPORTION)
{ Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier
int taille = tyTQ.Taille()+nb_loi;
tyTQ.Change_taille(taille); nexistePas = false;
};
if (nexistePas)
{TenseurHH* tens = NevezTenseurHH(ParaGlob::Dimension()); // un tenseur typique
// en fait on utilise systématiquement un tenseur d'ordre le + élevé, car c'est le conteneur le plus générique
// et Tab_Grandeur_TenseurHH ne supporte que des tenseurs du même ordre donc s'il y a un tenseur élevé
// interne il faut que tous les tenseurs soient du même ordre
Tab_Grandeur_TenseurHH gtHH(*tens,nb_loi);
// def d'un type quelconque représentatif
TypeQuelconque typQ(CONTRAINTE_INDIVIDUELLE_A_CHAQUE_LOI_A_T_SANS_PROPORTION,SIG11,gtHH);
liTQ.push_back(typQ);
delete tens; // car on n'en a plus besoin
};
};
// 2) -----cas des contraintes individuelles à chaque loi à t uniquement
// ici il s'agit du tenseur des contraintes du pas précédent ou du pas actuel
//on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == CONTRAINTE_INDIVIDUELLE_A_CHAQUE_LOI_A_T)
{ Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier
int taille = tyTQ.Taille()+nb_loi;
tyTQ.Change_taille(taille); nexistePas = false;
};
if (nexistePas)
{TenseurHH* tens = NevezTenseurHH(ParaGlob::Dimension()); // un tenseur typique
// en fait on utilise systématiquement un tenseur d'ordre le + élevé, car c'est le conteneur le plus générique
// et Tab_Grandeur_TenseurHH ne supporte que des tenseurs du même ordre donc s'il y a un tenseur élevé
// interne il faut que tous les tenseurs soient du même ordre
Tab_Grandeur_TenseurHH gtHH(*tens,nb_loi);
// def d'un type quelconque représentatif
TypeQuelconque typQ(CONTRAINTE_INDIVIDUELLE_A_CHAQUE_LOI_A_T,SIG11,gtHH);
liTQ.push_back(typQ);
delete tens; // car on n'en a plus besoin
};
};
// pour toutes les énergies
Tableau <double> tab_double(nb_loi);
Tab_Grandeur_scalaire_double grand_courant(tab_double);
// 3) -----cas de l'énergie élastique individuelles à chaque loi à t uniquement
//on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == ENERGIE_ELASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T)
{ Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
int taille = tyTQ.Taille()+nb_loi;
tyTQ.Change_taille(taille); nexistePas = false;
};
if (nexistePas)
{TypeQuelconque typQ1(ENERGIE_ELASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T,SIG11,grand_courant);
liTQ.push_back(typQ1);
};
};
// 4) -----cas de l'énergie plastique individuelles à chaque loi à t uniquement
//on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == ENERGIE_PLASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T)
{ Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
int taille = tyTQ.Taille()+nb_loi;
tyTQ.Change_taille(taille); nexistePas = false;
};
if (nexistePas)
{TypeQuelconque typQ1(ENERGIE_PLASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T,SIG11,grand_courant);
liTQ.push_back(typQ1);
};
};
// 5) -----cas de l'énergie visqueuse individuelles à chaque loi à t uniquement
//on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == ENERGIE_VISQUEUSE_INDIVIDUELLE_A_CHAQUE_LOI_A_T)
{Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
int taille = tyTQ.Taille()+nb_loi;
tyTQ.Change_taille(taille); nexistePas = false;
};
if (nexistePas)
{TypeQuelconque typQ1(ENERGIE_VISQUEUSE_INDIVIDUELLE_A_CHAQUE_LOI_A_T,SIG11,grand_courant);
liTQ.push_back(typQ1);
};
};
// 6) -----cas de la proportion relative entre les deux lois
//on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée
{//on commence par définir une grandeur_scalaire_double
Tableau <double> tab_1(1);
Tab_Grandeur_scalaire_double gtab(tab_1);
List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == PROPORTION_LOI_MELANGE)
{ Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
int taille = tyTQ.Taille()+1;
tyTQ.Change_taille(taille); nexistePas = false;
};
if (nexistePas)
{ TypeQuelconque typQ1(PROPORTION_LOI_MELANGE,SIG11,gtab);
liTQ.push_back(typQ1);
};
};
};
// indique le type Enum_comp_3D_CP_DP_1D correspondant à une loi de comportement
// la fonction est simple dans le cas d'une loi basique, par contre dans le cas
// d'une loi combinée, la réponse dépend des lois internes donc c'est redéfini
// dans les classes dérivées
Enum_comp_3D_CP_DP_1D LoiDesMelangesEnSigma::Comportement_3D_CP_DP_1D()
{ // si la première lois internes n'est pas nulle, on ramène le cas de la première loi
if (lois_internes1 != NULL)
{return lois_internes1->Comportement_3D_CP_DP_1D();}
else // sinon on ramène le cas non défini
{return RIEN_COMP_3D_CP_DP_1D;};
};
//----- lecture écriture de restart -----
// cas donne le niveau de la récupération
// = 1 : on récupère tout
// = 2 : on récupère uniquement les données variables (supposées comme telles)
void LoiDesMelangesEnSigma::Lecture_base_info_loi(ifstream& ent,const int cas,LesReferences& lesRef,LesCourbes1D& lesCourbes1D
,LesFonctions_nD& lesFonctionsnD)
{ if (cas == 1)
{ string st1; string nom;
ent >> st1 >> nom >> type_melange ;
if (st1 != "LOI_DES_MELANGES_EN_SIGMA")
{ cout << "\n erreur en lecture de la loi : LOI_DES_MELANGES_EN_SIGMA,"
<< " on attendait le mot cle : LOI_DES_MELANGES_EN_SIGMA "
<< "\n LoiDesMelangesEnSigma::Lecture_base_info_loi(...";
Sortie(1);
};
if (type_melange < 3) // cas de la mise en données historique
{ent >> nom >> type_grandeur
>> nom >> valeur_aux_noeuds >> nom;
// extension éventuelle
ent >> st1 >> aA;
// courbe d'interface éventuelle
bool test = false;
ent >> test;
if (!test)
{ if (c_proport != NULL) {if (c_proport->NomCourbe() == "_")
delete c_proport; c_proport = NULL;};
}
else
{ ent >> nom; c_proport = lesCourbes1D.Lecture_pour_base_info(ent,cas,c_proport); };
}
else // cas de la deuxième mise en données
{ // les grandeurs globales
ent >> nom;
if (nom == "avec_Ponderation_nD")
{ niveauF_grandeurND = lesFonctionsnD.Lecture_pour_base_info(ent,cas,niveauF_grandeurND);};
// les pondérations avec les ddl
ent >> nom;
if (nom == "avec_Ponderation_ddl")
{if (niveauF_ddlEtendu==NULL)
niveauF_ddlEtendu = new Ponderation;
niveauF_ddlEtendu->Lecture_base_info(ent,cas, lesCourbes1D);
}
else
{ if (niveauF_ddlEtendu!=NULL)
delete niveauF_ddlEtendu;
};
// la pondération temps
ent >> nom;
if (nom == "avec_Ponderation_temps")
{if (niveauF_temps==NULL)
niveauF_temps = new Ponderation_temps;
niveauF_temps->Lecture_base_info(ent,cas, lesCourbes1D);
}
else
{ if (niveauF_temps!=NULL)
delete niveauF_temps;
};
};
// ensuite normalement il n'y a pas de pb de lecture puisque c'est écrit automatiquement
// on supprime les lois actuellement présentent par sécurité
if (lois_internes1 != NULL) delete lois_internes1;
if (lois_internes2 != NULL) delete lois_internes2;
// lecture de la gestion conditionnel si prop non nulle
ent >> nom;
if (nom == "sans_test_proportion_non_nulle")
{ calcule_si_prop_non_nulle.Change_taille(0);}
else
{ calcule_si_prop_non_nulle.Change_taille(2);
ent >> nom >> calcule_si_prop_non_nulle(1) >> nom >> calcule_si_prop_non_nulle(2);
};
// --partie_relative_aux_lois_internes:
ent >> nom;
// on lit les deux lois
ent >> nom >> st1; lois_internes1 = (Loi_comp_abstraite *) LesLoisDeComp::Def_loi(st1);
lois_internes1->Lecture_base_info_loi(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD);
ent >> nom >> st1; lois_internes2 = (Loi_comp_abstraite *) LesLoisDeComp::Def_loi(st1);
lois_internes2->Lecture_base_info_loi(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD);
}
else
{ // on boucle directement sur les lois déjà définis
string nom;
ent >> nom; // lois_1-->
lois_internes1->Lecture_base_info_loi(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD);
ent >> nom; // lois_2-->
lois_internes2->Lecture_base_info_loi(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD);
};
};
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void LoiDesMelangesEnSigma::Ecriture_base_info_loi(ofstream& sort,const int cas)
{ if (cas == 1)
{ sort << "\n LOI_DES_MELANGES_EN_SIGMA "
<< "\n type_de_melange: "<<type_melange << " ";
if (type_melange < 3) // cas de la mise en données historique
{sort << " grandeur_proportion= " << type_grandeur
<< " aux_noeuds " << valeur_aux_noeuds <<" lois ";
// extension éventuelle
sort << " A= " << aA ;
// courbe d'interface
if (c_proport == NULL)
{ sort << false << " " ;}
else
{ sort << true << " fonction_c_proport ";
LesCourbes1D::Ecriture_pour_base_info(sort,cas,c_proport);
};
}
else // cas de la deuxième mise en données
{ bool sans_courbe = true;
if (niveauF_grandeurND != NULL)
{sort << " avec_Ponderation_nD ";
LesFonctions_nD::Ecriture_pour_base_info(sort, cas,niveauF_grandeurND);
}
else {sort << " sans_Ponderation_nD ";};
if (niveauF_ddlEtendu!= NULL)
{sort << " avec_Ponderation_ddl ";
niveauF_ddlEtendu->Ecriture_base_info(sort,cas);
}
else {sort << " sans_Ponderation_ddl ";};
if (niveauF_temps!= NULL)
{sort << " avec_Ponderation_temps ";
niveauF_temps->Ecriture_base_info(sort,cas);
}
else {sort << " sans_Ponderation_temps ";};
};
// gestion conditionnel si prop non nulle
if (calcule_si_prop_non_nulle.Taille() != 2)
{ sort << "\n sans_test_proportion_non_nulle \n ";}
else
{ sort << "\n AVEC_test_proportion_non_nulle ";
sort << "\n calcule_si_prop_non_nulle1= " << calcule_si_prop_non_nulle(1)
<< " calcule_si_prop_non_nulle2= " << calcule_si_prop_non_nulle(2) << " ";
};
sort << "\n --partie_relative_aux_lois_internes: ";
sort << "\n lois_1---> " << lois_internes1->Nom_comport() << " "; lois_internes1->Ecriture_base_info_loi(sort,cas);
sort << "\n lois_2---> " << lois_internes2->Nom_comport() << " "; lois_internes2->Ecriture_base_info_loi(sort,cas);
}
else
{ sort << "\n lois_1--> ";
lois_internes1->Ecriture_base_info_loi(sort,cas);
sort << "\n lois_2--> ";
lois_internes2->Ecriture_base_info_loi(sort,cas);
};
};
// ========== codage des METHODES VIRTUELLES protegees:================
// calcul des contraintes a t+dt
void LoiDesMelangesEnSigma::Calcul_SigmaHH (TenseurHH& sigHH_t,TenseurBB& DepsBB,DdlElement & tab_ddl,
TenseurBB & gijBB_t,TenseurHH & gijHH_t,BaseB& giB,BaseH& gi_H, TenseurBB & epsBB_,
TenseurBB & delta_epsBB,
TenseurBB & gijBB_,TenseurHH & gijHH_,Tableau <TenseurBB *>& d_gijBB_,
double& jacobien_0,double& jacobien,TenseurHH & sigHH
,EnergieMeca & energ,const EnergieMeca &
,double& module_compressibilite,double& module_cisaillement
,const Met_abstraite::Expli_t_tdt& ex)
{ // on commence par créer un tenseur contrainte qui totalisera toutes les contraintes
int dim_tens = sigHH.Dimension();
// on utilise des pointeurs pour utiliser delete à la fin
TenseurHH * sigtotalHH = (NevezTenseurHH(dim_tens,0.));
TenseurHH * zeroHH = (NevezTenseurHH(dim_tens,0.));
TenseurHH * deltaSigHH = (NevezTenseurHH(dim_tens,0.)); // pour la variation de contraintes
SaveResul_LoiDesMelangesEnSigma & save_resul = *((SaveResul_LoiDesMelangesEnSigma*) saveResul);
module_compressibilite=module_cisaillement=0.; // init
energ.Inita(0.); // initialisation des énergies mises en jeux
// on balaie l'ensemble des lois
list <TenseurHH* >::iterator isig,isig_t,jsig,jsig_t; int ili;
list <EnergieMeca >::iterator ienerg,ienerg_t;
list <SaveResul*>::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois
Loi_comp_abstraite * pt=NULL;
// on récupère la valeur de la proportion enregistrée, qui a donc été calculée dans les grandeurs de
// travail
proportion = save_resul.proportion;
bool premier_passage = true;
for (ili=1,isig_t = save_resul.l_sigoHH_t.begin(),isig = save_resul.l_sigoHH.begin()
,jsig_t = save_resul.J_sigoHH_t.begin(),jsig = save_resul.J_sigoHH.begin()
,ienerg = save_resul.l_energ.begin(),ienerg_t = save_resul.l_energ_t.begin();
ili<=2;ili++,isig_t++,isig++,jsig_t++,jsig++,isave++,ienerg++,ienerg_t++)
{ // dimensionnement si nécessaire
if ((*isig)->Dimension()!=sigHH_t.Dimension())
{ delete (*isig); (*isig)=NevezTenseurHH(sigHH_t.Dimension(),0.);};
if ((*isig_t)->Dimension()!=sigHH_t.Dimension())
{ delete (*isig_t); (*isig_t)=NevezTenseurHH(sigHH_t.Dimension(),0.);};
if ((*jsig)->Dimension()!=sigHH_t.Dimension())
{ delete (*jsig); (*jsig)=NevezTenseurHH(sigHH_t.Dimension(),0.);};
if ((*jsig_t)->Dimension()!=sigHH_t.Dimension())
{ delete (*jsig_t); (*jsig_t)=NevezTenseurHH(sigHH_t.Dimension(),0.);};
// initialisation du tenseurs contrainte
sigHH = (*zeroHH);
// calcul de la contrainte résultante,
if (ili==1) {pt=lois_internes1;} else {pt=lois_internes2;};
double compress_inter=0.; double cisaill_inter=0; // init
// passage des informations spécifique à la loi liste_des_SaveResul
pt->IndiqueSaveResult(*isave);
pt->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca
pt->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours
// prise en compte éventuel d'un calcul conditionel au cas d'une proportion non nulle
bool traitement = true; // par défaut
if (calcule_si_prop_non_nulle.Taille() == 2)
{if (calcule_si_prop_non_nulle(ili) == 1)
{if (premier_passage && ( proportion == 0.)) {traitement = false;}
else if ((!premier_passage) && ( proportion == 1.)) {traitement = false;};
}
else if ((calcule_si_prop_non_nulle(ili) == 2)||(calcule_si_prop_non_nulle(ili) == 3))
{ if ((premier_passage)&& (!save_resul.deja_actif_sur_iter1))
// première loi et pas encore actif
{ if ( proportion == 0. ) // on désactive et on signale pour la suite
{traitement = false;save_resul.deja_actif_sur_iter1=true;};
};
if ((!premier_passage)&& (!save_resul.deja_actif_sur_iter2))
// seconde loi et pas encore actif
{ if ( proportion == 1. ) // on ne traite pas
{traitement = false;}
else // sinon le traitement commence
{save_resul.deja_actif_sur_iter2=true;};
};
}
};
//--- debug
// cout << "\n debug LoiDesMelangesEnSigma::Calcul_SigmaHH traitement= "
// << traitement ;
// if (premier_passage) {cout << " P1 " << endl;} else {cout << " P2 " << endl;}
// if (!premier_passage && traitement)
// {cout << "\n debug LoiDesMelangesEnSigma::Calcul_SigmaHH traitement= enclanche "
// << calcule_si_prop_non_nulle(1) << " " << calcule_si_prop_non_nulle(2)
// << endl;
// };
//--- fin debug
if (traitement)
{ pt->Calcul_SigmaHH((*(*isig_t)),DepsBB,tab_ddl,gijBB_t,gijHH_t,giB,gi_H,epsBB_,delta_epsBB,
gijBB_,gijHH_,d_gijBB_,jacobien_0,jacobien,sigHH
,(*ienerg),(*ienerg_t),compress_inter,cisaill_inter,ex);
// on commence par sauvegarder la contrainte partielle avant application de la proportion
(*(*isig))=sigHH; // on sauvegarde la contrainte partielle totale
// def du facteur multiplicatif du à la proportion
double facteur_multiplicatif = aA * proportion;
////--- debug
// cout << "\n debug LoiDesMelangesEnSigma::Calcul_SigmaHH facteur_multiplicatif= "
// << facteur_multiplicatif << endl;
////--- fin debug
#ifdef MISE_AU_POINT
if (Permet_affichage() > 3)
cout << "\n LoiDesMelangesEnSigma::Calcul_SigmaHH ";
#endif
if (premier_passage) { premier_passage = false;}
else {facteur_multiplicatif = aA*(1.-proportion);};
// traitement
if ((type_melange == 1)||(type_melange == 3))
{ sigHH *= facteur_multiplicatif;
(*(*jsig))=sigHH; // on sauvegarde la contrainte partielle proportionalisée
(*sigtotalHH) += sigHH; // on ajoute la contrainte au total
#ifdef MISE_AU_POINT
if (Permet_affichage() > 3)
{if (premier_passage) {cout << "\n 1ere loi:";}
else {cout << "\n 2ieme loi: ";};
cout << " facteur_multiplicatif= "
<< facteur_multiplicatif
<< ", sigHH_tdt avec ponderation ";
sigHH.Ecriture(cout);
};
#endif
}
else // cas == 2
{ (*deltaSigHH) = sigHH - (*(*isig_t)); (*deltaSigHH) *= facteur_multiplicatif;
(*(*jsig))=(*(*jsig_t)) + (*deltaSigHH); // on sauvegarde la contrainte partielle proportionalisée
(*sigtotalHH) += (*(*jsig)); // cumule
};
energ += (*ienerg) * facteur_multiplicatif; // update des énergies
module_compressibilite += compress_inter * facteur_multiplicatif;
module_cisaillement += cisaill_inter * facteur_multiplicatif;
}
else
{ if (premier_passage) { premier_passage = false;};
(*(*isig))=(*zeroHH);
(*(*jsig))=(*zeroHH);
(*ienerg).Inita(0.);
}; // fin du traitement conditionnel
}; // fin de la boucle sur les deux lois
// recopie du résultat
sigHH = (*sigtotalHH);
delete sigtotalHH; delete zeroHH;delete deltaSigHH;
LibereTenseur();
};
// calcul des contraintes a t+dt et de ses variations
void LoiDesMelangesEnSigma::Calcul_DsigmaHH_tdt (TenseurHH& sigHH_t,TenseurBB& DepsBB,DdlElement & tab_ddl
,BaseB& giB_t,TenseurBB & gijBB_t,TenseurHH & gijHH_t,
BaseB& giB_tdt,Tableau <BaseB> & d_giB_tdt,BaseH& giH_tdt,Tableau <BaseH> & d_giH_tdt,
TenseurBB & epsBB_tdt,Tableau <TenseurBB *>& d_epsBB,
TenseurBB & delta_epsBB,TenseurBB & gijBB_tdt,TenseurHH & gijHH_tdt,
Tableau <TenseurBB *>& d_gijBB_tdt,
Tableau <TenseurHH *>& d_gijHH_tdt,double& jacobien_0,double& jacobien,
Vecteur& d_jacobien_tdt,TenseurHH& sigHH_tdt,Tableau <TenseurHH *>& d_sigHH
,EnergieMeca & energ,const EnergieMeca &
,double& module_compressibilite,double& module_cisaillement
,const Met_abstraite::Impli& ex)
{ // on commence par créer un tenseur contrainte qui totalisera toutes les contraintes
// le tenseurs est initialisé à 0.
// on utilise des pointeurs pour utiliser delete à la fin
int dim_tens = sigHH_tdt.Dimension();
TenseurHH * sigtotalHH = (NevezTenseurHH(dim_tens,0.));
TenseurHH * zeroHH = (NevezTenseurHH(dim_tens,0.));
TenseurHH * deltaSigHH = (NevezTenseurHH(dim_tens,0.)); // pour la variation de contraintes
SaveResul_LoiDesMelangesEnSigma & save_resul = *((SaveResul_LoiDesMelangesEnSigma*) saveResul);
module_compressibilite=module_cisaillement=0.; // init
//---debug
//ofstream fichier("toto", ios::app);
//save_resul.Ecriture_base_info(fichier,1); // calcul de la contrainte résultante
//list <SaveResul *>::iterator ili=save_resul.liste_des_SaveResul.begin();
//(*ili)->Ecriture_base_info(fichier,1);
//ili++;
//(*ili)->Ecriture_base_info(fichier,1);
//save_resul.Ecriture_base_info(fichier,1); // calcul de la contrainte résultante
////fichier.close();
////---fin debug
energ.Inita(0.); // initialisation des énergies mises en jeux
// on vérifie que le tableau de travail intermédiaire statique est correctement
// dimensionné sinon on le modifie
int taille = d_sigHH.Taille();
if (d_sigtotalHH.Taille() == 0)
{ d_sigtotalHH.Change_taille(taille,NULL);}
// for (int i=1;i<=taille;i++) d_sigtotalHH)(i)=NULL;
else if ( taille != d_sigtotalHH.Taille())
{ int ancienne_taille = d_sigtotalHH.Taille();
d_sigtotalHH.Change_taille(taille);
if (ancienne_taille < taille)
for (int i=ancienne_taille+1;i<=taille;i++) d_sigtotalHH(i)=NULL;
};
for (int i=1;i<=taille;i++)
{ // mise à zéro des tenseurs du tableau avec création si nécessaire
if (d_sigtotalHH(i) == NULL) {d_sigtotalHH(i)=NevezTenseurHH(dim_tens,0.);}
else if ( d_sigtotalHH(i)->Dimension() != dim_tens)
{ delete d_sigtotalHH(i); d_sigtotalHH(i)=NevezTenseurHH(dim_tens,0.);}
else // mise à zéro simple
*(d_sigtotalHH(i))= (*zeroHH);
};
// première mise à zéro de d_sigHH
for (int j1=1;j1<=taille;j1++) *d_sigHH(j1) = (*zeroHH);
Tableau <TenseurHH *>& d_SigtotalHH = d_sigtotalHH; // pour simplifier l'acces
// maintenant on balaie l'ensemble des lois
bool premier_passage = true;
list <TenseurHH* >::iterator isig_t = save_resul.l_sigoHH_t.begin();
list <TenseurHH* >::iterator isig = save_resul.l_sigoHH.begin();
list <TenseurHH* >::iterator jsig_t = save_resul.J_sigoHH_t.begin();
list <TenseurHH* >::iterator jsig = save_resul.J_sigoHH.begin();
list <SaveResul*>::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois
list <EnergieMeca >::iterator ienerg = save_resul.l_energ.begin();
list <EnergieMeca >::iterator ienerg_t = save_resul.l_energ_t.begin();
Loi_comp_abstraite * pt=NULL;
// on récupère la valeur de la proportion enregistrée, qui a donc été calculée dans les grandeurs de
// travail
proportion = save_resul.proportion;
//try {
for (int ili=1;ili<=2;ili++,isig_t++,isig++,jsig_t++,jsig++,isave++,ienerg++,ienerg_t++)
{ // initialisation du tenseurs contrainte à chaque début de boucle
sigHH_tdt = (*zeroHH);
// dimensionnement si nécessaire
if ((*isig)->Dimension()!=sigHH_t.Dimension())
{ delete (*isig); (*isig)=NevezTenseurHH(sigHH_t.Dimension(),0.);};
if ((*isig_t)->Dimension()!=sigHH_t.Dimension())
{ delete (*isig_t); (*isig_t)=NevezTenseurHH(sigHH_t.Dimension(),0.);};
if ((*jsig)->Dimension()!=sigHH_t.Dimension())
{ delete (*jsig); (*jsig)=NevezTenseurHH(sigHH_t.Dimension(),0.);};
if ((*jsig_t)->Dimension()!=sigHH_t.Dimension())
{ delete (*jsig_t); (*jsig_t)=NevezTenseurHH(sigHH_t.Dimension(),0.);};
// calcul de la contrainte résultante,
if (ili==1) {pt=lois_internes1;} else {pt=lois_internes2;};
double compress_inter=0.; double cisaill_inter=0; // init
// passage des informations spécifique à la loi liste_des_SaveResul
pt->IndiqueSaveResult(*isave);
pt->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca
pt->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours
////---debug
//cout << "\n isave melange = " << ( (*isave) == NULL ) << endl;
////ofstream fichier("toto");
//(*isave)->Ecriture_base_info(fichier,1); // calcul de la contrainte résultante
//fichier.close();
//---fin debug
// prise en compte éventuel d'un calcul conditionel au cas d'une proportion non nulle
bool traitement = true; // par défaut
if (calcule_si_prop_non_nulle.Taille() == 2)
{if (calcule_si_prop_non_nulle(ili) == 1)
{if (premier_passage && ( proportion == 0.)) {traitement = false;}
else if ((!premier_passage) && ( proportion == 1.)) {traitement = false;};
}
else if ((calcule_si_prop_non_nulle(ili) == 2)||(calcule_si_prop_non_nulle(ili) == 3))
{ if ((premier_passage)&& (!save_resul.deja_actif_sur_iter1))
// première loi et pas encore actif
{ if ( proportion == 0. ) // on désactive et on signale pour la suite
{traitement = false;save_resul.deja_actif_sur_iter1=true;};
};
if ((!premier_passage)&& (!save_resul.deja_actif_sur_iter2))
// seconde loi et pas encore actif
{ if ( proportion == 1. ) // on ne traite pas
{traitement = false;}
else // sinon le traitement commence
{save_resul.deja_actif_sur_iter2=true;};
};
}
};
//--- debug
// if (proportion == 0.)
// cout << "\n premier_passage= " << premier_passage << ", traitement= " << traitement << endl;
//--- fin debug
if (traitement)
{ pt->Calcul_DsigmaHH_tdt((*(*isig_t)),DepsBB,tab_ddl,giB_t,gijBB_t,gijHH_t,giB_tdt,d_giB_tdt,giH_tdt,d_giH_tdt,
epsBB_tdt,d_epsBB,delta_epsBB,gijBB_tdt,gijHH_tdt,d_gijBB_tdt,
d_gijHH_tdt,jacobien_0,jacobien,d_jacobien_tdt,sigHH_tdt,d_sigHH
,(*ienerg),(*ienerg_t),compress_inter,cisaill_inter,ex);
// on sauvegarde la contrainte partielle totale
(*(*isig))=sigHH_tdt;
#ifdef MISE_AU_POINT
if (Permet_affichage() > 3)
cout << "\n LoiDesMelangesEnSigma::Calcul_DsigmaHH_tdt ";
#endif
// def du facteur multiplicatif du à la proportion
double facteur_multiplicatif = aA * proportion;
if (premier_passage) { premier_passage = false;}
else {facteur_multiplicatif = aA*(1.-proportion);};
// traitement
if ((type_melange == 1)||(type_melange == 3))
{ sigHH_tdt *= facteur_multiplicatif;
(*(*jsig))=sigHH_tdt; // on sauvegarde la contrainte partielle proportionalisée
(*sigtotalHH) += sigHH_tdt; // on ajoute la contrainte au total
#ifdef MISE_AU_POINT
if (Permet_affichage() > 3)
{if (premier_passage) {cout << "\n 1ere loi:";}
else {cout << "\n 2ieme loi: ";};
cout << " facteur_multiplicatif= "
<< facteur_multiplicatif
<< ", sigHH_tdt avec ponderation ";
sigHH_tdt.Ecriture(cout);
};
#endif
}
else // cas == 2
{ (*deltaSigHH) = sigHH_tdt - (*(*isig_t)); (*deltaSigHH) *= facteur_multiplicatif;
(*(*jsig))=(*(*jsig_t)) + (*deltaSigHH); // on sauvegarde la contrainte partielle proportionalisée
(*sigtotalHH) += (*(*jsig)); // cumule
};
energ += (*ienerg) * facteur_multiplicatif; // update des énergies
module_compressibilite += compress_inter * facteur_multiplicatif;
module_cisaillement += cisaill_inter * facteur_multiplicatif;
// récup de l'opérateur tangent
for (int j=1;j<=taille;j++) (*d_sigHH(j))*= facteur_multiplicatif;
#ifdef MISE_AU_POINT
if (Permet_affichage() > 4)
for (int j = 1; j<= taille; j++)
{ cout << "\n d_sigHH("<<j<<") ";
d_sigHH(j)->Ecriture(cout);
};
#endif
for (int j=1;j<=taille;j++)
{ (*d_SigtotalHH(j)) += (*d_sigHH(j)); // cumul
*d_sigHH(j) = (*zeroHH); // et on initialise pour le prochain coup
}
}
else
{ if (premier_passage) { premier_passage = false;};
(*(*isig))=(*zeroHH);
(*(*jsig))=(*zeroHH);
(*ienerg).Inita(0.);
}; // fin du traitement conditionnel
}; // fin de la boucle sur les deux lois
// }
//catch ( ... )
// { this->Affiche();
// Sortie(1);
// };
// recopie du résultat
sigHH_tdt = (*sigtotalHH);
for (int k=1;k<=taille;k++)
(*d_sigHH(k)) = (*d_SigtotalHH(k));
delete sigtotalHH; delete zeroHH;delete deltaSigHH;
LibereTenseur();
//---debug
//fichier.close();
//---fin debug
};
// 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 orthonormee
// 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 LoiDesMelangesEnSigma::Calcul_dsigma_deps (bool en_base_orthonormee, TenseurHH & sigHH_t,TenseurBB& DepsBB
,TenseurBB & epsBB_tdt,TenseurBB & delta_epsBB,double& jacobien_0,double& jacobien
,TenseurHH& sigHH_tdt,TenseurHHHH& d_sigma_deps
,EnergieMeca & energ,const EnergieMeca &
,double& module_compressibilite,double& module_cisaillement
,const Met_abstraite::Umat_cont& ex)
{ // on commence par créer un tenseur contrainte qui totalisera toutes les contraintes
// le tenseurs est initialisé à 0.
int dim_tens = sigHH_tdt.Dimension();
TenseurHH * sigtotalHH = (NevezTenseurHH(dim_tens,0.));
TenseurHH * zeroHH = (NevezTenseurHH(dim_tens,0.));
TenseurHH * deltaSigHH = (NevezTenseurHH(dim_tens,0.)); // pour la variation de contraintes
SaveResul_LoiDesMelangesEnSigma & save_resul = *((SaveResul_LoiDesMelangesEnSigma*) saveResul);
module_compressibilite=module_cisaillement=0.; // init
energ.Inita(0.); // initialisation des énergies mises en jeux
// redimentionnement éventuel pour le comportement tangent
if (d_sigma_deps_inter != NULL)
{ if (d_sigma_deps_inter->Dimension() != d_sigma_deps.Dimension())
{ delete d_sigma_deps_inter; d_sigma_deps_inter = NevezTenseurHHHH(d_sigma_deps);}
}
else {d_sigma_deps_inter = NevezTenseurHHHH(d_sigma_deps);};
// maintenant on balaie l'ensemble des lois
bool premier_passage = true;
list <TenseurHH* >::iterator isig,isig_t,jsig,jsig_t;int ili;
list <EnergieMeca >::iterator ienerg,ienerg_t;
list <SaveResul*>::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois
Loi_comp_abstraite * pt=NULL;
// on récupère la valeur de la proportion enregistrée, qui a donc été calculée dans les grandeurs de
// travail
proportion = save_resul.proportion;
for (ili=1,isig_t = save_resul.l_sigoHH_t.begin(),isig = save_resul.l_sigoHH.begin()
,jsig_t = save_resul.l_sigoHH_t.begin(),jsig = save_resul.l_sigoHH.begin()
,ienerg = save_resul.l_energ.begin(),ienerg_t = save_resul.l_energ_t.begin();
ili<=2;ili++,isig_t++,isig++,jsig_t++,jsig++,isave++,ienerg++,ienerg_t++)
{ // initialisation du tenseurs contrainte à chaque début de boucle
sigHH_tdt = (*zeroHH);
// dimensionnement si nécessaire
if ((*isig)->Dimension()!=sigHH_t.Dimension())
{ delete (*isig); (*isig)=NevezTenseurHH(sigHH_t.Dimension(),0.);};
if ((*isig_t)->Dimension()!=sigHH_t.Dimension())
{ delete (*isig_t); (*isig_t)=NevezTenseurHH(sigHH_t.Dimension(),0.);};
if ((*jsig)->Dimension()!=sigHH_t.Dimension())
{ delete (*jsig); (*jsig)=NevezTenseurHH(sigHH_t.Dimension(),0.);};
if ((*jsig_t)->Dimension()!=sigHH_t.Dimension())
{ delete (*jsig_t); (*jsig_t)=NevezTenseurHH(sigHH_t.Dimension(),0.);};
// calcul de la contrainte résultante,
if (ili==1) {pt=lois_internes1;} else {pt=lois_internes2;};
double compress_inter=0.; double cisaill_inter=0; // init
// passage des informations spécifique à la loi liste_des_SaveResul
pt->IndiqueSaveResult(*isave);
pt->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca
pt->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours
// initialisation du comportement tangent
d_sigma_deps_inter->Inita(0.);
// prise en compte éventuel d'un calcul conditionel au cas d'une proportion non nulle
bool traitement = true; // par défaut
if (calcule_si_prop_non_nulle.Taille() == 2)
{if (calcule_si_prop_non_nulle(ili) == 1)
{if (premier_passage && ( proportion == 0.)) {traitement = false;}
else if ((!premier_passage) && ( proportion == 1.)) {traitement = false;};
}
else if ((calcule_si_prop_non_nulle(ili) == 2)||(calcule_si_prop_non_nulle(ili) == 3))
{ if ((premier_passage)&& (!save_resul.deja_actif_sur_iter1))
// première loi et pas encore actif
{ if ( proportion == 0. ) // on désactive et on signale pour la suite
{traitement = false;save_resul.deja_actif_sur_iter1=true;};
};
if ((!premier_passage)&& (!save_resul.deja_actif_sur_iter2))
// seconde loi et pas encore actif
{ if ( proportion == 1. ) // on ne traite pas
{traitement = false;}
else // sinon le traitement commence
{save_resul.deja_actif_sur_iter2=true;};
};
}
};
if (traitement)
{ // calcul de la contrainte résultante
pt->Calcul_dsigma_deps (en_base_orthonormee, (*(*isig_t)),DepsBB,epsBB_tdt,delta_epsBB,jacobien_0,jacobien
,sigHH_tdt,*d_sigma_deps_inter
,(*ienerg),(*ienerg_t),compress_inter,cisaill_inter,ex);
// on sauvegarde la contrainte partielle totale
(*(*isig))=sigHH_tdt;
#ifdef MISE_AU_POINT
if (Permet_affichage() > 3)
cout << "\n LoiDesMelangesEnSigma::Calcul_dsigma_deps ";
#endif
// def du facteur multiplicatif du à la proportion
double facteur_multiplicatif = aA * proportion;
if (premier_passage) { premier_passage = false;}
else {facteur_multiplicatif = aA*(1.-proportion);};
// traitement
if ((type_melange == 1)||(type_melange == 3))
{ sigHH_tdt *= facteur_multiplicatif;
(*(*jsig))=sigHH_tdt; // on sauvegarde la contrainte partielle proportionalisée
(*sigtotalHH) += sigHH_tdt; // on ajoute la contrainte au total
#ifdef MISE_AU_POINT
if (Permet_affichage() > 3)
{if (premier_passage) {cout << "\n 1ere loi:";}
else {cout << "\n 2ieme loi: ";};
cout << " facteur_multiplicatif= "
<< facteur_multiplicatif
<< ", sigHH_tdt avec ponderation ";
sigHH_tdt.Ecriture(cout);
};
#endif
}
else // cas == 2
{ (*deltaSigHH) = sigHH_tdt - (*(*isig_t)); (*deltaSigHH) *= facteur_multiplicatif;
(*(*jsig))=(*(*jsig_t)) + (*deltaSigHH); // on sauvegarde la contrainte partielle proportionalisée
(*sigtotalHH) += (*(*jsig)); // cumule
};
energ += (*ienerg) * facteur_multiplicatif; // update des énergies
module_compressibilite += compress_inter * facteur_multiplicatif;
module_cisaillement += cisaill_inter * facteur_multiplicatif;
(*d_sigma_deps_inter) *= facteur_multiplicatif; // module tangent
#ifdef MISE_AU_POINT
if (Permet_affichage() > 4)
{ cout << "\n d_sigma_deps_inter: ";
d_sigma_deps_inter->Ecriture(cout);
};
#endif
// récup de l'opérateur tangent
d_sigma_deps += *d_sigma_deps_inter;
}
else
{ if (premier_passage) { premier_passage = false;};
(*(*isig))=(*zeroHH);
(*(*jsig))=(*zeroHH);
(*ienerg).Inita(0.);
}; // fin du traitement conditionnel
}; // fin de la boucle sur les deux lois
// recopie du résultat
sigHH_tdt = (*sigtotalHH);
delete sigtotalHH; delete zeroHH;delete deltaSigHH;
LibereTenseur();LibereTenseurQ();
};
// fonction surchargée dans les classes dérivée si besoin est
void LoiDesMelangesEnSigma::CalculGrandeurTravail
(const PtIntegMecaInterne& ptintmeca
,const Deformation & def,Enum_dure temps,const ThermoDonnee& dTP
,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>* exclure_dd_etend
,const List_io<const TypeQuelconque *>* exclure_Q
)
{ // calcul de la proportion
double proportion_locale; // variable locale de travail pour être indépendant de la variable de la classe
if (type_melange < 3) // cas de la loi historique
{ if (valeur_aux_noeuds) // pour l'instant que des ddl patentés !
// cas d'une proportion provenant d'une interpolation aux noeuds
{ double grand = def.DonneeInterpoleeScalaire(type_grandeur.Enum(),temps);
if (c_proport != NULL)
{ proportion_locale = c_proport->Valeur(grand);}
else
{ proportion_locale = grand;};
}
else
// sinon il s'agit d'une grandeur directement accessible au point d'intégration
// pour l'instant il n'y a pas de procédure générale de récupération, seulement des cas particuliers
{
// deux cas suivant que l'on a affaire à un ddl de base ou à un vrai ddl étendu
if (type_grandeur.Nom_vide())
{switch (type_grandeur.Enum())
{ case PROP_CRISTA:
{ const double* taux_crita = dTP.TauxCrista();
if (taux_crita != NULL)
{ if (c_proport != NULL)
{ proportion_locale = c_proport->Valeur(*taux_crita);}
else
{ proportion_locale = *taux_crita;};
}
else
{ cout << "\n erreur, le taux de cristalinite n'est pas disponible au point d'integration "
<< " il n'est pas possible de calculer la proportion pour la loi des melanges "
<< "\n LoiDesMelangesEnSigma::CalculGrandeurTravail(.... ";
};
break;
}
default:
// cout << "\n erreur, le type de proportion " << Nom_ddl(type_grandeur) << " n'est pas disponible "
cout << "\n erreur, le type de proportion " << type_grandeur << " n'est pas disponible "
<< " pour l'instant au point d'integration ! "
<< "\n LoiDesMelangesEnSigma::CalculGrandeurTravail(.... ";
Sortie(1);
};
}
else
{// cas d'un vrai ddl étendue
switch (type_grandeur.Position()-NbEnum_ddl())
{case 87: // cas de "def_equivalente"
{const double def_equivalente = ptintmeca.Deformation_equi_const()(1); // recup de la def equi
if (c_proport != NULL)
{ proportion_locale = c_proport->Valeur(def_equivalente);}
else
{ proportion_locale = def_equivalente;}; // là mécanquement c'est débile mais techniquement c'est correcte
break;
}
case 88: // cas de "def_duale_mises_maxi"
{const double def_duale_mises_maxi = ptintmeca.Deformation_equi_const()(3); // recup de la def equi
if (c_proport != NULL)
{ proportion_locale = c_proport->Valeur(def_duale_mises_maxi);}
else
{ proportion_locale = def_duale_mises_maxi;}; // là mécanquement c'est débile mais techniquement c'est correcte
break;
}
case 77: // cas de "def_duale_mises"
{const double def_duale_mises = ptintmeca.Deformation_equi_const()(2); // recup de la def equi
if (c_proport != NULL)
{ proportion_locale = c_proport->Valeur(def_duale_mises);}
else
{ proportion_locale = def_duale_mises;}; // là mécanquement c'est débile mais techniquement c'est correcte
break;
}
// {const Vecteur & epsInvar = ptintmeca.EpsInvar_const(); // recup des invariants
// double def_duale_mises = sqrt(2./3. * epsInvar(2));
//
// if (c_proport != NULL)
// { proportion = c_proport->Valeur(def_duale_mises);}
// else
// { proportion = def_duale_mises;}; // là mécanquement c'est débile mais techniquement c'est correcte
// break;
// }
case 78: // cas de "Spherique_eps"
{const Vecteur & epsInvar = ptintmeca.EpsInvar_const(); // recup des invariants
double spherique_eps = epsInvar(1);
// cout << " Ieps=" << spherique_eps;
if (c_proport != NULL)
{ proportion_locale = c_proport->Valeur(spherique_eps);}
else
{ proportion_locale = spherique_eps;}; // là mécaniquement c'est débile mais techniquement c'est correcte
break;
}
case 81: // cas de "Spherique_sig"
{const Vecteur & sigInvar = ptintmeca.SigInvar_const(); // recup des invariants
double spherique_sig = sigInvar(1);
if (c_proport != NULL)
{ proportion_locale = c_proport->Valeur(spherique_sig);}
else
{ proportion_locale = spherique_sig;}; // là mécaniquement c'est débile mais techniquement c'est correcte
break;
}
default:
cout << "\n erreur, le type de proportion " << type_grandeur << " n'est pas disponible "
<< " pour l'instant au point d'integration ! "
<< "\n LoiDesMelangesEnSigma::CalculGrandeurTravail(.... ";
Sortie(1);
break;
}
}
};
}
else // cas type_melange = 3 ou 4: -> fonctions complexes
{
// le résultat de la proportion est le produit de toutes les proportions
// on initialise donc à 1
proportion_locale = 1.;
if (niveauF_grandeurND != NULL)
{
// il faut calculer la fonction nD
SaveResul_LoiDesMelangesEnSigma & save_resul = *((SaveResul_LoiDesMelangesEnSigma*) saveResul);
// on utilise la méthode générique de loi abstraite
Tableau <double> & tab_val = Loi_comp_abstraite::Loi_comp_Valeur_FnD_Evoluee
(niveauF_grandeurND,1 // une seule valeur attendue en retour
,ex_impli,ex_expli_tdt,ex_umat
,exclure_dd_etend
,exclure_Q
,&save_resul.liste_des_SaveResul
);
/*
// 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 = niveauF_grandeurND->Li_enu_etendu_scalaire();
List_io <TypeQuelconque >& li_quelc = niveauF_grandeurND->Li_equi_Quel_evolue();
bool absolue = true; // on se place systématiquement en absolu
SaveResul_LoiDesMelangesEnSigma & save_resul = *((SaveResul_LoiDesMelangesEnSigma*) saveResul);
// on va exclure certaines grandeurs de l'appel de Valeur_multi_interpoler_ou_calculer(..)
// on va utiliser la méhode Valeur_multi_interpoler_ou_calculer
// pour les grandeurs strictement scalaire
List_io<EnumTypeQuelconque> exclure_Q; // init de la liste à exclure
{List_io <TypeQuelconque>::iterator it,itfin = li_quelc.end();
map < EnumTypeQuelconque , TypeQuelconque, std::less < EnumTypeQuelconque> >::const_iterator imap;
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 lois pour récupérer les types quelconques
Loi_comp_abstraite * pt=NULL;
// pour couvrir l'ensemble des lois
list <SaveResul*>::iterator isave=save_resul.liste_des_SaveResul.begin(); // pour les saveResul des lois
for (int iloi = 1;iloi<3;iloi++,isave++)
{ if (iloi==1) {pt=lois_internes1;} else {pt=lois_internes2;};
// récupération des type quelconque sous forme d'un arbre pour faciliter la recherche
const map < EnumTypeQuelconque , TypeQuelconque, std::less < EnumTypeQuelconque> >*
map_quelcon = (*isave)->Map_type_quelconque();
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 LoiDesMelangesEnSigma::CalculGrandeurTravail(... ";
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_Q.push_back(enu);
};
};
// maintenant on appel les méthodes génériques
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 fait de même pour les grandeurs tensorielles
// 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_Q);
// calcul de la valeur et retour dans tab_val
Tableau <double> & tab_val = niveauF_grandeurND->Valeur_FnD_Evoluee(&val_ddl_enum,&li_enu_scal,&li_quelc,NULL,NULL);
#ifdef MISE_AU_POINT
if (tab_val.Taille() != 1)
{ cout << "\nErreur : la fonction nD relative a la ponderation nD "
<< " doit calculer un scalaire or le tableau de retour est de taille "
<< tab_val.Taille() << " ce n'est pas normal !\n";
cout << " LoiDesMelangesEnSigma::CalculGrandeurTravail(..\n";
Sortie(1);
};
#endif
*/
proportion_locale *= tab_val(1); // mise à jour de la proportion
};
if (niveauF_temps != NULL) // cas d'une dépendance au temps
proportion_locale *= niveauF_temps->CalculPonder();
// avec une dépendance via éventuellement des ddl étendu
if (niveauF_ddlEtendu != NULL)
proportion_locale *= niveauF_ddlEtendu->CalculPonderMultiplicatif(ptintmeca, def, temps, dTP);
};
// --- arrivée ici on a une proposition de proportion = proportion_locale
#ifdef MISE_AU_POINT
if (Permet_affichage() > 5)
{
cout << "\n loi melange: proportion avant limitation "<< proportion_locale;
}
#endif
// on traite les extrémums !!: a conserver absolument, car sert dans les tests avec le tableau: calcule_si_prop_non_nulle
if (proportion_locale < 0.) proportion_locale = 0;
if (proportion_locale > 1.) proportion_locale = 1.;
#ifdef MISE_AU_POINT
if (Permet_affichage() > 4)
{
cout << "\n proportion apres limitation "<< proportion_locale;
}
#endif
// if ( (proportion < -0.02) || (proportion > 1.02))
// { cout << "\n attention, la proportion entre les deux lois est hors de [-0.02,1.02], proportion = "
// << proportion << " ";
// cout << "\n LoiDesMelangesEnSigma::CalculGrandeurTravail(..";
// };
// calcul de l'enregistrement dans les variables spécifiques au point calculé
SaveResul_LoiDesMelangesEnSigma & save_res = *((SaveResul_LoiDesMelangesEnSigma*) saveResul);
// auparavant: traitement particulier d'une proportion toujours progressive
// if (calcule_si_prop_non_nulle.Taille() == 2)
// {if ((calcule_si_prop_non_nulle(1) == 2) || (calcule_si_prop_non_nulle(2) == 2)
// || ((calcule_si_prop_non_nulle(1) == 3) || (calcule_si_prop_non_nulle(2) == 3))
// )
if ((save_res.type_evolution_proportion == 1) || (save_res.type_evolution_proportion == 2))
// ici il s'agit d'une évolution absolue sur tout le calcul = tous les incréments
{ if (proportion_locale > save_res.proportion )
proportion_locale = save_res.proportion; // la proportion a augmenté, on garde la plus petite
}
// };
// suite normale
save_res.proportion = proportion_locale;
// répercution sur les classes dérivées si besoin est
list <SaveResul*>::iterator isave=save_res.liste_des_SaveResul.begin(); // pour les saveResul des lois
Loi_comp_abstraite * pt=NULL;
for (int ili=1;ili<=2;ili++,isave++)
{ if (ili==1) {pt=lois_internes1;} else {pt=lois_internes2;};
// passage des informations spécifique à la loi liste_des_SaveResul
pt->IndiqueSaveResult(*isave);
pt->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca
pt->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours
pt->CalculGrandeurTravail(ptintmeca,def,temps,dTP,ex_impli
,ex_expli_tdt,ex_umat,exclure_dd_etend,exclure_Q);
};
};
// fonction interne utilisée par les classes dérivées de Loi_comp_abstraite
// pour répercuter les modifications de la température
// ici utiliser pour modifier la température des lois élémentaires
// l'Enum_dure: indique quel est la température courante : 0 t ou tdt
void LoiDesMelangesEnSigma::RepercuteChangeTemperature(Enum_dure temps)
{ lois_internes1->temperature_0 = this->temperature_0;
lois_internes1->temperature_t = this->temperature_t;
lois_internes1->temperature_tdt = this->temperature_tdt;
lois_internes1->dilatation=dilatation;
lois_internes2->temperature_0 = this->temperature_0;
lois_internes2->temperature_t = this->temperature_t;
lois_internes2->temperature_tdt = this->temperature_tdt;
lois_internes2->dilatation=dilatation;
if (dilatation)
{// a- dimensionnement des tenseurs intermédiaires
int dim_tens = epsBB_therm->Dimension();
// -- cas de la déformation
if (lois_internes1->epsBB_therm == NULL) { lois_internes1->epsBB_therm = NevezTenseurBB(dim_tens);}
else if (lois_internes1->epsBB_therm->Dimension() != dim_tens)
{ delete lois_internes1->epsBB_therm;lois_internes1->epsBB_therm = NevezTenseurBB(dim_tens);};
if (lois_internes2->epsBB_therm == NULL) { lois_internes2->epsBB_therm = NevezTenseurBB(dim_tens);}
else if (lois_internes2->epsBB_therm->Dimension() != dim_tens)
{ delete lois_internes2->epsBB_therm;lois_internes2->epsBB_therm = NevezTenseurBB(dim_tens);};
// -- cas de la vitesse de déformation
if (lois_internes1->DepsBB_therm == NULL) { lois_internes1->DepsBB_therm = NevezTenseurBB(dim_tens);}
else if (lois_internes1->DepsBB_therm->Dimension() != dim_tens)
{ delete lois_internes1->DepsBB_therm;lois_internes1->DepsBB_totale = NevezTenseurBB(dim_tens);};
if (lois_internes2->DepsBB_therm == NULL) { lois_internes2->DepsBB_therm = NevezTenseurBB(dim_tens);}
else if (lois_internes2->DepsBB_therm->Dimension() != dim_tens)
{ delete lois_internes2->DepsBB_therm;lois_internes2->DepsBB_totale = NevezTenseurBB(dim_tens);};
// b- affectation des tenseurs
(*lois_internes1->epsBB_therm)=(*epsBB_therm);
(*lois_internes1->DepsBB_therm)=(*DepsBB_therm);
(*lois_internes2->epsBB_therm)=(*epsBB_therm);
(*lois_internes2->DepsBB_therm)=(*DepsBB_therm);
};
lois_internes1->RepercuteChangeTemperature(temps);
lois_internes2->RepercuteChangeTemperature(temps);
switch (temps)
{ case TEMPS_0:
{lois_internes1->temperature = &lois_internes1->temperature_0;
lois_internes2->temperature = &lois_internes2->temperature_0;
break;
}
case TEMPS_t:
{lois_internes1->temperature = &lois_internes1->temperature_t;
lois_internes2->temperature = &lois_internes2->temperature_t;
break;
}
case TEMPS_tdt:
{lois_internes1->temperature = &lois_internes1->temperature_tdt;
lois_internes2->temperature = &lois_internes2->temperature_tdt;
break;
}
default:
{ cout << "\n erreur, cas de temps non prevu !! "
<< "\n LoiDesMelangesEnSigma::RepercuteChangeTemperature(...";
Sortie(1);
};
};
#ifdef MISE_AU_POINT
if (Permet_affichage() > 7)
{ cout << "\n init temperatures:\n "
<< " lois_internes1->temperature_0= " << lois_internes1->temperature_0
<< " lois_internes1->temperature_t= " << lois_internes1->temperature_t
<< " lois_internes1->temperature_tdt= " << lois_internes1->temperature_tdt
<< " lois_internes1->temperature= " << *(lois_internes1->temperature)
<< " lois_internes2->temperature_0= " << lois_internes2->temperature_0
<< " lois_internes2->temperature_t= " << lois_internes2->temperature_t
<< " lois_internes2->temperature_tdt= " << lois_internes2->temperature_tdt
<< " lois_internes2->temperature= " << *(lois_internes2->temperature)
<< " \n LoiDesMelangesEnSigma::RepercuteChangeTemperature(.."
<< endl;
};
#endif
};