Herezh_dev/herezh_pp/References/ReferenceAF.cc

555 lines
22 KiB
C++
Executable file

// FICHIER : ReferenceAF.cp
// CLASSE : ReferenceAF
#include "ReferenceAF.h"
#include "PtTabRel.h"
#ifndef REFERENCEAF_H_deja_inclus
#ifndef MISE_AU_POINT
inline
#endif
// Constructeur par defaut (appel au constructeur par defaut de Tableau<T>)
ReferenceAF::ReferenceAF (string nom):
Reference(nom),tab_Elem(),tab_FA()
{ };
#ifndef MISE_AU_POINT
inline
#endif
// Constructeur fonction du nb de maillage et du type de ref
ReferenceAF::ReferenceAF (int nb , int ind) :
Reference(nb,ind),tab_Elem(),tab_FA()
{ };
#ifndef MISE_AU_POINT
inline
#endif
// Constructeur fonction de deux tableaux de numeros, le premier pour les numéros
// d'éléments le second pour les numéros de faces, d'aretes, de noeud d'element, ou de point d'integ
// du nb de maillage, du type de ref
ReferenceAF::ReferenceAF (const Tableau<int>& tabelem,const Tableau<int>& tab
,int nbmaille , int indic, string nom):
Reference(nom,nbmaille,indic),tab_Elem(tabelem),tab_FA(tab)
{ };
#ifndef MISE_AU_POINT
inline
#endif
// Constructeur fonction de deux listes de numeros, la première pour les numéros
// d'éléments la seconde pour les numéros de faces, d'aretes, de noeud d'element, ou de point d'integ
// du nb de maillage, du type de ref
ReferenceAF::ReferenceAF (const list <int>& list_elem,const list <int>& list_num
,int nbmaille , int indic, string nom):
Reference(nom,nbmaille,indic),tab_Elem(list_elem.size()),tab_FA(list_num.size())
{ int tail = tab_Elem.Taille();
list <int>::const_iterator it=list_elem.begin();
for (int i=1;i<= tail;i++,it++)
tab_Elem(i)=(*it);
tail = tab_FA.Taille(); it = list_num.begin();
for (int i=1;i<= tail;i++,it++)
tab_FA(i)=(*it);
};
#ifndef MISE_AU_POINT
inline
#endif
// Constructeur utile si le nom de la reference est connu
ReferenceAF::ReferenceAF (string nom,int nb , int ind) :
Reference(nom,nb,ind),tab_Elem(),tab_FA()
{ };
#ifndef MISE_AU_POINT
inline
#endif
// Constructeur de copie
ReferenceAF::ReferenceAF (const ReferenceAF& ref):
Reference (ref),tab_Elem(ref.tab_Elem),tab_FA(ref.tab_FA)
{ };
// Destructeur
#ifndef MISE_AU_POINT
inline
#endif
ReferenceAF::~ReferenceAF ()
{ };
//================== METHODES : ================================
#ifndef MISE_AU_POINT
inline
#endif
Reference& ReferenceAF::operator= (const Reference& ref)
{ *this = this->Reference::operator=(ref); // pour la partie de la classe mère
#ifdef MISE_AU_POINT
// vérification du type de ref
if ((ref.Indic() != 3) && (ref.Indic() != 4)&& (ref.Indic() != 5)&& (ref.Indic() != 6))
{if (ParaGlob::Francais())
{cout << " \n erreur dans l'affectation de reference : ReferenceAF::operator= (const Reference& ref)"
<< "\n la reference ref n'est ni celle de face, d'arete, de noeud d'element "
<< " ou de pt d'integ ";
}
else
{cout << " \n error in the operator of reference : ReferenceAF::operator= (const Reference& ref)"
<< "\n the reference ref is not a reference of a face, an edge, a node "
<< " or a gauss point ";
};
};
#endif
tab_Elem = ((ReferenceAF&) ref).tab_Elem;
tab_FA = ((ReferenceAF&) ref).tab_FA;
return (*this);
};
// change un numéro i de référence
// nbe: le numéro d'élément, nbAF: le numéro de de faces, ou d'arêtes, ou de noeud d'element,
// ou de points d'integ
#ifndef MISE_AU_POINT
inline
#endif
void ReferenceAF::Change_num_AF_dans_ref(int i,int nbe, int nbAF)
{ if ((i < 1)|| (i>tab_Elem.Taille()))
{ cout << "\n *** erreur de changement de numero dans la reference : " << this->Nom()
<< "\n le numero demande est le " << i << " ce qui est en dehors des valeurs possibles "
<< " qui doivent etre comprises entre 1 et "<<tab_Elem.Taille()<< " on affiche la ref actuelle : ";
this->Affiche();
Sortie(1);
};
tab_Elem(i)=nbe;tab_FA(i)= nbAF;
};
// change les 2 tableaux de la ref
#ifndef MISE_AU_POINT
inline
#endif
void ReferenceAF::Change_tab_num(const Tableau<int>& tabele,const Tableau<int>& tab)
{ // on vérifie que les deux tableaux ont la même taille
if (tabele.Taille() != tab.Taille())
{ cout << "\n *** erreur de changement des deux tableaux dans la reference : " << this->Nom()
<< "\n les tailles des deux tableaux sont differentes: taille des elements="<< tabele.Taille()
<< ", taille du second tableau =" << tab.Taille() << " on affiche la ref actuelle : ";
this->Affiche();
Sortie(1);
};
tab_Elem=tabele;
tab_FA= tab;
};
// Affiche les donnees liees a la reference
#ifndef MISE_AU_POINT
inline
#endif
// indique si le numéro d'élément et le numéro de faces, d'arête ou de noeud d'élément
// ou de pt d'integ passé en argument, fait partie de la référence
// nbe: le numéro d'élément, nbAF: le numéro de face, d'arête, de noeud d'element ou de pt d'integ
bool ReferenceAF::Contient_AF(int nbe, int nbAF) const
{ int tail_tab=tab_Elem.Taille();
for (int i=1;i<= tail_tab;i++)
if ((tab_Elem(i)==nbe) && (tab_FA(i)==nbAF)) return true;
return false;
};
// Affiche les donnees liees a la reference
#ifndef MISE_AU_POINT
inline
#endif
void ReferenceAF::Affiche () const
{ // affichage du type de référence
if (indic == 3)
{ if (ParaGlob::Francais()) {cout << "\n reference de face d'element";}
else {cout << "\n reference of an element face ";};}
else if (indic == 4)
{ if (ParaGlob::Francais()) {cout << "\n reference d'arete d'element";}
else {cout << "\n reference of an element edge ";};}
else if (indic == 5)
{ if (ParaGlob::Francais()) {cout << "\n reference de noeud d'element";}
else {cout << "\n reference of node ";};}
else if (indic == 6)
{ if (ParaGlob::Francais()) {cout << "\n reference de pt d'integ d'element";}
else {cout << "\n reference of a gauss point ";};}
else if (indic == 7)
{ if (ParaGlob::Francais()) {cout << "\n reference de pt d'integ relatif a une face d'element";}
else {cout << "\n reference of a gauss point for a facet of an element ";};}
else if (indic == 8)
{ if (ParaGlob::Francais()) {cout << "\n reference de pt d'integ relatif a une arete d'element";}
else {cout << "\n reference of a gauss point for an edge of an element";};}
else
{ if (ParaGlob::Francais()) {cout << "\n reference de type non defini ";}
else {cout << "\n reference not defined ";};}
// affichage pour la partie de la classe mère
this->Reference::Affiche();
// partie spécifique
if (ParaGlob::Francais()) {cout << "Taille des tableaux : " ;}
else {cout << "size of the tab : " ;};
cout << tab_Elem.Taille() << " .\n";
if (ParaGlob::Francais())
{cout << "Composante(s) (1 element puis une face ou arete ou noeud ou pt integ ):\n\t[ ";}
else
{cout << "Components(s) (1 element then one face or edge or node or gauss point ):\n\t[ ";};
for (int i=1;i<=tab_Elem.Taille();i++)
cout << tab_Elem(i) << " "<< tab_FA(i) << " ";
cout << "]\n\n";
};
// supprime les doublons internes éventuels dans la référence
#ifndef MISE_AU_POINT
inline
#endif
void ReferenceAF::Supprime_doublons_internes()
{ //Tableau<int> tab_Elem; // tableau des numeros des éléments de la reference
//Tableau<int> tab_FA; // tableau des numeros des faces ou arêtes de la reference
// ou noeud d'element, ou de points d'intégrations d'élément
int taille = tab_Elem.Taille();
list <int> agarder; // contiendra les seules numéros à sauvegarder
for (int i=1;i<=taille;i++)
{ bool bon=true;
for (int j=i+1;j<=taille;j++)
if ((tab_Elem(i)==tab_Elem(j))&& (tab_FA(i)==tab_FA(j)))
{bon=false;
if (ParaGlob::NiveauImpression() > 3)
{ cout << "\n *** attention suppression doublon: ref "<<nom_ref
<< " maillage:"<<nbmaille<<" element " << tab_Elem(i)
<< " face/arrete.. "<< tab_FA(i)<<endl;
};
break;
} // cas d'un doublon
if (bon)
agarder.push_back(i);
};
int new_taille = agarder.size();
// on modifie la liste initiale si la nouvelle taille est différente
if (new_taille != taille)
{list <int>::iterator ili,ilifin = agarder.end();
int position=1;
for (ili=agarder.begin();ili!=ilifin;ili++,position++)
{tab_Elem(position) = tab_Elem(*ili); //position est toujours < *ili donc on écrase a partir du bas
tab_FA(position) = tab_FA(*ili); // et tab_Elem(*ili) et tab_FA(*ili) sont toujours valides
};
// on supprime les données de new_taille à taille
tab_Elem.Change_taille(new_taille);
tab_FA.Change_taille(new_taille);
};
};
// lecture d'une liste de references pt d'integ, ou de noeud, ou arêtes ou faces d'éléments
#ifndef MISE_AU_POINT
inline
#endif
bool ReferenceAF::LectureReference(UtilLecture & entreePrinc)
{ *(entreePrinc.entree) >> nom_ref; // lecture d'une reference
// si l'on est à la fin de la ligne on passe à la ligne suivante
//cout << "\n rdstate " << entreePrinc.entree->rdstate() << endl;
if ((entreePrinc.entree->eof() != 0) && (!(entreePrinc.entree->fail())))
{ entreePrinc.NouvelleDonnee(); }
// on utilise une liste pour la lecture, ce qui permet de lire une nombre quelconque
// de numéros attachés à une référence
list <Reels2> inter; // on utilise des réels car c'est déjà défini par ailleurs
// mais cela n'a aucune importance sur le traitement
int il;
if ((entreePrinc.entree->rdstate() != 0)
&& (!motCle.SimotCle(entreePrinc.tablcar)))
// si le buffer ne contiend pas de mot cle et qu'il y a un
// pb de lecture ( donc pas de def de reference)
{ if (ParaGlob::Francais())
{cout << " \n Erreur de lecture de reference \n contenu du buffer = ";}
else {cout << " \n Error of reference reading \n buffer = ";};
cout << entreePrinc.tablcar << endl;
if (ParaGlob::Francais())
{entreePrinc.MessageBuffer
("lecture d une reference de face ou d'arete ou de noeud d'element ou de pt d'integ"); }
else
{entreePrinc.MessageBuffer
("reading of a reference of face or edge or node or gauss point "); };
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie (1);
}
else if (motCle.SimotCle(entreePrinc.tablcar))
{ // fin de la lecture de reference
// remise correcte du flot
entreePrinc.FlotDebutDonnee();
return false;
}
else
{
// cas ou on a bien lu un nom de reference
{
il = 0; // nb de nb d'entier lu
bool fin = false;
// les deux cas qui font sortir de la boucle sont l'apparition
// d'un mot cle ou une erreur en lecture dans entier
// apres une bonne lecture sur la meme ligne
bool aumoinsune = true;
bool prem = true; // ne sert que pour le cas d'une reference sans numero
while ( (!fin) & aumoinsune)
{aumoinsune = false;
// def du maillon à lire dans la liste
Reels2 as1;
// while (!entreePrinc.entree->rdstate()) // lecture tant qu'il n'y a pas d'erreur
while ((!entreePrinc.entree->rdstate())&& // lecture tant qu'il n'y a pas d'erreur
(!(entreePrinc.entree->eof())))
{ // lecture de deux entiers mis dans deux réels
*(entreePrinc.entree) >> as1.donnees[0] ;
// si jamais on est à la fin d'une ligne on passe à la ligne suivante
if (entreePrinc.entree->eof())
{
#ifdef ENLINUX
if (!(entreePrinc.entree->bad()))
// on continue que si le flot est correcte car en linux il s'apperçoit du pb
// qu'après la mauvaise lecture, c'est-à-dire eof() ne fonctionne pas correctement
{ break; }
#endif
/* #ifdef SYSTEM_MAC_OS_X_unix
if (!(entreePrinc.entree->bad()))
// on continue que si le flot est correcte car en linux il s'apperçoit du pb
// qu'après la mauvaise lecture, c'est-à-dire eof() ne fonctionne pas correctement
{ break; }
#endif */
entreePrinc.NouvelleDonnee(); // lecture d'une nouvelle ligne
}
*(entreePrinc.entree) >> as1.donnees[1];
// pour la verif
// pour mémoire ici on a
/* enum io_state
{ badbit = 1<<0, // -> 1 dans rdstate()
eofbit = 1<<1, // -> 2
failbit = 1<<2, // -> 4
goodbit = 0 // -> O
};*/
// if ((entreePrinc.entree->rdstate() == 0)||
// (entreePrinc.entree->eof() ))
#ifdef ENLINUX
if (entreePrinc.entree->rdstate() == 0)
#else
/* #ifdef SYSTEM_MAC_OS_X_unix
if (entreePrinc.entree->rdstate() == 0)
#else*/
if (((entreePrinc.entree->rdstate() == 0)||
(entreePrinc.entree->eof()))&&(!(entreePrinc.entree->bad()))
&&(!(entreePrinc.entree->fail())))
// #endif
#endif
{il++;
aumoinsune = true;
prem = false;
inter.push_back(as1);
}
}
if ((aumoinsune) || prem )
{entreePrinc.NouvelleDonnee(); // lecture d'une nouvelle ligne
if (motCle.SimotCle(entreePrinc.tablcar))
// c'est un mot cle
fin = true;
}
else
// remise correcte du flot pour la lecture
//d'une prochaine reference
entreePrinc.FlotDebutDonnee();
}
if (il == 0 )
{ if (ParaGlob::Francais()) {cout << "\n WARNING : aucun numero attache a la reference = ";}
else {cout << "\n WARNING : no number linked to the reference = ";};
cout << nom_ref << endl;
}
// transfert dans les tableaux
tab_Elem.Change_taille(il);
tab_FA.Change_taille(il);
listdouble2Iter b; int a;
for (b=inter.begin(),a=1 ;b != inter.end();b++,a++)
{ tab_Elem(a) = (int) (b->donnees[0]); // transformation en entier
tab_FA(a) = (int) (b->donnees[1]); // transformation en entier
}
return true;
}
}
return false;
};
// affichage et definition interactive des commandes
// nbMaxi: nombre maxi de noeud ou d'éléments pour les exemples
// cas : =1 premier passage, il s'agit de références de noeuds uniquement
// cas : =2 second passage, il s'agit de l'ensemble des possibilités de références
#ifndef MISE_AU_POINT
inline
#endif
void ReferenceAF::Info_commande_Ref(int nbMaxi,UtilLecture * entreePrinc,int cas)
{ ofstream & sort = *(entreePrinc->Commande_pointInfo()); // pour simplifier
if (cas == 1)
{ if (ParaGlob::Francais()) {cout << "\n erreur: cas = "; }
else { cout << "\n error: case = "; };
cout << cas << "\n ReferenceAF::Info_commande_Ref(....";
Sortie(1);
}
else
{ if (indic ==3) // cas d'une ref de surface d'élément
{ if (ParaGlob::Francais())
{sort << "\n # -- exemple de reference de face d'element";}
else {sort << "\n # -- exemple of a reference of an element face ";};
cout << "\n F_tout ";
int compteur_ligne=0;
for (int n1=1;n1<= nbMaxi;n1++,compteur_ligne++)
{ if (compteur_ligne > 10)
{ compteur_ligne = 0; sort << "\n";}
sort << setw (6) << n1 << setw (6)<< 1 <<" ";
}
sort << "\n \n";
}
else if (indic ==4) // cas d'une ref d'arete d'élément
{ if (ParaGlob::Francais())
{ sort << "\n # -- exemple de reference d'arete d'elements ";}
else {sort << "\n # -- exemple of a reference of an element edge ";};
cout << "\n A_tout ";
int compteur_ligne=0;
for (int n1=1;n1<= nbMaxi;n1++,compteur_ligne++)
{ if (compteur_ligne > 10)
{ compteur_ligne = 0; sort << "\n";}
sort << setw (6) << n1 << setw (6)<< 1<<" ";
}
sort << "\n \n";
}
else if (indic ==5) // cas d'une ref de noeuds d'élément
{ if (ParaGlob::Francais())
{ sort << "\n # -- exemple de reference de noeuds d'elements ";}
else {sort << "\n # -- exemple of a reference of an element node ";};
cout << "\n P_tout ";
int compteur_ligne=0;
for (int n1=1;n1<= nbMaxi;n1++,compteur_ligne++)
{ if (compteur_ligne > 10)
{ compteur_ligne = 0; sort << "\n";}
sort << setw (6) << n1 << setw (6)<< 1<<" ";
}
sort << "\n \n";
}
else if (indic ==6) // cas d'une ref de pt d'integ d'élément
{ if (ParaGlob::Francais())
{ sort << "\n # -- exemple de reference de point d'integration d'elements ";}
else {sort << "\n # -- exemple of a reference of an element gauss point ";};
cout << "\n G_tout ";
int compteur_ligne=0;
for (int n1=1;n1<= nbMaxi;n1++,compteur_ligne++)
{ if (compteur_ligne > 10)
{ compteur_ligne = 0; sort << "\n";}
sort << setw (6) << n1 << setw (6)<< 1<<" ";
}
sort << "\n \n";
}
else if (indic ==7) // cas d'une ref de pt d'integ de face d'élément
{ if (ParaGlob::Francais())
{ sort << "\n # -- exemple de reference de point d'integration de face d'elements "
<< "\n nb_elem nb_face nb_pti " ;}
else {sort << "\n # -- exemple of a reference of Gauss point for an element facet "
<< "\n nb_elem nb_facet nb_Gauss ";};
cout << "\n P_tout ";
int compteur_ligne=0;
for (int n1=1;n1<= nbMaxi;n1++,compteur_ligne++)
{ if (compteur_ligne > 10)
{ compteur_ligne = 0; sort << "\n";}
sort << setw (6) << n1 << setw (6)<< 1 << setw (6)<< 1 <<" ";
};
sort << "\n \n";
}
else if (indic ==8) // cas d'une ref de pt d'integ d'arête d'élément
{ if (ParaGlob::Francais())
{ sort << "\n # -- exemple de reference de point d'integration d'arete d'elements "
<< "\n nb_elem nb_arete nb_pti " ;}
else {sort << "\n # -- exemple of a reference of Gauss point for an element edge "
<< "\n nb_elem nb_edge nb_Gauss ";};
cout << "\n L_tout ";
int compteur_ligne=0;
for (int n1=1;n1<= nbMaxi;n1++,compteur_ligne++)
{ if (compteur_ligne > 10)
{ compteur_ligne = 0; sort << "\n";}
sort << setw (6) << n1 << setw (6)<< 1 << setw (6)<< 1<<" ";
};
sort << "\n \n";
}
}
};
//----- lecture écriture dans base info -----
// cas donne le niveau de la récupération
// = 1 : on récupère tout
// = 2 : on récupère uniquement les données variables (supposées comme telles)
#ifndef MISE_AU_POINT
inline
#endif
void ReferenceAF::Lecture_base_info(ifstream& ent,const int cas)
{ // ici a priori il n'y a pas de de données supposées variables
if (cas == 1)
{
// appelle de la méthode de la classe mère
Lect_int_base_info(ent);
// lecture des deux tableaux d'entiers qui ont la même taille
int tab_FATaille; string toto;
ent >> toto >> tab_FATaille;
tab_Elem.Change_taille(tab_FATaille);
tab_FA.Change_taille(tab_FATaille);
for (int i=1;i<= tab_FATaille; i++)
ent >> tab_Elem(i) >> tab_FA(i) ;
};
};
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
#ifndef MISE_AU_POINT
inline
#endif
void ReferenceAF::Ecriture_base_info(ofstream& sort,const int cas)
{ // ici a priori il n'y a pas de de données supposées variables
if (cas == 1)
{
// appelle de la méthode de la classe mère
Ecrit_int_base_info(sort);
// écriture des deux tableau d'entier, normalement ils ont la même taille
int tab_FATaille = tab_FA.Taille();
#ifdef MISE_AU_POINT
if ( tab_FATaille != tab_Elem.Taille())
{ if (ParaGlob::Francais())
{cout << " \n erreur, les deux tableaux ont une taille differente : ";}
else {cout << " \n error, the two tabs have not the same size : ";};
cout << tab_FATaille << " " << tab_Elem.Taille();
Sortie(1);
}
#endif
sort << "tailleAF " << tab_FATaille << " ";
for (int i=1;i<= tab_FATaille; i++)
sort << tab_Elem(i) << " " << tab_FA(i) << " ";
sort << "\n";
};
};
#ifndef MISE_AU_POINT
inline
#endif
// Affiche les donnees des références dans le flux passé en paramètre
void ReferenceAF::Affiche_dans_lis(ofstream& sort) const
{ int taille_tab= tab_Elem.Taille();
// dans le cas où il n'y a pas de numéro associé à la référence on ne l'écrit pas
if (taille_tab > 0 )
{ sort << "\n" << setw (6) << nom_ref << " ";
int nb_par_ligne=20;
for (int i=1,nb_p_l=1;i<=taille_tab;i++,nb_p_l++)
{ if(nb_p_l > nb_par_ligne)
{ nb_p_l=1; sort << "\n";}
sort << tab_Elem(i) << " " << tab_FA(i) << " ";
};
sort << "\n";
}
#ifdef MISE_AU_POINT
else if (ParaGlob::NiveauImpression() > 1)
{ cout << "\n attention: ref "<<nom_ref <<" sans numero associe, on ne la sauvegarde pas ";}
#endif
};
#endif