// FICHIER : ReferenceNE.cc
// CLASSE : ReferenceNE
// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) .
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//
// For more information, please consult: .
#include "ReferenceNE.h"
#include "PtTabRel.h"
#include "ParaGlob.h"
#ifndef REFERENCENE_H_deja_inclus
#ifndef MISE_AU_POINT
inline
#endif
// Constructeur par defaut (appel au constructeur par defaut de Tableau)
ReferenceNE::ReferenceNE (string nom):
Reference(nom),tab_num()
{ };
#ifndef MISE_AU_POINT
inline
#endif
// Constructeur fonction du nb de maillage et du type de ref
ReferenceNE::ReferenceNE (int nb , int ind) :
Reference(nb,ind),tab_num()
{ };
#ifndef MISE_AU_POINT
inline
#endif
// Constructeur utile si le tableau des numeros
// de la reference est connu, le nb de maillage, le type de ref
ReferenceNE::ReferenceNE (const Tableau& tab,int nb, int ind, string nom):
Reference(nom,nb,ind),tab_num(tab)
{ };
#ifndef MISE_AU_POINT
inline
#endif
// Constructeur utile si une liste des numeros
// de la reference est connu, le nb de maillage, le type de ref
ReferenceNE::ReferenceNE (const list & list_entiers,int nb, int ind, string nom):
Reference(nom,nb,ind),tab_num(list_entiers.size())
{ int tail = tab_num.Taille();
list ::const_iterator it=list_entiers.begin();
for (int i=1;i<= tail;i++,it++)
tab_num(i)=(*it);
};
#ifndef MISE_AU_POINT
inline
#endif
// Constructeur utile si le nom de la reference est connu
ReferenceNE::ReferenceNE (string nom,int nb , int ind) :
Reference(nom,nb,ind),tab_num()
{ };
#ifndef MISE_AU_POINT
inline
#endif
// Constructeur de copie
ReferenceNE::ReferenceNE (const ReferenceNE& ref):
Reference (ref),tab_num(ref.tab_num)
{ };
// Destructeur
#ifndef MISE_AU_POINT
inline
#endif
ReferenceNE::~ReferenceNE ()
{ };
//================== METHODES : ================================
#ifndef MISE_AU_POINT
inline
#endif
Reference& ReferenceNE::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() != 2) && (ref.Indic() != 1))
{if (ParaGlob::Francais())
{cout << " \n erreur dans l'affectation de reference : ReferenceNE::operator= (const Reference& ref)"
<< "\n la reference ref n'est ni celle de noeud ni celle d'elements ";
}
else
{cout << " \n error in the operator of reference : ReferenceNE::operator= (const Reference& ref)"
<< "\n the reference ref is not a reference of a node or of an element "
<< " or a gauss point ";
};
};
#endif
tab_num = ((ReferenceNE&) ref).tab_num;
return (*this);
};
// Affiche les donnees liees a la reference
#ifndef MISE_AU_POINT
inline
#endif
void ReferenceNE::Affiche () const
{ // affichage du type de référence
if (indic == 1)
{ if (ParaGlob::Francais()) {cout << "\n reference de noeud ";}
else {cout << "\n reference of node ";};}
else if (indic == 2)
{ if (ParaGlob::Francais()) {cout << "\n reference d'element ";}
else {cout << "\n reference of element ";};}
else
{ if (ParaGlob::Francais()) {cout << "\n reference de type non défini ";}
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 du tableaux : " ;}
else {cout << "size of the tab : " ;};
cout << tab_num.Taille() << " .\n";
if (ParaGlob::Francais()) {cout << "Composante(s)";}
else {cout << "Component(s)";};
cout << " :\n\t[ ";
for (int i=1;i<=tab_num.Taille();i++)
cout << tab_num(i) << " ";
cout << "]\n\n";
};
// lecture d'une liste de references de noeuds ou d'éléments
#ifndef MISE_AU_POINT
inline
#endif
bool ReferenceNE::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 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 noeud ou d'element");}
else
{entreePrinc.MessageBuffer
("reading of a reference of node or element "); };
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
Reels1 as1;
// while (!entreePrinc.entree->rdstate()) // lecture tant qu'il n'y a pas d'erreur
while ((entreePrinc.entree->rdstate()== 0)&& // lecture tant qu'il n'y a pas d'erreur
(!(entreePrinc.entree->eof())))
{ *(entreePrinc.entree) >> as1.donnees; // lecture d'un entier mis dans un réel
// 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->rdstate() == 2))
// (entreePrinc.entree->eof()))
// cout << "\n entreePrinc.entree->eof()" << entreePrinc.entree->eof();
// cout << "\n entreePrinc.entree->bad()" << entreePrinc.entree->bad();
// cout << "\n entreePrinc.entree->fail()" << entreePrinc.entree->fail() << endl;
#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 le tableau tab
tab_num.Change_taille(il);
listdouble1Iter b; int a;
for (b=inter.begin(),a=1 ;b != inter.end();b++,a++)
tab_num(a) = (int) (b->donnees); // transformation en entier
return true;
}
}
return false;
};
// supprime les doublons internes éventuels dans la référence
#ifndef MISE_AU_POINT
inline
#endif
void ReferenceNE::Supprime_doublons_internes()
{ //Tableau tab_num;
int taille = tab_num.Taille();
list 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_num(i)==tab_num(j))
{bon=false;
if (ParaGlob::NiveauImpression() > 3)
{ cout << "\n *** attention suppression doublon: ref "<::iterator ili,ilifin = agarder.end();
int position=1;
for (ili=agarder.begin();ili!=ilifin;ili++,position++)
{tab_num(position) = tab_num(*ili); //position est toujours < *ili donc on écrase a partir du bas
// et tab_num(*ili) est toujours valide
};
// on supprime les données de new_taille à taille
tab_num.Change_taille(new_taille);
};
};
// 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 ReferenceNE::Info_commande_Ref(int nbMaxi,UtilLecture * entreePrinc,int cas)
{ ofstream & sort = *(entreePrinc->Commande_pointInfo()); // pour simplifier
if (cas == 1)
{ if (ParaGlob::Francais())
{sort << "\n # -- exemple de reference de noeud ";}
else {sort << "\n # -- exemple of a reference of node ";};
sort << "\n N_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 <<" ";
}
sort << "\n \n";
}
else
{ if (indic ==1) // cas d'une ref de noeud
{ if (ParaGlob::Francais())
{sort << "\n # -- exemple de reference de noeud ";}
else {sort << "\n # -- exemple of a reference of node ";};
cout << "\n N_deb 1 ";
}
else // cas d'une ref d'élément
{ if (ParaGlob::Francais())
{sort << "\n # -- exemple de reference d'elements ";}
else {sort << "\n # -- exemple of a reference of elements ";};
cout << "\n E_tout_les_elements ";
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 <<" ";
}
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 ReferenceNE::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 du tableau d'entier
ent >> tab_num ;
};
};
// 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 ReferenceNE::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 du tableau d'entier
sort << tab_num;
};
};
#ifndef MISE_AU_POINT
inline
#endif
// Affiche les donnees des références dans le flux passé en paramètre
void ReferenceNE::Affiche_dans_lis(ofstream& sort) const
{ int taille_tab= tab_num.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_num(i) << " ";
}
sort << "\n";
}
// #ifdef MISE_AU_POINT
else if (ParaGlob::NiveauImpression() > 1)
{ sort <