// 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 "ParaGlob.h" #include "Sortie.h" #include "Banniere.h" #include "Handler_exception.h" #include "EnumTypeGrandeur.h" #include "TypeQuelconque.h" #include "TypeQuelconqueParticulier.h" // ----------- déclaration des variables statiques ----------------- // elles sont faites dans EnteteParaGlob.h // ----------- fin de la déclaration des variables statiques ------- // constructeur par defaut ParaGlob::ParaGlob() : typeDeCalcul_maitre(RIEN_TYPECALCUL),soustypeDeCalcul() ,avec_typeDeCalcul(false),avec_soustypeDeCalcul() ,paraAlgoControle(NULL),chdimensionPb(0),NombreMaxiDeMaillage(5) ,etatDeLaLecturePointInfo(-1),demandeLectureSecondaireInPointInfo(0) ,listegrandeurs(),listegrandeurs_par_string() ,pt_temps_courant(NULL) // ,tab_typeQuelconque_enum_etendu_modifier(false) { dimensionPb = 1; // calcul du nombre de composantes des tenseurs en absolu nbComposantesTenseur = 1; // cas par défaut 1D if (dimensionPb == 2) nbComposantesTenseur = 3; else if (dimensionPb == 3) nbComposantesTenseur= 6; if (param != NULL) {// normalement on devrait pas utiliser le contructeur de copie cout << "\n warning : normalement on ne devrait pas avoir plusieurs ParaGlob !!!! "; cout << "\n ParaGlob::ParaGlob()"; }; param=this; // le seul pointeur dispo // --- cas de la gestion des interruptions systèmes --- Remplissage de la structure ad hoc /* adresse du gestionnaire */ prepaSignal.sa_handler = &(Handler_signal); // par défaut on utilise la fonction /* Mise a zero du champ sa_flags theoriquement ignoré */ prepaSignal.sa_flags=0; /* On ne bloque pas de signaux spécifiques */ sigemptyset(&prepaSignal.sa_mask); // --- gestion d'une interruption ctrl-c --- sigaction(SIGINT,&prepaSignal,0); // SIGINT correspond à controle-c sigaction(SIGTERM,&prepaSignal,0); // SIGTERM correspond à kill 15 // ajout de la grandeur global TEMPS_COURANT par défaut Grandeur_scalaire_double grand_courant(0.); TypeQuelconque typQ1(GENERIQUE_UNE_GRANDEUR_GLOBALE,NU_DDL,grand_courant); Ajout_grandeur_consultable(&typQ1,TEMPS_COURANT); // mise à jour du pointeur qui fait la liaison avec le temps courant {TypeQuelconque* pt_quelc = (TypeQuelconque*) listegrandeurs.at(TEMPS_COURANT); Grandeur_scalaire_double& gr = *((Grandeur_scalaire_double*) pt_quelc->Grandeur_pointee()); // pour simplifier pt_temps_courant = gr.ConteneurDouble(); // on pointe sur le conteneur }; }; // constructeur en fonction de la dimension du pb ParaGlob::ParaGlob(int dim) : typeDeCalcul_maitre(RIEN_TYPECALCUL),soustypeDeCalcul() ,avec_typeDeCalcul(false),avec_soustypeDeCalcul() ,paraAlgoControle(NULL),chdimensionPb(0),NombreMaxiDeMaillage(5) ,etatDeLaLecturePointInfo(-1),demandeLectureSecondaireInPointInfo(0) ,listegrandeurs(),listegrandeurs_par_string() ,pt_temps_courant(NULL) // ,tab_typeQuelconque_enum_etendu_modifier(false) { dimensionPb = dim; // calcul du nombre de composantes des tenseurs en absolu nbComposantesTenseur = 1; // cas par défaut 1D if (dimensionPb == 2) nbComposantesTenseur = 3; else if (dimensionPb == 3) nbComposantesTenseur= 6; if (param != NULL) {// normalement on devrait pas utiliser le contructeur de copie cout << "\n warning : normalement on ne devrait pas avoir plusieurs ParaGlob !!!! "; cout << "\n ParaGlob::ParaGlob(int dim)"; }; param=this; // le seul pointeur dispo // --- cas de la gestion des interruptions systèmes --- Remplissage de la structure ad hoc /* adresse du gestionnaire */ prepaSignal.sa_handler = &(Handler_signal); // par défaut on utilise la fonction /* Mise a zero du champ sa_flags theoriquement ignoré */ prepaSignal.sa_flags=0; /* On ne bloque pas de signaux spécifiques */ sigemptyset(&prepaSignal.sa_mask); // --- gestion d'une interruption ctrl-c --- sigaction(SIGINT,&prepaSignal,0); // SIGINT correspond à controle-c sigaction(SIGTERM,&prepaSignal,0); // SIGTERM correspond à kill 15 // ajout de la grandeur global TEMPS_COURANT par défaut Grandeur_scalaire_double grand_courant(0.); TypeQuelconque typQ1(GENERIQUE_UNE_GRANDEUR_GLOBALE,NU_DDL,grand_courant); Ajout_grandeur_consultable(&typQ1,TEMPS_COURANT); // mise à jour du pointeur qui fait la liaison avec le temps courant {TypeQuelconque* pt_quelc = (TypeQuelconque*) listegrandeurs.at(TEMPS_COURANT); Grandeur_scalaire_double& gr = *((Grandeur_scalaire_double*) pt_quelc->Grandeur_pointee()); // pour simplifier pt_temps_courant = gr.ConteneurDouble(); // on pointe sur le conteneur }; }; // Constructeur de copie ParaGlob::ParaGlob (const ParaGlob & nd) : typeDeCalcul_maitre(nd.typeDeCalcul_maitre),chdimensionPb(nd.chdimensionPb) ,NombreMaxiDeMaillage(nd.NombreMaxiDeMaillage) ,soustypeDeCalcul(nd.soustypeDeCalcul) ,avec_typeDeCalcul(nd.avec_typeDeCalcul) ,avec_soustypeDeCalcul(nd.avec_soustypeDeCalcul) ,paraAlgoControle(nd.paraAlgoControle) ,etatDeLaLecturePointInfo(nd.etatDeLaLecturePointInfo) ,demandeLectureSecondaireInPointInfo(nd.demandeLectureSecondaireInPointInfo) ,listegrandeurs(nd.listegrandeurs),listegrandeurs_par_string(nd.listegrandeurs_par_string) // ,tab_typeQuelconque_enum_etendu_modifier(nd.tab_typeQuelconque_enum_etendu_modifier) { // normalement on devrait pas utiliser le contructeur de copie cout << "\n ******* warning : normalement on ne devrait pas avoir plusieurs ParaGlob !!!! "; cout << "\n ******* ParaGlob::ParaGlob (const ParaGlob & nd)"; // --- cas de la gestion des interruptions systèmes --- Remplissage de la structure ad hoc /* adresse du gestionnaire */ prepaSignal.sa_handler = &(Handler_signal); // par défaut on utilise la fonction /* Mise a zero du champ sa_flags theoriquement ignoré */ prepaSignal.sa_flags=0; /* On ne bloque pas de signaux spécifiques */ sigemptyset(&prepaSignal.sa_mask); // --- gestion d'une interruption ctrl-c --- sigaction(SIGINT,&prepaSignal,0); // SIGINT correspond à controle-c sigaction(SIGTERM,&prepaSignal,0); // SIGTERM correspond à kill 15 // mise à jour du pointeur qui fait la liaison avec le temps courant {TypeQuelconque* pt_quelc = (TypeQuelconque*) listegrandeurs.at(TEMPS_COURANT); Grandeur_scalaire_double& gr = *((Grandeur_scalaire_double*) pt_quelc->Grandeur_pointee()); // pour simplifier pt_temps_courant = gr.ConteneurDouble(); // on pointe sur le conteneur }; }; ParaGlob::~ParaGlob () {// suppression des conteneurs globaux {std::map < Enum_GrandeurGlobale, const void * , std::less >::iterator il,ilfin=listegrandeurs.end(); for (il=listegrandeurs.begin(); il!= ilfin; ++il) {TypeQuelconque* gr_quelc = (TypeQuelconque*) il->second; delete gr_quelc; }; }; {std::map < string, const void * , std::less >::iterator il,ilfin=listegrandeurs_par_string.end(); for (il=listegrandeurs_par_string.begin(); il!= ilfin; ++il) {TypeQuelconque* gr_ici = (TypeQuelconque*) listegrandeurs_par_string.at(il->first); delete gr_ici; }; } }; // destructeur // changement de la dimension du pb : une seule fois void ParaGlob::ChangeDimension(int nouvelleDimension) { if ((chdimensionPb==0)&&(nouvelleDimension<=3)&&(nouvelleDimension>= 1)) {dimensionPb = nouvelleDimension;chdimensionPb=1;} else cout << " **changement de dimension au probleme non autorise** "; }; // lecture du type de calcul et d'une liste de sous type éventuel void ParaGlob::LecTypeCalcul(UtilLecture& lec) { if (strstr(lec.tablcar,"TYPE_DE_CALCUL")!=NULL) { lec.NouvelleDonnee(); LectureTypeCalcul(lec,typeDeCalcul_maitre,avec_typeDeCalcul ,soustypeDeCalcul,avec_soustypeDeCalcul); } else { cout << " \n erreur de lecture du mot cle TYPE_DE_CALCUL, arret lecture \n"; cout << " ParaGlob::LecTypeCalcul(UtilLecture& lec) " << endl; } }; // définition interactive du type de calcul et d'une liste de sous_type éventuel // écriture du fichier de commande void ParaGlob::Info_commande_TypeCalcul(UtilLecture& lec) { switch (lec.Lec_ent_info()) {case -12: // cas de la sortie d'un schéma XML {// l'idée ici est de définir les infos par défaut permettant de construire le schéma typeDeCalcul_maitre=DEF_SCHEMA_XML; avec_typeDeCalcul=true; // on ne définie pas de sous type break; } default: // cas d'une lecture standard sur fichier {// affichage des différents type de calcul et choix du type et éventuellement // de sous type Info_commande_type_calcul(lec,typeDeCalcul_maitre,avec_typeDeCalcul ,soustypeDeCalcul,avec_soustypeDeCalcul); }; }; }; // 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 "actif" est true, il n'y a pas de test // si c'est actif ou pas bool ParaGlob::TypeCalcul_principal(EnumTypeCalcul type,bool actif) { if ((type == typeDeCalcul_maitre) && (avec_typeDeCalcul || actif)) return true; else return false; }; // détermine si le sous type de calcul existe et s'il est actif bool ParaGlob::SousTypeCalcul(EnumSousTypeCalcul soustype) { bool retour = false; // retour faux a priori list ::iterator ili; list ::iterator ila; list ::iterator ilifin = avec_soustypeDeCalcul.end(); for (ili = avec_soustypeDeCalcul.begin() ,ila = soustypeDeCalcul.begin() ;ili!= ilifin; ili++,ila++) if ((soustype == (*ila)) && (*ili)) retour = true; return retour; }; // affichage du type de calcul et des sous_types éventuelles void ParaGlob::AfficheTypeEtSousTypes() { cout << "\n --> type de calcul = " << Nom_TypeCalcul(typeDeCalcul_maitre) << '\n'; // puis les sous types list ::iterator ili; list ::iterator ila; list ::iterator ilifin = avec_soustypeDeCalcul.end(); for (ili = avec_soustypeDeCalcul.begin() ,ila = soustypeDeCalcul.begin() ;ili!= ilifin; ili++,ila++) { cout << "sous_type : " << Nom_SousTypeCalcul(*ila) << " "; if (*ili) cout << " actif \n"; else cout << " inactif \n"; } }; // modifie le niveau d'impression void ParaGlob::Change_niveau_impression(int n ) { // vérification du niveau d'impression demandée if (n >= 10) nivImpression = 10; else if (n <= 0) nivImpression = 0; else nivImpression = n; }; // 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 void ParaGlob::Change_Nb_diggit_double(int cas,int n_nb_dig) { if ( n_nb_dig <= 0) { cout << "\n erreur le nombre de chiffre significatif pour l'affichage des reel doit etre >= 1" << "\n alors que la valeur demandé est : " << n_nb_dig << "!!!" << "\n ParaGlob::Change_Nb_diggit_double(int n_nb_dig)"; Sortie(1); } if (cas == 1) nb_diggit_double_calcul = n_nb_dig; else if (cas == 2) nb_diggit_double_graphique = n_nb_dig; else if (cas == 3) nb_diggit_double_ecran = n_nb_dig; else { cout << "\n erreur le cas = " << cas << "n'est pas implanté " << "\n ParaGlob::Change_Nb_diggit_double(int n_nb_dig)"; Sortie(1); } }; //----- lecture écriture de base info ----- // lecture base info // = 1 : on récupère tout // = 2 : on récupère uniquement les données variables (supposées comme telles) void ParaGlob::Lecture_base_info(ifstream& entr,const int cas) { // a priori il n'y a pas de grandeur qui varie d'où lecture uniquement // dans le cas =1 if (cas == 1) { // passage de la banniere Banniere::Passage_lecture_banniere(entr); // lecture du numéro de version de l'entrée Lecture_Version(entr); // lecture de la langue ParaGlob::Lecture_Langue(entr); // message si numéro de version différent if(NbVersionsurfichier != nbVersion) cout << "\n **** attention le numero de version de votre fichier d'entree est " << " plus ancien que la version actuelle d'HEREZH++, " << " \n il peut eventuellement y avoir des disfonctionnements (cf doc)" << "\n ************** \n"; // lecture de la dimension string toto; entr >> toto >> dimensionPb; if ((dimensionPb!=1)&&(dimensionPb!=2)&&(dimensionPb!=3)) { // dans le cas ou déjà la dimension est mauvaise // on signal qu'il y a un pb dans Paraglob cout << "\n*** erreur de lecture de dimension du problème ***\n" << " ParaGlob::Lecture_base_info(ifstream& entr,const int cas)"; Sortie(1); }; // niveau d'impression des commentaires entr >> toto >> nivImpression ; // def du nombre de composantes des tenseurs en absolu nbComposantesTenseur = 1; // cas par défaut 1D if (dimensionPb == 2) nbComposantesTenseur = 3; else if (dimensionPb == 3) nbComposantesTenseur= 6; // lecture du type de pb string typecal,soustypecal; int nb_soustype; bool act_soustype; entr >> toto >> typecal >> toto >> avec_typeDeCalcul >> toto >> nb_soustype; typeDeCalcul_maitre = Id_nom_TypeCalcul (typecal.c_str()); // remplissage de la liste de sous type for (int i=1;i<=nb_soustype;i++) { entr >> soustypecal >> act_soustype; soustypeDeCalcul.push_back(Id_nom_SousTypeCalcul(soustypecal.c_str())); avec_soustypeDeCalcul.push_back(act_soustype); } } ; }; // écriture base info // = 1 : on sauvegarde tout // = 2 : on sauvegarde uniquement les données variables (supposées comme telles) void ParaGlob::Ecriture_base_info(ofstream& sort,const int cas) { // a priori il n'y a pas de grandeur qui varie d'où sauvegarde uniquement // dans le cas =1 if (cas == 1) { // sortie de la banniere Banniere::Sortie_banniere( sort); // puis affichage de la version ParaGlob::Sortie_Version(sort); // puis affichage de la langue ParaGlob::Sortie_Langue(sort); sort << "\n"; // écriture de la dimension sort << " Dimension " << dimensionPb << "\n"; // niveau d'impression des commentaires sort << " niveau_impression " << nivImpression << "\n"; // puis type de calcul sort << "\n PARAGLOB " << Nom_TypeCalcul(typeDeCalcul_maitre) << " " << "activation? " << avec_typeDeCalcul ; sort << " ,NB__sous_type_de_calcul " << avec_soustypeDeCalcul.size() << " \n" ; list ::iterator ili; list ::iterator ila; list ::iterator ilifin = avec_soustypeDeCalcul.end(); for (ili = avec_soustypeDeCalcul.begin() ,ila = soustypeDeCalcul.begin() ;ili!= ilifin; ili++,ila++) sort << Nom_SousTypeCalcul(*ila) << " " << (*ili) << " "; } ; }; // ajout d'une nouvelle grandeur qui restera ensuite disponible void ParaGlob::Ajout_grandeur_consultable(void* grandeur, Enum_GrandeurGlobale enu) { // les grandeurs sont systématiquement et uniquement des types quelconque TypeQuelconque* gr_quelc = (TypeQuelconque*) grandeur; // // liste des grandeurs consultables de partout sous forme d'un arbre pour faciliter la recherche // std::map < Enum_GrandeurGlobale, const void * , std::less > listegrandeurs; std::map < Enum_GrandeurGlobale, const void * , std::less >::iterator il; il = listegrandeurs.find(enu); if (il == listegrandeurs.end()) // cas où la grandeur n'existe pas, on l'enregistre {TypeQuelconque* nouveau_tq = new TypeQuelconque(*gr_quelc); listegrandeurs[enu] = nouveau_tq; } else // sinon comme elle existe, on peut faire un cast { TypeQuelconque* gr_ici = (TypeQuelconque*) listegrandeurs.at(enu); TypeQuelconque::Grandeur* gr_ici_pt = gr_ici->Grandeur_pointee(); TypeQuelconque::Grandeur* gr_quelc_pt = gr_quelc->Grandeur_pointee(); // on vérifie que la place est identique sinon on couine if ( (gr_ici_pt->Type_grandeurAssocie() != gr_quelc_pt->Type_grandeurAssocie() ) || (gr_ici_pt->Type_structure_grandeurAssocie() != gr_quelc_pt->Type_structure_grandeurAssocie() ) || (gr_ici_pt->Type_enumGrandeurParticuliere() != gr_quelc_pt->Type_enumGrandeurParticuliere() ) || (gr_quelc->EnuTypeQuelconque() != GENERIQUE_UNE_GRANDEUR_GLOBALE) ) { cout << "\n *** erreur , la grandeur "< 5) {cout << "\n ParaGlob::Ajout_grandeur_consultable(..";}; Sortie(1); }; // sinon tout va bien }; }; // 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 * ParaGlob::Mise_a_jour_grandeur_consultable(Enum_GrandeurGlobale enu) { if (listegrandeurs.find(enu) == listegrandeurs.end()) { cout << "\n *** erreur en acces à la grandeur "<Grandeur_pointee()); // pour simplifier *(gr.ConteneurDouble()) = valeur; }; // suppression d'une grandeur void ParaGlob::Suppression_grandeur_consultable(Enum_GrandeurGlobale enu) //// suppression d'une grandeur //void ParaGlob::Suppression_place_grandeur_consultable(string& nom) { // on regarde si la grandeur existe déjà, std::map < Enum_GrandeurGlobale, const void * , std::less >::iterator il=listegrandeurs.find(enu); if (il == listegrandeurs.end()) // cas où la grandeur n'existe pas on couine { cout << "\n *** erreur , la grandeur "< 5) {cout << "\n ParaGlob::Suppression_place_grandeur_consultable(..";}; Sortie(1); } else // on supprime {listegrandeurs.erase(il);}; }; // ajout d'une nouvelle grandeur qui restera ensuite disponible // mais ici pour une grandeur typée par une chaine de caractère, void ParaGlob::Ajout_grandeur_consultable(void* grandeur, string nom_ref) { // les grandeurs sont systématiquement et uniquement des types quelconque TypeQuelconque* gr_quelc = (TypeQuelconque*) grandeur; // // liste des grandeurs consultables de partout sous forme d'un arbre pour faciliter la recherche // std::map < Enum_GrandeurGlobale, const void * , std::less > listegrandeurs; std::map < string, const void * , std::less >::iterator il; il = listegrandeurs_par_string.find(nom_ref); if (il == listegrandeurs_par_string.end()) // cas où la grandeur n'existe pas, on l'enregistre {TypeQuelconque* nouveau_tq = new TypeQuelconque(*gr_quelc); listegrandeurs_par_string[nom_ref] = nouveau_tq; } else // sinon comme elle existe, on peut faire un cast { TypeQuelconque* gr_ici = (TypeQuelconque*) listegrandeurs_par_string.at(nom_ref); TypeQuelconque::Grandeur* gr_ici_pt = gr_ici->Grandeur_pointee(); TypeQuelconque::Grandeur* gr_quelc_pt = gr_quelc->Grandeur_pointee(); // on vérifie que la place est identique sinon on couine if ( (gr_ici_pt->Type_grandeurAssocie() != gr_quelc_pt->Type_grandeurAssocie() ) || (gr_ici_pt->Type_structure_grandeurAssocie() != gr_quelc_pt->Type_structure_grandeurAssocie() ) || (gr_ici_pt->Type_enumGrandeurParticuliere() != gr_quelc_pt->Type_enumGrandeurParticuliere() ) // pas forcément ici || (gr_quelc->EnuTypeQuelconque() != GENERIQUE_UNE_GRANDEUR_GLOBALE) ) { cout << "\n *** erreur , la grandeur "< 5) {cout << "\n ParaGlob::Ajout_grandeur_consultable(..";}; Sortie(1); }; // sinon tout va bien }; }; // récupération d'une grandeur quelconque pour modification // mais ici pour une grandeur typée par une chaine de caractère, // après l'appel de cette méthode, la grandeur quelconque est réputée updaté void * ParaGlob::Mise_a_jour_grandeur_consultable(const string& nom_ref) { if (listegrandeurs_par_string.find(nom_ref) == listegrandeurs_par_string.end()) { cout << "\n *** erreur en acces à la grandeur "<< nom_ref << " pour modification, or la grandeur n'existe pas " << endl; Sortie(1); return NULL; // pour taire le compilo }; TypeQuelconque* gr_ici = (TypeQuelconque*) listegrandeurs_par_string.at(nom_ref); return gr_ici; }; void ParaGlob::Mise_a_jour_grandeur_consultable_Scalaire_double(const string& nom_ref,const double& valeur) { if (listegrandeurs_par_string.find(nom_ref) == listegrandeurs_par_string.end()) { cout << "\n *** erreur en acces à la grandeur "<< nom_ref << " pour modification, or la grandeur n'existe pas " << endl; Sortie(1); }; TypeQuelconque* gr_ici = (TypeQuelconque*) listegrandeurs_par_string.at(nom_ref); Grandeur_scalaire_double& gr = *((Grandeur_scalaire_double*) gr_ici->Grandeur_pointee()); // pour simplifier *(gr.ConteneurDouble()) = valeur; }; // suppression d'une grandeur // mais ici pour une grandeur typée par une chaine de caractère, void ParaGlob::Suppression_grandeur_consultable(const string& nom_ref) //// suppression d'une grandeur //void ParaGlob::Suppression_place_grandeur_consultable(string& nom) { // on regarde si la grandeur existe déjà, std::map < string, const void * , std::less >::iterator il=listegrandeurs_par_string.find(nom_ref); if (il == listegrandeurs_par_string.end()) // cas où la grandeur n'existe pas on couine { cout << "\n *** erreur , la grandeur "<< nom_ref << " n'existe pas, on ne peut pas la supprimer "; if (nivImpression > 5) {cout << "\n ParaGlob::Suppression_place_grandeur_consultable(..";}; Sortie(1); } else // on supprime {listegrandeurs_par_string.erase(il);}; }; // affichage de la liste des noms de grandeurs actuelles accessibles globalement void ParaGlob::Affiche_GrandeurGlobal(ostream & sort) const { sort << "\n --- liste des grandeurs consultables de partout --- "; if (listegrandeurs.size() != 0) {// tout d'abord les grandeurs de types énuméré sort << "\n === les enumeres : === \n "; std::map < Enum_GrandeurGlobale, const void * , std::less >::const_iterator il,ilfin; ilfin=listegrandeurs.end(); il = listegrandeurs.begin(); for (;il != ilfin;il++) sort << Nom_GrandeurGlobale(il->first)<< "\n "; }; if (listegrandeurs_par_string.size() != 0) {// puis les grandeurs typée par une chaine de caractères sort << "\n === les grandeurs typees par une chaine de caracteres : ===\n "; std::map < string, const void * , std::less >::const_iterator il,ilfin; ilfin=listegrandeurs_par_string.end(); il = listegrandeurs_par_string.begin(); for (;il != ilfin;il++) sort << (il->first)<< "\n "; }; sort << endl; }; // 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 ParaGlob::Recup_list_GrandeurGlobal(list & list_grandeurs_globals) const { list_grandeurs_globals.clear(); if (listegrandeurs.size() != 0) {// tout d'abord les grandeurs de types énuméré std::map < Enum_GrandeurGlobale, const void * , std::less >::const_iterator il,ilfin; ilfin=listegrandeurs.end(); il = listegrandeurs.begin(); for (;il != ilfin;il++) list_grandeurs_globals.push_back(Nom_GrandeurGlobale(il->first)); }; if (listegrandeurs_par_string.size() != 0) {// puis les grandeurs typée par une chaine de caractères std::map < string, const void * , std::less >::const_iterator il,ilfin; ilfin=listegrandeurs_par_string.end(); il = listegrandeurs_par_string.begin(); for (;il != ilfin;il++) list_grandeurs_globals.push_back(il->first); }; }; // récup d'une composante d'une grandeur quelconque d'une grandeur globale const void * ParaGlob::GrandeurGlobal_relaie(const string& nom_ref ) const {// il s'agit d'une variable utilisateur relai // on commence par récupérer le conteneur 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;} // cas où la variable pointée n'existe pas else {// cas où on a la variable pointée // on l'affecte TypeQuelconque* gr_quelc = (TypeQuelconque*) (il_ref->second); // on récupère le conteneur multidimensionnel associé const string* nom_cont = gr_quelc->Const_Grandeur_pointee()->Nom_ref(); if (nom_cont != NULL) { std::map< string, const void * , std::less >::const_iterator it=listegrandeurs_par_string.find(*nom_cont); if (it == listegrandeurs_par_string.end()) {return NULL;} // cas où le conteneur multi n'existe pas else {// cas où on a le conteneur // on le récupère const TypeQuelconque* gr_quelc_cont = (const TypeQuelconque*) (it->second); // on affecte le conteneur scalaire Grandeur_Double_Nommer_indicer& tyTQ= *((Grandeur_Double_Nommer_indicer*) gr_quelc->Grandeur_pointee()); *(tyTQ.ConteneurDouble()) = gr_quelc_cont->GrandeurNumOrdre(tyTQ.Indice_const()); // retour du conteneur modifié return (il_ref->second); } } else // le conteneur multi n'est pas disponible { return NULL; }; // on ramène un pointeur NULL }; };