// 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 <