
// 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 "CharUtil.h"
#include "MotCle.h"
#include "Banniere.h"
#ifdef UTILISATION_MPI
  #include <boost/mpi/environment.hpp>
  #include <boost/mpi/communicator.hpp>
  #include <boost/serialization/string.hpp>
  #include <boost/mpi.hpp>
  namespace mpi = boost::mpi;
#endif

 // Constructeur par defaut (car les arguments sont par défauts
// il y a passage éventuelle d'argument : argc=le nombre d'argument
// argv : donne un tableau correspondant de mots clés
 Projet::Projet (string & retour,int argc, const char * argv[]) :
  paraGlob(NULL),entreePrinc(NULL),lesMaillages(NULL),algori(NULL)
  ,lesRef(NULL),lesCourbes1D(NULL),lesFonctionsnD(NULL)
  ,lesLoisDeComp(NULL),diversStockage(NULL),charge(NULL)
  ,lesCondLim(NULL),lescontacts(NULL),resultats(NULL)
  ,varExpor(NULL),tabAlgo()
  ,tempsMiseEnDonnees()

 { 
  tempsMiseEnDonnees.Mise_en_route_du_comptage(); // comptage cpu
  // initialisation par defaut de la classe des utilitaires de lecture
  // lecture du nom de fichier principal d'entree
  entreePrinc = new UtilLecture (argc,argv);
  // dans le cas du mode de demande de renseignement (-help) de UtilLecture -> arrêt
  if (entreePrinc->Lec_ent_info() == -100)
   { cout << "\n *** bizarre: on a lue :\n ";
     for (int i=0;i< argc;i++)
        cout << (argv[i]) << " ";
     cout << "\n*** on ne sait pas quoi faire !! ";
     retour = "fin"; return;
   };
  entreePrinc->OuvrirFichier(); // ouverture du fichier principal 
  int lec_ent_info = entreePrinc->Lec_ent_info();
  // ---- traitement suivant le type d'entrée de données
  #ifdef UTILISATION_MPI
    // si calcul //, on ne continue que si on a une entrée via .info
    // ou via base-info
    // def global d'un communicator
    mpi::communicator* world = ParaGlob::Monde();
    if (world->rank() != 0)
     {if (!((lec_ent_info==0)||(lec_ent_info==1)))
       {cout << "\n *** Erreur : en execution parallele, seules les entrees via .info ou base-info sont possible ";
        // on envoie un signal d'erreur  au process 0
        world->send(0, 2, std::string("erreur_en_lecture"));
        Sortie(1);
       };
     };
  #endif
  
  switch (lec_ent_info)
  {case -12 : // --------- cas de la construction shema XML d'entrée de données .info ----
     { InitConstructionSchemaXml(retour);
       break;
     }
   case -11 : // ------------ cas d'une écriture d'un fichier de commande ----------
     { InitConstructionFichierCommande(retour);
       break;
     }
   case 0 :  // ------------ cas d'une entrée via un fichier .info ----------
     { InitEntreeFichierInfo(retour);
       break;
     }
   case 1 :  // ------------ cas d'une entrée via un fichier .base-info ----------
     { InitEntreeFichierBaseInfo(retour);
       break;
     }
   default :
		   cout << "\nErreur : valeur incorrecte de lec_ent_info =" 
		        << entreePrinc->Lec_ent_info() << "   !\n";
		   cout << "Projet::Projet () " << endl;
     tempsMiseEnDonnees.Arret_du_comptage(); // fin comptage cpu
		   Sortie(1);
  };
  tempsMiseEnDonnees.Arret_du_comptage(); // fin comptage cpu
 };
 // destructeur
 Projet::~Projet ()
 {  if (paraGlob != NULL) delete  paraGlob;       // parametres globaux 
    if (entreePrinc != NULL) delete  entreePrinc;    // acces a la lecture du fichier principal
    if (lesMaillages != NULL) delete  lesMaillages;   // description des maillages
    if (algori != NULL) delete  algori;         // algorithme de calcul
    if (lesRef != NULL) delete  lesRef;         // references des maillages
    if (lesCourbes1D != NULL) delete  lesCourbes1D;   // courbes 1D
    if (lesFonctionsnD != NULL) delete lesFonctionsnD;  // courbes nD
    if (lesLoisDeComp != NULL) delete  lesLoisDeComp;  // lois de comportement
    if (diversStockage != NULL) delete  diversStockage; // stockage divers
    if (charge != NULL) delete  charge;         // chargement
    if (lesCondLim != NULL) delete  lesCondLim;     // conditions limites
    if (lescontacts != NULL) delete  lescontacts;    // le contact eventuel
    if (resultats != NULL) delete  resultats;      // sortie des resultats
    if (varExpor != NULL) delete varExpor;         // définition des variables a exporter
    int nbAlgo=tabAlgo.Taille();
    for (int i=2;i<=nbAlgo;i++)
      if (tabAlgo(i)!= NULL) delete tabAlgo(i);
    // fermeture du fichier base info si nécessaire
    if (algori != NULL)
     if (algori->Active_sauvegarde()) 
       entreePrinc->Fermeture_base_info();
 };

//  définition d'un fichier de commandes
void Projet::Def_fichier_commande(string& )
  {
     tempsMiseEnDonnees.Mise_en_route_du_comptage(); // comptage cpu
     //On va proposer un menu
     string rep=" ";
     while ((Minuscules(rep) != "f")&&(Minuscules(rep) != "0"))
      {
       try 
       {cin.clear();
        cout 
           << "\n [c] -> para tres classique [-] para assez courants "
           << "\n (0 ou f)  (fin)               "
           << "\n (1)maillage(s)..........[c]    (2)courbes 1D et fonction nD .......[-]"
           << "\n (3)loi de comportement..[c]    (4)divers stockages 1...............[c] "
           << "\n (5)zones contact               (6)efforts..........................[c]"
           << "\n (7)cond limites cine  ..[c]    (8)cond limites lineaires  "
           << "\n (9)divers stockages 2          (10)initialisation .................[-]"
           << "\n (11)type de chargement         (12)parametres de controle..........[c]"
           << "\n (13)type de fin fichier.[c]    (14 ou ? ) informations  "
           << "\n  ";
        // procédure de lecture avec prise en charge d'un retour chariot
        rep = lect_return_defaut(false,"f");
        // si la taille de rep == 0 cela veut dire que c'est un retour chariot
        if (rep.size()==0)
           {rep = "0";
            cout << "--> valeur: 0 ";
           };

        if ((Minuscules(rep) == "f") || (Minuscules(rep) == "0"))// sortie directe
          break;
        int num = ChangeEntier(rep);
        if (Minuscules(rep) == "?")
          num = 14;
        bool choix_valide=false;
        if ((num >= 0)&&(num<=14))
             { choix_valide=true; }
        else { cout << "\n Erreur on attendait un entier entre 0 et 14 !!, "
                    << "\n redonnez une bonne valeur"
                    << "\n ou taper f ou 0 pour arreter le programme"; 
               choix_valide=false;
             }
        switch (num)
         { case 0:  //pas de sous type
             { break;} // normalement cela a déjà été filtré avant
           case 1:  // les maillage
             { lesMaillages->Info_commande_lesMaillages(); // def des maillages et des references
               break;}
           case 2:  // les courbes et fonction
             { lesCourbes1D->Info_commande_lesCourbes1D(*entreePrinc); // def des courbes 1D
               lesFonctionsnD->Info_commande_lesFonctions_nD(*entreePrinc); // def des courbes nD
               break;}
           case 3:  // les lois de comp
             { lesLoisDeComp->Info_commande_lesLoisDeComp(*entreePrinc,*lesRef); // def des lois
               break;}
           case 4:  // divers stockage 1
             { diversStockage->Info_commande_DiversStockage1(*entreePrinc); 
               break;}
           case 5:  // contact
             { lescontacts->Info_commande_LesContacts(*entreePrinc); 
               break;}
           case 6:  // les efforts
             { charge->Info_commande_LesCharges1(*entreePrinc);
               break;}
           case 7:  // les conditions limites cinématiques (CL)
             { lesCondLim->Info_commande_LesCondLim1(*entreePrinc);
               break;}
           case 8:  // les conditions limites linéaires (CLL)
             { lesCondLim->Info_commande_LesCondLim2(*entreePrinc);
               break;}
           case 9:  // divers stockage 2
             { diversStockage->Info_commande_DiversStockage2(*entreePrinc); // def des lois
               break;}
           case 10:  // les conditions limites d'initialisation
             { lesCondLim->Info_commande_LesCondLim3(*entreePrinc);
               break;}
           case 11:  // le chargement général
             { charge->Info_commande_LesCharges2(*entreePrinc);
               break;}
           case 12:  // paramètres de contrôle
             { algori->Info_commande_ParaAlgoControle(*entreePrinc);
               break;}
           case 13:  // remonte
             { resultats->Info_commande_Resultats();  // def des parametres de gestion de la sortie des resultats
               break;}
           default:
             cout << "\n le cas "<<rep<<" n'est pas encore traite !!, mais cela devrait ce faire sans tarder ";
          };
        }    
       catch (ErrSortieFinale)
            // cas d'une direction voulue vers la sortie
            // on relance l'interuption pour le niveau supérieur
          { ErrSortieFinale toto;
            throw (toto);
          }
       catch (...)//(UtilLecture::ErrNouvelleDonnee erreur)
        {  cout << "\n Erreur on attendait un des mots clés proposés !!, "
                << "\n redonnez une bonne valeur"
                << "\n ou taper f ou 0 pour sortir "; 
        };
      }; //-- fin du while
   
     // mot clé de fin de fichier
     ofstream & sort = *(entreePrinc->Commande_pointInfo()); // pour simplifier
     sort << "\n\n\n  _fin_point_info_  \n \n  " << endl;
     // fermeture du fichier .info
     entreePrinc->fermeture_pointInfo();
     tempsMiseEnDonnees.Arret_du_comptage(); // fin comptage cpu
    };
       
//  définition du fichier schema XML
void Projet::Def_fichier_SchemaXML(string& )
  {   // récupération du flot dans lequel on écrit le schéma
      ofstream* sort=entreePrinc->ShemaXML();
      // chaque classe s'occupe de gérer ses sorties de commandes
      // la sortie s'effectue en plusieurs niveaux: premier niveau les classes de base
      // niveau 2: les classes complexes etc...
      for (int niveau=1;niveau<=nombre_maxi_de_type_de_Enum_IO_XML; niveau++)
        { // écriture de séparateurs pour une lecture plus simple et def des éléments racines
          Enum_IO_XML type_traitement_XML = Enum_IO_XML(niveau);
          // tout d'abord le début de chaque traitement
	      switch (type_traitement_XML)
	       {case XML_TYPE_GLOBAUX :
	         { (*sort) << "\n <!--  ************************************************   -->"
	                   << "\n <!--  ********   definition des types globaux ********   -->"
	                   << "\n <!--  ************************************************   -->";
	            // pas de définition d'élément particulier       
			    break;
	         }
		    case XML_IO_POINT_INFO :
	         { (*sort) << "\n <!--  ********************************************************   -->"
	                   << "\n <!--  ********   definition fichier de commande .info ********   -->"
	                   << "\n <!--  ********************************************************   -->";
	            // définition d'un élément maître       
                (*sort) << "\n<xs:element name=\"FormatXML_point_info\"  >"                  	                   
  	                    << "\n  <xs:complexType >"
  	                    << "\n    <xs:annotation>"
  	                    << "\n      <xs:documentation> "
  	                    << "\n        ******************************************************** "
  	                    << "\n        ********   definition fichier de commande .info ******** "
  	                    << "\n        ******************************************************** "
                        << "\n      </xs:documentation>"
  	                    << "\n    </xs:annotation>"
  	                    << "\n    <xs:sequence>";
			    break;
	         }
		    case XML_IO_POINT_BI :
	         { (*sort) << "\n <!--  ******************************************************   -->"
	                   << "\n <!--  ********   definition fichier restart .BI     ********   -->"
	                   << "\n <!--  ******************************************************   -->";
	            // définition d'un élément maître       
                (*sort) << "\n<xs:element name=\"FormatXML_point_BI\" >"                  	                   
  	                    << "\n  <xs:complexType >"
  	                    << "\n    <xs:annotation>"
  	                    << "\n      <xs:documentation> "
  	                    << "\n        ******************************************************** "
  	                    << "\n        ********   definition fichier restart .BI       ******** "
  	                    << "\n        ******************************************************** "
                        << "\n      </xs:documentation>"
  	                    << "\n    </xs:annotation>"
  	                    << "\n    <xs:sequence>";
			    break;
	         }
		    case XML_IO_ELEMENT_FINI :
	         { (*sort) << "\n <!--  **************************************************************  -->"
	                   << "\n <!--  ********   interface pour un element fini particulier ********  -->"
	                   << "\n <!--  **************************************************************  -->";
	            // définition d'un élément maître       
                (*sort) << "\n<xs:element name=\"FormatXML_element_fini\" >"                  	                   
  	                    << "\n  <xs:complexType >"
  	                    << "\n    <xs:annotation>"
  	                    << "\n      <xs:documentation> "
  	                    << "\n        ************************************************************** "
  	                    << "\n        ********   interface pour un element fini particulier ******** "
  	                    << "\n        ************************************************************** "
                        << "\n      </xs:documentation>"
  	                    << "\n    </xs:annotation>"
  	                    << "\n    <xs:sequence>";
			    break;
	         }
		    case XML_ACTION_INTERACTIVE :
	         { (*sort) << "\n <!--  **************************************************************  -->"
	                   << "\n <!--  ********   interface pour les actions interactives    ********  -->"
	                   << "\n <!--  **************************************************************  -->";
	            // définition d'un élément maître       
                (*sort) << "\n<xs:element name=\"FormatXML_element_fini\" >"                  	                   
  	                    << "\n  <xs:complexType >"
  	                    << "\n    <xs:annotation>"
  	                    << "\n      <xs:documentation> "
  	                    << "\n        ************************************************************** "
  	                    << "\n        ********   interface pour les actions interactives    ******** "
  	                    << "\n        ************************************************************** "
                        << "\n      </xs:documentation>"
  	                    << "\n    </xs:annotation>"
  	                    << "\n    <xs:sequence>";
			    break;
	         }
		    case XML_STRUCTURE_DONNEE :
	         { (*sort) << "\n <!--  **************************************************************  -->"
	                   << "\n <!--  ******** interface : structures de donnees internes   ********  -->"
	                   << "\n <!--  **************************************************************  -->";
	            // définition d'un élément maître       
                (*sort) << "\n<xs:element name=\"FormatXML_element_fini\" >"                  	                   
  	                    << "\n  <xs:complexType >"
  	                    << "\n    <xs:annotation>"
  	                    << "\n      <xs:documentation> "
  	                    << "\n        ************************************************************** "
  	                    << "\n        ******** interface : structures de donnees internes   ******** "
  	                    << "\n        ************************************************************** "
                        << "\n      </xs:documentation>"
  	                    << "\n    </xs:annotation>"
  	                    << "\n    <xs:sequence>";
			    break;
	         }
	       };
	      // ++++++++++++++++ maintenant sortie relatives aux différentes entitées ++++++++++++++++ 
          // -- def de  la dimension pour une sortie schema XML, def du type global
          SchemaXML_dim(entreePrinc,type_traitement_XML);
          varExpor->SchemaXML_VariablesExporters(entreePrinc,type_traitement_XML);
          // cas de l'ensemble des algorithmes
          int nb_algo=tabAlgo.Taille();
          for (int i=1;i<=nb_algo;i++)
              tabAlgo(i)->SchemaXML_Algori(*sort,type_traitement_XML);
          // la suite
          SchemaXML_Type_de_base(*sort,type_traitement_XML); // les types de base 
          lesMaillages->SchemaXML_LesMaillages(*sort,type_traitement_XML); // def des maillages et des references
          lesCourbes1D->SchemaXML_lesCourbes1D(*sort,type_traitement_XML); // def des courbes 1D
          lesFonctionsnD->SchemaXML_lesFonctions_nD(*sort,type_traitement_XML); // def des courbes nD
     /* lesLoisDeComp->SchemaXML_lesLoisDeComp(*entreePrinc,*lesRef); // def des lois
      diversStockage->SchemaXML_diversStockage1(*entreePrinc,*lesRef);  // premiere lecture des stockages divers
      charge->SchemaXML_charge1(*entreePrinc,*lesRef);  // lecture des actions exterieurs de chargement
      lesCondLim->SchemaXML_lesCondLim1(*entreePrinc,*lesRef);  // lecture des ddl bloques
      diversStockage->SchemaXML_diversStockage2(*entreePrinc,*lesRef);  // seconde lecture du stockage divers
      lesCondLim->SchemaXML_lesCondLim2(*entreePrinc,*lesRef);  // lecture des ddl d'initialisation 
      diversStockage->SchemaXML_diversStockage3(*entreePrinc,*lesRef);  // lecture des masses additionnelles 
      charge->SchemaXML_charge2(*entreePrinc);  // lecture du type d'application du chargement
      algori->SchemaXML_algori(*entreePrinc);  // lecture des parametres de controle de l'algorithme
      resultats->SchemaXML_resultats(lesRef);  // lecture des parametres de gestion de la sortie des resultats
      // s'il y a des données externes sur les maillages nécessaires pour l'algorithme
      if (algori->ExisteDonneesExternes())
        SchemaXML_algoriLectureDonneesExternes();*/ 
          // la fin de chaque traitement
	      switch (type_traitement_XML)
	       {case XML_TYPE_GLOBAUX :
	         { // pas de définition d'élément particulier       
			   break;
	         }
		    case XML_IO_POINT_INFO: case XML_IO_POINT_BI: case XML_IO_ELEMENT_FINI:
	       	case XML_ACTION_INTERACTIVE: 
	       	case XML_STRUCTURE_DONNEE:
	         {  // fin de la définition d'un élément maître       
                (*sort) << "\n    </xs:sequence>"
                        << "\n  </xs:complexType>"                 	                   
                        << "\n</xs:element>";                 	                   
			    break;
	         }
	       };
        };
  
     // fin du schema
     SchemaXML_fin(entreePrinc);
    }; 
 
//------------------------------------ protegees ----------------------
    // lecture eventuelle de la dimension sinon elle est mise a trois
int Projet::LectureDimension()
   { int dim;
     int lec_ent_info = entreePrinc->Lec_ent_info();
     // traitement suivant le type d'entrée de données
     if (lec_ent_info == 0)
       // ------------ cas d'une entrée via un fichier .info ----------
       // on regarde si lle mot cle "dimension" existe
        {if (strstr(entreePrinc->tablcar,"dimension")!=NULL)
          {string mot;
           *(entreePrinc->entree) >> mot >> dim;
           if ((dim!=1) && (dim!=2) && (dim!=3))
            { cout << "\n erreur en lecture de la dimension du probleme ";
              cout << " \n la dimension doit etre 1 ou 2 ou 3 , ici la valeur lue = "
                   << dim << " !! " << endl;
              entreePrinc->MessageBuffer("** lecture de la dimension du probleme **");
              throw (UtilLecture::ErrNouvelleDonnee(-1));
              Sortie (1);
             }
           entreePrinc->NouvelleDonnee();  // pour la prochaine lecture                  
          }
         else 
          { dim = 3; // par defaut
            cout << "\n mot clé dimension non trouvé, on retiend la dimension 3 par défaut";
           } 
        }
     return dim;
   };

    // lecture eventuelle du niveau de sortie des commentaires
int Projet::LectureNiveauCommentaire()
   { int niveau = ParaGlob::NiveauImpression();
     int lec_ent_info = entreePrinc->Lec_ent_info();
     // traitement suivant le type d'entrée de données
     if (lec_ent_info == 0)
       // ------------ cas d'une entrée via un fichier .info ----------
       // on regarde si lle mot cle "niveau_commentaire" existe
        {if (strstr(entreePrinc->tablcar,"niveau_commentaire")!=NULL)
          {string mot;
           *(entreePrinc->entree) >> mot >> niveau;
           entreePrinc->NouvelleDonnee();  // pour la prochaine lecture                  
          }
        }
     return niveau;
   };


// -- def de la dimension pour une sortie sur un fichier de commande
int Projet::Info_commande_dimension(UtilLecture * entreePrinc)
 { int retour;
   //cout << "\n ";
   cout << "\n ==> Dimension espace geometrique (defaut 3) : 1 2 ou 3 ?  ";
   string rep; bool choix_valide=false;
  
   while (!choix_valide)
    { rep = "_";
      int c = std::cin.peek();  // peek character (sans changer le flux !!)
      if (( c == EOF )||(c=='\n'))
         {rep = "3";cout << "--> valeur: 3 "; // si c'est return on met "3"
          c = getchar(); // on lit quand même le caractère
         }
      else // sinon on peut lire
        {std::getline (std::cin,rep);
         // a priori les prochaines lectures vont utilisées un getline
        };
      // si la taille de rep == 0 cela veut aussi dire que c'est un retour chariot
      if (rep.size()==0)
         {rep = "3";
          cout << "--> valeur: 3 ";
         };
    
      if (rep == "1") { retour = 1; choix_valide=true;}
      else if (rep == "2") {retour = 2;choix_valide=true;}
      else if (rep == "3") {retour = 3;choix_valide=true;}
      else if (rep == "f") {retour = 3;choix_valide=true;}
      else if (rep == "fin_prog") Sortie(1);
      else { cout << "\n Erreur on attendait 1 2 ou 3 !!, redonnez une bonne valeur"
                  << "\n ou taper fin_prog pour arreter le programme"; 
             choix_valide=false;
           }
      }     
   // écriture de la dimension
   ofstream & sort = *(entreePrinc->Commande_pointInfo()); // pour simplifier
//   // affichage de la banniere sur la sortie passée en argument
//   Banniere::Sortie_banniere( sort);
//   // puis affichage de la version
//   ParaGlob::Sortie_Version(sort); sort << "\n \n";
//   sort << "\n#######################################################################"
//        << "\n#                       fichier de commande                           #"
//        << "\n \n \n"
//        << "#     --- commentaire sur l'objet du travail ???"
//        << "\n \n \n"
   sort << "\n#----------------------------------------------------"
        << "\n# definition de la dimension de l'espace de travail |"
        << "\n#----------------------------------------------------"
        << "\n dimension   " << retour
        <<  endl;
    return retour;                                        
  };

// -- def du niveau de commentaire pour une sortie sur un fichier de commande
int Projet::Info_commande_niveauCommentaire(UtilLecture * entreePrinc)
 { int retour;
   //cout << "\n ";
   cout << "\n ==> Niveau de commentaire souhaitez (defaut 3) : 0 a 10 ?  ";
   string rep; bool choix_valide=false;
   while (!choix_valide)
    { rep = "_";
      int c = std::cin.peek();  // peek character (sans changer le flux !!)
      if (( c == EOF )||(c=='\n'))
         {rep = "3";cout << "-->  valeur par defaut : 3 "; // si c'est return on met "3"
          c = getchar(); // on lit quand même le caractère
         }
      else // sinon on peut lire
        {std::getline (std::cin,rep);
         // a priori les prochaines lectures vont utilisées un getline
        };
      // si la taille de rep == 0 cela veut dire que c'est un retour chariot
      if (rep.size()==0)
         {rep = "3";
          cout << "-->  valeur par defaut : 3 ";
         };
      try
       { if (rep == "fin_prog") {Sortie(1);}
         else if (rep == "f") {retour = 3;}
         // sinon
         else {retour = ChangeEntier(rep);};
         if ((retour >= 0)&&(retour<=10))
            choix_valide=true;
         else { cout << "\n Erreur on attendait un entier entre 0 et 10 !!, "
                     << "\n redonnez une bonne valeur"
                     << "\n ou taper fin_prog pour arreter le programme";
             choix_valide=false;
            }
        }
      catch (ErrSortieFinale)
           // cas d'une direction voulue vers la sortie
           // on relance l'interuption pour le niveau supérieur
         { ErrSortieFinale toto;
           throw (toto);
         }
      catch (...)//(UtilLecture::ErrNouvelleDonnee erreur)
      {  cout << "\n Erreur on attendait un entier entre 0 et 10 !!, "
                     << "\n redonnez une bonne valeur"
                     << "\n ou taper fin_prog pour arreter le programme";
             choix_valide=false;
       }
    } //-- fin du while
   // écriture du niveau de commentaire
   ofstream & sort = *(entreePrinc->Commande_pointInfo()); // pour simplifier
   sort << "\n#---------------------------------------------------------------"
        << "\n# definition facultative du niveau d'impression (entre 0 et 10)|" 
        << "\n#---------------------------------------------------------------"
        << "\n niveau_commentaire   " << retour
        <<  endl;
    return retour;                                      
  };

// lecture éventuelle de l'indicateur  de version 
void Projet::LectureVersion()
 { if (   (strstr(entreePrinc->tablcar,"version ")!=NULL)
       || (strstr(entreePrinc->tablcar,"numero_version ")!=NULL))
       { // lecture de la version sur l'entrée passée en argument
         ParaGlob::Lecture_Version((*(entreePrinc->entree)));
         entreePrinc->NouvelleDonnee();  // preparation du flot
        }
  };

// lecture éventuelle de l'indicateur de langue 
void Projet::LectureLangue()
 { if (strstr(entreePrinc->tablcar,"lang ")!=NULL)
       { // lecture de l'indicateur de langue sur l'entrée passée en argument
         ParaGlob::Lecture_Langue((*(entreePrinc->entree)));
         entreePrinc->NouvelleDonnee();  // preparation du flot
        }
  };

// -- def de l'entête  pour une sortie schema XML
void Projet::SchemaXML_entete(UtilLecture * entreePrinc)
 { if (ParaGlob::NiveauImpression() >= 1)
     cout << "\n entete et dimension ";
   if (ParaGlob::NiveauImpression() >= 8)
     cout << " Projet::SchemaXML_entete(...)  ";
   ofstream & sort = *(entreePrinc->ShemaXML()); // récup du fichier
   // sortie de l'entête
   sort << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
        << "\n<xs:schema " //targetNamespace=\"http:\/\/web.univ-ubs.fr\/lg2m\/rio/Herezh++/schemaXML\""
        << "\n xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"" // l'adresse officielle
        << "\n version=\""<<ParaGlob::NbVersion()<<"\" "
        << "\n xml:lang=\"fr\" >"; 
      
   sort << "\n<xs:annotation>"
        << "\n    <xs:documentation> "
        << "\n        schema XML genere automatiquement par Herezh++, permettant de dialoguer avec Herezh++"
        << "\n        ceci en utilisant une syntaxe XML pour l'ensemble des entrees sorties "
		<< "\n    </xs:documentation> "
        << "\n</xs:annotation>";
 //           targetNamespace="http://schema.morphon.com/2002/markup"
 //           elementFormDefault="qualified"
 //           xmlns:tns="http://schema.morphon.com/2002/markup"> 
     
  };   
// -- def de la fin  pour une sortie schema XML
void Projet::SchemaXML_fin(UtilLecture * entreePrinc)
 {  // écriture de la fin de fichier
    // récup du fichier
    ofstream & sort = *(entreePrinc->ShemaXML());
    sort << "\n</xs:schema>" << endl; // fermeture du schéma
    // fermeture du fichier
    entreePrinc->fermetureSchemaXML();
  };

// -- def de  la dimension pour une sortie schema XML suivant le type d'io
void Projet::SchemaXML_dim(UtilLecture * entreePrinc,Enum_IO_XML enuIO_XML)
 { // définition de la dimension dans le fichier .info
   ofstream & sort = *(entreePrinc->ShemaXML()); // récup du fichier
   // choix en fonction de l'io
   switch (enuIO_XML)
   	{case XML_TYPE_GLOBAUX: // cas de la sortie du type global
      {sort << "\n<xs:simpleType  name=\"dimensionProbleme\" >"
  	        << "\n    <xs:annotation>"
  	        << "\n      <xs:documentation> "
  	        << "\n          definition de la dimension du probleme  1 2 ou 3"
            << "\n      </xs:documentation>"
  	        << "\n    </xs:annotation>"
      	    << "\n    <xs:restriction base=\"xs:positiveInteger\" >"
  	        << "\n      <xs:enumeration value=\"1\" />"
  	        << "\n      <xs:enumeration value=\"2\" />"
  	        << "\n      <xs:enumeration value=\"3\" />"
  	        << "\n    </xs:restriction>"
     	    << "\n</xs:simpleType>";
      break;
      }
	default : // pour tous les autres cas on sort un élément pour définir la dimension
	  sort << "\n      <xs:element name=\"dimensionDuProbleme\" type=\"dimensionProbleme\" />";
   	};
 };

// ---- fonctions d'aides pour le constructeur de Projet ----
//  démarrage: cas de la construction du schema XML  
void Projet::InitConstructionSchemaXml(string & retour)
{ retour = "def_schema_XML";
  // les parametres globaux
  // -- def de l'entête  pour une sortie schema XML
  SchemaXML_entete(entreePrinc);
  int dim = 3; // par défaut pour renseigner ParaGlob
  // -- niveau de commentaire
  int niveau = 5;
  paraGlob = new ParaGlob (dim) ; // initialisation a la dimension 
       
  // modif éventuelle du niveau de commentaire précédemment lue
  if (ParaGlob::NiveauImpression() != niveau) paraGlob->Change_niveau_impression(niveau);  
  // def des valeurs des constantes en fonction de la dimension
  ConstantesTenseur(dim);
  // def du type de calcul: ici c'est de type DEF_SCHEMA_XML, la méthode le sait
  // en intérogeant  entreePrinc
  paraGlob->Info_commande_TypeCalcul((UtilLecture&) *entreePrinc);
  // définition de l'ensemble des algorithmes
  tabAlgo.Change_taille(13);
  // par défaut le premier est l'algo courant
  tabAlgo = Algori::New_tous_les_Algo
                   (paraGlob->Avec_typeDeCalcul(),paraGlob->LesSousTypesDeCalcul()
                   ,paraGlob->Avec_soustypeDeCalcul(),(UtilLecture&) *entreePrinc);
  algori = tabAlgo(1);
               
  // def des classes generales
  lesRef = new LesReferences ;  //def des reference
  lesCourbes1D = new LesCourbes1D ; // def des courbes1D
  lesFonctionsnD = new LesFonctions_nD(lesCourbes1D); // def des courbes nD
  lesMaillages = new LesMaillages (entreePrinc,paraGlob,lesRef);// def des maillages
  lesLoisDeComp = new LesLoisDeComp ; // def des lois de comportement
  diversStockage = new DiversStockage ;  // stockage divers
  charge = new Charge ;  // chargement
  lesCondLim = new LesCondLim ;  // conditions limites
  resultats = new Resultats(entreePrinc) ; // sortie des resultats
  lescontacts = new LesContacts; // les  contacts éventuelles
  cout << "\n !!sortie schema XML: en cours de d\'eveloppement";
};  

//  démarrage: cas d'une écriture d'un fichier de commande  
void Projet::InitConstructionFichierCommande(string & retour)
	{  retour = "def_fichier_commande";
    // les parametres globaux
    // -- def exportation de constantes et variables utilisateurs
    varExpor = new  VariablesExporter() ;
    varExpor->Info_commande_VariablesExporters(entreePrinc);

    // -- def de la dimension
    int dim = Info_commande_dimension(entreePrinc);
    // -- niveau de commentaire
    int niveau = Info_commande_niveauCommentaire(entreePrinc);
    paraGlob = new ParaGlob (dim) ; // initialisation a la dimension
    // modif éventuelle du niveau de commentaire précédemment lue
    if (ParaGlob::NiveauImpression() != niveau) paraGlob->Change_niveau_impression(niveau);
    // def des valeurs des constantes en fonction de la dimension
    ConstantesTenseur(dim);
    // def du type de calcul et éventuellement des sous-types éventuel
    // indiquant qu'il y a par exemple
    // un calcul d'erreur, remonté au contrainte, relocation etc...
    paraGlob->Info_commande_TypeCalcul((UtilLecture&) *entreePrinc);

    // définition d'un algorithme pour l'affichage des données particulières
    algori = Algori::New_Agori
                  (paraGlob->TypeCalcul_maitre(),paraGlob->Avec_typeDeCalcul()
                  ,paraGlob->LesSousTypesDeCalcul()
                  ,paraGlob->Avec_soustypeDeCalcul(),(UtilLecture&) *entreePrinc
                  );

    // def des classes generales
    lesRef = new LesReferences ;  //def des reference
    lesCourbes1D = new LesCourbes1D ; // def des courbes1D
    lesFonctionsnD = new LesFonctions_nD(lesCourbes1D); // def des courbes nD
    lesMaillages = new LesMaillages (entreePrinc,paraGlob,lesRef);// def des maillages
    lesLoisDeComp = new LesLoisDeComp ; // def des lois de comportement
    diversStockage = new DiversStockage ;  // stockage divers
    charge = new Charge ;  // chargement
    lesCondLim = new LesCondLim ;  // conditions limites
    resultats = new Resultats(entreePrinc) ; // sortie des resultats
    lescontacts = new LesContacts; // les  contacts éventuelles
	};

//  démarrage: cas d'une entrée via un fichier .info  
void Projet::InitEntreeFichierInfo(string & retour)
    {try
     { retour = "calcul_elements_finis";
       // les parametres globaux
       // lecture éventuelle de l'indicateur  de version 
       entreePrinc->NouvelleDonnee();  // preparation du flot
       LectureVersion(); // lecture éventuelle du numéro de version
       LectureLangue(); // lecture éventuelle de l'indicateur de langue
       // lecture éventuelle de constantes utilisateur
       // et variables à exporter en grandeur globale
       varExpor = new  VariablesExporter();
       varExpor->LectureVariablesExporter(entreePrinc);
       // puis dimension  ....
       int dim = LectureDimension();  // lecture eventuelle de la dimension sinon = 3 par defaut
       int niveau = LectureNiveauCommentaire(); // lecture eventuelle du niveau de commentaire
       paraGlob = new ParaGlob (dim) ; // initialisation a la dimension 
       // modif éventuelle du niveau de commentaire précédemment lue
       if (ParaGlob::NiveauImpression() != niveau) paraGlob->Change_niveau_impression(niveau);
       // dans le cas où il y a une différence de niveau de version message de warning... non , pas utile !!
       // insertion et stockage des constantes utilisateur au niveau de ParaGlob
       // idem pour les variables à exporter
       varExpor->InsertConstVarUtilisateur_dans_globale();
       // def des valeurs des constantes internes en fonction de la dimension
       ConstantesTenseur(dim);
       // lecture du type de calcul sans modification du flux d'entree
       // ainsi que lecture d'un sous type éventuel indiquant qu'il y a par exemple
       // un calcul d'erreur, remonté au contrainte, relocation etc...
       // lecture du type de calcul sans modification du flux d'entree
       paraGlob->LecTypeCalcul((UtilLecture&) *entreePrinc) ;

       // def de l'algorithme
       algori = Algori::New_Agori
                     (paraGlob->TypeCalcul_maitre(),paraGlob->Avec_typeDeCalcul()
                     ,paraGlob->LesSousTypesDeCalcul()
                     ,paraGlob->Avec_soustypeDeCalcul(),(UtilLecture&) *entreePrinc
                     );
       
       // dans le cas où un grand nombre d'information nécessaire pour l'algorithme
       // est stocké de manière externe sur un fichier
       // exemple :  calcul d'erreur a partir
       // d'un champ  d'information stocké de manière externe sur un fichier
       // l'acquisition du (ou des) lieu(x) (flot) où sont stockées ces infos est effectuée
       // ce lieu fait parti des paramètres de l'algorithme
      //// entreePrinc->NouvelleDonnee(); 
       // preparation du flot sur un nouveau mot clé s'il n'est pas déjà sur un mot clé
       MotCle motCle; // ref aux mots cle
       while ( !motCle.SimotCle(entreePrinc->tablcar)) 
         {entreePrinc->NouvelleDonnee(); };
       // def de flot externe        
       algori->DefFlotExterne(entreePrinc);
      
       // appel d'une procedure qui definit un exemplaire de chaque element
       // pour que l'edition de lien est lieu effectivement
       //  DefElement();
       // def des classes generales                                
       lesRef = new LesReferences ;  //def des references
       lesCourbes1D = new LesCourbes1D ; // def des courbes1D
       lesFonctionsnD = new LesFonctions_nD(lesCourbes1D); // def des courbes nD
       lesMaillages = new LesMaillages (entreePrinc,paraGlob,lesRef);// def des maillages
       lesLoisDeComp = new LesLoisDeComp ; // def des lois de comportement
       diversStockage = new DiversStockage ;  // stockage divers
       charge = new Charge ;  // chargement
       lesCondLim = new LesCondLim ;  // conditions limites
       resultats = new Resultats(entreePrinc) ; // sortie des resultats
       lescontacts = new LesContacts; // les  contacts éventuelles
     }
    catch (UtilLecture::ErrNouvelleDonnee erreur) 
     { if ( erreur.lecture == 1) 
        { cout << "\n  fin de fichier atteinte ";
          cout << " Il manque des informations !!!! " << endl;
          entreePrinc->MessageBuffer("** lecture du type d\'algorithme **");
          Affiche();
          Sortie (1);
        }
       else if ( erreur.lecture == -1 ) 
        { cout << "\n erreur de lecture,  ";
         // cout << " la derniere ligne lue du fichier est : \n ";
         // cout << entreePrinc->tablcar << endl;
          entreePrinc->MessageBuffer("** lecture du type d\'algorithme **");
          Affiche();
          Sortie (1);
        }
       else 
        { cout << "\n erreur de lecture inconnue  ";
         // cout << " la derniere ligne lue du fichier est : \n ";
         // cout << entreePrinc->tablcar << endl;
          entreePrinc->MessageBuffer("** lecture du type d\'algorithme **");
          Affiche();
          Sortie (1);
        };
     };
	};  

//  démarrage: cas d'une entrée via un fichier .base-info  
void Projet::InitEntreeFichierBaseInfo(string & retour)
     { retour = "calcul_elements_finis";
       
       // les parametres globaux
       paraGlob = new ParaGlob () ; // construction par défaut
       int cas = 1;
       // lecture éventuelle de variables à exporter en grandeur globale
       varExpor = new  VariablesExporter();
       varExpor->Lecture_base_info(*(entreePrinc->Ent_BI()),cas); 
       // lecture de la dimension et du type de calcul
       paraGlob->Lecture_base_info(*(entreePrinc->Ent_BI()),cas);
       int dim = paraGlob->Dimension (); // récup de la dimension  
       // def des valeurs des constantes en fonction de la dimension
       ConstantesTenseur(dim);

       // def de l'algorithme
       algori = Algori::New_Agori
                     (paraGlob->TypeCalcul_maitre(),paraGlob->Avec_typeDeCalcul()
                     ,paraGlob->LesSousTypesDeCalcul()
                     ,paraGlob->Avec_soustypeDeCalcul(),(UtilLecture&) *entreePrinc
                     );
       // def des classes generales
       lesRef = new LesReferences ;  //def des reference
       lesCourbes1D = new LesCourbes1D ; // def des courbes1D
       lesFonctionsnD = new LesFonctions_nD(lesCourbes1D); // def des courbes nD
       lesMaillages = new LesMaillages (entreePrinc,paraGlob,lesRef);// def des maillages
       lesLoisDeComp = new LesLoisDeComp ; // def des lois de comportement
       diversStockage = new DiversStockage ;  // stockage divers
       charge = new Charge ;  // chargement
       lesCondLim = new LesCondLim ;  // conditions limites
       resultats = new Resultats(entreePrinc) ; // sortie des resultats		
       lescontacts = new LesContacts; // les  contacts éventuelles
	   };



