975 lines
53 KiB
C++
975 lines
53 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(ostream& sort,const int& cas)
|
|
{
|
|
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(istream& ent,const int& cas,bool choix)
|
|
{if (cas == 1)
|
|
{// dimensionnement
|
|
paraTypeCalcul.Change_taille(3);
|
|
if (choix)
|
|
{// cas d'une lecture normale
|
|
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;
|
|
};
|
|
|
|
|