// 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: . /************************************************************************ * DATE: 3/09/99 * * $ * * AUTEUR: G RIO (mailto:gerardrio56@free.fr) * * $ * * PROJET: Herezh++ * * $ * ************************************************************************ * BUT: Algorithme de relaxation dynamique selon la méthode * * de Barnes, modifiée par Julien Troufflard puis * * généralisée. * * $ * * '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * * * VERIFICATION: * * * * ! date ! auteur ! but ! * * ------------------------------------------------------------ * * ! ! ! ! * * $ * * '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * * MODIFICATIONS: * * ! date ! auteur ! but ! * * ------------------------------------------------------------ * * $ * ************************************************************************/ #ifndef AGORI_RELAX_DYNA_H #define AGORI_RELAX_DYNA_H #include "Algori.h" #include "Assemblage.h" #include "Ponderation.h" /// @addtogroup Les_algorithmes_de_resolutions_globales /// @{ /// /// BUT: Algorithme de relaxation dynamique selon la méthode /// de Barnes, modifiée par Julien Troufflard puis /// généralisée. class AlgoriRelaxDyna : public Algori { public : // CONSTRUCTEURS : AlgoriRelaxDyna () ; // par defaut // constructeur en fonction du type de calcul // du sous type (pour les erreurs, remaillage etc...) // il y a ici lecture des parametres attaches au type AlgoriRelaxDyna (const bool avec_typeDeCal ,const list & soustype ,const list & avec_soustypeDeCal ,UtilLecture& entreePrinc); // constructeur de copie AlgoriRelaxDyna (const AlgoriRelaxDyna& algo); // constructeur de copie à partie d'une instance indifférenciée Algori * New_idem(const Algori* algo) const {// on vérifie qu'il s'agit bien d'une instance if (algo->TypeDeCalcul() != RELAX_DYNA) { cout << "\n *** erreur lors de la creation par copie d'un algo RELAX_DYNA " << " l'algo passe en parametre est en fait : " << Nom_TypeCalcul(algo->TypeDeCalcul()) << " arret !! " << flush; Sortie(1); } else { AlgoriRelaxDyna* inter = (AlgoriRelaxDyna*) algo; return ((Algori *) new AlgoriRelaxDyna(*inter)); }; }; // DESTRUCTEUR : ~AlgoriRelaxDyna () ; // METHODES PUBLIQUES : // execution de l'algorithme explicite dans le cas dynamique sans contact void Execution(ParaGlob * ,LesMaillages *,LesReferences*,LesCourbes1D* ,LesFonctions_nD* ,VariablesExporter* varExpor,LesLoisDeComp* ,DiversStockage*,Charge*,LesCondLim*,LesContacts*,Resultats* ); //------- décomposition en 3 du calcul d'équilibre ------------- // a priori : InitAlgorithme et FinCalcul ne s'appellent qu'une fois, // par contre : CalEquilibre peut s'appeler plusieurs fois, le résultat sera différent si entre deux calcul // certaines variables ont-été changés // initialisation void InitAlgorithme(ParaGlob * ,LesMaillages *,LesReferences*,LesCourbes1D* ,LesFonctions_nD* ,VariablesExporter* ,LesLoisDeComp* ,DiversStockage*,Charge*,LesCondLim*,LesContacts*,Resultats* ); // mise à jour void MiseAJourAlgo(ParaGlob * ,LesMaillages *,LesReferences*,LesCourbes1D* ,LesFonctions_nD* ,VariablesExporter* ,LesLoisDeComp* ,DiversStockage*,Charge*,LesCondLim*,LesContacts*,Resultats* ); // calcul de l'équilibre // si tb_combiner est non null -> un tableau de 2 fonctions // - la première fct dit si on doit valider ou non le calcul à convergence ok, // - la seconde dit si on doit sortir de la boucle ou non à convergence ok // // si la validation est effectuée, la sauvegarde pour le post-traitement est également effectuée // en fonction de la demande de sauvegard, // sinon pas de sauvegarde pour le post-traitement à moins que l'on a demandé un mode debug // qui lui fonctionne indépendamment void CalEquilibre(ParaGlob * ,LesMaillages *,LesReferences*,LesCourbes1D* ,LesFonctions_nD* ,VariablesExporter* ,LesLoisDeComp* ,DiversStockage*,Charge*,LesCondLim*,LesContacts*,Resultats* ,Tableau < Fonction_nD* > * tb_combiner); // dernière passe void FinCalcul(ParaGlob * ,LesMaillages *,LesReferences*,LesCourbes1D* ,LesFonctions_nD* ,VariablesExporter* ,LesLoisDeComp* ,DiversStockage*,Charge*,LesCondLim*,LesContacts*,Resultats* ); // sortie du schemaXML: en fonction de enu void SchemaXML_Algori(ofstream& sort,const Enum_IO_XML enu) const; protected : // VARIABLES PROTEGEES : // indicateur disant s'il faut calculer les conditions limites à chaque itération on non int cL_a_chaque_iteration; // par défaut, non, == uniquement à chaque début d'incrément // liste de variables de travail déclarées ici pour éviter le passage de paramètre entre les // méthodes internes à la classe double delta_t; int typeCalRelaxation ; // type de calcul de relaxation // ---para de contrôle du calcul de la masse double lambda; // le lambda effectif qui peut évoluer pendant le calcul double lambda_initial; // lambda initiale lue // a) contrôle éventuel de lambda via une ou plusieurs grandeurs globales Ponderation_GGlobal* niveauLambda_grandeurGlobale; // b) via éventuellement un ddl étendu Ponderation * niveauLambda_ddlEtendu; // c) via éventuellement le temps Ponderation_temps * niveauLambda_temps; // pilotage automatique éventuel double lambda_min,lambda_max,delta_lambda; bool pilotage_auto_lambda; List_io list_iter_relax; // sauvegarde des iters à suivre int casMass_relax; // indique le type de calcul de la matrice masse Tableau option_recalcul_mass; // indique le type de recalcul de la masse // par défaut dim = 1, si dim = 2, le premier est pour le cinétique le second // pour le visqueux Tableau fct_nD_option_recalcul_mass; // si non NULL: donne une // valeur qui remplace option_recalcul_mass Tableau nom_fct_nD_option_recalcul_mass; // nom éventuel de la fonction associée // --- pour typeCalRelaxation = 1 // .... pour la première version double alph,beta; // para de répartition entre K et mu double gamma; // para multiplicatif du rôle de la trace du tenseur de contrainte double theta; // para multiplicatif du rôle de la contrainte de mises // --- pour typeCalRelaxation = 2 int ncycle_calcul; int type_calcul_mass; double fac_epsilon; // facteur pour le test du recalcul de la matrice masse // -- pour typeCalRelaxation = 4 c-a-d mixte: amortissement cinétique au début puis visqueux à la fin double proportion_cinetique; // indique la proportion de la précision qui est faite en amortissement cinétique bool visqueux_activer; // permet d'éviter de revenir en arrière int et_recalcul_masse_a_la_transition; // indique si on recalcule la masse à la transition cinétique visqueux Ponderation_GGlobal* niveauF_grandeurGlobale; // b) via éventuellement un ddl étendu Ponderation * niveauF_ddlEtendu; // c) via éventuellement le temps Ponderation_temps* niveauF_temps; // === parametre pour le contact: int type_activation_contact; // indique quand le contact doit-être activé // 0: par défaut la recherche de nouveaux contacts est activée à la fin de chaque incrément // d'une manière analogue au cas d'un algo implicite classique // 1: la recherche de nouveaux contacts est activée après chaque itération // 2: la recherche de nouveaux contacts est activée après chaque pic d'énergie et à la fin // de chaque incrément. Si l'amortissement n'est pas cinétique, c'est équivalent au cas 0 // permet de choisir le type de remplacement des masses nulles // = 0 : on ne change rien, on laisse les 0 // = 1 : on choisit la valeur moyenne des valeurs de la matrice masse // = 2 : on choisit la valeur maxi des valeurs de la matrice masse int choix_mini_masse_nul; // -------------------------------------------------------------------------------------- // -- variables de transferts internes entre: InitAlgorithme, CalEquilibre, FinCalcul -- // -------------------------------------------------------------------------------------- // === pointeurs d'instance et classe particulières Assemblage * Ass1_, * Ass2_, * Ass3_; // pointeurs d'assemblages // === variables scalaires int cas_combi_ddl; // def combinaison des ddl int icas; // idem cas_combi_ddl mais pour lesCondlim int compteur; // compteur d'itération bool prepa_avec_remont; // comme son nom l'indique bool brestart; // booleen qui indique si l'on est en restart ou pas OrdreVisu::EnumTypeIncre type_incre; // pour la visualisation au fil du calcul int compteur_demarrage; // compteur pour les premiers incréments // === vecteurs Vecteur vglobin; // puissance interne (sans accélération): pour ddl accélération Vecteur vglobex; // puissance externe (sans accélération) Vecteur vglobaal; // puissance totale qui ecrase vglobin Vecteur vcontact; // puissance des forces de contact Vecteur save_X_t; // vecteur intermédiaire de sauvegarde Vecteur X_Bl,V_Bl,G_Bl; // stockage transitoirement des X V GAMMA <-> CL Vecteur forces_vis_num; // forces visqueuses d'origines numériques // === les listes list li_gene_asso; // tableaux d'indices généraux des ddl bloqués // === les tableaux Tableau t_assemb; // tableau globalisant les numéros d'assemblage de X V gamma Tableau tenuXVG; // les enum des inconnues // === les matrices Mat_abstraite* mat_masse,* mat_masse_sauve; // choix de la matrice de masse Mat_abstraite* mat_C_pt; // matrice visqueuse numérique Vecteur v_mass,v_mass1; // vecteurs intermédiaires qui servent pour la construction // de la matrice masse Tableau sortie_mass_noeud; // pour la sortie // de dimension le nombre de noeud Mat_abstraite* matglob; // choix de la matrice de raideur pour un assemblage à partir de la raideur réelle // ------------------------------------------------------------------------------------------ // -- fin variables de transferts internes entre: InitAlgorithme, CalEquilibre, FinCalcul -- // ------------------------------------------------------------------------------------------ // ---------- pour le calcul de la masse pour la méthode de relaxation dynamique static Ddl_enum_etendu masseRelax_1; // simplement pour le définir une fois pour toute static TypeQuelconque masseRelax_2; // simplement pour le définir une fois pour // METHODES PROTEGEES : // lecture des paramètres du calcul void lecture_Parametres(UtilLecture& 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 Ecrit_Base_info_Parametre(UtilLecture& entreePrinc,const int& cas); // 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 Lecture_Base_info_Parametre(UtilLecture& entreePrinc,const int& cas,bool choix); // création d'un fichier de commande: cas des paramètres spécifiques void Info_commande_parametres(UtilLecture& entreePrinc); // gestion et vérification du pas de temps et modif en conséquence si nécessaire // cas = 1: initialisation du pas de temps et vérif / au pas de temps critique // cas = 2: vérif / au pas de temps critique // en entrée: modif_pas_de_temps: indique qu'il y a eu par ailleurs (via Charge->Avance()) // une modification du pas de temps depuis le dernier appel // retourne vrai s'il y a une modification du pas de temps, faux sinon bool Gestion_pas_de_temps(bool modif_pas_de_temps,LesMaillages * lesMail,int cas); //---- 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 ActionInteractiveAlgo(); // initialisation pour le calcul de la matrice masse dans le cas de l'algorithme de relaxation dynamique void InitCalculMatriceMasse(LesMaillages * lesMail,Mat_abstraite& mat_mass ,Assemblage& Ass,Mat_abstraite& mat_mass_sauve ,LesFonctions_nD* lesFonctionsnD); // calcul de la matrice masse dans le cas de l'algorithme de relaxation dynamique void CalculMatriceMasse(const int& relax_vit_acce,LesMaillages * lesMail ,Assemblage& Ass, int compteur ,const DiversStockage* diversStockage,LesReferences* lesRef ,const Enum_ddl & N_ddl,LesContacts* lescontacts ,LesFonctions_nD* lesFonctionsnD); // calcul de la matrice masse dans le cas de l'algorithme de relaxation dynamique avec optimisation en continu // de la matrice masse // force_recalcul_masse : un indicateur pour forcer le calcul éventuellement // en retour est mis à false s'il était true en entrée void CalculEnContinuMatriceMasse(const int& relax_vit_acce,LesMaillages * lesMail ,Assemblage& Ass, int compteur ,const DiversStockage* diversStockage,LesReferences* lesRef ,const Enum_ddl & N_ddl,bool premier_calcul ,LesContacts* lescontacts ,bool & force_recalcul_masse,LesFonctions_nD* lesFonctionsnD); // dans le cas d'une relaxation de type 4 (mixte cinétique et visqueuse, on test pour savoir // s'il faut du visqueux ou du cinétique // ramène true si on continue en cinétique // false si on bascule // force_recalcul_masse : un indicateur de retour qui s'applique uniquement si // et_recalcul_masse_a_la_transition = true // et que l'on est juste à la transition, sinon il est toujours false bool Cinetique_ou_visqueux(bool & force_recalcul_masse); // calcul du facteur lambda en fonction de ce qui est demandé (automatique ou via une fonction etc.) double Calcul_Lambda(); // fonction virtuelle permettant de mettre à jour les infos aux noeuds // à cause de certains contact (ex: cas_contact = 4) // Les vecteurs Xtdt et Vtdt sont mis à jour par la méthode // la vitesse locale du noeud est mis à jour en fonction de la position locale et de l'algo virtual void Repercussion_algo_sur_cinematique(LesContacts* lesContacts,Vecteur& Xtdt,Vecteur& Vtdt) ; // des fonctions inlines pour mettre à jour des grandeurs globales // -- initialisation du fait que l'on est en amortissement cinétique (=1) ou visqueux (0) void Transfert_ParaGlob_AMOR_CINET_VISQUEUX() const {void* pt_void = ParaGlob::param->Mise_a_jour_grandeur_consultable(AMOR_CINET_VISQUEUX); TypeQuelconque* pt_quelc = (TypeQuelconque*) pt_void; Grandeur_scalaire_entier& gr = *((Grandeur_scalaire_entier*) pt_quelc->Grandeur_pointee()); // pour simplifier if (visqueux_activer) {*(gr.ConteneurEntier()) = 0;} else {*(gr.ConteneurEntier()) = 1;}; }; }; /// @} // end of group #endif