// 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 "Distribution_CPU.h"
#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>
#include <boost/serialization/string.hpp>
#include <boost/mpi.hpp>
namespace mpi = boost::mpi;

// constructeur par défaut
Distribution_CPU::Distribution_CPU():
  tab_list_maillage_element(),tab_indic()
  ,total_elem(0),total_elem_maitre(0)
  ,tab_vide_list_maillage_element()
  ,tab_list_maillage_noeud(),tab_indic_noeud()
  ,total_noeud(0)
  ,tab_vide_list_maillage_noeud()
  {};
       
// constructeur de copie
Distribution_CPU::Distribution_CPU (const Distribution_CPU& a):
  tab_list_maillage_element(a.tab_list_maillage_element)
  ,tab_indic(a.tab_indic)
  ,total_elem(a.total_elem),total_elem_maitre(a.total_elem_maitre)
  ,tab_vide_list_maillage_element()
  ,tab_list_maillage_noeud(a.tab_list_maillage_noeud)
  ,tab_indic_noeud(a.tab_indic_noeud),total_noeud(a.total_noeud)
  ,tab_vide_list_maillage_noeud()
  {};

// calcul de l'équilibrage initiale
void Distribution_CPU::Calcul_Equilibrage_initiale(const LesMaillages *   lesMaillages, LesContacts * lesContacts)
  {
    if (ParaGlob::Monde()->rank() == 0)
     { // on équilibre sur tous les cpu excepté le maître, qui lui ne calcule pas
       int nb_proc_calcul = ParaGlob::Monde()->size() - 1;
       // si nb_proc_calcul == 0 on ne peut pas continuer, aucun cpu n'étant disponible
       // pour le calcul, on arrête
       if (nb_proc_calcul == 0)
        {cout << "\n *** erreur en calcul d'equilibrage initial: le nombre de cpu "
              << " disponible pour le calcul est nul ! on ne peut pas continuer "
              << " (il faut utiliser la version mono-processeur d'Herezh++ !  ) "
              << endl;
         Sortie(1);
        };
        
       // dans une première étape on ne s'intéresse qu'aux éléments
       // on suppose que les éléments sont identiques en temps de calcul
       // on repère les éléments par le numéro de maillage + le numéro d'élément, en cours
       // on récupère le nombre total d'éléments
       int nb_mail = lesMaillages->NbMaillage();
       
       total_elem = 0; // init
       Tableau <Tableau <bool > > inter(nb_mail); // inter utilisé ensuite pour dimensionner tab_indic
       Tableau <Tableau <bool > > inter_noeud(nb_mail); // inter utilisé ensuite pour dimensionner tab_indic_noeud
       for (int i=1;i<=nb_mail;i++)
         {int nb_elem_mail = lesMaillages->Nombre_element(i);
          total_elem += nb_elem_mail;
          inter(i).Change_taille(nb_elem_mail,false);
          int nb_noeud_mail = lesMaillages->Nombre_noeud(i);
          total_noeud += nb_noeud_mail;
          inter_noeud(i).Change_taille(nb_noeud_mail,false);
         };
       // on  dimensionne tab_indic, tout est à false
       tab_indic.Change_taille(nb_proc_calcul,inter);
       tab_indic_noeud.Change_taille(nb_proc_calcul,inter_noeud);
       // il faut que le nombre d'élément soit au moins >= au nb de proc de calcul
       // pour que l'on puisse distribuer au moins un elem par proc de calcul
       if (total_elem < nb_proc_calcul)
        {cout << "\n *** erreur en calcul d'equilibrage initial: le nombre de cpu "
              << " disponible pour le calcul \n est inferieur au nb d'element total ! on ne peut pas continuer "
              << "\n (il faut utiliser la version mono-processeur d'Herezh++ !  ) "
              << endl;
         Sortie(1);
        };

         
       // le nombre théorique d'élément par cpu
       int nb_elem_un_cpu = total_elem/nb_proc_calcul; // arrondi inférieur
       // on adapte le tableau de liste
       tab_list_maillage_element.Change_taille(nb_proc_calcul); 
       tab_list_maillage_noeud.Change_taille(nb_proc_calcul);
       for (int iproc =1;iproc <= nb_proc_calcul; iproc++)
          {tab_list_maillage_element(iproc).Change_taille(nb_mail);
           tab_list_maillage_noeud(iproc).Change_taille(nb_mail);
           for (int imail=1; imail<= nb_mail; imail++)
             {tab_list_maillage_element(iproc)(imail).clear();
              tab_list_maillage_noeud(iproc)(imail).clear();
             };
          };
          
       // on différencie le cas sans et avec contact
       // dans le cas sans contact on parcours linéairement tous les maillages successivement
       int nb_mail_Esclave = lesMaillages->NbEsclave(); // def du nombre de maillages esclaves
       
       // si aucun esclave 
       if (nb_mail_Esclave==0)
        {// on parcours tous les éléments et on remplit les tableaux
         int iproc = 1; // le num du proc en cours
         int nb_ele_enreg_iproc = 1; // init le nombre d'élément enregistré pour le proc
         for (int imail=1;imail<=nb_mail;imail++)
          {
           int nb_ele = lesMaillages->Nombre_element(imail);
           {list <int > * li_maillage_element = & tab_list_maillage_element(iproc)(imail); // init
            list <int > * li_maillage_noeud = & tab_list_maillage_noeud(iproc)(imail); // init
              // de la liste courante
            for (int ile = 1; ile<=nb_ele;ile++,nb_ele_enreg_iproc++)
              { li_maillage_element->push_back(ile);
                tab_indic(iproc)(imail)(ile)=true; // on signale
                // idem pour les noeuds
                Element& ele = lesMaillages->Element_LesMaille(imail,ile);
                Tableau<Noeud *>& tab_N = ele.Tab_noeud();
                int nb_N = tab_N.Taille();
                for (int ne =1;ne<=nb_N;ne++)
                 {int num_noeud = tab_N(ne)->Num_noeud();
                  tab_indic_noeud(iproc)(imail)(num_noeud)=true;
                  li_maillage_noeud->push_back(num_noeud);
                 };
                // on regarde s'il faut changer de cpu
                // si c'est le dernier cpu, on ne change pas -> pour éviter
                // les pb d'arrondi
                if ((nb_ele_enreg_iproc > nb_elem_un_cpu)
                    && (iproc < nb_proc_calcul) )
                 {iproc++;
                  nb_ele_enreg_iproc=1; // reinit du compteur
                  li_maillage_element = & tab_list_maillage_element(iproc)(imail); // pointage liste associée
                  li_maillage_noeud = & tab_list_maillage_noeud(iproc)(imail);
                 };
              };
           };
          };
        }
       else // cas où on a des maillages maîtres particuliers donc du contact
        {// l'idée est de tout d'abord, ventiler les éléments des maillages maîtres ou en autocontact
         // de manière à l'exécution qu'il y ait une ventilation:
         // 1) de la recherche du contact
         // 2) potentiellement (si contact il y a) d'élément de contact
         int iproc = 1; // le num du proc en cours
         // on va calculer le nb d'éléments maitres (environ) qui doivent être attribué à chaque cpu
         int nbmailautocontact = lesContacts->NbmailAutoContact();
//         int nbmailMaitre = nb_mail-(nb_mail_Esclave-nbmailautocontact); // def du nombre de maillage maitres
         // ce sont les derniers maillages
         total_elem_maitre = 0; // init
         for (int i=1+nb_mail_Esclave-nbmailautocontact;i<=nb_mail;i++)
           {int nb_elem_mail = lesMaillages->Nombre_element(i);
            total_elem_maitre += nb_elem_mail;
           };
         int nb_elem_maitre_un_cpu = total_elem_maitre/nb_proc_calcul; // arrondi inférieur
// // --- debug
// cout << "\n *** debug Distribution_CPU::Calcul_Equilibrage_initiale"
//      << "\n  total_elem_maitre= "<< total_elem_maitre
//      << " nb_elem_maitre_un_cpu= "<< nb_elem_maitre_un_cpu;
// //--- fin debug
         // on distribue en parcourant les maillages maîtres
         int nb_ele_enreg_iproc = 1; // init le nombre d'élément enregistré pour le proc
         for (int imail=1+nb_mail_Esclave-nbmailautocontact;imail<=nb_mail;imail++)
          {
           int nb_ele = lesMaillages->Nombre_element(imail);
           {list <int > * li_maillage_element = & tab_list_maillage_element(iproc)(imail); // init
            list <int > * li_maillage_noeud = & tab_list_maillage_noeud(iproc)(imail); // init
              // de la liste courante
            for (int ile = 1; ile<=nb_ele;ile++,nb_ele_enreg_iproc++)
              { li_maillage_element->push_back(ile);
                tab_indic(iproc)(imail)(ile)=true; // on signale
                // idem pour les noeuds
                Element& ele = lesMaillages->Element_LesMaille(imail,ile);
                Tableau<Noeud *>& tab_N = ele.Tab_noeud();
                int nb_N = tab_N.Taille();
                for (int ne =1;ne<=nb_N;ne++)
                 {int num_noeud = tab_N(ne)->Num_noeud();
                  tab_indic_noeud(iproc)(imail)(num_noeud)=true;
                  li_maillage_noeud->push_back(num_noeud);
                 };
                // on regarde s'il faut changer de cpu
                // si c'est le dernier cpu, on ne change pas -> pour éviter
                // les pb d'arrondi
                if ((nb_ele_enreg_iproc > nb_elem_maitre_un_cpu)
                    && (iproc < nb_proc_calcul) )
                 {iproc++;
                  nb_ele_enreg_iproc=1; // reinit du compteur
                  li_maillage_element = & tab_list_maillage_element(iproc)(imail); // pointage liste associée
                  li_maillage_noeud = & tab_list_maillage_noeud(iproc)(imail);
                 };
              };
           };
          };
//// --- debug
//cout << "\n *** debug Distribution_CPU::Calcul_Equilibrage_initiale";
//cout << "\n 1) elements maitres pour chaque proc : ";
//for (int iproc = 1;iproc <= nb_proc_calcul; iproc++)
// {for (int imail=1+nb_mail_Esclave-nbmailautocontact;imail<=nb_mail;imail++)
//   {list <int > * li_maillage_element = & tab_list_maillage_element(iproc)(imail); // init
//    list <int >::iterator il,ilfin = li_maillage_element->end();
//    for (il = li_maillage_element->begin();il != ilfin; il++)
//      cout << "\n proc("<<iproc<<") mail= "<<imail<< ", elem= "<< (*il)<< flush;
//   }
// }
////--- fin debug
         // puis on distribue en parcourant les maillages esclaves
         // le nombre théorique d'élément par cpu
         int nb_elem_esclave_un_cpu = (total_elem-total_elem_maitre)/nb_proc_calcul; // arrondi inférieur
//// --- debug
//cout << "\n *** debug Distribution_CPU::Calcul_Equilibrage_initiale"
//     << "\n  total_elem= "<< total_elem
//     << " nb_elem_esclave_un_cpu= "<< nb_elem_esclave_un_cpu;
////--- fin debug
         nb_ele_enreg_iproc = 1; // on réinit
         iproc = 1;// réinit
         for (int imail=1;imail<=nb_mail_Esclave-nbmailautocontact;imail++)
          {
           int nb_ele = lesMaillages->Nombre_element(imail);
           {list <int > * li_maillage_element = & tab_list_maillage_element(iproc)(imail); // init
            list <int > * li_maillage_noeud = & tab_list_maillage_noeud(iproc)(imail); // init
              // de la liste courante
            for (int ile = 1; ile<=nb_ele;ile++,nb_ele_enreg_iproc++)
              { li_maillage_element->push_back(ile);
                tab_indic(iproc)(imail)(ile)=true; // on signale
                // idem pour les noeuds
                Element& ele = lesMaillages->Element_LesMaille(imail,ile);
                Tableau<Noeud *>& tab_N = ele.Tab_noeud();
                int nb_N = tab_N.Taille();
                for (int ne =1;ne<=nb_N;ne++)
                 {int num_noeud = tab_N(ne)->Num_noeud();
                  tab_indic_noeud(iproc)(imail)(num_noeud)=true;
                  li_maillage_noeud->push_back(num_noeud);
                 };
                // on regarde s'il faut changer de cpu
                // si c'est le dernier cpu, on ne change pas -> pour éviter
                // les pb d'arrondi
                if ((nb_ele_enreg_iproc > nb_elem_esclave_un_cpu)
                    && (iproc < nb_proc_calcul) )
                 {iproc++;
                  nb_ele_enreg_iproc=1; // reinit du compteur
                  li_maillage_element = & tab_list_maillage_element(iproc)(imail); // pointage liste associée
                  li_maillage_noeud = & tab_list_maillage_noeud(iproc)(imail);
                 };
              };
           };
          };
//// --- debug
//cout << "\n *** debug Distribution_CPU::Calcul_Equilibrage_initiale";
//cout << "\n 2) au final les elements  pour chaque proc : ";
//for (int iproc = 1;iproc <= nb_proc_calcul; iproc++)
// {for (int imail=1;imail<=nb_mail;imail++)
//   {list <int > * li_maillage_element = & tab_list_maillage_element(iproc)(imail); // init
//    list <int >::iterator il,ilfin = li_maillage_element->end();
//    for (il = li_maillage_element->begin();il != ilfin; il++)
//      cout << "\n proc("<<iproc<<") mail= "<<imail<< ", elem= "<< (*il)<< flush;
//   }
// }
////--- fin debug


        }
//// ----- debug
//cout << "\n debug Distribution_CPU::Calcul_Equilibrage_initiale ";
//Distribution_CPU::Affiche();
//cout << flush;
//// ----- fin debug ---

     }
  };
  
// passage de l'équilibrage à tous les cpu autres que 0
void Distribution_CPU::Passage_Equilibrage_aux_CPU() 
  { //if (ParaGlob::Monde()->rank() == 0)
      broadcast(*ParaGlob::Monde(), *this, 0);
    // synchronisation ici de tous les process
//    ParaGlob::Monde()->barrier();

    // mise à jour de ParaGlob, qui peut transmettre à tous
    // la liste des numéros d'éléments concernés
    ParaGlob::param->Init_tableau(&tab_list_maillage_element,&tab_indic
                                  ,&tab_list_maillage_noeud,&tab_indic_noeud);
  };


// -- serialisation ---
// on spécialise la sauvegarde et la restitution
// version == 0 pour la première sauvegarde et ensuite > 0
// NB: c'est toujours la version en cours au moment de la sauvegarde
// ==> dans notre cas, on ne sent sert pas pour l'instant: supposé tjs == 0
template<class Archive>
void Distribution_CPU::save(Archive & ar, const unsigned int version) const
  { // comme on a des listes on sauvegarde explicitement
    int nb_proc_calcul = tab_list_maillage_element.Taille();
    ar << std::string("Distribution_CPU:taille= ")  << nb_proc_calcul ;
    for (int i_proc=1;i_proc<= nb_proc_calcul; i_proc++)
     {int nb_mail = tab_list_maillage_element(i_proc).Taille();
      ar << std::string(" nb_mail= ")<< nb_mail ;
      // on sauvegarde également le nombre total d'élément par maillage
      // pour cela on se sert de tab_indic pour le premier cpu
      for (int num_mail = 1; num_mail <= nb_mail;num_mail++)
         ar << (int) tab_indic(1)(num_mail).Taille();
      // maintenant tab_list_maillage_element
      for (int imail=1;imail<=nb_mail;imail++)
        { const list <int >& list_maillage_element = tab_list_maillage_element(i_proc)(imail);
          ar << std::string(" list_maillage_element:i_taille= ")<< (int) list_maillage_element.size() ;
          list <int >::const_iterator  il, ilfin= list_maillage_element.end();
          for (il = list_maillage_element.begin(); il != ilfin; il++)
            { int truc = (*il);
              ar <<  truc ;
            };
        };
      // on sauvegarde également le nombre total de noeud par maillage
      // pour cela on se sert de tab_indic_noeud pour le premier cpu
      for (int num_mail = 1; num_mail <= nb_mail;num_mail++)
         ar << (int) tab_indic_noeud(1)(num_mail).Taille();
      // puis tab_list_maillage_noeud
      for (int imail=1;imail<=nb_mail;imail++)
        { const list <int >& list_maillage_noeud = tab_list_maillage_noeud(i_proc)(imail);
          ar << std::string(" list_maillage_noeud:i_taille= ")<< (int) list_maillage_noeud.size() ;
          list <int >::const_iterator  il, ilfin= list_maillage_noeud.end();
          for (il = list_maillage_noeud.begin(); il != ilfin; il++)
            { int truc = (*il);
              ar <<  truc ;
            };
        };
     };
  }
  
// en lecture, le num de version permet de ce positionner sur une version particulière
// ==> dans notre cas, on ne sent sert pas pour l'instant: supposé tjs == 0
template<class Archive>
void Distribution_CPU::load(Archive & ar, const unsigned int version)
 { // opération inverse de save
   std::string toto; int taille;
   ar >> toto >> taille;
   // on vérifie que c'est cohérent avec le nombre de CPU en cours
   int nb_proc_calcul = ParaGlob::Monde()->size() - 1;
   if (taille != nb_proc_calcul)
    {cout << "\n **** erreur en recuperation d'une distribution CPU, le nombre de cpu "
          << " en cours: "<<nb_proc_calcul << "est different de celui archive: "
          << taille << " on ne peut pas continuer l'execution  !!!";
     Sortie(1);
    };
   
   // redimentionnement éventuel, si même taille, aucune action
   tab_list_maillage_element.Change_taille(nb_proc_calcul);
   tab_list_maillage_noeud.Change_taille(nb_proc_calcul);
   // idem tab_indic
   tab_indic.Change_taille(nb_proc_calcul);
   tab_indic_noeud.Change_taille(nb_proc_calcul);

   total_elem = 0; // init
   total_noeud = 0; // init

   for (int i_proc=1;i_proc<= nb_proc_calcul; i_proc++)
    { int nb_mail;
      ar >> toto >> nb_mail;
      tab_list_maillage_element(i_proc).Change_taille(nb_mail);
      tab_indic(i_proc).Change_taille(nb_mail);
      tab_list_maillage_noeud(i_proc).Change_taille(nb_mail);
      tab_indic_noeud(i_proc).Change_taille(nb_mail);
      // on va lire le nombre total d'éléments pour chaque maillage
      for (int num_mail = 1; num_mail <= nb_mail;num_mail++)
         { int nb_elem_mail;
           ar >> nb_elem_mail;
           tab_indic(i_proc)(num_mail).Change_taille(nb_elem_mail,false);
         };
      // puis les tableaux
      for (int imail=1;imail<=nb_mail;imail++)
        { Tableau <bool > & tab_indic_cpu_mail = tab_indic(i_proc)(imail); // pour simplifier
          list <int >& list_maillage_element = tab_list_maillage_element(i_proc)(imail);
          int size_list;
          ar >> toto >> size_list;
          if (size_list == list_maillage_element.size())
            {// si la liste existante a la bonne taille, on ne fait que lire
             int inter;
             list <int >::iterator  il, ilfin= list_maillage_element.end();
             for (il = list_maillage_element.begin(); il != ilfin; il++)
              {ar >> inter; (*il)=inter;
               tab_indic_cpu_mail(inter)=true; // on rempli tab_indic
              }
            }
          else // cas où la taille n'est pas bonne
            {list_maillage_element.clear();
             int inter; // élément de travail
             for (int j=1;j<= size_list;j++)
              {ar >> inter;
               list_maillage_element.push_back(inter);
               tab_indic_cpu_mail(inter)=true; // on rempli tab_indic
              };
            };
          // mise à jour du nombre total d'élément
          total_elem += list_maillage_element.size();
        };
      // on va lire le nombre total de noeud pour chaque maillage
      for (int num_mail = 1; num_mail <= nb_mail;num_mail++)
         { int nb_noeud_mail;
           ar >> nb_noeud_mail;
           tab_indic_noeud(i_proc)(num_mail).Change_taille(nb_noeud_mail,false);
         };
      // puis les tableaux
      for (int imail=1;imail<=nb_mail;imail++)
        { Tableau <bool > & tab_indic_noeud_cpu_mail = tab_indic_noeud(i_proc)(imail); // pour simplifier
          list <int >& list_maillage_noeud = tab_list_maillage_noeud(i_proc)(imail);
          int size_list;
          ar >> toto >> size_list;
          if (size_list == list_maillage_noeud.size())
            {// si la liste existante a la bonne taille, on ne fait que lire
             int inter;
             list <int >::iterator  il, ilfin= list_maillage_noeud.end();
             for (il = list_maillage_noeud.begin(); il != ilfin; il++)
              {ar >> inter; (*il)=inter;
               tab_indic_noeud_cpu_mail(inter)=true; // on rempli tab_indic
              }
            }
          else // cas où la taille n'est pas bonne
            {list_maillage_noeud.clear();
             int inter; // élément de travail
             for (int j=1;j<= size_list;j++)
              {ar >> inter;
               list_maillage_noeud.push_back(inter);
               tab_indic_noeud_cpu_mail(inter)=true; // on rempli tab_indic
              };
            };
          // mise à jour du nombre total d'élément
          total_noeud += list_maillage_noeud.size();
        };
    };
 };

// affichage des infos relatives à la distribution
void Distribution_CPU::Affiche() const
   { // comme on a des listes on sauvegarde explicitement
     cout << "\n ------ Distribution ---------";
     int nb_proc_calcul = tab_list_maillage_element.Taille();
     cout << std::string(" nb total de proc de calcul :  ")  << nb_proc_calcul ;
     for (int i_proc=1;i_proc<= nb_proc_calcul; i_proc++)
      {cout << "\n ... cas du proc de calcul : "<< i_proc;
       int nb_mail = tab_list_maillage_element(i_proc).Taille();
       cout << std::string(" nb_mail considere = ")<< nb_mail ;
       // on affiche également le nombre total d'élément par maillage
       // pour cela on se sert de tab_indic pour le premier cpu
       for (int num_mail = 1; num_mail <= nb_mail;num_mail++)
          cout << ",  nb elem total du maillage " << num_mail << " => " << (int) tab_indic(1)(num_mail).Taille();
       for (int imail=1;imail<=nb_mail;imail++)
         { const list <int >& list_maillage_element = tab_list_maillage_element(i_proc)(imail);
           cout << " \n cas du maillage "<< imail
                << std::string(": nb elem pour le proc => ")<< (int) list_maillage_element.size()
                << " c-a-d les elem : \n ";
           list <int >::const_iterator  il, ilfin= list_maillage_element.end();
           for (il = list_maillage_element.begin(); il != ilfin; il++)
             { int truc = (*il);
               cout <<  truc << " ,  ";
             };
         };
       // idem pour les noeuds on affiche le nombre total de noeud par maillage
       // pour cela on se sert de tab_indic_noeud pour le premier cpu
       for (int num_mail = 1; num_mail <= nb_mail;num_mail++)
          cout << ",  nb noeud total du maillage " << num_mail << " => " << (int) tab_indic_noeud(1)(num_mail).Taille();
       for (int imail=1;imail<=nb_mail;imail++)
         { const list <int >& list_maillage_noeud = tab_list_maillage_noeud(i_proc)(imail);
           cout << " \n cas du maillage "<< imail
                << std::string(": nb noeud pour le proc => ")<< (int) list_maillage_noeud.size()
                << " c-a-d les elem : \n ";
           list <int >::const_iterator  il, ilfin= list_maillage_noeud.end();
           for (il = list_maillage_noeud.begin(); il != ilfin; il++)
             { int truc = (*il);
               cout <<  truc << " ,  ";
             };
         };
      };
   }


// 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)
void Distribution_CPU::Lecture_base_info(istream& ent,const int cas)
 { // on récupère le tableau de list : tab_list_maillage_element
   // on suit exactement la même procédure que pour archive
   load(ent,cas);
 };
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void Distribution_CPU::Ecriture_base_info(ostream& sort,const int cas)
 { // on sauvegarde le tableau de list : tab_list_maillage_element
   // on suit exactement la même procédure que pour archive
   save(sort,cas);
 };


