// 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-2021 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
};
};