Herezh_dev/Algo/GalerkinContinu/AlgoDynaImplicite/AlgoriNewmark.cc
2023-05-03 17:23:49 +02:00

980 lines
54 KiB
C++

// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.
#include "AlgoriNewmark.h"
#include "ConstMath.h"
// CONSTRUCTEURS :
AlgoriNewmark::AlgoriNewmark () : // par defaut
Algori(),beta_newmark(NULL),gamma_newmark(NULL),hht(NULL),stabilite(false)
,delta_t(),delta_t_2(),unSurBetaDeltaTcarre(),betaDelta_t_2()
,betaMoinsGammaSurBeta(),unSurGammaDeltat(),unMoinGamma(),unMoinGammasurgamma()
,zero5deltatcarreUnMoinDeuxBeta(),zero5deltatcarredeuxBeta(),deltatUnMoinGamma()
,deltatGamma(),unsurbetadeltat(),unmoinsdeuxbetasurdeuxbeta(),unSurBetaDeltaTcarre_o()
,nuAphaPrime(),coef_masse(),nuBetaPrime(),coef_raideur(),nuAphaPrimeunsurcoef_masse(),unsurcoef_masse()
//----- cas du masse scaling pilotée
,avec_masse_scaling(false)
,et_pilotage_masse_scaling_par_maxRatioForce_inertieSurStatique(false)
,ou_pilotage_masse_scaling_par_maxRatioForce_inertieSurStatique(false)
,ratioForce_inertieSurStatique(0.)
,et_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur(false)
,ou_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur(false)
,ratioDiag_masseSurRaideur(0.)
,cL_a_chaque_iteration(0)
// --------------------------------------------------------------------------------------
// -- variables de transferts internes entre: InitAlgorithme, CalEquilibre, FinCalcul --
// --------------------------------------------------------------------------------------
,Ass1_(NULL),Ass2_(NULL),Ass3_(NULL),cas_combi_ddl(0),icas(0),prepa_avec_remont(false)
,brestart(false),type_incre(OrdreVisu::INCRE_0),vglobin(),vglobex(),vglobaal()
,vglobal_n(),vglobal_n_inter(),vcontact()
,delta_prec_X(),inter_tdt()
,X_Bl(),V_Bl(),G_Bl(),forces_vis_num(0)
,li_gene_asso(),t_assemb(),tenuXVG(),mat_masse(NULL),mat_C_pt(NULL)
,matglob(NULL),assembMat(NULL),sauve_deltadept(NULL),sauve_dept_a_tdt(NULL)
,tab_mato(1)
,Vres(NULL),v_travail(NULL)
// ------------------------------------------------------------------------------------------
// -- fin variables de transferts internes entre: InitAlgorithme, CalEquilibre, FinCalcul --
// ------------------------------------------------------------------------------------------
{// a priori ce constructeur n'est pas utilisé
cout << "\n $$$$$$$$$ a priori ce constructeur n'est pas utilisable $$$$$$$ "
<< "\n revoir: AlgoriNewmark::AlgoriNewmark() " << endl;
Sortie(1);
};
// constructeur en fonction du type de calcul et du sous type
// il y a ici lecture des parametres attaches au type
AlgoriNewmark::AlgoriNewmark (const bool avec_typeDeCal
,const list <EnumSousTypeCalcul>& soustype
,const list <bool>& avec_soustypeDeCal
,UtilLecture& entreePrinc) :
Algori(DYNA_IMP,avec_typeDeCal,soustype,avec_soustypeDeCal,entreePrinc)
,beta_newmark(NULL),gamma_newmark(NULL),hht(NULL),stabilite(false)
,delta_t(),delta_t_2(),unSurBetaDeltaTcarre(),betaDelta_t_2()
,betaMoinsGammaSurBeta(),unSurGammaDeltat(),unMoinGamma(),unMoinGammasurgamma()
,zero5deltatcarreUnMoinDeuxBeta(),zero5deltatcarredeuxBeta(),deltatUnMoinGamma()
,deltatGamma(),unsurbetadeltat(),unmoinsdeuxbetasurdeuxbeta(),unSurBetaDeltaTcarre_o()
,nuAphaPrime(),coef_masse(),nuBetaPrime(),coef_raideur(),nuAphaPrimeunsurcoef_masse(),unsurcoef_masse()
//----- cas du masse scaling pilotée
,avec_masse_scaling(false)
,et_pilotage_masse_scaling_par_maxRatioForce_inertieSurStatique(false)
,ou_pilotage_masse_scaling_par_maxRatioForce_inertieSurStatique(false)
,ratioForce_inertieSurStatique(0.)
,et_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur(false)
,ou_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur(false)
,ratioDiag_masseSurRaideur(0.)
,cL_a_chaque_iteration(0)
// --------------------------------------------------------------------------------------
// -- variables de transferts internes entre: InitAlgorithme, CalEquilibre, FinCalcul --
// --------------------------------------------------------------------------------------
,Ass1_(NULL),Ass2_(NULL),Ass3_(NULL),cas_combi_ddl(0),icas(0),prepa_avec_remont(false)
,brestart(false),type_incre(OrdreVisu::INCRE_0),vglobin(),vglobex(),vglobaal()
,vglobal_n(),vglobal_n_inter(),vcontact()
,delta_prec_X(),inter_tdt()
,X_Bl(),V_Bl(),G_Bl(),forces_vis_num(0)
,li_gene_asso(),t_assemb(),tenuXVG(),mat_masse(NULL),mat_C_pt(NULL)
,matglob(NULL),assembMat(NULL),sauve_deltadept(NULL),sauve_dept_a_tdt(NULL)
,tab_mato(1)
,Vres(NULL),v_travail(NULL)
// ------------------------------------------------------------------------------------------
// -- fin variables de transferts internes entre: InitAlgorithme, CalEquilibre, FinCalcul --
// ------------------------------------------------------------------------------------------
{ //vglobaal = &vglobin;
// lecture des paramètres attachés au type de calcul (ici aucun)
switch (entreePrinc.Lec_ent_info())
{ case 0 :
{ lecture_Parametres(entreePrinc); break;}
case -11 : // cas de la création d'un fichier de commande
{ Info_commande_parametres(entreePrinc); break;}
case -12 : // cas de la création d'un schéma XML, on ne fait rien à ce niveau
{ break;}
default:
Sortie(1);
}
// associations pour les tableaux de matrices
tab_mato(1)=matglob;
};
// constructeur de copie
AlgoriNewmark::AlgoriNewmark (const AlgoriNewmark& algo):
Algori(algo)
,beta_newmark(NULL),gamma_newmark(NULL),hht(NULL),stabilite(false)
,delta_t(),delta_t_2(),unSurBetaDeltaTcarre(),betaDelta_t_2()
,betaMoinsGammaSurBeta(),unSurGammaDeltat(),unMoinGamma(),unMoinGammasurgamma()
,zero5deltatcarreUnMoinDeuxBeta(),zero5deltatcarredeuxBeta(),deltatUnMoinGamma()
,deltatGamma(),unsurbetadeltat(),unmoinsdeuxbetasurdeuxbeta(),unSurBetaDeltaTcarre_o()
,nuAphaPrime(),coef_masse(),nuBetaPrime(),coef_raideur(),nuAphaPrimeunsurcoef_masse(),unsurcoef_masse()
//----- cas du masse scaling pilotée
,avec_masse_scaling(algo.avec_masse_scaling)
,et_pilotage_masse_scaling_par_maxRatioForce_inertieSurStatique
(algo.et_pilotage_masse_scaling_par_maxRatioForce_inertieSurStatique)
,ou_pilotage_masse_scaling_par_maxRatioForce_inertieSurStatique
(algo.ou_pilotage_masse_scaling_par_maxRatioForce_inertieSurStatique)
,ratioForce_inertieSurStatique(algo.ratioForce_inertieSurStatique)
,et_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur
(algo.et_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur)
,ou_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur
(algo.ou_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur)
,ratioDiag_masseSurRaideur(algo.ratioDiag_masseSurRaideur)
,cL_a_chaque_iteration(algo.cL_a_chaque_iteration)
// --------------------------------------------------------------------------------------
// -- variables de transferts internes entre: InitAlgorithme, CalEquilibre, FinCalcul --
// --------------------------------------------------------------------------------------
,Ass1_(NULL),Ass2_(NULL),Ass3_(NULL),cas_combi_ddl(0),icas(0)
,prepa_avec_remont(false)
,brestart(false),type_incre(OrdreVisu::INCRE_0),vglobin(),vglobex(),vglobaal()
,vglobal_n(),vglobal_n_inter(),vcontact()
,delta_prec_X(),inter_tdt()
,X_Bl(),V_Bl(),G_Bl(),forces_vis_num(0)
,li_gene_asso(),t_assemb(),tenuXVG(),mat_masse(NULL),mat_C_pt(NULL)
,matglob(NULL),assembMat(NULL),sauve_deltadept(NULL),sauve_dept_a_tdt(NULL)
,tab_mato(1)
,Vres(NULL),v_travail(NULL)
// ------------------------------------------------------------------------------------------
// -- fin variables de transferts internes entre: InitAlgorithme, CalEquilibre, FinCalcul --
// ------------------------------------------------------------------------------------------
{ //vglobaal = &vglobin;
beta_newmark = & paraTypeCalcul(1);
gamma_newmark = & paraTypeCalcul(2);
hht = & paraTypeCalcul(3);
// associations pour les tableaux de matrices
tab_mato(1)=matglob;
};
// destructeur
AlgoriNewmark::~AlgoriNewmark ()
{
// --------------------------------------------------------------------------------------
// -- variables de transferts internes entre: InitAlgorithme, CalEquilibre, FinCalcul --
// --------------------------------------------------------------------------------------
if (mat_masse != NULL) delete mat_masse;
if (mat_C_pt != NULL) delete mat_C_pt;
if (Ass1_ != NULL) delete Ass1_;
if (Ass2_ != NULL) delete Ass2_;
if (Ass3_ != NULL) delete Ass3_;
{int taille = tab_mato.Taille();
for (int i=1;i<=taille;i++)
if (tab_mato(i)!= NULL)
delete tab_mato(i);
}
// if (mato != NULL) delete mato;
if (sauve_deltadept != NULL) delete sauve_deltadept;
if (sauve_dept_a_tdt != NULL) delete sauve_dept_a_tdt;
if (Vres != NULL) delete Vres;
if (v_travail != NULL) delete v_travail;
// ------------------------------------------------------------------------------------------
// -- fin variables de transferts internes entre: InitAlgorithme, CalEquilibre, FinCalcul --
// ------------------------------------------------------------------------------------------
};
// execution de l'algorithme
void AlgoriNewmark::Execution(ParaGlob * paraGlob,LesMaillages * lesMail
,LesReferences* lesRef,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD
,VariablesExporter* varExpor,LesLoisDeComp* lesLoisDeComp, DiversStockage* divStock
,Charge* charge,LesCondLim* lesCondLim,LesContacts* lesContacts,Resultats* resultats)
{ Tableau < Fonction_nD* > * tb_combiner = NULL; // ici ne sert pas
// on définit le type de calcul a effectuer :
if ( soustypeDeCalcul->size()==0 )
// cas où il n'y a pas de sous type, on fait le calcul d'équilibre classique
// signifie que le type principal est forcément valide
{ // initialisation du calcul : deux cas, soit avec une lecture initiale du .info, soit une lecture secondaire
if (paraGlob->EtatDeLaLecturePointInfo() == 0)
{ // initialisation du calcul
InitAlgorithme(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
,divStock,charge,lesCondLim,lesContacts,resultats );
}
else
{MiseAJourAlgo(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
,divStock,charge,lesCondLim,lesContacts,resultats );
};
// on ne continue que si on n'a pas dépasser le nombre d'incréments maxi ou le temps maxi
if (! (charge->Fin(icharge,true) ) )
{ // calcul de l'équilibre
CalEquilibre(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
,divStock,charge,lesCondLim,lesContacts,resultats
,tb_combiner);
// fin du calcul, pour l'instant on ne considère pas les autres sous-types
FinCalcul(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
,divStock,charge,lesCondLim,lesContacts,resultats );
};
}
else
{if ( avec_typeDeCalcul )
// cas où le type principal est valide et qu'il y a des sous_types
{// on regarde si le sous-type "commandeInteractive" existe, si oui on le met en place
// détermine si le sous type de calcul existe et s'il est actif
if (paraGlob->SousTypeCalcul(commandeInteractive))
{// -- cas avec commandes interactives
// initialisation du calcul
InitAlgorithme(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
,divStock,charge,lesCondLim,lesContacts,resultats );
// calcul de l'équilibre tant qu'il y a des commandes
while (ActionInteractiveAlgo())
{// on ne continue que si on n'a pas dépasser le nombre d'incréments maxi ou le temps maxi
if (! (charge->Fin(icharge,true) ) )
CalEquilibre(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
,divStock,charge,lesCondLim,lesContacts,resultats
,tb_combiner);
};
// fin du calcul, pour l'instant on ne considère pas les autres sous-types
FinCalcul(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
,divStock,charge,lesCondLim,lesContacts,resultats );
}
else // cas sans commandes interactives
{// on fait le calcul d'équilibre
// initialisation du calcul : deux cas, soit avec une lecture initiale du .info, soit une lecture secondaire
if (paraGlob->EtatDeLaLecturePointInfo() == 0)
{InitAlgorithme(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
,divStock,charge,lesCondLim,lesContacts,resultats );
}
else {// on est en lecture secondaire
MiseAJourAlgo(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
,divStock,charge,lesCondLim,lesContacts,resultats );;
};
// on ne continue que si on n'a pas dépasser le nombre d'incréments maxi ou le temps maxi
if (! (charge->Fin(icharge,true) ) )
{ // calcul de l'équilibre
CalEquilibre(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
,divStock,charge,lesCondLim,lesContacts,resultats
,tb_combiner);
// fin du calcul, pour l'instant on ne considère pas les autres sous-types
FinCalcul(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
,divStock,charge,lesCondLim,lesContacts,resultats );
};
};// fin du cas sans commandes interactives
// ensuite on teste en fonction des calculs complémentaires
// dépendant des sous_types. Pour l'instant ici uniquement la remontée
list <EnumSousTypeCalcul>::const_iterator ili,ili_fin = soustypeDeCalcul->end();
list <bool>::const_iterator ila;
for (ili = soustypeDeCalcul->begin(),ila = avec_soustypeDeCalcul->begin();
ili!=ili_fin;ili++,ila++)
if (*ila) // cas où le sous type est valide
{if (Remonte_in(*ili)) // on test la présence du calcul de remonté
{ // certaines initialisations sont nécessaires car c'est le premier calcul
Algori::InitRemontSigma(lesMail,lesRef,divStock,charge,lesCondLim,lesContacts,resultats);
Algori::InitErreur(lesMail,lesRef,divStock,charge,lesCondLim,lesContacts,resultats);
Algori::RemontSigma(lesMail);
Algori::RemontErreur(lesMail);
}
else if ( (*ili) == sauveMaillagesEnCours )
{ cout << "\n================================================================="
<< "\n| ecriture des maillages en cours en .her et .lis |"
<< "\n================================================================="
<< endl;
// ----- sort les informations sur fichiers
// Affichage des donnees des maillages dans des fichiers dont le nom est construit
// à partir du nom de chaque maillage au format ".her" et ".lis"
lesMail->Affiche_maillage_dans_her_lis(TEMPS_tdt,*lesRef);
};
};
}
else
// cas ou le type principal n'est pas valide
// on ne fait que le calcul complémentaire
{ list <EnumSousTypeCalcul>::const_iterator ili,ili_fin = soustypeDeCalcul->end();
list <bool>::const_iterator ila;
for (ili = soustypeDeCalcul->begin(),ila = avec_soustypeDeCalcul->begin();
ili!=ili_fin;ili++,ila++)
if (*ila) // cas où le sous type est valide
{if (Remonte_in(*ili)) // on test la présence du calcul de remonté
{ // certaines initialisations sont nécessaires car c'est le premier calcul
Algori::InitRemontSigma(lesMail,lesRef,divStock,charge,lesCondLim,lesContacts,resultats);
Algori::InitErreur(lesMail,lesRef,divStock,charge,lesCondLim,lesContacts,resultats);
Algori::RemontSigma(lesMail);
Algori::RemontErreur(lesMail);
}
else if ( (*ili) == sauveMaillagesEnCours )
{ cout << "\n================================================================="
<< "\n| ecriture des maillages en cours en .her et .lis |"
<< "\n================================================================="
<< endl;
// ----- sort les informations sur fichiers
// Affichage des donnees des maillages dans des fichiers dont le nom est construit
// à partir du nom de chaque maillage au format ".her" et ".lis"
lesMail->Affiche_maillage_dans_her_lis(TEMPS_0,*lesRef);
};
};
};
};
// si on a forcé la sortie des itérations et incréments, il faut réinitialiser l'indicateur
if (!(pa.EtatSortieEquilibreGlobal()))
pa.ChangeSortieEquilibreGlobal(false);
};
// lecture des paramètres du calcul
void AlgoriNewmark::lecture_Parametres(UtilLecture& entreePrinc)
{ // dimensionnement
paraTypeCalcul.Change_taille(3); // donc le troisième est nulle par défaut
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(DYNA_IMP); // transfert info
MotCle motCle; // ref aux mots cle
deja_lue_entete_parametre = 1; // a priori pas de lecture d'entête
// on se positionne sur le prochain mot clé
do
{ entreePrinc.NouvelleDonnee();
}
while ( !motCle.SimotCle(entreePrinc.tablcar)) ;
// si le mot clé est "PARA_TYPE_DE_CALCUL" cela signifie
// qu'il y a un paramètre à lire
bool lecture_effective = false;
if (strstr(entreePrinc.tablcar,"PARA_TYPE_DE_CALCUL")!=NULL)
{ //cas de la définition de paramètres
// on signale à Algori qu'il y a eu déjà une lecture de paramètre
deja_lue_entete_parametre=2;
// lecture du premier paramètres de l'algorithme
entreePrinc.NouvelleDonnee(); // ligne suivante
if (strstr(entreePrinc.tablcar,"hht")!=NULL)
{ // cas de la méthode hht, dans ce cas les paramètres beta et gamma sont fixés
// le seul paramètre à lire est donc le hht c'est-à-dire alpha
// lecture du nom du paramètre et vérification
string st1;
*(entreePrinc.entree) >> st1 ;
if (st1 == "beta_et_gamma=")
{ cout << "\n erreur en lecture du parametre de l'algorithme newmark "
<< "\n on attendait le mot : hht= , au lieu de " << st1
<< "\n dans la methode hht les parametres beta et gamma sont definit à partir de hht"
<< "\n AlgoriNewmark::lecture_Parametres( ... ";
Sortie(1);
}
// lecture du paramètre hht
*(entreePrinc.entree) >> paraTypeCalcul(3);
lecture_effective=true;
hht = & paraTypeCalcul(3);
// on calcul les paramètres beta et gamma
paraTypeCalcul(1) = (1.- (*hht))*(1.- (*hht))/4.;
paraTypeCalcul(2) = 1./2. - (*hht);
beta_newmark = & paraTypeCalcul(1);
gamma_newmark = & paraTypeCalcul(2);
stabilite=true;
}
else
// cas de la méthode de newmark classique
{ // lecture du nom du paramètre et vérification
string st1;
*(entreePrinc.entree) >> st1 ;
if (st1 != "beta_et_gamma=")
{ cout << "\n erreur en lecture du parametre de l'algorithme de newmark "
<< "\n on attendait le mot : beta_et_gamma= , au lieu de " << st1
<< "\n AlgoriNewmark::lecture_Parametres( ... ";
Sortie(1);
}
// lecture du parametre
*(entreePrinc.entree) >> paraTypeCalcul(1) >> paraTypeCalcul(2);
lecture_effective=true;
// on relie les paramètres à béta et gamma
beta_newmark = & paraTypeCalcul(1);
gamma_newmark = & paraTypeCalcul(2);
// si gamma n'est pas supérieur à 0.5 il ne peut pas y avoir stabilité même conditionnelle
// hughes p.94, an. 1983 (belytschko et hughes)
if ((*gamma_newmark) < 0.5)
{ cout << "\n erreur sur le parametre gamma de l'algorithme de newmark "
<< "\n gamma doit etre superieur a 0.5 quelque soit la stabilite requise " << st1
<< "\n AlgoriNewmark::lecture_Parametres( ... ";
Sortie(1);
}
hht = & paraTypeCalcul(3); // le troisième est nulle par défaut donc ici == 0
// vérification de la stabilité
if ((2. *(*beta_newmark)) >= (*gamma_newmark))
{ // cas d'une stabilité inconditionnelle
stabilite=true;}
else { stabilite = false;} // stabilité conditionnelle
};
// si on a déjà lue une ligne on passe à l'enreg suivant
if ((lecture_effective) && ( !motCle.SimotCle(entreePrinc.tablcar)))
{entreePrinc.NouvelleDonnee(); // ligne suivante
lecture_effective = false; // on re-init pour la suite
};
// -- cas où on veut faire du masse scaling avec éventuellement du pilotage
if(strstr(entreePrinc.tablcar,"avec_pilote_masse_scaling_")!=0)
{avec_masse_scaling = 1;
string nom;
entreePrinc.NouvelleDonnee(); // on se positionne sur un nouvel enreg
// on lit tant que l'on ne rencontre pas la ligne contenant "fin_pilote_masse_scaling_"
// ou un nouveau mot clé global auquel cas il y a pb !!
MotCle motCle; // ref aux mots cle
while (strstr(entreePrinc.tablcar,"fin_pilote_masse_scaling_")==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 de masse scaling: on n'a pas trouve le mot cle "
<< " fin_pilote_masse_scaling_ et par contre la ligne courante contient un mot cle global ";
entreePrinc.MessageBuffer("** erreur des parametres de pilotage de masse scaling **");
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_pilote_masse_scaling_")
{entreePrinc.NouvelleDonnee(); *(entreePrinc.entree) >> nom;};
}
#endif
else // cas d'une erreur de lecture
{ cout << "\n erreur de lecture inconnue ";
entreePrinc.MessageBuffer("** erreur2 des parametres de reglage de masse scaling **");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// cas et_pilotage_masse_scaling_par_maxRatioForce_inertieSurStatique
if(nom == "et_pilotage_masse_scaling_par_maxRatioForce_inertieSurStatique_")
{et_pilotage_masse_scaling_par_maxRatioForce_inertieSurStatique=true;
// si on a déjà lue ou au lieu de et -> pas possible -> erreur
if (ou_pilotage_masse_scaling_par_maxRatioForce_inertieSurStatique)
{ cout << "\n erreur en lecture on a auparavant: ou_pilotage_masse_scaling_par_maxRatioForce_inertieSurStatique_ "
<< " c'est donc incoherent (car incompatible) "
<< "\n AlgoriNewmark::lecture_Parametres(.. " << endl ;
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
*(entreePrinc.entree) >> ratioForce_inertieSurStatique;
lecture_effective = true;
}
// cas ou_pilotage_masse_scaling_par_maxRatioForce_inertieSurStatique
else if(nom == "ou_pilotage_masse_scaling_par_maxRatioForce_inertieSurStatique_")
{ou_pilotage_masse_scaling_par_maxRatioForce_inertieSurStatique=true;
// si on a déjà lue et au lieu de ou -> pas possible -> erreur
if (et_pilotage_masse_scaling_par_maxRatioForce_inertieSurStatique)
{ cout << "\n erreur en lecture on a auparavant: et_pilotage_masse_scaling_par_maxRatioForce_inertieSurStatique_ "
<< " c'est donc incoherent (car incompatible) "
<< "\n AlgoriNewmark::lecture_Parametres(.. " << endl ;
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
*(entreePrinc.entree) >> ratioForce_inertieSurStatique;
lecture_effective = true;
}
// cas ou_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur
else if(nom == "ou_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur_")
{ou_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur=true;
// si on a déjà lue et au lieu de ou -> pas possible -> erreur
if (et_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur)
{ cout << "\n erreur en lecture on a auparavant: et_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur_ "
<< " c'est donc incoherent (car incompatible) "
<< "\n AlgoriNewmark::lecture_Parametres(.. " << endl ;
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
*(entreePrinc.entree) >> ratioDiag_masseSurRaideur;
lecture_effective = true;
}
// cas et_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur
else if(nom == "et_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur_")
{et_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur=true;
// si on a déjà lue ou au lieu de et -> pas possible -> erreur
if (ou_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur)
{ cout << "\n erreur en lecture on a auparavant: ou_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur_ "
<< " c'est donc incoherent (car incompatible) "
<< "\n AlgoriNewmark::lecture_Parametres(.. " << endl ;
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
*(entreePrinc.entree) >> ratioDiag_masseSurRaideur;
lecture_effective = true;
}
// sinon ce n'est pas un mot clé connu, on le signale
else if(nom != "fin_pilote_masse_scaling_")
{ cout << "\n erreur en lecture d'un parametre, le mot cle est inconnu "
<< " on a lu : " << nom << endl;
if (ParaGlob::NiveauImpression()>3)
cout << "\n AlgoriNewmark::lecture_Parametres( " << endl ;
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
}; //-- fin du while
}; //-- fin de la lecture des paramètres de réglage du masse scaling
// on prépare la prochaine lecture si la lecture a été effective et que l'on n'est pas
// sur un mot clé
if ((lecture_effective) && ( !motCle.SimotCle(entreePrinc.tablcar)))
{entreePrinc.NouvelleDonnee(); // ligne suivante
lecture_effective = false; // on re-init pour la suite
};
//---- autres paramètres particuliers ---
// on s'arrête lorsqu'il n'y a plus de mot clé spécifique à lire
while ( (strstr(entreePrinc.tablcar,"cL_a_chaque_iteration_")!=NULL)
)
{ string nom_mot_cle="";
*(entreePrinc.entree) >> nom_mot_cle;
if (nom_mot_cle == "cL_a_chaque_iteration_")
{ // on lit le paramètre
*(entreePrinc.entree) >> cL_a_chaque_iteration;
lecture_effective = true;
}
// gestion des fins de ligne
if ( ((strstr(entreePrinc.tablcar,"cL_a_chaque_iteration_")==NULL)
)
&& ((lecture_effective) && ( !motCle.SimotCle(entreePrinc.tablcar)))
)
// s'il n'y a plus rien et que l'on vient de lire dans ce cas on tente la ligne suivante
{entreePrinc.NouvelleDonnee(); // ligne suivante
lecture_effective = false; // on re-init pour la suite
};
#ifdef ENLINUX
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
}
#else
if ((entreePrinc.entree)->eof())
// la lecture est bonne mais on a atteind la fin de la ligne
{ entreePrinc.NouvelleDonnee(); // lecture d'un nouvelle enregistrement
}
// #endif
#endif
// sinon ce n'est pas une ligne ad hoc, la lecture s'arrêtera
}; // -- fin du while sur les paramètres particulier
}
else // sinon on met une valeur par défaut
{ paraTypeCalcul(1) = 0.25; paraTypeCalcul(2) = 0.5;paraTypeCalcul(3) = 0.;
beta_newmark = & paraTypeCalcul(1);
gamma_newmark = & paraTypeCalcul(2);
hht = & paraTypeCalcul(3); //c-a-d 0 par défaut
stabilite=true;
cL_a_chaque_iteration = 0;
};
// on vérifie que la valeur hht lue conduit à un algo inconditionnellement stable
if (((*hht) < -(1./3.)) || ((*hht) > 0))
cout << "\n *** attention le parametre de la methode HHT est en dehors de l'interval [-1/3,0]"
<< " la stabilite sera donc conditionnellement stable !!"
<< " \n cependant aucune modification du pas de temps propose par l'utilisateur n'est realise"
<< " \n la stabilite est donc a controler par l'utilisateur !!";
// on prépare la prochaine lecture si la lecture a été effective et que l'on n'est pas
// sur un mot clé
if ((lecture_effective) && ( !motCle.SimotCle(entreePrinc.tablcar)))
entreePrinc.NouvelleDonnee(); // ligne suivante
// puis appel de la méthode de la classe mère
Algori::lecture_Parametres(entreePrinc);
};
// écriture des paramètres dans la base info
// = 1 : on écrit tout
// = 2 : on écrot uniquement les données variables (supposées comme telles)
void AlgoriNewmark::Ecrit_Base_info_Parametre(UtilLecture& entreePrinc,const int& cas)
{
// récup du flot
ofstream * sort = entreePrinc.Sort_BI();
// (*sort) << "\n parametres_algo_specifiques_ "<< Nom_TypeCalcul(this->TypeDeCalcul());
if (cas == 1)
{ // ecriture des parametres
*(sort) << " beta_et_gamma= " << paraTypeCalcul(1) << " "
<< paraTypeCalcul(2) << " ";
// écriture du paramètre hht
*(sort) << " hht= " << paraTypeCalcul(3) << " ";
// et le paramètre
*(sort) << " cL_a_chaque_iteration "<< cL_a_chaque_iteration << " ";
};
// (*sort) << "\n fin_parametres_algo_specifiques_ ";
};
// lecture des paramètres dans la base info
// = 1 : on récupère tout
// = 2 : on récupère uniquement les données variables (supposées comme telles)
// choix = true : fonctionnememt normal
// choix = false : la méthode ne doit pas lire mais initialiser les données à leurs valeurs par défaut
// car la lecture est impossible
void AlgoriNewmark::Lecture_Base_info_Parametre(UtilLecture& entreePrinc,const int& cas,bool choix)
{if (cas == 1)
{// dimensionnement
paraTypeCalcul.Change_taille(3);
if (choix)
{// cas d'une lecture normale
// récup du flot
ifstream * ent = entreePrinc.Ent_BI();
string toto;
// lecture du premier parametre
*(ent) >> toto ;
if (toto != "beta_et_gamma=")
{ cout << "\n erreur en lecture du parametre de l'algorithme explicite "
<< "\n on attendait le mot : beta_et_gamma= , au lieu de " << toto
<< "\n AlgoriNewmark::Lecture_Base_info_Parametre( ... ";
Sortie(1);
}
*(ent) >> paraTypeCalcul(1) >> paraTypeCalcul(2);
// idem pour le paramètre hht
*(ent) >> toto >> paraTypeCalcul(3);
// lecture de cL_a_chaque_iteration
*(ent) >> toto ;
if (toto != "cL_a_chaque_iteration")
{ cout << "\n erreur en lecture du parametre cL_a_chaque_iteration"
<< "\n on attendait le mot : cL_a_chaque_iteration , au lieu de " << toto
<< "\n AlgoriNewmark::Lecture_Base_info_Parametre( ... ";
Sortie(1);
}
*(ent) >> cL_a_chaque_iteration ;
}
else
{// cas où la lecture n'est pas possible, attribution des valeurs par défaut
paraTypeCalcul(1) = 0.25; paraTypeCalcul(2) = 0.5;paraTypeCalcul(3) = 0.;
cL_a_chaque_iteration = 0;
}
// on relie les paramètres à béta et gamma
beta_newmark = & paraTypeCalcul(1);
gamma_newmark = & paraTypeCalcul(2);
hht = & paraTypeCalcul(3);
}
};
// création d'un fichier de commande: cas des paramètres spécifiques
void AlgoriNewmark::Info_commande_parametres(UtilLecture& entreePrinc)
{ // écriture dans le fichier de commande
ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier
sort << "\n#-------------------------------------------------------------------"
<< "\n| parametres (falcultatifs) associes l'algorithme de Newmark |"
<< "\n#-------------------------------------------------------------------"
<< "\n"
<< "\n PARA_TYPE_DE_CALCUL"
<< "\n # ..........................................................."
<< "\n # / facteur beta puis facteur gamma, (ou facteur hht) /"
<< "\n # / (dans le cas de la methode hht: beta et gamma sont fixe)/"
<< "\n # / ( il ne sont donc pas à indiquer ) /"
<< "\n #..........................................................."
<< "\n # hht= 0.05 "
<< "\n beta_et_gamma= 0.25 0.5 "
<< "\n # ................................................................"
<< "\n # / mise en place des conditions limites a chaque iteration /"
<< "\n #.................................................................."
<< "\n # mot cle : cL_a_chaque_iteration_ suivi de 0 ou 1 "
<< "\n # par defaut == 0, c-a-d que les CL sont mises en place "
<< "\n # au debut de chaque increment et ensuite reste fixe pendant les iterations "
<< "\n # == 1 : a chaque iteration, les CL sont de nouveaux imposes "
<< "\n ";
// appel de la classe mère
Algori::Info_com_parametres(entreePrinc);
sort << "\n" << endl;
};
// gestion et vérification du pas de temps et modif en conséquence si nécessaire
// cas = 1: initialisation du pas de temps et de l'amortissement numérique si nécessaire
// ceci pour le temps t=0
// cas = 2: initialisation du pas de temps
// ceci pour le temps t
void AlgoriNewmark::Gestion_pas_de_temps(LesMaillages * lesMail,int cas)
{ bool modif_deltat = false; // booleen pour la prise en compte éventuelle de la modif du temps éventuelle
static double coef_delta_crit; // coef multiplicateur du pas critique
if (cas==1)
{ // dans le cas où le pas de temps ou le pas de temps maxi dépendent d'un pas critique,
// ou dans le cas où la stabilitée est conditionnelle on calcul le pas de temps critique
// et on met à jour les pas de temps
if ((pa.DeltatOuDeltatmaxDependantTempsCritique())|| !stabilite)
// on calcul le pas de temps minimal pour cela on utilise
// les caractéristiques dynamiques d'une biellette de longueur
// valant le minimum d'un coté d'arrête
{ // --<NM>-- on calcul le pas de temps minimal
delta_t = pa.Deltat(); double delta_t_old = delta_t;
double l_sur_c = lesMail->Longueur_arrete_mini_sur_c(TEMPS_0);
double delta_t_essai = l_sur_c ;
if (!stabilite) // calcul du delta t critique conditionnel
{ coef_delta_crit = ConstMath::Pi * pow((0.5 * (*gamma_newmark) - (*beta_newmark)),-0.5);
delta_t_essai *= coef_delta_crit;
}
// mise à jour éventuel du pas de temps et du pas de temps maxi et mini s'ils sont définit à partir du temps critique,
// par contre il n'y a pas adéquation entre le deltat et les mini et maxi
modif_deltat = pa.Modif_Deltat_DeltatMaxi(delta_t_essai,l_sur_c); // mais pas de test vis-a-vis des bornes
delta_t = pa.Deltat(); // mise à jour éventuelle du pas de temps
// maintenant on vérifie le pas de temps choisit
if (!stabilite && (pa.Limit_temps_stable() && ( delta_t > delta_t_essai)))
{ cout << "\n ** ATTENTION ** , l'increment de temps propose : " << delta_t
<< ", ne satisfait pas la condition de stabilite conditionnelle de Newmark, "
<< "\n on le regle donc pour que cette condition soit satisfaite: nouvel increment: "
<< delta_t_essai;
delta_t = delta_t_essai;
// modification de l'increment de temps dans les paramètres
switch (pa.Modif_Deltat(delta_t))
{ case -1: { cout << "\n initialisation du pas de temps avec la condition de Courant impossible, le nouveau pas"
<< "\n de temps calcule est plus petit que le pas de temps mini limite: " << pa.Deltatmini();
Sortie(1); break;
}
case 0: { break;} // cas normal
case 1: { pa.Modif_Detat_dans_borne(delta_t);
cout << "\n >>>> rectification du pas de temps "<<delta_t_old<<" dans les bornes : nouvel increment:" << delta_t;
break;
} // cas ou on dépasse la borne maxi
};
modif_deltat=true;
};
// on modifie éventuellement le pas de temps dans les bornes mini et maxi
if (pa.Modif_Detat_dans_borne(delta_t))
{ cout << "\n **** modification du pas de temps "<<delta_t_old<<" entre les bornes mini et maxi "
<< " le nouveau pas de temps = "<<delta_t<<endl;
};
};
delta_t = pa.Deltat();
delta_t_2 = delta_t * delta_t;
unSurBetaDeltaTcarre = 1./delta_t_2/(*beta_newmark);
betaDelta_t_2 = (*beta_newmark) * delta_t_2;
// def de coeffs simplificateurs
betaMoinsGammaSurBeta = ((*beta_newmark)-(*gamma_newmark))/(*beta_newmark);
unSurGammaDeltat = 1./( (*gamma_newmark)* delta_t);
unMoinGamma = 1. - (*gamma_newmark);
unMoinGammasurgamma = unMoinGamma/(*gamma_newmark);
zero5deltatcarreUnMoinDeuxBeta= (0.5 * (delta_t*delta_t)) * ((1.- 2. * (*beta_newmark)));
zero5deltatcarredeuxBeta = (0.5 * (delta_t*delta_t)) * (2. * (*beta_newmark));
deltatUnMoinGamma = delta_t * (1.-(*gamma_newmark));
deltatGamma = delta_t * (*gamma_newmark);
unsurbetadeltat = 1./( (*beta_newmark) * delta_t);
unmoinsdeuxbetasurdeuxbeta = (1.-2.*(*beta_newmark))/(2.*(*beta_newmark));
// cas de l'amortissement numérique
nuAphaPrime=0.; coef_masse = 1.; nuAphaPrimeunsurcoef_masse = 0.;
unsurcoef_masse =1.; nuBetaPrime=0.; coef_raideur = 1.;
// dans le cas où l'on utilise de l'amortissement numérique, calcul des coefs
// 1° la matrice masse vaux théoriquement : (1/(beta*delta t2) + nu * alphaPrime * gamma/(beta*delta t)) [M]
// mais ici dans le programme on utilise [M]/(beta delta t2), donc pour tenir compte de la viscosité il faut
// multiplier cette viscosité dynamique par le coef : coef_masse
// 2° la matrice raideur vaux théoriquement (1. + nu*betaPrime*gamme / (beta*Delta t))[K] d'où le coef coef_raideur
// 3° pour le second membre on a pour la partie visqueuse: [C] qPoint = nu(alphaPrime[M] + betaPrime[K]) qPoint
// mais on utilisera pour plus de facilité, la prémultiplication des vecteurs ce qui permettra de ne pas
// modifier les matrices d'où les coef nuAphaPrimeBetatDelta_t_2 et nuBetaPrime, le premier étant particulier
// parceque l'on utilise une matrice masse modifiée
if (pa.Amort_visco_artificielle())
{if (pa.CoefRayleighMasse()!=0.)
{nuAphaPrime = pa.Visco_artificielle() * pa.CoefRayleighMasse();
coef_masse= betaDelta_t_2 * (unSurBetaDeltaTcarre + nuAphaPrime * (*gamma_newmark)*unsurbetadeltat);
unsurcoef_masse = 1./coef_masse;
nuAphaPrimeunsurcoef_masse = nuAphaPrime * unsurcoef_masse;
};
if (pa.CoefRayleighRaideur()!=0.)
{ nuBetaPrime = pa.Visco_artificielle() * pa.CoefRayleighRaideur();
coef_raideur = 1. + nuBetaPrime * (*gamma_newmark)*unsurbetadeltat;
};
};
}
else if (cas==2)
{ // dans le cas ou la stabilité est conditionnelle
// on regarde si le pas de temps n'est pas devenu supérieur au pas critique
if (!stabilite)
{ double l_sur_c = lesMail->Longueur_arrete_mini_sur_c(TEMPS_t);
double delta_t_essai = l_sur_c * coef_delta_crit ;double ancien_pas=delta_t;
// on intervient que si le nouveau pas de temps critique est inférieur au pas de temps en cours
if ( delta_t_essai < delta_t)
{// mise à jour éventuel du pas de temps et du pas de temps maxi s'ils sont définit à partir du temps critique
bool modif = pa.Modif_Deltat_DeltatMaxi(delta_t_essai,l_sur_c); // mais pas de test vis-a-vis des bornes
// s'il y a eu modif du pas de temps on met à jour le pas courant
if (modif) { delta_t = pa.Deltat(); modif_deltat=true;}
// maintenant on vérifie néanmoins le pas de temps choisit au cas où
// en particulier cette vérification n'est en fait pas utile si l'utilisateur
// à utilisé un facteur du pas critique < 1
if (pa.Limit_temps_stable() && ( delta_t > delta_t_essai))
{ delta_t = pa.Coefficient_pas_critique_deltat() * delta_t_essai;
// modification de l'increment de temps dans les paramètres
switch (pa.Modif_Deltat(delta_t))
{case -1: { cout << "\n **** modification du pas de temps impossible,"
<< " le nouveau pas de temps calcule est plus petit que le pas de temps mini limite: "
<< pa.Deltatmini();
Sortie(1); break;
}
case 0: { break;} // cas normal
case 1: { pa.Modif_Detat_dans_borne(delta_t); break;} // cas ou on dépasse la borne maxi
};
modif_deltat=true;
}
if (modif_deltat)
cout << "\n --->>>> modif increment de temps de " << ancien_pas << " a " << delta_t;
}
} // -- fin du cas de la stabilité conditionnelle
// maintenant on regarde le cas ou on a définit des temps maxi et/ou min, dépendants du pas de temps critique
if (pa.DeltatOuDeltatmaxDependantTempsCritique())
// on calcul le pas de temps minimal pour cela on utilise
// les caractéristiques dynamiques d'une biellette de longueur
// valant le minimum d'un coté d'arrête
{ // --<NM>-- on calcul le pas de temps minimal
double delta_t_old = delta_t;
double l_sur_c = lesMail->Longueur_arrete_mini_sur_c(TEMPS_0);
double delta_t_essai = l_sur_c ;
// mise à jour éventuel du pas de temps et du pas de temps maxi et mini s'ils sont définit à partir du temps critique,
// par contre il n'y a pas adéquation entre le deltat et les mini et maxi
modif_deltat = pa.Modif_Deltat_DeltatMaxi(delta_t_essai,l_sur_c); // mais pas de test vis-a-vis des bornes
delta_t = pa.Deltat(); // mise à jour éventuelle du pas de temps
// maintenant on vérifie le pas de temps choisit
// on modifie éventuellement le pas de temps dans les bornes mini et maxi
if (pa.Modif_Detat_dans_borne(delta_t))
{ cout << "\n **** modification du pas de temps "<<delta_t_old<<" entre les bornes mini et maxi "
<< " le nouveau pas de temps = "<<delta_t<<endl;
};
};
delta_t = pa.Deltat(); delta_t_2 = delta_t * delta_t;
// mise à jour du coef de la matrice de masse en fonction de la nouvelle
// valeur de unSurBetaDeltaTcarre
unSurBetaDeltaTcarre_o = unSurBetaDeltaTcarre; // sauvegarde de l'ancienne facteur de la matrice masse
unSurBetaDeltaTcarre = 1./delta_t_2/(*beta_newmark); // nouvelle valeur
betaDelta_t_2 = (*beta_newmark) * delta_t_2;
// mise à jour des coeffs simplificateurs
unSurGammaDeltat = 1./( (*gamma_newmark)* delta_t);
zero5deltatcarreUnMoinDeuxBeta= (0.5 * (delta_t*delta_t)) * ((1.- 2. * (*beta_newmark)));
zero5deltatcarredeuxBeta = (0.5 * (delta_t*delta_t)) * (2. * (*beta_newmark));
deltatUnMoinGamma = delta_t * (1.-(*gamma_newmark));
deltatGamma = delta_t * (*gamma_newmark);
unsurbetadeltat = 1./( (*beta_newmark) * delta_t);
// cas où l'on utilise de l'amortissement numérique, calcul des coefs (cf intro visqueux au début du programme)
coef_masse = 1.; // initialisation
if (pa.Amort_visco_artificielle())
{ if (Arret_A_Equilibre_Statique()) // si on veut un équilibre statique, on sauvegarde les forces statiques
(*vglob_stat) = vglobaal;
if (pa.CoefRayleighMasse()!=0.)
{nuAphaPrime = pa.Visco_artificielle() * pa.CoefRayleighMasse();
coef_masse= betaDelta_t_2 * (unSurBetaDeltaTcarre + nuAphaPrime * (*gamma_newmark)*unsurbetadeltat);
unsurcoef_masse = 1./coef_masse;
nuAphaPrimeunsurcoef_masse = nuAphaPrime * unsurcoef_masse;
};
if (pa.CoefRayleighRaideur()!=0.)
{ nuBetaPrime = pa.Visco_artificielle() * pa.CoefRayleighRaideur();
coef_raideur = 1. + nuBetaPrime * (*gamma_newmark)*unsurbetadeltat;
};
};
} //-- fin du cas == 2
};
// pilotage éventuel du masse scaling
void AlgoriNewmark::Pilotage_masse_scaling(const double& moy_diag_masse,const double& moy_diag_K
,const int& sauve_indic_convergence)
{
// on adapte en fonction de la cible si on a une différence de plus de 3%
const double diffPermi=0.03;
double multi=5.; // init
if (sauve_indic_convergence >= 0)
{if ( ((et_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur)
&& (Dabs(moy_diag_K)>ConstMath::trespetit)
)
&& ((et_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur)
&& (Dabs(moy_diag_K)>ConstMath::trespetit)
)
)
{// on calcul le rapport
double ratio_actuel_1 = moy_diag_masse/moy_diag_K;
double ratio_actuel_2 = (P_acc_t+ConstMath::trespetit)/(Dabs(- P_int_t - P_ext_t)+ConstMath::trespetit);
if (Dabs(ratioDiag_masseSurRaideur/ratio_actuel_1) > Dabs(ratioDiag_masseSurRaideur/ratio_actuel_2))
{if (diffpourcent(ratio_actuel_1,ratioDiag_masseSurRaideur,ratioDiag_masseSurRaideur,diffPermi))
{(*mat_masse) *= Dabs(ratioDiag_masseSurRaideur/ratio_actuel_1);
if (ParaGlob::NiveauImpression()>3)
cout << "\n Pilotage_masse_scaling diag : modif coeff mat_mass= "<< Dabs(ratioDiag_masseSurRaideur/ratio_actuel_1)
<< endl;
}
else
{if (diffpourcent(ratio_actuel_2,ratioForce_inertieSurStatique,ratioForce_inertieSurStatique,diffPermi))
{(*mat_masse) *= Dabs(ratioForce_inertieSurStatique/ratio_actuel_2);
if (ParaGlob::NiveauImpression()>3)
{cout << "\n Pilotage_masse_scaling puiss : modif coeff mat_mass= "<< Dabs(ratioForce_inertieSurStatique/ratio_actuel_2);
cout << "\n debug: P_acc_t= "<<P_acc_t<<", abs(- P_int_t - P_ext_t)= "<< Dabs(- P_int_t - P_ext_t)
<< " ratio_actuel= "<<ratio_actuel_2<<", ratio_cible= "<<ratioForce_inertieSurStatique;
cout << endl;
};
};
};
};
}
else if ((et_pilotage_masse_scaling_par_maxRatioDiag_masseSurRaideur)
&& (Dabs(moy_diag_K)>ConstMath::trespetit))
{// on calcul le rapport
double ratio_actuel = moy_diag_masse/moy_diag_K;
if (diffpourcent(ratio_actuel,ratioDiag_masseSurRaideur,ratioDiag_masseSurRaideur,diffPermi))
{(*mat_masse) *= Dabs(ratioDiag_masseSurRaideur/ratio_actuel);
if (ParaGlob::NiveauImpression()>3)
cout << "\n Pilotage_masse_scaling: modif coeff mat_mass= "<< Dabs(ratioDiag_masseSurRaideur/ratio_actuel)
<< endl;
};
}
else if (et_pilotage_masse_scaling_par_maxRatioForce_inertieSurStatique)
{// on calcul le rapport. Pour cela on se sert des puissances déjà stockées
// pour éviter des divergences au moment des itérations, on utilise les grandeurs à t
double ratio_actuel = (P_acc_t+ConstMath::trespetit)/(Dabs(- P_int_t - P_ext_t)+ConstMath::trespetit);
if (diffpourcent(ratio_actuel,ratioForce_inertieSurStatique,ratioForce_inertieSurStatique,diffPermi))
{(*mat_masse) *= Dabs(ratioForce_inertieSurStatique/ratio_actuel);
if (ParaGlob::NiveauImpression()>3)
{cout << "\n Pilotage_masse_scaling: modif coeff mat_mass= "<< Dabs(ratioForce_inertieSurStatique/ratio_actuel);
cout << "\n debug: P_acc_t= "<<P_acc_t<<", abs(- P_int_t - P_ext_t)= "<< Dabs(- P_int_t - P_ext_t)
<< " ratio_actuel= "<<ratio_actuel<<", ratio_cible= "<<ratioForce_inertieSurStatique;
cout << endl;
};
};
};
}
// si on a eu une divergence on multiplie par un coef l'augmentation de masse
else //if (sauve_indic_convergence < 0)
{ if (ParaGlob::NiveauImpression()>3)
cout << "\n Pilotage_masse_scaling: divergence donc multi mat_mass= "<< multi
<< endl;
(*mat_masse) *= multi;
};
};
//---- gestion des commndes interactives --------------
// écoute et prise en compte d'une commande interactive
// ramène true tant qu'il y a des commandes en cours
bool AlgoriNewmark::ActionInteractiveAlgo()
{ cout << "\n commande? ";
return false;
};