// 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) . // // 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 . // // For more information, please consult: . #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 & soustype ,const list & 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 ::const_iterator ili,ili_fin = soustypeDeCalcul->end(); list ::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 ::const_iterator ili,ili_fin = soustypeDeCalcul->end(); list ::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 { // ---- 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 "<>>> 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 { // ---- 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 "<