// 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: .
#ifndef PARAGLOB_H
#define PARAGLOB_H
/************************************************************************
* DATE: 19/01/2001 *
* $ *
* AUTEUR: G RIO (mailto:gerardrio56@free.fr) *
* $ *
* PROJET: Herezh++ *
* $ *
************************************************************************
*BUT:Ensemble de variables et de parametres globaux a tout le programme*
* les methodes permettent de changer certaines valeurs ou *
* de leurs donner une seule fois une valeur differente *
* de celle par defaut. *
* $ *
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * *
* VERIFICATION: *
* *
* ! date ! auteur ! but ! *
* ------------------------------------------------------------ *
* ! ! ! ! *
* $ *
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
* MODIFICATIONS: *
* ! date ! auteur ! but ! *
* ------------------------------------------------------------ *
* $ *
************************************************************************/
#include
using namespace std;
#include
#include
#include
#include // pour les interruptions systèmes
#include "Tableau_T.h"
#include "UtilLecture.h"
#include "EnumTypeCalcul.h"
#include "VariablesTemps.h"
#include "ParaAlgoControle.h"
#include "EnumLangue.h"
#include "Handler_exception.h"
#include "Enum_GrandeurGlobale.h"
#include "EnumTypeGrandeur.h"
#ifdef UTILISATION_MPI
#include "mpi.h"
#include
#include
#include
#include
namespace mpi = boost::mpi;
#endif
/** @defgroup Les_parametres_generaux
*
* BUT: groupe relatif à la gestion des paramètres généraux
*
*
* \author Gérard Rio
* \version 1.0
* \date 19/01/2001
* \brief groupe relatif à la gestion des paramètres généraux
*
*/
/// @addtogroup Les_parametres_generaux
/// @{
///
class ParaGlob
{ public :
// tout d'abord une méthode friend, qui a pour objectif de modifier éventuellement
// l'instance ParaAlgoControle courante
friend void Handler_signal(int theSignal);
friend class ParaAlgoControle;
friend class AlgoriCombine;
// déclaration de classe
ParaGlob (); // constructeur par defaut
ParaGlob (int dim); // constructeur en fonction de la dimension du pb
~ParaGlob (); // destructeur
// Constructeur de copie
ParaGlob (const ParaGlob & nd);
// les methodes publiques
static const int Dimension () // retourne la dimension du pb
{ return dimensionPb; } ;
const int NombreMaillage() // retourne la taille initiale du tableau de maillage
{ return NombreMaxiDeMaillage; };
// la dimension du pb ne peut etre change qu'une seule fois
void ChangeDimension(int ); //
// retourne le nombre de composantes des tenseurs en absolu
static const int NbCompTens ()
{ return nbComposantesTenseur; } ;
static ParaGlob * param; // pointeur sur le seul membre ouvert
// Ramène une référence sur l'ensemble des paramètres de contrôles qui sont actuellement "actifs"
// ne sera utile que pour de la consultation
const ParaAlgoControle & ParaAlgoControleActifs() const {return *paraAlgoControle;};
// change l'ensemble des paramètres de contrôles qui sont actuellement "actifs"
void ChangeParaAlgoControleActifs( ParaAlgoControle * para) {paraAlgoControle = para;};
#ifdef UTILISATION_MPI
//-- pour le calcul parallèle
// récup de l'environnement et init
static boost::mpi::environment * Environnement() { return env;};
static void Init_boost_environnement(boost::mpi::environment * pt_env)
{env = pt_env;};
// récup du communicateur global et init
static boost::mpi::communicator * Monde() {return world;};
static void Init_boost_communicator (boost::mpi::communicator * pt_world)
{world = pt_world;};
// -- equilibrage d'éléments et noeuds associés
void Init_tableau (const Tableau > >* tab_list_maillage_element
,const Tableau > >* tab_indic
,const Tableau > >* tab_list_maillage_noeud
,const Tableau > >* tab_indic_noeud)
{tab_list_mail_element = tab_list_maillage_element;
tabb_indic = tab_indic;
tab_list_mail_noeud = tab_list_maillage_noeud;
tabb_indic_noeud = tab_indic_noeud;
};
// retour des listes des éléments relatif au cpu en cours, c-a-d pour tous les maillages
// tab (j) donne la liste des éléments pour le maillage j
const Tableau < list > & const_List_element_CPU_en_cours() const
{return (*tab_list_mail_element)(world->rank());};
// spécifiquement, la liste des éléments pour le maillage j
const list & const_List_element_CPU_en_cours(int j) const
{return (*tab_list_mail_element)(world->rank())(j);};
// indicateur permettant de dire si un élément est concerné par le cpu en cours
// tab_indic(mail)(ele) : = 1 si l'élément ele du maillage mail est concerné
// par le CPU
bool Element_concerner(int mail,int ele) const
{return (*tabb_indic)(world->rank())(mail)(ele);};
// retour des listes des noeuds relatif au cpu en cours, c-a-d pour tous les maillages
// tab (j) donne la liste des noeuds pour le maillage j
const Tableau < list > & const_List_noeud_CPU_en_cours() const
{return (*tab_list_mail_noeud)(world->rank());};
// spécifiquement, la liste des noeud pour le maillage j
const list & const_List_noeud_CPU_en_cours(int j) const
{return (*tab_list_mail_noeud)(world->rank())(j);};
// indicateur permettant de dire si un noeud est concerné par le cpu en cours
// tab_indic_noeud(mail)(ne) : = 1 si noeud ne du maillage mail est concerné
// par le CPU
bool Noeud_concerner(int mail,int ne) const
{return (*tabb_indic_noeud)(world->rank())(mail)(ne);};
#endif
// lecture du type de calcul et d'une liste de sous_type éventuel
void LecTypeCalcul(UtilLecture& lec);
// définition interactive du type de calcul et d'une liste de sous_type éventuel
// écriture du fichier de commande
void Info_commande_TypeCalcul(UtilLecture& lec);
// retourne le type de calcul principal: en fait le type maître
// qui est unique et dure pendant toute l'exécution
// il peut-être différent de celui de l'algo en cours, du coup il permet de savoir
// à l'algo en cours s'il est maître ou pas
EnumTypeCalcul TypeCalcul_maitre() {return typeDeCalcul_maitre;};
// retourne vraie si le type de calcul demandé est celui en cours
// et s'il est actif
// dans le cas où le paramètre optionnel est true, il n'y a pas de test
// si le type de calcul demandé est actif ou pas
bool TypeCalcul_principal(EnumTypeCalcul type,bool actif=false);
// détermine si le sous type de calcul existe et s'il est actif
bool SousTypeCalcul(EnumSousTypeCalcul soustype);
// détermine si le type de calcul est activé ou pas
bool Avec_typeDeCalcul() const { return avec_typeDeCalcul;};
// retourne la liste de sous_types en cours
list const & LesSousTypesDeCalcul() const { return soustypeDeCalcul;};
// retourne une liste de booleen cohérente avec la liste des sous_types
// chaque booleen indique si le sous_type correspondant est actif ou pas
list const& Avec_soustypeDeCalcul() const{ return avec_soustypeDeCalcul;};
// affichage du type de calcul et des sous_types éventuelles
void AfficheTypeEtSousTypes();
// retourne le niveau d'impression
static int NiveauImpression() {return nivImpression;};
// modifie le niveau d'impression
void Change_niveau_impression(int n );
// ramène l'identificateur de la version d'herezh++
// sur 5 caractères
static string NbVersion() { return nbVersion;};
// affichage de la version sur la sortie passée en argument
static void Sortie_Version(ofstream & sort)
{ sort << "\n version " << nbVersion ;};
// affichage de la version sur cout
static void Sortie_Version()
{ cout << "\n version " << nbVersion ;};
// lecture de la version sur l'entrée passée en argument
static string Lecture_Version(ifstream& entr)
{ string toto; entr >>toto >> NbVersionsurfichier; return NbVersionsurfichier;};
// lecture de la version sur l'entrée passée en argument
static string Lecture_Version(istream& entr)
{ string toto; entr >>toto >> NbVersionsurfichier; return NbVersionsurfichier;};
// retour de la version lue sur fichier
static string NbVersion_de_fichier(){return NbVersionsurfichier;};
// lecture de l'indicateur de langue sur l'entrée passée en argument
static EnumLangue Lecture_Langue(ifstream& entr)
{ string toto; entr >>toto >> langueHZ; return langueHZ;};
// lecture de l'indicateur de langue sur l'entrée passée en argument
static EnumLangue Lecture_Langue(istream& entr)
{ string toto; entr >>toto >> langueHZ; return langueHZ;};
// retour de la langue
static EnumLangue Langage(){return langueHZ;};
static bool Anglais() {return (langueHZ == ENGLISH);};
static bool Francais() {return (langueHZ == FRANCAIS);};
// affichage de la langue sur la sortie passée en argument
static void Sortie_Langue(ofstream & sort) { sort << "\n langue " << langueHZ ;};
// ramène le nombre de diggit utilisé pour afficher des réels en double précision pour l'archivage
// de calcul
static int NbdigdoCA() { return nb_diggit_double_calcul;};
// ramène le nombre de diggit utilisé pour afficher des réels en double précision pour l'affichage
// du graphique
static int NbdigdoGR() { return nb_diggit_double_graphique;};
// ramène le nombre de diggit utilisé pour afficher des réels en double précision pour l'affichage
// sur l'écran
static int NbdigdoEC() { return nb_diggit_double_ecran;};
// change le nombre de diggit utilisé pour l'affichage des réels en double précision
// int cas =1 pour le calcul, = 2 pour le graphique
// =3 pour l'écran
void Change_Nb_diggit_double(int cas, int nevez_nb_diggit);
// indique si oui ou non, l'espace est axisymétrique
static bool AxiSymetrie() {return geometrie_axisymetrique;};
// changement d'espace non axisymétrique en un espace axisymétrique
// (c'est le seule changement accepter actuellement)
static void Change_en_AxiSymetrie() {geometrie_axisymetrique=true;};
// une méthode permettant de lire les grandeurs globales
static std::vector & Grandeurs_globales() {return grandeurs_globales;};
//----- lecture écriture dans base info -----
// cas donne le niveau de la récupération
// = 1 : on récupère tout
// = 2 : on récupère uniquement les données variables (supposées comme telles)
void Lecture_base_info(ifstream& ent,const int cas);
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void Ecriture_base_info(ofstream& sort,const int cas);
//------------ gestion lecture dans le .info ---------
// --- variable de lecture du .info, utilisées par des classes externes
// en particulier: Projet et les Algorithmes
// 1) récupération de l'état de la lecture dans le fichier .info
// =-1 : non initialisée
// =0 après la première lecture "globale" du .info
// =n après la nième lecture "secondaire" dans le .info
int EtatDeLaLecturePointInfo() const {return etatDeLaLecturePointInfo;};
void ChangeEtatDeLaLecturePointInfo(int etat) { etatDeLaLecturePointInfo=etat;};
// 1) demande d'une lecture secondaire dans le point info
// 0 pas de demande: valeur par défaut, = 1 demande d'une lecture supplémentaire
void ChangeDemandeLectureSecondaireInPointInfo(int val) {demandeLectureSecondaireInPointInfo=val;};
int EtatDemandeLectureSecondaireInPointInfo() const {return demandeLectureSecondaireInPointInfo;};
// ======== gestion du temps ============================================
static void Init_temps(VariablesTemps& temps)
{tempo = &temps;};
// récup des paramètres liés au temps
static const VariablesTemps& Variables_de_temps() {return *tempo;};
// ---- aller-retour en lecture sur des grandeurs globalisées
// la classe ParaGlob ne sert que de relais, elle stocke uniquement la grandeur
// mais n'est pas responsable de leur utilisation
// Il faudra utiliser un try, lors de l'utilisation des grandeurs pour tracer
// les erreurs éventuelles de déférencement, car il faut ensuite faire un cast
// pour utiliser la grandeur
// retoune un pointeur de la grandeur: qui est tjs de type : TypeQuelconque
// si jamais le nom de la grandeur n'existe pas, le retour pointe sur NULL
const void * GrandeurGlobal(Enum_GrandeurGlobale enu ) const
{if (listegrandeurs.find(enu) == listegrandeurs.end())
return NULL; else return listegrandeurs.at(enu);
};
// idem mais pour une grandeur typée par une chaine de caractère,
const void * GrandeurGlobal(const string& nom_ref ) const
{if (!((nom_ref[0]=='V') && (nom_ref[1]=='R') && (nom_ref[2] == '_')))
// cas normal, générique
{std::map< string, const void * , std::less >::const_iterator
il_ref =listegrandeurs_par_string.find(nom_ref);
if (il_ref == listegrandeurs_par_string.end())
{return NULL;}
else
{ return il_ref->second;};
}
else
// là il s'agit d'une variable composante
{return this->GrandeurGlobal_relaie(nom_ref );};
};
// ajout d'une nouvelle grandeur qui restera ensuite disponible
void Ajout_grandeur_consultable(void* grandeur, Enum_GrandeurGlobale enu);
// idem mais pour une grandeur typée par une chaine de caractère,
void Ajout_grandeur_consultable(void* grandeur, string nom_ref);
// récupération d'une grandeur quelconque pour modification
// après l'appel de cette méthode, la grandeur quelconque est réputée updaté
void * Mise_a_jour_grandeur_consultable(Enum_GrandeurGlobale enu);
// idem mais pour une grandeur typée par une chaine de caractère,
void * Mise_a_jour_grandeur_consultable(const string& nom_ref);
// raccourci pour mettre à jour une grandeur consultable de type: Grandeur_scalaire_double
void Mise_a_jour_grandeur_consultable_Scalaire_double(Enum_GrandeurGlobale enu,const double& valeur);
void Mise_a_jour_grandeur_consultable_Scalaire_double(const string& nom_ref,const double& valeur);
// modification interactive d'une constante utilisateur
void Modif_interactive_constante_utilisateur()
{UtilLecture::Modif_interactive_constante_utilisateur();};
// suppression d'une grandeur
void Suppression_grandeur_consultable(Enum_GrandeurGlobale enu);
// idem mais pour une grandeur typée par une chaine de caractère,
void Suppression_grandeur_consultable(const string& nom_ref);
// affichage de la liste des noms de grandeurs actuelles accessibles globalement
void Affiche_GrandeurGlobal(ostream & sort) const;
// récupération de la liste des noms de grandeurs actuelles accessibles globalement
// la liste passée en paramètre est vidée puis remplie par les grandeurs actuelles
void Recup_list_GrandeurGlobal(list & list_grandeurs_globals) const;
// cas particulier du temps courant
// mise à jour du temps : permet de mettre à jour la variable globale TEMPS_COURANT
// doit-être appelé à chaque modification du temps courant
void Mise_a_jour_TEMPS_COURANT() {*pt_temps_courant = (tempo->TempsCourant());};
// // --- gestion des typeQuelconque_enum_etendu
// // un drapeau qui permet de savoir
// // globalement, que la liste des typeQuelconque_enum_etendu a été modifié
// bool T_typeQuelconque_enum_etendu_modifier()
// const {return tab_typeQuelconque_enum_etendu_modifier;};
// // modification du drapeau
// void Change_T_typeQuelconque_enum_etendu_modifier(bool new_statut)
// {tab_typeQuelconque_enum_etendu_modifier=new_statut;}
//------------------------------------------- uniquement protégé ------------------
protected:
// Ramène une référence sur l'ensemble des paramètres de contrôles qui sont actuellement "actifs"
// n'est accessible que des fonctions friends, permet la modification de l'instance
ParaAlgoControle & ParaAlgoContActifs() {return *paraAlgoControle;};
// changement de paramètres pointés
void Change_ParaAlgoControle(ParaAlgoControle& pa)
{paraAlgoControle = &pa;
tempo->Mise_a_jour_bornes(pa.Variables_de_temps_specifiques_algo());
};
// un tableau de grandeurs globales quelconques pour être accessibles de partout
// ici il s'agit d'un conteneur intermédiaire qui est mis à jour par ParaAlgoControle
static std::vector grandeurs_globales;
// une méthode permettant de mettre à jour les éléments du tableau
// uniquement accessible par la classe friend ParaAlgoControle
static std::vector & Mise_a_jour_Grandeurs_globales() {return grandeurs_globales;};
// liste des grandeurs consultables de partout sous forme d'un arbre pour faciliter la recherche
std::map < Enum_GrandeurGlobale, const void * , std::less > listegrandeurs;
// idem pour une liste des grandeurs consultables de partout typée par une chaine de caractères
std::map < string, const void * , std::less > listegrandeurs_par_string;
double * pt_temps_courant; // pointeur interne pour lier TEMPS_COURANT avec tempo
private :
static EnumLangue langueHZ; // langue utilisée pour les entrées sorties
static int dimensionPb; // dimension du probleme = 1 unidimensionnel par defaut
int chdimensionPb ; // blocage de la dimension
// nombre de composantes des tenseurs en absolu
static int nbComposantesTenseur;
static int nivImpression; // niveau d'impression
static string nbVersion; // numéro de version du logiciel
static string NbVersionsurfichier; // numéro de version lue sur l'entrée
// info pour l'affichage:
// nombre de chiffre significatifs utilisé pour l'affichage des double précision
// pour l'archivage, pour le graphique et pour l'écran
static int nb_diggit_double_calcul;
static int nb_diggit_double_graphique;
static int nb_diggit_double_ecran;
#ifdef UTILISATION_MPI
// -- pour le calcul parallèle
static boost::mpi::environment * env; // environnement global
static boost::mpi::communicator * world; // le communicateur global
// -- equilibrage d'éléments
// tab_list_maillage_element(i)(j) contient la liste
// pour le maillage j des num <élément> associés au cpu i
// ici il s'agit d'une copie de tab_list_maillage_element qui doit être mise à jour par Distribution_CPU
const Tableau > >* tab_list_mail_element;
// indicateur permettant de dire si un élément est concerné par un CPU donné
// tab_indic(CPU)(mail)(ele) : = 1 si l'élément ele du maillage mail est concerné
// par le CPU, il s'agit d'une copie qui doit être mise à jour par Distribution_CPU
const Tableau > >* tabb_indic;
// -- noeuds associés aux éléments
// tab_list_maillage_noeud(i)(j) contient la liste
// pour le maillage j des num associés au cpu i
// ici il s'agit d'une copie de tab_list_maillage_noeud qui doit être mise à jour par Distribution_CPU
const Tableau > >* tab_list_mail_noeud;
// indicateur permettant de dire si un noeud est concerné par un CPU donné
// tab_indic_noeud(CPU)(mail)(ne) : = 1 si le noeud ne du maillage mail est concerné
// par le CPU, il s'agit d'une copie qui doit être mise à jour par Distribution_CPU
const Tableau > >* tabb_indic_noeud;
#endif
//------------ info sur le temps ---------------
// c'est paraAlgoControle qui gère le temps, cependant paraglob sert de relais pour
// ramené les infos sur le temps
static VariablesTemps* tempo; // contient les différentes grandeurs liées au temps
int NombreMaxiDeMaillage; // taille initiale du tableau des maillages
EnumTypeCalcul typeDeCalcul_maitre; // identificateur du type de Calcul principal ou maître
static bool geometrie_axisymetrique; // indique si oui ou non, l'espace est axisymétrique
// éventuellement par la suite on aura plusieurs type de calcul à enchainer
// d'où il faudra le type en cours et une liste de tous les types à pourvoir
list soustypeDeCalcul; // identificateurs secondaire optionnel
//du type de Calcul renseigne sur le fait de calculer l'erreur,
// une relocation, un raffinement, éventuel.
bool avec_typeDeCalcul; // def si le calcul a lieu effectivement
list avec_soustypeDeCalcul; // def si les sous-types existent seulement ou
// si il faut les prendre en compte effectivement.
// bool tab_typeQuelconque_enum_etendu_modifier; // un drapeau qui permet de savoir
// // globalement, que la liste des typeQuelconque_enum_etendu a été modifié
//
// pointeur sur l'ensemble des paramètres de contrôles qui sont actuellement "actifs"
// la valeur pointée peut évoluer pendant le calcul (il peut y avoir plusieurs paquets de paramètres
// de contrôle présent dans le programme)
ParaAlgoControle * paraAlgoControle;
// // un tableau de grandeurs globales quelconques pour être accessibles de partout
// static std::vector grandeurs_globales;
// // une méthode permettant de mettre à jour les éléments du tableau de grandeurs globales
// // via uniquement la classe friend paraAlgoControle
// void Mise_a_jour_Grandeurs_globales(std::vector & grandeurs)
// {grandeurs_globales=grandeurs;};
// --- variables qui sont stockées ici, mais sont utilisées par des classes externes
// en particulier: Projet et les Algorithmes
int etatDeLaLecturePointInfo; // =0 après la première lecture "globale" du .info
// =n après la nième lecture "secondaire" dans le .info
int demandeLectureSecondaireInPointInfo; // 0 pas de demande: valeur par défaut
// 1 demande d'une lecture supplémentaire
// ---définition d'une structure permettant de gérer les interruptions systèmes type: controle-c
struct sigaction prepaSignal;
// récup d'une composante d'une grandeur quelconque d'une grandeur globale
const void * GrandeurGlobal_relaie(const string& nom_ref ) const;
};
/// @} // end of group
#endif