// 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 "Algori.h"
#include "string"
#include "MathUtil.h"
#include <iostream>   //  pour utiliser la classe istrstream
#include <strstream>  //      nouveau dans CW5.3


#include "ReferenceNE.h"
#include "ReferenceAF.h"
#include "ExceptionsElemMeca.h"
#include "ExceptionsLoiComp.h"
#include "TypeQuelconqueParticulier.h"


#include "AlgoriCombine.h" // pour la sortie base_info


// cas eventuel d'un démarrage à partir de base_info
// si inc_voulu est négatif cela signifie que l'on est déjà positionné sur un
// incrément voulu et qu'il faut simplement faire la lecture des infos
	   // 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 Algori::Lecture_base_info(int cas,LesMaillages *lesMaillages,
                   LesReferences* lesReferences,LesCourbes1D* lesCourbes1D,
                   LesFonctions_nD* lesFonctionsnD,LesLoisDeComp*   lesLoisDeComp,
                   DiversStockage* diversStockage,Charge* charge,
                   LesCondLim* lesCondlim,LesContacts* lesContacts,Resultats* resultats,
                   int inc_voulu)
 {  //il y a deux types d'entrée de donnée soit via un fichier info
    // soir via via base info
    int lec_ent_info = entreePrinc->Lec_ent_info();
    // récup du flot d'entrée
  #ifndef UTILISATION_MPI
    ifstream * entrons = entreePrinc->Ent_BI();
  #else
    int proc_en_cours = ParaGlob::Monde()->rank();
    MPI_File * ent_MPI = entreePrinc->Ent_BI(); // récup du fichier
    posi_buffer.resize(13); // cf. .h
  
  #endif
   // -- lec_ent_info --
     // = 0 indique que ce sera via le fichier info
     // = 1 ce sera via un fichier base-info: (pas opérationnelle en MPI)
     // = 2 ce sera via un serveur base-info: (pas opérationnelle en MPI)

    // si l'incrément est positif on se positionne à l'incrément voulu
    if (inc_voulu >= 0)
     {if (lec_ent_info == 0) // cas où on travaille à partir d'un .info
                             // et d'un .BI en restart
       { // on se positionne dans le .BI
         // après l'appel de Positionnement_base_info on est pret pour lire
         // la ligne qui est après la ligne des "==== ...==="
         bool inc_trouve = entreePrinc->Positionnement_base_info(inc_voulu);
         if (!inc_trouve)
          {  cout << "\nErreur : On ne trouve pas l'increment de restart demande !\n";
             if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
               cout << "Algori::Lecture_base_info(....)"
                    << " increment = " << inc_voulu << endl;
             // dans le cas où un comptage du calcul est en cours on l'arrête
             if (tempsInitialisation.Comptage_en_cours()) tempsInitialisation.Arret_du_comptage();
             if (tempsMiseAjourAlgo.Comptage_en_cours()) tempsMiseAjourAlgo.Arret_du_comptage();
             Sortie(1);
          };
       }
      else
       {cout << "\n *** cas non traite MPI pour l'instant "
             << "\n inc_voulu= "<< inc_voulu <<", lec_ent_info= "<<lec_ent_info
             << "\n Algori::Lecture_base_info(... "<< endl;
       };
     };
    
    #ifdef UTILISATION_MPI
       // en MPI, le processus de lecture associé à Positionnement_base_info
       // qui a été appelé précédemment,
       // est très particulier, et permet également de se positionner sur la ligne
       // après la ligne des "==== ...===", ce qui correspond à la fin du premier
       // buffer, donc le premier buffer a déjà été lu, il correspond uniquement
       // au numéro d'incrément
       // il faut ensuite lire les offsets relatifs aux classes principales
       // Lecture des offsets MPI des infos bufferisées
            // on crée un flux sur le tableau de caractères:
       Algori::Lecture_offset_base_info_MPI_IO(cas);
       
       // a) ==== lecture du premier buffer propres à Algo ref et def du flux d'entrée associé
       
       // en fait on n'a pas à lire le premier buffer, car est déjà en position de lire
       // le deuxième buffer
       
//       { char * buffer_car = new char [tailles_buffer_ioBI_MPI[0]] ;
//         MPI_Status status1;
//         int ierr1 = MPI_File_read_all(*ent_MPI, buffer_car, tailles_buffer_ioBI_MPI[0], MPI_CHAR, &status1);
//         // on crée le flux sur le tableau de caractères:
//         istrstream * entrons = new istrstream(buffer_car,tailles_buffer_ioBI_MPI[0]) ;
 
    #endif

 #ifndef UTILISATION_MPI
    // si l'incrément est positif on se positionne à l'incrément voulu
    if (inc_voulu >= 0)
      // lecture différenciée en fonction du cas -> positionnement à l'incrément donné
      switch (lec_ent_info)
       {
         case 0 : // ---- cas d'un restart, on récupère à un incrément donné -----------
          {bool inc_trouve = entreePrinc->Positionnement_base_info(inc_voulu);
           if (!inc_trouve)
	           {  cout << "\nErreur : On ne trouve pas l'increment de restart demande !\n";
               if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
	                cout << "Algori::Lecture_base_info(....)"
			                   << " increment = " << inc_voulu << endl;
               // dans le cas où un comptage du calcul est en cours on l'arrête
               if (tempsInitialisation.Comptage_en_cours()) tempsInitialisation.Arret_du_comptage();
               if (tempsMiseAjourAlgo.Comptage_en_cours()) tempsMiseAjourAlgo.Arret_du_comptage();
	              Sortie(1);
            };
    	      break;
	         }
         case 1 : // ------- on récupère  tout -------------------------
          // dans le cas d'une première lecture on passe les informations sur les incréments
          {string toto; int titi; double xxx;
           (*entrons) >> toto 
                      >> titi >> toto >> xxx >> toto >> xxx >> toto >> xxx;
           (*entrons)  >> toto ; // la ligne des tirets
    	      break;
	         }
         case  2 : case 3 : // ----------- on récupère à un incrément donné --------------------
          {string toto; int titi; int inc; bool inc_trouve = false;double xxx;
           // lecture tant que l'on n'a pas atteint la fin du fichier
           do
             { (*entrons) >> toto;
               if (toto == "INCREMENT_DE_CHARGE_:")
                // on a trouvé un incrément
                { (*entrons) >> inc;
                  if (inc == inc_voulu)
                   // ok on a l'incrément voulu
                   // fin de la préparation de la lecture pour l'incrément 
                   {(*entrons)  >> titi >> toto >> xxx >> toto >> xxx >> toto >> xxx;
                    (*entrons)  >> toto ; // la ligne des tirets
                    inc_trouve = true;
                   };
                };
               // test pour vérifier l'intégrité du flot
               if (entrons->rdstate() != 0)
                // si l'on est arrivé  à la fin du fichier il n'y a rien à faire
                // sinon on remet à flot le flot (cas par exemple d'entier au lieu de caractère)!
                if (!(entrons->eof()))
                  entrons->clear();
             }
           while ((!(entrons->eof()))&& (!inc_trouve));
           // dans le cas où on n'a pas trouvé le bon incrément message d'erreur
	          if (!inc_trouve)
	           {  cout << "\nErreur : On ne trouve pas l'increment  demande !\n";
               if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
	                cout << "Algori::Lecture_base_info(....)"
			                   << " incrément = " << inc_voulu << endl;
               // dans le cas où un comptage du calcul est en cours on l'arrête
               if (tempsInitialisation.Comptage_en_cours()) tempsInitialisation.Arret_du_comptage();
               if (tempsMiseAjourAlgo.Comptage_en_cours()) tempsMiseAjourAlgo.Arret_du_comptage();
	              Sortie(1);
            };
    	      break;
	         }
         default :
	         { cout << "\nErreur : valeur incorrecte du type de restart !\n";
            if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
	             cout << "Algori::Lecture_base_info(....)"
			                << " cas= " << cas << endl;
            // dans le cas où un comptage du calcul est en cours on l'arrête
            if (tempsInitialisation.Comptage_en_cours()) tempsInitialisation.Arret_du_comptage();
            if (tempsMiseAjourAlgo.Comptage_en_cours()) tempsMiseAjourAlgo.Arret_du_comptage();
	           Sortie(1);
	         }
	      };
 #endif
       
       
	   // fin du positionnement à l'incrément donné
  #ifdef UTILISATION_MPI
    // b) ==== lecture du deuxième buffer propres à Algo ref et def du flux d'entrée associé
    { char * buffer_car = new char [tailles_buffer_ioBI_MPI[1]] ;
      MPI_Status status1;
      int ierr1 = MPI_File_read_all(*ent_MPI, buffer_car, tailles_buffer_ioBI_MPI[1], MPI_CHAR, &status1);
      // on crée le flux sur le tableau de caractères:
      istrstream * entrons = new istrstream(buffer_car,tailles_buffer_ioBI_MPI[1]) ;
    
  #endif

    // lecture particulière à l'algorithme
    Lecture_base_info(*entrons,cas);
  #ifdef UTILISATION_MPI
     }; // fin de la lecture du second buffer

   // lecture MPI des infos bufferisées
   lesMaillages->Mise_a_jour_Offset_BI_lecture(posi_buffer[2],cas); // indication offset
   lesMaillages->Lecture_base_info_MPI_IO(ent_MPI,cas);
   lesReferences->Mise_a_jour_Offset_BI_lecture(posi_buffer[3],cas); // indication offset
   lesReferences->Lecture_base_info_MPI_IO(ent_MPI,cas);
   lesCourbes1D->Mise_a_jour_Offset_BI_lecture(posi_buffer[4],cas); // indication offset
   lesCourbes1D->Lecture_base_info_MPI_IO(ent_MPI,cas);
   lesFonctionsnD->Mise_a_jour_Offset_BI_lecture(posi_buffer[5],cas); // indication offset
   lesFonctionsnD->Lecture_base_info_MPI_IO(ent_MPI,cas);
   lesLoisDeComp->Mise_a_jour_Offset_BI_lecture(posi_buffer[6],cas); // indication offset
   lesLoisDeComp->Lecture_base_info_MPI_IO(ent_MPI,cas);
   diversStockage->Mise_a_jour_Offset_BI_lecture(posi_buffer[7],cas); // indication offset
   diversStockage->Lecture_base_info_MPI_IO(ent_MPI,cas);
   charge->Mise_a_jour_Offset_BI_lecture(posi_buffer[8],cas); // indication offset
   charge->Lecture_base_info_MPI_IO(ent_MPI,cas);
   lesCondlim->Mise_a_jour_Offset_BI_lecture(posi_buffer[9],cas); // indication offset
   lesCondlim->Lecture_base_info_MPI_IO(ent_MPI,cas);
   lesContacts->Mise_a_jour_Offset_BI_lecture(posi_buffer[10],cas); // indication offset
   lesContacts->Lecture_base_info_MPI_IO(ent_MPI,cas);
   resultats->Mise_a_jour_Offset_BI_lecture(posi_buffer[11],cas); // indication offset
   resultats->Lecture_base_info_MPI_IO(ent_MPI,cas);


   // puis lecture dans les buffers
   ifstream * entrons = NULL; // en MPI on ne doit pas utiliser entrons, on le met donc à NULL
                                  // ce qui permettra de détecter des erreurs éventuelles
      // si calcul on sauvegarde la distribution
  //    distribution_CPU_algo.Lecture_base_info(*entrons,cas);


  #endif
    lesMaillages->Lecture_base_info(*entrons,cas); // lecture des maillages et des references
    lesReferences->Lecture_base_info(*entrons,cas); // lecture des références
    lesCourbes1D->Lecture_base_info(*entrons,cas); // lecture des courbes1D
    lesFonctionsnD->Lecture_base_info(*entrons,cas); // lecture des fonctions nD
    lesLoisDeComp->Lecture_base_info(*entrons,cas,*lesReferences,*lesCourbes1D,*lesFonctionsnD); // lecture des lois
    diversStockage->Lecture_base_info(*entrons,cas);  // premiere lecture des stockages divers
    charge->Lecture_base_info(*entrons,cas,*lesReferences,*lesCourbes1D,*lesFonctionsnD);  // lecture des actions exterieurs de chargement
    lesCondlim->Lecture_base_info(*entrons,cas,*lesReferences,*lesCourbes1D,*lesFonctionsnD);  // lecture des ddl bloques
    lesContacts->Lec_base_info_LesContacts(*entrons,*lesMaillages
       , &LesMaillages::Noeud_LesMaille, &LesMaillages::Element_LesMaille); // lecture des contacts éventuelles
    resultats->Lect_result_base_info(*entrons,cas);  // lecture des parametres de gestion de la sortie des resultats

    // --- on récupère la position du pointeur dans le fichier, utilisé éventuellement ensuite pour l'écriture du prochain incrément
    // l'opération n'est pas si simple car on a deux cas:
  
  #ifndef UTILISATION_MPI
    // 1) soit on est arrivée à la fin du fichier c-a-d eofbit   = 1<<1, // -> 2
    // dans ce cas il ne faut pas utiliser tellg() car cela va générer un failbit  = 1<<2, // -> 4
    // au contraire on va à la fin et ensuite on demande la position
    // comme on ne peut plus changer les bit
    if (entrons->eof())
     { // ici on fait une manip bizarre mais qui marche
       entreePrinc->Fermeture_base_info(); // on ferme
       entreePrinc->Ouverture_base_info("lecture"); // puis on ouvre
       // récup du flot d'entrée
       entrons = entreePrinc->Ent_BI();
       entrons->seekg (0, entrons->end); // on se met à la fin
       debut_increment = entrons->tellg(); // on récupère la position
     }
    else // sinon cela veut que l'on n'est pas à la fin, on peut donc récupérer la position
      debut_increment = entrons->tellg();
  #else
    // cas MPI pour l'instant on considère que l'accès à la position est toujours ok (à confirmer !)
    MPI_File_get_position(*ent_MPI,&debut_increment);
  #endif
      
    // mémorisation du temps de la sauvegarde     
    temps_derniere_sauvegarde=pa.Variables_de_temps().TempsCourant(); 
    list_incre_temps_sauvegarder.push_front(Entier_et_Double(inc_voulu,temps_derniere_sauvegarde));

   };
    
// sauvegarde sur base info
    // sauvegarde sur base info
    // cas donne le niveau de sauvegarde
    // = 0 : initialisation de la sauvegarde -> c'est-à-dire de la sortie base info
    // = 1 : on sauvegarde tout
    // = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
    // incre : numero d'incrément auquel on sauvegarde 
    // éventuellement est définit de manière spécifique pour chaque algorithme
    // dans les classes filles
    // type_incre :signal permet de localiser le dernier incrément

void Algori::Ecriture_base_info
             (int cas,LesMaillages *lesMaillages,
                   LesReferences* lesReferences,LesCourbes1D* lesCourbes1D,
                   LesFonctions_nD* lesFonctionsnD,LesLoisDeComp*   lesLoisDeComp,
                   DiversStockage* diversStockage,Charge* charge,
                   LesCondLim* lesCondlim,LesContacts* lesContacts,Resultats* resultats
                   ,OrdreVisu::EnumTypeIncre type_incre, int incre)
 {
  tempsSauvegarde.Mise_en_route_du_comptage(); // temps cpu
  // récup des flots pour base info
  bool sortie_effectuee = false;
 #ifndef UTILISATION_MPI
  ofstream * sortons = entreePrinc->Sort_BI();
 #else
  int proc_en_cours = ParaGlob::Monde()->rank();
  // 1) dans le cas d'un proc 0 ou i, on redéfinit le flux de sortie, pour bufferiser les infos en sortie
  // qui sont ensuite sortie via MPI i-o à l'aide de la méthode Ecriture_base_info_MPI_IO
  // les récupérations et les sorties sont effectuées de manière asynchrone par rapport aux autres proc
  // 2) seul le proc 0 sort l'entête et les paramètres spécifiques de l'algo

  if (proc_en_cours == 0) // première partie dédiée proc 0
   {// dimensionnement de buffer_ioBI_MPI
    MPI_Offset taille_buffer_io_MPI =  2; // la partie entête
    buffer_ioBI_MPI.Change_taille(taille_buffer_io_MPI); // si c'est la bonne taille aucune action
    std::ostringstream sort; // définition de sort
    std::ostringstream * sortons = &sort;
  #endif
    switch (cas)
    { case 1 : // ------- on sauvegarde tout -------------------------
      { entreePrinc->Enregistrement_position_increment_base_info(0.);
        // écriture du numéro d'incrément = 0 pour signifier que c'est le début des infos
        (*sortons) << "\n=========================================================================="
                      << "===================="
             << "\n    INCREMENT_DE_CHARGE_: " << 0 << "  intensite " << 0.
             << " t= " << setprecision(ParaGlob::NbdigdoCA()) << pa.Variables_de_temps().TempsCourant()
             << " dt= " << setprecision(ParaGlob::NbdigdoCA())<< ParaGlob::Variables_de_temps().IncreTempsCourant()
             << "\n========================================================================================="
             << "====================";
        // mémorisation du temps de la sauvegarde
        temps_derniere_sauvegarde=pa.Variables_de_temps().TempsCourant();
        list_incre_temps_sauvegarder.push_front(Entier_et_Double(0,temps_derniere_sauvegarde));
        sortie_effectuee = true;
        break;
      }
      case  2 : // ----------- sauvegarde uniquement de se qui varie --------------------
       { // la sauvegarde est effectuée uniquement pour les incréments demandés
         // --dans le cas où le temps courant == le dernier temps déjà sauvegardé, ce n'est pas la peine de faire une seconde sauvegarde
         // sauf si c'est une demande explicite via les paramètres de contrôle
         if ((pa.Variables_de_temps().TempsCourant() == temps_derniere_sauvegarde)
             && (!pa.EtatSortieEtatActuelDansBI()))return;

         if ((pa.SauvegardeAutorisee(incre,temps_derniere_sauvegarde,(type_incre==OrdreVisu::DERNIER_INCRE))) // cas courant
             || (pa.EtatSortieEtatActuelDansBI())) // cas où la demande est explicite -> ce n'est pas le cas courant
          {
          double temps = pa.Variables_de_temps().TempsCourant();
           entreePrinc->Enregistrement_position_increment_base_info(incre);
          // écriture du numéro d'incrément dans le cas d'une sauvegarde partielle
           // écriture du numéro d'incrément
           (*sortons) << "\n========================================================================================="
                      << "===================="
             << "\n    INCREMENT_DE_CHARGE_: " << incre << "  intensite "
             << setprecision(ParaGlob::NbdigdoCA()) << charge->IntensiteCharge()
             << " t= " << setprecision(ParaGlob::NbdigdoCA()) << pa.Variables_de_temps().TempsCourant()
             << " dt= " << setprecision(ParaGlob::NbdigdoCA())<< ParaGlob::Variables_de_temps().IncreTempsCourant()
             << "\n========================================================================================="
             << "====================";
           // mémorisation du temps de la sauvegarde
           temps_derniere_sauvegarde=temps;
           list_incre_temps_sauvegarder.push_front(Entier_et_Double(incre,temps_derniere_sauvegarde));
           sortie_effectuee = true;
          }
         break;
       }
      default :
       { cout << "\nErreur : valeur incorrecte du type de sauvegarde !\n";
         if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
           cout << "Algori::Ecriture_base_info(....)"
                << " cas= " << cas << endl;
         // dans le cas où un comptage du calcul est en cours on l'arrête
         if (tempsSauvegarde.Comptage_en_cours()) tempsSauvegarde.Arret_du_comptage();
         if (tempsSortieFilCalcul.Comptage_en_cours()) tempsSortieFilCalcul.Arret_du_comptage();
         Sortie(1);
       };
    };
 #ifdef UTILISATION_MPI
       buffer_ioBI_MPI(1) = sort.str(); // on sauvegarde
   } // fin de la sortie de l'entête proc 0
  else
   { // on met quand même à jour la variable sortie_effectuee et sauvegarde des temps pour les tests futurs
     switch (cas)
      { case 1 :
         {        // mémorisation du temps de la sauvegarde
          temps_derniere_sauvegarde=pa.Variables_de_temps().TempsCourant();
          list_incre_temps_sauvegarder.push_front(Entier_et_Double(0,temps_derniere_sauvegarde));
          sortie_effectuee = true;
          break;
         }
        case  2 : // ----------- sauvegarde uniquement de se qui varie --------------------
         { // la sauvegarde est effectuée uniquement pour les incréments demandés
           // --dans le cas où le temps courant == le dernier temps déjà sauvegardé, ce n'est pas la peine de faire une seconde sauvegarde
           // sauf si c'est une demande explicite via les paramètres de contrôle
           if ((pa.Variables_de_temps().TempsCourant() == temps_derniere_sauvegarde)
               && (!pa.EtatSortieEtatActuelDansBI()))return;

           if ((pa.SauvegardeAutorisee(incre,temps_derniere_sauvegarde,(type_incre==OrdreVisu::DERNIER_INCRE))) // cas courant
               || (pa.EtatSortieEtatActuelDansBI())) // cas où la demande est explicite -> ce n'est pas le cas courant
            {
             // mémorisation du temps de la sauvegarde
             double temps = pa.Variables_de_temps().TempsCourant();
             temps_derniere_sauvegarde=temps;
             list_incre_temps_sauvegarder.push_front(Entier_et_Double(incre,temps_derniere_sauvegarde));
             sortie_effectuee = true;
            }
         break;
        }
        default :
         { cout << "\n*** Erreur : valeur incorrecte du type de sauvegarde !\n";
           if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
             cout << "\n proc: "<< proc_en_cours << ", Algori::Ecriture_base_info(....)"
                  << " cas= " << cas << endl;
           // dans le cas où un comptage du calcul est en cours on l'arrête
           if (tempsSauvegarde.Comptage_en_cours()) tempsSauvegarde.Arret_du_comptage();
           if (tempsSortieFilCalcul.Comptage_en_cours()) tempsSortieFilCalcul.Arret_du_comptage();
           Sortie(1);
         };
      };

   };
 #endif
 
  // écriture sur le flot de sortie en fonction du "cas"
  if (sortie_effectuee)
    {
   #ifdef UTILISATION_MPI
     if (proc_en_cours == 0) // deuxième partie dédiée proc 0
      {// redéfinition de sortons sur un nouveau buffer de charactère
       std::ostringstream sort; // définition de sort
       std::ostringstream * sortons = &sort;
   #endif
       Ecriture_base_info(*sortons,cas);
   #ifdef UTILISATION_MPI
       buffer_ioBI_MPI(2) = sort.str(); // on sauvegarde
      }; // fin du cas proc 0
     // on redéfinit sortons pointant sur un buffer qui doit rester vide
     // car en MPI il ne faut pas l'utiliser directement ici
              
     std::ostringstream sort; // définition de sort
     std::ostringstream * sortons = &sort;
     // si calcul on sauvegarde la distribution
/// pour l'instant on commente mais il faut l'écrire normalement !!     distribution_CPU_algo.Ecriture_base_info(*sortons,cas);

   #endif

     lesMaillages->Ecriture_base_info(*sortons,cas); // Ecriture des maillages et des references
     lesReferences->Ecriture_base_info(*sortons,cas); // Ecriture des  references
     lesCourbes1D->Ecriture_base_info(*sortons,cas); // Ecriture des  courbes1D
     lesFonctionsnD->Ecriture_base_info(*sortons,cas); // Ecriture des  fonctions nD
     lesLoisDeComp->Ecriture_base_info(*sortons,cas); // Ecriture des lois
     diversStockage->Ecriture_base_info(*sortons,cas);  // Ecriture des stockages divers
     charge->Ecriture_base_info(*sortons,cas);  // Ecriture des actions exterieurs de chargement
     lesCondlim->Ecriture_base_info(*sortons,cas);  // Ecriture des ddl bloques
     lesContacts->Ecri_base_info_LesContacts(*sortons);  // Ecriture des contacts éventuelles
     resultats->Ecri_result_base_info(*sortons,cas);  // Ecriture des parametres de gestion de la sortie des resultats

   #ifdef UTILISATION_MPI
    #ifdef MISE_AU_POINT
     // normalement le buffer doit-être vide ! on vérifie
     string toto(sort.str());
     if (toto.size())
       {cout << "\n *** sans doute une erreur, le buffer toto devrait etre vide !! "
             << "\n  Algori::Ecriture_base_info(..."
             << "\n  toto = " << toto << endl;
        Sortie(1);
       };
    #endif
    
     // si MPI on calcul les offsets pour l'écriture réelle en MPI IO
     // et on transmet aux proc i
     Calcul_offsets_IO_MPI(cas,lesMaillages,lesReferences,lesCourbes1D
                        ,lesFonctionsnD,lesLoisDeComp,diversStockage
                        ,charge,lesCondlim,lesContacts,resultats
                        ,type_incre,incre);
     // on écrit les offsets et des buffers propres à Algo ref
     Ecriture_offset_et_buffersAlgoRef_base_info_MPI_IO(cas);
     // on sort sur fichier les buffers de toutes les classes principales
     Ecriture_base_info_MPI_IO(cas,lesMaillages,lesReferences,lesCourbes1D
                                ,lesFonctionsnD,lesLoisDeComp,diversStockage
                                ,charge,lesCondlim,lesContacts,resultats
                                ,type_incre,incre);
   #endif

   //  cout << "\n écriture terminée !!";
    };
  tempsSauvegarde.Arret_du_comptage(); // temps cpu
 };

#ifdef UTILISATION_MPI
  // calcul des offsets pour la préparation à l'utilisation de MPI IO
  // et transmission au proc i
  void Algori::Calcul_offsets_IO_MPI
            (int cas,LesMaillages *lesMaillages,
             LesReferences* lesReferences,LesCourbes1D* lesCourbes1D,
             LesFonctions_nD*  lesFonctionsnD,
             LesLoisDeComp*   lesLoisDeComp,
             DiversStockage* diversStockage,Charge* charge,
             LesCondLim* lesCondlim,LesContacts* lesContacts,Resultats* resultats,
             OrdreVisu::EnumTypeIncre type_incre,int incre)
 {  int proc_en_cours = ParaGlob::Monde()->rank();
    tailles_buffer_ioBI_MPI.resize(2);
    if (proc_en_cours == 0)
     { // concernant l'algo de ref
       tailles_buffer_ioBI_MPI[0] = buffer_ioBI_MPI(1).size();
       tailles_buffer_ioBI_MPI[1] = buffer_ioBI_MPI(2).size();
     };
    // puis les offsets pour toutes les classes principales
    // tous les proc doivent y passer mais seul le proc 0 comptabilise
    MPI_Offset taille_buf_lesMaillage = lesMaillages->Taille_buffer_sortie_BI(); // pour tous les proc
    MPI_Offset taille_buf_lesReferences = lesReferences->Taille_buffer_sortie_BI();
    MPI_Offset taille_buf_lesCourbes1D = lesCourbes1D->Taille_buffer_sortie_BI();
    MPI_Offset taille_buf_lesFonctionsnD = lesFonctionsnD->Taille_buffer_sortie_BI();
    MPI_Offset taille_buf_lesLoisDeComp = lesLoisDeComp->Taille_buffer_sortie_BI();
    MPI_Offset taille_buf_diversStockage = diversStockage->Taille_buffer_sortie_BI();
    MPI_Offset taille_buf_charge = charge->Taille_buffer_sortie_BI();
    MPI_Offset taille_buf_lesCondlim = lesCondlim->Taille_buffer_sortie_BI();
    MPI_Offset taille_buf_lesContacts = lesContacts->Taille_buffer_sortie_BI();
    MPI_Offset taille_buf_resultats = resultats->Taille_buffer_sortie_BI();

    
    posi_buffer.resize(13); // cf. .h
    if (proc_en_cours == 0)
     {switch (cas)
      { case 1 : // cas de l'incrément 0: c'est donc la première sortie
          {posi_buffer[0] = entreePrinc->OffsetPosition(0); // début du fichier
           break;
          }
        case 2: // cas d'un incrément courant,
          {// la position de début d'enregistrement a été sauvegardée via
           // entreePrinc->Enregistrement_position_increment_base_info
           // en début de Algori::Ecriture_base_info, on récupère cette position
           posi_buffer[0] =  entreePrinc->OffsetPosition(incre);
           break;
          }
      };
      // on intègre la taille de l'ensemble des offsets:
      MPI_Offset taille_entete = 34 + 27 + 2*21 +(13)*21+20; // cf. Ecriture_offset_et_buffersAlgoRef_base_info_MPI_IO
      posi_buffer[1] = posi_buffer[0] + tailles_buffer_ioBI_MPI[0] + taille_entete;
      //NB: posi_buffer[1] correspond à la position du début du deuxième buffer
      // le premier buffer se situe juste après posi_buffer[0]
      // puis il y a l'entête
      // puis le second buffer
      posi_buffer[2] = posi_buffer[1] + tailles_buffer_ioBI_MPI[1];
      // position après les maillages
      posi_buffer[3] = posi_buffer[2] + taille_buf_lesMaillage;
      // après les références
      posi_buffer[4] = posi_buffer[3] + taille_buf_lesReferences;
      // après les courbes 1D
      posi_buffer[5] = posi_buffer[4] + taille_buf_lesCourbes1D;
      // après les fonctions nD
      posi_buffer[6] = posi_buffer[5] + taille_buf_lesFonctionsnD;
      // après les lois de comp
      posi_buffer[7] = posi_buffer[6] + taille_buf_lesLoisDeComp;
      // après diversStockage
      posi_buffer[8] = posi_buffer[7] + taille_buf_diversStockage;
      // après charge
      posi_buffer[9] = posi_buffer[8] + taille_buf_charge;
      // après charge
      posi_buffer[10] = posi_buffer[9] + taille_buf_lesCondlim;
      // après lesContacts
      posi_buffer[11] = posi_buffer[10] + taille_buf_lesContacts;
      // après resultats
      posi_buffer[12] = posi_buffer[11] + taille_buf_resultats;

     };

       
       //******** à suivre pour les autres classes principales

    // on transmet aux proc i
    broadcast(*ParaGlob::Monde(), tailles_buffer_ioBI_MPI, 0);
    broadcast(*ParaGlob::Monde(), posi_buffer, 0);
    
    // on met à jour les offsets de chaque classe générale
    // pour tous les proc car posi_buffer a été broadcasté
    lesMaillages->Mise_a_jour_Offset_BI_ecriture(posi_buffer[2],cas);
    lesReferences->Mise_a_jour_Offset_BI_ecriture(posi_buffer[3],cas);
    lesCourbes1D->Mise_a_jour_Offset_BI_ecriture(posi_buffer[4],cas);
    lesFonctionsnD->Mise_a_jour_Offset_BI_ecriture(posi_buffer[5],cas);
    lesLoisDeComp->Mise_a_jour_Offset_BI_ecriture(posi_buffer[6],cas);
    diversStockage->Mise_a_jour_Offset_BI_ecriture(posi_buffer[7],cas);
    charge->Mise_a_jour_Offset_BI_ecriture(posi_buffer[8],cas);
    lesCondlim->Mise_a_jour_Offset_BI_ecriture(posi_buffer[9],cas);
    lesContacts->Mise_a_jour_Offset_BI_ecriture(posi_buffer[10],cas);
    resultats->Mise_a_jour_Offset_BI_ecriture(posi_buffer[11],cas);


//     Tableau <std::string > buffer_ioBI_MPI; // les buffers pour la sortie retardée
//     std::vector<int>  tailles_buffer_ioBI_MPI; // les tailles qui sont transmises par proc 0
// std::vector<int> posi_buffer; // positions pour chaque classe principale
// 0 : début de l'incrément, puis les débuts de:
// 1 algo, 2 lesMaillages, 3 lesReferences, 4 lesCourbes1D, 5 lesFonctionsnD
// 6 lesLoisDeComp, 7 diversStockage, 8 charge, 9 lesCondlim,
// 10 lesContacts, 11 resultats, 12 fin enreg (offset de début de l'incre suivant)




 };

// écriture des offsets MPI des infos bufferisées
void Algori::Ecriture_offset_et_buffersAlgoRef_base_info_MPI_IO(const int cas)
   { int proc_en_cours = ParaGlob::Monde()->rank();
     // concerne uniquement le proc 0
     if (proc_en_cours == 0)
      { MPI_File * sort_MPI = entreePrinc->Sort_BI(); // récup du fichier
      
//// --- test debug
//if (*sort_MPI == MPI_FILE_NULL)
//   cout << "\n la il y a vraiment un pb !! MPI_file " << (*sort_MPI) << endl;
//{MPI_Status status; // pour le retour
// int ierr = MPI_File_write(*sort_MPI,"toto",4,MPI_CHAR,&status);
//        if (ierr)
//          {cout << "\n *** erreur d'acces a MPI_File_write: code " << ierr << " , stop Herezh "
//                << "\n Algori::Ecriture_offset_et_buffersAlgoRef_base_info_MPI_IO(..." << endl;
//           Sortie(1);
//          };
//}
////--- fin test debug

        //  === écriture dans flot string de la taille des buffers propres à algo ref
        // et de la taille du vector posi_buffer
        // pour avoir une sortie lisible, on crée tout d'abord un buffer string avec les infos
        std::ostringstream buf2(std::ios_base::out);
        buf2 << "\n offset_base_info_MPI_IO \n"; // 27 char
        MPI_Offset taille_tailles_buffer_ioBI_MPI = tailles_buffer_ioBI_MPI.size(); // c'est 2
        #ifdef MISE_AU_POINT
         if (taille_tailles_buffer_ioBI_MPI != 2)
           {cout << "\n *** sans doute une erreur, taille_offset "<<taille_tailles_buffer_ioBI_MPI
                 << " est  different de 2 "
                 << "\n  Algori::Ecriture_offset_et_buffersAlgoRef_base_info_MPI_IO(..." << endl;
            Sortie(1);
           };
        #endif
        for (MPI_Offset i=0;i < taille_tailles_buffer_ioBI_MPI;i++)
          // on sort donc (2)*21 char
          buf2 << std::right << setw(20) << tailles_buffer_ioBI_MPI[i] << " ";
        // puis la taille de posi_buffer
        MPI_Offset taille_posi_buffer = posi_buffer.size();
        buf2 << "\n posi_buffer_algo \n"; // 20 char
        for (MPI_Offset i=0; i < taille_posi_buffer ; i++) // normalement == 13
          // on sort 13*21 char
          buf2 << std::right << setw(20) << posi_buffer[i] << " ";
         
        // le buffer du stream n'est pas pérenne il faut le récupérer
        string buf_inter = buf2.str(); // on récupère le buffer
        MPI_Offset taille_buf = buf_inter.size();
        #ifdef MISE_AU_POINT
         if (taille_buf != 27 + 2*21 +(13)*21+20)
           {cout << "\n *** sans doute erreur, taille_buf "<<taille_buf
                 << " est  different de  27 + 2*21 +(13)*21+20 ="<< 27 + 2*21 +(13)*21+20
                 << "\n  Algori::Ecriture_offset_et_buffersAlgoRef_base_info_MPI_IO(..." << endl;
            Sortie(1);
           };
        #endif

        // 1) ==== on écrit d'abord le buffer 1 qui correspond à l'entête
        //         qui contient le numéro d'incrément, qui est en fait le marqueur
        //         qui permet le positionnement initiale de manière indépendante des offsets stockés
        { MPI_Status status; // pour le retour
          int ierr = MPI_File_write(*sort_MPI,buffer_ioBI_MPI(1).c_str()
                                       ,buffer_ioBI_MPI(1).size(),MPI_CHAR,&status);
          if (ierr)
              {cout << "\n *** erreur d'acces a MPI_File_write: code " << ierr << " , stop Herezh "
                    << "\n ecriture du premier buffer "
                    << "\n Algori::Ecriture_offset_et_buffersAlgoRef_base_info_MPI_IO(..." << endl;
               Sortie(1);
              };
        };
        // 2) ==== écriture de la taille de l'ensemble des offsets propres à Algo ref
        // on encapsule pour ré-utiliser la même trame
        {
          std::ostringstream bufdeb(std::ios_base::out);
          bufdeb << "\noffset_algo "; // 13 char
          bufdeb << std::right << setw(20) << taille_buf << " "; // 21 char
          string buf_inter2 = bufdeb.str(); // normalement 34 char
          MPI_Offset taille_buf_inter2 = buf_inter2.size();
          #ifdef MISE_AU_POINT
           if (taille_buf_inter2 != 34)
             {cout << "\n *** sans doute erreur, taille_buf_inter2 "<<taille_buf_inter2
                   << " est  different de  34 "
                   << "\n  Algori::Ecriture_offset_et_buffersAlgoRef_base_info_MPI_IO(..." << endl;
              Sortie(1);
             };
          #endif
          // sortie sur fichier de la taille de buf2
          MPI_Status status; // pour le retour
          int ierr = MPI_File_write(*sort_MPI,buf_inter2.c_str(),34,MPI_CHAR,&status);
          if (ierr)
            {cout << "\n *** erreur d'acces a MPI_File_write: code " << ierr << " , stop Herezh "
                  << "\n Algori::Ecriture_offset_et_buffersAlgoRef_base_info_MPI_IO(..." << endl;
             Sortie(1);
            };

        };

        // 3) ==== écriture de la taille des buffers propres à Algo ref
        //    et de la taille de posi_buffer et de posi_buffer lui-même
        { // sortie sur fichier de buf2
          MPI_Status status; // pour le retour
          int ierr = MPI_File_write(*sort_MPI,buf_inter.c_str(),taille_buf,MPI_CHAR,&status);
          if (ierr)
            {cout << "\n *** erreur d'acces a MPI_File_write: code " << ierr << " , stop Herezh "
                  << "\n Algori::Ecriture_offset_et_buffersAlgoRef_base_info_MPI_IO(..." << endl;
             Sortie(1);
            };
        };

        // 4) ==== écriture des buffers propres à Algo ref, sauf le premier
        //         qui a déjà été écrit en préambule
        { MPI_Status status; // pour le retour
          for (MPI_Offset i=2;i<= 2;i++)
           {int ierr = MPI_File_write(*sort_MPI,buffer_ioBI_MPI(i).c_str()
                                       ,buffer_ioBI_MPI(i).size(),MPI_CHAR,&status);
            if (ierr)
              {cout << "\n *** erreur d'acces a MPI_File_write: code " << ierr << " , stop Herezh "
                    << "\n ecriture du buffer "<< i
                    << "\n Algori::Ecriture_offset_et_buffersAlgoRef_base_info_MPI_IO(..." << endl;
               Sortie(1);
              };
           };
        };
      };
   };
   
// Lecture des offsets MPI des infos bufferisées
void Algori::Lecture_offset_base_info_MPI_IO(const int cas)
  {// on commence par lire la taille du buffer d'offset
   MPI_File * ent_MPI = entreePrinc->Ent_BI(); // récup du fichier
   // tous les proc lisent
   
   // 1) ==== la taille de l'ensemble des offsets propres à Algo ref
   MPI_Offset taille_buf = 0; // init
   // on encapsule pour ré-utiliser la même trame
   { char * buffer_car = new char [34] ; // def du tableau de travail
     MPI_Status status;
//     int ierr = MPI_File_read_all(*ent_MPI, buffer_car, 34, MPI_CHAR, &status);
     int ierr = MPI_File_read(*ent_MPI, buffer_car, 34, MPI_CHAR, &status);
     // on crée un flux sur le tableau de caractères:
     istrstream * ent_inter = new istrstream(buffer_car,34) ;
     // lecture de l'entête
     string toto;
     (*ent_inter) >> toto;
     if (toto != "offset_algo" )
       {cout << "\n **** erreur on devait lire : 'offset_algo' "
             << " et on lue "<< toto << " la suite n'est pas possible -> arret !! "
             << "\n Algori::Lecture_offset_base_info_MPI_IO(... "<<endl;
        Sortie(1);
       };
     // on lit la taille de buf2
     (*ent_inter) >> taille_buf;
   };
   // 2) ==== lecture de la taille des buffers propres à Algo ref
   //    et de la taille de posi_buffer et de posi_buffer lui-même
   { char * buffer_car = new char [taille_buf] ; // def du tableau de travail
     MPI_Status status;
     int ierr = MPI_File_read_all(*ent_MPI, buffer_car, taille_buf, MPI_CHAR, &status);
     // on crée un flux sur le tableau de caractères:
     istrstream * ent_inter = new istrstream(buffer_car,taille_buf) ;
     // lecture de l'entête
     string toto;
     (*ent_inter) >> toto;
     if (toto != "offset_base_info_MPI_IO" )
       {cout << "\n **** erreur on devait lire : 'offset_base_info_MPI_IO' "
             << " et on lue "<< toto << " la suite n'est pas possible -> arret !! "
             << "\n Algori::Lecture_offset_base_info_MPI_IO(... "<<endl;
        Sortie(1);
       };
     // on lit les tailles des buffers
     tailles_buffer_ioBI_MPI.resize(2);
     for (MPI_Offset i = 0; i < 2; i++)
       (*ent_inter) >> tailles_buffer_ioBI_MPI[i];
     // puis posi_buffer
     MPI_Offset taille_posi_buffer = 13;
     (*ent_inter) >> toto;
     if (toto != "posi_buffer_algo" )
       {cout << "\n **** erreur on devait lire : 'posi_buffer_algo' "
             << " et on lue "<< toto << " la suite n'est pas possible -> arret !! "
             << "\n Algori::Lecture_base_info(... "<<endl;
        Sortie(1);
       };
     posi_buffer.resize(taille_posi_buffer);
     // puis lecture de posi_buffer
     for (MPI_Offset i=0; i < taille_posi_buffer ; i++)
       (*ent_inter) >> posi_buffer[i];
   };

  };

// écriture MPI des infos bufferisées
void Algori::Ecriture_base_info_MPI_IO
          (int cas,LesMaillages *lesMaillages,
           LesReferences* lesReferences,LesCourbes1D* lesCourbes1D,
           LesFonctions_nD*  lesFonctionsnD,
           LesLoisDeComp*   lesLoisDeComp,
           DiversStockage* diversStockage,Charge* charge,
           LesCondLim* lesCondlim,LesContacts* lesContacts,Resultats* resultats,
           OrdreVisu::EnumTypeIncre type_incre,int incre)
  { // on passe en revue les classes principales
    MPI_File * sort_MPI = entreePrinc->Sort_BI(); // récup du fichier
    
    lesMaillages->Ecriture_base_info_MPI_IO(sort_MPI,cas); // Ecriture des maillages et des references
    lesReferences->Ecriture_base_info_MPI_IO(sort_MPI,cas);
    lesCourbes1D->Ecriture_base_info_MPI_IO(sort_MPI,cas);
    lesFonctionsnD->Ecriture_base_info_MPI_IO(sort_MPI,cas);
    lesLoisDeComp->Ecriture_base_info_MPI_IO(sort_MPI,cas);
    diversStockage->Ecriture_base_info_MPI_IO(sort_MPI,cas);
    charge->Ecriture_base_info_MPI_IO(sort_MPI,cas);
    lesCondlim->Ecriture_base_info_MPI_IO(sort_MPI,cas);
    lesContacts->Ecriture_base_info_MPI_IO(sort_MPI,cas);
    resultats->Ecriture_base_info_MPI_IO(sort_MPI,cas);
  
  };
   
#endif  // fin MPI



// visualisation intéractive via le standard vrml
// la fonction est virtuelle ce qui lui permet d'être éventuellement facilement surchargée
// dans les algorithmes dérivées
void Algori::Visu_vrml(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesReferences* lesReferences
                       ,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD
                       ,LesLoisDeComp* lesLoisDeComp,DiversStockage* diversStockage
                       ,Charge* charge,LesCondLim* lesCondLim,LesContacts* lesContacts
                       ,Resultats* resultats)
 {	// on gère les exceptions éventuelles en mettant le bloc sous surveillance
    try 
    {// écriture de l'en-tête
     if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
        cout << "\n ========  module de visualisation format vrml  ========\n";
     // -- on définit l'ensemble des incréments possibles, ceci sont stocké dans .BI
     // tout d'abord ouverture du fichier de restart si nécessaire
     entreePrinc->Ouverture_base_info("lecture");
     // récup du flot d'entrée 
//     ifstream * entrons = entreePrinc->Ent_BI();
     // def du conteneur des numéros d'incréments
     list <int> list_incre = entreePrinc->Liste_increment();
     // on informe l'instance de visualisation de la liste des incréments possibles
     visualise.List_increment_disponible(list_incre);
     // on informe l'instance de visualisation du nombre de maillages possibles
     // par défaut tous les maillages seront visualisés, ceci est descidé aussi ici
     visualise.List_maillage_disponible(lesMaillages->NbMaillage());     
     // on demande à l'utilisateur la liste d'incrément pour l'initialisation de la visualisation
     const list<int> & list_incre_init = visualise.List_balaie_init();
     // on balaie la liste d'initialisation
     list<int>::const_iterator itee,itetest,itee_fin = list_incre_init.end();
     list<int>::const_iterator iteedeb =list_incre_init.begin();
     OrdreVisu::EnumTypeIncre type_incre; // pour qualifier le type d'incrément
     for (itee = iteedeb;itee!= itee_fin; itee++)
       { int inc_lu = *itee; // pour + lisible
         // on se positionne à l'incrément voulu
         entreePrinc->Positionnement_base_info(inc_lu); 
         // on initialise les ordres disponibles 
         // par exemple pour les isovaleurs on définit la liste des isovaleurs disponibles 
         // et les extrémas 
         // tout d'abord on récupère les infos sauf pour l'incrément 0, 
         if (inc_lu != 0)
             Lecture_base_info(2,lesMaillages,lesReferences,lesCourbes1D,lesFonctionsnD,lesLoisDeComp,
                   diversStockage,charge,lesCondLim,lesContacts,resultats,-inc_lu);
         else // pour l'incrément 0 on a toutes les infos sauf qu'il faut mettre le temps courant à 0
             {pa.Modif_Temps(0.);ParaGlob::param->Mise_a_jour_TEMPS_COURANT();};
                                  
         // puis on initialise
         //    tout d'abord on définit le type d'incrément
         itetest = itee; itetest++;
         if (itee==iteedeb)  type_incre = OrdreVisu::PREMIER_INCRE;
         else if (itetest == itee_fin) type_incre = OrdreVisu::DERNIER_INCRE;
         else type_incre = OrdreVisu::INCRE_COURANT;
         // et on initialise
         bool fil_calcul = false; // ce n'est pas une sortie au fil du calcul
         visualise.Initialisation(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                       ,charge,lesCondLim,lesContacts,resultats,type_incre,inc_lu
                       ,listeVarGlob,listeVecGlob,fil_calcul);
        }               
     // maintemant on affiche les ordres possibles 
     // et tant que le retour est différent de -1 (= fin de la visulisation demandée) on boucle 
     while (visualise.OrdresPossible() != -1)
      { // récup de la list des incréments à balayer
        list<int> li_balaie = visualise.List_balaie();
        // initialisation de la sortie vrml (fichier)
        entreePrinc->Ouverture_fichier_principal_vrml();
        entreePrinc->Ouverture_fichier_legende_vrml();
        visualise.Contexte_debut_visualisation(); 
       
        // on balaie la liste et on visualise à chaque passe
        list<int>::iterator ik,ikfin=li_balaie.end();
        list<int>::iterator iktest,ikdeb=li_balaie.begin();
        for (ik=ikdeb;ik!=ikfin;ik++)
         {// récupération des information de l'incrément à visualiser
          // lorsque l'incrément est différent de 0 
          // la lecture de l'incrément 0 n'est pas possible car elle conduit à l'initialisation
          // du problème d'où des informations en double et éventuellement des disfonctionnements 
          // de structure
          // normalement la visualisation d'info relatives à l'incrément 0 est indépendante en
          // fait de l'incrément donc peuve être visualisée avec l'incrément courant
          if (*ik != 0)
           { // on repositionne le flot de lecture au début du fichier
             entreePrinc->Fermeture_base_info();
             entreePrinc->Ouverture_base_info("lecture");
             Lecture_base_info(2,lesMaillages,lesReferences,lesCourbes1D,lesFonctionsnD,lesLoisDeComp,
                   diversStockage,charge,lesCondLim,lesContacts,resultats,*ik);
            }       
          else // pour l'incrément 0 on a toutes les infos sauf qu'il faut mettre le temps courant à 0
             {pa.Modif_Temps(0.);ParaGlob::param->Mise_a_jour_TEMPS_COURANT();};
          //   def du type d'incrément
          iktest = ik; iktest++;
          if (ik==ikdeb)  type_incre = OrdreVisu::PREMIER_INCRE;
          else if (iktest == ikfin) type_incre = OrdreVisu::DERNIER_INCRE;
          else type_incre = OrdreVisu::INCRE_COURANT;
          // appel du programme principal de visualisation
          visualise.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                       ,charge,lesCondLim,lesContacts,resultats,type_incre,*ik,listeVarGlob,listeVecGlob);
          }            
        
        // == définition des paramètres de fin de visualisation
        visualise.Contexte_fin_visualisation();                  
 
// -- maintenant n'est effectué qu'une seule fois à la fin du projet
//        // on ferme les sorties vrml (fichier) et appel éventuel du visualisateur
//        entreePrinc->Fermeture_fichier_principal_vrml();
//        entreePrinc->Fermeture_fichier_legende_vrml();
       }
     // fin de la visualisation
     if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
       cout << "\n ======== fin du module de visualisation format vrml  ========\n";
    }
    catch (ErrSortieFinale)
         // cas d'une direction voulue vers la sortie
         // on relance l'interuption pour le niveau supérieur
       { ErrSortieFinale toto;
         throw (toto);
       }
    catch ( ... )
       { if (ParaGlob::NiveauImpression() >= 1) 
           {cout << "\n **** warning: erreur en ecriture pour la visualisation interactive via le format vrml";
            if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
              cout <<  "\n Algori::Visu_vrml(..";
            cout << endl;
            };
        };                
   };               
               

// visualisation intéractive via le standard maple ou gnuplot
// la fonction est virtuelle ce qui lui permet d'être éventuellement facilement surchargée
// dans les algorithmes dérivées
void Algori::Visu_maple(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesReferences* lesReferences
                       ,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD
                       ,LesLoisDeComp* lesLoisDeComp,DiversStockage* diversStockage
                       ,Charge* charge,LesCondLim* lesCondLim,LesContacts* lesContacts
                       ,Resultats* resultats)
 {	// on gère les exceptions éventuelles en mettant le bloc sous surveillance
    try 
    {// écriture de l'en-tête
     if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
        cout << "\n ========  module de visualisation par fichiers de points au format maple  ========\n";
     // -- on définit l'ensemble des incréments possibles, ceci sont stocké dans .BI
     // tout d'abord ouverture du fichier de restart si nécessaire
     entreePrinc->Ouverture_base_info("lecture");
     // récup du flot d'entrée 
//     ifstream * entrons = entreePrinc->Ent_BI();
     // def du conteneur des numéros d'incréments
     list <int> list_incre = entreePrinc->Liste_increment();
     // on informe l'instance de visualisation de la liste des incréments possibles
     visualise_maple.List_increment_disponible(list_incre);
     // on informe l'instance de visualisation du nombre de maillages possibles
     // par défaut tous les maillages seront visualisés, ceci est descidé aussi ici
     visualise_maple.List_maillage_disponible(lesMaillages->NbMaillage());
     // on demande à l'utilisateur la liste d'incrément pour l'initialisation de la visualisation
     const list<int> & list_incre_init = visualise_maple.List_balaie_init();
     // on balaie la liste d'initialisation
     list<int>::const_iterator itee,itetest,itee_fin = list_incre_init.end();
     list<int>::const_iterator iteedeb =list_incre_init.begin();
     OrdreVisu::EnumTypeIncre type_incre; // pour qualifier le type d'incrément
     // dans le cas où il n'y a aucun incrément disponible, on ne peut pas initialiser dans ce cas
     // il faut arrêter et mettre un message
     if (iteedeb == itee_fin)
      { cout << "\n warning !! il n'y a pas d'increment sauvegarde, dans ce cas"
             << " l'initialisation des differentes grandeurs disponibles pour le post-traitement "
             << " n'est pas disponible, **** la suite n'est pas possible *** "
             << " une solution est de relancer le calcul a minima sur un increment, puis faire au moins"
             << " une sauvegarde via le parametre de controle SAUVEGARDE " << endl;
        return;
      };
     
     for (itee = iteedeb;itee!= itee_fin; itee++)
       { int inc_lu = *itee; // pour + lisible
         // on se positionne à l'incrément voulu
         entreePrinc->Positionnement_base_info(inc_lu); 
         // on initialise les ordres disponibles 
         // par exemple pour les isovaleurs on définit la liste des isovaleurs disponibles 
         // et les extrémas 
         // tout d'abord on récupère les infos sauf pour l'incrément 0
         if (inc_lu != 0)
             Lecture_base_info(2,lesMaillages,lesReferences,lesCourbes1D,lesFonctionsnD,lesLoisDeComp,
                   diversStockage,charge,lesCondLim,lesContacts,resultats,-inc_lu);
         else // pour l'incrément 0 on a toutes les infos sauf qu'il faut mettre le temps courant à 0
             {pa.Modif_Temps(0.);ParaGlob::param->Mise_a_jour_TEMPS_COURANT();};
         // puis on initialise
         //    tout d'abord on définit le type d'incrément
         itetest = itee; itetest++;
         if (itee==iteedeb)  type_incre = OrdreVisu::PREMIER_INCRE;
         else if (itetest == itee_fin) type_incre = OrdreVisu::DERNIER_INCRE;
         else type_incre = OrdreVisu::INCRE_COURANT;
         // et on initialise
         bool fil_calcul = false; // ce n'est pas une sortie au fil du calcul
         visualise_maple.Initialisation(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                       ,charge,lesCondLim,lesContacts,resultats,type_incre,inc_lu
                       ,listeVarGlob,listeVecGlob,fil_calcul);
        }               
     // maintemant on affiche les ordres possibles 
     // et tant que le retour est différent de -1 (= fin de la visulisation demandée) on boucle 
     while (visualise_maple.OrdresPossible() != -1)
      { // récup de la list des incréments à balayer
        list<int> li_balaie = visualise_maple.List_balaie();
        // initialisation de la maple (fichier)
        entreePrinc->Ouverture_fichier_principal_maple();
        // == définition des paramètres d'entête de visualisation 
        visualise_maple.Contexte_debut_visualisation(); 
       
        // on balaie la liste des incréments et on visualise_maple à chaque passe
        list<int>::iterator ik,ikfin=li_balaie.end();
        list<int>::iterator iktest,ikdeb=li_balaie.begin();
        for (ik=ikdeb;ik!=ikfin;ik++)
         {// récupération des information de l'incrément à visualiser
          // lorsque l'incrément est différent de 0 
          // la lecture de l'incrément 0 n'est pas possible car elle conduit à l'initialisation
          // du problème d'où des informations en double et éventuellement des disfonctionnements 
          // de structure
          // normalement la visualisation d'info relatives à l'incrément 0 est indépendante en
          // fait de l'incrément donc peuve être visualisée avec l'incrément courant
          if (*ik != 0)
           { // on repositionne le flot de lecture au début du fichier
             entreePrinc->Fermeture_base_info();
             entreePrinc->Ouverture_base_info("lecture");
             Lecture_base_info(2,lesMaillages,lesReferences,lesCourbes1D,lesFonctionsnD,lesLoisDeComp,
                   diversStockage,charge,lesCondLim,lesContacts,resultats,*ik);
            }       
          else // pour l'incrément 0 on a toutes les infos sauf qu'il faut mettre le temps courant à 0
             {pa.Modif_Temps(0.);ParaGlob::param->Mise_a_jour_TEMPS_COURANT();};
          //   def du type d'incrément
          iktest = ik; iktest++;
          if (ik==ikdeb)  type_incre = OrdreVisu::PREMIER_INCRE;
          else if (iktest == ikfin) type_incre = OrdreVisu::DERNIER_INCRE;
          else type_incre = OrdreVisu::INCRE_COURANT;
          // appel du programme principal de visualisation
          visualise_maple.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                  ,charge,lesCondLim,lesContacts,resultats,type_incre,*ik,listeVarGlob,listeVecGlob);
          }            
        
        // == définition des paramètres de fin de visualisation
        visualise_maple.Contexte_fin_visualisation();                  
 
// -- maintenant n'est effectué qu'une seule fois à la fin du projet
//        // on ferme la sortie maple (fichier) et appel éventuel du visualisateur
//        entreePrinc->Fermeture_fichier_principal_maple();
       }
     // fin de la visualisation
     if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
        cout << "\n ======== fin module de visualisation par fichiers de points au format maple  ========\n";
    }
    catch (ErrSortieFinale)
         // cas d'une direction voulue vers la sortie
         // on relance l'interuption pour le niveau supérieur
       { ErrSortieFinale toto;
         throw (toto);
       }
    catch ( ... )
       { if (ParaGlob::NiveauImpression() >= 1) 
           {cout << "\n **** warning: erreur en ecriture pour la visualisation interactive via le format maple";
            if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
               cout <<  "\n Algori::Visu_maple(..";
            cout << endl;
            };
        };                

   };               
               
// visualisation intéractive via geomview
// la fonction est virtuelle ce qui lui permet d'être éventuellement facilement surchargée
// dans les algorithmes dérivées
void Algori::Visu_geomview(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesReferences* lesReferences
                       ,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD
                       ,LesLoisDeComp* lesLoisDeComp,DiversStockage* diversStockage
                       ,Charge* charge,LesCondLim* lesCondLim,LesContacts* lesContacts
                       ,Resultats* resultats)
 {	// on gère les exceptions éventuelles en mettant le bloc sous surveillance
    try 
    {// écriture de l'en-tête
     if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
        cout << "\n ========  module de visualisation format geomview  ========\n";
     // -- on définit l'ensemble des incréments possibles, ceci sont stocké dans .BI
     // tout d'abord ouverture du fichier de restart si nécessaire
     entreePrinc->Ouverture_base_info("lecture");
     // récup du flot d'entrée 
//     ifstream * entrons = entreePrinc->Ent_BI();
     // def du conteneur des numéros d'incréments
     list <int> list_incre = entreePrinc->Liste_increment();
     // on informe l'instance de visualisation de la liste des incréments possibles
     visualise_geomview.List_increment_disponible(list_incre);
     // on informe l'instance de visualisation du nombre de maillages possibles
     // par défaut tous les maillages seront visualisés, ceci est descidé aussi ici
     visualise_geomview.List_maillage_disponible(lesMaillages->NbMaillage());     
     // on demande à l'utilisateur la liste d'incrément pour l'initialisation de la visualisation
     const list<int> & list_incre_init = visualise_geomview.List_balaie_init();
     // on balaie la liste d'initialisation
     list<int>::const_iterator itee,itetest,itee_fin = list_incre_init.end();
     list<int>::const_iterator iteedeb =list_incre_init.begin();
     OrdreVisu::EnumTypeIncre type_incre; // pour qualifier le type d'incrément
     // dans le cas où il n'y a aucun incrément disponible, on ne peut pas initialiser dans ce cas
     // il faut arrêter et mettre un message
     if (iteedeb == itee_fin)
      { cout << "\n warning !! il n'y a pas d'increment sauvegarde, dans ce cas"
             << " l'initialisation des differentes grandeurs disponibles pour le post-traitement "
             << " n'est pas disponible, **** la suite n'est pas possible *** "
             << " une solution est de relancer le calcul a minima sur un increment, puis faire au moins"
             << " une sauvegarde via le parametre de controle SAUVEGARDE " << endl;
        return;
      };
     
     for (itee = iteedeb;itee!= itee_fin; itee++)
       { int inc_lu = *itee; // pour + lisible
         // on se positionne à l'incrément voulu
         entreePrinc->Positionnement_base_info(inc_lu); 
         // on initialise les ordres disponibles 
         // par exemple pour les isovaleurs on définit la liste des isovaleurs disponibles 
         // et les extrémas 
         // tout d'abord on récupère les infos sauf pour l'incrément 0
         if (inc_lu != 0)
             Lecture_base_info(2,lesMaillages,lesReferences,lesCourbes1D,lesFonctionsnD,lesLoisDeComp,
                   diversStockage,charge,lesCondLim,lesContacts,resultats,-inc_lu);
         else // pour l'incrément 0 on a toutes les infos sauf qu'il faut mettre le temps courant à 0
             {pa.Modif_Temps(0.);ParaGlob::param->Mise_a_jour_TEMPS_COURANT();};
         // puis on initialise
         //    tout d'abord on définit le type d'incrément
         itetest = itee; itetest++;
         if (itee==iteedeb)  type_incre = OrdreVisu::PREMIER_INCRE;
         else if (itetest == itee_fin) type_incre = OrdreVisu::DERNIER_INCRE;
         else type_incre = OrdreVisu::INCRE_COURANT;
         // et on initialise
         bool fil_calcul = false; // ce n'est pas une sortie au fil du calcul
         visualise_geomview.Initialisation(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                       ,charge,lesCondLim,lesContacts,resultats,type_incre,inc_lu
                       ,listeVarGlob,listeVecGlob,fil_calcul);
        }               
     // maintemant on affiche les ordres possibles 
     // et tant que le retour est différent de -1 (= fin de la visulisation demandée) on boucle 
     while (visualise_geomview.OrdresPossible() != -1)
      { // récup de la list des incréments à balayer
        list<int> li_balaie = visualise_geomview.List_balaie();
        // initialisation de la sortie geomview (fichier)
        entreePrinc->Ouverture_fichier_principal_geomview();
        entreePrinc->Ouverture_fichier_legende_geomview();
        visualise_geomview.Contexte_debut_visualisation(); 
       
        // on balaie la liste et on visualise à chaque passe
        list<int>::iterator ik,ikfin=li_balaie.end();
        list<int>::iterator iktest,ikdeb=li_balaie.begin();
        for (ik=ikdeb;ik!=ikfin;ik++)
         {// récupération des information de l'incrément à visualiser
          // lorsque l'incrément est différent de 0 
          // la lecture de l'incrément 0 n'est pas possible car elle conduit à l'initialisation
          // du problème d'où des informations en double et éventuellement des disfonctionnements 
          // de structure
          // normalement la visualisation d'info relatives à l'incrément 0 est indépendante en
          // fait de l'incrément donc peuve être visualisée avec l'incrément courant
          if (*ik != 0)
           { // on repositionne le flot de lecture au début du fichier
             entreePrinc->Fermeture_base_info();
             entreePrinc->Ouverture_base_info("lecture");
             Lecture_base_info(2,lesMaillages,lesReferences,lesCourbes1D,lesFonctionsnD,lesLoisDeComp,
                   diversStockage,charge,lesCondLim,lesContacts,resultats,*ik);
            }       
          else // pour l'incrément 0 on a toutes les infos sauf qu'il faut mettre le temps courant à 0
              {pa.Modif_Temps(0.);ParaGlob::param->Mise_a_jour_TEMPS_COURANT();};
          //   def du type d'incrément
          iktest = ik; iktest++;
          if (ik==ikdeb)  type_incre = OrdreVisu::PREMIER_INCRE;
          else if (iktest == ikfin) type_incre = OrdreVisu::DERNIER_INCRE;
          else type_incre = OrdreVisu::INCRE_COURANT;

          // temps cpu: passage des temps cpu de leur format natif à un tableau interne de double utilisé
          Temps_CPU_HZpp_to_lesTempsCpu(*lesCondLim,*charge,*lesContacts); // pour la visualisation de grandeurs globales

          // passage aux noeuds éventuellement des grandeurs globales, pour une sortie de post-traitement par exemple
          // le principe est que ce passage s'effectue si les conteneurs existent au niveau des noeuds
          // les conteneurs doivent donc avoir été définis dans la phase précédente d'initialisation et de lecture
          // a priori n'est disponible que lors d'une visualisation au fil du calcul
          Passage_aux_noeuds_grandeurs_globales(lesMaillages);
         
          // passage éventuel de scalaire à vecteur au niveau des noeuds
          lesMaillages->PassageInterneDansNoeud_composantes_vers_vectorielles();

          // appel du programme principal de visualisation
          visualise_geomview.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                       ,charge,lesCondLim,lesContacts,resultats,type_incre,*ik
                       ,listeVarGlob,listeVecGlob);
          }            
        
        // == définition des paramètres de fin de visualisation
        visualise_geomview.Contexte_fin_visualisation();                  
 
// -- maintenant n'est effectué qu'une seule fois à la fin du projet
//        // on ferme les sorties geomview (fichier) et appel éventuel du visualisateur
//        entreePrinc->Fermeture_fichier_principal_geomview();
//        entreePrinc->Fermeture_fichier_legende_geomview();
       }
     // fin de la visualisation
     if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
        cout << "\n ======== fin du module de visualisation format geomview  ========\n";
    }
    catch (ErrSortieFinale)
         // cas d'une direction voulue vers la sortie
         // on relance l'interuption pour le niveau supérieur
       { ErrSortieFinale toto;
         throw (toto);
       }
    catch ( ... )
       { if (ParaGlob::NiveauImpression() >= 1) 
           {cout << "\n **** warning: erreur en ecriture pour la visualisation interactive via le format geomview";
            if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
               cout <<  "\n Algori::Visu_geomview(..";
            cout << endl;
            };
        };                

   };  
                
// visualisation intéractive via Gid
// la fonction est virtuelle ce qui lui permet d'être éventuellement facilement surchargée
// dans les algorithmes dérivées
void Algori::Visu_Gid(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesReferences* lesReferences
                       ,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD
                       ,LesLoisDeComp* lesLoisDeComp,DiversStockage* diversStockage
                       ,Charge* charge,LesCondLim* lesCondLim,LesContacts* lesContacts
                       ,Resultats* resultats)
 {	// on gère les exceptions éventuelles en mettant le bloc sous surveillance
    try 
    {// écriture de l'en-tête
     if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
        cout << "\n ========  module de visualisation format Gid  ========\n";
     // -- on définit l'ensemble des incréments possibles, ceci sont stocké dans .BI
     // tout d'abord ouverture du fichier de restart si nécessaire
     entreePrinc->Ouverture_base_info("lecture");
     // récup du flot d'entrée 
//     ifstream * entrons = entreePrinc->Ent_BI();
     // def du conteneur des numéros d'incréments
     list <int> list_incre = entreePrinc->Liste_increment();
     // on informe l'instance de visualisation de la liste des incréments possibles
     visualise_Gid.List_increment_disponible(list_incre);
     // on informe l'instance de visualisation du nombre de maillages possibles
     // par défaut tous les maillages seront visualisés, ceci est descidé aussi ici
     visualise_Gid.List_maillage_disponible(lesMaillages->NbMaillage());     
     // on demande à l'utilisateur la liste d'incrément pour l'initialisation de la visualisation
     const list<int> & list_incre_init = visualise_Gid.List_balaie_init();
     // on balaie la liste d'initialisation
     list<int>::const_iterator itee,itetest,itee_fin = list_incre_init.end();
     list<int>::const_iterator iteedeb =list_incre_init.begin();
     OrdreVisu::EnumTypeIncre type_incre; // pour qualifier le type d'incrément
     // dans le cas où il n'y a aucun incrément disponible, on ne peut pas initialiser dans ce cas
     // il faut arrêter et mettre un message
     if (iteedeb == itee_fin)
      { cout << "\n warning !! il n'y a pas d'increment sauvegarde, dans ce cas"
             << " l'initialisation des differentes grandeurs disponibles pour le post-traitement "
             << " n'est pas disponible, **** la suite n'est pas possible *** "
             << " une solution est de relancer le calcul a minima sur un increment, puis faire au moins"
             << " une sauvegarde via le parametre de controle SAUVEGARDE " << endl;
        return;
      };
     
     for (itee = iteedeb;itee!= itee_fin; itee++)
       { int inc_lu = *itee; // pour + lisible
         // on se positionne à l'incrément voulu
         entreePrinc->Positionnement_base_info(inc_lu); 
         // on initialise les ordres disponibles 
         // par exemple pour les isovaleurs on définit la liste des isovaleurs disponibles 
         // et les extrémas 
         // tout d'abord on récupère les infos sauf pour l'incrément 0
         if (inc_lu != 0)
             Lecture_base_info(2,lesMaillages,lesReferences,lesCourbes1D,lesFonctionsnD,lesLoisDeComp,
                   diversStockage,charge,lesCondLim,lesContacts,resultats,-inc_lu);
         else // pour l'incrément 0 on a toutes les infos sauf qu'il faut mettre le temps courant à 0
             {pa.Modif_Temps(0.);ParaGlob::param->Mise_a_jour_TEMPS_COURANT();};
         // puis on initialise
         //    tout d'abord on définit le type d'incrément
         itetest = itee; itetest++;
         if (itee==iteedeb)  type_incre = OrdreVisu::PREMIER_INCRE;
         else if (itetest == itee_fin) type_incre = OrdreVisu::DERNIER_INCRE;
         else type_incre = OrdreVisu::INCRE_COURANT;
         // et on initialise
         bool fil_calcul = false; // ce n'est pas une sortie au fil du calcul
         visualise_Gid.Initialisation(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                       ,charge,lesCondLim,lesContacts,resultats,type_incre,inc_lu
                       ,listeVarGlob,listeVecGlob,fil_calcul);
        }               
     // maintemant on affiche les ordres possibles 
     // et tant que le retour est différent de -1 (= fin de la visulisation demandée) on boucle 
     while (visualise_Gid.OrdresPossible() != -1)
      { // récup de la list des incréments à balayer
        list<int> li_balaie = visualise_Gid.List_balaie();
        // initialisation des  sorties Gid (fichier)
        entreePrinc->Ouverture_fichier_initial_Gid();
        entreePrinc->Ouverture_fichier_resultat_Gid();
        visualise_Gid.Contexte_debut_visualisation(); 
       
        // par défaut on sort l'incrément 0
        pa.Modif_Temps(0.);// pour l'incrément 0 on a toutes les infos sauf qu'il faut mettre le temps courant à 0
        ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
        visualise_Gid.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
              ,charge,lesCondLim,lesContacts,resultats,OrdreVisu::PREMIER_INCRE,0
              ,listeVarGlob,listeVecGlob);
        
        // on balaie la liste et on visualise à chaque passe
        list<int>::iterator ik,ikfin=li_balaie.end();
        list<int>::iterator iktest,ikdeb=li_balaie.begin();
        for (ik=ikdeb;ik!=ikfin;ik++)
         {// récupération des information de l'incrément à visualiser
          // lorsque l'incrément est différent de 0 
          // la lecture de l'incrément 0 n'est pas possible car elle conduit à l'initialisation
          // du problème d'où des informations en double et éventuellement des disfonctionnements 
          // de structure
          // normalement la visualisation d'info relatives à l'incrément 0 est indépendante en
          // fait de l'incrément donc peuve être visualisée avec l'incrément courant
          if (*ik != 0)
           { // on repositionne le flot de lecture au début du fichier
             entreePrinc->Fermeture_base_info();
             entreePrinc->Ouverture_base_info("lecture");
             Lecture_base_info(2,lesMaillages,lesReferences,lesCourbes1D,lesFonctionsnD,lesLoisDeComp,
                   diversStockage,charge,lesCondLim,lesContacts,resultats,*ik);
            };       
          //   def du type d'incrément
          iktest = ik; iktest++;
          if (ik==ikdeb)  type_incre = OrdreVisu::PREMIER_INCRE;
          else if (iktest == ikfin) type_incre = OrdreVisu::DERNIER_INCRE;
          else type_incre = OrdreVisu::INCRE_COURANT;

          // temps cpu: passage des temps cpu de leur format natif à un tableau interne de double utilisé
          Temps_CPU_HZpp_to_lesTempsCpu(*lesCondLim,*charge,*lesContacts); // pour la visualisation de grandeurs globales

          // passage aux noeuds éventuellement des grandeurs globales, pour une sortie de post-traitement par exemple
          // le principe est que ce passage s'effectue si les conteneurs existent au niveau des noeuds
          // les conteneurs doivent donc avoir été définis dans la phase précédente d'initialisation et de lecture
          // a priori n'est disponible que lors d'une visualisation au fil du calcul
          Passage_aux_noeuds_grandeurs_globales(lesMaillages);
         
          // passage éventuel de scalaire à vecteur au niveau des noeuds
          lesMaillages->PassageInterneDansNoeud_composantes_vers_vectorielles();

          // appel du programme principal de visualisation
          if (*ik != 0) // le cas 0 a déjà été réalisé par défaut avant la boucle
             visualise_Gid.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                       ,charge,lesCondLim,lesContacts,resultats,type_incre,*ik
                       ,listeVarGlob,listeVecGlob);
         ;}
        
        // == définition des paramètres de fin de visualisation
        visualise_Gid.Contexte_fin_visualisation();                  
 
// -- maintenant n'est effectué qu'une seule fois à la fin du projet
//        // on ferme les sorties Gid (fichier) et appel éventuel du visualisateur
//        entreePrinc->Fermeture_fichier_initial_Gid();
//        entreePrinc->Fermeture_fichier_resultat_Gid();
       }
     // fin de la visualisation
     if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
        cout << "\n ======== fin du module de visualisation format GID  ========\n";
    }
    catch (ErrSortieFinale)
         // cas d'une direction voulue vers la sortie
         // on relance l'interuption pour le niveau supérieur
       { ErrSortieFinale toto;
         throw (toto);
       }
    catch ( ... )
       { if (ParaGlob::NiveauImpression() >= 1) 
           {cout << "\n **** warning: erreur en ecriture pour la visualisation interactive via le format GID";
            if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
               cout <<  "\n Algori::Visu_Gid(..";
            cout << endl;
            };
        };                

   };               
                
// visualisation intéractive via Gmsh
// la fonction est virtuelle ce qui lui permet d'être éventuellement facilement surchargée
// dans les algorithmes dérivées
void Algori::Visu_Gmsh(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesReferences* lesReferences
                       ,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD
                       ,LesLoisDeComp* lesLoisDeComp,DiversStockage* diversStockage
                       ,Charge* charge,LesCondLim* lesCondLim,LesContacts* lesContacts
                       ,Resultats* resultats)
 {	// on gère les exceptions éventuelles en mettant le bloc sous surveillance
    try 
    {// écriture de l'en-tête
     if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
       cout << "\n ========  module de visualisation format Gmsh  ========\n";
     // -- on définit l'ensemble des incréments possibles, ceci sont stocké dans .BI
     // tout d'abord ouverture du fichier de restart si nécessaire
     entreePrinc->Ouverture_base_info("lecture");
     // récup du flot d'entrée 
//     ifstream * entrons = entreePrinc->Ent_BI();
     // def du conteneur des numéros d'incréments
     list <int> list_incre = entreePrinc->Liste_increment();
     // on informe l'instance de visualisation de la liste des incréments possibles
     visualise_Gmsh.List_increment_disponible(list_incre);
     // on informe l'instance de visualisation du nombre de maillages possibles
     // par défaut tous les maillages seront visualisés, ceci est descidé aussi ici
     visualise_Gmsh.List_maillage_disponible(lesMaillages->NbMaillage());     
     // on demande à l'utilisateur la liste d'incrément pour l'initialisation de la visualisation
     const list<int> & list_incre_init = visualise_Gmsh.List_balaie_init();
     // on balaie la liste d'initialisation
     list<int>::const_iterator itee,itetest,itee_fin = list_incre_init.end();
     list<int>::const_iterator iteedeb =list_incre_init.begin();
     OrdreVisu::EnumTypeIncre type_incre; // pour qualifier le type d'incrément
     // dans le cas où il n'y a aucun incrément disponible, on ne peut pas initialiser dans ce cas
     // il faut arrêter et mettre un message
     if (iteedeb == itee_fin)
      { cout << "\n warning !! il n'y a pas d'increment sauvegarde, dans ce cas"
             << " l'initialisation des differentes grandeurs disponibles pour le post-traitement "
             << " n'est pas disponible, **** la suite n'est pas possible *** "
             << " une solution est de relancer le calcul a minima sur un increment, puis faire au moins"
             << " une sauvegarde via le parametre de controle SAUVEGARDE " << endl;
        return;
      };
     
     for (itee = iteedeb;itee!= itee_fin; itee++)
       { int inc_lu = *itee; // pour + lisible
         // on se positionne à l'incrément voulu
         entreePrinc->Positionnement_base_info(inc_lu); 
         // on initialise les ordres disponibles 
         // par exemple pour les isovaleurs on définit la liste des isovaleurs disponibles 
         // et les extrémas 
         // tout d'abord on récupère les infos sauf pour l'incrément 0
         if (inc_lu != 0)
             Lecture_base_info(2,lesMaillages,lesReferences,lesCourbes1D,lesFonctionsnD,lesLoisDeComp,
                   diversStockage,charge,lesCondLim,lesContacts,resultats,-inc_lu);
         else // pour l'incrément 0 on a toutes les infos sauf qu'il faut mettre le temps courant à 0
            {pa.Modif_Temps(0.);ParaGlob::param->Mise_a_jour_TEMPS_COURANT();};
         // puis on initialise
         //    tout d'abord on définit le type d'incrément
         itetest = itee; itetest++;
         if (itee==iteedeb)  type_incre = OrdreVisu::PREMIER_INCRE;
         else if (itetest == itee_fin) type_incre = OrdreVisu::DERNIER_INCRE;
         else type_incre = OrdreVisu::INCRE_COURANT;
         // et on initialise
         bool fil_calcul = false; // ce n'est pas une sortie au fil du calcul
         visualise_Gmsh.Initialisation(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                       ,charge,lesCondLim,lesContacts,resultats,type_incre,inc_lu
                       ,listeVarGlob,listeVecGlob,fil_calcul);
        }               
     // maintemant on affiche les ordres possibles 
     // et tant que le retour est différent de -1 (= fin de la visulisation demandée) on boucle 
     while (visualise_Gmsh.OrdresPossible() != -1)
      { // récup de la list des incréments à balayer
        list<int> li_balaie = visualise_Gmsh.List_balaie();
        // initialisation des  sorties Gmsh (fichier)
        entreePrinc->Ouverture_fichier_initial_Gmsh();
        entreePrinc->CreationRepertoireResultat();
        entreePrinc->Ouverture_fichier_resultat_Gmsh(visualise_Gmsh.NomsTousLesGrandeursSortie());
        visualise_Gmsh.Contexte_debut_visualisation(); 
       
        // par défaut on sort l'incrément 0
        pa.Modif_Temps(0.);// pour l'incrément 0 on a toutes les infos sauf qu'il faut mettre le temps courant à 0
        ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
        visualise_Gmsh.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                       ,charge,lesCondLim,lesContacts,resultats,OrdreVisu::PREMIER_INCRE,0
                       ,listeVarGlob,listeVecGlob);
        
        // on balaie la liste et on visualise à chaque passe
        list<int>::iterator ik,ikfin=li_balaie.end();
        list<int>::iterator iktest,ikdeb=li_balaie.begin();
        for (ik=ikdeb;ik!=ikfin;ik++)
         {// récupération des information de l'incrément à visualiser
          // lorsque l'incrément est différent de 0 
          // la lecture de l'incrément 0 n'est pas possible car elle conduit à l'initialisation
          // du problème d'où des informations en double et éventuellement des disfonctionnements 
          // de structure
          // normalement la visualisation d'info relatives à l'incrément 0 est indépendante en
          // fait de l'incrément donc peuve être visualisée avec l'incrément courant
          if (*ik != 0)
           { // on repositionne le flot de lecture au début du fichier
             entreePrinc->Fermeture_base_info();
             entreePrinc->Ouverture_base_info("lecture");
             Lecture_base_info(2,lesMaillages,lesReferences,lesCourbes1D,lesFonctionsnD,lesLoisDeComp,
                   diversStockage,charge,lesCondLim,lesContacts,resultats,*ik);
            };       
          //   def du type d'incrément
          iktest = ik; iktest++;
          if (ik==ikdeb)  type_incre = OrdreVisu::PREMIER_INCRE;
          else if (iktest == ikfin) type_incre = OrdreVisu::DERNIER_INCRE;
          else type_incre = OrdreVisu::INCRE_COURANT;

          // temps cpu: passage des temps cpu de leur format natif à un tableau interne de double utilisé
          Temps_CPU_HZpp_to_lesTempsCpu(*lesCondLim,*charge,*lesContacts); // pour la visualisation de grandeurs globales
          
          // passage aux noeuds éventuellement des grandeurs globales, pour une sortie de post-traitement par exemple
          // le principe est que ce passage s'effectue si les conteneurs existent au niveau des noeuds
          // les conteneurs doivent donc avoir été définis dans la phase précédente d'initialisation et de lecture
          // a priori n'est disponible que lors d'une visualisation au fil du calcul
          Passage_aux_noeuds_grandeurs_globales(lesMaillages);
         
          // passage éventuel de scalaire à vecteur au niveau des noeuds
          lesMaillages->PassageInterneDansNoeud_composantes_vers_vectorielles();

          // appel du programme principal de visualisation
          if (*ik != 0) // le cas 0 a déjà été réalisé par défaut avant la boucle
             visualise_Gmsh.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                       ,charge,lesCondLim,lesContacts,resultats,type_incre,*ik
                       ,listeVarGlob,listeVecGlob);
          }            
        
        // == définition des paramètres de fin de visualisation
        visualise_Gmsh.Contexte_fin_visualisation();                  
 
// -- maintenant n'est effectué qu'une seule fois à la fin du projet
//        // on ferme les sorties Gmsh (fichier) et appel éventuel du visualisateur
//        entreePrinc->Fermeture_fichier_initial_Gmsh();
//        entreePrinc->Fermeture_TousLesFichiersResultats_Gmsh();
       }                
     // fin de la visualisation
     if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
        cout << "\n ======== fin du module de visualisation format Gmsh  ========\n";
    }
    catch (ErrSortieFinale)
         // cas d'une direction voulue vers la sortie
         // on relance l'interuption pour le niveau supérieur
       { ErrSortieFinale toto;
         throw (toto);
       }
    catch ( ... )
       { if (ParaGlob::NiveauImpression() >= 1) 
           {cout << "\n **** warning: erreur en ecriture pour la visualisation interactive via le format Gmsh";
            if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
               cout <<  "\n Algori::Visu_Gmsh(..";
            cout << endl;
            };
        };                

   };               
                              
// lecture et visualisation d'informations de visualisation dans un fichier de commande externe
void Algori::LectureCommandeVisu(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesReferences* lesReferences
                       ,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD
                       ,LesLoisDeComp* lesLoisDeComp,DiversStockage* diversStockage
                       ,Charge* charge,LesCondLim* lesCondLim,LesContacts* lesContacts
                       ,Resultats* resultats)
{ // on gère les exceptions éventuelles en mettant le bloc sous surveillance
  try 
  {// ouverture du fichier de commande en lecture
   entreePrinc->Ouverture_CommandeVisu("lecture");
   //    --- on se positionne au début valide du fichier
   bool debut = entreePrinc->PositionEtExisteCVisu("debut_fichier_commande_visu");
   if (!debut) // cas ou le mot clé de début de fichier n'existe pas
    { cout << "\n erreur en lecture du fichier de commande, on ne trouve pas le mot clee de debut de fichier"
           << " <debut_fichier_commande_visu>, le fichier est non valide";
      return;
     }
   // écriture de l'en-tête
 #ifdef UTILISATION_MPI
   // cas d'un  calcul //, seul le CPU 0 affiche
   if (ParaGlob::Monde()->rank() == 0)
 #endif
   if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
      cout << "\n ========  lecture du fichier de commande de visualisation  ========\n";
   // -- on définit l'ensemble des incréments possibles, ceci sont stocké dans .BI
   // tout d'abord ouverture du fichier de restart si nécessaire
   entreePrinc->Ouverture_base_info("lecture");
   // récup du flot d'entrée 
//   ifstream * entrons = entreePrinc->Ent_BI();
   // def du conteneur des numéros d'incréments
   list <int> list_incre = entreePrinc->Liste_increment();
   // on informe les instances  de visualisation de la liste des incréments possibles
   visualise.List_increment_disponible(list_incre);
   visualise_maple.List_increment_disponible(list_incre);
   visualise_geomview.List_increment_disponible(list_incre);
   visualise_Gid.List_increment_disponible(list_incre);
   visualise_Gmsh.List_increment_disponible(list_incre);
   // on informe les instances de visualisation du nombre de maillages possibles
   // par défaut tous les maillages seront visualisés, ceci est descidé aussi ici
   visualise.List_maillage_disponible(lesMaillages->NbMaillage());     
   visualise_maple.List_maillage_disponible(lesMaillages->NbMaillage());     
   visualise_geomview.List_maillage_disponible(lesMaillages->NbMaillage()); 
   visualise_Gid.List_maillage_disponible(lesMaillages->NbMaillage()); 
   visualise_Gmsh.List_maillage_disponible(lesMaillages->NbMaillage()); 
   // lecture éventuelle de la liste d'incrément, pour l'initialisation de la visualisation
   // indique le choix de la liste d'incrément à visualiser
   const list<int> * list_incre_init_inter; 
   // maintenant on fait une lecture éventuelle
   if (entreePrinc->PositionEtExisteCVisu("debut_list_increment"))
     { // cas où une liste existe -> lecture de la liste
       list_incre_init_inter = &(visualise.List_balaie_init(0));
      }
   else
     { // cas où pas de  liste -> on initialise à 0 et au dernier incrément si différent
       list_incre_init_inter = &(visualise.List_balaie_init(-1));
      }
//   const list<int> &  list_incre_init = * list_incre_init_inter;
   // on impose la liste pour les autres types de visualisation
   visualise_maple.List_balaie_init(*list_incre_init_inter);//list_incre_init);
   visualise_geomview.List_balaie_init(*list_incre_init_inter);//list_incre_init);
   visualise_Gid.List_balaie_init(*list_incre_init_inter);//list_incre_init);
   visualise_Gmsh.List_balaie_init(*list_incre_init_inter);//list_incre_init);
   // on balaie la liste d'initialisation
   list<int>::const_iterator itee,itetest,itee_fin = list_incre_init_inter->end(); //list_incre_init.end();
   list<int>::const_iterator iteedeb =list_incre_init_inter->begin(); //list_incre_init.begin();
   
   OrdreVisu::EnumTypeIncre type_incre; // pour qualifier le type d'incrément
   if (list_incre_init_inter->size()==0) // arrêt s'il n'y a aucun incrément à visualiser
     { cout << "\n ****************************************************"
            << "\n **** aucun increment enregistre a visualiser ! *****" 
            << "\n ****************************************************\n"; return;};
   for (itee = iteedeb;itee!= itee_fin; itee++)
       { int inc_lu = *itee; // pour + lisible
         // on se positionne à l'incrément voulu
         bool cherche_increment = true; // init par défaut
         if (inc_lu != 0) // pour l'incrément 0 on a toutes les infos
            cherche_increment= entreePrinc->Positionnement_base_info(inc_lu);
         //
         if (cherche_increment == false)
          { cout << "\n ****************************************************"
                 << "\n on n'a pas trouve l'increment= " << inc_lu << " ???"
                 << "\n on ne peut pas continuer la visualisation ! " 
                 << "\n ****************************************************";
            return;
          };
         // on initialise les ordres disponibles 
         // par exemple pour les isovaleurs on définit la liste des isovaleurs disponibles 
         // et les extrémas 
         // tout d'abord on récupère les infos sauf pour l'incrément 0
         if (inc_lu != 0)
             Lecture_base_info(2,lesMaillages,lesReferences,lesCourbes1D,lesFonctionsnD,lesLoisDeComp,
                   diversStockage,charge,lesCondLim,lesContacts,resultats,-inc_lu);
         else // pour l'incrément 0 on a toutes les infos sauf qu'il faut mettre le temps courant à 0
            {pa.Modif_Temps(0.);ParaGlob::param->Mise_a_jour_TEMPS_COURANT();};
         // puis on initialise
         //    tout d'abord on définit le type d'incrément
         itetest = itee; itetest++;
         if (itee==iteedeb)  type_incre = OrdreVisu::PREMIER_INCRE;
         else if (itetest == itee_fin) type_incre = OrdreVisu::DERNIER_INCRE;
         else type_incre = OrdreVisu::INCRE_COURANT;
         // et on initialise
         bool fil_calcul = false; // ce n'est pas une sortie au fil du calcul
         visualise.Initialisation(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                       ,charge,lesCondLim,lesContacts,resultats,type_incre,inc_lu
                       ,listeVarGlob,listeVecGlob,fil_calcul);
         visualise_maple.Initialisation(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                       ,charge,lesCondLim,lesContacts,resultats,type_incre,inc_lu
                       ,listeVarGlob,listeVecGlob,fil_calcul);
         visualise_geomview.Initialisation(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                       ,charge,lesCondLim,lesContacts,resultats,type_incre,inc_lu
                       ,listeVarGlob,listeVecGlob,fil_calcul);
         visualise_Gid.Initialisation(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                       ,charge,lesCondLim,lesContacts,resultats,type_incre,inc_lu
                       ,listeVarGlob,listeVecGlob,fil_calcul);
         visualise_Gmsh.Initialisation(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                       ,charge,lesCondLim,lesContacts,resultats,type_incre,inc_lu
                       ,listeVarGlob,listeVecGlob,fil_calcul);
        }               
   // on effectue la lecture des différents types de visualisation jusqu'à la fin du fichier de commande
   //    --- on verifie que le mot cle de fin de fichier existe
   if (!entreePrinc->PositionEtExisteCVisu("fin_fichier_commande_visu"))
    { cout << "\n erreur en lecture du fichier de commande, on ne trouve pas le mot clee de fin de fichier"
           << " <fin_fichier_commande_visu>, le fichier est non valide";
      return;
     }
   //    --- on se repositionne au début du fichier
   entreePrinc->PositionEtExisteCVisu("debut_fichier_commande_visu");
   entreePrinc->NouvelleDonneeCVisu();

   //    --- lecture
   try
    { while (strstr(entreePrinc->tablcarCVisu,"fin_fichier_commande_visu")==NULL)
       { visualise.Lecture_parametres_OrdreVisu(*entreePrinc);
         visualise_maple.Lecture_parametres_OrdreVisu(*entreePrinc);
         visualise_geomview.Lecture_parametres_OrdreVisu(*entreePrinc);    
         visualise_Gid.Lecture_parametres_OrdreVisu(*entreePrinc);    
         visualise_Gmsh.Lecture_parametres_OrdreVisu(*entreePrinc);    
        }
     }   
   // sortie anormale de la lecture  
   catch (UtilLecture::ErrNouvelleDonneeCVisu erreur)
         {  if ( erreur.lecture == 1) // on a atteind une fin de fichier
              { // fin de fichier atteind sans le mot clé de fin
                cout << "\n **** fin du fichier de commande de visualisation, atteinte sans le mot cle"
                     << " fin_fichier_commande_visu ! "
                     << "\n normalement ce mot cle doit finir le fichier, on continue quand meme, mais"
                     << "\n il y a peut-etre un probleme";
            if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
                cout  << "\n Algori::LectureCommandeVisu(..";
               } 
            else
              { // erreur en lecture
                cout << "\n **** ERREUR en lecture du fichier de  commande de visualisation "
                     << "\n on continue quand meme, mais il y aura peut-etre un probleme de coherence pour la suite";
               if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
                  cout  << "\n Algori::LectureCommandeVisu(..";
               }      
         }    
   catch (ErrSortieFinale)
        // cas d'une direction voulue vers la sortie
        // on relance l'interuption pour le niveau supérieur
      { ErrSortieFinale toto;
        throw (toto);
      }
   catch (...)// erreur inconnue
      {  cout << "\n **** ERREUR inconnuee en lecture du fichier de  commande de visualisation "
              << "\n on continue quand meme, mais il y aura peut-etre un probleme de coherence pour la suite";
         if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
             cout  << "\n Algori::LectureCommandeVisu(..";
      };
      
   // avertissement de la fin de lecture du fichier de commande
//   if (ParaGlob::NiveauImpression() >= 0)
 #ifdef UTILISATION_MPI
   // cas d'un  calcul //, pour l'instant seul le CPU 0 affiche
   if (ParaGlob::Monde()->rank() == 0)
 #endif
   if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
     cout << "\n ========  fin de la lecture du fichier de commande de visualisation  ========\n";
   // visualisation en fonction de l'activité des différents types de sortie
   // récup de la list des incréments à balayer
   list<int> li_balaie = visualise.List_balaie();
   // initialisation de la sortie vrml (fichier) si la sortie vrml est valide
   if (visualise.Visu_vrml_valide())
      { entreePrinc->Ouverture_fichier_principal_vrml();
        entreePrinc->Ouverture_fichier_legende_vrml();
        visualise.Contexte_debut_visualisation(); 
       }  
   // initialisation de la sortie maple (fichier) si la sortie geomview est valide
   if (visualise_maple.Visu_maple_valide())
      { // initialisation de la maple (fichier)
        entreePrinc->Ouverture_fichier_principal_maple();
        // == définition des paramètres d'entête de visualisation 
        visualise_maple.Contexte_debut_visualisation(); 
       }  
   // initialisation de la sortie geomview (fichier) si la sortie geomview est valide
   if (visualise_geomview.Visu_geomview_valide())
      { entreePrinc->Ouverture_fichier_principal_geomview();
        entreePrinc->Ouverture_fichier_legende_geomview();
        visualise_geomview.Contexte_debut_visualisation();
       }  
   // initialisation des  sorties Gid (fichier) si la sortie Gid est valide
   if (visualise_Gid.Visu_Gid_valide())
      { entreePrinc->Ouverture_fichier_initial_Gid();
        entreePrinc->Ouverture_fichier_resultat_Gid();
        visualise_Gid.Contexte_debut_visualisation();
       }
   // dans le cas ou la sortie gid est valide on sort par défaut l'incrément 0 
   if (visualise_Gid.Visu_Gid_valide())
       { pa.Modif_Temps(0.); // pour l'incrément 0 on a toutes les infos sauf qu'il faut mettre le temps courant à 0
         ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
         visualise_Gid.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                          ,charge,lesCondLim,lesContacts,resultats,OrdreVisu::PREMIER_INCRE,0
                          ,listeVarGlob,listeVecGlob);
       };
   // initialisation des  sorties Gmsh (fichier) si la sortie Gmsh est valide
   if (visualise_Gmsh.Visu_Gmsh_valide())
      { entreePrinc->Ouverture_fichier_initial_Gmsh();
        entreePrinc->CreationRepertoireResultat();
        entreePrinc->Ouverture_fichier_resultat_Gmsh(visualise_Gmsh.NomsTousLesGrandeursSortie());
        visualise_Gmsh.Contexte_debut_visualisation();
       }
   // dans le cas ou la sortie Gmsh est valide on sort par défaut l'incrément 0 
   if (visualise_Gmsh.Visu_Gmsh_valide())
       { pa.Modif_Temps(0.); // pour l'incrément 0 on a toutes les infos sauf qu'il faut mettre le temps courant à 0
         ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
         visualise_Gmsh.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                          ,charge,lesCondLim,lesContacts,resultats,OrdreVisu::PREMIER_INCRE,0
                          ,listeVarGlob,listeVecGlob);
       };
   // on balaie la liste et on visualise à chaque passe
   list<int>::iterator ik,ikfin=li_balaie.end();
   list<int>::iterator iktest,ikdeb=li_balaie.begin();
   for (ik=ikdeb;ik!=ikfin;ik++)
         {// récupération des information de l'incrément à visualiser
          // lorsque l'incrément est différent de 0 
          // la lecture de l'incrément 0 n'est pas possible car elle conduit à l'initialisation
          // du problème d'où des informations en double et éventuellement des disfonctionnements 
          // de structure
          // normalement la visualisation d'info relatives à l'incrément 0 est indépendante en
          // fait de l'incrément donc peuve être visualisée avec l'incrément courant
          if (*ik != 0)
           { // on repositionne le flot de lecture au début du fichier
             entreePrinc->Fermeture_base_info();
             entreePrinc->Ouverture_base_info("lecture");
             Lecture_base_info(2,lesMaillages,lesReferences,lesCourbes1D,lesFonctionsnD,lesLoisDeComp,
                   diversStockage,charge,lesCondLim,lesContacts,resultats,*ik);
            };       
           //   def du type d'incrément
          iktest = ik; iktest++;
          if (ik==ikdeb)  type_incre = OrdreVisu::PREMIER_INCRE;
          else if (iktest == ikfin) type_incre = OrdreVisu::DERNIER_INCRE;
          else type_incre = OrdreVisu::INCRE_COURANT;

          // temps cpu: passage des temps cpu de leur format natif à un tableau interne de double utilisé
          Temps_CPU_HZpp_to_lesTempsCpu(*lesCondLim,*charge,*lesContacts); // pour la visualisation de grandeurs globales

          // passage aux noeuds éventuellement des grandeurs globales, pour une sortie de post-traitement par exemple
          // le principe est que ce passage s'effectue si les conteneurs existent au niveau des noeuds
          // les conteneurs doivent donc avoir été définis dans la phase précédente d'initialisation et de lecture
          // a priori n'est disponible que lors d'une visualisation au fil du calcul
          Passage_aux_noeuds_grandeurs_globales(lesMaillages);
         
          // passage éventuel de scalaire à vecteur au niveau des noeuds
          lesMaillages->PassageInterneDansNoeud_composantes_vers_vectorielles();

          // appel du programme principal de visualisation
          if (visualise.Visu_vrml_valide())
               visualise.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                              ,charge,lesCondLim,lesContacts,resultats,type_incre,*ik
                              ,listeVarGlob,listeVecGlob);
          if (visualise_maple.Visu_maple_valide())
               visualise_maple.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                                      ,charge,lesCondLim,lesContacts,resultats,type_incre,*ik
                                      ,listeVarGlob,listeVecGlob);
          if (visualise_geomview.Visu_geomview_valide())
              visualise_geomview.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                                      ,charge,lesCondLim,lesContacts,resultats,type_incre,*ik
                                      ,listeVarGlob,listeVecGlob);
          if ((visualise_Gid.Visu_Gid_valide())&&(*ik != 0)) // le cas ik == 0 a déjà été étudié
              visualise_Gid.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                                      ,charge,lesCondLim,lesContacts,resultats,type_incre,*ik
                                      ,listeVarGlob,listeVecGlob);
          if ((visualise_Gmsh.Visu_Gmsh_valide())&&(*ik != 0)) // le cas ik == 0 a déjà été étudié
              visualise_Gmsh.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                                      ,charge,lesCondLim,lesContacts,resultats,type_incre,*ik
                                      ,listeVarGlob,listeVecGlob);
          }            
        
   // == définition des paramètres de fin de visualisation
   if (visualise.Visu_vrml_valide())
      { visualise.Contexte_fin_visualisation();                  
// -- maintenant n'est effectué qu'une seule fois à la fin du projet
//        // on ferme les sorties vrml (fichier) et appel éventuel du visualisateur
//        entreePrinc->Fermeture_fichier_principal_vrml();
//        entreePrinc->Fermeture_fichier_legende_vrml();
        // fin de la visualisation
        if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
           cout << "\n ======== fin du module de visualisation format vrml  ========\n";
       } 
   if (visualise_maple.Visu_maple_valide())
       {// == définition des paramètres de fin de visualisation
        visualise_maple.Contexte_fin_visualisation();                  
// -- maintenant n'est effectué qu'une seule fois à la fin du projet
//        // on ferme la sortie maple (fichier) et appel éventuel du visualisateur
//        entreePrinc->Fermeture_fichier_principal_maple();
        // fin de la visualisation
        if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
           cout << "\n ======== fin module de visualisation par fichiers de points au format maple  ========\n";
        }
   if (visualise_geomview.Visu_geomview_valide()) 
      { visualise_geomview.Contexte_fin_visualisation();                  
// -- maintenant n'est effectué qu'une seule fois à la fin du projet
//        // on ferme les sorties geomview (fichier) et appel éventuel du visualisateur
//        entreePrinc->Fermeture_fichier_principal_geomview();
//        entreePrinc->Fermeture_fichier_legende_geomview();
        // fin de la visualisation
        if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
           cout << "\n ======== fin du module de visualisation format geomview  ========\n";
       } 
   if (visualise_Gid.Visu_Gid_valide()) 
      { visualise_Gid.Contexte_fin_visualisation();                  
// -- maintenant n'est effectué qu'une seule fois à la fin du projet
//        // on ferme les sorties Gid (fichier) et appel éventuel du visualisateur
//        entreePrinc->Fermeture_fichier_initial_Gid();
//        entreePrinc->Fermeture_fichier_resultat_Gid();
        // fin de la visualisation
        if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
           cout << "\n ======== fin du module de visualisation format Gid  ========\n";
       } 
   if (visualise_Gmsh.Visu_Gmsh_valide()) 
      { visualise_Gmsh.Contexte_fin_visualisation();                  
// -- maintenant n'est effectué qu'une seule fois à la fin du projet
//        // on ferme les sorties Gmsh (fichier) et appel éventuel du visualisateur
//        entreePrinc->Fermeture_fichier_initial_Gmsh();
//        entreePrinc->Fermeture_TousLesFichiersResultats_Gmsh();
        // fin de la visualisation
        if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
           cout << "\n ======== fin du module de visualisation format Gmsh  ========\n";
       } 
    }
    catch (ErrSortieFinale)
         // cas d'une direction voulue vers la sortie
         // on relance l'interuption pour le niveau supérieur
       { ErrSortieFinale toto;
         throw (toto);
       }
    catch ( ... )
       { if (ParaGlob::NiveauImpression() >= 1) 
           {cout << "\n **** warning: erreur inconnue en lecture du fichier commande Visu";
            if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
               cout <<  "\n Algori::LectureCommandeVisu(..";
            cout << "endl";
            };
        };                
       
  };
                           
// Ecriture des informations de visualisation dans un fichier de commande externe
void Algori::EcritureCommandeVisu()                                       
{ try
    { // ouverture du flot de sortie
      entreePrinc->Ouverture_CommandeVisu("ecriture");
      // écriture de l'entête du fichier de commande de visualisation
      visualise.EcritDebut_fichier_OrdreVisu(*entreePrinc);
      // on écrit en fonction de l'activation ou pas de chaque type de visualisation
      visualise.Ecriture_parametres_OrdreVisu(*entreePrinc);
      visualise_maple.Ecriture_parametres_OrdreVisu(*entreePrinc);
      visualise_geomview.Ecriture_parametres_OrdreVisu(*entreePrinc);
      visualise_Gid.Ecriture_parametres_OrdreVisu(*entreePrinc);
      visualise_Gmsh.Ecriture_parametres_OrdreVisu(*entreePrinc);
      // écriture de la fin du fichier de commande de visualisation
      visualise.EcritFin_fichier_OrdreVisu(*entreePrinc);
      // fermeture du flot de sortie
      entreePrinc->Fermeture_CommandeVisu();
    }
  // sortie anormale de l'écriture  
  catch (...)// erreur en écriture
    {  cout << "\n **** ERREUR en ecriture du fichier de  commande de visualisation "
            << "\n on continue quand meme";
       if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
           cout  << "\n Algori::EcritureCommandeVisu(..";
    };
};
                                                      
                              
    // visualisation au fil du calcul à partir d'un fichier de commande externe
    // type_incre signal ce qu'il y a a faire, il est modifié dans le programme !! donc le laisser en variable
    //                 en fait après le premier passage 
    
void Algori::VisuAuFilDuCalcul(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesReferences* lesReferences
                       ,LesCourbes1D* ,LesFonctions_nD*
                       ,LesLoisDeComp* lesLoisDeComp,DiversStockage* diversStockage
                       ,Charge* charge,LesCondLim* lesCondLim,LesContacts* lesContacts
                       ,Resultats* resultats,OrdreVisu::EnumTypeIncre& type_incre,int num_incre)
{
 tempsSortieFilCalcul.Mise_en_route_du_comptage(); // temps cpu
 // on gère les exceptions éventuelles en mettant le bloc sous surveillance
 try 
   {// s'il s'agit de l'incrément 0 on arrête
    if (num_incre == 0) return;
    // s'il n'y a pas de sortie au fil du calcul on arrête
    if (!(pa.Sortie_fil_calcul()))
      {tempsSortieFilCalcul.Arret_du_comptage();
       return ;
      };
    // sinon ...cas normal avec sortie au fil du calcul
    
    // def du conteneur des numéros d'incréments disponible
    list <int> list_incre; // par défaut on indique un conteneur vide
    // on informe les instances  de visualisation de la liste des incréments possibles
    // début possible, mais cela n'a pas d'importance pour l'exécution,
    // c'est seulement dans le cas d'un choix que cela intervient or ici il n'y a pas de choix
    // utilisé pour les méthodes List_increment_disponible( et on le définit en dehors du if
    // sinon, il cesse d'exister quand le if est fermé
    
    if (type_incre == OrdreVisu::PREMIER_INCRE)
      // ---------- partie initialisation ------------------
      { // on prépare la  variable de contrôle dans le cas ou l'on veut une visualisation en cours du calcul
        // ouverture du fichier de commande en lecture
        entreePrinc->Ouverture_CommandeVisu("lecture");
        //    --- on se positionne au début valide du fichier
        bool debut = entreePrinc->PositionEtExisteCVisu("debut_fichier_commande_visu");
        if (!debut) // cas ou le mot clé de début de fichier n'existe pas
         { cout << "\n erreur en lecture du fichier de commande, "
                << " on ne trouve pas le mot clee de debut de fichier"
                << " <debut_fichier_commande_visu>, le fichier est non valide"
                << "\n VisuAuFilDuCalcul(...";
           return;
          }
     #ifdef UTILISATION_MPI
       // cas d'un  calcul //, seul le CPU 0 affiche
       if (ParaGlob::Monde()->rank() == 0)
     #endif
        // écriture de l'en-tête
        if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 1)) || (permet_affichage > 2))
          {cout << "\n ========  lecture du fichier de commande "
                                             << "de visualisation  ========\n"; 
                                        };
        //-- initialisation des grandeurs globales par maillage
  //      int nb_maille = lesMaillages->NbMaillage();
  //      List_io < double>::iterator 
  //      for (int i=1; i<= nb_maille; i++)
  //        { //
  //        
  //        
  //        };
       
        visualise.List_increment_disponible(list_incre);
        visualise_maple.List_increment_disponible(list_incre);
        visualise_geomview.List_increment_disponible(list_incre);
        visualise_Gid.List_increment_disponible(list_incre);
        visualise_Gmsh.List_increment_disponible(list_incre);
        // on informe les instances de visualisation du nombre de maillages possibles
        // par défaut tous les maillages seront visualisés, ceci est descidé aussi ici
        visualise.List_maillage_disponible(lesMaillages->NbMaillage());     
        visualise_maple.List_maillage_disponible(lesMaillages->NbMaillage());     
        visualise_geomview.List_maillage_disponible(lesMaillages->NbMaillage());
        visualise_Gid.List_maillage_disponible(lesMaillages->NbMaillage());
        visualise_Gmsh.List_maillage_disponible(lesMaillages->NbMaillage());
      };
    // ---------- partie traitement courant ------------------
    // on test si on doit continuer
    // arrivé ici on sait que la fréquence est positive donc valide
    
    if   (!(pa.SauvegardeFilCalculAutorisee(num_incre,tempsDerniereSortieFilCalcul,(type_incre==OrdreVisu::DERNIER_INCRE)))      
          && (type_incre != OrdreVisu::PREMIER_INCRE)
          && (!pa.EtatSortieEtatActuelDansCVisu())
          && (!mode_debug)
         )
          {tempsSortieFilCalcul.Arret_du_comptage();
           return ;
          };

    // dans le cas où le temps courant == le dernier temps déjà sauvegardé, ce n'est pas la peine de faire une seconde sauvegarde
    // sauf si on a un incrément est sup a 1000000, = un cas particulier utilisé uniquement en debug
    // de toute manière, dans le pire des cas, on aura deux fois le meme incrément, ce n'est pas vraiment une erreur
    if (num_incre < 1000000)
     {if (pa.Variables_de_temps().TempsCourant() == tempsDerniereSortieFilCalcul)
          {tempsSortieFilCalcul.Arret_du_comptage();
           return ;
          };
     };

    // sinon ...
    // indique le choix de la liste d'incrément à visualiser
    // par défaut  on initialise à 0 et au dernier incrément si différent
    const list<int> * list_incre_init_inter = &(visualise.List_balaie_init(-1));
    const list<int> &  list_incre_init = * list_incre_init_inter; 
    // on impose la liste pour les autres types de visualisation
    visualise_maple.List_balaie_init(list_incre_init); 
    visualise_geomview.List_balaie_init(list_incre_init); 
    visualise_Gid.List_balaie_init(list_incre_init); 
    visualise_Gmsh.List_balaie_init(list_incre_init);
              
    // on initialise à chaque passage en indiquant ici que c'est le premier incrément
    // par contre on indique que ce sera uniquement une exécution au fil du calcul
    // donc initialisation lite sauf pour le premier passage
    { bool fil_calcul = true; // init
      if (type_incre == OrdreVisu::PREMIER_INCRE)
         fil_calcul = false;
     
      visualise.Initialisation(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                           ,charge,lesCondLim,lesContacts,resultats,OrdreVisu::PREMIER_INCRE,num_incre
                           ,listeVarGlob,listeVecGlob,fil_calcul);
      visualise_maple.Initialisation(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                          ,charge,lesCondLim,lesContacts,resultats,OrdreVisu::PREMIER_INCRE,num_incre
                          ,listeVarGlob,listeVecGlob,fil_calcul);
      visualise_geomview.Initialisation(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                          ,charge,lesCondLim,lesContacts,resultats,OrdreVisu::PREMIER_INCRE,num_incre
                          ,listeVarGlob,listeVecGlob,fil_calcul);
      visualise_Gid.Initialisation(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                          ,charge,lesCondLim,lesContacts,resultats,OrdreVisu::PREMIER_INCRE,num_incre
                          ,listeVarGlob,listeVecGlob,fil_calcul);
      visualise_Gmsh.Initialisation(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                          ,charge,lesCondLim,lesContacts,resultats,OrdreVisu::PREMIER_INCRE,num_incre
                          ,listeVarGlob,listeVecGlob,fil_calcul);
    };

    // lecture du fichier de commande au premier passage
    if (type_incre == OrdreVisu::PREMIER_INCRE)
      { // on effectue la lecture des différents types de visualisation jusqu'à la fin du fichier de commande
        //    --- on verifie que le mot cle de fin de fichier existe
        if (!entreePrinc->PositionEtExisteCVisu("fin_fichier_commande_visu"))
         { cout << "\n erreur en lecture du fichier de commande, on ne trouve pas le mot clee de fin de fichier"
                << " <fin_fichier_commande_visu>, le fichier est non valide";
           tempsSortieFilCalcul.Arret_du_comptage();
           return;
          }
        //    --- on se repositionne au début du fichier
        entreePrinc->PositionEtExisteCVisu("debut_fichier_commande_visu");
        entreePrinc->NouvelleDonneeCVisu();
        //    --- lecture
        try
         { while (strstr(entreePrinc->tablcarCVisu,"fin_fichier_commande_visu")==NULL)
            { visualise.Lecture_parametres_OrdreVisu(*entreePrinc);
              visualise_maple.Lecture_parametres_OrdreVisu(*entreePrinc);
              visualise_geomview.Lecture_parametres_OrdreVisu(*entreePrinc);    
              visualise_Gid.Lecture_parametres_OrdreVisu(*entreePrinc);    
              visualise_Gmsh.Lecture_parametres_OrdreVisu(*entreePrinc);    
             }
          }   
        // sortie anormale de la lecture  
        catch (UtilLecture::ErrNouvelleDonneeCVisu erreur)
           {  if ( erreur.lecture == 1) // on a atteind une fin de fichier
                { // fin de fichier atteind sans le mot clé de fin
                  cout << "\n **** fin du fichier de commande de visualisation, atteinte sans le mot cle"
                       << " fin_fichier_commande_visu ! "
                       << "\n normalement ce mot cle doit finir le fichier, on continue quand meme, mais"
                       << "\n il y a peut-etre un probleme";
                  if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
                  cout  << "\n Algori::VisuAuFilDuCalcul(..";
                }
              else if ( erreur.lecture == 0) // on ne peut pas ouvrir le fichier
                { cout << "\n **** erreur en ouverture du fichier ";
                  if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
                     cout  << "\n Algori::VisuAuFilDuCalcul(..";
                 } 
              else
                { // erreur en lecture
                  cout << "\n **** ERREUR en lecture du fichier de  commande de visualisation "
                       << "\n on continue quand meme, mais il y aura peut-etre un probleme de coherence pour la suite";
                 if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
                    cout  << "\n Algori::VisuAuFilDuCalcul(..";
                 }      
           }    
        catch (ErrSortieFinale)
             // cas d'une direction voulue vers la sortie
             // on relance l'interuption pour le niveau supérieur
           { ErrSortieFinale toto;
             throw (toto);
           }
        catch (...)// erreur inconnue
           {  cout << "\n **** ERREUR inconnuee en lecture du fichier de  commande de visualisation "
                   << "\n on continue quand meme, mais il y aura peut-etre un probleme de coherence pour la suite";
              if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
                  cout  << "\n Algori::VisuAuFilDuCalcul(..";
             }
        // avertissement de la fin de lecture du fichier de commande
//        if (ParaGlob::NiveauImpression() >= 2)
      #ifdef UTILISATION_MPI
        // cas d'un  calcul //, pour l'instant seul le CPU 0 affiche
        if (ParaGlob::Monde()->rank() == 0)
      #endif
        if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 2)) || (permet_affichage > 2))
           cout << "\n ========  fin de la lecture du fichier de commande de visualisation  ========\n";
        // initialisation de la sortie vrml (fichier) si la sortie vrml est valide
        if (visualise.Visu_vrml_valide())
         { entreePrinc->Ouverture_fichier_principal_vrml();
           entreePrinc->Ouverture_fichier_legende_vrml();
           visualise.Contexte_debut_visualisation(); 
         };
        // initialisation de la sortie maple (fichier) si la sortie maple est valide
        if (visualise_maple.Visu_maple_valide())
         { // initialisation de la maple (fichier)
           entreePrinc->Ouverture_fichier_principal_maple();
           // == définition des paramètres d'entête de visualisation 
           visualise_maple.Contexte_debut_visualisation(); 
         };
        // initialisation de la sortie geomview (fichier) si la sortie geomview est valide
        if (visualise_geomview.Visu_geomview_valide())
         { entreePrinc->Ouverture_fichier_principal_geomview();
           entreePrinc->Ouverture_fichier_legende_geomview();
           visualise_geomview.Contexte_debut_visualisation();
         };
        // initialisation des sorties Gid (fichier) si la sortie Gid est valide
        if (visualise_Gid.Visu_Gid_valide())
         { entreePrinc->Ouverture_fichier_initial_Gid();
           entreePrinc->Ouverture_fichier_resultat_Gid();
           visualise_Gid.Contexte_debut_visualisation();
         };
        // dans le cas particulier de la visualisation GID on sort le maillage initial
        if (visualise_Gid.Visu_Gid_valide())
          visualise_Gid.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                         ,charge,lesCondLim,lesContacts,resultats,OrdreVisu::PREMIER_INCRE,0
                         ,listeVarGlob,listeVecGlob);

        // initialisation des sorties Gmsh (fichier) si la sortie Gmsh est valide
        if (visualise_Gmsh.Visu_Gmsh_valide())
        { entreePrinc->Ouverture_fichier_initial_Gmsh();
          entreePrinc->CreationRepertoireResultat();
          const list <string >& nomsTousLesGrandeursSortie = visualise_Gmsh.NomsTousLesGrandeursSortie();
  ////------ debug
  //{list <string >::const_iterator ila,ilafin=nomsTousLesGrandeursSortie.end();
  //cout << "\n debug Algori::VisuAuFilDuCalcul ";
  //for (ila = nomsTousLesGrandeursSortie.begin();ila != ilafin;ila++)
  //  cout << " " << (*ila);
  //cout << endl;
  //
  //}
  ////--- fin debug
          entreePrinc->Ouverture_fichier_resultat_Gmsh(nomsTousLesGrandeursSortie);
          visualise_Gmsh.Contexte_debut_visualisation();
         }  
        // dans le cas particulier de la visualisation Gmsh on sort le maillage initial
        if (visualise_Gmsh.Visu_Gmsh_valide())
          visualise_Gmsh.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                         ,charge,lesCondLim,lesContacts,resultats,OrdreVisu::PREMIER_INCRE,0
                         ,listeVarGlob,listeVecGlob);
        // maintenant on modifie le type d'incrément pour les futures sortie
        type_incre = OrdreVisu::INCRE_COURANT;  
       }; //-- fin du if (type_incre == OrdreVisu::PREMIER_INCRE)
         
     // temps cpu: passage des temps cpu de leur format natif à un tableau interne de double utilisé
     Temps_CPU_HZpp_to_lesTempsCpu(*lesCondLim,*charge,*lesContacts); // pour la visualisation de grandeurs globales

     // passage aux noeuds éventuellement des grandeurs globales, pour une sortie de post-traitement par exemple
     // le principe est que ce passage s'effectue si les conteneurs existent au niveau des noeuds
     // les conteneurs doivent donc avoir été définis dans la phase précédente d'initialisation et de lecture
     // a priori n'est disponible que lors d'une visualisation au fil du calcul
     Passage_aux_noeuds_grandeurs_globales(lesMaillages);
    
     // passage éventuel de scalaire à vecteur au niveau des noeuds
     lesMaillages->PassageInterneDansNoeud_composantes_vers_vectorielles();
          
     // visualisation en fonction de l'activité des différents types de sortie
     // il faut retester l'autorisation de sauvegarde car plus haut on a laissé passer le cas
     // du premier incrément, ceci pour permettre l'initialisation, mais cela de veut pas dire
     // qu'il faut sortir l'incrément en cours
    if   ((pa.SauvegardeFilCalculAutorisee(num_incre,tempsDerniereSortieFilCalcul,(type_incre==OrdreVisu::DERNIER_INCRE)))
//          && (type_incre != OrdreVisu::PREMIER_INCRE)
          || (pa.EtatSortieEtatActuelDansCVisu())
          || (mode_debug)
         )
       {
        // on visualise le dernier incrément disponible:  num_incre
        // appel du programme principal de visualisation
        // on indique ici que c'est toujours le dernier incrément pour que la visualisation soit possible
        bool sortie_valide= false; // pour gagner du temps
        if (visualise.Visu_vrml_valide())
             {visualise.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                            ,charge,lesCondLim,lesContacts,resultats,OrdreVisu::DERNIER_INCRE,num_incre
                            ,listeVarGlob,listeVecGlob);
              sortie_valide=true;
             };
        if (visualise_maple.Visu_maple_valide())
             {visualise_maple.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                            ,charge,lesCondLim,lesContacts,resultats,OrdreVisu::DERNIER_INCRE,num_incre
                            ,listeVarGlob,listeVecGlob);
              sortie_valide=true;
             };
        if (visualise_geomview.Visu_geomview_valide())
             {visualise_geomview.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                            ,charge,lesCondLim,lesContacts,resultats,OrdreVisu::DERNIER_INCRE,num_incre
                            ,listeVarGlob,listeVecGlob);
              sortie_valide=true;
             };
        if (visualise_Gid.Visu_Gid_valide())
             {visualise_Gid.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                            ,charge,lesCondLim,lesContacts,resultats,OrdreVisu::DERNIER_INCRE,num_incre
                            ,listeVarGlob,listeVecGlob);
              sortie_valide=true;
             };
        if (visualise_Gmsh.Visu_Gmsh_valide())
             {visualise_Gmsh.Visu(paraGlob,lesMaillages,lesReferences,lesLoisDeComp,diversStockage
                            ,charge,lesCondLim,lesContacts,resultats,OrdreVisu::DERNIER_INCRE,num_incre
                            ,listeVarGlob,listeVecGlob);
              sortie_valide=true;
             };
        // si une des sorties a été faite on sauvegarde le temps, au cas où on fait une sortie en delta t
        if (sortie_valide)
           // mémorisation du temps de la sauvegarde
           tempsDerniereSortieFilCalcul=pa.Variables_de_temps().TempsCourant();
       };

     // fermeture des fichiers si c'est le dernier incrément    
     if (type_incre == OrdreVisu::DERNIER_INCRE)
      {// == définition des paramètres de fin de visualisation 
       if (visualise.Visu_vrml_valide())
        { visualise.Contexte_fin_visualisation();                  
// -- maintenant n'est effectué qu'une seule fois à la fin du projet
//          // on ferme les sorties vrml (fichier) et appel éventuel du visualisateur
//          entreePrinc->Fermeture_fichier_principal_vrml();
//          entreePrinc->Fermeture_fichier_legende_vrml();
          // fin de la visualisation
          if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
             cout << "\n ======== fin du module de visualisation format vrml  ========\n";
         }; 
       if (visualise_maple.Visu_maple_valide())
         {// == définition des paramètres de fin de visualisation
          visualise_maple.Contexte_fin_visualisation();                  
// -- maintenant n'est effectué qu'une seule fois à la fin du projet
//          // on ferme la sortie maple (fichier) et appel éventuel du visualisateur
//          entreePrinc->Fermeture_fichier_principal_maple();
          // fin de la visualisation
          if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
             cout << "\n ======== fin module de visualisation par fichiers de points au format maple  ========\n";
          };
       if (visualise_geomview.Visu_geomview_valide()) 
        { visualise_geomview.Contexte_fin_visualisation();                  
// -- maintenant n'est effectué qu'une seule fois à la fin du projet
//          // on ferme les sorties geomview (fichier) et appel éventuel du visualisateur
//          entreePrinc->Fermeture_fichier_principal_geomview();
//          entreePrinc->Fermeture_fichier_legende_geomview();
          // fin de la visualisation
          if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
             cout << "\n ======== fin du module de visualisation format geomview  ========\n";
         };
       if (visualise_Gid.Visu_Gid_valide()) 
        { visualise_Gid.Contexte_fin_visualisation();                  
// -- maintenant n'est effectué qu'une seule fois à la fin du projet
//          // on ferme les sorties Gid (fichier) et appel éventuel du visualisateur
//          entreePrinc->Fermeture_fichier_initial_Gid();
//          entreePrinc->Fermeture_fichier_resultat_Gid();
          // fin de la visualisation
          if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
             cout << "\n ======== fin du module de visualisation format Gid  ========\n";
         };
       if (visualise_Gmsh.Visu_Gmsh_valide()) 
        { visualise_Gmsh.Contexte_fin_visualisation();                  
// -- maintenant n'est effectué qu'une seule fois à la fin du projet
//          // on ferme les sorties Gmsh (fichier) et appel éventuel du visualisateur
//          entreePrinc->Fermeture_fichier_initial_Gmsh();
//          entreePrinc->Fermeture_TousLesFichiersResultats_Gmsh();
          // fin de la visualisation
          if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
             cout << "\n ======== fin du module de visualisation format Gmsh  ========\n";
         };
       }; //-- fin du if  (type_incre == OrdreVisu::DERNIER_INCRE)  
      }
 catch (ErrSortieFinale)
      // cas d'une direction voulue vers la sortie
      // on relance l'interuption pour le niveau supérieur
    { ErrSortieFinale toto;
      tempsSortieFilCalcul.Arret_du_comptage(); // temps cpu
      throw (toto);
    }
 catch ( ... )
   { if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
       {cout << "\n **** warning: erreur en ecriture pour la visualisation au fil du calcul";
        if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
           cout <<  "\n Algori::VisuAuFilDuCalcul(..";
        cout << endl;
        };
    };
 // dans le cas où on a forcé une sortie au fil du calcul, via un drapeau, on le désarme
 if (pa.EtatSortieEtatActuelDansCVisu()) // si le drapeau a été enclanché on le désarme
        pa.ChangeSortieEtatActuelDansCVisu(false);
 tempsSortieFilCalcul.Arret_du_comptage(); // temps cpu
};
                           
// -------------------- Méthodes protégées --------------------------


    // sauvegarde propre de l'élément sur base info
    // cas donne le niveau de sauvegarde
    // = 1 : on sauvegarde tout
    // = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
    // incre : numero d'incrément auquel on sauvegarde 
    // éventuellement est définit de manière spécifique pour chaque algorithme
    // dans les classes filles
void Algori::Ecriture_base_info
             (ostream& sort, int cas)
   {switch (cas)
    { case 1 : // on sauvegarde tout
        {
          // --- écriture éventuelle des paramètres de l'algorithme et informations particulières
          sort << "\n -----parametre_et_variables_particulieres_algo: " << Nom_TypeCalcul(typeCalcul);
//cout << "\n debug algori::ecriture_base_info "
//     << "\n -----parametre_et_variables_particulieres_algo: Nom_TypeCalcul(typeCalcul)= "<< Nom_TypeCalcul(typeCalcul)
//     << flush;
//sort << "\n debug algori::ecriture_base_info "
//     << "\n -----parametre_et_variables_particulieres_algo: Nom_TypeCalcul(typeCalcul)= "<< Nom_TypeCalcul(typeCalcul)
//     << flush;
          Ecrit_Base_info_Parametre(sort,cas);
          sort << "\n -----FIN_parametre_et_variables_particulieres_algo: " << Nom_TypeCalcul(typeCalcul);
          sort << "\n mode_debug= " << mode_debug << " ";
          //--- amortissement cinétique
          if (amortissement_cinetique)
           { sort << "\n " << amortissement_cinetique << "  ---algorithme_avec_amortissement_cinetique--- "
                  << "\n max_nb_decroit_pourRelaxDyn_ "   << max_nb_decroit_pourRelaxDyn
                  << "\n inter_nb_entre_relax_ "          << inter_nb_entre_relax;
             // fonction nD éventuelle
             if (nom_fct_nD_inter_nb_entre_relax.length())
                {sort << " nom_fct_nD_inter_nb_entre_relax: "<< nom_fct_nD_inter_nb_entre_relax;}
             else
                {sort << " pas_de_fct_nD_inter_nb_entre_relax ";};
             sort << "\n taille_moyenne_glissante_ "      << taille_moyenne_glissante
                  << "\n test_fraction_energie_ "         << test_fraction_energie
                  << "\n coef_arret_pourRelaxDyn_ "       << coef_arret_pourRelaxDyn
                  << "\n coef_redemarrage_pourRelaxDyn_ " << coef_redemarrage_pourRelaxDyn
                  << "\n max_deltaX_pourRelaxDyn_ "       << max_deltaX_pourRelaxDyn
                  << "\n nb_max_dX_OK_pourRelaxDyn_ "     << nb_max_dX_OK_pourRelaxDyn
                  << "\n nb_deb_testfin_pourRelaxDyn_ "   << nb_deb_testfin_pourRelaxDyn
                  << "\n nb_deb_test_amort_cinetique_ "   << nb_deb_test_amort_cinetique;
           }
          else {sort << "\n " << amortissement_cinetique << " --pas_de_amortissement_cinetique--";};
          //---- amortissement critique pour par exemple relaxation dynamique
          if (type_calcul_visqu_critique)
           { sort << " type_calcul_visqu_critique= " << type_calcul_visqu_critique 
                  << " opt_cal_C_critique= " << opt_cal_C_critique
                  << " f_= " << f_
                  << " ampli_visco= " << ampli_visco << " ";
           }
          else {sort << "\n " << type_calcul_visqu_critique << " --pas_de_amortissement_visqueux_critique--";};
          //-------- arrêt sur équilibre statique sans la partie visqueuse
          sort << "\n arret_a_equilibre_statique= " << arret_a_equilibre_statique;
          //------- modulation de la précision d'équilibre ---
          if (nom_modulation_precision.length())
            {sort << "\n fct_nD_modulation_precision: "<< nom_modulation_precision;}
          else
            {sort << "\n pas_de_fct_nD_de_modulation_precision ";};
          //------  écriture des différentes énergies
          sort << "\n energies:_cin= "<< setprecision(ParaGlob::NbdigdoCA()) << E_cin_t 
               << " int= " << setprecision(ParaGlob::NbdigdoCA()) << E_int_t 
               << " ext= " << setprecision(ParaGlob::NbdigdoCA()) << E_ext_t
               << " balance= " << setprecision(ParaGlob::NbdigdoCA()) << bilan_E;
          // la quantité de mouvement globale
          sort << "\n quantite_mouvement= " << setprecision(ParaGlob::NbdigdoCA()) << q_mov_t ;    
          // énergies internes aux éléments     
          sort << "\n energie_elastique= " << setprecision(ParaGlob::NbdigdoCA()) << energTotal.EnergieElastique()     
               << " energie_plastique= " << setprecision(ParaGlob::NbdigdoCA()) << energTotal.DissipationPlastique()     
               << " energie_visqueuse= " << setprecision(ParaGlob::NbdigdoCA()) << energTotal.DissipationVisqueuse();
          // énergies dues aux contact - frottement
          sort << "\n energie_contact_elastique= " << setprecision(ParaGlob::NbdigdoCA()) << energFrottement.EnergieElastique()     
               << " energie_frot_plastique= " << setprecision(ParaGlob::NbdigdoCA()) << energFrottement.DissipationPlastique()     
               << " energie_frot_visqueuse= " << setprecision(ParaGlob::NbdigdoCA()) << energFrottement.DissipationVisqueuse(); 
          sort << "\n energie_Penalisation_contact= " << setprecision(ParaGlob::NbdigdoCA()) << energPenalisation;     
          // écriture des différentes puissances
          sort << "\n puissances:_acc= "<< setprecision(ParaGlob::NbdigdoCA()) << P_acc_t 
               << " int= " << setprecision(ParaGlob::NbdigdoCA()) << P_int_t 
               << " ext= " << setprecision(ParaGlob::NbdigdoCA()) << P_ext_t
               << " balance= " << setprecision(ParaGlob::NbdigdoCA()) << bilan_P_t;
          // écriture des énergies et puissances numériques (non physique)
          sort << "\n E_visco_numerique_t= "<< setprecision(ParaGlob::NbdigdoCA()) << E_visco_numerique_t;
          sort << "\n E_bulk= "<< setprecision(ParaGlob::NbdigdoCA()) << E_bulk;
          sort << " P_bulk= "<< setprecision(ParaGlob::NbdigdoCA()) << P_bulk;
          // dans le cas particulier de cette classe il y a  les paramètres
          // du calcul à sauvegarder
          pa.Ecriture_base_info_Para(sort,cas);
          sort << flush;
          break;
        }
       case 2 : // on sauvegarde ce qui varie 
       { // écriture des temps cpu :
         sort << "\n temps_cpu_en_nanoseconde: ";
         //  --- a) la partie spécifique à l'algo
         // si ptalgo est non nulle, on a une sortie des temps cpu, spécifique
         // à la classe AlgoriCombine pointée
         if (ptalgocombi == NULL)
           {
            sort << "\n tps_InitAlgo        " << tempsInitialisation;
            sort << "\n tps_MiseAJourAlgo   "<< tempsMiseAjourAlgo;
            sort << "\n tps_CalEquilibre    "<< tempsCalEquilibre;
            sort << "\n tps_MatSmLoc        "<< tempsRaidSmEner;
            sort << "\n tps_SmLoc           "<< tempsSecondMembreEnerg;
            sort << "\n tps_ResSystLineaire "<< tempsResolSystemLineaire;
            sort << "\n tps_Sauvegarde      "<< tempsSauvegarde;
            sort << "\n tps_SortieFilCalcul "<< tempsSortieFilCalcul;
            sort << "\n tps_contactMatSmLoc "<< tempsRaidSmEnerContact;
            sort << "\n tps_contactSmLoc    "<< tempsSecondMembreEnergContact;
            sort << "\n tempsCalMasse       "<< tempsCalMasse;
            sort << "\n tempsCalViscoNum    "<< tempsCalViscoNum;
          }
         else
          {ptalgocombi->AutreSortieTempsCPU(1,sort,cas); };
         // --- b) parties extérieures à l'algo
         sort << "\n tps_CL              "<< temps_CL;
         sort << "\n tps_CLL             "<< temps_CLL;
         sort << "\n tps_lois_comp       "<< temps_lois_comportement;
         sort << "\n tps_metrique_KSM    "<< temps_metrique_K_SM;
         sort << "\n tps_chargement      "<< temps_chargement;
         sort << "\n tps_rech_contact    "<< temps_rech_contact;
       #ifdef UTILISATION_MPI
         // les temps de transfert
         if (ptalgocombi == NULL)
           {sort << "\n tps_transfert_court_Algo  "<< temps_transfert_court_algo;
            sort << "\n tps_transfert_long_Algo  "<< temps_transfert_long_algo;
            sort << "\n tps_attente_Algo  "<< temps_attente_algo;
            sort << "\n tps_transfert_court_matSm  "<< temps_transfert_court_matSm;
            sort << "\n tps_transfert_long_matSm  "<< temps_transfert_long_matSm;
            sort << "\n tps_attente_matSm  "<< temps_attente_matSm;
            sort << "\n tps_transfert_court_charge  "<< temps_transfert_court_charge;
            sort << "\n tps_transfert_long_charge  "<< temps_transfert_long_charge;
            sort << "\n tps_attente_charge  "<< temps_attente_charge;
            sort << "\n tps_transfert_court_contact  "<< temps_transfert_court_contact;
            sort << "\n tps_transfert_long_contact  "<< temps_transfert_long_contact;
            sort << "\n tps_attente_contact  "<< temps_attente_contact;
           }
        else
          {ptalgocombi->AutreSortieTempsCPU(2,sort,cas); };
       #endif

         // ----- écriture éventuelle des paramètres de l'algorithme et informations particulières
         sort << "\n -----parametre_et_variables_particulieres_algo: " << Nom_TypeCalcul(typeCalcul);
         Ecrit_Base_info_Parametre(sort,cas);
         sort << " \n -----FIN_parametre_et_variables_particulieres_algo: " << Nom_TypeCalcul(typeCalcul) ;
         //------- modulation de la précision d'équilibre ---
         if (modulation_precision != NULL)
           {sort << "\n modulation_precision: "<< (modulation_precision->Valeur_pour_variables_globales())(1);}
         else
           {sort << "\n modulation_precision: 0 ";};

           
        // ---- écriture des différentes énergies
         sort << "\n energies:_cin= "<< setprecision(ParaGlob::NbdigdoCA()) << E_cin_t 
              << " int= " << setprecision(ParaGlob::NbdigdoCA()) << E_int_t 
              << " ext= " << setprecision(ParaGlob::NbdigdoCA()) << E_ext_t
              << " balance= " << setprecision(ParaGlob::NbdigdoCA()) << bilan_E;
         // la quantité de mouvement globale
         sort << "\n quantite_mouvement= " << setprecision(ParaGlob::NbdigdoCA()) << q_mov_t ;    
         // énergies internes aux éléments     
         sort << "\n energie_elastique= " << setprecision(ParaGlob::NbdigdoCA()) << energTotal.EnergieElastique()     
              << " energie_plastique= " << setprecision(ParaGlob::NbdigdoCA()) << energTotal.DissipationPlastique()     
              << " energie_visqueuse= " << setprecision(ParaGlob::NbdigdoCA()) << energTotal.DissipationVisqueuse();     
         // énergies dues aux contact - frottement
         sort << "\n energie_contact_elastique= " << setprecision(ParaGlob::NbdigdoCA())
              << energFrottement.EnergieElastique()
              << " energie_frot_plastique= " << setprecision(ParaGlob::NbdigdoCA()) << energFrottement.DissipationPlastique()     
              << " energie_frot_visqueuse= " << setprecision(ParaGlob::NbdigdoCA()) << energFrottement.DissipationVisqueuse();
              
         sort << "\n energie_Penalisation_contact= " << setprecision(ParaGlob::NbdigdoCA()) << energPenalisation;
         
         // écriture des différentes puissances
         sort << "\n puissances:_acc= "<< setprecision(ParaGlob::NbdigdoCA()) << P_acc_t
              << " int= " << setprecision(ParaGlob::NbdigdoCA()) << P_int_t
              << " ext= " << setprecision(ParaGlob::NbdigdoCA()) << P_ext_t
              << " balance= " << setprecision(ParaGlob::NbdigdoCA()) << bilan_P_t;
         // écriture des énergies et puissances numériques (non physique)
         sort << "\n E_visco_numerique_t= "<< setprecision(ParaGlob::NbdigdoCA()) << E_visco_numerique_t; 
         sort << "\n E_bulk= "<< setprecision(ParaGlob::NbdigdoCA()) << E_bulk;
         sort << " P_bulk= "<< setprecision(ParaGlob::NbdigdoCA()) << P_bulk;
         // dans le cas particulier de cette classe il y a les paramètres
         // de calcul à sauvegarder
         pa.Ecriture_base_info_Para(sort,cas);
         break;
        }
      }      
     };
     
// cas de la lecture spécifique à l'algorithme 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)
void Algori::Lecture_base_info(istream& ent,int cas)
 { bool mono_proc_on_lit_un_BI_multiProc = false;
   switch (cas)
    { case 1 : // on récupère tout
       {
         // ----- lecture éventuelle des paramètres de l'algorithme
         string nom1,nom2;
         ent >> nom1 ;
         // dans le cas où on lit un fichier créé avec MPI io, et que l'on n'est pas
         // en MPI, on passe les offsets et tailles
       #ifndef UTILISATION_MPI
         if (nom1 == "offset_algo")
          {for (int i=0;i<6;i++) // 6 et non 5, car au premier passage il y a la lecture de \n
            {nom1.clear();
             std::getline(ent, nom1);
            };
           mono_proc_on_lit_un_BI_multiProc = true;
          };
       #endif

         // on regarde tout d'abord si l'algo en lecture correspond
         if (nom1 == "-----parametre_et_variables_particulieres_algo:")
          { // lecture du nom de l'algo
            ent >> nom2; 
            if (Id_nom_TypeCalcul(nom2.c_str()) == typeCalcul)
             { // les données sauvegardées correspondent à l'algo en cours, on peut les récupérer
               Lecture_Base_info_Parametre(ent,cas,true);
               // on finit la lecture en passant les dernières lignes jusqu'au mot clé
               ent >> nom1;
               while (nom1 != "-----FIN_parametre_et_variables_particulieres_algo:")
                 ent >> nom1;
               ent >> nom1; // enfin on passe le nom de l'algo
             }
            else
             { // l'algo ne correspond pas, on passe les informations correspondants
               while (nom1 != "-----FIN_parametre_et_variables_particulieres_algo:")
                 ent >> nom1;
               ent >> nom1; // enfin on passe le nom de l'algo
               // on demande à l'agorithme de faire une initialisation sans lecture
               Lecture_Base_info_Parametre(ent,cas,false);
             };
          }
         else
          { // erreur on est mal positionné dans le fichier
            cout << "\n *** erreur en lecture des parametres specifiques de l'algorithme"
                 << " on attendait le mot cle -----parametre_et_variables_particulieres_algo: "
                 << " et on a lue "<< nom1
                 << "\n Algori::Lecture_base_info(...";
            // dans le cas où un comptage du calcul est en cours on l'arrête
            if (tempsInitialisation.Comptage_en_cours()) tempsInitialisation.Arret_du_comptage();
            if (tempsMiseAjourAlgo.Comptage_en_cours()) tempsMiseAjourAlgo.Arret_du_comptage();
            Sortie(1);
          };
		       string nominter;
         ent >> nominter >> mode_debug ;    
			      //--- amortissement cinétique
         ent >> amortissement_cinetique >> nominter;
         if (amortissement_cinetique)
         	{ ent >> nominter >> max_nb_decroit_pourRelaxDyn
                >> nominter >> inter_nb_entre_relax
                >> nominter;
            if (nominter == "nom_fct_nD_inter_nb_entre_relax:")
              {ent >> nom_fct_nD_inter_nb_entre_relax; };
              // sinon on n'a rien n'a lire
           
						      ent >> nominter >> taille_moyenne_glissante
						          >> nominter >> test_fraction_energie
         	      >> nominter >> coef_arret_pourRelaxDyn
         	      >> nominter >> coef_redemarrage_pourRelaxDyn
         	      >> nominter >> max_deltaX_pourRelaxDyn
         	      >> nominter >> nb_max_dX_OK_pourRelaxDyn
         	      >> nominter >> nb_deb_testfin_pourRelaxDyn
						          >> nominter >> nb_deb_test_amort_cinetique;
         	};
         //---- amortissement critique pour par exemple relaxation dynamique
         ent >> type_calcul_visqu_critique >> nominter;
			      if (type_calcul_visqu_critique)
         	{ ent >> nominter >> type_calcul_visqu_critique
         	      >> nominter >> opt_cal_C_critique
         	      >> nominter >> f_
         	      >> nominter >> ampli_visco;
				      };
			      //-------- arrêt sur équilibre statique sans la partie visqueuse
         ent >> nominter >> arret_a_equilibre_statique; // pour retirer éventuellement la partie visqueuse numérique
			      // si le paramètre est activé, on définit le vecteur intermédiaire de sauvegarde du résidu statique
			      if (   (arret_a_equilibre_statique ) // le dimensionnement se fera à l'affectation (=)
			          && (type_calcul_visqu_critique || pa.Amort_visco_artificielle()))
			        { if (vglob_stat == NULL)
			            vglob_stat  = new Vecteur();}
			      else // dans le cas on ne veut pas un arret statique spécifique sans viscosité numérique
			        { if (vglob_stat != NULL) {delete vglob_stat; vglob_stat=NULL ;};};
         //------- lecture modulation de la précision d'équilibre ---
         string toto;
         ent >> toto;
         if (toto == "fct_nD_modulation_precision:")
            {ent >> nom_modulation_precision;};
         // sinon on n'a rien n'a lire
         // ---- lecture des différentes énergies globales
         ent >>  toto >> E_cin_t >> toto >> E_int_t >> toto >> E_ext_t >> toto >> bilan_E;
         E_cin_0 = E_cin_t - bilan_E + E_int_t - E_ext_t; 
         // la quantité de mouvement globale
         ent >> toto >>  q_mov_t;  
         double ener_elas, ener_plas, ener_visc;
         ent >> toto >> ener_elas >> toto >> ener_plas >> toto >> ener_visc;
         // énergies internes aux éléments     
         energTotal.ChangeEnergieElastique(ener_elas);
         energTotal.ChangeDissipationPlastique(ener_plas);
         energTotal.ChangeDissipationVisqueuse(ener_visc);
         // énergies dues aux contact - frottement
         ent >> toto >> ener_elas >> toto >> ener_plas >> toto >> ener_visc;
         energFrottement.ChangeEnergieElastique(ener_elas);
         energFrottement.ChangeDissipationPlastique(ener_plas);
         energFrottement.ChangeDissipationVisqueuse(ener_visc);
         ent >> toto >> energPenalisation;
         // lecture des différentes puissances
         ent >>  toto >> P_acc_t >> toto >> P_int_t >> toto >> P_ext_t >> toto >> bilan_P_t;
         // lecture des énergies et puissances numériques (non physique)
         ent >>  toto >> E_visco_numerique_t;
         ent >>  toto >> E_bulk >>  toto >> P_bulk; // énergie et puissance bulk

         //----- dans le cas particulier de cette classe il y a les paramètres
         // du calcul qu'il faut lire
         pa.Lecture_base_info_Para(ent,cas); 
         break;
       }
     case 2 :  // on ce qui varie 
       {
         string nom1,nom2;
         // lecture des temps cpu de l'algo:
         ent >> nom1;
         // dans le cas où on lit un fichier créé avec MPI io, et que l'on n'est pas
         // en MPI, on passe les offsets et tailles
       #ifndef UTILISATION_MPI
         if (nom1 == "offset_algo")
          {for (int i=0;i<6;i++) // 6 et non 5, car au premier passage il y a la lecture de \n
            {nom1.clear();
             std::getline(ent, nom1);
            };
           mono_proc_on_lit_un_BI_multiProc = true;
          };
       #endif
         ent >> nom1 >> tempsInitialisation;
         ent >> nom1 >> tempsMiseAjourAlgo;
         ent >> nom1 >> tempsCalEquilibre;
         ent >> nom1 >> tempsRaidSmEner;
         ent >> nom1 >> tempsSecondMembreEnerg;
         ent >> nom1 >> tempsResolSystemLineaire;
         ent >> nom1 >> tempsSauvegarde;
         ent >> nom1 >> tempsSortieFilCalcul;
         ent >> nom1 >> tempsRaidSmEnerContact;
         ent >> nom1 >> tempsSecondMembreEnergContact;
         ent >> nom1 >> tempsCalMasse;
         ent >> nom1 >> tempsCalViscoNum;

        // --- b) parties extérieures à l'algo
         ent >> nom1 >> temps_CL;
         ent >> nom1 >> temps_CLL;
         ent >> nom1 >> temps_lois_comportement;
         ent >> nom1 >> temps_metrique_K_SM;
         ent >> nom1 >> temps_chargement;
         ent >> nom1 >> temps_rech_contact;
       #ifdef UTILISATION_MPI
         ent >> nom1 >> temps_transfert_court_algo;
         ent >> nom1 >> temps_transfert_long_algo;
         ent >> nom1 >> temps_attente_algo;
         ent >> nom1 >>  temps_transfert_court_matSm;
         ent >> nom1 >>  temps_transfert_long_matSm;
         ent >> nom1 >>  temps_attente_matSm;
         ent >> nom1 >>  temps_transfert_court_charge;
         ent >> nom1 >>  temps_transfert_long_charge;
         ent >> nom1 >>  temps_attente_charge;
         ent >> nom1 >>  temps_transfert_court_contact;
         ent >> nom1 >>  temps_transfert_long_contact;
         ent >> nom1 >>  temps_attente_contact;
       #else
         if (mono_proc_on_lit_un_BI_multiProc) // passage des temps de transfert
           {for (int i=0;i<13;i++) // 13 car au premier passage il y a la lecture de fin de ligne
             {nom1.clear();
              std::getline(ent, nom1);
             };
           };
       #endif

         // --- lecture éventuelle des paramètres de l'algorithme
         // on regarde tout d'abord si l'algo en lecture correspond
         ent >> nom1 ;
         if (nom1 == "-----parametre_et_variables_particulieres_algo:")
          { // lecture du nom de l'algo
            ent >> nom2; 
            if (Id_nom_TypeCalcul(nom2.c_str()) == typeCalcul)
             { // les données sauvegardées correspondent à l'algo en cours, on peut les récupérer
               Lecture_Base_info_Parametre(ent,cas,true);
               // on finit la lecture en passant les dernières lignes jusqu'au mot clé
               ent >> nom1;
               while (nom1 != "-----FIN_parametre_et_variables_particulieres_algo:")
                 ent >> nom1;
               ent >> nom1; // enfin on passe le nom de l'algo
             }
            else
             { // l'algo ne correspond pas, on passe les informations correspondants
               while (nom1 != "-----FIN_parametre_et_variables_particulieres_algo:")
                 ent >> nom1;
               ent >> nom1; // enfin on passe le nom de l'algo
               // on demande à l'agorithme de faire une initialisation sans lecture
               Lecture_Base_info_Parametre(ent,cas,false);
             };
          }
         else
          { // erreur on est mal positionné dans le fichier
            cout << "\n *** erreur en lecture des parametres specifiques de l'algorithme"
                 << " on attendait le mot cle -----parametre_et_variables_particulieres_algo: "
                 << " et on a lue "<< nom1
                 << "\n Algori::Lecture_base_info(...";
            // dans le cas où un comptage du calcul est en cours on l'arrête
            if (tempsInitialisation.Comptage_en_cours()) tempsInitialisation.Arret_du_comptage();
            if (tempsMiseAjourAlgo.Comptage_en_cours()) tempsMiseAjourAlgo.Arret_du_comptage();
            Sortie(1);
          };
         //------- lecture modulation de la précision d'équilibre ---
         {// en fait on passe l'information car elle sera recalculée au moment de son utilisation
          string toto;double truc;
          ent >> toto >> truc;
         };

	        // ---- lecture des différentes énergies
         string toto,toto2; //ent >>  toto >> E_cin_tdt >> toto >> E_int_t >> toto >> E_ext_t;
         ent >> toto2  >> E_cin_t  >> toto >> E_int_t >> toto >> E_ext_t  >> toto >> bilan_E;; // puis petite vérif ??
         #ifdef MISE_AU_POINT
           if (toto2 != "energies:_cin=")
            { cout << "\n erreur en entree de l'energie cinetique, chaine lue: " << toto2;
              // dans le cas où un comptage du calcul est en cours on l'arrête
              if (tempsInitialisation.Comptage_en_cours()) tempsInitialisation.Arret_du_comptage();
              if (tempsMiseAjourAlgo.Comptage_en_cours()) tempsMiseAjourAlgo.Arret_du_comptage();
              Sortie(1);
            }
         #endif
         // lecture des énergies globales
//         ent >>  E_cin_t ;
//		 ent >> toto >> E_int_t ;
//		 ent >> toto >> E_ext_t ;
//		 ent >> toto >> bilan_E;
         E_cin_0 = E_cin_t - bilan_E + E_int_t - E_ext_t; 
         E_cin_t=E_cin_tdt; // on initialise car E_cin_t n'est pas sauvegardée
         // la quantité de mouvement globale
         ent >> toto >>  q_mov_t;  
         // énergies internes aux éléments     
         double ener_elas, ener_plas, ener_visc;
         ent >> toto >> ener_elas >> toto >> ener_plas >> toto >> ener_visc;
		       energTotal.ChangeEnergieElastique(ener_elas);
         energTotal.ChangeDissipationPlastique(ener_plas);
         energTotal.ChangeDissipationVisqueuse(ener_visc);

         // énergies dues aux contact - frottement
         ent >> toto >> ener_elas >> toto >> ener_plas >> toto >> ener_visc;
         
         
         energFrottement.ChangeEnergieElastique(ener_elas);
         energFrottement.ChangeDissipationPlastique(ener_plas);
         energFrottement.ChangeDissipationVisqueuse(ener_visc);
         
         ent >> toto >> energPenalisation;
         
         
         // lecture des différentes puissances
         ent >>  toto >> P_acc_t >> toto >> P_int_t >> toto >> P_ext_t >> toto >> bilan_P_t;
         // lecture des énergies numériques (non physique)
         ent >>  toto >> E_visco_numerique_t;
         ent >>  toto >> E_bulk >>  toto >> P_bulk; // énergie et puissance bulk
	        // --- dans le cas particulier de cette classe il y a les paramètres
         // du calcul qu'il faut lire
         pa.Lecture_base_info_Para(ent,cas);
         break;
       }     
    } // --- fin du switch    
  };               


