// 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 "Mail_initiale_Gid.h"


#include <iomanip>
#include "ReferenceNE.h"

    // CONSTRUCTEURS :
// par defaut
Mail_initiale_Gid::Mail_initiale_Gid () :
   OrdreVisu("","visualisation des maillages initiaux","")
//   OrdreVisu(".................................maillage initiale"
//             ,"visualisation des maillages initiaux","mi")
   ,tabtab_sous_mesh(),tabli_sig_elem(),tabli_sous_mesh()
   ,decal_noeud(),decal_element()
     {};  
     
     // constructeur de copie 
Mail_initiale_Gid::Mail_initiale_Gid (const Mail_initiale_Gid& ord) :
   OrdreVisu(ord),tabtab_sous_mesh(ord.tabtab_sous_mesh)
   ,tabli_sig_elem(ord.tabli_sig_elem)
   ,tabli_sous_mesh(ord.tabli_sous_mesh)
   ,decal_noeud(ord.decal_noeud),decal_element(ord.decal_element)
      {};
               
    // DESTRUCTEUR :
Mail_initiale_Gid::~Mail_initiale_Gid () 
     {};  
    
    // METHODES PUBLIQUES :  
            
// initialisation : permet d'initialiser les différents paramètres de l'ordre
// lors d'un premier passage des différents incréments
// en virtuelle, a priori est défini si nécessaire dans les classes dérivées
void Mail_initiale_Gid::Initialisation(ParaGlob * paraGlob,LesMaillages * lesmail,LesReferences* lesRef
                      ,LesLoisDeComp* lesLoisDeComp,DiversStockage* diversStockage,Charge* charge
                      ,LesCondLim* lesCondLim,LesContacts* lesContacts
                      ,Resultats* resultats,EnumTypeIncre type_incre,int incre
                      ,const map < string, const double * , std::less <string> >& listeVarGlob
                      ,const List_io < TypeQuelconque >& listeVecGlob
                      ,bool fil_calcul) 
   { // initialisation des tableaux 
     int nb_maillage = lesmail->NbMaillage();
     tabtab_sous_mesh.Change_taille(nb_maillage);
     tabli_sig_elem.Change_taille(nb_maillage); 
     tabli_sous_mesh.Change_taille(nb_maillage);                
     //appel de l'ordre d'initialisation de la classe mère
     OrdreVisu::Initialisation(paraGlob,lesmail,lesRef,lesLoisDeComp,diversStockage,charge
                      ,lesCondLim,lesContacts,resultats,type_incre,incre
                      ,listeVarGlob,listeVecGlob,fil_calcul);
     // la sortie du maillage initial est a priori obligatoire donc on effectue le choix par défaut
     Mail_initiale_Gid::ChoixOrdre();
     // on calcule le décalage de numéros de noeud, du au fait qu'il peut y avoir plusieurs maillages
     decal_noeud.Change_taille(nb_maillage); decal_element.Change_taille(nb_maillage);
     int decal_n = 0; int decal_e=0; // variables intermédiaires
     for (int nm=1;nm<=nb_maillage;nm++)
     	{decal_noeud(nm)=decal_n; decal_element(nm)=decal_e;
     	 decal_n += lesmail->Nombre_noeud(nm);
     	 decal_e += lesmail->Nombre_element(nm);
     	};
   };
            
// execution de l'ordre
// tab_mail : donne les numéros de maillage concerné
// incre : numéro d'incrément qui en cours
// type_incre : indique si c'est le premier le dernier ou l'incrément courant a visualiser ou pas
// animation : indique si l'on est en animation ou pas
// unseul_incre : indique si oui ou non il y a un seul increment à visualiser
void Mail_initiale_Gid::ExeOrdre(ParaGlob * ,const Tableau <int>& tab_mail,LesMaillages * lesMail,bool 
            ,LesReferences* lesRef,LesLoisDeComp* ,DiversStockage*,Charge*,LesCondLim*
//                      ,LesContacts*,Resultats*,ostream & sort,EnumTypeIncre type_incre,int incre
                      ,LesContacts*,Resultats*,UtilLecture & entreePrinc,OrdreVisu::EnumTypeIncre ,int incre
//                      ,bool animation)
                      ,bool,const map < string, const double * , std::less <string> >&
                      ,const List_io < TypeQuelconque >& listeVecGlob)
{ // --- la partie qui suie est systématiquement exécutée, que ce soit actif, ou pas et quelque soit l'incrément --
  // constitue une initialisation pour les autres ordres, mais que l'on ne peut pas mettre dans Initialisation
  // car dépend de tab_mail, qui dépend du choix de l'utilisateur
  
  // on recalcule les décalages de noeuds en fonction des maillages actifs, car c'est utilisé par les isovaleurs et autres
  // ordres, les maillages qui ne sont pas concerné, ont des décal_noe et éléments inchangé donc quelconques, ceci permet de garder les mêmes tailles
  int decal_n = 0; int decal_e=0; // variables intermédiaires
  int nbmail = tab_mail.Taille();
  for (int nm=1;nm<=nbmail;nm++)
   {int numMail=tab_mail(nm);
    decal_noeud(numMail)=decal_n; decal_element(numMail)=decal_e;
    decal_n += lesMail->Nombre_noeud(numMail);
    decal_e += lesMail->Nombre_element(numMail);
   };

  if (incre==0) // dans tous les cas on sort le maillage initiale au premier incrément
   {ostream &sort = entreePrinc.Sort_initial_Gid();
    // on boucle sur les maillages
    int nbmail = tab_mail.Taille();
    for (int im=1;im<=nbmail;im++)
     { int numMail=tab_mail(im);
       // écriture d'une entete
       sort << "\n // ========================================="
            << "\n // |      definition du maillage initiale  |"
            << "\n // =========================================";
       int decal_noe=decal_noeud(numMail); // pour simplifier
       int decal_ele =decal_element(numMail); // pour simplifier
       // on cherche tout d'abord le nombre d'éléments différents dans le maillage     
       List_io <Element::Signature>& li_sig_elem=tabli_sig_elem(numMail);
       li_sig_elem.erase(li_sig_elem.begin(),li_sig_elem.end());
       // on initialise également tabli_sous_mesh(numMail)
       tabli_sous_mesh(numMail).erase(tabli_sous_mesh(numMail).begin(),tabli_sous_mesh(numMail).end());
       // on balaie tous les éléments du maillage
       int nbmaxiElement = lesMail->Nombre_element(numMail);
       List_io <Element::Signature>::iterator ipos;
       for (int numElem=1; numElem<= nbmaxiElement;numElem++) 
         { // recup de la signature de l'élément
           Element::Signature  sig_elem = lesMail->Element_LesMaille(numMail,numElem).Signature_element();
           // on regarde s'il existe déjà
           ipos = find(li_sig_elem.begin(),li_sig_elem.end(),sig_elem);
           if (ipos == li_sig_elem.end()) // enregistrement s'il n'existe pas
                li_sig_elem.push_back(sig_elem);
         };
       // dimensionne le tableau de sous maillages    
       tabtab_sous_mesh(numMail).Change_taille(li_sig_elem.size());   
       // simplification et préparation
       Tableau < List_io <  Element* > >& tab_sous_mesh = tabtab_sous_mesh(numMail);
        
       // maintenant on boucle sur les types d'éléments
       List_io <Element::Signature>::iterator ifin=li_sig_elem.end();
       int num_type = 1;
       for (ipos= li_sig_elem.begin();ipos!=ifin;ipos++,num_type++)
        { // initialisation
          tab_sous_mesh(num_type).erase(tab_sous_mesh(num_type).begin(),tab_sous_mesh(num_type).end());
          // maintenant on sort la  partie d'élément correspondante avec pour la première partie
          //la liste de tous les noeuds
          sort << "\n     #  maillage: " << lesMail->NomMaillage(numMail) << "\n";
          // création du nom du sous maillage 
          ostrstream tab_out;
          tab_out << lesMail->NomMaillage(numMail) << "_" << num_type << ends;
          string nom_sous_maillage = tab_out.str() ;  // le nom
          tabli_sous_mesh(numMail).push_back(nom_sous_maillage); // sauvegarde
          // sortie sur fichier
          sort << "\n MESH \""<< nom_sous_maillage << "\" ";
          int dim = ParaGlob::Dimension(); // récup de la dimension
          if (dim != 1)
            {sort <<" dimension " <<  ParaGlob::Dimension() << " ";}
          else
            // le cas dim = 1 ne semble pas fonctionner par contre avec 3 c'est ok
            // on met donc 3, car de toute façon on rajoute des coordonnées nulles
            {sort <<" dimension " <<  3 << " ";};
          // définition du type d'élément
          sort << "Elemtype " ; bool erreur = false;
          switch ((*ipos).id_geom)
           { case TRIANGLE : case TRIA_AXI:
              { sort << "Triangle ";
                switch ((*ipos).id_interpol)
                  { case LINEAIRE : {sort << " Nnode  3 "; break;}
                    case QUADRACOMPL :{ sort << " Nnode  6 "; break;}
                    case SFE3C: case SFE3 : case SFE2: case SFE1 : // on ne considère que les noeuds centraux
                    case SFE3C_3D: case SFE3_3D : case SFE2_3D: case SFE1_3D :{ sort << " Nnode  3 "; break;}
                    case QSFE1: case QSFE3: // on ne considère que les noeuds centraux
                      { sort << " Nnode  6 "; break;}
                    default : erreur = true;
                  };
                break;
              }
             case QUADRANGLE :   case QUAD_AXI:
              { sort << "Quadrilateral ";
                switch ((*ipos).id_interpol)
                  { case LINEAIRE : {sort << " Nnode  4 "; break;}
                    case QUADRATIQUE : {sort << " Nnode  8 "; break;}
                    case QUADRACOMPL : {sort << " Nnode  9 "; break;}
                    default : erreur = true;
                  };
                break;
              }
             case TETRAEDRE :
              { sort << "Tetrahedra ";
                switch ((*ipos).id_interpol)
                  { case LINEAIRE : {sort << " Nnode  4 "; break;}
                    case QUADRACOMPL : {sort << " Nnode  10 "; break;}
                    default : erreur = true;
                  };
                break;
              }
             case HEXAEDRE : 
              { sort << "Hexahedra ";
                switch ((*ipos).id_interpol)
                 { case LINEAIRE : {sort << " Nnode  8 "; break;}
                   case QUADRATIQUE : {sort << " Nnode  20 "; break;}
                   case QUADRACOMPL : {sort << " Nnode  27 "; break;}
                   default : erreur = true;
                 };
                break;
              }
             case POUT : case SEGMENT : case SEG_AXI:
              { sort << "Linear ";
                switch ((*ipos).id_interpol)
                 { case BIE1  : sort << " Nnode 2 "; break;
                   case LINEAIRE : sort << " Nnode 2 "; break;
                   case QUADRATIQUE : case BIE2 : sort << " Nnode 3 "; break;
                   default : erreur = true;
                 };
                break;
              }
             case POINT : sort << "Point  Nnode 1 "; break;
             case PENTAEDRE : 
              { // il n'y a pas de pentaèdre dans gid, on modélise donc à l'aide d'hexaèdre dont deux arrêtes
                // sont confondu
                sort << "Hexahedra ";
                switch ((*ipos).id_interpol)
                 { case LINEAIRE : {sort << " Nnode  8 "; break;}
                   case QUADRATIQUE : {sort << " Nnode  20 "; break;}
                   case QUADRACOMPL : {sort << " Nnode  27 "; break;}
                   default : erreur = true;
                 };
                break;
              }
             default :
             cout << "\nErreur : cas d'element non traite par Gid ! " << Nom_geom((*ipos).id_geom)
                  << " **********  attention, le fichier maillage initial ne sera pas exploitable !!!\n";
            };
          if (erreur)
          cout << "\nErreur : cas d'element + interpolation non traite par Gid !" << Nom_geom((*ipos).id_geom)
               << " " <<  Nom_interpol((*ipos).id_interpol) 
               << " **********  attention, le fichier de sortie ne sera pas exploitable !!!\n";
          // maintenant on sort la liste de tous les noeuds dans le cas de la première partie
          if (ipos == li_sig_elem.begin())
           { sort << "\n  \n   # tous les noeuds du maillage: " << lesMail->NomMaillage(numMail) << "\n";
             int nbmaxinoeud = lesMail->Nombre_noeud(numMail);
             sort << "\n Coordinates ";
             for (int numNoeud=1; numNoeud<= nbmaxinoeud;numNoeud++) 
               {// recup du noeud
                 Noeud & noe = lesMail->Noeud_LesMaille(numMail,numNoeud);
                 sort << "\n" << noe.Num_noeud()+decal_noe << " " ;
                 const Coordonnee& co = noe.Coord0();
                 co.Affiche(sort,ParaGlob::NbdigdoGR()); 
                 switch (dim) // dans le cas d'une dimension diff de 3, on complète avec des 0
                  { case 1: sort << "  0.   ";
                    case 2: sort << "  0.   ";
                  };
               };
             sort << "\n end coordinates ";
           };
          // on sort les éléments
          sort << "\n  \n   # tous les element du maillage: " << lesMail->NomMaillage(numMail) 
               << " du meme type " << Nom_geom((*ipos).id_geom) << " " <<  Nom_interpol((*ipos).id_interpol) 
               << "\n";
          int nbmaxinoeud = lesMail->Nombre_noeud(numMail);
          sort << "\n Elements ";
          int nbmaxiElement = lesMail->Nombre_element(numMail);
          for (int numElem=1; numElem<= nbmaxiElement;numElem++)
           { // recup de l'élément
             Element & elem = lesMail->Element_LesMaille(numMail,numElem);
             // si c'est la bonne signature on sort l'élément
             if (elem.Signature_element() == *ipos)
              {sort << "\n" << elem.Num_elt() + decal_ele << " ";
               Tableau<Noeud *>& tab_noeud = elem.Tab_noeud();
               int nb_n = tab_noeud.Taille();
               // dans le cas des pentaèdres on a un traitement spécial pour sortir sous forme d'hexaèdres
               if ((*ipos).id_geom == PENTAEDRE)
                {if ((*ipos).id_interpol == LINEAIRE)
                   {for (int j=1;j<=3;j++) // les 3 premiers noeuds
                       sort << tab_noeud(j)->Num_noeud()+decal_noe<< " " ;
                    sort << tab_noeud(3)->Num_noeud()+decal_noe << " " ; // le 4h = 3p
                    for (int j=4;j<=6;j++) // les 3 derniers noeuds
                       sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
                    sort << tab_noeud(6)->Num_noeud()+decal_noe << " " ; // le 8h = 6p
                   }
                 else if((*ipos).id_interpol == QUADRATIQUE)
                   {for (int j=1;j<=3;j++) // les 3 premiers noeuds
                       sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
                    sort << tab_noeud(3)->Num_noeud()+decal_noe << " " ; // le 4h = 3p
                    for (int j=4;j<=6;j++) // les 3 noeuds du dessus
                       sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
                    sort << tab_noeud(6)->Num_noeud()+decal_noe << " " ; // le 8h = 6p
                    for (int j=7;j<=9;j++) // les 3 noeuds intermédiaires du bas
                       sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
                    sort << tab_noeud(9)->Num_noeud()+decal_noe << " " ; // le 12h = 9p
                    for (int j=10;j<=12;j++) // les 3 noeuds à mi-hauteur
                       sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
                    sort << tab_noeud(12)->Num_noeud()+decal_noe << " " ; // le 16h = 12p
                    for (int j=13;j<=15;j++) // les 3 noeuds intermédiaires du dessus
                       sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
                    sort << tab_noeud(15)->Num_noeud()+decal_noe << " " ; // le 20h = 15p
                   }
                 else if((*ipos).id_interpol == QUADRACOMPL)
                   {for (int j=1;j<=3;j++) // les 3 premiers noeuds
                       sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
                    sort << tab_noeud(3)->Num_noeud()+decal_noe << " " ; // le 4h = 3p
                    for (int j=4;j<=6;j++) // les 3 noeuds du dessus
                       sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
                    sort << tab_noeud(6)->Num_noeud()+decal_noe << " " ; // le 8h = 6p
                    for (int j=7;j<=9;j++) // les 3 noeuds intermédiaires du bas
                       sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
                    sort << tab_noeud(9)->Num_noeud()+decal_noe << " " ; // le 12h = 9p
                    for (int j=10;j<=12;j++) // les 3 noeuds à mi-hauteur
                       sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
                    sort << tab_noeud(12)->Num_noeud()+decal_noe << " " ; // le 16h = 12p
                    for (int j=13;j<=15;j++) // les 3 noeuds intermédiaires du dessus
                       sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
                    sort << tab_noeud(15)->Num_noeud()+decal_noe << " " ; // le 20h = 15p
                    sort << tab_noeud(9)->Num_noeud()+decal_noe << " " ; // le 21h = 9p
                    sort << tab_noeud(16)->Num_noeud()+decal_noe << " " ; // le 22h = 16p
                    sort << tab_noeud(17)->Num_noeud()+decal_noe << " " ; // le 23h = 17p
                    sort << tab_noeud(18)->Num_noeud()+decal_noe << " " ; // le 24h = 18p
                    sort << tab_noeud(18)->Num_noeud()+decal_noe << " " ; // le 25h = 18p idem
                    sort << tab_noeud(15)->Num_noeud()+decal_noe << " " ; // le 21h = 15p
                    sort << tab_noeud(18)->Num_noeud()+decal_noe << " " ; // le 27h = 18p
                   };
                }
               else if (ElementSfe((*ipos).id_interpol))
                 // dans le cas des sfe on ne sort que les noeuds du centre
                {for (int j=1;j<=3;j++) // 3 noeuds centraux
                   sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
                }
               else 
                // cas normal
                {for (int j=1;j<=nb_n;j++)
                    sort << tab_noeud(j)->Num_noeud()+decal_noe << " " ;
                };
               // le nb de matériau: pour l'instant on met le numéro de maillage
               sort << numMail;
               // et on sauvegarde la ref à l'élément
               tab_sous_mesh(num_type).push_back(&elem);
              };  
           };
        sort << "\n end elements ";
        // et on vide le buffer de sortie
        sort << endl; 
        }; // -- fin de la boucle sur les types différents de signatures
     
      //----------------------------------------------------------------
      //        cas des références 
      //----------------------------------------------------------------
      int numero_reference=1;
      // 1 -- cas des références de noeuds
      ostream &sart = entreePrinc.Sort_resultat_Gid();
      sart << "\n # ============================================="
           << "\n # |      definition des references de noeuds  |"
           << "\n # ============================================="
           << "\n #  maillage : " << lesMail->NomMaillage(numMail) << "\n"
           << "\n #  decalage des numeros de noeuds : " << decal_noe << " "
           << "\n #  decalage des numeros d'elements : " << decal_ele << " ";
          
      // on va boucler sur les références et sortir les références de noeuds
      const Reference* reff =NULL; bool prempass = true;
      do { if (prempass)
             { reff= lesRef->Init_et_Premiere();} // récup de la ref 1 et init
           else
             { reff = lesRef->Reference_suivante();} // récup de la ref courante  
           // sortie de la ref si c'est le bon maillage, et si c'est une ref de noeud
           if (reff != NULL)
             if ((reff->Nbmaille() == numMail) && (reff->Indic() == 1)) 
              {// on a récupérer une référence de noeud du maillage
               ReferenceNE * refNE =((ReferenceNE*) reff);
               // sortie sur fichier
               sart << "\n\n Result \""<< reff->Nom() <<"_" << numMail << "_\" ";
               sart <<" \"ref_de_noeud\" " <<  incre << " Scalar OnNodes "; 
               // définition du type d'élément
               sart <<  "\n  ComponentNames \"" << reff->Nom()<<"_" << numMail << "\" "; 
               // pas de coordonné car on utilise les coordonnées déjà données
               sart << "\n Values ";
               int reftaille = refNE->Taille();
               for (int nn =1; nn<= reftaille;nn++)  // nn = position des  num de noeud
                  sart << "\n  "  <<  refNE->Numero(nn) + decal_noe << " "<< numero_reference <<" ";
               sart << "\n End Values ";
              };
           prempass = false; 
         } while (reff != NULL);
     };//-- fin de la boucle sur les maillages
   }; //-- fin de if ((actif)&&(incre==0))
};

 
// choix de l'ordre, cet méthode peut entraîner la demande d'informations
// supplémentaires si nécessaire. qui sont ensuite gérer par la classe elle même
void Mail_initiale_Gid::ChoixOrdre()
   { // demande de précision
       // appel de la méthode de la classe mère
       OrdreVisu::ChoixOrdre();    
     };     
            
    
// lecture des paramètres de l'ordre dans un flux
void Mail_initiale_Gid::Lecture_parametres_OrdreVisu(UtilLecture & entreePrinc)
 { // si dans le flot il existe l'identificateur adoc on lit sinon on passe
   if (strstr(entreePrinc.tablcarCVisu,"debut_maillage_initial")!=NULL)
     {// sauvegarde des paramètres  actuelles
      // essaie de lecture
      try 
        { string nom; 
          (*entreePrinc.entCVisu) >> nom ;
          if (nom != "debut_maillage_initial")
            { cout << "\n Erreur en lecture des parametres du maillage initial a partir d'un fichier .CVisu,"
                   << " le premier enregistrement doit etre le mot clef: debut_maillage_initial "
                   << " on ne tiens pas compte  des parametres fournies !! ";
              }
          else
           { // appel de l'ordre de la classe mère
             OrdreVisu::Lect_para_OrdreVisu_general(entreePrinc);
             while (nom != "fin_maillage_initial")
               { (*entreePrinc.entCVisu) >> nom;
                 entreePrinc.NouvelleDonneeCVisu();                    
                }
            }       
         }    
      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 de lecture
       {  cout << "\n Erreur en lecture des parametres du maillage initial a partir d'un fichier .CVisu,"
               << " on ne tiens pas compte  des parametres fournies !! ";
          // récup des infos  sauvées
          if (ParaGlob::NiveauImpression() >= 4)     
             cout  << "\n Mail_initiale_Gid::Lecture_parametres_OrdreVisu(..";
        }
      } 
  };

// écriture des paramètres de l'ordre dans un flux
void Mail_initiale_Gid::Ecriture_parametres_OrdreVisu(UtilLecture & entreePrinc)
 { // récup du flot  
   ostream & sort = (*(entreePrinc.Sort_CommandeVisu()));
   // on commente le fonctionnement
   sort << "\n #  ----------------------------- definition des parametres du maillage initial: ---------------- "
        << "\n debut_maillage_initial  #  un mot cle de debut de liste ";
   // appel de l'ordre de la classe mère
   OrdreVisu::Ecrit_para_OrdreVisu_general(entreePrinc);
   // fin      
   sort << "\n fin_maillage_initial " << " #   le mot cle de fin  \n";    
  };