Herezh_dev/comportement/hysteresis/Hysteresis3D.cc

3435 lines
186 KiB
C++
Raw Normal View History

2021-09-23 11:21:15 +02:00
// FICHIER : Hysteresis3D.cc
// CLASSE : Hysteresis3D
// 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.
//
2023-05-03 17:23:49 +02:00
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
2021-09-23 11:21:15 +02:00
// 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 <iostream>
using namespace std; //introduces namespace std
#include <math.h>
#include <stdlib.h>
#include "Sortie.h"
#include "ConstMath.h"
#include "MatLapack.h"
#include "ExceptionsLoiComp.h"
#include "MotCle.h"
#include "CharUtil.h"
#include "Hysteresis3D.h"
#include "Enum_TypeQuelconque.h"
#include "TypeQuelconqueParticulier.h"
// $$$$$$$$$$$$$$$$$$$$$ a faire $$$$$$$$$$$$$$$$$
// a priori la sauvegarde de w_base n'est pas nécessaire car c'est un résultat
// mais on ne sans sert pas comme test, et à l'aide des listes on peut savoir si l'on est sur
// une première charge ou non, ce qui donne la valeur de w_base
// ========== fonctions pour la classe de sauvegarde des résultats =========
// constructeur par défaut
Hysteresis3D::SaveResulHysteresis3D::SaveResulHysteresis3D() :
sigma_barre_BH_t(),sigma_barre_BH_tdt(),sigma_barre_BH_R()
,oc_BH_R(),oc_BH_t(),oc_BH_tdt(),fonction_aide_t(0.),fonction_aide_tdt(0.)
,wBase_t(1),wBase_tdt(1)
,def_equi_at(0.),def_equi_atdt(0.)
,ip2(),fct_aide_t_a_tdt(),fct_aide()
,modif(0),sigma_barre_BH_R_t_a_tdt(),nb_coincidence(0)
,oc_BH_t_a_tdt(),def_equi_t_a_tdt(),def_equi()
,sigma_barre_BH_R_atrans(),oc_BH_R_atrans()
,indicateurs_resolution(),indicateurs_resolution_t()
// ,modif_sauve(0),sigma_barre_BH_R_sauve(),nb_ref_new_sauve(0)
// ,nb_coincidence_sauve(0),oc_BH_R_sauve(),nb_centre_new_sauve(0)
// ,def_equi_sauve()
{ // la première valeur de la déformation équivalente est 0
def_equi.push_front(0.);
// la première valeur de la fonction d'aide est l'infini
fct_aide.push_front(ConstMath::tresgrand);
};
// constructeur de copie
Hysteresis3D::SaveResulHysteresis3D::SaveResulHysteresis3D(const SaveResulHysteresis3D& sav):
sigma_barre_BH_t(sav.sigma_barre_BH_t),sigma_barre_BH_tdt(sav.sigma_barre_BH_tdt)
,sigma_barre_BH_R(sav.sigma_barre_BH_R)
,oc_BH_R(sav.oc_BH_R),oc_BH_t(sav.oc_BH_t),oc_BH_tdt(sav.oc_BH_tdt)
,fonction_aide_t(sav.fonction_aide_t),fonction_aide_tdt(sav.fonction_aide_tdt)
,wBase_t(sav.wBase_t),wBase_tdt(sav.wBase_tdt)
,def_equi_at(sav.def_equi_at),def_equi_atdt(sav.def_equi_atdt)
,modif(sav.modif),sigma_barre_BH_R_t_a_tdt(sav.sigma_barre_BH_R_t_a_tdt)
,nb_coincidence(sav.nb_coincidence),oc_BH_t_a_tdt(sav.oc_BH_t_a_tdt)
,def_equi_t_a_tdt(sav.def_equi_t_a_tdt),def_equi(sav.def_equi)
,ip2(),fct_aide_t_a_tdt(sav.fct_aide_t_a_tdt),fct_aide(sav.fct_aide)
,sigma_barre_BH_R_atrans(sav.sigma_barre_BH_R_atrans),oc_BH_R_atrans(sav.oc_BH_R_atrans)
,indicateurs_resolution(sav.indicateurs_resolution),indicateurs_resolution_t(sav.indicateurs_resolution_t)
// ,modif_sauve(sav.modif_sauve),sigma_barre_BH_R_sauve(sav.sigma_barre_BH_R_sauve)
// ,nb_ref_new_sauve(sav.nb_ref_new_sauve),nb_coincidence_sauve(sav.nb_coincidence_sauve)
// ,oc_BH_R_sauve(sav.oc_BH_R_sauve),nb_centre_new_sauve(sav.nb_centre_new_sauve)
// ,def_equi_sauve(sav.def_equi_sauve)
{ if (fct_aide.size() >= 2) // pointage de ip2
{ip2= fct_aide.end(); ip2--;ip2--; }
};
// affectation
Loi_comp_abstraite::SaveResul & Hysteresis3D::SaveResulHysteresis3D::operator = ( const Loi_comp_abstraite::SaveResul & a)
{ Hysteresis3D::SaveResulHysteresis3D& sav = *((Hysteresis3D::SaveResulHysteresis3D*) &a);
// recopie de toutes les grandeurs
oc_BH_t = sav.oc_BH_t;
oc_BH_tdt = sav.oc_BH_tdt;
def_equi_at = sav.def_equi_at;
def_equi_atdt = sav.def_equi_atdt;
oc_BH_t_a_tdt = sav.oc_BH_t_a_tdt;
def_equi_t_a_tdt = sav.def_equi_t_a_tdt;
oc_BH_R = sav.oc_BH_R;
def_equi = sav.def_equi;
sigma_barre_BH_R_atrans = sav.sigma_barre_BH_R_atrans;
oc_BH_R_atrans = sav.oc_BH_R_atrans;
sigma_barre_BH_t = sav.sigma_barre_BH_t;
sigma_barre_BH_tdt = sav.sigma_barre_BH_tdt;
fonction_aide_t = sav.fonction_aide_t;
fonction_aide_tdt = sav.fonction_aide_tdt;
wBase_t = sav.wBase_t;
wBase_tdt = sav.wBase_tdt;
fct_aide = sav.fct_aide;
if (fct_aide.size() >= 2) // pointage de ip2
{ip2= fct_aide.end(); ip2--;ip2--; };
modif = sav.modif;
sigma_barre_BH_R_t_a_tdt = sav.sigma_barre_BH_R_t_a_tdt;
nb_coincidence = sav.nb_coincidence;
fct_aide_t_a_tdt = sav.fct_aide_t_a_tdt;
sigma_barre_BH_R = sav.sigma_barre_BH_R;
indicateurs_resolution = sav.indicateurs_resolution;
indicateurs_resolution_t = sav.indicateurs_resolution_t;
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 Hysteresis3D::SaveResulHysteresis3D::Lecture_base_info (ifstream& ent,const int )
{ // ici toutes les données sont toujours a priori variables
string toto;
ent >> toto >> sigma_barre_BH_t ;sigma_barre_BH_tdt = sigma_barre_BH_t;
ent >> toto >> oc_BH_t; oc_BH_tdt=oc_BH_t;
ent >> toto >> wBase_t; wBase_tdt=wBase_t;
ent >> toto >> def_equi_at >> def_equi_atdt;
ent >> toto >> fonction_aide_t; fonction_aide_tdt=fonction_aide_t;
// ---- lecture liste fonction d'aide
ent >> toto;
#ifdef MISE_AU_POINT
if (toto != "list_fct_aide")
{ cout << "\n erreur dans la lecture de la list_io fonction d'aide, on ne trouve pas le mot cle: list_fct_aide "
<< " on a lu "<< toto
<< " avec auparavent: "
<< "\n fonction_aide_t= "<< fonction_aide_t
<< "\n def_equi_at= "<< def_equi_at
<< "\n def_equi_atdt= "<< def_equi_atdt
<< "\n wBase_t= "<< wBase_t
<< "\n Hysteresis3D::SaveResulHysteresis3D::Lecture_base_info (... ";
Sortie(1);
}
#endif
int taille;ent >> toto >> taille; // lecture de la taille
double un_elem;
// on vide la liste actuelle
fct_aide.clear();
for (int i=1;i<=taille;i++) // puis on lit
{ ent >> un_elem; // lecture
fct_aide.push_back(un_elem); // enregistrement
}
if (fct_aide.size() >= 2) // pointage de ip2
{ip2= fct_aide.end(); ip2--;ip2--; }
// ---- lecture des centre de cercle
ent >> toto;
#ifdef MISE_AU_POINT
if (toto != "list_oc_BH_R")
{ cout << "\n erreur dans la lecture de la list_io de centre, on ne trouve pas le mot cle: list_oc_BH_R "
<< "\n Hysteresis3D::SaveResulHysteresis3D::Lecture_base_info (... ";
Sortie(1);
}
#endif
ent >> toto >> taille; // lecture de la taille de la liste
Tenseur3BH elem;
// on vide la liste actuelle
oc_BH_R.clear();
for (int i=1;i<=taille;i++) // puis on lit
{ ent >> elem; // lecture
oc_BH_R.push_back(elem); // enregistrement
}
// initialisation pour le transport éventuel
oc_BH_R_atrans= oc_BH_R;
ent >> toto; // ---- lecture des points d'inversion
#ifdef MISE_AU_POINT
if (toto != "list_pt_inver")
{ cout << "\n erreur dans la lecture de la list_io: ref contrainte, on ne trouve pas le mot cle: list_pt_inver "
<< "\n Hysteresis3D::SaveResulHysteresis3D::Lecture_base_info (... ";
Sortie(1);
}
#endif
// on vide la listes actuelle et on lit
sigma_barre_BH_R.clear();
ent >> toto >> taille; // lecture de la taille du nombre de point d'inversion
for (int j=1;j<=taille;j++) // puis on lit
{ ent >> elem; // lecture
sigma_barre_BH_R.push_back(elem); // enregistrement
};
// initialisation pour le transport éventuel
sigma_barre_BH_R_atrans = sigma_barre_BH_R;
ent >> toto; // ---- lecture def équivalente
#ifdef MISE_AU_POINT
if (toto != "list_def_equi")
{ cout << "\n erreur dans la lecture de la list_io def equivalente, on ne trouve pas le mot cle: list_def_equi "
<< "\n Hysteresis3D::SaveResulHysteresis3D::Lecture_base_info (... ";
Sortie(1);
}
#endif
int taille_C;ent >> toto >> taille_C; // lecture de la taille
double un_elem_eps;
// on vide la liste actuelle
def_equi.clear();
for (int i=1;i<=taille_C;i++) // puis on lit
{ ent >> un_elem_eps; // lecture
def_equi.push_back(un_elem_eps); // enregistrement
}
//re-initialisation des variables de travail
TversTdt();
// Init_debut_calcul();
};
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables
//(supposées comme telles)
void Hysteresis3D::SaveResulHysteresis3D::Ecriture_base_info(ofstream& sort,const int )
{ // ici toutes les données sont toujours a priori variables
sort << " sigma_barre_BH_t " << sigma_barre_BH_t;
sort << "\n oc_BH_t " << oc_BH_t;
sort << "\n wBase_t " << wBase_t;
sort << "\n def_equi_at_et_tdt " << def_equi_at << " " << def_equi_atdt;
sort << " fct_aide_t " << fonction_aide_t;
// liste des fonctions d'aide
{sort << "\n list_fct_aide " << "taille= " << fct_aide.size() << " ";
List_io <double>::const_iterator iter_courant,iter_fin = fct_aide.end();
for (iter_courant=fct_aide.begin();iter_courant!=iter_fin;iter_courant++)
{ sort << setprecision(ParaGlob::NbdigdoCA()) << (*iter_courant) ; sort << " "; }
}
// listes: centre de cercle et point d'inversion
sort << "\n list_oc_BH_R " << "taille= " << oc_BH_R.size() << " ";
List_io <Tenseur3BH>::const_iterator iter_courant,iter_fin = oc_BH_R.end();
for (iter_courant=oc_BH_R.begin();iter_courant!=iter_fin;iter_courant++)
{ sort << setprecision(ParaGlob::NbdigdoCA()) << (*iter_courant) ; sort << " ";
};
int taille_sigma_barre_BH_R= sigma_barre_BH_R.size();
sort << "\n list_pt_inver " << "taille= " << taille_sigma_barre_BH_R << " ";
List_io <Tenseur3BH>::const_iterator jter_courant,jter_fin = sigma_barre_BH_R.end();
for (jter_courant=sigma_barre_BH_R.begin();jter_courant!=jter_fin;jter_courant++)
{ sort << setprecision(ParaGlob::NbdigdoCA()) << (*jter_courant) ;
sort << " ";
};
// les listes: def équivalente
sort << " list_def_equi " << "taille= " << def_equi.size() << " ";
List_io <double>::const_iterator kter_courant,kter_fin = def_equi.end();
for (kter_courant=def_equi.begin();kter_courant!=kter_fin;kter_courant++)
{ sort << setprecision(ParaGlob::NbdigdoCA()) << (*kter_courant) ; sort << " "; };
};
// mise à jour des informations transitoires
void Hysteresis3D::SaveResulHysteresis3D::TdtversT()
{ // partie générale
sigma_barre_BH_t = sigma_barre_BH_tdt;oc_BH_t=oc_BH_tdt;
wBase_t = wBase_tdt;
def_equi_at = def_equi_atdt; // def équivalente
fonction_aide_t=fonction_aide_tdt;
// partie spécifique
// en fait ici on pourrait simplifier car le cas 3 est toujours valide -> supprime l'utilité
// du paramètre modif !!
// int maxi_ref_en_plus = 0; // indique le maximum de ref que l'on a mis en plus dans la liste
//------- débug ---------
// vérif de la cohérence des centres et références: les rayons associés doivent être de tailles
// décroissantes
// Verif_centre_reference();
//-------- fin débug -----------
// ------- mise en place des modifs ----------
// modif_sauve = modif ; // pour le retour t -> tdt éventuel
// nb_coincidence_sauve = nb_coincidence; // idem
switch (modif)
{ case 0: // rien ne change sur le pas en terme de coincidence et d'inversion
{ break;
}
case 1: // cas où l'on a une ou plusieurs coincidences
{ // a chaque coincidence il faut supprimer 1 pt de ref et un centre de cercle
// sauf si l'on arrive au centre nul ou au point de référence null
List_io <Tenseur3BH>::iterator itens;List_io <Tenseur3BH>::iterator ioc_i;
for (int i=1;i<=nb_coincidence;i++)
{ itens = sigma_barre_BH_R.begin();
if (itens != sigma_barre_BH_R.end()) // si itens == sigma_barre_BH_R.end(), cela signifie
{//sigma_barre_BH_R_sauve.push_back(*itens); // on sauve avant de détruire
sigma_barre_BH_R.erase(itens); // que la référence est le tenseur nulle, on arrête de dépiler
};
ioc_i = oc_BH_R.begin();
if (ioc_i != oc_BH_R.end()) // si ioc_i == oc_BH_R.end(), cela signifie que le centre de référence
{//oc_BH_R_sauve.push_back(*ioc_i); // on sauve avant de détruire
oc_BH_R.erase(ioc_i); // est le tenseur nulle
};
// idem pour les def équivalentes
List_io <double>::iterator idouble;
idouble = def_equi.begin();
if (idouble != def_equi.end()) // si idouble == def_equi.end(), cela signifie que l'on est arrivé
{ //def_equi_sauve.push_back(*idouble); // on sauve avant de détruire
def_equi.erase(idouble); // sur la branche fondamentale
};
// idem pour la fonction d'aide
List_io <double>::iterator ifct;
ifct = fct_aide.begin();
if (ifct != fct_aide.end()) // si ifct == fct_aide.end(), cela signifie que l'on est arrivé
{ //fct_aide_sauve.push_back(*ifct); // on sauve avant de détruire
fct_aide.erase(ifct); // sur la branche fondamentale
};
};
break;
}
case 2: // cas où l'on a une ou plusieurs inversions
{ // on traite les centres différement des points d'inversions
int nb_centre_new = oc_BH_t_a_tdt.size(); // récup du nombre de nouveaux centres
// nb_centre_new_sauve = nb_centre_new; // on sauvegarde pour un retour t -> tdt éventuel
// on ajoute les différents nouveaux centres, en tenant compte du fait que le premier rentrée est
// le dernier dans la liste, d'où l'utilisation de reverse_iterator
List_io <Tenseur3BH>::reverse_iterator iifoi = oc_BH_t_a_tdt.rbegin();
for (int ii=1;ii<=nb_centre_new;ii++,iifoi++)
oc_BH_R.push_front(*iifoi);
// maintenant on traites les points d'inversions
int nb_ref_new = sigma_barre_BH_R_t_a_tdt.size(); // récup du nombre de nouveaux pt
// nb_ref_new_sauve = nb_ref_new; // on sauve pour le retour t -> tdt éventuel
// on ajoute les différents points d'inversions
List_io <Tenseur3BH>::reverse_iterator iitens = sigma_barre_BH_R_t_a_tdt.rbegin();
for (int ii=1;ii<=nb_ref_new;ii++,iitens++)
sigma_barre_BH_R.push_front(*iitens);
// pour les def équivalentes
List_io <double>::reverse_iterator iidouble = def_equi_t_a_tdt.rbegin();
for (int ij=1;ij<=nb_ref_new;ij++,iidouble++)
def_equi.push_front(*iidouble);
// cas de la fonction d'aide
int nb_ref = fct_aide.size(); // récup du nombre de pt de ref actuel
bool init_ip2 = false; if (nb_ref == 1) init_ip2=true; // pour gérer ip2
int nb_fct_new = fct_aide_t_a_tdt.size(); // récup du nombre de nouveau pt
// on ajoute les différentes valeurs
List_io <double>::iterator iifct = fct_aide_t_a_tdt.begin();
for (int ii=1;ii<=nb_ref_new;ii++,iitens++,iifct++)
{fct_aide.push_front(*iifct);
if (init_ip2) // uniquement pour mémoriser le W_a de la première charge
{ // cas où l'on doit initialiser ip2 (car ici le nombre de pt = 2)
ip2 = fct_aide.begin(); init_ip2 = false;
};
};
break;
}
case 3: // cas où l'on a une ou plusieurs coincidence(s) et inversion (s)
{ // les coïncidences sont forcéments au début puis on a les inversions qui sont
// au nombre d'éléments sur la liste secondaire
// a) on commence par traiter les coïncidences
// a chaque coincidence il faut supprimer 1 pt de ref et un centre de cercle
// sauf si l'on arrive au centre nul ou au point de référence null
List_io <Tenseur3BH>::iterator itens;List_io <Tenseur3BH>::iterator ioc_i;
for (int i=1;i<=nb_coincidence;i++)
{ itens = sigma_barre_BH_R.begin();
if (itens != sigma_barre_BH_R.end()) // si itens == sigma_barre_BH_R.end(), cela signifie
{//sigma_barre_BH_R_sauve.push_back(*itens); // on sauve avant de détruire
sigma_barre_BH_R.erase(itens); // que la référence est le tenseur nulle, on arrête de dépiler
};
ioc_i = oc_BH_R.begin();
if (ioc_i != oc_BH_R.end()) // si ioc_i == oc_BH_R.end(), cela signifie que le centre de référence
{//oc_BH_R_sauve.push_back(*ioc_i); // on sauve avant de détruire
oc_BH_R.erase(ioc_i); // est le tenseur nulle
};
// idem pour les def équivalentes
List_io <double>::iterator idouble;
idouble = def_equi.begin();
if (idouble != def_equi.end()) // si idouble == def_equi.end(), cela signifie que l'on est arrivé
{ //def_equi_sauve.push_back(*idouble); // on sauve avant de détruire
def_equi.erase(idouble); // sur la branche fondamentale
}
// idem pour la fonction d'aide
List_io <double>::iterator ifct;
ifct = fct_aide.begin();
if (ifct != fct_aide.end()) // si ifct == fct_aide.end(), cela signifie que l'on est arrivé
{ //fct_aide_sauve.push_back(*ifct); // on sauve avant de détruire
fct_aide.erase(ifct); // sur la branche fondamentale
};
};
// b) maintenant on s'occupe des inversions
// on traite les centres différemment des points d'inversions
int nb_centre_new = oc_BH_t_a_tdt.size(); // récup du nombre de nouveaux centres
// nb_centre_new_sauve = nb_centre_new; // on sauvegarde pour un retour t -> tdt éventuel
// on ajoute les différents nouveaux centres
List_io <Tenseur3BH>::reverse_iterator iifoi = oc_BH_t_a_tdt.rbegin();
for (int ii=1;ii<=nb_centre_new;ii++,iifoi++)
oc_BH_R.push_front(*iifoi);
// maintenant on traites les points d'inversions
int nb_ref_new = sigma_barre_BH_R_t_a_tdt.size(); // récup du nombre de nouveaux pt
// nb_ref_new_sauve = nb_ref_new; // on sauve pour le retour t -> tdt éventuel
// on ajoute les différents points d'inversions
List_io <Tenseur3BH>::reverse_iterator iitens = sigma_barre_BH_R_t_a_tdt.rbegin();
for (int ii=1;ii<=nb_ref_new;ii++,iitens++)
sigma_barre_BH_R.push_front(*iitens);
// pour les def équivalentes
List_io <double>::reverse_iterator iidouble = def_equi_t_a_tdt.rbegin();
for (int ij=1;ij<=nb_ref_new;ij++,iidouble++)
def_equi.push_front(*iidouble);
// cas de la fonction d'aide
int nb_ref = fct_aide.size(); // récup du nombre de pt de ref actuel
bool init_ip2 = false; if (nb_ref == 1) init_ip2=true; // pour gérer ip2
int nb_fct_new = fct_aide_t_a_tdt.size(); // récup du nombre de nouveau pt
// on ajoute les différentes valeurs
List_io <double>::iterator iifct = fct_aide_t_a_tdt.begin();
for (int ii=1;ii<=nb_ref_new;ii++,iitens++,iifct++)
{fct_aide.push_front(*iifct);
if (init_ip2) // uniquement pour mémoriser le W_a de la première charge
{ // cas où l'on doit initialiser ip2 (car ici le nombre de pt = 2)
ip2 = fct_aide.begin(); init_ip2 = false;
};
};
break;
}
default:
cout << "\n erreur dans la mise a jour des informations transitoire: modif= " << modif
<< "\n Hysteresis3D::SaveResulHysteresis3D::TversTdt() ";
Sortie(1);
}
// --------------------- très important: traitement de finition --------------------------
// si les rayons résultants que l'on a ajoute sont à une distance inférieure à la précision de la coincidence
// on les collapses !!
// finalement on va traiter directement au niveau des coincidences pour l'instant !!
// if (maxi_ref_en_plus != 0)
// {
// }
//------- débug ---------
// vérif de la cohérence des centres et références: les rayons associés doivent être de tailles
// décroissantes
// Verif_centre_reference(6);
//-------- fin débug -----------
// on sauve les grandeurs transportables
sigma_barre_BH_R_atrans = sigma_barre_BH_R;
oc_BH_R_atrans= oc_BH_R;
// on met à jour éventuellement les indicateurs de résolution
if (indicateurs_resolution.Taille())
{ indicateurs_resolution_t = indicateurs_resolution;
// on met les indicateurs à 0
indicateurs_resolution.Change_taille(5,0.);
};
//re-initialisation des variables de travail
Init_debut_calcul();
};
void Hysteresis3D::SaveResulHysteresis3D::TversTdt()
{ // partie générale
sigma_barre_BH_tdt = sigma_barre_BH_t;oc_BH_tdt=oc_BH_t;
wBase_tdt=wBase_t;
def_equi_atdt = def_equi_at; // def équivalente
// on supprime le transport éventuel
sigma_barre_BH_R = sigma_barre_BH_R_atrans;
oc_BH_R = oc_BH_R_atrans;
fonction_aide_tdt=fonction_aide_t;
// en fait le tant que le pas n'est pas validé, les différentes listes ne sont pas changées
// donc il n'y a pas à mettre en place une stratégie pour revenir en arrière
// une fois que le pas est validé, effectivement on ne peut pas revenir en arrière, mais
// c'est aussi vrai pour toutes les autres lois
// ceci étant la suite serait une solution pour revenir en arrière
// // maintenant on essaie de remettre les choses d'aplomb
// switch (modif_sauve)
// { case 0: // rien n'a changé sur le pas en terme de coincidence et d'inversion
// { break; // donc rien n'a faire !! ouf
// }
// case 1: // cas où l'on a eu une ou plusieurs coincidences
// { // ici il suffit de rajouter tous les tenseurs qui ont été supprimés
// List_io <Tenseur3BH>::iterator itens;List_io <Tenseur3BH>::iterator ioc_i;
// {List_io <Tenseur3BH>::iterator itens_fin=sigma_barre_BH_R_sauve.end();
// for (itens = sigma_barre_BH_R_sauve.begin(); itens != itens_fin;itens++)
// sigma_barre_BH_R.push_front(*itens);
// };
// {List_io <Tenseur3BH>::iterator itens_fin=oc_BH_R_sauve.end();
// for (itens = oc_BH_R_sauve.begin(); itens != itens_fin;itens++)
// oc_BH_R.push_front(*itens);
// };
// {List_io <double>::iterator idouble,idouble_fin= def_equi_sauve.end();
// for (idouble = def_equi_sauve.begin(); idouble != idouble_fin;idouble++)
// def_equi.push_front(*idouble);
// };
// // puis on supprime les sauvegardes histoire de ne pas rajouter une nouvelle fois
// sigma_barre_BH_R.clear();oc_BH_R_sauve.clear();def_equi_sauve.clear();
// break;
// }
// case 2: // cas où l'on a eu une ou plusieurs inversions
// { // pour les centres on en a rajouté nb_centre_new_sauve, on les supprimes
// List_io <Tenseur3BH>::iterator ioc_i;
// for (int i=1; i<= nb_centre_new_sauve;i++)
// { ioc_i = oc_BH_R.begin();
// oc_BH_R.erase(ioc_i);
// };
// // maintenant on traites les points d'inversions, même chose que les centres on supprime
// List_io <Tenseur3BH>::iterator iitens;
// for (int i=1; i<= nb_ref_new_sauve;i++)
// { iitens = sigma_barre_BH_R.begin();
// sigma_barre_BH_R.erase(iitens);
// };
// // pour les def équivalentes, même chose
// List_io <double>::iterator iidouble;
// for (int i=1; i<= nb_ref_new_sauve;i++)
// { iidouble = def_equi.begin();
// def_equi.erase(iidouble);
// };
// // on supprime les compteurs pour éviter une autre suppression future
// nb_centre_new_sauve=0;nb_ref_new_sauve=0;
// break;
// }
// case 3: // cas où l'on a eu une ou plusieurs coincidence(s) et inversion (s)
// { // on traite dans l'ordre inverse du cas tdt -> t
// // -- a) on s'occupe des inversions
// // pour les centres on en a rajouté nb_centre_new_sauve, on les supprimes
// {List_io <Tenseur3BH>::iterator ioc_i;
// for (int i=1; i<= nb_centre_new_sauve;i++)
// { ioc_i = oc_BH_R.begin();
// oc_BH_R.erase(ioc_i);
// };
// // maintenant on traites les points d'inversions, même chose que les centres on supprime
// List_io <Tenseur3BH>::iterator iitens;
// for (int i=1; i<= nb_ref_new_sauve;i++)
// { iitens = sigma_barre_BH_R.begin();
// sigma_barre_BH_R.erase(iitens);
// };
// // pour les def équivalentes, même chose
// List_io <double>::iterator iidouble;
// for (int i=1; i<= nb_ref_new_sauve;i++)
// { iidouble = def_equi.begin();
// def_equi.erase(iidouble);
// };
// // on supprime les compteurs pour éviter une autre suppression future
// nb_centre_new_sauve=0;nb_ref_new_sauve=0;
// };
// // -- b) on s'occupe des coincidences
// // ici il suffit de rajouter tous les tenseurs qui ont été supprimés
// {List_io <Tenseur3BH>::iterator itens;List_io <Tenseur3BH>::iterator ioc_i;
// {List_io <Tenseur3BH>::iterator itens_fin=sigma_barre_BH_R_sauve.end();
// for (itens = sigma_barre_BH_R_sauve.begin(); itens != itens_fin;itens++)
// sigma_barre_BH_R.push_front(*itens);
// };
// {List_io <Tenseur3BH>::iterator itens_fin=oc_BH_R_sauve.end();
// for (itens = oc_BH_R_sauve.begin(); itens != itens_fin;itens++)
// oc_BH_R.push_front(*itens);
// };
// {List_io <double>::iterator idouble,idouble_fin= def_equi_sauve.end();
// for (idouble = def_equi_sauve.begin(); idouble != idouble_fin;idouble++)
// def_equi.push_front(*idouble);
// };
// // puis on supprime les sauvegardes histoire de ne pas rajouter une nouvelle fois
// sigma_barre_BH_R.clear();oc_BH_R_sauve.clear();def_equi_sauve.clear();
// };
// break;
// }
// default:
// cout << "\n erreur dans la mise a jour des informations transitoire: modif= " << modif
// << "\n Hysteresis3D::SaveResulHysteresis3D::TversTdt() ";
// Sortie(1);
// };
//re-initialisation des variables de travail
Init_debut_calcul();
};
// affichage à l'écran des infos
void Hysteresis3D::SaveResulHysteresis3D::Affiche() const
{ cout << "\n SaveResulHysteresis3D: " ;
cout << "\n sigma_barre_BH_t= " << sigma_barre_BH_t << " sigma_barre_BH_tdt= " << sigma_barre_BH_tdt
<< " oc_BH_t= " << oc_BH_t << " oc_BH_tdt= " << oc_BH_tdt
<< " wBase_t= " << wBase_t << " wBase_tdt= " << wBase_tdt
<< " def_equi_at= " << def_equi_at << " def_equi_atdt= " << def_equi_atdt
<< " fonction_aide_t= " << fonction_aide_t << " fonction_aide_tdt= " << fonction_aide_tdt;
cout << "\n -- info de travail en cours: ";
cout << " modif= " << modif << "\n list sigma_barre_BH_R_t_a_tdt: " << sigma_barre_BH_R_t_a_tdt
<< "\n nb_coincidence= " << nb_coincidence
<< "\n list oc_BH_t_a_tdt: " << oc_BH_t_a_tdt
<< "\n list def_equi_t_a_tdt: " << def_equi_t_a_tdt;
cout << "\n -- memorisation discrete de 0 a t: ";
cout << "\n list sigma_barre_BH_R: " << sigma_barre_BH_R;
cout << "\n list oc_BH_R: " << oc_BH_R;
cout << "\n list def_equi: " << def_equi;
cout << "\n list fct_aide: " << fct_aide << " ";
cout << "\n .. fin SaveResulHysteresis3D ... ";
};
//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 Hysteresis3D::SaveResulHysteresis3D::ChBase_des_grandeurs(const Mat_pleine& beta,const Mat_pleine& gamma)
{ // on ne s'intéresse qu'aux grandeurs tensorielles
sigma_barre_BH_t.ChBase(beta,gamma);
sigma_barre_BH_tdt.ChBase(beta,gamma);
oc_BH_t.ChBase(beta,gamma);
oc_BH_tdt.ChBase(beta,gamma);
// encapsulage pour utiliser deux fois les mêmes itérators
{ List_io <Tenseur3BH>::iterator lit(sigma_barre_BH_R_t_a_tdt.begin()),
lend(sigma_barre_BH_R_t_a_tdt.end());
for(;lit!=lend;++lit) // ici les bornes ne changent pas
(*lit).ChBase(beta,gamma);
};
{ List_io <Tenseur3BH>::iterator lit(oc_BH_t_a_tdt.begin()),
lend(oc_BH_t_a_tdt.end());
for(;lit!=lend;++lit) // ici les bornes ne changent pas
(*lit).ChBase(beta,gamma);
};
{ List_io <Tenseur3BH>::iterator lit(sigma_barre_BH_R.begin()),
lend(sigma_barre_BH_R.end());
for(;lit!=lend;++lit) // ici les bornes ne changent pas
(*lit).ChBase(beta,gamma);
};
{ List_io <Tenseur3BH>::iterator lit(oc_BH_R.begin()),
lend(oc_BH_R.end());
for(;lit!=lend;++lit) // ici les bornes ne changent pas
(*lit).ChBase(beta,gamma);
};
{ List_io <Tenseur3BH>::iterator lit(sigma_barre_BH_R_atrans.begin()),
lend(sigma_barre_BH_R_atrans.end());
for(;lit!=lend;++lit) // ici les bornes ne changent pas
(*lit).ChBase(beta,gamma);
};
{ List_io <Tenseur3BH>::iterator lit(oc_BH_R_atrans.begin()),
lend(oc_BH_R_atrans.end());
for(;lit!=lend;++lit) // ici les bornes ne changent pas
(*lit).ChBase(beta,gamma);
};
};
// initialise les informations de travail concernant le pas de temps en cours
void Hysteresis3D::SaveResulHysteresis3D::Init_debut_calcul()
{ //initialisation des variables de travail
modif = 0; nb_coincidence=0;
sigma_barre_BH_R_t_a_tdt.clear();oc_BH_t_a_tdt.clear();def_equi_t_a_tdt.clear();
fct_aide_t_a_tdt.clear();
//---- debug
// cout << "\n Hysteresis3D::SaveResulHysteresis3D::Init_debut_calcul() "<< endl;
//---- fin debug
};
///----------***** fin de l'introduction de la fonction d'aide
// ========== fin des fonctions pour la classe de sauvegarde des résultats =========
Hysteresis3D::Hysteresis3D () : // Constructeur par defaut
Loi_comp_abstraite(HYSTERESIS_3D,CAT_MECANIQUE,3)
// ---- para matériau
,xnp(ConstMath::tresgrand),xnp_temperature(NULL),xnp_lue(ConstMath::tresgrand)
,Qzero(ConstMath::tresgrand),Qzero_temperature(NULL),Qzero_lue(ConstMath::tresgrand)
,xmu(ConstMath::tresgrand),xmu_temperature(NULL),xmu_lue(ConstMath::tresgrand)
// parmètres de phase éventuelles
,xnp_phase(NULL),Qzero_defEqui(NULL),xnp_defEqui(NULL),Qzero_phase(NULL),xmu_phase(NULL)
,avec_phaseDeltaSig(false),avec_phaseEps(NULL)
,avec_defEqui(false),avec_phase_paradefEqui(false),coef_paradefEqui(NULL)
,val_coef_paradefEqui(1.),mini_QepsilonBH(1.e-4)
,type_de_transport_memorisation(0)
,niveau_bascule_fct_aide(10.) //volontairement très grand => ne sert pas
// --- réglage résolution de l'équation constitutive
,tolerance_coincidence(),mini_rayon(ConstMath::pasmalpetit)
,tolerance_centre(0.001)
,min_angle_trajet_neutre(0.008),possibilite_cosAlphaNegatif(true) // environ 90° - 0.5°
,mini_Qsig_pour_phase_sigma_Oi_tdt(1.5) // 1.5 MPa
,type_resolution_equa_constitutive(1)
,type_calcul_comportement_tangent(1),avecVarWprimeS(false)
,nb_maxInvCoinSurUnPas(4),force_phi_zero_si_negatif(0.)
,depassement_Q0(2.)
// ---- réglage résolution avec linéarisation
,tolerance_residu(1.e-3),tolerance_residu_rel(1.e-5),nb_boucle_maxi(6),nb_dichotomie(4)
,maxi_delta_var_sig_sur_iter_pour_Newton(-1)
// ---- réglage résolution avec Kutta
,cas_kutta(5),erreurAbsolue(1.e-3),erreurRelative(1.e-5),nbMaxiAppel(1000)
// ---- affichage
,sortie_post(0)
// ---- init variable de travail
,sigma_t_barre_tdt(),sigma_i_barre_BH(),sigma_barre_BH_R()
,def_equi_R(0.),def_i_equi(0.),def_equi_atdt(0.),defEqui_maxi(0.)
,delta_sigma_barre_BH_Rat(),delta_sigma_barre_BH_Ra_i(),delta_sigma_barre_BH_Ratdt()
,delta_sigma_barre_tdt_BH(),residuBH()
,delta_epsBH(),delta_barre_epsBH(),delta_barre_alpha_epsBH()
,wBase(1),wprime(1),wprime_point(0.),trajet_neutre(false),d_wprime(),d_wprime_point()
,residu(9),derResidu(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT)
,derResidu_adefConstant(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT)
,alg_zero(),alg_edp()
,rdelta_sigma_barre_BH_Ratdt(),rdelta_sigma_barre_tdt_BH()
,sig_point(9),sigma_pointBH(),sigma_tauBH(),sigma_tau(9)
,delta_sigma_barre_R_a_tauBH(),delta_sigma_barre_t_a_tauBH()
,betaphideltasigHB(),deuxmudeltaepsHB()
,sig_initiale(9),dersig_initiale(9),sig_finale(9),dersig_finale(9),estime_erreur(9)
,val_initiale(9),racine(9)
,der_at_racine(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT)
,centre_initial(true),aucun_pt_inversion(true)
,dRdsigMoinsun(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT)
,dRdeps(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT)
,MPC(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT)
,dsig_ojef_HHHH()
,matriceH(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT)
,matriceM(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT)
,matHmoinsun(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT)
,calcul_dResi_dsig(false)
{// initialisation des paramètres de la résolution de newton
alg_zero.Modif_prec_res_abs(tolerance_residu);
alg_zero.Modif_prec_res_rel(tolerance_residu_rel);
alg_zero.Modif_iter_max(nb_boucle_maxi);
alg_zero.Modif_nbMaxiIncre(nb_dichotomie);
tolerance_coincidence = tolerance_residu * 100;
tolerance_centre = tolerance_coincidence;
// idem avec kutta
alg_edp.Modif_nbMaxiAppel(nbMaxiAppel);
};
// Constructeur de copie
Hysteresis3D::Hysteresis3D (const Hysteresis3D& loi) :
Loi_comp_abstraite(loi)
// ---- para matériau
,xnp(loi.xnp),xmu(loi.xmu),Qzero(loi.Qzero)
,xnp_lue(loi.xnp_lue),xmu_lue(loi.xmu_lue),Qzero_lue(loi.Qzero_lue)
,xnp_temperature(loi.xnp_temperature),Qzero_temperature(loi.Qzero_temperature)
,xmu_temperature(loi.xmu_temperature)
// paramètres de phase éventuelles
,xnp_phase(loi.xnp_phase),Qzero_defEqui(loi.Qzero_defEqui)
,xnp_defEqui(loi.xnp_defEqui),Qzero_phase(loi.Qzero_phase),xmu_phase(loi.xmu_phase)
,avec_phaseDeltaSig(loi.avec_phaseDeltaSig),avec_phaseEps(loi.avec_phaseEps)
,avec_defEqui(loi.avec_defEqui)
,avec_phase_paradefEqui(loi.avec_phase_paradefEqui),coef_paradefEqui(loi.coef_paradefEqui)
,val_coef_paradefEqui(1.),mini_QepsilonBH(loi.mini_QepsilonBH)
,type_de_transport_memorisation(loi.type_de_transport_memorisation)
,niveau_bascule_fct_aide(loi.niveau_bascule_fct_aide)
// --- réglage résolution de l'équation constitutive
,tolerance_coincidence(loi.tolerance_coincidence),mini_rayon(loi.mini_rayon)
,tolerance_centre(loi.tolerance_centre)
,min_angle_trajet_neutre(loi.min_angle_trajet_neutre) // environ 90° - 0.5°
,possibilite_cosAlphaNegatif(loi.possibilite_cosAlphaNegatif)
,mini_Qsig_pour_phase_sigma_Oi_tdt(loi.mini_Qsig_pour_phase_sigma_Oi_tdt)
,type_resolution_equa_constitutive(loi.type_resolution_equa_constitutive)
,type_calcul_comportement_tangent(loi.type_calcul_comportement_tangent),avecVarWprimeS(loi.avecVarWprimeS)
,nb_maxInvCoinSurUnPas(loi.nb_maxInvCoinSurUnPas),force_phi_zero_si_negatif(loi.force_phi_zero_si_negatif)
,depassement_Q0(loi.depassement_Q0)
// ---- réglage résolution avec linéarisation
,tolerance_residu(loi.tolerance_residu),tolerance_residu_rel(loi.tolerance_residu_rel)
,nb_boucle_maxi(loi.nb_boucle_maxi),nb_dichotomie(loi.nb_dichotomie)
,maxi_delta_var_sig_sur_iter_pour_Newton(loi.maxi_delta_var_sig_sur_iter_pour_Newton)
// ---- réglage résolution avec Kutta
,cas_kutta(loi.cas_kutta),erreurAbsolue(loi.erreurAbsolue),erreurRelative(loi.erreurRelative)
,nbMaxiAppel(loi.nbMaxiAppel)
// ---- affichage
,sortie_post(loi.sortie_post)
// ---- intit variable de travail
,sigma_t_barre_tdt(loi.sigma_t_barre_tdt),sigma_i_barre_BH(loi.sigma_i_barre_BH)
,sigma_barre_BH_R(loi.sigma_barre_BH_R)
,def_equi_R(loi.def_equi_R),def_i_equi(loi.def_i_equi),def_equi_atdt(loi.def_equi_atdt)
,defEqui_maxi(loi.defEqui_maxi)
,delta_sigma_barre_BH_Rat(loi.delta_sigma_barre_BH_Rat)
,delta_sigma_barre_BH_Ra_i(loi.delta_sigma_barre_BH_Ra_i)
,delta_sigma_barre_BH_Ratdt(loi.delta_sigma_barre_BH_Ratdt)
,delta_sigma_barre_tdt_BH(loi.delta_sigma_barre_tdt_BH)
,residuBH(loi.residuBH),delta_epsBH(loi.delta_epsBH)
,delta_barre_epsBH(loi.delta_barre_epsBH)
,delta_barre_alpha_epsBH(loi.delta_barre_alpha_epsBH)
,wBase(loi.wBase),wprime(loi.wprime),trajet_neutre(loi.trajet_neutre),wprime_point(loi.wprime_point)
,d_wprime(loi.d_wprime),d_wprime_point(loi.d_wprime_point)
,residu(9),derResidu(loi.derResidu),derResidu_adefConstant(loi.derResidu_adefConstant),alg_zero(),alg_edp()
,rdelta_sigma_barre_BH_Ratdt(),rdelta_sigma_barre_tdt_BH()
,centre_initial(true),aucun_pt_inversion(true)
,dRdsigMoinsun(loi.dRdsigMoinsun),dRdeps(loi.dRdeps),MPC(loi.MPC)
,dsig_ojef_HHHH()
,matriceH(loi.matriceH), matriceM(loi.matriceM),matHmoinsun(loi.matHmoinsun)
,calcul_dResi_dsig(false)
,sig_point(9),sigma_pointBH(),sigma_tauBH(),sigma_tau(9)
,delta_sigma_barre_R_a_tauBH(),delta_sigma_barre_t_a_tauBH()
,betaphideltasigHB(),deuxmudeltaepsHB()
,sig_initiale(9),dersig_initiale(9),sig_finale(9),dersig_finale(9),estime_erreur(9)
,val_initiale(9),racine(9)
,der_at_racine(9,9,false,0.,GAUSS,RIEN_PRECONDITIONNEMENT)
{// initialisation des paramètres de la résolution de newton
alg_zero.Modif_prec_res_abs(tolerance_residu);
alg_zero.Modif_prec_res_rel(tolerance_residu_rel);
alg_zero.Modif_iter_max(nb_boucle_maxi);
alg_zero.Modif_nbMaxiIncre(nb_dichotomie);
// idem avec kutta
alg_edp.Modif_nbMaxiAppel(nbMaxiAppel);
// pour les pointeurs de courbes, on regarde s'il s'agit d'une courbe locale ou d'une courbe globale
if (xnp_temperature != NULL)
if (xnp_temperature->NomCourbe() == "_")
xnp_temperature = Courbe1D::New_Courbe1D(*(loi.xnp_temperature));
if (Qzero_temperature != NULL)
if (Qzero_temperature->NomCourbe() == "_")
Qzero_temperature = Courbe1D::New_Courbe1D(*(loi.Qzero_temperature));
if (xmu_temperature != NULL)
if (xmu_temperature->NomCourbe() == "_")
xmu_temperature = Courbe1D::New_Courbe1D(*(loi.xmu_temperature));
// pour la phase
if (xnp_phase != NULL)
if (xnp_phase->NomCourbe() == "_")
xnp_phase = Courbe1D::New_Courbe1D(*(loi.xnp_phase));
if (Qzero_phase != NULL)
if (Qzero_phase->NomCourbe() == "_")
Qzero_phase = Courbe1D::New_Courbe1D(*(loi.Qzero_phase));
if (xmu_phase != NULL)
if (xmu_phase->NomCourbe() == "_")
xmu_phase = Courbe1D::New_Courbe1D(*(loi.xmu_phase));
// pour la dépendance à la déformation équivalente
if (xnp_defEqui != NULL)
if (xnp_defEqui->NomCourbe() == "_")
xnp_defEqui = Courbe1D::New_Courbe1D(*(loi.xnp_defEqui));
// pour la dépendance à la déformation équivalente
if (Qzero_defEqui != NULL)
if (Qzero_defEqui->NomCourbe() == "_")
Qzero_defEqui = Courbe1D::New_Courbe1D(*(loi.Qzero_defEqui));
// pour la dépendance à la déformation totale
if (coef_paradefEqui != NULL)
if (coef_paradefEqui->NomCourbe() == "_")
coef_paradefEqui = Courbe1D::New_Courbe1D(*(loi.coef_paradefEqui));
};
Hysteresis3D::~Hysteresis3D ()
// Destructeur
{ if (xnp_temperature != NULL)
if (xnp_temperature->NomCourbe() == "_") delete xnp_temperature;
if (Qzero_temperature != NULL)
if (Qzero_temperature->NomCourbe() == "_") delete Qzero_temperature;
if (xmu_temperature != NULL)
if (xmu_temperature->NomCourbe() == "_") delete xmu_temperature;
if (xnp_phase != NULL)
if (xnp_phase->NomCourbe() == "_") delete xnp_phase;
if (xnp_defEqui != NULL)
if (xnp_defEqui->NomCourbe() == "_") delete xnp_defEqui;
if (Qzero_defEqui != NULL)
if (Qzero_defEqui->NomCourbe() == "_") delete Qzero_defEqui;
if (Qzero_phase != NULL)
if (Qzero_phase->NomCourbe() == "_") delete Qzero_phase;
if (xmu_phase != NULL)
if (xmu_phase->NomCourbe() == "_") delete xmu_phase;
if (coef_paradefEqui != NULL)
if (coef_paradefEqui->NomCourbe() == "_") delete coef_paradefEqui;
};
// Lecture des donnees de la classe sur fichier
void Hysteresis3D::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D
,LesFonctions_nD& lesFonctionsnD)
{ // ---- lecture du paramètre de prager -----
string nom;
*(entreePrinc->entree) >> nom; // lecture d'un identificateur
if(nom != "np=")
{ cout << "\n erreur en lecture du parametre de prager "
<< " on attendait la chaine : np= et on a lue " << nom;
cout << "\n Hysteresis3D::LectureDonneesParticulieres "
<< "(UtilLecture * entreePrinc) " << endl ;
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// on regarde si le paramètre de prager est thermo dépendant
if(strstr(entreePrinc->tablcar,"np_thermo_dependant_")!=0)
{ thermo_dependant=true;
*(entreePrinc->entree) >> nom;
if (nom != "np_thermo_dependant_")
{ cout << "\n erreur en lecture de la thermodependance de np, on aurait du lire le mot cle np_thermo_dependant_"
<< " suivi du nom d'une courbe de charge ou de la courbe elle meme "<< endl;
entreePrinc->MessageBuffer("**erreur2 Hysteresis3D::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
// lecture de la loi d'évolution du paramètre de prager en fonction de la température
*(entreePrinc->entree) >> nom;
// on regarde si la courbe existe, si oui on récupère la référence
if (lesCourbes1D.Existe(nom))
{ xnp_temperature = lesCourbes1D.Trouve(nom);
}
else
{ // sinon il faut la lire maintenant
string non_courbe("_");
xnp_temperature = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
// lecture de la courbe
xnp_temperature->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
}
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
}
else // sinon on lit directement le paramètre de prager
{*(entreePrinc->entree) >> xnp;
if (xnp <= 0)
{cout << "\n erreur en lecture du parametre de prager np= " << xnp
<< " il doit etre superieur a 0 ! ";
cout << "\n Hysteresis3D::LectureDonneesParticulieres "
<< "(UtilLecture * entreePrinc) " << endl ;
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
};
// ---- lecture de mu : coefficient de lame ----
*(entreePrinc->entree) >> nom;
if(nom != "mu=")
{ cout << "\n erreur en lecture du coefficient mu de lame "
<< " on attendait la chaine : mu= et on a lue " << nom;
cout << "\n Hysteresis3D::LectureDonneesParticulieres "
<< "(UtilLecture * entreePrinc) " << endl ;
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
// on regarde si le coefficient de lame est thermo dépendant
if(strstr(entreePrinc->tablcar,"mu_thermo_dependant_")!=0)
{ thermo_dependant=true;
*(entreePrinc->entree) >> nom;
if (nom != "mu_thermo_dependant_")
{ cout << "\n erreur en lecture de la thermodependance de mu, on aurait du lire le mot cle mu_thermo_dependant_"
<< " suivi du nom d'une courbe de charge ou de la courbe elle meme ";
entreePrinc->MessageBuffer("**erreur3 Hysteresis3D::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
// lecture de la loi d'évolution du coefficient mu en fonction de la température
*(entreePrinc->entree) >> nom;
// on regarde si la courbe existe, si oui on récupère la référence
if (lesCourbes1D.Existe(nom))
{ xmu_temperature = lesCourbes1D.Trouve(nom);
}
else
{ // sinon il faut la lire maintenant
string non_courbe("_");
xmu_temperature = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
// lecture de la courbe
xmu_temperature->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
}
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
}
else // sinon on lit directement le paramètre mu
{*(entreePrinc->entree) >> xmu;};
// ---- lecture de la limite de plasticité infini -----
*(entreePrinc->entree) >> nom;
if(nom != "Qzero=")
{ cout << "\n erreur en lecture du coefficient mu de lame "
<< " on attendait la chaine : Qzero= et on a lue " << nom;
cout << "\n Hysteresis3D::LectureDonneesParticulieres "
<< "(UtilLecture * entreePrinc) " << endl ;
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
// on regarde si Qzero est thermo dépendant
if(strstr(entreePrinc->tablcar,"Qzero_thermo_dependant_")!=0)
{ thermo_dependant=true;
*(entreePrinc->entree) >> nom;
if (nom != "Qzero_thermo_dependant_")
{ cout << "\n erreur en lecture de la thermodependance de Qzero, on aurait du lire le mot cle Qzero_thermo_dependant_"
<< " suivi du nom d'une courbe de charge ou de la courbe elle meme ";
entreePrinc->MessageBuffer("**erreur4 Hysteresis3D::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
// lecture de la loi d'évolution du coefficient Qzero en fonction de la température
*(entreePrinc->entree) >> nom;
// on regarde si la courbe existe, si oui on récupère la référence
if (lesCourbes1D.Existe(nom))
{ Qzero_temperature = lesCourbes1D.Trouve(nom);
}
else
{ // sinon il faut la lire maintenant
string non_courbe("_");
Qzero_temperature = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
// lecture de la courbe
Qzero_temperature->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
}
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
}
else // sinon on lit directement le paramètre Qzero
{*(entreePrinc->entree) >> Qzero;};
// on garde en mémoire ce que l'on a lue
xnp_lue=xnp; Qzero_lue=Qzero; xmu_lue=xmu;
// --- lecture éventuelle d'une dépendance à la phase
if ((strstr(entreePrinc->tablcar,"avec_phaseDeltaSig")!=NULL)
|| (strstr(entreePrinc->tablcar,"avec_phaseEps")!=NULL))
{ string nom1,nom2;
int drapeau=0; // une variable intermédiaire
if (strstr(entreePrinc->tablcar,"avec_phaseDeltaSig")!=NULL) {drapeau=1;}
else { drapeau=2; }; // on oriente le type de dépendance (contrainte ou def)
// lecture des paramètres de phase
entreePrinc->NouvelleDonnee(); // passage d'une ligne
// cas de np
if (strstr(entreePrinc->tablcar,"xnp_phase=")!=NULL)
{drapeau +=10; // petite ope pour valider que l'on a bien lue qqchose
*(entreePrinc->entree) >> nom;
if (nom != "xnp_phase=")
{ cout << "\n erreur en lecture de la dependance a la phase de xnp, on aurait du lire"
<< " le mot cle xnp_phase="
<< " suivi du nom d'une courbe de charge ou de la courbe elle meme ";
entreePrinc->MessageBuffer("**erreur41 Hysteresis3D::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
// lecture de la loi d'évolution du coefficient xnp en fonction de la phase
*(entreePrinc->entree) >> nom;
// on regarde si la courbe existe, si oui on récupère la référence
if (lesCourbes1D.Existe(nom))
{ xnp_phase = lesCourbes1D.Trouve(nom);
}
else
{ // sinon il faut la lire maintenant
string non_courbe("_");
xnp_phase = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
// lecture de la courbe
xnp_phase->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
}
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
};
// cas de xmu
if (strstr(entreePrinc->tablcar,"xmu_phase=")!=NULL)
{drapeau +=10; // petite ope pour valider que l'on a bien lue qqchose
*(entreePrinc->entree) >> nom;
if (nom != "xmu_phase=")
{ cout << "\n erreur en lecture de la dependance a la phase de xmu, on aurait du lire"
<< " le mot cle xmu_phase="
<< " suivi du nom d'une courbe de charge ou de la courbe elle meme ";
entreePrinc->MessageBuffer("**erreur42 Hysteresis3D::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
// lecture de la loi d'évolution du coefficient xmu en fonction de la phase
*(entreePrinc->entree) >> nom;
// on regarde si la courbe existe, si oui on récupère la référence
if (lesCourbes1D.Existe(nom))
{ xmu_phase = lesCourbes1D.Trouve(nom);
}
else
{ // sinon il faut la lire maintenant
string non_courbe("_");
xmu_phase = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
// lecture de la courbe
xmu_phase->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
}
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
};
// cas de Qzero
if (strstr(entreePrinc->tablcar,"Qzero_phase=")!=NULL)
{drapeau +=10; // petite ope pour valider que l'on a bien lue qqchose
*(entreePrinc->entree) >> nom;
if (nom != "Qzero_phase=")
{ cout << "\n erreur en lecture de la dependance a la phase de Qzero, on aurait du lire"
<< " le mot cle Qzero_phase="
<< " suivi du nom d'une courbe de charge ou de la courbe elle meme ";
entreePrinc->MessageBuffer("**erreur43 Hysteresis3D::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
// lecture de la loi d'évolution du coefficient Qzero en fonction de la phase
*(entreePrinc->entree) >> nom;
// on regarde si la courbe existe, si oui on récupère la référence
if (lesCourbes1D.Existe(nom))
{ Qzero_phase = lesCourbes1D.Trouve(nom);
}
else
{ // sinon il faut la lire maintenant
string non_courbe("_");
Qzero_phase = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
// lecture de la courbe
Qzero_phase->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
}
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
};
// fin de la manip avec le drapeau
// si drapeau > 10 cela veut dire qu'il y a eu au moins une validation
// le reste de la division euclidienne = la valeur initiale
if ((drapeau % 10) == 1) {avec_phaseDeltaSig = true; avec_phaseEps = false; }
else if ((drapeau % 10) == 2) {avec_phaseDeltaSig = false; avec_phaseEps = true; }
else
// sinon, malgré la dépendance à la phase il n'y a aucun paramètre lue
// donc on désactive
{avec_phaseDeltaSig = false; avec_phaseEps = false; };
};
// --- lecture éventuelle d'une dépendance à la déformation équivalente
if (strstr(entreePrinc->tablcar,"avec_defEquivalente")!=NULL)
{ string nom1,nom2;
// lecture des de dépendance
entreePrinc->NouvelleDonnee(); // passage d'une ligne
// cas de np
if (strstr(entreePrinc->tablcar,"xnp_defEqui=")!=NULL)
{avec_defEqui=true;
*(entreePrinc->entree) >> nom;
if (nom != "xnp_defEqui=")
{ cout << "\n erreur en lecture de la dependance a la deformation equivalente de xnp, on aurait du lire"
<< " le mot cle xnp_defEqui="
<< " suivi du nom d'une courbe de charge ou de la courbe elle meme ";
entreePrinc->MessageBuffer("**erreur44 Hysteresis3D::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
// lecture de la loi d'évolution du coefficient xnp en fonction de def Equi
*(entreePrinc->entree) >> nom;
// on regarde si la courbe existe, si oui on récupère la référence
if (lesCourbes1D.Existe(nom))
{ xnp_defEqui = lesCourbes1D.Trouve(nom);
}
else
{ // sinon il faut la lire maintenant
string non_courbe("_");
xnp_defEqui = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
// lecture de la courbe
xnp_defEqui->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
}
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
}
else { xnp_defEqui=NULL;};
// cas de Qzero
if (strstr(entreePrinc->tablcar,"Qzero_defEqui=")!=NULL)
{avec_defEqui=true;
*(entreePrinc->entree) >> nom;
if (nom != "Qzero_defEqui=")
{ cout << "\n erreur en lecture de la dependance a la deformation equivalente de Qzero, on aurait du lire"
<< " le mot cle Qzero_defEqui="
<< " suivi du nom d'une courbe de charge ou de la courbe elle meme ";
entreePrinc->MessageBuffer("**erreur44 Hysteresis3D::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
// lecture de la loi d'évolution du coefficient Qzero en fonction de def Equi
*(entreePrinc->entree) >> nom;
// on regarde si la courbe existe, si oui on récupère la référence
if (lesCourbes1D.Existe(nom))
{ Qzero_defEqui = lesCourbes1D.Trouve(nom);
}
else
{ // sinon il faut la lire maintenant
string non_courbe("_");
Qzero_defEqui = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
// lecture de la courbe
Qzero_defEqui->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
}
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
}
else {Qzero_defEqui = NULL;} ;
};
// --- lecture éventuelle d'une dépendance à la phase de la déformation
if (strstr(entreePrinc->tablcar,"avec_phase_paradefEqui")!=NULL)
{ string nom1,nom2;
// pour l'instant ne fonctionne qu'avec la dépendance conjointe à la def équivalente
if (!avec_defEqui)
{ cout << "\n erreur la dependance a la phase de la deformation n'est licite que "
<< " conjointement avec la dependance la deformation equivalente de xnp qui n'est pas ici"
<< " activee on s'arrete donc !! ";
entreePrinc->MessageBuffer("**erreur444 Hysteresis3D::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// lecture des de dépendance
entreePrinc->NouvelleDonnee(); // passage d'une ligne
// lecture de la fonction
if (strstr(entreePrinc->tablcar,"coef_paradefEqui=")!=NULL)
{avec_phase_paradefEqui=true;
*(entreePrinc->entree) >> nom;
if (nom != "coef_paradefEqui=")
{ cout << "\n erreur en lecture de la dependance a la phase de la deformation totale, "
<< " on aurait du lire le mot cle coef_paradefEqui="
<< " suivi du nom d'une courbe de charge ou de la courbe elle meme ";
entreePrinc->MessageBuffer("**erreur445 Hysteresis3D::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
// lecture de la loi d'évolution du paradefEqui en fonction de cos(3phi) de la déformation totale
*(entreePrinc->entree) >> nom;
// on regarde si la courbe existe, si oui on récupère la référence
if (lesCourbes1D.Existe(nom))
{ coef_paradefEqui = lesCourbes1D.Trouve(nom);
}
else
{ // sinon il faut la lire maintenant
string non_courbe("_");
coef_paradefEqui = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
// lecture de la courbe
coef_paradefEqui->LectDonnParticulieres_courbes (non_courbe,entreePrinc);
}
entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
}
else
{ cout << "\n erreur en lecture de la dependance a la phase de la deformation totale, "
<< " on devrait avoir sur la ligne courante le mot cle coef_paradefEqui="
<< " suivi du nom d'une courbe de charge ou de la courbe elle meme ";
entreePrinc->MessageBuffer("**erreur446 Hysteresis3D::LectureDonneesParticulieres (...**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
};
// --- lecture éventuelle des paramètres de réglage ----
// de l'algo de résolution de l'équation d'avancement temporel
if(strstr(entreePrinc->tablcar,"avec_parametres_de_reglage_")!=0)
{type_resolution_equa_constitutive = 0; // valeur voulant dire qu'il n'y a pas eu de lecture
entreePrinc->NouvelleDonnee(); // on se positionne sur un nouvel enreg
// on lit tant que l'on ne rencontre pas la ligne contenant "fin_parametres_reglage_Hysteresis_"
// ou un nouveau mot clé global auquel cas il y a pb !!
MotCle motCle; // ref aux mots cle
while (strstr(entreePrinc->tablcar,"fin_parametres_reglage_Hysteresis_")==0)
{
// si on a un mot clé global dans la ligne courante c-a-d dans tablcar --> erreur
if ( motCle.SimotCle(entreePrinc->tablcar))
{ cout << "\n erreur de lecture des parametre de reglage d'hysteresis: on n'a pas trouve le mot cle "
<< " fin_parametres_reglage_Hysteresis_ et par contre la ligne courante contient un mot cle global ";
entreePrinc->MessageBuffer("** erreur5 des parametres de reglage de la loi de comportement d'hyteresis**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// lecture d'un mot clé
*(entreePrinc->entree) >> nom;
if ((entreePrinc->entree)->rdstate() == 0)
{} // lecture normale
#ifdef ENLINUX
else if ((entreePrinc->entree)->fail())
// on a atteind la fin de la ligne et on appelle un nouvel enregistrement
{ entreePrinc->NouvelleDonnee(); // lecture d'un nouvelle enregistrement
*(entreePrinc->entree) >>nom;
}
#else
else if ((entreePrinc->entree)->eof())
// la lecture est bonne mais on a atteind la fin de la ligne
{ if(nom != "fin_parametres_reglage_Hysteresis_")
{entreePrinc->NouvelleDonnee(); *(entreePrinc->entree) >> nom;};
}
#endif
else // cas d'une erreur de lecture
{ cout << "\n erreur de lecture inconnue ";
entreePrinc->MessageBuffer("** erreur5 des parametres de reglage de la loi de comportement d'hyteresis**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// cas du type de résolution
if(nom == "type_de_resolution_")
{*(entreePrinc->entree) >> type_resolution_equa_constitutive;
if ((type_resolution_equa_constitutive < 1) || (type_resolution_equa_constitutive> 6)) // 6 valeur exploratoire
{ cout << "\n erreur en lecture du type de resolution, on attendait un nombre compris entre 1 et 6 "
<< " et on a lu : " << type_resolution_equa_constitutive << " ce cas n'est pas implante (cf. doc) "
<< "\n Hysteresis3D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ;
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
}
// type de calcul de la matrice tangente
else if (nom == "type_calcul_comportement_tangent_")
{*(entreePrinc->entree) >> type_calcul_comportement_tangent;
if ((type_calcul_comportement_tangent < 1) || (type_calcul_comportement_tangent> 2))
{ cout << "\n erreur en lecture du type de calcul du comportement tangent,"
<< " on attendait un nombre compris entre 1 et 2 "
<< " et on a lu : " << type_calcul_comportement_tangent << " ce cas n'est pas implante (cf. doc) "
<< "\n Hysteresis3D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ;
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
}
// nombre d'itération maxi
else if (nom == "nb_iteration_maxi_")
{*(entreePrinc->entree) >> nb_boucle_maxi;
alg_zero.Modif_iter_max(nb_boucle_maxi);
}
// nombre de dichotomie maxi
else if (nom == "nb_dichotomie_maxi_")
{*(entreePrinc->entree) >> nb_dichotomie;
alg_zero.Modif_nbMaxiIncre(nb_dichotomie);
}
// tolérance absolue sur le résidu
else if (nom == "tolerance_residu_")
{*(entreePrinc->entree) >> tolerance_residu;
alg_zero.Modif_prec_res_abs(tolerance_residu);
}
// tolérance relative sur le résidu
else if (nom == "tolerance_residu_rel_")
{*(entreePrinc->entree) >> tolerance_residu_rel;
alg_zero.Modif_prec_res_rel(tolerance_residu_rel);
}
// le maxi de variation que l'on tolère d'une itération à l'autre
else if (nom == "maxi_delta_var_sig_sur_iter_pour_Newton_")
{ *(entreePrinc->entree) >> maxi_delta_var_sig_sur_iter_pour_Newton;
}
// type d'algo de kutta
else if (nom == "cas_kutta_")
{*(entreePrinc->entree) >> cas_kutta;
}
// l'erreur absolue
else if (nom == "erreurAbsolue_")
{*(entreePrinc->entree) >> erreurAbsolue;
}
// l'erreur relative
else if (nom == "erreurRelative_")
{*(entreePrinc->entree) >> erreurRelative;
}
// le nombre d'appel maxi de la fonction f
else if (nom == "nbMaxiAppel_")
{*(entreePrinc->entree) >> nbMaxiAppel;
alg_edp.Modif_nbMaxiAppel(nbMaxiAppel);
}
// tolérance sur la coïncidence
else if (nom == "tolerance_coincidence_")
{*(entreePrinc->entree) >> tolerance_coincidence;
}
// tolérance sur le calcul de centre
else if (nom == "tolerance_centre_")
{*(entreePrinc->entree) >> tolerance_centre;
}
// minimun du rayon
else if (nom == "mini_rayon_")
{*(entreePrinc->entree) >> mini_rayon;
}
// nombre maxi d'inversion sur le pas
else if (nom == "nb_maxInvCoinSurUnPas_")
{*(entreePrinc->entree) >> nb_maxInvCoinSurUnPas;
}
else if (nom == "force_phi_zero_si_negatif_")
{*(entreePrinc->entree) >> force_phi_zero_si_negatif;
}
else if (nom == "depassement_Q0_")
{*(entreePrinc->entree) >> depassement_Q0;
}
else if (nom == "type_de_transport_memorisation_")
{*(entreePrinc->entree) >> type_de_transport_memorisation;
}
else if (nom == "niveau_bascule_fct_aide_")
{*(entreePrinc->entree) >> niveau_bascule_fct_aide;
}
// l'angle mini pour les trajets neutre
else if (nom == "min_angle_trajet_neutre_")
{*(entreePrinc->entree) >> min_angle_trajet_neutre;
if ((min_angle_trajet_neutre < 0.) || (min_angle_trajet_neutre > 1.))
{ cout << "\n erreur en lecture sur le l'angle mini pour les trajets neutre, "
<< "\n il doit etre compris entre 0 et 1 on a lu : " << min_angle_trajet_neutre
<< "\n Hysteresis3D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ;
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
}
// possibilité ou non d'accepter transitoirement un cosAlpha négatif
else if (nom == "possibilite_cosAlphaNegatif_")
{*(entreePrinc->entree) >> possibilite_cosAlphaNegatif;
}
else if (nom == "mini_Qsig_pour_phase_sigma_Oi_tdt_")
{*(entreePrinc->entree) >> mini_Qsig_pour_phase_sigma_Oi_tdt;
// if (mini_Qsig_pour_phase_sigma_Oi_tdt < 0.)
// { cout << "\n erreur en lecture sur mini_Qsig_pour_phase_sigma_Oi_tdt, "
// << "\n il doit etre positif on a lu : " << mini_Qsig_pour_phase_sigma_Oi_tdt
// << "\n Hysteresis3D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ;
// throw (UtilLecture::ErrNouvelleDonnee(-1));
// Sortie(1);
// };
}
else if (nom == "mini_QepsilonBH_")
{*(entreePrinc->entree) >> mini_QepsilonBH;
// if (mini_QepsilonBH < 0.)
// { cout << "\n erreur en lecture sur mini_QepsilonBH, "
// << "\n il doit etre positif on a lu : " << mini_QepsilonBH
// << "\n Hysteresis3D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ;
// throw (UtilLecture::ErrNouvelleDonnee(-1));
// Sortie(1);
// };
}
// prise en compte des variations de w' et w'point dans le calcul de l'évolution tangente
else if (nom == "avecVarWprimeS_")
{*(entreePrinc->entree) >> avecVarWprimeS;
}
// forcer un affichage particulier pour les méthodes
else if (nom == "permet_affichage_")
{Lecture_permet_affichage(entreePrinc,lesFonctionsnD);
alg_edp.Change_niveau_affichage(Permet_affichage());
}
// forcer un stockage des indicateurs de la résolution
else if (nom == "sortie_post_")
{*(entreePrinc->entree) >> sortie_post;
}
// sinon ce n'est pas un mot clé connu, on le signale
else if(nom != "fin_parametres_reglage_Hysteresis_")
{ cout << "\n erreur en lecture d'un parametre, le mot cle est inconnu "
<< " on a lu : " << nom << endl;
if (ParaGlob::NiveauImpression()>3)
cout << "\n Hysteresis3D::LectureDonneesParticulieres(UtilLecture * entreePrinc) " << endl ;
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
}; //-- fin du while
}; //-- fin de la lecture des paramètres de réglage
// traitement de certains paramètres non initialisés
if (type_calcul_comportement_tangent == 0)
{ // == 0 signifie qu'il n'y a pas eu de lecture, on met donc les valeurs cohérentes par défaut
if (type_resolution_equa_constitutive == 1) {type_calcul_comportement_tangent = 1;}
else {type_calcul_comportement_tangent = 2;};
};
// le niveau d'affichage
alg_zero.Modif_affichage(Permet_affichage());
// appel au niveau de la classe mère
Loi_comp_abstraite::Lecture_type_deformation_et_niveau_commentaire
(*entreePrinc,lesFonctionsnD);
};
// affichage de la loi
void Hysteresis3D::Affiche() const
{ cout << " \n loi_de_comportement d'hysteresis3D " ;
if ( xnp_temperature != NULL) { cout << " np thermo dependant "
<< " courbe np=f(T): " << xnp_temperature->NomCourbe() <<" ";}
else { cout << " np= " << xnp_lue ;};
if ( Qzero_temperature != NULL) { cout << " Qzero thermo dependant "
<< " courbe np=f(T): " << Qzero_temperature->NomCourbe() <<" ";}
else { cout << " Qzero= " << Qzero_lue ;};
if ( xmu_temperature != NULL) { cout << " xmu thermo dependant "
<< " courbe xmu=f(T): " << xmu_temperature->NomCourbe() <<" ";}
else { cout << " mu= " << xmu_lue ;};
// -- éventuellement dépendance à la phase
if (avec_phaseDeltaSig || avec_phaseEps)
{if (avec_phaseDeltaSig ) { cout << " \n dependance a la phase de Delta_R^t_sigma ";}
else { cout << " \n dependance a la phase de la deformation ";};
if (xnp_phase != NULL) { cout << " np dependant de la phase "
<< " courbe np=f(3cos(phi)): " << xnp_phase->NomCourbe() <<" ";};
if (Qzero_phase != NULL) { cout << " Qzero dependant de la phase "
<< " courbe Qzero=f(3cos(phi)): " << Qzero_phase->NomCourbe() <<" ";};
if (xmu_phase != NULL) { cout << " xmu dependant de la phase "
<< " courbe xmu=f(3cos(phi)): " << xmu_phase->NomCourbe() <<" ";};
};
// -- éventuellement dépendance à la defEqui
if (avec_defEqui)
{if (xnp_defEqui != NULL) { cout << " np dependant de la deformation equivalente "
<< " courbe np=f(3cos(phi)): " << xnp_defEqui->NomCourbe() <<" ";};
if (Qzero_defEqui != NULL) { cout << " Qzero dependant de la deformation equivalente "
<< " courbe np=f(3cos(phi)): " << Qzero_defEqui->NomCourbe() <<" ";};
};
// -- éventuellement dépendance à la phase de la déformation totale
if (avec_phase_paradefEqui)
{if (coef_paradefEqui != NULL) { cout << " dependance a la phase de la deformation totale "
<< " courbe coef_paradefEqui=f(3cos(phi)): " << coef_paradefEqui->NomCourbe() <<" ";};
};
// --- paramètre de réglage
cout << "\n type_resolution_equa_constitutive " << type_resolution_equa_constitutive
<< " type_calcul_comportement_tangent " << type_calcul_comportement_tangent;
if (type_resolution_equa_constitutive == 1)
{ cout << " \n type de resolution: linearisation, nbmax iteration= " << nb_boucle_maxi
<< " nbmax_dichotonmie= " << nb_dichotomie
<< " tolerance_residu_absolue= " << tolerance_residu
<< " tolerance_residu_relative= " << tolerance_residu_rel
<< " maxi_delta_var_sig_sur_iter_pour_Newton= " << maxi_delta_var_sig_sur_iter_pour_Newton;
}
else //if ((type_resolution_equa_constitutive == 2) || (type_resolution_equa_constitutive == 3))
{ cout << " \n type de resolution: Runge_Kutta " << cas_kutta << " erreurAbsolue " << erreurAbsolue
<< " erreurRelative= " << erreurRelative ;
};
cout << " tolerance_coincidence= " << tolerance_coincidence << " mini_rayon " << mini_rayon
<< " tolerance_centre= " << tolerance_centre
<< " nb_maxInvCoinSurUnPas= " << nb_maxInvCoinSurUnPas
<< " min_angle_trajet_neutre= " << min_angle_trajet_neutre
<< " possibilite_cosAlphaNegatif= " << possibilite_cosAlphaNegatif
<< " mini_Qsig_pour_phase_sigma_Oi_tdt= " << mini_Qsig_pour_phase_sigma_Oi_tdt
<< " mini_QepsilonBH= " << mini_QepsilonBH
<< " force_phi_zero_si_negatif= " << force_phi_zero_si_negatif << " "
<< " depassement_Q0= " << depassement_Q0
<< " type_de_transport_memorisation= "<< type_de_transport_memorisation
<< " niveau_bascule_fct_aide= "<< niveau_bascule_fct_aide;
// niveau d'affichage
Affiche_niveau_affichage();
cout << " sortie_post "<< sortie_post
<< " ";
// appel de la classe mère
Loi_comp_abstraite::Affiche_don_classe_abstraite();
};
// affichage et definition interactive des commandes particulières à chaques lois
void Hysteresis3D::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");
Qzero = 200.; xnp = 1.; xmu = 1000; // init à des exemples de valeurs
if ((rep != "o") && (rep != "O" ) && (rep != "0") )
{ sort << "\n#-------------------------------------------------------------------------"
<< "\n# ....... loi_de_comportement d'hysteresis 3D ........ |"
<< "\n# para de prager : mu : limite maxi de plasticite |"
<< "\n#-------------------------------------------------------------------------"
<< "\n np= " << setprecision(6) << xnp << " mu= " << setprecision(6) << xmu
<< " Qzero= "<< setprecision(6) << Qzero
<< "\n# il est possible de definir des parametres thermo-dependants (1 ou 2 ou 3 parametres)"
<< "\n# par exemple pour les trois parametres on ecrit: "
<< "\n#-----------------------------------"
<< "\n# np= np_thermo_dependant_ courbe1 "
<< "\n# mu= mu_thermo_dependant_ courbe4 "
<< "\n# Qzero= Qzero_thermo_dependant_ courbe3 "
<< "\n#-----------------------------------"
<< "\n# noter qu'apres la definition de chaque courbe, on change de ligne, d'une maniere inverse "
<< "\n# si la valeur du parametre est fixe, on poursuit sur la meme ligne. "
<< "\n# par exemple supposons np fixe, mu et Qzero thermo-dependant, on ecrit: "
<< "\n#-----------------------------------"
<< "\n# np= 2. mu= mu_thermo_dependant_ courbe4 "
<< "\n# Qzero= Qzero_thermo_dependant_ courbe3 "
<< "\n#-----------------------------------"
<< "\n# il est egalement possible de definir une dependance a la phase des parametres "
<< "\n# deux possibilites: soit une dependance a la phase du delta deviateur de contrainte "
<< "\n# entre le centre instantane et sa valeur a tdt"
<< "\n# soit une dependance a la phase a la phase de la deformation totale. "
<< "\n# Dans ce cas, a la suite du parametre Qzero on met le mot cle: avec_phaseDeltaSig ou avec_phaseDeltaSig"
<< "\n# puis sur la ligne qui suit on met les fonctions de controle de la dependance "
<< "\n# suit un exemple de declaration (il est possible d'ommettre une fonction "
<< "\n# mais il faut respecter l'ordre ). Comme pour toutes les courbes on peut soit mettre directement"
<< "\n# la courbe, soit mettre un nom de courbe. Ne pas oublier de passer a la ligne apres chaque courbe "
<< "\n# np= 1 mu= 4000 Qzero= 80 avec_phaseDeltaSig "
<< "\n# xnp_phase= courbe_xnp_phase "
<< "\n# xmu_phase= courbe_xmu_phase "
<< "\n# Qzero_phase= courbe_Qzero_phase "
<< "\n# "
<< "\n#-----------------------------------"
<< "\n# il est egalement possible de definir une dependance a la deformation equivalente (cf. doc)"
<< "\n# il s'agit ici d'une grandeur qui mesure une mesure de def equivalente a un trajet radial pur. "
<< "\n# Il s'agit :"
<< "\n# 1) d'une dependance du parametre de prager sous la forme suivante:"
<< "\n# xp = f(eps_equi * Q_deltaSigma_R_tdt * para) tel que para = (2*Qzero^2/(w'*mu). "
<< "\n# 2) d'une dependance de la saturation Qzero sous la forme suivante:"
<< "\n# Qzero = f(eps_equi) * Qzero "
<< "\n# Dans ce cas, a la suite du parametre Qzero (ou des parametres de phase et du type de transport ) "
<< "\n# on met le mot cle: avec_defEqui . "
<< "\n# puis sur la ligne qui suit on met la fonctions de controle de la dependance pour xnp et/ou pour Qzero. "
<< "\n# on peut mettre l'une ou l'autre ou les deux "
<< "\n# suit un exemple de declaration. Comme pour toutes les courbes on peut soit mettre directement"
<< "\n# la courbe, soit mettre un nom de courbe. Ne pas oublier de passer a la ligne apres chaque courbe "
<< "\n# np= 1 mu= 4000 Qzero= 80 avec_defEqui "
<< "\n# xnp_phase= courbe_xnp_defEqui Qzero_phase= courbe_Qzero_defEqui"
<< "\n# "
<< "\n#-----------------------------------"
<< "\n# il est egalement possible de definir une dependance a la phase de la deformation totale"
<< "\n# (cf. doc) pour para = (2*Qzero^2/(w'*mu) . Il s'agit d'une fonction multiplicatrice de para"
<< "\n# Cette dependance s'utilise donc conjointement avec la dependance a la deformation equivalente "
<< "\n# Dans le cas d'une dependance, a la suite de la dependance a la deformation equivalente "
<< "\n# on met le mot cle: avec_phase_paradefEqui . "
<< "\n# puis sur la ligne qui suit on met la fonctions de controle de la dependance. "
<< "\n# suit un exemple de declaration. Comme pour toutes les courbes on peut soit mettre directement"
<< "\n# la courbe, soit mettre un nom de courbe. Ne pas oublier de passer a la ligne apres chaque courbe "
<< "\n# np= 1 mu= 4000 Qzero= 80 avec_defEqui "
<< "\n# xnp_phase= courbe_xnp_defEqui "
<< "\n# avec_phase_paradefEqui "
<< "\n# coef_paradefEqui= courbe_coef_paradefEqui "
<< "\n# "
<< "\n#-----------------------------------"
<< "\n# il est egalement possible (mais pas obligatoire) de definir les parametres de reglage "
<< "\n# de la resolution. Dans ce cas, a la suite de la limite maxi de plasticite (si l'on est sans phase) "
<< "\n# ou sur la ligne qui suit le dernier parametre de phase on indique le mot cle: avec_parametres_de_reglage_ "
<< "\n# ensuite on defini (dans un ordre quelconque) les parametres que l'on souhaites "
<< "\n# chaque parametre est precede d'un mot cle, on a donc une succession de mot cle suivi d'une grandeur "
<< "\n# on peut avoir un ou plusieur couple parametre-grandeur sur chaque ligne "
<< "\n# par contre la derniere ligne doit comporter uniquement le mot cle: "
<< "\n# fin_parametres_reglage_Hysteresis_ "
<< "\n# les differents parametres sont: "
<< "\n# - le type de resolution: par linearisation(1) (valeur par defaut) ou integration directe via Runge_Kutta(2)"
<< "\n# s'il n'y a pas convergence avec (1) arret et generation d'une exception, avec 2, on bascule sur (1) et "
<< "\n# s'il n'y a pas de nouveau convergence on bascule sur un appel directe de kutta"
<< "\n# type (3) = idem que type (2) mais s'il n'y a pas convergence arret et genration d'une exception"
<< "\n# type (4) = idem que type (2) mais s'il n'y a pas convergence bascule sur la linearisation, et s'il n'y"
<< "\n# a pas convergence arret et generation d'une exception"
<< "\n# ex: type_de_resolution_ 2 "
<< "\n# - le nombre d'iteration (pour (1)) ex: nb_iteration_maxi_ 20 "
<< "\n# - le nombre de dichotomie(pour (1)) ex: nb_dichotomie_maxi_ 20 "
<< "\n# - la tolerance absolue sur le residu(pour (1)) ex: tolerance_residu_ 1.e-3 "
<< "\n# - la tolerance relative sur le residu(pour (1)) ex: tolerance_residu_rel_ 1.e-3 "
<< "\n# signifie que la precision sera tolerance_residu_ + ||sig_tdt|| * tolerance_residu_rel_"
<< "\n# la norme maximale du delta sigma qui est permise a chaque iteration de Newton "
<< "\n# par defaut = -1 , si on veut une autre valeur: exe: "
<< "\n# maxi_delta_var_sig_sur_iter_pour_Newton_ 2 # donc 2 MPa a chaque iter "
<< "\n# si on donne une valeur negative (val par defaut), il n'y a pas de limite "
<< "\n# "
// << "\n# si la valeur est negative il s'agit d'une presicion relative: exe -1.e-3 "
// << "\n# signifie que la precision sera max (0.001*||sig_tdt||,0.001) "
<< "\n# - le type de Runge_kutta (pour (2)): 3 pour une methode imbriquee 2-3, 4 pour 3-4, 5 pour 4-5, "
<< "\n# ex: cas_kutta_ 5 "
<< "\n# - l'erreur absolue sur la contrainte finale(pour (2)) ex: erreurAbsolue_ 1.e-3"
<< "\n# - l'erreur relative sur la contrainte finale(pour (2)) ex: erreurRelative_ 1.e-5"
<< "\n# - le nombre maxi d'appel de la fonction derivee (sigma_point) (pour (2)) ex: nbMaxiAppel_ 100"
<< "\n# "
<< "\n# - la tolerance sur la detection des coincidences ex: tolerance_coincidence_ 1.e-3"
<< "\n# si le nombre indique est negatif, cela signifie que la tolerance sera relative a la valeur "
<< "\n# de la norme de la contrainte de reference: exe -0.1 signifie que la tolerance sera "
<< "\n# max (0.1*||sig_R||,0.1) "
<< "\n# "
<< "\n# - la tolerance sur le calcul des hyper-centres de trajet neutre ex: tolerance_centre_ 1.e-3"
<< "\n# si le nombre indique est negatif, cela signifie que la tolerance sera relative a la valeur "
<< "\n# de la norme de la contrainte de reference: exe -0.1 signifie que la tolerance sera "
<< "\n# max (0.1*||sig_R||,0.1) "
<< "\n# "
<< "\n# -le mini en dessous duquel on considere delta_O_R et delta_R_Stdt nul ex: mini_rayon_ 1. e-8"
<< "\n# Meme comportement que pour mini_Qsig_pour_phase_sigma_Oi_tdt_, dans le cas ou mini_rayon est negatif"
<< "\n# ce parametre devient un parametre de regularisation "
<< "\n# "
<< "\n# -le maxi d'inversion ou de coincidence que l'on tolere sur un pas "
<< "\n# dans le cas ou ce maxi est un nombre negatif, on utilise sa valeur absolue et lorsque le maxi "
<< "\n# depasse ce nombre, on retient la valeur final de la contrainte, sinon cas normal: on genere une erreur "
<< "\n# ex nb_maxInvCoinSurUnPas_ -20"
<< "\n# "
<< "\n# - min_angle_trajet_neutre : indique le minimun du cos de l'angle en dessous duquel le trajet est neutre "
<< "\n# ex min_angle_trajet_neutre_ 0.008"
<< "\n# "
<< "\n# - possibilite_cosAlphaNegatif : indique si oui (diff de 0) on non (0) on accepte transitoirement une valeur "
<< "\n# de cosAlpha negative: ex: possibilite_cosAlphaNegatif_ 0 , si c'est non, c'est traite comme un cas neutre "
<< "\n# "
<< "\n#------------- mini_Qsig_pour_phase_sigma_Oi_tdt_ ------------------"
<< "\n# - mini_Qsig_pour_phase_sigma_Oi_tdt : indique le minimum de Qsig en dessous duquel on "
<< "\n# considere que la phase pour delta sigma de Oi a tdt, est nulle "
<< "\n# ex mini_Qsig_pour_phase_sigma_Oi_tdt_ 1.5 "
<< "\n# Dans le cas ou mini_Qsig_pour_phase_sigma_Oi_tdt_ est negatif, cela devient un parametre de regularisation "
<< "\n# Qsig est alors transforme en (Qsig-mini_Qsig_pour_phase_sigma_Oi_tdt) au niveau des divisions qui servent "
<< "\n# a calculer la phase. Dans ce cas l'angle de phase est toujours calculable, par contre pour les faibles "
<< "\n# valeur de Qsig, on peut avoir angle errone, mais ce n'est peut-etre pas un pb "
<< "\n# "
<< "\n#------------- mini_QepsilonBH_ ------------------"
<< "\n# - mini_QepsilonBH : indique le minimum de QepsilonBH en dessous duquel on "
<< "\n# considere que la phase pour la deformation totale, est nulle "
<< "\n# ex mini_QepsilonBH_ 1.e-4 "
<< "\n# Meme comportement que pour mini_Qsig_pour_phase_sigma_Oi_tdt_, dans le cas ou mini_QepsilonBH est negatif"
<< "\n# ce parametre devient un parametre de regularisation "
<< "\n# "
<< "\n#------------- force_phi_zero_si_negatif_ ------------------"
<< "\n# - au niveau de l'equation constitutive, phi doit-etre toujours positif, cependant pendant le processus "
<< "\n# de convergence il peut etre transitoirement negatif: on peut neanmoins forcer phi a etre toujours >= 0 "
<< "\n# avec le parametre : force_phi_zero_si_negatif_ "
<< "\n# Par defaut => force_phi_zero_si_negatif_ = 0. : on ne force pas la mise a 0"
<< "\n# si : force_phi_zero_si_negatif_ x , avec x diff de 0 : on force la mise a 0 "
<< "\n# si phi devient negatif et |phi| < x "
<< "\n#------------- type de transport ------------------"
<< "\n# - il est egalement possible de preciser un type de transport des grandeurs memorises "
<< "\n# (cf. doc) "
<< "\n# Dans ce cas, on met le mot cle: type_de_transport_memorisation_ suivi d'un entier signe 'i' "
<< "\n# i = 0 : transport historique en mixte (valeur par defaut pour l'instant) "
<< "\n# i = -1 : transport incremental ( a la fin de chaque increment) de maniere coherente avec "
<< "\n# la derivee de Jauman "
<< "\n#--------------- utilisation de la fonction d'aide -----------------"
<< "\n# "
<< "\n# - l'algorithme de gestion de la memorisation discrete s'effectue soit via le rayon des "
<< "\n# hypersphere representant les tenseurs OiSigma_tdt ceci pour de faibles rayons, "
<< "\n# soit via une fonction d'aide pour des rayons importants. Le passage entre ces deux modes "
<< "\n# de gestion s'effectue en fonction du parametre niveau_bascule_fct_aide_ qui est compris entre 0 et 1"
<< "\n# ex: niveau_bascule_fct_aide_ 0.5 # signifie que l'on bascule pour un rayon superieur a 50% "
<< "\n# # du rayon maxi "
<< "\n# "
<< "\n# "
<< "\n#-------------- limitation de l'intensite du deviateur ------------------"
<< "\n# "
<< "\n# - normalement l'intensite du deviateur des contraintes Qsig doit etre inferieure a la saturation Q_0 "
<< "\n# le parametre depassement_Q0 donne la valeur toleree de depassement, au-dessus de laquelle "
<< "\n# la contrainte n'est plus recevable "
<< "\n# ex: depassement_Q0_ 1.2 # signifie que l'on tolere 20% de deplacement"
<< "\n# "
<< "\n# "
<< "\n# -------------- calcul du comportement tangent ---------"
<< "\n# - Pour le type de resolution par linearisation, le comportement tangent est calcule par une methode coherente"
<< "\n# differente du cas de type de resolution par Kutta. Il est possible d'indiquer explicitement "
<< "\n# le type de calcul du comportement tangent: deux cas possibles, soit en utilisant l'equation linearise "
<< "\n# (cas = 1), soit en utilisant l'equation exacte sans linearisation (cas 2) "
<< "\n# Pour cela, par exemple apres la definition du cas de resolution , on indique le mot cle"
<< "\n# type_calcul_comportement_tangent_ suivi du cas : 1 ou 2 "
<< "\n# ex type_calcul_comportement_tangent_ 2"
<< "\n# Il est possible de tenir compte ou pas de la variation de l'angle de phase et de sa derivee danse le "
<< "\n# calcul du comportement tangent. Par defaut, il n'y a pas de prise en compte de ces variations. Pour "
<< "\n# en tenir compte il faut mettre le mot cle avecVarWprimeS_ suivi de 1 (0 etant la valeur par defaut) "
<< "\n# ex avecVarWprimeS_ 1"
<< "\n# "
<< "\n# -------------- affichage des erreurs et des warning ---------- "
<< "\n# - l'affichage normale est fonction du parametre global d'affichage gerer par le niveau d'affichage"
<< "\n# cependant pour des raisons par exemple de mise au point, il est possible de permettre l'affichage "
<< "\n# a un niveau particulier (mot cle : permet_affichage_ suivi d'un nombre entier) en plus de l'affichage normal. "
<< "\n# l'affichage s'effectuera donc en fonction de l'affichage normale et de l'affichage particulier."
<< "\n# Le fonctionnement de l'affichage particulier suit les mêmes règles que l'affichage globale"
<< "\n# soit permet_affichage_ est nulle (cas par defaut), dans ce cas l'affichage est fonction du niveau global"
<< "\n# soit permet_affichage_ vaut n par exemple, dans ce cas l'affichage est fonction uniquement de n "
<< "\n# "
<< "\n# ex: permet_affichage_ 5 "
<< "\n# --------------- acces aux indicateurs de la resolution par -------"
<< "\n# A chaque resolution, il est possible de stocker les indicateurs: nombre d'iteration, d'increment "
<< "\n# precision etc. les indicateurs sont renseignes en fonction du type de resolution "
<< "\n# le mot cle est sortie_post_ , par defaut il vaut 0, dans ce cas aucun indicateur n'est stoke"
<< "\n# s'il est different de 0, on peut acceder aux indicateurs en post-traitement"
<< "\n# seules les indicateurs en cours sont disponibles, il n'y a pas de stockage sur plusieurs increment "
<< "\n# "
<< "\n# ex: sortie_post_ 1 "
<< "\n# "
<< "\n# \n Exemple de declaration: sans la phase "
<< "\n#-------------------------------------------------------------------------"
<< "\n# ....... loi_de_comportement d'hysteresis 3D ........ |"
<< "\n# para de prager : mu : limite maxi de plasticite |"
<< "\n#-------------------------------------------------------------------------"
<< "\n# np= " << setprecision(6) << xnp << " mu= " << setprecision(6) << xmu
<< "\n# Qzero= "<< setprecision(6) << Qzero << " avec_parametres_de_reglage_ "
<< "\n# nb_iteration_maxi_ 20 nb_dichotomie_maxi_ 20 tolerance_residu_ 1.e-3 tolerance_residu_rel_ 1.e-5 "
<< "\n# tolerance_coincidence_ 1.e-3 mini_rayon_ 1. e-8 tolerance_centre_ 1. e-3 "
<< "\n# fin_parametres_reglage_Hysteresis_ "
<< "\n# "
<< "\n# \n Exemple de declaration pour une resolution avec une methode de Runge_Kutta: "
<< "\n#-------------------------------------------------------------------------"
<< "\n# ....... loi_de_comportement d'hysteresis 3D ........ |"
<< "\n# para de prager : mu : limite maxi de plasticite |"
<< "\n#-------------------------------------------------------------------------"
<< "\n# np= " << setprecision(6) << xnp << " mu= " << setprecision(6) << xmu
<< "\n# Qzero= "<< setprecision(6) << Qzero << " avec_parametres_de_reglage_ "
<< "\n# type_de_resolution_ 2 "
<< "\n# cas_kutta_ 5 erreurAbsolue_ 1.e-3 erreurRelative_ 1.e-5 nbMaxiAppel_ 100"
<< "\n# tolerance_coincidence_ 1.e-3 nb_maxInvCoinSurUnPas_ 20 min_angle_trajet_neutre_ 0.008"
<< "\n# possibilite_cosAlphaNegatif_ 0 mini_Qsig_pour_phase_sigma_Oi_tdt_ 1.5 "
<< "\n# fin_parametres_reglage_Hysteresis_ ";
}
else
{sort
<< "\n# \n Exemple de declaration pour une resolution avec une methode de Runge_Kutta: "
<< "\n#-------------------------------------------------------------------------"
<< "\n# ....... loi_de_comportement d'hysteresis 3D ........ |"
<< "\n# para de prager : mu : limite maxi de plasticite |"
<< "\n#-------------------------------------------------------------------------"
<< "\n np= " << setprecision(6) << xnp << " mu= " << setprecision(6) << xmu
<< " Qzero= "<< setprecision(6) << Qzero << " avec_parametres_de_reglage_ "
<< "\n type_de_resolution_ 2 "
<< "\n cas_kutta_ 5 erreurAbsolue_ 1.e-3 erreurRelative_ 1.e-5 nbMaxiAppel_ 3000"
<< "\n tolerance_coincidence_ 1.e-3 nb_maxInvCoinSurUnPas_ 20 min_angle_trajet_neutre_ 0.008"
<< "\n possibilite_cosAlphaNegatif_ 0 mini_Qsig_pour_phase_sigma_Oi_tdt_ 1.5 "
<< "\n fin_parametres_reglage_Hysteresis_ ";
};
sort << endl;
// appel de la classe mère
Loi_comp_abstraite::Info_commande_don_LoisDeComp(entreePrinc);
};
// test si la loi est complete
int Hysteresis3D::TestComplet()
{ int ret = LoiAbstraiteGeneral::TestComplet();
if ((xnp_temperature == NULL) && (xnp == ConstMath::tresgrand))
{ cout << " \n le parametre de prager n'est pas défini pour la loi " << Nom_comp(id_comp)
<< '\n';
ret = 0;
}
if ((xmu_temperature == NULL) && (xmu == ConstMath::tresgrand))
{ cout << " \n le parametre de lame mu n'est pas défini pour la loi " << Nom_comp(id_comp)
<< '\n';
ret = 0;
}
if ((Qzero_temperature == NULL) && (Qzero == ConstMath::tresgrand))
{ cout << " \n la limite de plasticite n'est pas défini pour la loi " << Nom_comp(id_comp)
<< '\n';
ret = 0;
}
return ret;
};
// calcul d'un module d'young équivalent à la loi, ceci pour un
// chargement nul
double Hysteresis3D::Module_young_equivalent(Enum_dure temps,const Deformation & ,SaveResul * )
{ // par défaut on prend un mu de 0.3 et on utilise l'équivalent d'une loi élastique
// mu = G = E/(2(1+nu)) -> E=2.6 * mu
if (xmu_temperature != NULL) xmu = xmu_temperature->Valeur(*temperature);
return (2.6 * xmu);
};
// 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 Hysteresis3D::Grandeur_particuliere
(bool ,List_io<TypeQuelconque>& liTQ,Loi_comp_abstraite::SaveResul * saveDon,list<int>& decal) const
{ // ici on est en 3D et les grandeurs sont par principe en absolue, donc la variable absolue ne sert pas
// on passe en revue la liste
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
switch (tipParticu.EnuTypeQuelconque().EnumTQ())
{ case NB_INVERSION:
// a) ----- cas du nombre d'inversion actuelle
{ SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon);
Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
tyTQ(1+(*idecal))=save_resul.sigma_barre_BH_R.size();
(*idecal)++; break;
}
case HYPER_CENTRE_HYSTERESIS:
// b) ----- cas du centre du cercle actuelle de référence
{ SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon);
Tab_Grandeur_TenseurBH& tyTQ= *((Tab_Grandeur_TenseurBH*) (*itq).Grandeur_pointee()); // pour simplifier
if (save_resul.oc_BH_R.size() != 0)
{tyTQ(1+(*idecal))= *(save_resul.oc_BH_R.begin());}
else
{tyTQ(1+(*idecal)).Inita(0.);}
(*idecal)++; break;
}
case SIGMA_REF:
// c) ----- cas de la contrainte de référence actuelle
{ SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon);
Tab_Grandeur_TenseurBH& tyTQ= *((Tab_Grandeur_TenseurBH*) (*itq).Grandeur_pointee()); // pour simplifier
if (save_resul.sigma_barre_BH_R.size() != 0)
{tyTQ(1+(*idecal))= *(save_resul.sigma_barre_BH_R.begin());}
else
{tyTQ(1+(*idecal)).Inita(0.);};
(*idecal)++; break;
}
// d) ----- Q_sigma actuel de Oi à T
case Q_SIG_HYST_Oi_A_R:
{ SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon);
Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
Tenseur3BH delta__sigma_barre_BH_OiaR; // a priori le centre et la référence = 0: cas du début
if (save_resul.sigma_barre_BH_R.size() != 0) delta__sigma_barre_BH_OiaR=(*(save_resul.sigma_barre_BH_R.begin()));
if (save_resul.oc_BH_R.size() != 0) delta__sigma_barre_BH_OiaR -= *(save_resul.oc_BH_R.begin());
tyTQ(1+(*idecal)) = sqrt(delta__sigma_barre_BH_OiaR.II());
(*idecal)++; break;
}
// e) ----- Q_sigma actuel de R à T
case Q_SIG_HYST_R_A_T:
{ SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon);
Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
Tenseur3BH delta__sigma_barre_BH_Ratdt (save_resul.sigma_barre_BH_tdt); // a priori la ref = 0: cas du début
if (save_resul.sigma_barre_BH_R.size() != 0) delta__sigma_barre_BH_Ratdt -= *(save_resul.sigma_barre_BH_R.begin());
tyTQ(1+(*idecal))=sqrt(delta__sigma_barre_BH_Ratdt.II());
(*idecal)++; break;
}
// f) ----- COS_ALPHA_HYSTERESIS actuel
case COS_ALPHA_HYSTERESIS:
{ SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon);
Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
// le plus simple est de recalculer
double w__prime,w__prime_point; // grandeurs de retour
bool trajet_neutre=false;
Tenseur3BH delta__sigma_barre_BH_Ratdt (save_resul.sigma_barre_BH_tdt); // a priori la ref = 0: cas du début
if (save_resul.sigma_barre_BH_R.size() != 0) delta__sigma_barre_BH_Ratdt -= *(save_resul.sigma_barre_BH_R.begin());
double Q__deltaSiRatdt = sqrt(delta__sigma_barre_BH_Ratdt.II());
Tenseur3BH delta__sigma_barre_BH_OiaR; // a priori le centre et la référence = 0: cas du début
if (save_resul.sigma_barre_BH_R.size() != 0) delta__sigma_barre_BH_OiaR=(*(save_resul.sigma_barre_BH_R.begin()));
if (save_resul.oc_BH_R.size() != 0) delta__sigma_barre_BH_OiaR -= *(save_resul.oc_BH_R.begin());
double Q__OiaR = sqrt(delta__sigma_barre_BH_OiaR.II());
Cal_wprime(Q__deltaSiRatdt,delta__sigma_barre_BH_Ratdt,Q__OiaR,delta__sigma_barre_BH_OiaR
,save_resul.wBase_tdt,ZeroBH3,w__prime,w__prime_point,trajet_neutre);
tyTQ(1+(*idecal))=w__prime/save_resul.wBase_tdt;
(*idecal)++; break;
}
// g) ----- cos_3phi actuel pour la contrainte totale d'hystérésis
case COS3PHI_SIG_HYSTERESIS:
{ SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon);
Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
double Qsig = sqrt(Dabs(save_resul.sigma_barre_BH_tdt.II()));
double Qsig3 = Qsig * Qsig * Qsig;
// if (Qsig > mini_Qsig_pour_phase_sigma_Oi_tdt )
{ // on peut calculer un cos3phi pas débile
double bIIIb = save_resul.sigma_barre_BH_tdt.III() / 3.;
if (mini_Qsig_pour_phase_sigma_Oi_tdt > 0.)
tyTQ(1+(*idecal)) = 3. * sqrt(6.) * bIIIb/ Qsig3;
else
tyTQ(1+(*idecal)) = 3. * sqrt(6.) * bIIIb/ (Qsig3-mini_Qsig_pour_phase_sigma_Oi_tdt);
};
// else tyTQ=0.; // sinon on le met à 0
(*idecal)++; break;
}
// h) ----- cos_3phi actuel pour l'incrément de contrainte totale d'hystérésis
case COS3PHI_DELTA_SIG_HYSTERESIS:
{ SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon);
Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
Tenseur3BH delta__sigma_barre_BH_tatdt(save_resul.sigma_barre_BH_tdt-save_resul.sigma_barre_BH_t);
double Qsig = sqrt(delta__sigma_barre_BH_tatdt.II());
double Qsig3 = Qsig * Qsig * Qsig;
// if (Qsig > mini_Qsig_pour_phase_sigma_Oi_tdt )
{ // on peut calculer un cos3phi pas débile
double bIIIb = delta__sigma_barre_BH_tatdt.III() / 3.;
if (mini_Qsig_pour_phase_sigma_Oi_tdt > 0.)
tyTQ(1+(*idecal)) = 3. * sqrt(6.) * bIIIb/ Qsig3;
else
tyTQ(1+(*idecal)) = 3. * sqrt(6.) * bIIIb/ (Qsig3-mini_Qsig_pour_phase_sigma_Oi_tdt);
}
// else tyTQ=0.; // sinon on le met à 0
(*idecal)++; break;
}
// i) ----- Q_delta_sig d'hystérésis
case Q_DELTA_SIG_HYST:
{ SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon);
Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
Tenseur3BH delta__sigma_barre_BH_tatdt(save_resul.sigma_barre_BH_tdt-save_resul.sigma_barre_BH_t);
tyTQ(1+(*idecal)) = sqrt(delta__sigma_barre_BH_tatdt.II());
(*idecal)++; break;
}
// ----- fonction d'aide
case FCT_AIDE:
{ SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon);
Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
tyTQ(1+(*idecal)) = save_resul.fonction_aide_tdt;
(*idecal)++; break;
}
case NB_INCRE_TOTAL_RESIDU:
{ SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon);
Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
if ((save_resul.indicateurs_resolution_t.Taille()))
tyTQ(1+(*idecal)) = save_resul.indicateurs_resolution_t(1);
else tyTQ(1+(*idecal)) = 0.;
(*idecal)++; break;
}
case NB_ITER_TOTAL_RESIDU:
{ SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon);
Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
if ((save_resul.indicateurs_resolution_t.Taille()))
tyTQ(1+(*idecal)) = save_resul.indicateurs_resolution_t(2);
else tyTQ(1+(*idecal)) = 0.;
(*idecal)++; break;
}
case NB_APPEL_FCT:
{ SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon);
Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
if ((save_resul.indicateurs_resolution_t.Taille()))
tyTQ(1+(*idecal)) = save_resul.indicateurs_resolution_t(3);
else tyTQ(1+(*idecal)) = 0.;
(*idecal)++; break;
}
case NB_STEP:
{ SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon);
Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
if ((save_resul.indicateurs_resolution_t.Taille()))
tyTQ(1+(*idecal)) = save_resul.indicateurs_resolution_t(4);
else tyTQ(1+(*idecal)) = 0.;
(*idecal)++; break;
}
case ERREUR_RK:
{ SaveResulHysteresis3D & save_resul = *((SaveResulHysteresis3D*) saveDon);
Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
if ((save_resul.indicateurs_resolution_t.Taille()))
tyTQ(1+(*idecal)) = save_resul.indicateurs_resolution_t(5);
else tyTQ(1+(*idecal)) = 0.;
(*idecal)++; break;
}
default: ;// on ne fait rien
};
};
};
// récupération et création 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 Hysteresis3D::ListeGrandeurs_particulieres(bool absolue,List_io<TypeQuelconque>& liTQ) const
{// ici on est en 3D et les grandeurs sont par principe en absolue, donc la variable absolue ne sert pas
Tableau <double> tab_1(1);
Tab_Grandeur_scalaire_double grand_courant(tab_1);
// def d'un type quelconque représentatif à chaque grandeur
// a priori ces grandeurs sont défini aux points d'intégration identique à la contrainte par exemple
// enu_ddl_type_pt est définit dans la loi Abtraite générale
// on n'ajoute que si sortie_post est vraie, sinon aucune grandeur n'est sauvegardé, donc on ne peut
// plus y accèder
//on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée
// a) $$$ cas du nombre d'inversion actuelle
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == NB_INVERSION)
{ 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(NB_INVERSION,enu_ddl_type_pt,grand_courant);
liTQ.push_back(typQ1);
};
};
// b) $$$ cas du centre du cercle actuelle de référence
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == HYPER_CENTRE_HYSTERESIS)
{Tab_Grandeur_TenseurBH& tyTQ= *((Tab_Grandeur_TenseurBH*) (*itq).Grandeur_pointee()); // pour simplifier
int taille = tyTQ.Taille()+1;
tyTQ.Change_taille(taille); nexistePas = false;
};
if (nexistePas)
{TenseurBH* tens = NevezTenseurBH(3); // un tenseur typique
Tab_Grandeur_TenseurBH sigrefBH(*tens,1);
// def d'un type quelconque représentatif
TypeQuelconque typQ(HYPER_CENTRE_HYSTERESIS,SIG11,sigrefBH);
liTQ.push_back(typQ);
delete tens; // car on n'en a plus besoin
};
};
// c) $$$ cas de la contrainte de référence actuelle
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == SIGMA_REF)
{Tab_Grandeur_TenseurBH& tyTQ= *((Tab_Grandeur_TenseurBH*) (*itq).Grandeur_pointee()); // pour simplifier
int taille = tyTQ.Taille()+1;
tyTQ.Change_taille(taille); nexistePas = false;
};
if (nexistePas)
{TenseurBH* tens = NevezTenseurBH(3); // un tenseur typique
Tab_Grandeur_TenseurBH sigrefBH(*tens,1);
// def d'un type quelconque représentatif
TypeQuelconque typQ(SIGMA_REF,SIG11,sigrefBH);
liTQ.push_back(typQ);
delete tens; // car on n'en a plus besoin
};
};
// d) $$$ Q_sigma actuel de Oi à R
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == Q_SIG_HYST_Oi_A_R)
{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(Q_SIG_HYST_Oi_A_R,SIG11,grand_courant);
liTQ.push_back(typQ1);
};
};
// e) $$$ Q_sigma actuel de R à T
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == Q_SIG_HYST_R_A_T)
{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(Q_SIG_HYST_R_A_T,SIG11,grand_courant);
liTQ.push_back(typQ1);
};
};
// f) $$$ cos_alpha actuel
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == COS_ALPHA_HYSTERESIS)
{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(COS_ALPHA_HYSTERESIS,SIG11,grand_courant);
liTQ.push_back(typQ1);
};
};
// g) ----- cos_3phi actuel pour la contrainte totale d'hystérésis
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == COS3PHI_SIG_HYSTERESIS)
{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(COS3PHI_SIG_HYSTERESIS,SIG11,grand_courant);
liTQ.push_back(typQ1);
};
};
// h) ----- cos_3phi actuel pour l'incrément de contrainte totale d'hystérésis
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == COS3PHI_DELTA_SIG_HYSTERESIS)
{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(COS3PHI_DELTA_SIG_HYSTERESIS,SIG11,grand_courant);
liTQ.push_back(typQ1);
};
};
// i) ----- Q_delta_sig d'hystérésis
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == Q_DELTA_SIG_HYST)
{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(Q_DELTA_SIG_HYST,SIG11,grand_courant);
liTQ.push_back(typQ1);
};
};
// ----- fonction d'aide
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == FCT_AIDE)
{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(FCT_AIDE,SIG11,grand_courant);
liTQ.push_back(typQ1);
};
};
// ---- la suite dépend de l'indicateur : sortie_post
if (sortie_post)
{ // j) ----- NB_INCRE_TOTAL_RESIDU
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == NB_INCRE_TOTAL_RESIDU)
{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(NB_INCRE_TOTAL_RESIDU,SIG11,grand_courant);
liTQ.push_back(typQ1);
};
};
// k) ----- NB_ITER_TOTAL_RESIDU
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == NB_ITER_TOTAL_RESIDU)
{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(NB_ITER_TOTAL_RESIDU,SIG11,grand_courant);
liTQ.push_back(typQ1);
};
};
// l) ----- NB_APPEL_FCT
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == NB_APPEL_FCT)
{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(NB_APPEL_FCT,SIG11,grand_courant);
liTQ.push_back(typQ1);
};
};
// m) ----- NB_STEP
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == NB_STEP)
{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(NB_STEP,SIG11,grand_courant);
liTQ.push_back(typQ1);
};
};
// n) ----- ERREUR_RK
{List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
for (itq=liTQ.begin();itq!=itqfin;itq++)
if ((*itq).EnuTypeQuelconque() == ERREUR_RK)
{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(ERREUR_RK,SIG11,grand_courant);
liTQ.push_back(typQ1);
};
};
}; // fin du cas ou sortie_post est actif, c-a-d que l'on veut des infos sur les indicateurs
// de résolution
};
// ========== codage des METHODES VIRTUELLES protegees:================
//----- 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 Hysteresis3D::Lecture_base_info_loi(ifstream& ent,const int cas,LesReferences& lesRef,LesCourbes1D& lesCourbes1D
,LesFonctions_nD& lesFonctionsnD)
{if (cas == 1)
{ bool test;string nom;
// param_prager_(np)
ent >> nom >> test;
if (!test)
{ ent >> xnp;
if (xnp_temperature != NULL) {if (xnp_temperature->NomCourbe() == "_")
delete xnp_temperature; xnp_temperature = NULL;
};
}
else
{ ent >> nom; xnp_temperature = lesCourbes1D.Lecture_pour_base_info(ent,cas,xnp_temperature); };
// limite_plasticite_(Q0)
ent >> nom >> test;
if (!test)
{ ent >> Qzero;
if (Qzero_temperature != NULL) {if (Qzero_temperature->NomCourbe() == "_")
delete Qzero_temperature; Qzero_temperature = NULL;
};
}
else
{ ent >> nom; Qzero_temperature = lesCourbes1D.Lecture_pour_base_info(ent,cas,Qzero_temperature); };
// param_lame_(mu)
ent >> nom >> test;
if (!test)
{ ent >> xmu;
if (xmu_temperature != NULL) {if (xmu_temperature->NomCourbe() == "_")
delete xmu_temperature; xmu_temperature = NULL;
};
}
else
{ ent >> nom; xmu_temperature = lesCourbes1D.Lecture_pour_base_info(ent,cas,xmu_temperature); };
// --- dépendance à la phase éventuelle
ent >> nom;
if (nom == "avec_phaseDeltaSig") {avec_phaseDeltaSig = true; avec_phaseEps = false; }
else if (nom == "avec_phaseEps") {avec_phaseDeltaSig = false; avec_phaseEps = true; }
else {avec_phaseDeltaSig = false; avec_phaseEps = false; };
if (avec_phaseDeltaSig || avec_phaseEps)
{// param_prager_(np)
ent >> nom >> test;
if (!test)
{ if (xnp_phase != NULL) {if (xnp_phase->NomCourbe() == "_") delete xnp_phase;
xnp_phase = NULL;
};
}
else
{ ent >> nom; xnp_phase = lesCourbes1D.Lecture_pour_base_info(ent,cas,xnp_phase); };
// xmu
ent >> nom >> test;
if (!test)
{ if (xmu_phase != NULL) {if (xmu_phase->NomCourbe() == "_") delete xmu_phase;
xmu_phase = NULL;
};
}
else
{ ent >> nom; xmu_phase = lesCourbes1D.Lecture_pour_base_info(ent,cas,xmu_phase); };
// Qzero
ent >> nom >> test;
if (!test)
{ if (Qzero_phase != NULL) {if (Qzero_phase->NomCourbe() == "_") delete Qzero_phase;
Qzero_phase = NULL;
};
}
else
{ ent >> nom; Qzero_phase = lesCourbes1D.Lecture_pour_base_info(ent,cas,Qzero_phase); };
};
// --- dépendance à la def Equi éventuelle
ent >> nom;
if (nom == "avec_defEqui")
{ // param_prager_(np)
ent >> test >> nom;
if ((!test) && (nom == "pas_de_fct_xnp_defEqui_"))
{ // pas de dépendance de xn à la defEqui
if (xnp_defEqui != NULL) {if (xnp_defEqui->NomCourbe() == "_") delete xnp_defEqui;
xnp_defEqui = NULL;
};
}
else if (test)
{ ent >> nom;
if (nom == "fonction_xnp_defEqui")
{xnp_defEqui = lesCourbes1D.Lecture_pour_base_info(ent,cas,xnp_defEqui);};
}
else
{ cout << "\n erreur en lecture de xnp_defEqui, on attendait de lire la chaine: pas_de_fct_xnp_defEqui_ et on a lue "
<< nom << endl;
Sortie(1);
};
// dépendance de Qzero
ent >> test >> nom;
if ((!test) && (nom == "pas_de_fct_Qzero_defEqui_"))
{ // pas de dépendance de Qzero à la defEqui
if (Qzero_defEqui != NULL) {if (Qzero_defEqui->NomCourbe() == "_") delete Qzero_defEqui;
Qzero_defEqui = NULL;
};
}
else if (test)
{ ent >> nom;
if (nom == "fonction_Qzero_defEqui")
{Qzero_defEqui = lesCourbes1D.Lecture_pour_base_info(ent,cas,Qzero_defEqui);};
}
else
{ cout << "\n erreur en lecture de Qzero_defEqui, on attendait de lire la chaine: pas_de_fct_Qzero_defEqui_ et on a lue "
<< nom << endl;
Sortie(1);
};
};
// --- dépendance à la phase de la déformation totale
ent >> nom;
if (nom == "avec_phase_paradefEqui")
{ent >> nom >> test;
// coef_paradefEqui
if (!test)
{ if (coef_paradefEqui != NULL) {if (coef_paradefEqui->NomCourbe() == "_") delete coef_paradefEqui;
coef_paradefEqui = NULL;
};
}
else
{ ent >> nom; coef_paradefEqui = lesCourbes1D.Lecture_pour_base_info(ent,cas,coef_paradefEqui); };
};
// les paramètres de réglage de l'algorithme
ent >> nom >> tolerance_residu >> nom >> tolerance_residu_rel
>> nom >> nb_boucle_maxi >> nom >> maxi_delta_var_sig_sur_iter_pour_Newton
>> nom >> nb_dichotomie
>> nom >> mini_rayon
>> nom >> tolerance_coincidence
>> nom >> tolerance_centre;
ent >> nom >> type_resolution_equa_constitutive
>> nom >> type_calcul_comportement_tangent
>> nom >> avecVarWprimeS
>> nom >> cas_kutta >> nom >> erreurAbsolue >> nom >> erreurRelative;
ent >> nom >> nb_maxInvCoinSurUnPas >> nom >> min_angle_trajet_neutre >> nom >> possibilite_cosAlphaNegatif
>> nom >> mini_Qsig_pour_phase_sigma_Oi_tdt
>> nom >> mini_QepsilonBH
>> nom >> force_phi_zero_si_negatif
>> nom >> depassement_Q0
>> nom >> type_de_transport_memorisation
>> nom >> niveau_bascule_fct_aide;
// le niveau d'affichage
Lecture_permet_affichage(ent,cas,lesFonctionsnD);
ent >> nom >> sortie_post;
};
// appel de la classe mère
Loi_comp_abstraite::Lecture_don_base_info(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 Hysteresis3D::Ecriture_base_info_loi(ofstream& sort,const int cas)
{ if (cas == 1)
{ sort << " HYSTERESIS_3D ";
sort << " param_prager_(np) ";
if (xnp_temperature == NULL)
{ sort << false << " " << xnp_lue << " ";}
else
{ sort << true << " fonction_xnp_temperature ";
LesCourbes1D::Ecriture_pour_base_info(sort,cas,xnp_temperature);
};
sort << " limite_plasticite_(Q0) ";
if (Qzero_temperature == NULL)
{ sort << false << " " << Qzero_lue << " ";}
else
{ sort << true << " fonction_Qzero_temperature ";
LesCourbes1D::Ecriture_pour_base_info(sort,cas,Qzero_temperature);
};
sort << " param_lame_(mu) ";
if (xmu_temperature == NULL)
{ sort << false << " " << xmu_lue << " ";}
else
{ sort << true << " fonction_xmu_temperature ";
LesCourbes1D::Ecriture_pour_base_info(sort,cas,xmu_temperature);
};
// --- dépendance à la phase éventuelle
if (avec_phaseDeltaSig || avec_phaseEps)
{if (avec_phaseDeltaSig == 1) {sort << " avec_phaseDeltaSig ";}
else {sort << " avec_phaseEps ";};
if (xnp_phase == NULL)
{ sort << false << " " ;}
else
{ sort << true << " fonction_xnp_phase ";
LesCourbes1D::Ecriture_pour_base_info(sort,cas,xnp_phase);
};
if (xmu_phase == NULL)
{ sort << false << " " ;}
else
{ sort << true << " fonction_xmu_phase ";
LesCourbes1D::Ecriture_pour_base_info(sort,cas,xmu_phase);
};
if (Qzero_phase == NULL)
{ sort << false << " " ;}
else
{ sort << true << " fonction_Qzero_phase ";
LesCourbes1D::Ecriture_pour_base_info(sort,cas,Qzero_phase);
};
}
else
{sort << " sans_phase ";};
// --- dépendance à la def Equi éventuelle
if (avec_defEqui)
{sort << " avec_defEqui ";
if (xnp_defEqui == NULL)
{ sort << false << " pas_de_fct_xnp_defEqui_ " ;}
else
{ sort << true << " fonction_xnp_defEqui ";
LesCourbes1D::Ecriture_pour_base_info(sort,cas,xnp_defEqui);
};
if (Qzero_defEqui == NULL)
{ sort << false << " pas_de_fct_Qzero_defEqui_ " ;}
else
{ sort << true << " fonction_Qzero_defEqui ";
LesCourbes1D::Ecriture_pour_base_info(sort,cas,Qzero_defEqui);
};
}
else
{sort << " sans_defEqui ";};
// --- dépendance à la phase de la déformation totale pour paradefEqui
if (avec_phase_paradefEqui)
{sort << " avec_phase_paradefEqui ";
if (coef_paradefEqui == NULL)
{ sort << false << " " ;}
else
{ sort << true << " fonction_coef_paradefEqui ";
LesCourbes1D::Ecriture_pour_base_info(sort,cas,coef_paradefEqui);
};
}
else
{sort << " sans_phaseEps ";};
// --- paramètre de réglage
sort << "\n tolerance_algo_newton_equadiff:_absolue= " << tolerance_residu
<< " relative= "<< tolerance_residu_rel
<< " nb_boucle_maxi " << nb_boucle_maxi
<< " maxi_delta_var_sig_sur_iter_pour_Newton " << maxi_delta_var_sig_sur_iter_pour_Newton
<< " nb_dichotomie " << nb_dichotomie
<< " tolerance_coincidence " << tolerance_coincidence
<< " tolerance_centre " << tolerance_centre
<< " mini_rayon " << mini_rayon;
sort << "\n type_resolution_equa_constitutive " << type_resolution_equa_constitutive
<< " type_calcul_comportement_tangent " << type_calcul_comportement_tangent
<< " avecVarWprimeS " << avecVarWprimeS
<< " cas_kutta " << cas_kutta
<< " erreurAbsolue " << erreurAbsolue << " erreurRelative " << erreurRelative << " ";
sort << " nb_maxInvCoinSurUnPas " << nb_maxInvCoinSurUnPas
<< " min_angle_trajet_neutre " << min_angle_trajet_neutre
<< " possibilite_cosAlphaNegatif " << possibilite_cosAlphaNegatif
<< " mini_Qsig_pour_phase_sigma_Oi_tdt " << mini_Qsig_pour_phase_sigma_Oi_tdt
<< " mini_QepsilonBH " << mini_QepsilonBH
<< " force_phi_zero_si_negatif " << force_phi_zero_si_negatif
<< " depassement_Q0 " << depassement_Q0
<< " type_de_transport_memorisation "<< type_de_transport_memorisation
<< " niveau_bascule_fct_aide "<< niveau_bascule_fct_aide;
// niveau d'affichage
Affiche_niveau_affichage(sort,cas);
sort << " sortie_post " << sortie_post
<< " ";
};
// appel de la classe mère
Loi_comp_abstraite::Ecriture_don_base_info(sort,cas);
};
// =============== fonction protegee ============
// --------------- méthodes internes ---------------:
// 1) affinage d'un point de coincidence à l'aide des rayons
// ramène true si le traitement est exactement terminé, sinon false, ce qui signifie qu'il
// faut encore continuer à utiliser l'équation d'évolution
// pt_sur_principal : indique si oui ou non le pointeur iatens pointe sur sa liste principale
// oi_sur_principal : indique si oui ou non le pointeur iaOi pointe sur sa liste principale
// iatens_princ et iaOi_princ: pointeurs sur les listes principales
// force_coincidence : on force la coincidence à la position actuelle
// le rayon peut-être modifié dans le cas particulier d'une coincidence à la précision près
bool Hysteresis3D::Coincidence(bool bascule_fct_aide,double& unSur_wBaseCarre
,const Tenseur3HH & gijHH,const Tenseur3BB & gijBB
,SaveResulHysteresis3D & save_resul,double& W_a
,List_io <Tenseur3BH>::iterator& iatens
,List_io <double>::iterator& iadef_equi
,List_io <double>::iterator& iafct
,bool& pt_sur_principal
,List_io <Tenseur3BH>::iterator& iaOi,bool& oi_sur_principal
,List_io <Tenseur3BH>::iterator& iatens_princ
,List_io <double>::iterator& iadef_equi_princ
,List_io <Tenseur3BH>::iterator& iaOi_princ
,List_io <double>::iterator& iafct_princ
,const double& rayon_tdt,bool force_coincidence)
{ // tout d'abord on vérifie que l'on n'est pas exactement à un point de
// coincidence à la précision près
// -- modif 10 juillet 2014:
// on calcul la grandeur cc qui est un des coef de l'équation du second degré permettant
// de trouver la coïncidence (voir après)
Tenseur3BH delta_sigma_oi_a_t_BH = sigma_i_barre_BH - oc_BH_R; // OB
double cc = (delta_sigma_oi_a_t_BH && delta_sigma_oi_a_t_BH) - Q_OiaR * Q_OiaR; // cc=OB*OB - r^2
// si cc est positif, cela signifie qu'au pas précédent on n'a pas bien détecté une coincidence
// ou que c'est un pb de zero
// on considère alors que le point actuel est un point de coïncidence à la précision près et donc
// on finit le traitement
double tol_coincidence_reelle = tolerance_coincidence;
if (tolerance_coincidence < 0) // si l'indication est négative , cela veut dire que l'on veut une grandeur relative
tol_coincidence_reelle = MaX(-tolerance_coincidence * Q_OiaR,-tolerance_coincidence);
// -- fin modif
if ((Abs(rayon_tdt - Q_OiaR) <= tol_coincidence_reelle) || force_coincidence
// || ((cc >= 0.) && (sqrt(Dabs(cc)) <= tol_coincidence_reelle)) ) // -- ajout 10 juillet 2014:
|| (cc >= 0.) ) // -- ajout 11 juillet 2014: on ne peut plus revenir sur les grandeurs à t
// donc le mieux est de valider la coïncidence ce qui simplifiera la suite du traitement
{ // on est dans le cas où l'on a une coïncidence exacte à la précision "tolerance_coincidence" près
// mais dans tous les cas on a rayon_tdt > Q_OiaR sinon on n'aurait pas de coïncidence
// on signale qu'il y a une coincidence exacte (pour le retour de la méthode Coincidence)
// gestion des pointeurs
do
{Gestion_pointeur_coincidence(unSur_wBaseCarre,save_resul,W_a
,iatens,iadef_equi,iafct,pt_sur_principal,iaOi,oi_sur_principal
,iatens_princ,iadef_equi_princ,iaOi_princ,iafct_princ);
}// on traite le cas où des autres coincidences existent à la précision près
while (Autre_coincidence_a_la_tolerance_pres(bascule_fct_aide,gijHH,gijBB
,pt_sur_principal,oi_sur_principal,iatens,iaOi));
return true;
};
// --- sinon on continue mais le traitement ne sera pas fini !!
// dans une première étape on tente de calculer plus précisemment le point d'inversion,
// en supposant une approximation linéaire de l'évolution de sigma sur le pas de temps:
bool bon_calcul = false; // permet de savoir si le calcul précis est correcte,
// pour l'instant on dit que non au niveau de l'init
// a-- calcul des coefficients de l'équation du second degré qui gère le point exact
double aa = delta_sigma_barre_tdt_BH && delta_sigma_barre_tdt_BH; // BA*BA
// aa doit être sup à 0, si ce n'est pas le cas du à des arrondis ou des pb de transport on le met à 0
if (aa < ConstMath::pasmalpetit)
{ aa = 0.;
2023-05-03 17:23:49 +02:00
if (Permet_affichage() > 0)
2021-09-23 11:21:15 +02:00
cout << "\n warning algo coincidence, dans la recherche des racines de l'equa 2 degre "
<< " on a sig_tdt : sig_tdt qui est negatif !! = " << aa <<" on le met a 0 mais ce n'est pas normal "
<< "\n Hysteresis3D::Coincidence(... ";
};
// delta_sigma_oi_a_tdt_BH c'est OA
double bb = 2. * (delta_sigma_oi_a_t_BH && delta_sigma_barre_tdt_BH); // OB*BA
// bb *= 2. * bb; // 2 (OB*BA)^2
// double cc = (delta_sigma_oi_a_t_BH && delta_sigma_oi_a_t_BH) - Q_OiaR * Q_OiaR; // OB*OB - r^2
// #ifdef MISE_AU_POINT
//**** le test qui suit ne sert plus compte tenu du choix fait plus haut sur cc
// if(!aucun_pt_inversion)
// if (cc > 0.) // signifie qu'au pas précédent on n'a pas bien détecté une coincidence
// // ou que c'est un pb de zero
// { // les 4 lignes qui suivent n'ont plus lieu d'être : -- modif 10 juillet 2014
//// if (Dabs(cc) <= tolerance_coincidence)
//// { cc = 0.;
//// }
//// else
// { if ( ((Permet_affichage()==0) && (ParaGlob::NiveauImpression() > 0)) || (Permet_affichage() > 0))
// cout << "\n erreur algo coincidence : 1 : cc positif ! "
// << "\n Hysteresis3D::Coincidence(... " << endl;
// if ( ((Permet_affichage()==0) && (ParaGlob::NiveauImpression() > 2)) || (Permet_affichage() > 2))
// { cout << "\n aa= " << aa << " bb= " << bb << " cc= " << cc;};
// if ( ((Permet_affichage()==0) && (ParaGlob::NiveauImpression() > 4)) || (Permet_affichage() > 4))
// { Affiche_debug(unSur_wBaseCarre,save_resul,iatens,iadef_equi,pt_sur_principal
// ,iaOi,oi_sur_principal,iatens_princ,iadef_equi_princ,iaOi_princ);
// };
// // on génère une exception
// throw ErrNonConvergence_loiDeComportement();
//// Sortie(1);
// };
// };
//
//****
// #endif
// b-- recherche de racine
double racine1,racine2; int cas;
alg_zero.SecondDegre(aa,bb,cc,racine1,racine2,cas);
// --- traitement suivant les différents cas de la résolution de l'équation du second degré ---
switch (cas)
{ case 1: // deux racines distinctes
{ // normalement les deux racines sont de signe opposé, seule la positive <=1 est recevable
if (racine1*racine2 <=0.)
{// on regarde si racine2 <= 1 ce qui est le cas normal
if (racine2 <= 1.) // racine2 est la plus grande donc positive
// cas normal, on valide la procédure
{ bon_calcul = true;}
#ifdef MISE_AU_POINT
else // sinon cela signifie que la méthode n'est pas bonne
2023-05-03 17:23:49 +02:00
{ if (Permet_affichage() > 0)
2021-09-23 11:21:15 +02:00
cout << "\n warning algo coincidence, dans la recherche des racines de l'equa 2 degre "
<< " la seconde racine " << racine2 <<" est superieur a 1"
<< "\n Hysteresis3D::Coincidence(... ";
}
#endif
}
else
{
#ifdef MISE_AU_POINT
// normalement aa >=0 donc avec cc <0 on ne doit pas avoir 2 racines du même signe
if(!aucun_pt_inversion) // sauf dans le cas de la première charge
2023-05-03 17:23:49 +02:00
{ if (Permet_affichage() > 0)
2021-09-23 11:21:15 +02:00
cout << "\n erreur algo coincidence, dans la recherche des racines de l'equa 2 degre "
<< " les deux racines sont du meme signe ??, a= " <<aa<<" c= " << cc << " racine1= "
<< racine1 << " racine2= " << racine1
<< "\n Hysteresis3D::Coincidence(... ";
}
#endif
// on regarde si une des racines convient
// a priori on garde la plus grande, si les deux conviennent
double la_plus_grande = MaX(racine1,racine2);
if ((la_plus_grande>0.) && (la_plus_grande<1.))
{ racine2=la_plus_grande; bon_calcul = true;}
else // sinon on test l'autre
{ double la_plus_petite = MiN(racine1,racine2);
if ((la_plus_petite>0.) && (la_plus_petite<1.))
{ racine2=la_plus_petite; bon_calcul = true;}
// sinon rien tous les autres cas sont mauvais
};
};
break;
}
case 2: // deux racines identiques
{ // normalement la racine doit être comprise entre 0 et 1, sinon non recevable
if ((racine2>=0.) && (racine2 <= 1.))
// cas normal, on valide la procédure
{ bon_calcul = true;};
// tous les autres cas sont mauvais
break;
}
case -3: // une racine simple
{ // normalement la racine doit être comprise entre 0 et 1, sinon non recevable
if ((racine1>=0.) && (racine1 <= 1.))
// cas normal, on valide la procédure
{ bon_calcul = true;
racine2=racine1; // pour la suite
};
// tous les autres cas sont mauvais
break;
}
// tous les autres cas sont mauvais donc la variable bon_calcul sera fausse
// et on utilisera une autre procedure de calcul par la suite
}; //-- fin du switch
// --- fin du traitement suivant les différents cas de la résolution de l'équation du second degré ---
if (!bon_calcul)
// cas où la recherche fine avec la résolution de l'équat du second degré n'a pas marché
{ // on utilise une interpolation plus grossière à l'aide de la fonction de charge
2023-05-03 17:23:49 +02:00
if (Permet_affichage() > 4)
2021-09-23 11:21:15 +02:00
cout << "\n (algo hysteresis) on passe par l'interpolation lineaire de l'equation du second degre";
double delta_r2 = rayon_tdt - Q_OiaR;
double delta_r1 = Q_OiaR - sqrt(delta_sigma_oi_a_t_BH.II());
racine2 = delta_r1 / (delta_r1 + delta_r2);
// normalement racine2 est compris entre 0 et 1
if ( (racine2 < 0.) || (racine2 > 1.))
2023-05-03 17:23:49 +02:00
{ if (Permet_affichage() > 0)
2021-09-23 11:21:15 +02:00
cout << "\n erreur algo coincidence, dans la recherche de racine2 simplifiee"
<< "\n racine2= " << racine2 << " delta_r2= " << delta_r2 << " delta_r1= " << delta_r1
<< " Q_OiaR= " << Q_OiaR << " -> divergence ! "
<< "\n Hysteresis3D::Coincidence(... " << endl;
// on génère une exception
throw ErrNonConvergence_loiDeComportement();
};
};
// c-- maintenant on traite les infos
// comme racine2 appartient à [0,1], que OiR > Oisigma_t et que OiR < Oisigma_tdt, normalement on doit avoir
// Oisigma_tdt > Oisigma_coinci
// -- cas où à l'issue du calcul racines est très proche de 1 ---
// dans ce cas on considère que la coïncidence est exacte
if (sqrt(((1.-racine2)*delta_sigma_barre_tdt_BH).II()) <= tol_coincidence_reelle)
{ // on est dans le cas où l'on a une coïncidence exacte à la précision "tolerance_coincidence" près
// mais dans tous les cas on a rayon_tdt > Q_OiaR sinon on n'aurait pas de coïncidence
// on signale qu'il y a une coincidence exacte (pour le retour de la méthode Coincidence)
// gestion des pointeurs
do
{Gestion_pointeur_coincidence(unSur_wBaseCarre,save_resul,W_a
,iatens,iadef_equi,iafct,pt_sur_principal,iaOi,oi_sur_principal
,iatens_princ,iadef_equi_princ,iaOi_princ,iafct_princ);
}// on traite le cas où des autres coincidences existent à la précision près
while (Autre_coincidence_a_la_tolerance_pres(bascule_fct_aide,gijHH,gijBB
,pt_sur_principal,oi_sur_principal,iatens,iaOi));
return true;
};
// calcul de la valeur de sigma au point de coincidence, qui servira pour un nouveau calcul
sigma_i_barre_BH += racine2 * delta_sigma_barre_tdt_BH;
// donc à partir d'ici on considère que l'on va valider la coïncidence, il faut donc que
// la contrainte au point de conïncidence corresponde "exactement" à celle correspondante au critère de
// coïncidence, on va donc vérifier que "racine2" est correcte
double nouveau_rayon_tdt = sqrt((sigma_i_barre_BH - oc_BH_R).II()); // Q_OiaR
if ((Abs(nouveau_rayon_tdt - Q_OiaR) > tol_coincidence_reelle) )
2023-05-03 17:23:49 +02:00
if (Permet_affichage() > 4)
2021-09-23 11:21:15 +02:00
{ cout << "\n erreur2 algo coincidence, dans la recherche de racine2 "
<< "\n racine2= " << racine2 << " nouveau_rayon_tdt= " << nouveau_rayon_tdt
<< " Q_OiaR= " << Q_OiaR << " -> divergence ! "
<< "\n Hysteresis3D::Coincidence(... " << endl;
// on génère une exception
throw ErrNonConvergence_loiDeComportement();
};
// calcul du reste d'incrément de déformation qu'il faut utiliser pour la suite
delta_barre_epsBH *= (1.-racine2); // (1.-racine2) est >= 0
// mise à jour des différents pointeurs
Gestion_pointeur_coincidence(unSur_wBaseCarre,save_resul,W_a
,iatens,iadef_equi,iafct,pt_sur_principal,iaOi,oi_sur_principal
,iatens_princ,iadef_equi_princ,iaOi_princ,iafct_princ);
// fin et retour, comme le calcul n'est pas fini on retourne false
return false;
};
// traitement des cas où des autres coincidences existent à la précision près
// ramène true si effectivement il y a une nouvelle coincidence
bool Hysteresis3D::Autre_coincidence_a_la_tolerance_pres(bool bascule_fct_aide
,const Tenseur3HH & gijHH,const Tenseur3BB & gijBB
,const bool& pt_sur_principal,const bool& oi_sur_principal
,List_io <Tenseur3BH>::iterator& iatens
,List_io <Tenseur3BH>::iterator& iaOi)
{ // choix entre gestion avec rayons ou avec fonction d'aide
if (!bascule_fct_aide)
{// on va calculer le nouveau rayon et voir s'il y a de nouveau coincidence ou pas
// -- 1) sigma_barre_BH_R : initialisé sur la liste principal, mais ensuite peut évoluer sur liste secondaire
if (aucun_pt_inversion) {sigma_barre_BH_R.Inita(0.);def_equi_R=0.;}
else {sigma_barre_BH_R = *iatens; // la contrainte de référence
};
delta_sigma_barre_BH_Rat = sigma_i_barre_BH - sigma_barre_BH_R;
// -- 2) centre et rayon de la première surface de coïncidence
if (centre_initial) {oc_BH_R.Inita(0.);}
else {oc_BH_R = *iaOi;};
delta_sigma_barre_BH_OiaR = sigma_barre_BH_R-oc_BH_R; // le tenseur rayon
// -- 3) calcul du rayon: la première fois le rayon est infini
if (aucun_pt_inversion) {Q_OiaR = ConstMath::tresgrand;}
else {Q_OiaR = sqrt(delta_sigma_barre_BH_OiaR.II());};
// calcul du rayon actuelle, avec le nouveau centre éventuelle
Tenseur3BH delta_sigma_oi_a_tdt_BH = sigma_t_barre_tdt - oc_BH_R; // OA
double nouveau_rayon_tdt = sqrt(delta_sigma_oi_a_tdt_BH.II());
// on test
bool retour;
if (nouveau_rayon_tdt < Q_OiaR) {retour = false;} // cas normal
else {retour = true; }; // cas où il y a une nouvelle coincidence
// une nouvelle coincidence est possible si l'ancien rayon de référence et le nouveau ont une
// différence inférieure à la précision de la coincidence !!
//--------débug- traçage
#ifdef MISE_AU_POINT
if ((Permet_affichage() == -77)&&retour)
{ cout << "\n nouvelle coïncidence: cas de points tres rapprochees "
<< endl ;
};
#endif
//----- fin débug
return retour;
}
else // cas d'une gestion avec la fonction d'aide
{// pour l'instant on ne fait rien, s'il y a plusieurs coïncidence à suivre
// on passera plusieurs fois dans l'algo coïncidence
return false;
};
};
// 2) affinage d'un point de coincidence à l'aide de la fonction d'aide
// ramène true si le traitement est exactement terminé, sinon false, ce qui signifie qu'il
// faut encore continuer à utiliser l'équation d'évolution
// premiere_charge : indique si c'est oui ou non une coincidence avec la première charge
// pt_sur_principal : indique si oui ou non les pointeurs iafct et iatens pointent sur les listes
// principales
// iatens_princ et iafct_princ: pointeurs sur les listes principales
bool Hysteresis3D::Coincidence(bool bascule_fct_aide,double& unSur_wBaseCarre
,const Tenseur3HH & gijHH,const Tenseur3BB & gijBB
,SaveResulHysteresis3D & save_resul,double& W_a
,List_io <Tenseur3BH>::iterator& iatens
,List_io <double>::iterator& iadef_equi
,List_io <double>::iterator& iafct
,bool& pt_sur_principal
,List_io <Tenseur3BH>::iterator& iaOi,bool& oi_sur_principal
,List_io <Tenseur3BH>::iterator& iatens_princ
,List_io <double>::iterator& iadef_equi_princ
,double& position_coincidence
,List_io <Tenseur3BH>::iterator& iaOi_princ
,List_io <double>::iterator& iafct_princ
,double& delta_W_a,bool force_coincidence)
{ // tout d'abord on vérifie que l'on n'est pas exactement à un point de
// coincidence à la précision près
double c = (W_a - delta_W_a) - *iafct;
bool coin_exacte = false; // drapeau indiquant si l'on a une coincidence exacte ou pas
// calcul de la précision
double tol_coincidence_reelle = tolerance_coincidence;
if (tolerance_coincidence < 0) // si l'indication est négative , cela veut dire que l'on veut une grandeur négative
tol_coincidence_reelle = MaX(-tolerance_coincidence * W_a,-tolerance_coincidence);
if ((Abs(W_a - *iafct) <= tol_coincidence_reelle) || force_coincidence
|| (c >= 0.) ) // on ne peut plus revenir sur les grandeurs à t
// donc le mieux est de valider la coïncidence ce qui simplifiera la suite du traitement
{ // on est dans le cas où l'on a une coïncidence exacte à la précision "tolerance_coincidence" près
// mais dans tous les cas on a rayon_tdt > Q_OiaR sinon on n'aurait pas de coïncidence
// on signale qu'il y a une coincidence exacte (pour le retour de la méthode Coincidence)
// gestion des pointeurs
do
{ // on prend pour W_a la valeur au moment de la coïncidence ce qui permet d'éviter des approximations futures
W_a = *iafct;
Gestion_pointeur_coincidence(unSur_wBaseCarre,save_resul,W_a
,iatens,iadef_equi,iafct,pt_sur_principal,iaOi,oi_sur_principal
,iatens_princ,iadef_equi_princ,iaOi_princ,iafct_princ);
}// on traite le cas où des autres coincidences existent à la précision près
while (Autre_coincidence_a_la_tolerance_pres(bascule_fct_aide,gijHH,gijBB,pt_sur_principal
,oi_sur_principal,iatens,iaOi));
coin_exacte = true;position_coincidence=1.;
return coin_exacte;
};
// --- sinon on continue
// recherche de racine
double racine2;
// // c doit-être négatif, à la limite nul
// if (c >= 0.)
// {// on détermine la proportion de déformation qu'il faut faire pour être exactement à la coïncidence
// double W_t=W_a - delta_W_a;
// racine2 = (W_a - *iafct) / delta_W_a;
// }
// else
{ // on utilise une interpolation assez grossière à l'aide de la fonction de charge
// cout << "\n on passe par l'interpolation de la fonction d'aide";
double W_t=W_a - delta_W_a;
racine2 = (*iafct - W_t) / delta_W_a;
#ifdef MISE_AU_POINT
// normalement racine2 est compris entre 0 et 1
if ( (racine2 < 0.) || (racine2 > 1.))
{ cout << "\n erreur algo coincidence, dans la recherche de racine2 a l'aide de la fonction de charge "
<< " W_ref= " <<*iafct<<" W_t= " << W_t << " delta_W_a= " << delta_W_a
<< "\n Hysteresis1D::Coincidence(... ";
Sortie(1);
}
#endif
}
// -- maintenant on traite les infos
// comme racine2 appartient à [0,1], que OiR > Oisigma_t et que OiR < Oisigma_tdt, normalement on doit avoir
// Oisigma_tdt > Oisigma_coinci
// -- cas où à l'issue du calcul racines est très proche de 1 ---
// dans ce cas on considère que la coïncidence est exacte
if (sqrt(((1.-racine2)*delta_sigma_barre_tdt_BH).II()) <= tol_coincidence_reelle)
{ // on est dans le cas où l'on a une coïncidence exacte à la précision "tolerance_coincidence" près
// mais dans tous les cas on a rayon_tdt > Q_OiaR sinon on n'aurait pas de coïncidence
// on signale qu'il y a une coincidence exacte (pour le retour de la méthode Coincidence)
// gestion des pointeurs
do
{// on prend pour W_a la valeur au moment de la coïncidence ce qui permet d'éviter des approximations futures
W_a = *iafct;
Gestion_pointeur_coincidence(unSur_wBaseCarre,save_resul,W_a
,iatens,iadef_equi,iafct,pt_sur_principal,iaOi,oi_sur_principal
,iatens_princ,iadef_equi_princ,iaOi_princ,iafct_princ);
}// on traite le cas où des autres coincidences existent à la précision près
while (Autre_coincidence_a_la_tolerance_pres(bascule_fct_aide,gijHH,gijBB
,pt_sur_principal,oi_sur_principal,iatens,iaOi));
coin_exacte = true;position_coincidence=1.;
return coin_exacte;
};
// -- sinon cela veut dire que la coïncidence n'est pas précise, au lieu de chercher à calculer
// le tenseur sigma à l'aide d'une péréquation, on ne valide pas la coïncidence, par contre
// on ramène la valeur de la proportion racine2 indiquant la position approximative de l'inversion exacte
// // calcul de la valeur de sigma au point de coincidence, qui servira pour un nouveau calcul
// sigma_i_barre_BH += racine2 * delta_sigma_barre_tdt_BH;
//
// // calcul du reste d'incrément de déformation qu'il faut utiliser pour la suite
// delta_barre_epsBH *= (1.-racine2); // (1.-racine2) est >= 0
// // mise à jour des différents pointeurs
// Gestion_pointeur_coincidence(unSur_wBaseCarre,save_resul
// ,iatens,iadef_equi,iafct,pt_sur_principal,iaOi,oi_sur_principal
// ,iatens_princ,iadef_equi_princ,iaOi_princ,iafct_princ);
//
// // fin et retour, comme le calcul n'est pas fini on retourne false
coin_exacte = false;position_coincidence=racine2;
return coin_exacte;
};
// calcul de wprime en fonction de grandeurs supposées déjà calculées
// --- méthode indépendante -----
// utilise : Q_OiaR, QdeltaSigmaRatdt,
// delta_sigma_barre_BH_Ratdt, delta_sigma_barre_BH_OiaR
// wBase
// trajet_neutre: indique si oui ou non, on est dans un chargement neutre à la précision près
void Hysteresis3D::Cal_wprime(const double& Q__deltaSiRatdt,const Tenseur3BH& delta__sig_barre_BH_Ratdt
,const double& Q__OiaR,const Tenseur3BH& delta__sig_barre_BH_OiaR
,const double& w__Base,Tenseur3BH& delta__sig_barre_BH_tatdt
, double& w__prime, double& w__prime_point,bool& trajet_neut) const
{ // -- calculs relatifs aux angles de phases
// ces calculs ne sont nécessaires que si l'on n'est pas sur une première charge
if (w__Base!=1)
{// si l'intensité du rayon est nulle, celui de seconde charge doit
// être également nulle, on considére un alpha nulle donc un cos = 1 d'où w__prime = 2.
if (Q__OiaR >= mini_rayon) // si mini_rayon est négatif (=> régularisation), l'expression est tjs vrai
{// si l'intensité de l'accroissement du déviateur de contrainte est nulle,
// on considére un alpha nulle donc un cos = 1 d'où w__prime = 2.
if (Q__deltaSiRatdt >= mini_rayon) // idem test si dessus pour le cas où mini_rayon est négatif
{// cas où on peut calculer l'angle
// -- calcul de w__prime
double unSurQ__OiaR ; //= 1./Q__OiaR;
double unSurQ__deltaSiRatdt ;//= 1./Q__deltaSiRatdt;
if (mini_rayon > 0.) // cas historique
{ unSurQ__OiaR = 1./Q__OiaR;
unSurQ__deltaSiRatdt = 1./Q__deltaSiRatdt;
}
else // cas avec régularisation
{ unSurQ__OiaR = 1./(Q__OiaR-mini_rayon);
unSurQ__deltaSiRatdt = 1./(Q__deltaSiRatdt-mini_rayon);
};
double cos_alpha = - (delta__sig_barre_BH_Ratdt && delta__sig_barre_BH_OiaR)
* unSurQ__OiaR * unSurQ__deltaSiRatdt;
// if (Dabs(cos_alpha)<= ConstMath::pasmalpetit)
if (Dabs(cos_alpha)<= min_angle_trajet_neutre)
{ // dans ce cas il s'agit d'un trajet neutre
// le cos_alpha, sa dérivée, les w_prime et w_prime_point n'auront pas au final d'importance
trajet_neut=true;
w__prime=0.; w__prime_point=0.;
}
else if ((cos_alpha <= - min_angle_trajet_neutre) && (!possibilite_cosAlphaNegatif))
{ // cas ou cos_alpha est négatif et que l'on veut traiter ce cas comme un cas neutre
// le cos_alpha, sa dérivée, les w_prime et w_prime_point n'auront pas au final d'importance
trajet_neut=true;
w__prime=0.; w__prime_point=0.;
}
else
{ // chargement non neutre
trajet_neut = false;
w__prime = w__Base * cos_alpha;
if ((w__prime <= 0) && (possibilite_cosAlphaNegatif))
{ // dans le cas où cos_alpha est négatif et que l'on admet "transitoirement" que le cos_alpha puisse
// être négatif, on lui change de signe (cf. les anciens commentaires qui suivent)
// C1- il y a problème car cela signifie que cos_alpha est négatif donc que les cercles s'accroissent
// C1- ceci peut être du à une erreur d'arrondi
// C1- on considère alors que l'on est au cas limite de cos_alpha = 0`
// C2-- non en fait ça peut-être tout-à-fait normale, juste avant une inversion on a un angle négatif et c'est normale
// C2-- pour éviter d'avoir des pb le plus simple est de considérer la partie positive de l'angle
// -- if (MaX(ParaGlob::NiveauImpression(),Permet_affichage()) >= 3)
// -- cout << "\n attention, angle de phase negatif en hysteresis ! ,";
// << " on le met a 0";
// if (MaX(ParaGlob::NiveauImpression(),Permet_affichage()) >= 4)
// cout << " Q__deltaSiRatdt= " << Q__deltaSiRatdt << " w__prime= " << w__prime;
// w__prime = 2.;w__prime_point=0.;
w__prime = - w__prime;
double Rsig_point_scalaire_Rsig = delta__sig_barre_BH_tatdt && delta__sig_barre_BH_Ratdt;
double ee = Rsig_point_scalaire_Rsig * unSurQ__deltaSiRatdt * unSurQ__deltaSiRatdt;
double cos_alpha_point = - unSurQ__OiaR * unSurQ__deltaSiRatdt
* (delta__sig_barre_BH_OiaR &&
(delta__sig_barre_BH_tatdt - ee * delta__sig_barre_BH_Ratdt )) ;
w__prime_point = - w__Base * cos_alpha_point;
}
else
{// -- calcul de w__prime_point
double Rsig_point_scalaire_Rsig = delta__sig_barre_BH_tatdt && delta__sig_barre_BH_Ratdt;
double ee = Rsig_point_scalaire_Rsig * unSurQ__deltaSiRatdt * unSurQ__deltaSiRatdt;
double cos_alpha_point = - unSurQ__OiaR * unSurQ__deltaSiRatdt
* (delta__sig_barre_BH_OiaR &&
(delta__sig_barre_BH_tatdt - ee * delta__sig_barre_BH_Ratdt )) ;
w__prime_point = w__Base * cos_alpha_point;
};
}; // fin du cas non neutre
} // fin du cas où on peut calculer l'angle
else
// cas ou l'intensité de l'accroissement du déviateur de contrainte est nulle
{w__prime = 2.;w__prime_point=0.;trajet_neut = false;}; // cas de cos(alpha)=1.
}
else
// cas ou l'intensité du déviateur de référence est nulle
{w__prime = 2.;w__prime_point=0.;trajet_neut = false;}; // cas de cos(alpha)=1.
}
else
// cas d'une première charge
{w__prime=1.;w__prime_point=0.;trajet_neut = false;};
};
// calcul de wprime et de sa variation par rapport aux coordonnées de delta sigma barre
// en fonction de grandeurs supposées déjà calculées
// utilise : Q_OiaR, QdeltaSigmaRatdt,
// delta_sigma_barre_BH_Ratdt, delta_sigma_barre_BH_OiaR
// wBase
// trajet_neut: indique si oui ou non, on est dans un chargement neutre à la précision près
// --- méthode indépendante -----
void Hysteresis3D::Cal_wprime_et_der(const double& Q__deltaSiRatdt,const Tenseur3BH& delta__sig_barre_BH_Ratdt
,const double& Q__OiaR,const Tenseur3BH& delta__sig_barre_BH_OiaR
,const double& w__Base,Tenseur3BH& delta__sig_barre_BH_tatdt
,double& w__prime, Tenseur3BH& d_w__prime
,double& w__prime_point,Tenseur3BH& d_w__prime_point,bool& trajet_neut) const
{ // -- calculs relatifs aux angles de phases
static const double untiers=1./3.;static const double troisRacineDe6=3.*sqrt(6.);
// ces calculs ne sont nécessaires que si l'on n'est pas sur une première charge
d_w__prime.Inita(0.); // init pour tous les cas ou d_w__prime n'est pas calculée
// cf les différents cas qui suivent
d_w__prime_point.Inita(0.); // idem pour le w__prime_point
if (w__Base!=1)
{// si l'intensité du rayon est nulle, celui de seconde charge doit
// être également nulle, on considére un alpha nulle donc un cos = 1 d'où w__prime = 2.
// d'où des variations nulles
if (Q__OiaR >= mini_rayon) // si mini_rayon est négatif (=> régularisation), l'expression est tjs vrai
{// si l'intensité de l'accroissement du déviateur de contrainte est nulle,
// on considére un alpha nulle donc un cos = 1 d'où w__prime = 2.
if (Q__deltaSiRatdt >= mini_rayon) // idem test si dessus pour le cas où mini_rayon est négatif
{// cas où on peut calculer l'angle
double unSurQ__OiaR ;//= 1./Q__OiaR;
double unSurQ__deltaSiRatdt;// = 1./Q__deltaSiRatdt;
if (mini_rayon > 0.) // cas historique
{ unSurQ__OiaR = 1./Q__OiaR;
unSurQ__deltaSiRatdt = 1./Q__deltaSiRatdt;
}
else // cas avec régularisation
{ unSurQ__OiaR = 1./(Q__OiaR-mini_rayon);
unSurQ__deltaSiRatdt = 1./(Q__deltaSiRatdt-mini_rayon);
}
double x1 = delta__sig_barre_BH_Ratdt && delta__sig_barre_BH_OiaR;
double cos_alpha = - x1* unSurQ__OiaR * unSurQ__deltaSiRatdt;;
// if (Dabs(cos_alpha)<= ConstMath::pasmalpetit)
if (Dabs(cos_alpha)<= min_angle_trajet_neutre)
{ // dans ce cas il s'agit d'un trajet neutre
// le cos_alpha, sa dérivée, les w_prime et w_prime_point n'auront pas au final d'importance
trajet_neut=true;
w__prime=0.; w__prime_point=0.;
}
else if ((cos_alpha <= - min_angle_trajet_neutre) && (!possibilite_cosAlphaNegatif))
{ // cas ou cos_alpha est négatif et que l'on veut traiter ce cas comme un cas neutre
// le cos_alpha, sa dérivée, les w_prime et w_prime_point n'auront pas au final d'importance
trajet_neut=true;
w__prime=0.; w__prime_point=0.;
}
else
{ // chargement non neutre
trajet_neut = false;
w__prime = w__Base * cos_alpha;
if ((w__prime <= 0) && (possibilite_cosAlphaNegatif))
{ // dans le cas où cos_alpha est négatif et que l'on admet "transitoirement" que le cos_alpha puisse
// être négatif, on lui change de signe (cf. les anciens commentaires qui suivent)
// C1- il y a problème car cela signifie que cos_alpha est négatif donc que les cercles s'accroissent
// C1- ceci peut être du à une erreur d'arrondi
// C1- on considère alors que l'on est au cas limite de cos_alpha = 0`
// C2-- non en fait ça peut-être tout-à-fait normale, juste avant une inversion on a un angle négatif et c'est normale
// C2-- pour éviter d'avoir des pb le plus simple est de considérer la partie positive de l'angle
// if (MaX(ParaGlob::NiveauImpression(),Permet_affichage()) >= 3)
// cout << "\n attention, angle de phase negatif en hysteresis ! ,";
// << " on le met a 0";
// if (MaX(ParaGlob::NiveauImpression(),Permet_affichage()) >= 6)
// cout << " Q__deltaSiRatdt= " << Q__deltaSiRatdt ;
// w__prime = 2.;w__prime_point=0.; */
w__prime = - w__prime;
// -- calcul de w__prime_point
double a ;//= Q__deltaSiRatdt * Q__deltaSiRatdt;
if (mini_rayon > 0.) // cas historique
{ a = Q__deltaSiRatdt * Q__deltaSiRatdt;}
else // cas avec régularisation
{ a = Q__deltaSiRatdt * Q__deltaSiRatdt-mini_rayon;};
double b = delta__sig_barre_BH_tatdt && delta__sig_barre_BH_Ratdt;
double ee = b/a;
double C = delta__sig_barre_BH_OiaR && (delta__sig_barre_BH_tatdt - ee * delta__sig_barre_BH_Ratdt);
double cos_alpha_point = (- unSurQ__OiaR * unSurQ__deltaSiRatdt) * C;
w__prime_point = - w__Base * cos_alpha_point;
// calcul de la variation de cos_alpha et donc de w__prime
Tenseur3BH d_aSur2_BH(delta__sig_barre_BH_Ratdt);
d_aSur2_BH.PermuteHautBas();
Tenseur3BH num_cos_BH(delta__sig_barre_BH_OiaR);num_cos_BH.PermuteHautBas();
d_w__prime = d_aSur2_BH * (cos_alpha * unSurQ__deltaSiRatdt * unSurQ__deltaSiRatdt*w__Base)
+ num_cos_BH * (unSurQ__deltaSiRatdt * unSurQ__OiaR*w__Base);
// d_w__prime = d_a_BH;
// d_w__prime *= (x1/(Q__deltaSiRatdt*Q__deltaSiRatdt)-1)/(Q__deltaSiRatdt*Q__OiaR);
// calcul de la variation de cos_alpha_point
Tenseur3BH d_b_BH(delta__sig_barre_BH_tatdt);
d_b_BH.PermuteHautBas();
d_b_BH += d_aSur2_BH;
double unSur_a2 = 1./(a*a);
Tenseur3BH d_e_BH = d_b_BH / a - (2.* b*unSur_a2)*d_aSur2_BH;
d_w__prime_point = (w__Base * unSurQ__OiaR) *
( (- unSurQ__deltaSiRatdt / a * C)*d_aSur2_BH
+ ((1.-ee)*unSurQ__deltaSiRatdt) * num_cos_BH
+ (-unSurQ__deltaSiRatdt * x1)* d_e_BH
);
}
else
{// -- calcul de w__prime_point
double a ;//= Q__deltaSiRatdt * Q__deltaSiRatdt;
if (mini_rayon > 0.) // cas historique
{ a = Q__deltaSiRatdt * Q__deltaSiRatdt;}
else // cas avec régularisation
{ a = Q__deltaSiRatdt * Q__deltaSiRatdt-mini_rayon;};
double b = delta__sig_barre_BH_tatdt && delta__sig_barre_BH_Ratdt;
double ee = b/a;
double C = delta__sig_barre_BH_OiaR && (delta__sig_barre_BH_tatdt - ee * delta__sig_barre_BH_Ratdt);
double cos_alpha_point = (- unSurQ__OiaR * unSurQ__deltaSiRatdt) * C;
w__prime_point = w__Base * cos_alpha_point;
// calcul de la variation de cos_alpha et donc de w__prime
Tenseur3BH d_aSur2_BH(delta__sig_barre_BH_Ratdt);
d_aSur2_BH.PermuteHautBas();
Tenseur3BH num_cos_BH(delta__sig_barre_BH_OiaR);num_cos_BH.PermuteHautBas();
d_w__prime = d_aSur2_BH * (- cos_alpha * unSurQ__deltaSiRatdt * unSurQ__deltaSiRatdt*w__Base)
- num_cos_BH * (unSurQ__deltaSiRatdt * unSurQ__OiaR*w__Base);
// d_w__prime = d_a_BH;
// d_w__prime *= (x1/(Q__deltaSiRatdt*Q__deltaSiRatdt)-1)/(Q__deltaSiRatdt*Q__OiaR);
// calcul de la variation de cos_alpha_point
Tenseur3BH d_b_BH(delta__sig_barre_BH_tatdt);
d_b_BH.PermuteHautBas(); d_b_BH += d_aSur2_BH;
double unSur_a2 = 1./(a*a);
Tenseur3BH d_e_BH = d_b_BH / a - (2.*b*unSur_a2)*d_aSur2_BH;
d_w__prime_point = (-w__Base * unSurQ__OiaR) *
( (- unSurQ__deltaSiRatdt / a * C)*d_aSur2_BH
+ ((1.-ee)*unSurQ__deltaSiRatdt) * num_cos_BH
+ (-unSurQ__deltaSiRatdt * x1)* d_e_BH
);
};
}// fin du cas non neutre
}// fin du cas où on peut calculer l'angle
else
// cas ou l'intensité de l'accroissement du déviateur de contrainte est nulle
{w__prime = 2.;w__prime_point=0.;trajet_neut = false;}; // cas de cos(alpha)=1.
}
else
// cas ou l'intensité du déviateur de référence est nulle
{w__prime = 2.;w__prime_point=0.;trajet_neut = false;}; // cas de cos(alpha)=1.
}
else
// cas d'une première charge
{w__prime=1.;w__prime_point=0.;trajet_neut = false;};
};
// calcul du centre d'inversion avec les données actuelles
// ramène un indicateur informant comment l'opération s'est passé et si elle est valide (= 0)
int Hysteresis3D::CentreCercle(Tenseur3BH& sig0i_BH,const Tenseur3BH& oc_BH_R
,const Tenseur3BH & delta_sigma_barre_BH_OiaR
,const Tenseur3BH& delta_sigma_barre_BH_Rat)
{ // on part du principe que c'est le point à t qui est le point d'inversion
// ceci a été déterminé par le fait que le rayon à tdt a été trouvé plus petit que celui a t
double rayon_t = sqrt((delta_sigma_barre_BH_OiaR + delta_sigma_barre_BH_Rat).II());
double delta_rayon2 = (rayon_t*rayon_t - Q_OiaR*Q_OiaR);
// ici ce n'est pas le vrai cos, mais le cos * les deux normes, mais le signe est le même
double cos_alpha_a_t = (delta_sigma_barre_BH_OiaR && delta_sigma_barre_BH_Rat);
// double gamma = 0.5 * (rayon_t*rayon_t - Q_OiaR*Q_OiaR)
// / (delta_sigma_barre_BH_OiaR && delta_sigma_barre_BH_Rat);
int retour = 0; // init du retour a priori
// --- mise à jour précision éventuelle
double tol_centre_reelle = tolerance_centre;
if (tolerance_centre < 0) // si l'indication est négative , cela veut dire que l'on veut une grandeur relative
tol_centre_reelle = MaX(-tolerance_centre * Q_OiaR,-tolerance_centre);
// ---
// en fait peut-être très proche de 0 du aux erreurs d'arrondi
if (Dabs(delta_rayon2) < tol_centre_reelle)
// à la tolérance près on a le même rayon, cela veut dire qu'à l'incrément précédent on était sur un trajet
// neutre à la précision près, donc pas de nouveau centre à calculer
{retour = 1;}
else if (delta_rayon2 > 0.) // et donc sup aussi à tol_centre_reelle compte tenu du test plus haut
// là il s'agit d'un comportement qui n'est pas normal, car normalement le nouveau rayon doit-être plus petit
// que l'ancien donc on n'a pas de point d'inversion probant (ce serait plutôt une coïncidence mal déterminée)
// il vaut mieux attendre un incrément de charge supérieure qui permettra d'avoir
// un point d'inversion correctement déterminé
{retour = 1;} // on signale que ce n'est pas la peine de calculer un nouveau centre
else if (Dabs(cos_alpha_a_t) < min_angle_trajet_neutre)
// maintenant il faut que le cos_alpha ne soit pas trop petit
// si oui on était alors sur un trajet neutre qui s'ignorait, là encore le point d'inversion n'est pas probant
// il vaut mieux attendre un incrément de charge supérieure qui permettra d'avoir
// un point d'inversion correctement déterminé
{retour = 1;} // on signale que ce n'est pas la peine de calculer un nouveau centre
else if (cos_alpha_a_t > 0.) // et donc sup aussi à min_angle_trajet_neutre compte tenu du test plus haut
// c'est pas non plus normal, cela veut dire que l'on se déplace vers l'extérieur de la sphére de ref
// donc ce n'est pas un point d'inversion correct
{retour = 1;} // on signale que ce n'est pas la peine de calculer un nouveau centre
else
// arrivée ici toutes les conditions sont bonnes pour calculer un point d'inversion correct
{double gamma = 0.5 * delta_rayon2 / cos_alpha_a_t;
sig0i_BH = oc_BH_R + gamma * delta_sigma_barre_BH_OiaR;
};
// message d'info au cas où
if (retour)
2023-05-03 17:23:49 +02:00
if (Permet_affichage() > 5)
2021-09-23 11:21:15 +02:00
{ double cosalpha = (delta_sigma_barre_BH_OiaR && delta_sigma_barre_BH_Rat)
/sqrt((delta_sigma_barre_BH_OiaR.II()*delta_sigma_barre_BH_Rat.II()));
cout << "\n info concernant le calcul de centre, le centre ne peut-etre calcule ce qui n'est peut-etre pas normal !! "
<< "\n Hysteresis3D::CentreCercle(..."
<< " rayon_t= " << rayon_t << " Q_OiaR= " <<Q_OiaR
<< " cos_alpha_a_t= cos (delta_sigma_barre_BH_OiaR, delta_sigma_barre_BH_Rat) "
<< cosalpha << endl;
//// -- debug
// cout << "\n debug Hysteresis3D::CentreCercle( ";
// Q_OiaR = sqrt(delta_sigma_barre_BH_OiaR.II());
// double delta_RT2 = delta_sigma_barre_BH_Rat && delta_sigma_barre_BH_Rat;
// double delta_oiaR2 = delta_sigma_barre_BH_OiaR && delta_sigma_barre_BH_OiaR;
// double oiaRfoisRat = delta_sigma_barre_BH_OiaR && delta_sigma_barre_BH_Rat;
// double rayont2 = (delta_sigma_barre_BH_OiaR + delta_sigma_barre_BH_Rat) && (delta_sigma_barre_BH_OiaR + delta_sigma_barre_BH_Rat);
// cout << "\n nouvelle valeur Q_OiaR = " << Q_OiaR << endl;
//// -- fin debug
};
// retour
return retour;
};
// gestion d'un dépilement des pointeurs dans les listes, dans le cas d'une coïncidence
// met à jour les booléens interne à l'instance : aucun_pt_inversion et centre_initial
void Hysteresis3D::Gestion_pointeur_coincidence(double& unSur_wBaseCarre
,SaveResulHysteresis3D & save_resul,double& W_a
,List_io <Tenseur3BH>::iterator& iatens
,List_io <double>::iterator& iadef_equi
,List_io <double>::iterator& iafct
,bool& pt_sur_principal
,List_io <Tenseur3BH>::iterator& iaOi,bool& oi_sur_principal
,List_io <Tenseur3BH>::iterator& iatens_princ
,List_io <double>::iterator& iadef_equi_princ
,List_io <Tenseur3BH>::iterator& iaOi_princ
,List_io <double>::iterator& iafct_princ)
{ // 1-- cas de pt de ref: si on pointe sur la liste secondaire on retire le dernier élément
if (!pt_sur_principal)
{
if (iatens != save_resul.sigma_barre_BH_R_t_a_tdt.begin())
2023-05-03 17:23:49 +02:00
{ if (Permet_affichage() > 0)
2021-09-23 11:21:15 +02:00
cout << "\n incoherence, on devrait avoir ici le premier element de la liste secondaire"
<< " des sig d'inversion"
<< "\n Hysteresis3D::Gestion_pointeur_coïncidence(..."<< endl;
2023-05-03 17:23:49 +02:00
if (Permet_affichage() > 4)
2021-09-23 11:21:15 +02:00
Affiche_debug(unSur_wBaseCarre,save_resul,iatens,iadef_equi,pt_sur_principal
,iaOi,oi_sur_principal,iatens_princ,iadef_equi_princ,iaOi_princ);
// on génère une exception
throw ErrNonConvergence_loiDeComportement();
};
// comme on est sur la liste secondaire, cela signifie qu'elle n'est pas vide en point d'inversion
// donc on peut supprimer une contrainte d'inversion
save_resul.sigma_barre_BH_R_t_a_tdt.erase(iatens); // normalement c'est le premier de la liste!
save_resul.def_equi_t_a_tdt.erase(iadef_equi); // idem pour def_equi qui suit la même logique
save_resul.fct_aide_t_a_tdt.erase(iafct); // idem pour la fonction d'aide
// save_resul.nb_coincidence--; // on dépile également le nombre de coïncidence active
if (save_resul.sigma_barre_BH_R_t_a_tdt.size()==0)
{// il ne reste plus d'élément on revient sur la liste principal
pt_sur_principal = true;
iatens = iatens_princ; iadef_equi=iadef_equi_princ;iafct=iafct_princ;
// on regarde si le pointeur est valide
if (iatens != save_resul.sigma_barre_BH_R.end())
{aucun_pt_inversion = false;}
else {aucun_pt_inversion = true;};
}
else // cas où il reste des éléments sur les listes secondaires
{iatens = save_resul.sigma_barre_BH_R_t_a_tdt.begin();aucun_pt_inversion = false;
iadef_equi = save_resul.def_equi_t_a_tdt.begin();
iafct = save_resul.fct_aide_t_a_tdt.begin();
};
}
else // cas où on pointe sur la liste principal, on se déplace dans la liste principal,
{ // sans éliminer d'élément : on update le pointage
if (iatens != save_resul.sigma_barre_BH_R.end())
{iatens++;iadef_equi++;// idem pour def_equi et iafct qui suivent une même logique
// mais il faut mettre à jour la fonction d'aide par rapport à la valeur
// qu'elle avait au point d'inversion précédent sinon, c'est perdue
W_a = *iafct;
iafct++; // idem pour def_equi et iafct qui suivent une même logique
// on regarde si le pointeur est valide
if (iatens != save_resul.sigma_barre_BH_R.end()) {aucun_pt_inversion = false;}
else {aucun_pt_inversion = true;};
save_resul.nb_coincidence++; // on acte la coïncidence
// comme on est sur la liste principale, on met à jour les pointeurs de la liste principale
iatens_princ = iatens;iadef_equi_princ=iadef_equi;iafct_princ = iafct;
}
else // sinon il y a un pb car comme c'est une coïncidence il devrait rester un pointeur valide
2023-05-03 17:23:49 +02:00
{if (Permet_affichage() > 0)
2021-09-23 11:21:15 +02:00
cout << "\n incoherence, il devrait rester un pointeur de valide sur la liste de pt de ref"
<< "\n Hysteresis3D::Gestion_pointeur_coincidence(..." << endl;
2023-05-03 17:23:49 +02:00
if (Permet_affichage() > 4)
2021-09-23 11:21:15 +02:00
Affiche_debug(unSur_wBaseCarre,save_resul,iatens,iadef_equi,pt_sur_principal
,iaOi,oi_sur_principal,iatens_princ,iadef_equi_princ,iaOi_princ);
// cout << "\n tapper quelque chose ";
// string toto; cin >> toto;
// on génère une exception
throw ErrNonConvergence_loiDeComportement();
};
};
// 2-- cas des centres : si on pointe sur la liste secondaire on retire le dernier élément
if (!oi_sur_principal)
{
if (iaOi != save_resul.oc_BH_t_a_tdt.begin())
2023-05-03 17:23:49 +02:00
{ if (Permet_affichage() > 0)
2021-09-23 11:21:15 +02:00
cout << "\n incoherence, on devrait avoir ici le premier element de la liste secondaire des centres"
<< "\n Hysteresis3D::Gestion_pointeur_coïncidence(..."<< endl;
2023-05-03 17:23:49 +02:00
if (Permet_affichage() > 4)
2021-09-23 11:21:15 +02:00
Affiche_debug(unSur_wBaseCarre,save_resul,iatens,iadef_equi,pt_sur_principal
,iaOi,oi_sur_principal,iatens_princ,iadef_equi_princ,iaOi_princ);
// on génère une exception
throw ErrNonConvergence_loiDeComportement();
};
// on regarde si on peut supprimer un centre
if (iaOi != save_resul.oc_BH_t_a_tdt.end()) // dans le cas où l'origine est 0, il n'y a rien de sauvegardé
save_resul.oc_BH_t_a_tdt.erase(iaOi); // sinon normalement c'est le premier de la liste!
if (save_resul.oc_BH_t_a_tdt.size()==0)
{// il ne reste plus d'élément on revient sur la liste principal
oi_sur_principal = true; iaOi = iaOi_princ;
// on regarde de nouveau si le pointeur de centre est valide
if ((iaOi != save_resul.oc_BH_R.end())) {centre_initial=false;} else {centre_initial=true;};
}
else // cas où il reste des éléments sur les nouvelles listes
{iaOi = save_resul.oc_BH_t_a_tdt.begin(); centre_initial = false;
};
}
else // cas où on pointe sur la liste principal, on se déplace dans la liste principal,
{ // sans éliminer d'élément : on update le pointage
if (iaOi != save_resul.oc_BH_R.end()) // si la liste est vide, c-a-d le centre est le tenseur nulle
iaOi++; // on n'avance pas
// on regarde de nouveau si le pointeur de centre est valide
if ((iaOi != save_resul.oc_BH_R.end())) {centre_initial=false;} else {centre_initial=true;};
// comme on est sur la liste principale, on met à jour les pointeurs de la liste principale
iaOi_princ=iaOi;
};
// 3-- traitement particulier dans le cas où on a rejoint la première charge
if (aucun_pt_inversion) // cas où l'on est sur la courbe de première charge
{ wBase = 1; unSur_wBaseCarre = 1./(wBase*wBase);
}
else
// on met à jour le centre du cercle de référence, en indiquant que l'on a rattrapé une courbe
{ wBase = 2; unSur_wBaseCarre = 1./(wBase*wBase);
};
// gestion du paramètre "modif" de saveresult
bool inversion = false;
Gestion_para_Saveresult_Modif(pt_sur_principal,save_resul,inversion);
//--------débug- traçage
#ifdef MISE_AU_POINT
if (Permet_affichage() == -77)
{ cout << "\ngestion de pointeur de coïncidence ";
cout << " aucun_pt_inversion= " << aucun_pt_inversion
<< " save_resul.nb_coincidence= " << save_resul.nb_coincidence;
cout << " \nsigR_sur_principal= " << pt_sur_principal << ", oi_sur_principal= " << oi_sur_principal
<< " save_resul.modif= " << save_resul.modif
<< " \n nb_Oi= "<<save_resul.oc_BH_R.size() << " nb_sigR= "<<save_resul.sigma_barre_BH_R.size()
<< " || nb_Oi_sec= " << save_resul.oc_BH_t_a_tdt.size()
<< " nb_sigR_sec= " << save_resul.sigma_barre_BH_R_t_a_tdt.size()
<< " || wBase= " << wBase
<< endl ;
};
#endif
//----- fin débug
};
/* // **********calcul d'une dérivée numérique-------------
double peti= 1.E-10;
double lambda_ver = lambda+peti;
double un_sur_1_plus_2_G_lambda_ver = 1. / (1. + deux_G*lambda_ver);
double un_sur_1_plus_2_G_lambda2_ver =
un_sur_1_plus_2_G_lambda_ver * un_sur_1_plus_2_G_lambda_ver;
double alphaa_ver = un_sur_1_plus_2_G_lambda_ver*deux_G;
double alphaa2_ver = un_sur_1_plus_2_G_lambda2_ver * deux_G_carre;
double omega_ver = alphaa_ver*K/(alphaa_ver+2.*K); double omega2_ver = omega_ver*omega_ver;
// a moins que lambda soit très grand on considère qu'omega est positif
// par contre lambda peut-être négatif
// if (lambda >= 0)
double delta_eps_equi_ver = 2.*lambda_ver*omega_ver * eps_elasBH(1,1);
// delta_eps_equi = 2.*lambda*omega * sqrt(c_c);
double epsilon_barre_ver = epsilon_barre_t + // def plastique cumulée
delta_eps_equi_ver;
// nouvelle valeur de la variation de sigma_barre
// et valeur de la tangente de la courbe d'écrouissage
Courbe1D::ValDer valder_ver = f_ecrouissage->Valeur_Et_derivee(epsilon_barre_ver);
double sig_equi_ver = valder_ver.valeur;
// calcul du résidu
double res_plas_ver = 3.*c_c*omega2_ver - sig_equi_ver * sig_equi_ver * un_tiers;
double der1 = 3.*c_c*(omega2_ver-omega2)/peti;
double dereps_barre = (epsilon_barre_ver -epsilon_barre)/peti;
double der2 = un_tiers*(- sig_equi_ver * sig_equi_ver - - sig_equi * sig_equi)/peti;
double der = (res_plas_ver - res_plas)/peti;
double delta_lambda_ver = - res_plas/der ;
// **********fin du calcul de la dérivée numérique------- */
// affichage des informations pour le débug
void Hysteresis3D::Affiche_debug(double& unSur_wBaseCarre
,SaveResulHysteresis3D & save_resul
,List_io <Tenseur3BH>::iterator& iatens
,List_io <double>::iterator& iadef_equi,bool& pt_sur_principal
,List_io <Tenseur3BH>::iterator& iaOi,bool& oi_sur_principal
,const List_io <Tenseur3BH>::iterator& iatens_princ
,const List_io <double>::iterator& iadef_equi_princ
,const List_io <Tenseur3BH>::iterator& iaOi_princ)
{ // affichage de la loi
Affiche();
// départ
cout << "\n -- valeurs initiales -- ";
cout << "\n sigma_barre_BH_t= " << save_resul.sigma_barre_BH_t; // sigma à t
cout << "\n def_equi_at= " << save_resul.def_equi_at; // sigma à t
// variables actuelles
cout << "\n -- variables actuelles -- ";
cout << "\n sigma_t_barre_tdt= " << sigma_t_barre_tdt; // sigma barre finale
cout << "\n sigma_i_barre_BH= " << sigma_i_barre_BH; // sigma barre de début de calcul (à t au début)
cout << "\n sigma_barre_BH_R= " << sigma_barre_BH_R; // sigma barre de Référence en cours
cout << "\n def_equi_R= " << def_equi_R; // déformation équivalente à R
cout << "\n def_i_equi= " << def_i_equi; // dernière déformation équivalente à t
cout << "\n defEqui_maxi= " << defEqui_maxi; // déformation équivalente maxi sur la courbe de première charge
cout << "\n def_equi_atdt= " << def_equi_atdt; // déformation équivalente à tdt
cout << "\n delta_sigma_barre_BH_Rat= " << delta_sigma_barre_BH_Rat; // deltat sigma barre de R a t
cout << "\n delta_sigma_barre_BH_Ratdt= " << delta_sigma_barre_BH_Ratdt; // deltat sigma barre de R a tdt
cout << "\n delta_sigma_barre_tdt_BH= " << delta_sigma_barre_tdt_BH; // delta sigma barre de t à tdt
cout << "\n delta_sigma_barre_BH_OiaR= " << delta_sigma_barre_BH_OiaR; // delta sigma barre de Oi à R
cout << "\n Q_OiaR= " << Q_OiaR; // norme de delta_sigma_barre_BH_OiaR
cout << "\n QdeltaSigmaRatdt= " << QdeltaSigmaRatdt; // norme de rdelta_sigma_barre_BH_Ratdt
cout << "\n oc_BH_R= " << oc_BH_R;
cout << "\n unSur_wBaseCarre= " << unSur_wBaseCarre;
cout << "\n centre_initial= " << centre_initial; // pour gérer le fait qu'au début le centre initial = tenseur nul
cout << "\n aucun_pt_inversion= " << aucun_pt_inversion; // pour gérer le fait qu'au début il n'y a pas de pt d'inversion !
// variables de liste
cout << "\n -- variables de liste -- ";
cout << "\n *iatens= " << *iatens;
cout << "\n *iadef_equi= " << *iadef_equi;
cout << "\n pt_sur_principal= " << pt_sur_principal;
cout << "\n *iaOi= " << *iaOi;
cout << "\n oi_sur_principal= " << oi_sur_principal;
cout << "\n *iatens_princ= " << *iatens_princ;
cout << "\n *iadef_equi_princ= " << *iadef_equi_princ;
cout << "\n *iaOi_princ= " << *iaOi_princ;
// les listes
cout << "\n -- les listes -- ";
cout << "\n save_resul.sigma_barre_BH_R_t_a_tdt= " << save_resul.sigma_barre_BH_R_t_a_tdt;
cout << "\n save_resul.sigma_barre_BH_R= " << save_resul.sigma_barre_BH_R;
cout << "\n save_resul.oc_BH_t_a_tdt= " << save_resul.oc_BH_t_a_tdt;
cout << "\n save_resul.oc_BH_R= " << save_resul.oc_BH_R;
// on vide le buffer
cout << endl;
};