
// 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 "Projet.h"
#include "AlgoriNonDyna.h"
#include "ImpliNonDynaCont.h"
#include "AlgoriFlambLineaire.h"
#include "AlgoInformations.h"
#include "AlgoUtils.h"
#include "AlgoriDynaExpli.h"
#include "AlgoriNewmark.h"
#include "Algori_chung_lee.h"
#include "AlgoriDynaExpli_zhai.h"
#include "Algori_tchamwa.h"
#include "AlgoriCombine.h"
#include "CharUtil.h"
#include "MotCle.h"
#include "Banniere.h"
// les types de bases
#include "Coordonnee.h"
#include "Coordonnee1.h"
#include "Coordonnee2.h"
#include "Coordonnee3.h"
// handler d'exception
#include "Handler_exception.h"



 // lecture initiale des donnees
 void Projet::Lecture ()
 {tempsMiseEnDonnees.Mise_en_route_du_comptage(); // comptage cpu
  bool fr = ParaGlob::Francais(); // pour simplifier
  try
   { //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();
     switch (lec_ent_info)
      {case 0 : // ------- lecture dans le fichier info -----------------
        {
         // il s'agit des données initiales. Par exemple si l'on veut effectuer un restart
         // celui-ci sera effectué dans l'algorithme avant le début du calcul mais après
         // la mise en cohérence des données
         lesMaillages->LectureLesMaillages(); // lecture des maillages et des references
         lesCourbes1D->Lecture(*entreePrinc); // lecture des courbes 1D
         lesFonctionsnD->Lecture(*entreePrinc); // lecture des courbes nD
//         //------- debug
//         cout << "\n debug Projet::Lecture ";
//         lesMaillages->Noeud_LesMaille(1,120).Affiche(9);
//         cout << endl;
//         //-------- fin debug
         lesLoisDeComp->LecturelesLoisDeComp(*entreePrinc,*lesRef,*lesCourbes1D,*lesFonctionsnD); // lecture des lois
         diversStockage->Lecture1(*entreePrinc,*lesRef);  // premiere lecture des stockages divers
         // lecture éventuelle des zones de contact et auto-contact si nécessaire
         if(lescontacts != NULL) lescontacts->Lecture_zone_contact(*entreePrinc,*lesRef);
         charge->Lecture1(*entreePrinc,*lesRef,*lesCourbes1D,*lesFonctionsnD);  // lecture des actions exterieurs de chargement
         lesCondLim->Lecture1(*entreePrinc,*lesRef);  // lecture des ddl bloques
         diversStockage->Lecture1(*entreePrinc,*lesRef);  // seconde lecture du stockage divers
         lesCondLim->Lecture2(*entreePrinc,*lesRef);  // lecture des conditions limites linéaires 
         lesCondLim->Lecture3(*entreePrinc,*lesRef);  // lecture des ddl d'initialisation 
         diversStockage->Lecture2(*entreePrinc,*lesRef);  // lecture des masses additionnelles 
         charge->Lecture2(*entreePrinc,*lesCourbes1D,*lesFonctionsnD);  // lecture du type d'application du chargement
         algori->Lecture(*entreePrinc,*paraGlob,*lesMaillages); // lecture des parametres de controle de l'algorithme
         resultats->Lecture(lesRef);  // lecture des parametres de gestion de la sortie des resultats
//                 
//         // debug
//         cout << "\n debug : Projet::Lecture () ";
//         Sortie(1);
//         //-- fin debug
//         
//
         // s'il y a des données externes sur les maillages nécessaires pour l'algorithme
         if (algori->ExisteDonneesExternes())
           LectureDonneesExternes();
         // on garde en mémoire que l'on vient de faire une lecture primaire
         paraGlob->ChangeEtatDeLaLecturePointInfo(0); 
   ////----- debug
   //  // on écrit la connection de l'élément 55
   //  Element& el = lesMaillages->Element_LesMaille(1, 55);
   //  const Tableau<Noeud *>& tabi = el.Tab_noeud_const();
   //  cout << "\n *** connection de l'element 55: ";
   //  for (int i=1;i<=tabi.Taille();i++) cout << " "<<tabi(i)->Num_noeud();
   //  cout << " Projet::Lecture () " << endl;
   ////---fin debug
         break;
        }
       case 1 : // ------- lecture dans base_info -----------------
        {// cas  d'un démarrage à partir de base_info
         // lecture initiale
         algori->Lecture_base_info(lec_ent_info,lesMaillages,lesRef,lesCourbes1D,lesFonctionsnD,lesLoisDeComp
                                   ,diversStockage,charge,lesCondLim,lescontacts,resultats);
         break;
        }
      default :
        { if (fr){cout << "\nErreur : valeur incorrecte de lec_ent_info!\n";}
          else {cout << "\nError : incorrect value of  lec_ent_info!\n";};
          cout << "Projet::Lecture ()"
               << " lec_ent_info= " << lec_ent_info << endl;
          tempsMiseEnDonnees.Arret_du_comptage(); // fin comptage cpu
          Sortie(1);
        } 
      };
     if (fr){cout << "\n ======== fin de la lecture, Projet::Lecture( ...===========\n" << endl;}
     else {cout << "\n ======== end of the reading, Projet::Lecture( ...===========\n" << endl;};    
   }
  catch (UtilLecture::ErrNouvelleDonnee erreur)
   {  if ( erreur.lecture == 1) 
        { if (fr){cout << "\n ========lecture terminee, Projet::Lecture("
                       << " fin de fichier atteinte ======== " << endl; }
			       else   {cout << "\n ======== the reading is ended, Projet::Lecture("
                       << " the end of the file is reached ======== " << endl; };
			     }				  
      else
        {cout << "\n ===============================================\n" ;
         // on sort tous les informations lues par défaut
         if (fr){cout << "\n **** erreur en lecture, voulez-vous sortir les informations actuellement lues ?";
		               cout << " rep (o ou n)  ";}
			      else   {cout << "\n **** error in reading, do you want to print the data already read ? ";
					    cout << " answer yes (y) or not (n)   ";};
         string toto;
//         toto= lect_chaine();
         toto =  lect_o_n(true);
         if ((toto == "o")||(toto=="O")||(toto=="y")||(toto=="Y"))      
             Affiche();
         tempsMiseEnDonnees.Arret_du_comptage(); // fin comptage cpu
         Sortie(0);
        };
   } 
  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 (fr){cout << "\n ======== erreur inconnue en lecture =====  Projet::Lecture(.." << endl;}
	     else {cout << "\n ======== unknown error in reading =====  Projet::Lecture(.." << endl;} 
      // on sort tous les informations lues par défaut
      if (fr){cout << "\n **** erreur en lecture, voulez-vous sortir les informations actuellement lues ?";
		        cout << " rep (o ou n)  ";}
		    else   {cout << "\n **** error in reading, do you want to print the data already read ? ";
		        cout << " answer yes (y) or not (n)   ";};
      
      string toto; toto= lect_chaine();
      if ((toto == "o")||(toto=="O")||(toto=="y")||(toto=="Y"))  Affiche(); 
      tempsMiseEnDonnees.Arret_du_comptage(); // fin comptage cpu
      Sortie(0);
   };
  // recopie eventuelle de la lecture
  if (resultats->Copie())
     Affiche();
  tempsMiseEnDonnees.Arret_du_comptage(); // fin comptage cpu
 };

// lectures secondaires éventuelles: ramène true s'il y a effectivement
// une lecture secondaire, qui donc modifie la lecture initiale
bool Projet::Lecture_secondaire()
{ tempsMiseEnDonnees.Mise_en_route_du_comptage(); // comptage cpu
  // on regarde s'il y a une suite à lire dans le .info
  MotCle motCle; // ref aux mots cle
  bool fr = ParaGlob::Francais(); // pour simplifier
 
  if (strstr(entreePrinc->tablcar,"-fin_point_info_")!=NULL)
   // il faut s'arrêter,
   return false;
 
  // on se positionne sur un mot cle
  try {while ( !motCle.SimotCle(entreePrinc->tablcar))
              entreePrinc->NouvelleDonnee();
      }
  catch (UtilLecture::ErrNouvelleDonnee errnewdonnee)
   {if (errnewdonnee.lecture == 1)
     { cout << "\n fin de lecture de tous les fichiers atteint ";}
    else if (errnewdonnee.lecture == -1)
     { cout << "\n erreur de lecture en fermeture de fichier ";}
    // on arrête le processus
    return false;
   };
  
  // dans le cas où on rencontre un ordre de pause on appelle le handler d'exception
  bool pause_lue=false;
  while (strstr(entreePrinc->tablcar,"_pause_point_info_")!=NULL)
     { if (fr){cout << "\n\n !!======== pause demandee ========!! " << endl; }
       else   {cout << "\n\n  !!======== pause asked ========!! " << endl; };
      Handler_signal(0);pause_lue=true;
      // on passe une ligne 
      entreePrinc->NouvelleDonnee();
     
     };
 
  // dans le cas où on a forcé une lecture secondaire, il faut fermer le fichier
  // et le réouvrire et se positionner à la bonne place
  if (paraGlob->EtatDemandeLectureSecondaireInPointInfo() > 0)
    // raffraichir le dernier fichier de lecture .info en cours
    // il y a fermeture puis ouverture au même endroit du fichier  .info
    entreePrinc->Raffraichir_pointInfo();
  // si on vient d'une pause, on passe une ligne jusqu'à un mot clé
  if (pause_lue)
   { while ( !motCle.SimotCle(entreePrinc->tablcar))
            entreePrinc->NouvelleDonnee();
     pause_lue = false; // mise à jours au cas où
   };
  
  bool lecture_secondaire = false;
  if (strstr(entreePrinc->tablcar,"_suite_point_info_")!=NULL)
  {if (ParaGlob::NiveauImpression() >= 4)
   cout << " debut eventuel de lectures secondaires a la fin du .info " << endl;  
   try
    { // pour l'instant les changements en lecture secondaire ne concerne qu'un nombre restreind de cas
      entreePrinc->NouvelleDonnee(); // on passe le mot clé
      // on lit tant qu'il n'y a pas de mot clé fin ou que l'on n'est pas arrivé à la fin du fichier
      while ((strstr(entreePrinc->tablcar,"_suite_point_info_")==NULL)
             && (strstr(entreePrinc->tablcar,"_pause_point_info_")==NULL)
             && (strstr(entreePrinc->tablcar,"_fin_point_info_")==NULL))
       { // on indique en mémoire que l'on fait une lecture secondaire
         paraGlob->ChangeEtatDeLaLecturePointInfo(paraGlob->EtatDeLaLecturePointInfo()+1);
         if (strstr(entreePrinc->tablcar,"Mise_A_jour_Constantes_utilisateurs_")!=NULL)
          {varExpor->MiseAjourConstantesUtilisateur(*entreePrinc);
           lecture_secondaire = true;
          }
         else if (strstr(entreePrinc->tablcar,"charges")!=NULL)
          { charge->Lecture1(*entreePrinc,*lesRef,*lesCourbes1D,*lesFonctionsnD);
            lecture_secondaire=true;} // lecture des actions exterieurs de chargement
         else if (strstr(entreePrinc->tablcar,"blocages")!=NULL)
          { lesCondLim->Lecture1(*entreePrinc,*lesRef);
            lecture_secondaire=true;}  // lecture des ddl bloques
         else if ( (strstr(entreePrinc->tablcar,"controle")!=NULL) ||
                (strstr(entreePrinc->tablcar,"para_syteme_lineaire")!=NULL) ||
                (strstr(entreePrinc->tablcar,"para_pilotage_equi_global")!=NULL) ||
                (strstr(entreePrinc->tablcar,"para_dedies_dynamique")!=NULL) ||
                (strstr(entreePrinc->tablcar,"para_affichage")!=NULL)||
                (strstr(entreePrinc->tablcar,"para_contact")!=NULL)||
                (strstr(entreePrinc->tablcar,"para_energie")!=NULL)||
                (strstr(entreePrinc->tablcar,"para_calculs_geometriques")!=NULL))
          { algori->Lecture(*entreePrinc,*paraGlob,*lesMaillages);
            lecture_secondaire=true;}// lecture des parametres de controle de l'algorithme
         else if (strstr(entreePrinc->tablcar,"resultats")!=NULL)
          { resultats->Lecture(lesRef);
            lecture_secondaire=true;};  // lecture des parametres de gestion de la sortie des resultats
         if (!lecture_secondaire) // si on a rien lue on passe à l'enregistrement suivant
           entreePrinc->NouvelleDonnee();
       };
      // information sur la lecture secondaire
      if (fr){cout << "\n ======== lecture secondaire terminee ======== " << endl; }
      else   {cout << "\n ======== the secondary reading is ended ======== " << endl; };
    }
   catch (UtilLecture::ErrNouvelleDonnee erreur)
    {  if ( erreur.lecture == 1)
         { if (fr){cout << "\n ========lecture secondaire terminee, Projet::Lecture("
                        << " fin de fichier atteinte ======== " << endl; }
           else   {cout << "\n ======== the secondary reading is ended, Projet::Lecture("
                        << " the end of the file is reached ======== " << endl; };
         }
       else
        { cout << "\n ===============================================\n" ;
          // on sort tous les informations lues par défaut
          if (fr){cout << "\n **** erreur en lecture, voulez-vous sortir les informations actuellement lues ?";
                  cout << " rep (o ou n)  ";}
          else   {cout << "\n **** error in reading, do you want to print the data already read ? ";
                  cout << " answer yes (y) or not (n)   ";};
          string toto;
          toto= lect_chaine();
          if ((toto == "o")||(toto=="O")||(toto=="y")||(toto=="Y"))
            Affiche();
          tempsMiseEnDonnees.Arret_du_comptage(); // fin comptage cpu
          Sortie(0);
        };
    }
   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 (fr){cout << "\n ======== erreur inconnue en lecture secondaire =====  Projet::Lecture(.." << endl;}
       else   {cout << "\n ======== unknown error in secondary reading =====  Projet::Lecture(.." << endl;}
       // on sort tous les informations lues par défaut
       if (fr){cout << "\n **** erreur en lecture, voulez-vous sortir les informations actuellement lues ?";
               cout << " rep (o ou n)  ";}
		     else   {cout << "\n **** error in reading, do you want to print the data already read ? ";
               cout << " answer yes (y) or not (n)   ";};
        
      string toto; toto= lect_chaine();
      if ((toto == "o")||(toto=="O")||(toto=="y")||(toto=="Y"))  Affiche(); 
      tempsMiseEnDonnees.Arret_du_comptage(); // fin comptage cpu
      Sortie(0);
    } 
   // recopie eventuelle de la lecture
   if (resultats->Copie())  Affiche();
  };

  tempsMiseEnDonnees.Arret_du_comptage(); // fin comptage cpu
  return lecture_secondaire;
};

// dans le cas MPI, transmission au sous_process des infos nécessaire à la
// lecture initiale
#ifdef UTILISATION_MPI
 void Projet::Transmission_process_Lecture(int process)
   {
   };
#endif

 // resolution du probleme
 void Projet::Calcul()
  { if (!(paraGlob->EtatDeLaLecturePointInfo())) // cas d'une première exécution
      {// preparation et verification globale des instances de classe
       // 1) introduire les lois de comportement dans les elements qui le necessite
       //    des sections pour les biellettes etc c-a-d , completer les elements
       // avec les donnees qui ont ete acquises apres la lecture du maillage
////---- debug
//cout << "\n debug -- Projet::Calcul () ";
//lesRef->Affiche(2,0);
////----- fin debug
       lesCondLim->IntroductionDonnees(lesMaillages,lesRef,lesCourbes1D,lesFonctionsnD);
       lesMaillages->Completer(diversStockage,lesLoisDeComp,lesFonctionsnD);
       // 2) verification des elements
       if (!(lesMaillages->Complet()))
         { cout << "\n le maillage n\'est pas complet avant le calcul, il"
                << " faut completer les donnees "; 
           cout << " Projet::Calcul () ";
           Sortie(1);
         };
       // 3) vérification des courbes
       if (!(lesCourbes1D->Complet())) 
         { cout << "\n les courbes ne sont pas completes avant le calcul, il faut completer les donnees ";
           cout << " Projet::Calcul () ";
           Sortie(1);
         };
       // 3) vérification des fonctions nD et mise à jour des variables globales
       if (!(lesFonctionsnD->Complet()))
         { cout << "\n les fonctions nD ne sont pas completes avant le calcul, il faut completer les donnees ";
           cout << " Projet::Calcul () ";
           Sortie(1);
         };
       // vérification sur les variables utilisateurs
       if (!varExpor->Complet_VariablesExporter(*lesRef))
        { cout << "\n Les variables utilisateurs sont a revoir... ";
          cout << " Projet::Calcul () ";
          Sortie(1);
        };
       // vérification de la cohérence du critère d'arrêt de calcul
       algori->Coherence_Algo_typeConvergence();
      }
    else // cas d'une exécution suite point info
     { // pour l'instant ne fonctionne pas avec tous les algos
       switch (algori->TypeDeCalcul())
        {case NON_DYNA :  case RELAX_DYNA :  case DYNA_IMP :
         case DYNA_EXP_CHUNG_LEE : case DYNA_EXP_TCHAMWA :
         case DYNA_EXP:  case DYNA_EXP_ZHAI: case DYNA_RUNGE_KUTTA:
         case DYNA_EXP_BONELLI : break; // OK
         case COMBINER :
           {// on passe en revue tous les sous_algo
            AlgoriCombine* al = (AlgoriCombine*) algori;
            list <EnumTypeCalcul> list_algo = al->List_Sous_Algo();
            list <EnumTypeCalcul>::iterator il,ilfin = list_algo.end();
            bool tout_ok = true; // init
            for (il = list_algo.begin();il != ilfin; il++)
              {switch (*il)
                {case NON_DYNA :  case RELAX_DYNA :  case DYNA_IMP :
                 case DYNA_EXP_CHUNG_LEE : case DYNA_EXP_TCHAMWA :
                 case DYNA_EXP:  case DYNA_EXP_ZHAI: case DYNA_RUNGE_KUTTA:
                 case DYNA_EXP_BONELLI : break; // OK
                 default : tout_ok=false; break;
                }
               if (!tout_ok)
                 break;
              }
            if (!tout_ok)
              {cout << "\nErreur : pour l'instant le type d'algorithme COMBINER "
                    << " avec un sous algo de type " << Nom_TypeCalcul(*il)
                    << " n'est pas disponible pour faire un calcul avec l'option _suite_point_info_ !\n";
               cout << "\n faire une demande a gerard rio " << endl;
               Sortie(1);
              }
            break;
           }
         default :
          cout << "\nErreur : pour l'instant le type d'algorithme " << Nom_TypeCalcul(algori->TypeDeCalcul())
                << " n'est pas disponible pour faire un calcul avec l'option _suite_point_info_ !\n";
          cout << "\n faire une demande a gerard rio " << endl;
          Sortie(1);
        };
     };
    // execution de l'algorithme
    algori->Execution
        (paraGlob,lesMaillages,lesRef,lesCourbes1D,lesFonctionsnD, varExpor,lesLoisDeComp,diversStockage,charge
        ,lesCondLim,lescontacts,resultats);
 };
 
// sortie des resultats
void Projet::SortieDesResultats ()
 { // tout d'abord sortie des résultats fichiers
    resultats->SortieInfo(paraGlob,lesMaillages,lesRef,lesCondLim,lescontacts);
 };
       
// visualisation (éventuelle) via le format vrml ou autre
void Projet::Visualisation_interactive ()
{try
 { // dans le cas où il y a une lecture de fichier de commande de visualisation
   // on met en place la visualisation demandée et on exécute la visualisation
   if (paraGlob->SousTypeCalcul(lectureCommandesVisu))
    { algori->LectureCommandeVisu
             (paraGlob,lesMaillages,lesRef,lesCourbes1D,lesFonctionsnD,lesLoisDeComp,diversStockage,charge
             ,lesCondLim,lescontacts,resultats); 
    };
/*   // dans le cas où l'on veut une visualisation automatique
   if (paraGlob->SousTypeCalcul(VisuAutoCommandes))
    { algori->VisualisationAutomatique
             (paraGlob,lesMaillages,lesRef,lesCourbes1D,lesLoisDeComp,diversStockage,charge
             ,lesCondLim,lescontacts,resultats);
     } */   
   // dans le cas ou l'utilisateur veux également une visualisation interactive
   // via le format vrml ou autre on active l'algorithme adoc
   if (paraGlob->SousTypeCalcul(visualisation))
    { // on remet ok le flux d'entrée au cas où
      // gestion d'erreur éventuelle
      if ( std::cin.fail()  || std::cin.eof())
       {std::cin.clear(); // effacer les bits d'erreurs
        std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );// purge de cin
       };
    
      // choix entre les différents types de visualisation
      bool choix_valide = false;
      while (!choix_valide)
       { 
        if (ParaGlob::Francais()) 
		       {cout << "\n =========== choix du module de visualisation interactive ============"
               << "\n sauvegarde des commandes de visualisation         ?  (rep 1)"
               << "\n visualisation automatique                         ?  (rep 2)"
               << "\n visualisation au format vrml ?                       (rep 3)"
               << "\n visualisation par fichier de points, format maple ?  (rep 4)"
               << "\n visualisation au format geomview                  ?  (rep 5)"
               << "\n visualisation au format Gid                       ?  (rep 6)"
               << "\n changement de fichier de commande .CVisu          ?  (rep 7)"
               << "\n visualisation au format Gmsh                      ?  (rep 8)"
               << "\n nom grandeurs actuelles accessibles globalement   ?  (rep 9)"
               << "\n fin   (defaut)                                  (rep 0 ou f)";
			      }
		      else	  
		       {cout << "\n =========== choice of the type of visualisation  ============"
               << "\n save commands of visualization which have been read ?  (rep 1)"
               << "\n automatic visualisation                             ?  (rep 2)"
               << "\n visualisation with the output format: vrml          ?  (rep 3)"
               << "\n visualisation with a text format: style maple       ?  (rep 4)"
               << "\n visualisation with a format for Geomview            ?  (rep 5)"
               << "\n visualisation with a format for Gid                 ?  (rep 6)"
               << "\n change of command file :  .CVisu                    ?  (rep 7)"
               << "\n visualisation with a format for Gmsh                ?  (rep 8)"
               << "\n Name of current entities readable anywhere          ?  (rep 9)"
               << "\n finish   (default)                                (rep 0 ou f)";
			      };
        string rep;
        if (ParaGlob::Francais()) {cout << "\n reponse ? ";} else {cout << "\n answer ? ";};
////------- debug
//cout << "\n *** debug Projet::Visualisation_interactive ()--";
//raise(SIGINT);
//
//
////----- fin debug
        rep = lect_return_defaut(false,"f");
        if (rep == "1")
          {// cas d'une sauvegarde des commandes de visualisation 
           algori->EcritureCommandeVisu();}
        else if (rep == "2")
          {// cas d'une visualisation automatique demandée
           algori->LectureCommandeVisu
             (paraGlob,lesMaillages,lesRef,lesCourbes1D,lesFonctionsnD,lesLoisDeComp,diversStockage,charge
             ,lesCondLim,lescontacts,resultats);}
        else if (rep == "3")
          {// cas format vrml 
           algori->Visu_vrml
             (paraGlob,lesMaillages,lesRef,lesCourbes1D,lesFonctionsnD,lesLoisDeComp,diversStockage,charge
             ,lesCondLim,lescontacts,resultats);}
        else if (rep == "4")
          {// cas format maple 
           algori->Visu_maple
             (paraGlob,lesMaillages,lesRef,lesCourbes1D,lesFonctionsnD,lesLoisDeComp,diversStockage,charge
             ,lesCondLim,lescontacts,resultats);}
        else if (rep == "5")
          {// cas format geomview 
           algori->Visu_geomview
             (paraGlob,lesMaillages,lesRef,lesCourbes1D,lesFonctionsnD,lesLoisDeComp,diversStockage,charge
             ,lesCondLim,lescontacts,resultats);}
        else if (rep == "6")
          {// cas format Gid 
           algori->Visu_Gid
             (paraGlob,lesMaillages,lesRef,lesCourbes1D,lesFonctionsnD,lesLoisDeComp,diversStockage,charge
             ,lesCondLim,lescontacts,resultats);}
        else if (rep == "7")
          {// changement de fichier de commande .CVisu 
           entreePrinc->Fermeture_CommandeVisu(); // fermeture du fichier actuel s'il y en a un
           string nouveauNomCvisu=""; // pour faire l'entrée interactive dans Changement_NomCVisu
           entreePrinc->Changement_NomCVisu(nouveauNomCvisu);
          }
        else if (rep == "8")
          {// cas format Gmsh 
           algori->Visu_Gmsh
             (paraGlob,lesMaillages,lesRef,lesCourbes1D,lesFonctionsnD,lesLoisDeComp,diversStockage,charge
             ,lesCondLim,lescontacts,resultats);}
        else if (rep == "9")
             { // on affiche directement
               ParaGlob::param->Affiche_GrandeurGlobal(cout);
             }
        else if ((rep == "0") || (rep == "o") || (rep == "O") || (rep == "f"))
          choix_valide = true;
        else
          {if (ParaGlob::Francais()) {cout << "\n la réponse : " << rep << " n'est pas utilisable, recommencez !";}
			        else  {cout << "\n the answer : " << rep << " cannot be use , do it again  !";};
			       };
       };
     };
   // dans le cas où l'on veut une sauvegarde de la visualisation dans un fichier de commande
   // on effectue la sauvegarde (suite aux infos lue dans le .info)
   if (paraGlob->SousTypeCalcul(sauveCommandesVisu))
      algori->EcritureCommandeVisu();
 }
 catch ( ... )
   { cout << "\n ======== erreur  de lecture detectee ====== " << endl;
     ErrSortieFinale titi;
     throw (titi);
   };
};
       

// lecture des données externes pour chaque entitée gérée par le projet
// type indique le type de données externes à lire
void  Projet::LectureDonneesExternes()
   {  
    tempsMiseEnDonnees.Mise_en_route_du_comptage(); // comptage cpu
    // on boucle sur tous les types différents de flots externes définies
    for (int nbf=1;nbf<= algori->NbTypeFlotExt();nbf++)
     {// on parcours tous les éléments d'un même type
      const list <Algori::DeuxString > & lalist = algori->Noms_fichier(nbf).infos; 
      list <Algori::DeuxString >::const_iterator ii;
      for (ii=lalist.begin() ; ii != lalist.end(); ii++)
       {// récup du nom de fichier
        const string& nfichier = (*ii).nomFichier;
        // ouverture du nouveau flot
        entreePrinc->NouveauFichier(((char*)(nfichier).c_str()));
        // lecture des données externes
        const string& nmaillage = (*ii).nomMaillage; // récup nom du maillage
        const int type = algori->TypeDonneesExternes(nbf);
        // chaque entité est appelé 
        lesMaillages->LectureDonneesExternes(type,nmaillage); 
        lesLoisDeComp->LectureDonneesExternes(*entreePrinc,*lesRef,type,nmaillage);
        diversStockage->LectureDonneesExternes(*entreePrinc,*lesRef,type,nmaillage);
        charge->LectureDonneesExternes(*entreePrinc,*lesRef,type,nmaillage);
        lesCondLim->LectureDonneesExternes(*entreePrinc,*lesRef,type,nmaillage); 
        // fermeture du flot, retour au flot antérieur
        int indic; entreePrinc->FermetureFichier( indic);
        }
      } 
    tempsMiseEnDonnees.Arret_du_comptage(); // fin comptage cpu
   };

// affichage de toutes les informations lue
void Projet::Affiche()  const 
      { // entreePrinc->OuvrirCopie(); // ouverture de la sauvegarde
        //  memorisation du flux de sortie
         //iostream_withassign out;
        // ostream& out = cout;
     //    out = cout;
         // réaffectation de la sortie courante
//         ofstream* cout = entreePrinc->copie; 
     //    cout = entreePrinc->copie; 
         if (algori != NULL) algori->Affiche1();  // type de calcul
         if (lesMaillages != NULL) lesMaillages->Affiche(); //  maillages
         if (lesRef != NULL) lesRef->Affiche(); // affichage des references`
         if (lesCourbes1D != NULL) lesCourbes1D->Affiche(); // affichage des courbes 1D
         if (lesLoisDeComp != NULL) lesLoisDeComp->Affiche();  // affichage des lois
         if (diversStockage != NULL) diversStockage->Affiche1(); // 1er affichage des divers stockage
         // affichage du contact si nécessaire
         if (lescontacts != NULL) lescontacts->Affiche();
         if (charge != NULL) charge->Affiche1();  // chargement
         if (lesCondLim != NULL) lesCondLim->Affiche1();  // conditions limite bloquee 
         if (lesCondLim != NULL) lesCondLim->Affiche2();  // conditions d'initialisation
         if (diversStockage != NULL) diversStockage->Affiche2();  // second affichage des divers stockage
         if (charge != NULL) charge->Affiche2();  // type de charge
         if (algori != NULL) algori->Affiche2();   // parametres de controle
         if (resultats != NULL) resultats->Affiche(); // gestion de la sortie des resultats
         
      //  entreePrinc->FermerCopie(); // fermeture de la sauvegarde
       //  cout = *out;  // retour de la sortie sur l'ecran
         Sortie(1);
       };      

// sortie du schemaXML: en fonction de enu
// ceci pour tous les types de base 
void Projet::SchemaXML_Type_de_base(ostream& sort,const Enum_IO_XML enu) 
 { // définition d'une liste de réels
   if (enu == XML_TYPE_GLOBAUX) // cas de la sortie du type global
    {sort << "\n <!--  ************************ liste de reels  ***********************  -->"
  	      << "\n    <xs:simpleType name=\"liste_de_reels\">"
  	      << "\n       <xs:list itemType=\"xs:double\"/>"
  	      << "\n    </xs:simpleType>  "; 
    };
   // cas des différentes coordonnées
   Coordonnee::SchemaXML_Coordonnee(sort,enu);
   CoordonneeH::SchemaXML_Coordonnee(sort,enu);
   CoordonneeB::SchemaXML_Coordonnee(sort,enu);
   Coordonnee1::SchemaXML_Coordonnee(sort,enu);
   Coordonnee1H::SchemaXML_Coordonnee(sort,enu);
   Coordonnee1B::SchemaXML_Coordonnee(sort,enu);
   Coordonnee2::SchemaXML_Coordonnee(sort,enu);
   Coordonnee2H::SchemaXML_Coordonnee(sort,enu);
   Coordonnee2B::SchemaXML_Coordonnee(sort,enu);
   Coordonnee3::SchemaXML_Coordonnee(sort,enu);
   Coordonnee3H::SchemaXML_Coordonnee(sort,enu);
   Coordonnee3B::SchemaXML_Coordonnee(sort,enu);
 };


  
// fermeture des fichiers de visualisation liés au projet
void Projet::FermetureFichiersVisualisation()
 {if (entreePrinc != NULL)
    { // on ferme les sorties vrml (fichier) et appel éventuel du visualisateur
      entreePrinc->Fermeture_fichier_principal_vrml();
      entreePrinc->Fermeture_fichier_legende_vrml();
      // on ferme la sortie maple (fichier) et appel éventuel du visualisateur
      entreePrinc->Fermeture_fichier_principal_maple();
      // on ferme les sorties geomview (fichier) et appel éventuel du visualisateur
      entreePrinc->Fermeture_fichier_principal_geomview();
      entreePrinc->Fermeture_fichier_legende_geomview();
      // on ferme les sorties Gid (fichier) et appel éventuel du visualisateur
      entreePrinc->Fermeture_fichier_initial_Gid();
      entreePrinc->Fermeture_fichier_resultat_Gid();
      // on ferme les sorties Gmsh (fichier) et appel éventuel du visualisateur
      entreePrinc->Fermeture_fichier_initial_Gmsh();
      entreePrinc->Fermeture_TousLesFichiersResultats_Gmsh();
      // on ferme les sorties vrml (fichier) et appel éventuel du visualisateur
      entreePrinc->Fermeture_fichier_principal_vrml();
      entreePrinc->Fermeture_fichier_legende_vrml();
    };
 };

// sortie sur fichier des temps cpu
// retourne un pointeur sur UtilLecture pour la récupération du fichier
// de temps, qui peut ainsi être utilisé par la méthode appelant
UtilLecture * Projet::Sortie_temps_cpu()
  { // on commence par appeler l'algorithme
    // sortie sur fichier des temps cpu
    algori->Sortie_temps_cpu(*lesCondLim,*charge,*lescontacts);
    // puis la partie spécifique aux lois de comportement
    lesLoisDeComp->Sortie_temps_cpu(*entreePrinc);
    // écriture des temps cpu de la mise en donnéees:
    // récupération du fichier des temps cpu
    ofstream & sort_cpu = entreePrinc->Sort_temps_cpu();
    sort_cpu << "\n \n ---------------  temps_mise_en_donnees_en_milliseconde: ---------";
    sort_cpu << fixed;
    sort_cpu.precision(2);
    sort_cpu << "\n tps_de la mise en donnees        "
             << tempsMiseEnDonnees.Temps_CPU_User_milli();
    // puis retour
    return entreePrinc;
  };

// def du fichier des temps cpu
// puis retourne un pointeur sur UtilLecture pour la récupération du fichier
// de temps, qui peut ainsi être utilisé par la méthode appelant
UtilLecture * Projet::Def_sortie_temps_cpu()
  {
    // on ouvre le fichier des temps cpu
    entreePrinc->Ouverture_fichier_temps_cpu(); // ouverture au cas où
    // puis retour
    return entreePrinc;
  };

// une méthode qui a pour objectif de terminer tous les comptages, utile
// dans le cas d'un arrêt impromptu
void Projet::Arret_du_comptage_CPU()
 { // tout d'abord l'algorithme
   algori->Arret_du_comptage_CPU();
   // puis la mise en données
   tempsMiseEnDonnees.Arret_du_comptage();
 };




