3434 lines
186 KiB
C++
Executable file
3434 lines
186 KiB
C++
Executable file
// 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.
|
|
//
|
|
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
|
|
// AUTHOR : Gérard Rio
|
|
// E-MAIL : gerardrio56@free.fr
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License,
|
|
// or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
// See the GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
//
|
|
// For more information, please consult: <https://herezh.irdl.fr/>.
|
|
|
|
|
|
//#include "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.;
|
|
if ( ((Permet_affichage()==0) && (ParaGlob::NiveauImpression() > 3)) || (Permet_affichage() > 0))
|
|
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
|
|
{ if ( ((Permet_affichage()==0) && (ParaGlob::NiveauImpression() > 3)) || (Permet_affichage() > 0))
|
|
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
|
|
{ if ( ((Permet_affichage()==0) && (ParaGlob::NiveauImpression() > 3)) || (Permet_affichage() > 0))
|
|
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
|
|
if ( ((Permet_affichage()==0) && (ParaGlob::NiveauImpression() > 4)) || (Permet_affichage() > 4))
|
|
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.))
|
|
{ if ( ((Permet_affichage()==0) && (ParaGlob::NiveauImpression() > 3)) || (Permet_affichage() > 0))
|
|
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) )
|
|
if ( ((Permet_affichage()==0) && (ParaGlob::NiveauImpression() > 4)) || (Permet_affichage() > 4))
|
|
{ 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)
|
|
if ( ((Permet_affichage()==0) && (ParaGlob::NiveauImpression() > 5)) || (Permet_affichage() > 5))
|
|
{ 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())
|
|
{ if ( ((Permet_affichage()==0) && (ParaGlob::NiveauImpression() > 3)) || (Permet_affichage() > 0 ))
|
|
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;
|
|
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();
|
|
};
|
|
|
|
// 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
|
|
{if ( ((Permet_affichage()==0) && (ParaGlob::NiveauImpression() > 3)) || (Permet_affichage() > 0))
|
|
cout << "\n incoherence, il devrait rester un pointeur de valide sur la liste de pt de ref"
|
|
<< "\n Hysteresis3D::Gestion_pointeur_coincidence(..." << endl;
|
|
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);
|
|
// 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())
|
|
{ if ( ((Permet_affichage()==0) && (ParaGlob::NiveauImpression() > 3)) || (Permet_affichage() > 0))
|
|
cout << "\n incoherence, on devrait avoir ici le premier element de la liste secondaire des centres"
|
|
<< "\n Hysteresis3D::Gestion_pointeur_coïncidence(..."<< endl;
|
|
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();
|
|
};
|
|
// 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;
|
|
};
|
|
|