1202 lines
59 KiB
C++
1202 lines
59 KiB
C++
|
|
// 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) <https://www.irdl.fr/>.
|
|
//
|
|
// 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 <https://www.gnu.org/licenses/>.
|
|
//
|
|
// For more information, please consult: <https://herezh.irdl.fr/>.
|
|
|
|
|
|
#include "LesReferences.h"
|
|
#include "PtTabRel.h"
|
|
#include "ReferenceAF.h"
|
|
#include "ReferenceNE.h"
|
|
#include "ReferencePtiAF.h"
|
|
#include "ParaGlob.h"
|
|
|
|
//-------- une méthode permettant d'utiliser des tableaux de map de références -----
|
|
// surcharge de l'operator d'ecriture
|
|
ostream & operator << (ostream & sort, const map < string, Reference*, std::less <string> > & )
|
|
{ // tout d'abord un indicateur donnant le type
|
|
if (ParaGlob::Francais()) {sort << " \n erreur (de developpement) a une fonction d'ecriture << d'une map de reference "
|
|
<< " voir LesReference.h "; }
|
|
else {sort << " \n error (for developper) for the writing method << concerning a map of references "
|
|
<< " see LesReference.h "; }
|
|
Sortie(1); return sort;
|
|
};
|
|
//----------- fin de la méthode permettant d'utiliser des tableaux de map de références -----
|
|
|
|
// --------------- variables statiques ---------
|
|
MotCle LesReferences::motCle; // liste des mots clés
|
|
|
|
LesReferences::LesReferences () : // par defaut
|
|
t_mapDeRef(),ref(NULL),num_mail_presuivant(0),listeNomMail(NULL)
|
|
{ nbMaille =1;
|
|
indic = 0;
|
|
};
|
|
// DESTRUCTEUR :
|
|
LesReferences::~LesReferences ()
|
|
{ // effacement des grandeurs pointées par la liste de référence
|
|
int taille = t_mapDeRef.Taille();
|
|
for (int i=1;i<=taille;i++)
|
|
{ map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(i);
|
|
map < string, Reference*, std::less <string> >::iterator il,ilfin = mapDeRef.end();
|
|
for (il=mapDeRef.begin() ; il != ilfin; il++)
|
|
if ((*il).second != NULL) {delete (*il).second;(*il).second=NULL;};
|
|
mapDeRef.erase(mapDeRef.begin(),mapDeRef.end());
|
|
};
|
|
};
|
|
|
|
// def du numero de maillage courant, utilise avant la lecture
|
|
void LesReferences::NbMaille(int nb) { nbMaille = nb; };
|
|
// def du type de reference a lire, utilise avant la lecture
|
|
void LesReferences::Indic(string type)
|
|
{ if (type == "noeud") indic = 1;
|
|
else if (type == "element") indic =2;
|
|
else if(type == "surface") indic = 3;
|
|
else if(type == "arete")indic = 4;
|
|
else if(type == "noeud_element")indic = 5;
|
|
else if(type == "pt_integ_element")indic = 6;
|
|
else if(type == "pt_integ_face_element")indic = 7;
|
|
else if(type == "pt_integ_arete_element")indic = 8;
|
|
else if(type == "rien_actuellement") indic = 0;
|
|
else
|
|
{ if (ParaGlob::Francais()) {cout << " \n **** erreur de type de reference, type donne = " << type;}
|
|
else {cout << " \n **** error of type of reference, type = " << type;}
|
|
cout << "LesReferences::Indic(string type)" << endl;
|
|
Affiche();
|
|
Sortie(1);
|
|
};
|
|
};
|
|
|
|
// lecture des references
|
|
void LesReferences::Lecture(UtilLecture & entreePrinc)
|
|
{ // on lit des references temps qu'il n'y a pas de pb
|
|
if (indic < 0)
|
|
{ if (ParaGlob::Francais())
|
|
{cout << " \n erreur en lecture de reference, le type de reference n\'st pas defini " ;}
|
|
else {cout << " \n error in reading a reference, the reference type is not defined " ;};
|
|
cout << "\n LesReferences::LectureLesReferences(etc ... " << endl;
|
|
Affiche();
|
|
Sortie(1);
|
|
}
|
|
while ( LectureReference(entreePrinc))
|
|
// la methode LectureReference cree une référence pointée par ref
|
|
{ // verification que l'on n'a pas deux references identiques
|
|
if (Existe(ref->Nom(),ref->Nbmaille()))
|
|
{ if (ParaGlob::Francais())
|
|
{ cout <<" \n Erreur de lecture de reference, deux refs ont le meme nom \n";
|
|
cout <<" nom = " << ref->Nom() << " pour le meme maillage nb: "
|
|
<< ref->Nbmaille() << '\n';}
|
|
else { cout <<" \n Error in reading a reference, two refs have the same name \n";
|
|
cout <<" name = " << ref->Nom() << " for the same mesh nb: "
|
|
<< ref->Nbmaille() << '\n';}
|
|
cout <<"LesReferences::LectureLesReferences(UtilLecture & entreePrinc)"
|
|
<< endl;
|
|
entreePrinc.MessageBuffer("lecture des references");
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie (1);
|
|
}
|
|
else
|
|
{int num_mail = ref->Nbmaille();
|
|
if (num_mail < 1 )
|
|
// on vérifie que le numéro de maillage est licite
|
|
{ if (ParaGlob::Francais())
|
|
{ cout << "\n erreur, on veut ajouter une reference sur le maillage numero nul ou negatif : " << num_mail << " ";}
|
|
else { cout << "\n error, we cannot add a reference on the mesh, number : " << num_mail << " ";}
|
|
ref->Affiche();
|
|
cout << "\n LesReferences::LectureLesReferences(... ";
|
|
Sortie(1);
|
|
}
|
|
else if (num_mail > t_mapDeRef.Taille())
|
|
// maintenant on regarde si l'on a déjà enregistré dans ce maillage
|
|
{ t_mapDeRef.Change_taille(num_mail);
|
|
};
|
|
// puis on enregistre
|
|
t_mapDeRef(num_mail)[ref->Nom()]=ref;
|
|
// t_mapDeRef(nbMaille)[ref->Nom()]= ref;
|
|
};
|
|
}
|
|
};
|
|
|
|
// ajout d'une référence déjà construite par ailleurs
|
|
void LesReferences::Ajout_reference(Reference * refi)
|
|
{ int num_mail = refi->Nbmaille();
|
|
if (num_mail < 1 )
|
|
// on vérifie que le numéro de maillage est licite
|
|
{ if (ParaGlob::Francais())
|
|
{ cout << "\n erreur, on veut ajouter une reference sur le maillage numero nul ou negatif : "
|
|
<< num_mail << " ";
|
|
}
|
|
else
|
|
{ cout << "\n error, we cannot add a reference on the mesh, number : " << num_mail << " ";}
|
|
refi->Affiche();
|
|
cout << "\n LesReferences::Ajout_reference(Reference * refi) ";
|
|
Sortie(1);
|
|
}
|
|
else if (num_mail > t_mapDeRef.Taille())
|
|
// maintenant on regarde si l'on a déjà enregistré dans ce maillage
|
|
{ t_mapDeRef.Change_taille(num_mail);
|
|
};
|
|
// supprime les doublons internes éventuels dans la référence
|
|
refi->Supprime_doublons_internes();
|
|
// puis on enregistre
|
|
t_mapDeRef(num_mail)[refi->Nom()]=refi;
|
|
return;
|
|
};
|
|
|
|
// affichage et definition interactive des commandes
|
|
// nbMaxiNoeud: nombre maxi de noeud pour les exemples
|
|
void LesReferences::Info_commande_lesRef(int nbMaxiNoeud,int nbMaxiElem,UtilLecture * entreePrinc,int cas)
|
|
{
|
|
// on dimensionne la taille de t_mapDeRef
|
|
if ( nbMaille > t_mapDeRef.Taille())
|
|
// maintenant on regarde si l'on a déjà enregistré dans ce maillage
|
|
{ t_mapDeRef.Change_taille(nbMaille);
|
|
};
|
|
|
|
|
|
switch (cas)
|
|
{ case 1:
|
|
{// en fait on s'occupe ici uniquement des références de noeuds
|
|
ref = new ReferenceNE("N_exemple_ref_NE", nbMaille,1);
|
|
ref-> Info_commande_Ref(nbMaxiNoeud,entreePrinc,cas);
|
|
t_mapDeRef(nbMaille)[ref->Nom()]= ref;
|
|
break;
|
|
}
|
|
case 2:
|
|
{// cas de toutes les références
|
|
ref = new ReferenceNE(nbMaille,1); // cas d'une ref de noeuds
|
|
ref-> Info_commande_Ref(nbMaxiNoeud,entreePrinc,cas);
|
|
t_mapDeRef(nbMaille)[ref->Nom()]= ref;
|
|
ref = new ReferenceNE(nbMaille,2); // cas d'une ref d'elements
|
|
ref-> Info_commande_Ref(nbMaxiElem,entreePrinc,cas);
|
|
t_mapDeRef(nbMaille)[ref->Nom()]= ref;
|
|
ref = new ReferenceAF(nbMaille,3); // cas d'une ref de surfaces
|
|
ref-> Info_commande_Ref(nbMaxiElem,entreePrinc,cas);
|
|
t_mapDeRef(nbMaille)[ref->Nom()]= ref;
|
|
ref = new ReferenceAF(nbMaille,4); // cas d'une ref d'arrete
|
|
ref-> Info_commande_Ref(nbMaxiElem,entreePrinc,cas);
|
|
t_mapDeRef(nbMaille)[ref->Nom()]= ref;
|
|
ref = new ReferenceAF(nbMaille,5); // cas d'une ref de noeud associé à un élément
|
|
ref-> Info_commande_Ref(nbMaxiElem,entreePrinc,cas);
|
|
t_mapDeRef(nbMaille)[ref->Nom()]= ref;
|
|
ref = new ReferenceAF(nbMaille,6); // cas d'une ref de point d'intégration associé à un élément
|
|
ref-> Info_commande_Ref(nbMaxiElem,entreePrinc,cas);
|
|
t_mapDeRef(nbMaille)[ref->Nom()]= ref;
|
|
ref = new ReferencePtiAF(nbMaille,7); // cas d'une ref de point d'intégration associé à une face d'élément
|
|
ref-> Info_commande_Ref(nbMaxiElem,entreePrinc,cas);
|
|
t_mapDeRef(nbMaille)[ref->Nom()]= ref;
|
|
ref = new ReferencePtiAF(nbMaille,8); // cas d'une ref de point d'intégration associé à une arete d'élément
|
|
ref-> Info_commande_Ref(nbMaxiElem,entreePrinc,cas);
|
|
t_mapDeRef(nbMaille)[ref->Nom()]= ref;
|
|
|
|
break;
|
|
}
|
|
default :
|
|
{ if (ParaGlob::Francais()) {cout << "\nErreur : valeur incorrecte du cas = " << cas << "\n";}
|
|
else {cout << "\nError : incorrect value for the case = " << cas << "\n";}
|
|
cout << "LesReferences::Info_commande_lesRef..." ;
|
|
Sortie(1);
|
|
};
|
|
}
|
|
};
|
|
|
|
// affichage des informations contenu dans les references
|
|
// par défaut affiche toutes les infos
|
|
// si niveau = 1 : affiche que les noms des ref
|
|
void LesReferences::Affiche(int niveau) const
|
|
{ int taille = t_mapDeRef.Taille();
|
|
for (int i=1;i<=taille;i++)
|
|
{ map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(i);
|
|
map < string, Reference*, std::less <string> >::const_iterator i_map;
|
|
if (ParaGlob::Francais()) {cout << " \n ------- affichage des listes de references ------- \n ";}
|
|
else {cout << " \n ------- display of the lists of references ------- \n ";};
|
|
for (i_map=mapDeRef.begin() ; i_map != mapDeRef.end(); i_map++)
|
|
if (!niveau)
|
|
(*i_map).second->Affiche();
|
|
else cout << " " << (*i_map).first ;
|
|
cout << endl;
|
|
};
|
|
};
|
|
|
|
// affichage des informations contenu dans les references d'un certain type
|
|
// défini par indic :
|
|
// indic = 1 -> noeud, =2 -> element
|
|
// =3 -> surface associée à un élément , =4 -> arete associée à un élément
|
|
// =5 -> noeud associée à un élément
|
|
// =6 -> point d'intégration associée à un élément
|
|
// =7 -> de points d'intégrations relatifs à des surfaces d'éléments
|
|
// =8 -> de points d'intégrations relatifs à des arrete d'éléments
|
|
// =0 -> rien_actuellement
|
|
// par défaut affiche toutes les infos
|
|
// si niveau = 1 : affiche que les noms des ref
|
|
void LesReferences::Affiche(int indic, int niveau) const
|
|
{ int taille = t_mapDeRef.Taille();
|
|
for (int i=1;i<=taille;i++)
|
|
{ map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(i);
|
|
map < string, Reference*, std::less <string> >::const_iterator i_map;
|
|
if (ParaGlob::Francais()) {cout << " \n ------- affichage references ------- \n ";}
|
|
else {cout << " \n ------- display references ------- \n ";};
|
|
for (i_map=mapDeRef.begin() ; i_map != mapDeRef.end(); i_map++)
|
|
if ((*i_map).second->Indic() == indic)
|
|
{if (niveau==1)
|
|
cout << " " << (*i_map).first ;
|
|
else (*i_map).second->Affiche();
|
|
};
|
|
cout << endl;
|
|
};
|
|
};
|
|
|
|
|
|
// Affiche les donnees des références pour le maillage imail dans un fichier
|
|
// dont le nom est construit à partir du nom du maillage au format ".lis"
|
|
void LesReferences::Affiche_dans_lis(const string& nom_maillage,int imail)
|
|
{ // tout d'abord on vérifie qu'il existe des références pour ce maillage
|
|
// ce qui peut-être fait de manière très simple en testant t_mapDeRef.Taille()
|
|
// si l'élément de tableau n'existe pas, ce n'est pas la peine de continuer, il n'y a pas de ref
|
|
// s'il existe, il y a peut-être des ref ... donc on continue
|
|
if (imail > t_mapDeRef.Taille())
|
|
return;
|
|
// ouverture du fichier pour les noeuds
|
|
char namm[132];
|
|
char*fileNoome = namm;
|
|
strcpy(fileNoome, nom_maillage.c_str());
|
|
ofstream * sur_sort = new ofstream (strcat(fileNoome,".lis"));
|
|
ofstream & sort = * sur_sort;
|
|
if(!(sort.is_open()))
|
|
// le fichier ne peut être ouvert, message d'erreur
|
|
{ if (ParaGlob::Francais())
|
|
{cout << "\n erreur en ouverture pour l'ecriture du fichier " << fileNoome << "\n";}
|
|
else {cout << "\n error, when trying to open for writing, the file " << fileNoome << "\n";};
|
|
cout << " Maillage::Affiche_dans_her_lis(.... " << endl;
|
|
Sortie(1);
|
|
};
|
|
// écriture de l'entete
|
|
if (ParaGlob::Francais())
|
|
{sort << "\n ###########################################################################"
|
|
<< "\n # ecriture automatique d'un maillage au format .lis, par Herezh++ #"
|
|
<< "\n ###########################################################################";}
|
|
else {sort << "\n ###########################################################################"
|
|
<< "\n # automatic writing by Herezh++, of a mesh with format .lis #"
|
|
<< "\n ###########################################################################";};
|
|
sort << "\n # version: " << ParaGlob::NbVersion() << "\n \n \n ";
|
|
// --- écriture des références de noeuds
|
|
if (ParaGlob::Francais()) {sort << "\n # -- reference de noeud ";}
|
|
else {sort << "\n # -- reference of nodes ";};
|
|
// on passe en revue les différentes références pour trouver la bonne
|
|
map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(imail);
|
|
map < string, Reference*, std::less <string> >::const_iterator il,ilfin=mapDeRef.end();
|
|
for (il=mapDeRef.begin();il!=ilfin;il++)
|
|
if ((*il).second->Indic()==1)
|
|
{// on a trouvé une référence de noeud pour le maillage considéré
|
|
(*il).second->Affiche_dans_lis(sort); // affichage
|
|
};
|
|
// --- écriture des références des éléments
|
|
if (ParaGlob::Francais()) {sort << "\n # -- reference des elements ";}
|
|
else {sort << "\n # -- reference of elements ";};
|
|
// on passe en revue les différentes références pour trouver la bonne
|
|
for (il=mapDeRef.begin();il!=ilfin;il++)
|
|
if ((*il).second->Indic()==2)
|
|
{// on a trouvé une référence d'element pour le maillage considéré
|
|
(*il).second->Affiche_dans_lis(sort); // affichage
|
|
}
|
|
// --- écriture des références de pt d'integ, noeuds, faces et arretes
|
|
if (ParaGlob::Francais())
|
|
{sort << "\n # -- references de pt d'integ, noeuds, faces et arretes associes a des elements ";}
|
|
else {sort << "\n # -- references of Gauss points, nodes, facets, segments, associated with elements ";};
|
|
// on passe en revue les différentes références pour trouver la bonne
|
|
for (il=mapDeRef.begin();il!=ilfin;il++)
|
|
if (((*il).second->Indic()==3)||((*il).second->Indic()==4)
|
|
||((*il).second->Indic()==5)||((*il).second->Indic()==6)
|
|
||((*il).second->Indic()==7)||((*il).second->Indic()==8))
|
|
{// on a trouvé une référence de pt d'integ, noeuds, faces et arretes pour le maillage considéré
|
|
(*il).second->Affiche_dans_lis(sort); // affichage
|
|
};
|
|
// quelques lignes blanches à la fin du fichier
|
|
sort << "\n \n \n";
|
|
// fermeture du fichier
|
|
delete sur_sort;
|
|
};
|
|
|
|
|
|
// initialise le questionnement de la récupération de référence et
|
|
// retourne la première référence si elle existe sinon un pointeur nul
|
|
const Reference* LesReferences::Init_et_Premiere()
|
|
{ num_mail_presuivant=0;
|
|
Reference * refret = NULL;
|
|
int t_taille = t_mapDeRef.Taille();
|
|
if ( t_taille == 0)
|
|
return NULL;
|
|
// sinon on boucle sur les éléments du tableaux
|
|
// et on cherche la première ref valide qui existe
|
|
for (int i=1;i<=t_taille;i++)
|
|
{ iref = t_mapDeRef(i).begin();
|
|
if (iref != t_mapDeRef(i).end())
|
|
{ num_mail_presuivant=i;
|
|
refret = (*iref).second;
|
|
break;
|
|
};
|
|
};
|
|
// retour
|
|
return refret;
|
|
};
|
|
|
|
// retourne la référence suivante ou, s'il n'y en n'a plus, retourne
|
|
// un pointeur nul
|
|
const Reference* LesReferences::Reference_suivante()
|
|
{ Reference * refret = NULL;
|
|
if (num_mail_presuivant != 0)
|
|
{iref++;
|
|
if (iref != t_mapDeRef(num_mail_presuivant).end())
|
|
{ return (*iref).second;
|
|
}
|
|
// donc arrivé ici cela veut dire qu'on est sur une fin
|
|
else
|
|
{ // sinon on boucle sur les éléments du tableaux qui restent
|
|
// et on cherche la première ref valide qui existe
|
|
int t_taille = t_mapDeRef.Taille();
|
|
for (int i=num_mail_presuivant+1;i<=t_taille;i++)
|
|
{ iref = t_mapDeRef(i).begin();
|
|
if (iref != t_mapDeRef(i).end())
|
|
{ num_mail_presuivant=i;
|
|
refret = (*iref).second;
|
|
break;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
// retour
|
|
return refret;
|
|
};
|
|
|
|
// test si la reference existe reellement
|
|
// retourne false si n'existe pas , true sinon
|
|
bool LesReferences::Existe(const string & st1,int num_mail) const
|
|
{ // tout d'abord on regarde si le tableau de map n'est pas vide
|
|
if (t_mapDeRef.Taille() == 0)
|
|
return false;
|
|
// sinon on peut continuer
|
|
bool existe=true;
|
|
if (num_mail > t_mapDeRef.Taille())
|
|
{ existe = false;
|
|
}
|
|
else if (t_mapDeRef(num_mail).find(st1) == t_mapDeRef(num_mail).end())
|
|
{ existe = false;
|
|
};
|
|
// sinon c'est ok
|
|
return existe;
|
|
};
|
|
|
|
// idem mais avec un nom de maillage
|
|
bool LesReferences::Existe(const string & st1,const string* nom_mail) const
|
|
{ // tout d'abord on regarde si le tableau de map n'est pas vide
|
|
if (t_mapDeRef.Taille() == 0)
|
|
return false;
|
|
// sinon on peut continuer
|
|
// on regarde si le nom de maillage est licite
|
|
if (nom_mail == NULL)
|
|
{ // acceptable que si l'on a un seul maillage
|
|
#ifdef MISE_AU_POINT
|
|
if (listeNomMail != NULL)
|
|
if (listeNomMail->size() != 1)
|
|
if (ParaGlob::NiveauImpression() >2)
|
|
{ if (ParaGlob::Francais())
|
|
{cout << "\n warning: la reference demandee= " << st1 << " , n'a pas de nom de maillage associe"
|
|
<< " alors qu'il y a plusieurs maillage defini !! : on considere que c'est une ref du premier maillage";}
|
|
else {cout << "\n warning: the wanted reference " << st1 << " , has no associated mesh "
|
|
<< " but several meshes exist !! : we consider that it is a ref for the first mesh ";}
|
|
if (ParaGlob::NiveauImpression() >5)
|
|
{ if (ParaGlob::Francais()) {cout << "\n nom_de_maillages= ";}
|
|
else {cout << "\n names of the meshes = ";}
|
|
map < string, int , std::less <string> >::const_iterator ili,ilifin=listeNomMail->end();
|
|
for (ili = listeNomMail->begin();ili != ilifin; ili++)
|
|
cout << (*ili).first << ", " ;
|
|
cout << "\n LesReferences::Existe(const string & st1,const string* nom_mail) ";
|
|
};
|
|
}
|
|
// Sortie(1);
|
|
#endif
|
|
// on ramène le cas du premier maillage qui doit exister
|
|
return Existe(st1,1);
|
|
}
|
|
else
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
// on regarde si le nom de maillage existe dans la liste
|
|
if (listeNomMail->find(*nom_mail) == listeNomMail->end())
|
|
{ if (ParaGlob::Francais()) {cout << "\nErreur : le nom de maillage : " << *nom_mail << " n'existe pas \n";}
|
|
else {cout << "\nError : the name of the mesh : " << *nom_mail << " does not exist \n";}
|
|
if (ParaGlob::NiveauImpression() >5)
|
|
cout << "LesReferences::Existe(const string & st1,const string& nom_mail) \n";
|
|
Sortie(1);
|
|
}
|
|
#endif
|
|
return Existe(st1,(*(listeNomMail->find(*nom_mail))).second);
|
|
};
|
|
};
|
|
|
|
// retourne la reference correspondant a une cle
|
|
const Reference& LesReferences::Trouve(const string & st1,int num_mail) const
|
|
{ if (num_mail > t_mapDeRef.Taille())
|
|
{ if (ParaGlob::Francais())
|
|
{cout << " \n pb la reference de nom " << st1 << " pour le maillage nb= "<< num_mail << " n'existe pas \n";}
|
|
else {cout << "\nError : the reference with the name " << st1 << " for the mesh nb= " << num_mail << " does not exist \n";}
|
|
if (ParaGlob::NiveauImpression() >5)
|
|
{ cout << " \n LesReferences::Trouve(const string & st1,int num_mail) " << endl;};
|
|
Sortie (1);
|
|
}
|
|
else if (t_mapDeRef(num_mail).find(st1) == t_mapDeRef(num_mail).end())
|
|
{ if (ParaGlob::Francais())
|
|
{cout << " \n pb la reference de nom " << st1 << " pour le maillage nb= "<< num_mail << " n'existe pas \n";}
|
|
else {cout << "\nError : the reference with the name " << st1 << " for the mesh nb= " << num_mail << " does not exist \n";}
|
|
if (ParaGlob::NiveauImpression() >5)
|
|
{ cout << " \n LesReferences::Trouve(const string & st1,int num_mail) " << endl;};
|
|
Sortie (1);
|
|
};
|
|
// sinon c'est ok
|
|
return *(t_mapDeRef(num_mail)[st1]);
|
|
};
|
|
|
|
// idem mais avec un nom de maillage
|
|
const Reference& LesReferences::Trouve(const string & st1,const string* nom_mail) const
|
|
{ // on regarde si le nom de maillage est licite
|
|
if (nom_mail == NULL)
|
|
{ // acceptable que si l'on a un seul maillage
|
|
#ifdef MISE_AU_POINT
|
|
if (listeNomMail->size() != 1)
|
|
if (ParaGlob::NiveauImpression() >2)
|
|
{ if (ParaGlob::Francais())
|
|
{cout << "\n warning: la reference demandee= " << st1 << " , n'a pas de nom de maillage associe"
|
|
<< " alors qu'il y a plusieurs maillage defini !! : on considere que c'est une ref du premier maillage";}
|
|
else {cout << "\n warning: the wanted reference " << st1 << " , has no associated mesh "
|
|
<< " but several meshes exist !! : we consider that it is a ref for the first mesh ";}
|
|
if (ParaGlob::NiveauImpression() >5)
|
|
{ if (ParaGlob::Francais()) {cout << "\n nom_de_maillages= ";}
|
|
else {cout << "\n names of the meshes = ";}
|
|
map < string, int , std::less <string> >::const_iterator ili,ilifin=listeNomMail->end();
|
|
for (ili = listeNomMail->begin();ili != ilifin; ili++)
|
|
cout << (*ili).first << ", " ;
|
|
cout << "\n LesReferences::Trouve(const string & st1,const string& nom_mail) ";
|
|
};
|
|
// Sortie(1);
|
|
};
|
|
#endif
|
|
// on ramène le cas du premier maillage qui doit exister
|
|
return Trouve(st1,1);
|
|
}
|
|
else
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
// on regarde si le nom de maillage existe dans la liste
|
|
if (listeNomMail->find(*nom_mail) == listeNomMail->end())
|
|
{ if (ParaGlob::Francais()) {cout << "\nErreur : le nom de maillage : " << *nom_mail << " n'existe pas \n";}
|
|
else {cout << "\nError : the name of the mesh : " << *nom_mail << " does not exist \n";}
|
|
if (ParaGlob::NiveauImpression() >5)
|
|
cout << "LesReferences::Trouve(const string & st1,const string& nom_mail) \n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
return Trouve(st1,(*(listeNomMail->find(*nom_mail))).second);
|
|
};
|
|
};
|
|
|
|
// mise à jour des références de noeud, dans le cas où les numéros de noeuds ont changés
|
|
//1) cas où l'on supprime éventuellement des noeuds de la référence, qui ne sont plus référencé
|
|
// nv_tab est tel que : nv_tab(i) est le nouveau numéro qui avait auparavant le numéro "i"
|
|
// non_referencer(i) : = true signifie qu'il ne faut plus tenir compte de ce noeud
|
|
// = false indique qu'il continue d'être actif
|
|
void LesReferences::Mise_a_jour_ref_noeud(Tableau <int >& nv_tab,int num_mail,Tableau <bool>& non_referencer)
|
|
{ bool fr = ParaGlob::Francais(); // pour simplifier
|
|
// on vérifie le numéro de maillage
|
|
if ((num_mail < 0) || (num_mail > t_mapDeRef.Taille()))
|
|
{ if (fr) {cout << "\n **** bizarre on demande de changer la numerotation de noeuds de reference pour le"
|
|
<< " maillage numero: " << num_mail << " qui soit n'existe pas ou soit n'a pas de reference !! ";}
|
|
else {cout << "\n **** strange, we try to change the numerotation of nodes belonging to a reference of a "
|
|
<< " mesh number : " << num_mail << " which does not exist or does not contain any reference !! ";};
|
|
};
|
|
// on balaie la map
|
|
map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(num_mail);
|
|
map < string, Reference*, std::less <string> >::iterator il,ilfin = mapDeRef.end();
|
|
// list <Reference*>::const_iterator il,ilfin=listeDeRef.end();
|
|
int nb_noeud = nv_tab.Taille();
|
|
for (il=mapDeRef.begin() ; il != ilfin; il++)
|
|
{ if ((*il).second->Indic() == 1)
|
|
{ // cas où il s'agit d'une référence de noeud
|
|
ReferenceNE* refe = ((ReferenceNE*) (*il).second); // on récupère la référence
|
|
int nb_el = refe->Taille();
|
|
// premier passage on change les numéros
|
|
int nb_noeud_supprime = 0; // nombre de noeuds supprimés
|
|
for (int i=1; i<= nb_el; i++)
|
|
{ int num_ancien = refe->Numero(i);
|
|
// on vérifie que le noeud continue d'être valide
|
|
if (non_referencer(num_ancien))
|
|
{ if (ParaGlob::NiveauImpression() > 3)
|
|
{if (fr) {cout << "\n suppression du noeud " << num_ancien << " dans la reference "
|
|
<< refe->Nom() << " maillage:" << num_mail ;}
|
|
else {cout << "\n erasure of the node " << num_ancien << " in the reference "
|
|
<< refe->Nom() << " mesh :" << num_mail ;};
|
|
};
|
|
// on commence par mettre -100 dans le tableau de num et ensuite on retassera le tableau à la fin
|
|
refe->Change_num_dans_ref(i,-100);
|
|
nb_noeud_supprime++;
|
|
}
|
|
else // sinon il faut le garder
|
|
{ // on vérifie que le numéro de la référence est licite (normalement il doit l'être)
|
|
if ((num_ancien > 0) && (num_ancien <= nb_noeud))
|
|
{refe->Change_num_dans_ref(i,nv_tab(num_ancien));}
|
|
else
|
|
{if (fr) {cout << "\n erreur dans la mise a jour d'une reference , le numero "
|
|
<< num_ancien << " de la liste "
|
|
<< " n'appartient pas a l'intervalle des noeuds disponibles [1," << nb_noeud << "] ";}
|
|
else {cout << "\n error during the update of a reference, the number "
|
|
<< num_ancien << " in the list "
|
|
<< " does not belong to the range of existing nodes [1," << nb_noeud << "] ";};
|
|
// debug cout << " \n non_referencer(num_ancien) " << non_referencer(num_ancien) << endl;
|
|
refe->Affiche();
|
|
Sortie(1);
|
|
};
|
|
};
|
|
};
|
|
// second passage dans le cas où l'on a supprimé des noeuds
|
|
if (nb_noeud_supprime)
|
|
{// a) on fait un décalage dans le tableau initial
|
|
int indice_new = 1;
|
|
for (int i=1; i<= nb_el; i++)
|
|
{ if (refe->Numero(i) != -100)
|
|
{refe->Change_num_dans_ref(indice_new,refe->Numero(i));
|
|
indice_new++;
|
|
}
|
|
};
|
|
// b) on retasse le tableau
|
|
Tableau<int> tab_inter = refe->Tab_num();
|
|
tab_inter.Change_taille(nb_el-nb_noeud_supprime);
|
|
refe->Change_tab_num(tab_inter);
|
|
};
|
|
// on supprime les doublons éventuels
|
|
refe->Supprime_doublons_internes();
|
|
};
|
|
};
|
|
};
|
|
|
|
// mise à jour des références de noeud, dans le cas où les numéros de noeuds ont changés
|
|
//2) cas où on considère tous les noeuds
|
|
// nv_tab est tel que : nv_tab(i) est le nouveau numéro qui avait auparavant le numéro "i"
|
|
void LesReferences::Mise_a_jour_ref_noeud(Tableau <int >& nv_tab,int num_mail)
|
|
{ bool fr = ParaGlob::Francais(); // pour simplifier
|
|
// on vérifie le numéro de maillage
|
|
if ((num_mail < 0) || (num_mail > t_mapDeRef.Taille()))
|
|
{ if (fr) {cout << "\n **** bizarre on demande de changer la numerotation de noeuds de reference pour le"
|
|
<< " maillage numero: " << num_mail << " qui soit n'existe pas ou soit n'a pas de reference !! ";}
|
|
else {cout << "\n **** strange, we try to change the numerotation of nodes belonging to a reference of a "
|
|
<< " mesh number : " << num_mail << " which does not exist or does not contain any reference !! ";};
|
|
};
|
|
// on balaie la map
|
|
map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(num_mail);
|
|
map < string, Reference*, std::less <string> >::iterator il,ilfin = mapDeRef.end();
|
|
// list <Reference*>::const_iterator il,ilfin=listeDeRef.end();
|
|
int nb_noeud = nv_tab.Taille();
|
|
for (il=mapDeRef.begin() ; il != ilfin; il++)
|
|
{ if ((*il).second->Indic() == 1)
|
|
{ // cas où il s'agit d'une référence de noeud
|
|
ReferenceNE* refe = ((ReferenceNE*) (*il).second); // on récupère la référence
|
|
int nb_el = refe->Taille();
|
|
for (int i=1; i<= nb_el; i++)
|
|
{ int num_ancien = refe->Numero(i);
|
|
// on vérifie que le numéro de la référence est licite (normalement il doit l'être)
|
|
if ((num_ancien > 0) && (num_ancien <= nb_noeud))
|
|
{refe->Change_num_dans_ref(i,nv_tab(num_ancien));}
|
|
else
|
|
{if (fr) {cout << "\n erreur dans la mise a jour d'une reference , le numero "
|
|
<< num_ancien << " de la liste "
|
|
<< " n'appartient pas a l'intervalle des noeuds disponibles [1," << nb_noeud << "] ";}
|
|
else {cout << "\n error during the update of a reference, the number "
|
|
<< num_ancien << " in the list "
|
|
<< " does not belong to the range of existing nodes [1," << nb_noeud << "] ";};
|
|
refe->Affiche();
|
|
Sortie(1);
|
|
};
|
|
};
|
|
// on supprime les doublons éventuels
|
|
refe->Supprime_doublons_internes();
|
|
};
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// mise à jour des références d'élément, dans le cas où les numéros d'élément ont changés
|
|
//1) cas où l'on supprime éventuellement des éléments de la référence, qui ne sont plus référencé
|
|
// nv_tab est tel que : nv_tab(i) est le nouveau numéro qui avait auparavant le numéro "i"
|
|
// non_referencer(i) : = true signifie qu'il ne faut plus tenir compte de cet élément
|
|
// = false indique qu'il continue d'être actif
|
|
void LesReferences::Mise_a_jour_ref_element(Tableau <int >& nv_tab,int num_mail,Tableau <bool>& non_referencer)
|
|
{ bool fr = ParaGlob::Francais(); // pour simplifier
|
|
// on vérifie le numéro de maillage
|
|
if ((num_mail < 0) || (num_mail > t_mapDeRef.Taille()))
|
|
{ if (fr) {cout << "\n **** bizarre on demande de changer la numerotation d'element de reference pour le"
|
|
<< " maillage numero: " << num_mail << " qui soit n'existe pas ou soit n'a pas de reference !! ";}
|
|
else {cout << "\n **** strange, we try to change the numerotation of elements belonging to a reference of a "
|
|
<< " mesh number : " << num_mail << " which does not exist or does not contain any reference !! ";};
|
|
};
|
|
// on balaie la map
|
|
map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(num_mail);
|
|
map < string, Reference*, std::less <string> >::iterator il,ilfin = mapDeRef.end();
|
|
|
|
|
|
// { int i = num_mail;
|
|
// map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(i);
|
|
// map < string, Reference*, std::less <string> >::const_iterator i_map;
|
|
// if (ParaGlob::Francais()) {cout << " \n ------- affichage des listes de references ------- \n ";}
|
|
// else {cout << " \n ------- display of the lists of references ------- \n ";};
|
|
// for (i_map=mapDeRef.begin() ; i_map != mapDeRef.end(); i_map++)
|
|
// (*i_map).second->Affiche();
|
|
// cout << endl;
|
|
// };
|
|
|
|
|
|
|
|
// list <Reference*>::const_iterator il,ilfin=listeDeRef.end();
|
|
int nb_element = nv_tab.Taille();
|
|
for (il=mapDeRef.begin() ; il != mapDeRef.end(); il++)
|
|
{ switch((*il).second->Indic())
|
|
{case 2: // cas où il s'agit d'une référence d'élément
|
|
{ ReferenceNE* refe = ((ReferenceNE*) (*il).second); // on récupère la référence
|
|
int nb_el = refe->Taille();
|
|
// premier passage on change les numéros
|
|
int nb_element_supprime = 0; // nombre de elements supprimés
|
|
for (int i=1; i<= nb_el; i++)
|
|
{ int num_ancien = refe->Numero(i);
|
|
// on vérifie que l'élement continue d'être valide
|
|
if (non_referencer(num_ancien))
|
|
{ if (ParaGlob::NiveauImpression() > 3)
|
|
{if (fr) {cout << "\n suppression de l'element " << num_ancien << " dans la reference "
|
|
<< refe->Nom() << " maillage:" << num_mail << endl;}
|
|
else {cout << "\n erasure of the element " << num_ancien << " in the reference "
|
|
<< refe->Nom() << " mesh :" << num_mail << endl;};
|
|
};
|
|
// on commence par mettre -100 dans le tableau de num et ensuite on retassera le tableau à la fin
|
|
refe->Change_num_dans_ref(i,-100);
|
|
nb_element_supprime++;
|
|
}
|
|
else // sinon il faut le garder
|
|
{ // on vérifie que le numéro de la référence est licite (normalement il doit l'être)
|
|
if ((num_ancien > 0) && (num_ancien <= nb_element))
|
|
{refe->Change_num_dans_ref(i,nv_tab(num_ancien));}
|
|
else
|
|
{if (fr) {cout << "\n erreur dans la mise a jour d'une reference , le numero "
|
|
<< num_ancien << " de la liste "
|
|
<< " n'appartient pas a l'intervalle des elements disponibles [1," << nb_element << "] ";}
|
|
else {cout << "\n error during the update of a reference, the number "
|
|
<< num_ancien << " in the list "
|
|
<< " does not belong to the range of existing elements [1," << nb_element << "] ";};
|
|
// debug cout << " \n non_referencer(num_ancien) " << non_referencer(num_ancien) << endl;
|
|
refe->Affiche();
|
|
Sortie(1);
|
|
};
|
|
};
|
|
};
|
|
// second passage dans le cas où l'on a supprimé des elements
|
|
if (nb_element_supprime)
|
|
{ // a) on fait un décalage dans le tableau initial
|
|
int indice_new = 1;
|
|
for (int i=1; i<= nb_el; i++)
|
|
{ if (refe->Numero(i) != -100)
|
|
{refe->Change_num_dans_ref(indice_new,refe->Numero(i));
|
|
indice_new++;
|
|
};
|
|
};
|
|
// b) on retasse le tableau
|
|
Tableau<int> tab_inter = refe->Tab_num();
|
|
tab_inter.Change_taille(nb_el-nb_element_supprime);
|
|
refe->Change_tab_num(tab_inter);
|
|
};
|
|
// on supprime les doublons éventuels
|
|
refe->Supprime_doublons_internes();
|
|
break;
|
|
}
|
|
case 3: case 4: case 6: // cas où il s'agit d'une face ou arête ou ptint d'élément
|
|
{ReferenceAF* refe = ((ReferenceAF*) (*il).second); // on récupère la référence
|
|
// on récupère les deux tableaux de la référence
|
|
const Tableau<int>& tab_elem = refe->Tab_Elem(); // le tableau des numeros d'éléments
|
|
//puis le tableau des numeros de faces, ou d'arêtes, ou de noeud d'element, ou de points d'integ
|
|
const Tableau<int>& tab_entite = refe->Tab_FA();
|
|
// on va travailler avec ces tableaux et ensuite on recréra une nouvelle référence avec de nouveaux tableaux
|
|
int nb_el = tab_elem.Taille();
|
|
// premier passage on change les numéros
|
|
int nb_element_supprime = 0; // nombre de elements supprimés
|
|
for (int i=1; i<= nb_el; i++)
|
|
{ int num_ancien = refe->NumeroElem(i);
|
|
// on vérifie que le element continue d'être valide
|
|
if (non_referencer(num_ancien))
|
|
{ if (ParaGlob::NiveauImpression() > 3)
|
|
{if (fr) {cout << "\n suppression de l'element " << num_ancien << " dans la reference "
|
|
<< refe->Nom() << " maillage:" << num_mail ;}
|
|
else {cout << "\n erasure of the element " << num_ancien << " in the reference "
|
|
<< refe->Nom() << " mesh :" << num_mail ;};
|
|
};
|
|
// on commence par mettre -100 dans le tableau de num et ensuite on retassera le tableau à la fin
|
|
tab_elem(i) = -100;
|
|
nb_element_supprime++;
|
|
}
|
|
else // sinon il faut le garder
|
|
{ // on vérifie que le numéro de la référence est licite (normalement il doit l'être)
|
|
if ((num_ancien > 0) && (num_ancien <= nb_element))
|
|
{tab_elem(i) = nv_tab(num_ancien);}
|
|
// {refe->Change_num_dans_ref(i,nv_tab(num_ancien));}
|
|
else
|
|
{if (fr) {cout << "\n erreur dans la mise a jour d'une reference , le numero "
|
|
<< num_ancien << " de la liste "
|
|
<< " n'appartient pas a l'intervalle des elements disponibles [1," << nb_element << "] ";}
|
|
else {cout << "\n error during the update of a reference, the number "
|
|
<< num_ancien << " in the list "
|
|
<< " does not belong to the range of existing elements [1," << nb_element << "] ";};
|
|
// debug cout << " \n non_referencer(num_ancien) " << non_referencer(num_ancien) << endl;
|
|
refe->Affiche();
|
|
Sortie(1);
|
|
};
|
|
};
|
|
};
|
|
// on crée deux nouveaux tableaux
|
|
Tableau<int> tab_elem_new(nb_el-nb_element_supprime); // le nouveau tableau des numeros d'éléments
|
|
//puis le tableau des numeros de faces, ou d'arêtes, ou de noeud d'element, ou de points d'integ
|
|
Tableau<int> tab_entite_new(nb_el-nb_element_supprime);
|
|
// on va travailler avec ces tableaux et ensuite on mettra à jour la référence
|
|
// second passage dans le cas où l'on a supprimé des elements
|
|
if (nb_element_supprime)
|
|
{// on recopie les grandeurs correctes
|
|
int indice_new = 1;
|
|
for (int i=1; i<= nb_el; i++)
|
|
{ if (tab_elem(i) != -100)
|
|
{tab_elem_new(indice_new)=tab_elem(i);
|
|
tab_entite_new(indice_new) = tab_entite(i);
|
|
indice_new++;
|
|
};
|
|
};
|
|
// on change les deux tableaux dans la référence
|
|
refe->Change_tab_num(tab_elem_new,tab_entite_new);
|
|
// on supprime les doublons éventuels
|
|
refe->Supprime_doublons_internes();
|
|
}
|
|
else // sinon on ne fait que supprimer les doublons éventuels
|
|
{refe->Supprime_doublons_internes();};
|
|
break;
|
|
}
|
|
|
|
case 7: case 8: // cas où il s'agit de pti d'une face ou arête d'élément
|
|
{ReferencePtiAF* refe = ((ReferencePtiAF*) (*il).second); // on récupère la référence
|
|
// on récupère les trois tableaux de la référence
|
|
const Tableau<int>& tab_elem = refe->Tab_Elem(); // le tableau des numeros d'éléments
|
|
//puis le tableau des numeros de faces, ou d'arêtes
|
|
const Tableau<int>& tab_entite = refe->Tab_FA();
|
|
// puis le tableau des pti
|
|
const Tableau<int>& tab_entite_pti = refe->Tab_Pti();
|
|
|
|
// on va travailler avec ces tableaux et ensuite on recréra une nouvelle référence avec de nouveaux tableaux
|
|
int nb_el = tab_elem.Taille();
|
|
// premier passage on change les numéros
|
|
int nb_element_supprime = 0; // nombre de elements supprimés
|
|
for (int i=1; i<= nb_el; i++)
|
|
{ int num_ancien = refe->NumeroElem(i);
|
|
// on vérifie que le element continue d'être valide
|
|
if (non_referencer(num_ancien))
|
|
{ if (ParaGlob::NiveauImpression() > 3)
|
|
{if (fr) {cout << "\n suppression de l'element " << num_ancien << " dans la reference "
|
|
<< refe->Nom() << " maillage:" << num_mail ;}
|
|
else {cout << "\n erasure of the element " << num_ancien << " in the reference "
|
|
<< refe->Nom() << " mesh :" << num_mail ;};
|
|
};
|
|
// on commence par mettre -100 dans le tableau de num et ensuite on retassera le tableau à la fin
|
|
tab_elem(i) = -100;
|
|
nb_element_supprime++;
|
|
}
|
|
else // sinon il faut le garder
|
|
{ // on vérifie que le numéro de la référence est licite (normalement il doit l'être)
|
|
if ((num_ancien > 0) && (num_ancien <= nb_element))
|
|
{tab_elem(i) = nv_tab(num_ancien);}
|
|
else
|
|
{if (fr) {cout << "\n erreur dans la mise a jour d'une reference , le numero "
|
|
<< num_ancien << " de la liste "
|
|
<< " n'appartient pas a l'intervalle des elements disponibles [1," << nb_element << "] ";}
|
|
else {cout << "\n error during the update of a reference, the number "
|
|
<< num_ancien << " in the list "
|
|
<< " does not belong to the range of existing elements [1," << nb_element << "] ";};
|
|
// debug cout << " \n non_referencer(num_ancien) " << non_referencer(num_ancien) << endl;
|
|
refe->Affiche();
|
|
Sortie(1);
|
|
};
|
|
};
|
|
};
|
|
// on crée 3 nouveaux tableaux
|
|
Tableau<int> tab_elem_new(nb_el-nb_element_supprime); // le nouveau tableau des numeros d'éléments
|
|
//puis le tableau des numeros de faces, ou d'arêtes,
|
|
Tableau<int> tab_entite_new(nb_el-nb_element_supprime);
|
|
//puis le tableau de points d'integ
|
|
Tableau<int> tab_entite_pti_new(nb_el-nb_element_supprime);
|
|
// on va travailler avec ces tableaux et ensuite on mettra à jour la référence
|
|
// second passage dans le cas où l'on a supprimé des elements
|
|
if (nb_element_supprime)
|
|
{// on recopie les grandeurs correctes
|
|
int indice_new = 1;
|
|
for (int i=1; i<= nb_el; i++)
|
|
{ if (tab_elem(i) != -100)
|
|
{tab_elem_new(indice_new)=tab_elem(i);
|
|
tab_entite_new(indice_new) = tab_entite(i);
|
|
tab_entite_pti_new(indice_new) = tab_entite_pti(i);
|
|
indice_new++;
|
|
};
|
|
};
|
|
// on change les deux tableaux dans la référence
|
|
refe->Change_tab_num(tab_elem_new,tab_entite_new,tab_entite_pti_new);
|
|
// on supprime les doublons éventuels
|
|
refe->Supprime_doublons_internes();
|
|
}
|
|
else // sinon on ne fait que supprimer les doublons éventuels
|
|
{refe->Supprime_doublons_internes();};
|
|
break;
|
|
}
|
|
|
|
|
|
};
|
|
};
|
|
};
|
|
|
|
|
|
// suppression d'une référence
|
|
void LesReferences::SupprimeReference(const string & st1,int num_mail)
|
|
{ bool fr = ParaGlob::Francais(); // pour simplifier
|
|
// tout d'abord on cherche la référence
|
|
if (num_mail > t_mapDeRef.Taille())
|
|
{ if (fr) {cout << " \n pb1 la reference de nom " << st1 << " pour le maillage nb= "<< num_mail
|
|
<< " n\'existe pas !! , on ne peut pas la supprimer " << endl;}
|
|
else {cout << " \n pb1 the reference with name " << st1 << " for the mesh number= "<< num_mail
|
|
<< " does not exist !! , we cannot erase it " << endl;};
|
|
if (ParaGlob::NiveauImpression() >= 5)
|
|
cout << "\n LesReferences::SupprimeReference(...";
|
|
Sortie (1);
|
|
};
|
|
map < string, Reference*, std::less <string> >::iterator il = t_mapDeRef(num_mail).find(st1);
|
|
if (il == t_mapDeRef(num_mail).end())
|
|
{ if (fr) {cout << " \n pb2 la reference de nom " << st1 << " pour le maillage nb= "<< num_mail
|
|
<< " n\'existe pas !! , on ne peut pas la supprimer " << endl;}
|
|
else {cout << " \n pb2 the reference with name " << st1 << " for the mesh number= "<< num_mail
|
|
<< " does not exist !! , we cannot erase it " << endl;};
|
|
if (ParaGlob::NiveauImpression() >= 5)
|
|
cout << "\n LesReferences::SupprimeReference(...";
|
|
Sortie (1);
|
|
}
|
|
else // sinon c'est ok
|
|
{ // on commence par effacer la référence
|
|
if ((*il).second != NULL) {delete (*il).second;(*il).second=NULL;};
|
|
// puis on le suprime du tableau de map
|
|
t_mapDeRef(num_mail).erase(il);
|
|
};
|
|
};
|
|
|
|
// suppression de tous les référence d'un maillage donné
|
|
// si avec_diminution_num_maillage = true:
|
|
// tous les numéros de maillage, > num_mail, associé aux maillages qui restent
|
|
// sont diminués de un, pour tenir compte de la disparition du maillage et donc
|
|
// d'une nouvelle numérotation des maillages
|
|
// si avec_diminution_num_maillage = false, le conteneur des ref de maillage num_mail
|
|
// est vidé, mais il continu à exister: on considère qu'il y a toujours un maillage num_mail potentiel
|
|
void LesReferences::Supprime_tour_lesRef_un_maillage(int num_mail, bool avec_diminution_num_maillage)
|
|
{// bien que nbMaille ne serve pas a priori sans être initialisé
|
|
// , pour éviter qu'il soit inchoérent, on le modifie éventuellement
|
|
if (nbMaille > num_mail)
|
|
{nbMaille = 1; // par défaut
|
|
indic = 1; // toujours par défaut
|
|
};
|
|
// on met à jour la t_mapDeRef
|
|
map < string, Reference*, std::less <string> >::iterator il,ilfin;
|
|
map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(num_mail);
|
|
// vérif
|
|
int tai=t_mapDeRef.Taille();
|
|
if (num_mail <1)
|
|
{ cout << "\n erreur, impossible de supprimer les ref du maillage "<<num_mail;
|
|
cout << "\n LesReferences::Supprime_tour_lesRef_un_maillage(.." << endl;
|
|
Sortie(1);
|
|
};
|
|
|
|
if (num_mail > tai) // pas de référence enregistrées pour ce maillage
|
|
// on ne fait rien et on revient
|
|
return;
|
|
// on supprime les ref
|
|
ilfin = mapDeRef.end();
|
|
for (il = mapDeRef.begin();il != ilfin; il++)
|
|
delete (*il).second;
|
|
// suppression ou non du conteneur
|
|
if (avec_diminution_num_maillage)
|
|
{ // on retasse le tableau
|
|
for (int i=num_mail;i<=tai-1;i++)
|
|
{t_mapDeRef(i)=t_mapDeRef(i+1);
|
|
// on change les numéros de maillages
|
|
map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(i );
|
|
ilfin = mapDeRef.end();
|
|
for (il = mapDeRef.begin();il != ilfin; il++)
|
|
(*il).second->Change_Nbmaille(i);
|
|
};
|
|
// le fait de changer de taille supprime l'élément tai
|
|
t_mapDeRef.Change_taille(tai-1);
|
|
nbMaille--; // on diminue le nombre de maillage en service pour les ref
|
|
};
|
|
};
|
|
|
|
|
|
//----- 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 LesReferences::Lecture_base_info(istream& entr,const int cas)
|
|
{bool fr = ParaGlob::Francais(); // pour simplifier
|
|
// pour l'instant nous n'avons que des références fixes
|
|
if (cas == 1)
|
|
{if (fr) {cout << " == lecture des references \n";}
|
|
else {cout << " == reading of the references \n";};
|
|
// on commence par effacer les références existantes
|
|
int taille = t_mapDeRef.Taille();
|
|
for (int i=1;i<=taille;i++)
|
|
{ map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(i);
|
|
map < string, Reference*, std::less <string> >::iterator il,ilfin = mapDeRef.end();
|
|
for (il=mapDeRef.begin() ; il != ilfin; il++)
|
|
if ((*il).second != NULL) {delete (*il).second;(*il).second=NULL;};
|
|
mapDeRef.erase(mapDeRef.begin(),mapDeRef.end());
|
|
};
|
|
// on lit et dimensionne le tableau
|
|
string toto;int t_taille;
|
|
entr >> toto >> t_taille ;
|
|
t_mapDeRef.Change_taille(t_taille);
|
|
for (int i=1;i<=t_taille;i++)
|
|
{ map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(i);
|
|
int nb_ref=0;
|
|
entr >> toto >> nb_ref;
|
|
// on boucle sur le nombre de référence à lire
|
|
int indic;
|
|
for (int i=1;i<= nb_ref; i++)
|
|
{ // lecture du type de référence
|
|
entr >> toto >> indic;
|
|
// création d'une référence ad hoc
|
|
int nbMaille = -10;
|
|
switch (indic)
|
|
{// le numéro de maillage est mis en négatif pour indiquer qu'il est faux
|
|
// il est ensuite lue à la bonne valeur par la référence
|
|
case 1 : ref = new ReferenceNE(nbMaille,indic); break;
|
|
case 2 : ref = new ReferenceNE(nbMaille,indic); break;
|
|
case 3 : ref = new ReferenceAF(nbMaille,indic); break;
|
|
case 4 : ref = new ReferenceAF(nbMaille,indic); break;
|
|
case 5 : ref = new ReferenceAF(nbMaille,indic); break;
|
|
case 6 : ref = new ReferenceAF(nbMaille,indic); break;
|
|
case 7 : ref = new ReferencePtiAF(nbMaille,indic); break;
|
|
case 8 : ref = new ReferencePtiAF(nbMaille,indic); break;
|
|
default :
|
|
if (fr) {cout << "\nErreur : valeur incorrecte du type de reference indic = " << indic << "\n";}
|
|
else {cout << "\nError : incorrect value of the type of reference indic = " << indic << "\n";};
|
|
cout << "LesReferences::Lecture_base_info(..." ;
|
|
Sortie(1);
|
|
};
|
|
// lecture de la référence en question
|
|
ref->Lecture_base_info(entr,cas);
|
|
// intégration dans la map
|
|
mapDeRef[ref->Nom()]=ref;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// écriture base info
|
|
// = 1 : on sauvegarde tout
|
|
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
|
|
void LesReferences::Ecriture_base_info(ostream& sort,const int cas)
|
|
{bool fr = ParaGlob::Francais(); // pour simplifier
|
|
// pour l'instant nous n'avons que des références fixes
|
|
if (cas == 1)
|
|
{int t_taille = t_mapDeRef.Taille();
|
|
if (fr) {sort << "\n ****taille_tableau_references= " << t_taille << " ";}
|
|
else {sort << "\n ****size_tab_references= " << t_taille << " ";};
|
|
for (int i=1;i<=t_taille;i++)
|
|
{ map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(i);
|
|
map < string, Reference*, std::less <string> >::iterator il,ilfin=mapDeRef.end();
|
|
if (fr) {sort << "\n ****les_references_du_maillage"<<i<<"_nombre= " << mapDeRef.size() <<"\n";}
|
|
else {sort << "\n ****the_references_of_mesh"<<i<<"_number= " << mapDeRef.size() <<"\n";}
|
|
for (il=mapDeRef.begin() ; il != ilfin; il++)
|
|
{ // on écrit le type de référence
|
|
Reference& refi=*((*il).second);
|
|
if (fr) {sort << "\n type_de_reference= " << refi.Indic() << " ";}
|
|
else {sort << "\n type_of_reference= " << refi.Indic() << " ";};
|
|
// puis écriture de la référence
|
|
refi.Ecriture_base_info(sort,cas);
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
|
|
|
|
//------------------------------------ protegees ----------------------
|
|
|
|
/* */
|
|
|
|
// lecture d'une liste de reference
|
|
// création d'une référence pointée par ref
|
|
bool LesReferences::LectureReference(UtilLecture & entreePrinc)
|
|
{ bool fr = ParaGlob::Francais(); // pour simplifier
|
|
// tout d'abord il faut vérifier qu'il y a effectivement une référence à lire
|
|
// c'est à dire que l'on ne se trouve pas au niveau d'un mot cle sinon arret
|
|
if (motCle.SimotCle(entreePrinc.tablcar))
|
|
return false;
|
|
// maintenant cas d'une référence à lire
|
|
// deux cas : soit indic a déjà une valeur qui indique le type de référence à lire auquel cas
|
|
// on cré une référence du type a doc
|
|
// sinon on regarde l'identificateur de la référence et suivant la première lettre on choisit
|
|
// le type de référence à créer
|
|
int oldIndic = indic; // pour se rappeler l'ancienne valeur
|
|
if (indic == 0)
|
|
// cas où le type est a définir : on regarde le premier caratère
|
|
{ char premCar = entreePrinc.tablcar[0];
|
|
if (premCar == 'N')
|
|
indic = 1;
|
|
else if (premCar == 'E')
|
|
indic = 2;
|
|
else if (premCar == 'F')
|
|
indic = 3;
|
|
else if (premCar == 'A')
|
|
indic = 4;
|
|
else if (premCar == 'P')
|
|
indic = 5;
|
|
else if (premCar == 'G')
|
|
indic = 6;
|
|
else if (premCar == 'P')
|
|
indic = 7;
|
|
else if (premCar == 'L')
|
|
indic = 8;
|
|
else
|
|
{ // erreur, ce n'est pas un type de référence connu
|
|
if (fr)
|
|
{cout << "\n erreur dans la definition du type de reference, le premier caractere de l'identificateur doit etre "
|
|
<< " une des lettres suivantes : N ou E ou F ou A , alors que la valeur lue est : " << premCar << "\n";}
|
|
else {cout << "\n error in the definition of a reference type, the first character must be "
|
|
<< " one of the following character : N or E or F or A , but the read character is : " << premCar << "\n";}
|
|
entreePrinc.MessageBuffer("LectureReference") ;
|
|
Affiche();
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
};
|
|
// maintenant on définit la référence adoc
|
|
switch (indic)
|
|
{
|
|
case 1 : ref = new ReferenceNE(nbMaille,indic); break;
|
|
case 2 : ref = new ReferenceNE(nbMaille,indic); break;
|
|
case 3 : ref = new ReferenceAF(nbMaille,indic); break;
|
|
case 4 : ref = new ReferenceAF(nbMaille,indic); break;
|
|
case 5 : ref = new ReferenceAF(nbMaille,indic); break;
|
|
case 6 : ref = new ReferenceAF(nbMaille,indic); break;
|
|
case 7 : ref = new ReferencePtiAF(nbMaille,indic); break;
|
|
case 8 : ref = new ReferencePtiAF(nbMaille,indic); break;
|
|
default :
|
|
if (fr) {cout << "\nErreur : valeur incorrecte du type de référence indic = " << indic << "\n";}
|
|
else {cout << "\nError : incorrect value of the type of reference indic = " << indic << "\n";};
|
|
entreePrinc.MessageBuffer("LectureReference") ;
|
|
Affiche();
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
// remise à la valeur précédente d'indic
|
|
indic = oldIndic;
|
|
|
|
// lecture des données propres à la référence et retour
|
|
bool retour= (ref->LectureReference(entreePrinc));
|
|
// on supprime les doublons éventuels
|
|
ref->Supprime_doublons_internes();
|
|
return retour;
|
|
};
|
|
|
|
|
|
// retourne la reference correspondant a une cle
|
|
Reference& LesReferences::Trouve_interne(const string & st1,int num_mail) const
|
|
{ if (num_mail > t_mapDeRef.Taille())
|
|
{ if (ParaGlob::Francais())
|
|
{cout << " \n pb la reference de nom " << st1 << " pour le maillage nb= "<< num_mail << " n'existe pas \n";}
|
|
else {cout << "\nError : the reference with the name " << st1 << " for the mesh nb= " << num_mail << " does not exist \n";}
|
|
if (ParaGlob::NiveauImpression() >5)
|
|
{ cout << " \n LesReferences::Trouve(const string & st1,int num_mail) " << endl;};
|
|
Sortie (1);
|
|
}
|
|
else if (t_mapDeRef(num_mail).find(st1) == t_mapDeRef(num_mail).end())
|
|
{ if (ParaGlob::Francais())
|
|
{cout << " \n pb la reference de nom " << st1 << " pour le maillage nb= "<< num_mail << " n'existe pas \n";}
|
|
else {cout << "\nError : the reference with the name " << st1 << " for the mesh nb= " << num_mail << " does not exist \n";}
|
|
if (ParaGlob::NiveauImpression() >5)
|
|
{ cout << " \n LesReferences::Trouve(const string & st1,int num_mail) " << endl;};
|
|
Sortie (1);
|
|
};
|
|
// sinon c'est ok
|
|
return *(t_mapDeRef(num_mail)[st1]);
|
|
};
|
|
|
|
// idem mais avec un nom de maillage
|
|
Reference& LesReferences::Trouve_interne(const string & st1,const string* nom_mail) const
|
|
{ // on regarde si le nom de maillage est licite
|
|
if (nom_mail == NULL)
|
|
{ // acceptable que si l'on a un seul maillage
|
|
#ifdef MISE_AU_POINT
|
|
if (listeNomMail->size() != 1)
|
|
if (ParaGlob::NiveauImpression() >2)
|
|
{ if (ParaGlob::Francais())
|
|
{cout << "\n warning: la reference demandee= " << st1 << " , n'a pas de nom de maillage associe"
|
|
<< " alors qu'il y a plusieurs maillage defini !! : on considere que c'est une ref du premier maillage";}
|
|
else {cout << "\n warning: the wanted reference " << st1 << " , has no associated mesh "
|
|
<< " but several meshes exist !! : we consider that it is a ref for the first mesh ";}
|
|
if (ParaGlob::NiveauImpression() >5)
|
|
{ if (ParaGlob::Francais()) {cout << "\n nom_de_maillages= ";}
|
|
else {cout << "\n names of the meshes = ";}
|
|
map < string, int , std::less <string> >::const_iterator ili,ilifin=listeNomMail->end();
|
|
for (ili = listeNomMail->begin();ili != ilifin; ili++)
|
|
cout << (*ili).first << ", " ;
|
|
cout << "\n LesReferences::Trouve_interne(const string & st1,const string& nom_mail) ";
|
|
};
|
|
// Sortie(1);
|
|
};
|
|
#endif
|
|
// on ramène le cas du premier maillage qui doit exister
|
|
return Trouve_interne(st1,1);
|
|
}
|
|
else
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
// on regarde si le nom de maillage existe dans la liste
|
|
if (listeNomMail->find(*nom_mail) == listeNomMail->end())
|
|
{ if (ParaGlob::Francais()) {cout << "\nErreur : le nom de maillage : " << *nom_mail << " n'existe pas \n";}
|
|
else {cout << "\nError : the name of the mesh : " << *nom_mail << " does not exist \n";}
|
|
if (ParaGlob::NiveauImpression() >5)
|
|
cout << "LesReferences::Trouve_interne(const string & st1,const string& nom_mail) \n";
|
|
Sortie(1);
|
|
}
|
|
#endif
|
|
return Trouve_interne(st1,(*(listeNomMail->find(*nom_mail))).second);
|
|
};
|
|
};
|
|
|