// FICHIER : ReferencePtiAF.cc
// CLASSE : ReferencePtiAF

// 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 "ReferencePtiAF.h"
#include "PtTabRel.h"
#include "ParaGlob.h"

#ifndef  REFERENCEPTIAF_H_deja_inclus

#ifndef MISE_AU_POINT
  inline 
#endif
// Constructeur par defaut (appel au constructeur par defaut de Tableau<T>)
ReferencePtiAF::ReferencePtiAF (string nom):
 Reference(nom),tab_Elem(),tab_FA(),tab_pti()
    { };

    
#ifndef MISE_AU_POINT
  inline 
#endif
// Constructeur fonction  du nb de maillage et du type de ref		
ReferencePtiAF::ReferencePtiAF (int nb , int ind) :
  Reference(nb,ind),tab_Elem(),tab_FA(),tab_pti()
   { };
   
#ifndef MISE_AU_POINT
  inline 
#endif
// Constructeur fonction  de trois  tableaux de numeros, le premier pour les numéros
// d'éléments le deuxième pour les numéros de faces, ou d'aretes,
// le troisième pour le nb du pt d'integ,
// puis le  nb de maillage, et enfin le type de ref
ReferencePtiAF::ReferencePtiAF (const Tableau<int>& tabelem
               ,const Tableau<int>& tabAF,const Tableau<int>& tabPti
		             ,int nbmaille , int indic, string nom):
  Reference(nom,nbmaille,indic),tab_Elem(tabelem),tab_FA(tabAF),tab_pti(tabPti)
       { };


#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
ReferencePtiAF::ReferencePtiAF (const list <int>& list_elem,const list <int>& list_numAF
                                ,const list <int>& list_num_pti
                                ,int nbmaille , int indic, string nom):
  Reference(nom,nbmaille,indic),tab_Elem(list_elem.size()),tab_FA(list_numAF.size())
  ,tab_pti(list_num_pti.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_numAF.begin();
	  for (int i=1;i<= tail;i++,it++)
	    tab_FA(i)=(*it);
     
   tail = tab_pti.Taille(); it = list_num_pti.begin();
   for (int i=1;i<= tail;i++,it++)
     tab_pti(i)=(*it);

	}; 

#ifndef MISE_AU_POINT
  inline 
#endif
// Constructeur utile si le nom de la reference est connu 
ReferencePtiAF::ReferencePtiAF (string nom,int nb , int ind) :
  Reference(nom,nb,ind),tab_Elem(),tab_FA(),tab_pti()
       { };


#ifndef MISE_AU_POINT
  inline 
#endif
// Constructeur de copie 
ReferencePtiAF::ReferencePtiAF (const ReferencePtiAF& ref):
    Reference (ref),tab_Elem(ref.tab_Elem),tab_FA(ref.tab_FA)
    ,tab_pti(ref.tab_pti)
       { };
	
// Destructeur 
#ifndef MISE_AU_POINT
  inline 
#endif
ReferencePtiAF::~ReferencePtiAF ()
      { };

//================== METHODES : ================================
		
#ifndef MISE_AU_POINT
  inline 
#endif
Reference& ReferencePtiAF::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 : ReferencePtiAF::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 : ReferencePtiAF::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 = ((ReferencePtiAF&) ref).tab_Elem;
      tab_FA = ((ReferencePtiAF&) ref).tab_FA;
      tab_pti = ((ReferencePtiAF&) ref).tab_pti;
	  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, nbPti
//       le num de points d'integ
#ifndef MISE_AU_POINT
  inline 
#endif
void ReferencePtiAF::Change_num_PtiAF_dans_ref(int i,int nbe, int nbAF, int nbPti)
  { 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;tab_pti(i)= nbPti;
  };

// change les 3 tableaux de la ref
#ifndef MISE_AU_POINT
  inline 
#endif
void ReferencePtiAF::Change_tab_num(const Tableau<int>& tabele
                                    ,const Tableau<int>& tabAF,const Tableau<int>& tabPti)
  { // on vérifie que les 3 tableaux ont la même taille
    if ((tabele.Taille() != tabAF.Taille()) && (tabele.Taille() != tabPti.Taille()))
     { cout << "\n *** erreur de changement des trois tableaux dans la reference : " << this->Nom()
            << "\n les tailles des trois tableaux sont differentes: taille des elements="<< tabele.Taille()
            << ", taille du deuxieme tableau =" << tabAF.Taille()
            << ", taille du troisieme tableau ="<< tabPti.Taille()
            << " on affiche la ref actuelle : ";
       this->Affiche();
       Sortie(1);
     };
    tab_Elem=tabele;
    tab_FA= tabAF;
    tab_pti= tabPti;
  };

// Affiche les donnees liees a la reference
#ifndef MISE_AU_POINT
  inline 
#endif
// indique si le numéro d'élément, le numéro de faces ou d'arêtes, et le num de points
// d'integ, passé  en argument, fait partie de la référence
// nbe: le numéro d'élément, nbAF: le numéro de de faces, ou d'arêtes,
//       nbPti le num  de points d'integ
bool ReferencePtiAF::Contient_PtiAF(int nbe, int nbAF, int nbPti) const
 { int tail_tab=tab_Elem.Taille();
   for (int i=1;i<= tail_tab;i++)
     if ((tab_Elem(i)==nbe) && (tab_FA(i)==nbAF) && (tab_pti(i)==nbPti)) return true;
   return false;  
  };      
		
// Affiche les donnees liees a la reference
#ifndef MISE_AU_POINT
  inline 
#endif
void ReferencePtiAF::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 puis un pt integ ):\n\t[  ";}
			else 
			  {cout << "Components(s) (1 element then one face or edge then a gauss point ):\n\t[  ";};
			for (int i=1;i<=tab_Elem.Taille();i++)
				cout << tab_Elem(i) << "  "<< tab_FA(i) << "  "<< tab_pti(i) << "  ";
			cout << "]\n\n";
		};

// supprime les doublons internes éventuels dans la référence
#ifndef MISE_AU_POINT
  inline 
#endif
void ReferencePtiAF::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
  //Tableau<int> tab_pti; // tableau des  points d'intégrations
  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))&& (tab_pti(i)==tab_pti(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)
                   << " nbpti.. " << tab_pti(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
         tab_pti(position) = tab_pti(*ili); // et tab_pti(*ili)
        };
     // on supprime les données de new_taille à taille
     tab_Elem.Change_taille(new_taille);
     tab_FA.Change_taille(new_taille);
     tab_pti.Change_taille(new_taille);
    };
};
    
// lecture d'une liste de references 
#ifndef MISE_AU_POINT
  inline 
#endif
bool ReferencePtiAF::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 <Reels3> 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 pti de face ou d'arete d'element "); }
			else  
			 {entreePrinc.MessageBuffer
             ("reading of a reference of Gauss point of face or edge of 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
            Reels3 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 3 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]; 
              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
                entreePrinc.NouvelleDonnee();  // lecture d'une nouvelle ligne
               };
             *(entreePrinc.entree) >> as1.donnees[2];
             // 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);
          tab_pti.Change_taille(il);
          listdouble3Iter 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
              tab_pti(a) = (int) (b->donnees[2]); // 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 ReferencePtiAF::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 ReferencePtiAF::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 ReferencePtiAF::Lecture_base_info(istream& 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 3 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);
        tab_pti.Change_taille(tab_FATaille);
        for (int i=1;i<= tab_FATaille; i++)
          ent >> tab_Elem(i) >> tab_FA(i) >> tab_pti(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 ReferencePtiAF::Ecriture_base_info(ostream& 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 trois 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()) || (tab_FATaille != tab_pti.Taille()))
          { if (ParaGlob::Francais()) 
			           {cout << " \n erreur, les trois tableaux ont une taille differente : ";}
				        else {cout << " \n error, the 3 tabs have not the same size : ";};
            cout << "\n taille elem= "<< tab_Elem.Taille()
                 << " taille F ou A = "<< tab_FATaille
                 << " taille pti = "<< tab_pti.Taille();
            Sortie(1);
           }
        #endif 
        sort << "taillePtiAF " << tab_FATaille << "  ";
        for (int i=1;i<= tab_FATaille; i++)
          sort << tab_Elem(i) << "  " << tab_FA(i) << "  "<< tab_pti(i) << "  ";
        sort << "\n";  
       };
  };     
                
#ifndef MISE_AU_POINT
  inline 
#endif
// Affiche les donnees des références dans le flux passé en paramètre
void ReferencePtiAF::Affiche_dans_lis(ostream&  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) << " "<< tab_pti(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