
// 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-2021 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 "LesMaillages.h"
#include "ElemMeca.h"
#include "ReferenceNE.h"
#include "ReferenceAF.h"
#include "MathUtil.h"
#include "ConstMath.h"
#include "CharUtil.h"
#include "TypeQuelconqueParticulier.h"

#ifndef SYSTEM_MAC_OS_X_unix
 #include "Frontier.h"
#endif

// --------- calcul dynamique ---------
// ajout des ddl de vitesse pour tous les maillages
// pour tous les noeuds qui ont un ddl de déplacement
// val_fixe indique si l'on veut des ddl libres ou pas 
void LesMaillages::Plus_Les_ddl_Vitesse(Enum_boolddl val_fixe)
{ // recup de la dimension
  int dimen = ParaGlob::Dimension();
  // recup de la position de VI-1
  int  posi = Id_nom_ddl("V1") -1;
  // création du tableau de ddl de travail
  Tableau <Ddl> ta(dimen);  
  for (int ii=1; ii<= dimen; ii++) 
   {//ta(ii) = Enum_ddl(ii+posi); // ERREUR D'AFFECTATION, À VOIRE EN DEBUG OU IL VA
    ta(ii) = Ddl (Enum_ddl(ii+posi),0.,val_fixe); // bonne version
   };
  // dans le cas où le calcul est axisymétrique 
  // le dernier ddl en z est mis en HSLIBRE, car on ne le prend pas en compte dans le calcul
  // axisymétrique
  if (ParaGlob::AxiSymetrie()) 
      ta(3) = Ddl (Enum_ddl(3+posi),0.,HSLIBRE); // bonne version;
  // maintenant on passe en revu les noeuds   
  for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
      for (int i2 = 1; i2 <= nbnoeudmax; i2++)
        { // recup du noeud
          Noeud * noo = & Noeud_LesMaille(i1,i2);
          // on regarde si le déplacement existe
          if (noo->Existe_ici(X1))
            noo->PlusTabDdl(ta);
         } 
    };
};


   
// ajout des ddl d'accélération pour tous les maillages
// pour tous les noeuds qui ont un ddl de déplacement
// val_fixe indique si l'on veut des ddl libres ou pas 
void LesMaillages::Plus_Les_ddl_Acceleration(Enum_boolddl val_fixe)
{ // recup de la dimension
  int dimen = ParaGlob::Dimension();
  // recup de la position de GAMMA1-1
  int  posi = Id_nom_ddl("GAMMA1") -1;
  // création du tableau de ddl de travail
  Tableau <Ddl> ta(dimen); 
  for (int ii=1; ii<= dimen; ii++) 
    ta(ii) = Ddl (Enum_ddl(ii+posi),0.,val_fixe); // bonne version
  // dans le cas où le calcul est axisymétrique 
  // le dernier ddl en z est mis en HSLIBRE, car on ne le prend pas en compte dans le calcul
  // axisymétrique
  if (ParaGlob::AxiSymetrie()) 
      ta(3) = Ddl (Enum_ddl(3+posi),0.,HSLIBRE); // bonne version;
  // maintenant on passe en revu les noeuds   
  for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
      for (int i2 = 1; i2 <= nbnoeudmax; i2++)
        { // recup du noeud
          Noeud * noo = & Noeud_LesMaille(i1,i2);
          // on regarde si le déplacement existe
          if (noo->Existe_ici(X1))
            noo->PlusTabDdl(ta);
         } 
      }       
   };

// calcul  de la longueur d'arrête d'élément minimal
// divisé par la célérité dans le matériau
double LesMaillages::Longueur_arrete_mini_sur_c(Enum_dure temps)
 { double dist_ret = ConstMath::tresgrand; // def de la distance de retour
   // on balaie les maillages et les éléments
   for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { int nbelementmax = tabMaillage(i1)->Nombre_element();
      for (int i2 = 1; i2 <= nbelementmax; i2++)
        { Element & elem = Element_LesMaille(i1,i2);
          if (elem.Id_TypeProblem() == MECA_SOLIDE_DEFORMABLE)
             { double dist = ((ElemMeca&) elem).Long_arrete_mini_sur_c(temps);
               dist_ret = MiN(dist_ret,dist);
              } 
         }
     }
     return dist_ret;   
  };
    
// initialisation éventuelle du bulk viscosity
void LesMaillages::Init_bulk_viscosity(int choix,const DeuxDoubles &  coef)
 { // on renseigne la classe générique d'éléments mécanique si besoin
   // choix peut-être égale à 0, 1 ou 2
   if (choix)
    { ElemMeca::ActiveBulkViscosity(choix); // activation du bulk viscosity
      ElemMeca::ChangeCoefsBulkViscosity(coef); // passage des coeffs
     }
  };

// -- encore plus générique
// changement de toutes les conditions données (service, variable, fixage ..)  
// selon le tableau de ddl passé en paramètre
// par contre les valeurs de ta ne sont pas utilisé donc les valeurs actuelles restent inchangé
void LesMaillages::ChangeToutesLesConditions(const Tableau<Ddl>& ta)
{ // création d'une liste qui contiendra tous les ddl à passer aux noeuds
  list <Ddl> liddl;
  // on boucle sur le tableau 
  int taTaille = ta.Taille();
  for (int ita=1;ita<=taTaille;ita++)
   { Ddl& taa=ta(ita);Enum_boolddl enub=taa.Retour_Fixe();
     Tableau<Enum_ddl> tenu = TableauTypeDdl(taa.Id_nom()); // récup du tableau d'enum
     int tenuTaille = tenu.Taille(); 
     for (int i=1;i<=tenuTaille;i++) liddl.push_back(Ddl(tenu(i),0.,enub));
    };
  // création du tableau de travail que l'on passera aux noeuds 
  Tableau<Ddl> tddl(liddl.size()); 
  list<Ddl>::iterator il,ifin=liddl.end();int iii=1;
  for (il=liddl.begin();il!=ifin;il++,iii++) tddl(iii)=(*il);
  // maintenant on passe en revue les noeuds   
  for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
      for (int i2 = 1; i2 <= nbnoeudmax; i2++)
        { // recup du noeud
          Noeud * noo = & Noeud_LesMaille(i1,i2);
          noo->ChangeToutesLesConditions(tddl);
         } 
      }       
 };

// changement de statu des ddl d'une combinaison, en fonction du statut
// de enuta dans chaque noeud, les ddl de la combinaison, prennent le même statut que celui
// de enuta dans chaque noeud.
// cas est la combinaison,
void LesMaillages::ChangeStatut(int cas,Enum_ddl enuta)
 {// on passe en revue les noeuds   
  for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
      for (int i2 = 1; i2 <= nbnoeudmax; i2++)
        { // recup du noeud
          Noeud * noo = & Noeud_LesMaille(i1,i2);
          noo->ChangeStatut(cas,enuta);
         } 
      }       
 };

// changement de statu des ddl d'une combinaison dans chaque noeud, en fonction
// de enubold, les ddl de la combinaison, prennent le même statut que enubold
// cas est la combinaison,
void LesMaillages::ChangeStatut(int cas,Enum_boolddl enubold)
 {// on passe en revue les noeuds   
  for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
      for (int i2 = 1; i2 <= nbnoeudmax; i2++)
        { // recup du noeud
          Noeud * noo = & Noeud_LesMaille(i1,i2);
          noo->ChangeStatut(cas,enubold);
         } 
      }       
 };

//change le statut de tous les ddl liés à la physique en cours
//par exemple: met à libre ou bloque les ddl liés à la physique en cours
void LesMaillages::Libere_Ddl_representatifs_des_physiques(Enum_boolddl enubold)
 { // ddl_representatifs_des_physiques représentent tous les ddl de la physique
   if (ddl_representatifs_des_physiques.size()) // on ne continue que si c'est diff de 0
    {list <Enum_ddl >::iterator il,ilfin=  ddl_representatifs_des_physiques.end();
     list <Enum_ddl >::iterator ildebut = ddl_representatifs_des_physiques.begin();
     // on fait un premier balayage, car il s'agit des "types" de ddl mais pas de la liste
     // qui elle dépend de la dimension éventuellement
     int nbddl = 0; // init
     for (il = ildebut;il != ilfin; il++)
       nbddl += TableauTypeDdl(*il).Taille();
     // on définit un tableau "ta" pour appeler les noeuds
     // qui contient tous les ddl (et pas seulement les types)
     Ddl enu((*ildebut),0.0,enubold); // def du premier ddl
     Tableau<Ddl> ta(nbddl,enu); int ita=1;
     for (il = ildebut;il != ilfin; il++)
       {Tableau<Enum_ddl> tddl = TableauTypeDdl(*il);
        int ndPlus1 = tddl.Taille() + 1;
        for (int i=1;i< ndPlus1;i++,ita++)
         ta(ita).Change_nom(tddl(i));
       };
     // on passe en revue les noeuds
     for (int i1 = 1; i1<= nbMaillageTotal; i1++)
      { int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
        for (int i2 = 1; i2 <= nbnoeudmax; i2++)
          { // recup du noeud
            Noeud * noo = & Noeud_LesMaille(i1,i2);
            // on change les conditions données par ta
            noo->ChangeToutesLesConditions(ta);
           };
      };
    };
 };


//----- lecture écriture base info -----
// lecture base info
	 // cas donne le niveau de la récupération 
     // = 1 : on récupère tout
     // = 2 : on récupère uniquement les données variables (supposées comme telles)
void LesMaillages::Lecture_base_info(ifstream& ent,const int cas)
 { string toto;
//   cout << "\n debug **** LesMaillages::Lecture_base_info\n"
//        << "\n entr.rdstate() " << ent.rdstate() << flush;
   // lecture du nombre de maillage total
   ent >> toto >> nbMaillageTotal;
//  cout << "\n debug **** LesMaillages::Lecture_base_info\n"
//       << " toto= "<< toto << nbMaillageTotal
//       << "\n entr.rdstate() " << ent.rdstate() << flush;

   switch (cas)
   { case 1 : // ------- on récupère tout -------------------------
      {for (int i1 = 1; i1<= nbMaillageTotal; i1++)
        { // tout d'abord création du maillage
          tabMaillage(i1) = new Maillage (mapNomMail,i1,paraGlob->Dimension());
          // puis lecture
          tabMaillage(i1)->Lecture_base_info(ent,cas);
        };
       // on s'occupe de mettre à jour les types de pb et les ddl types associés
       Mise_a_jour_type_pb_type_associe_ddl();
       break;
      }
     case  2 : // ----------- on ne récupère que ce qui varie
      { for (int i1 = 1; i1<= nbMaillageTotal; i1++)
          tabMaillage(i1)->Lecture_base_info(ent,cas);
        // ----- cas des grandeurs intégrés éventuelles-----
        //  utile pour pouvoir post-traiter et également pour le cumul sur le temps
        ent >> toto;
        if (toto != "int_vol_mail")
         { cout << "\nErreur : en lecture de l'entete de l'integration de volume eventuelle"
                << " on attendait le mot cle int_vol_mail et on a lu "<< toto <<"  !\n";
           cout << "LesMaillages::Lecture_base_info(....)" << flush;
           Sortie(1);
         };
        int integ_vol_typeQuel_taille = 0;
        ent >> integ_vol_typeQuel_taille;
        // on boucle sur les grandeurs à lire
        // si la grandeur existe déjà, elle est mise à jour, sinon elle est crée
        // mais dans ce cas elle ne changera plus pendant le calcul
        for (int i=1;i<= integ_vol_typeQuel_taille;i++)
          { // on lit l'entête d'un type quelconque
            //  -> on crée un grandeur quelconque sans grandeur associé ceci pour lire les entêtes
            TypeQuelconque pour_lire(RIEN_TYPEQUELCONQUE);
            TypeQuelconque pour_lire_t(RIEN_TYPEQUELCONQUE);
            // lecture de l'entête et récup d'enu
            // on utilise: avec création, car il peut s'agir d'une intégrale qui n'est plus active
            // du coup le tableau existant ne contient pas cette intégrale
            EnuTypeQuelParticulier enu_t =
                           pour_lire_t.Lecture_un_avec_creation_TypeQuelconque_enum_etendu(ent);
            int indice_t = integ_vol_typeQuel_t.Contient(pour_lire_t);
            if (indice_t)
              {// là il suffit de lire la grandeur associée
               ent >> (*integ_vol_typeQuel_t(indice_t).Grandeur_pointee());
              };
            // normalement le cas a tdt est identique
            EnuTypeQuelParticulier enu =
                           pour_lire.Lecture_un_avec_creation_TypeQuelconque_enum_etendu(ent);
            // là on regarde dans le tableau existant, pour voir s'il existe déjà le bon conteneur
            // le test se fait uniquement sur le TypeQuelconque_enum_etendu
            // qui est supposé suffisant comme signature
            int indice = integ_vol_typeQuel.Contient(pour_lire);
            if (indice)
              {// là il suffit de lire la grandeur associée
               ent >> (*integ_vol_typeQuel(indice).Grandeur_pointee());
              };
            if (!indice)
              { // sinon c'est plus compliqué car cela signifie qu'il va s'agir d'une grandeur
                // figée, dont la valeur ne changera pas pendant le calcul
                // création d'une grandeur associée et lecture des information sur le flot
                TypeQuelconque::Grandeur* grandeur_t =NevezGrandeurParticuliereEnLecture(enu_t,ent);
                // création du type quelconque
                TypeQuelconque typQ_t(pour_lire_t.EnuTypeQuelconque(),pour_lire_t.Enum(),*grandeur_t);
                delete grandeur_t; // car il ne sert plus à rien
                TypeQuelconque::Grandeur* grandeur =NevezGrandeurParticuliereEnLecture(enu,ent);
                // création du type quelconque
                TypeQuelconque typQ(pour_lire.EnuTypeQuelconque(),pour_lire.Enum(),*grandeur);
                delete grandeur; // car il ne sert plus à rien


                // maintenant on va mettre à jour le stockage interne
                // ici on rajoute à la fin des tableaux, donc cela ne change pas ce qui a été lue
                // à l'initialisation du .info
                indice_t = integ_vol_typeQuel_t.Taille()+1;
                indice = integ_vol_typeQuel.Taille()+1;
                integ_vol_typeQuel_t.Change_taille(indice_t);
                integ_vol_typeQuel.Change_taille(indice);
                integ_vol_typeQuel(indice) = typQ;
                integ_vol_typeQuel_t(indice_t) = typQ_t;
                ref_integ_vol.Change_taille(indice);// normalement c'est le même qu'indice_t
                // par défaut on met la ref à NULL, ce qui veut dire que la grandeur est
                // figé, car aucun domaine d'intégration n'a été définit
                ref_integ_vol(indice) = NULL;
              };
            // on va créer ou mettre à jour une grandeur globale associée
            {TypeQuelconque& TQ_t = integ_vol_typeQuel_t(indice); // pour simplifier
             // cas des grandeurs à t: on alimente les grandeurs globales
             // le conteneur qui contient le résultat globalisé
             TypeQuelconque::Grandeur* g_TG_t = TQ_t.Grandeur_pointee();
             const string* nom_de_ref = g_TG_t->Nom_ref();
             #ifdef MISE_AU_POINT
             if (nom_de_ref == NULL)
                { cout << "\n *** pb dans l'integration  !! "
                       << " nom_de_ref est nul, on ne peut pas continuer  "
                       << "\n LesMaillages::Lecture_base_info(..."<<flush;
                  Sortie(1);
                };
             #endif
             // récup du pointeur de conteneur éventuel
             const void* pointe =  (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
             if (pointe == NULL)
               // la grandeur n'existe pas on la définie
                ParaGlob::param->Ajout_grandeur_consultable(&integ_vol_typeQuel_t(indice),*nom_de_ref);
             else // sinon on affecte
              {TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
               (gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG_t));
              };
            };
           // idem pour la grandeur courante
            {TypeQuelconque& TQ = integ_vol_typeQuel(indice); // pour simplifier
             // cas des grandeurs à tdt: on alimente les grandeurs globales
             // le conteneur qui contient le résultat globalisé
             TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
             const string* nom_de_ref = g_TG->Nom_ref();
             #ifdef MISE_AU_POINT
             if (nom_de_ref == NULL)
                { cout << "\n *** pb dans l'integration  !! "
                       << " nom_de_ref est nul, on ne peut pas continuer  "
                       << "\n LesMaillages::Lecture_base_info(..."<<flush;
                  Sortie(1);
                };
             #endif
             // récup du pointeur de conteneur éventuel
             const void* pointe =  (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
             if (pointe == NULL)
               // la grandeur n'existe pas on la définie
                ParaGlob::param->Ajout_grandeur_consultable(&integ_vol_typeQuel(indice),*nom_de_ref);
             else // sinon on affecte
              {TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
               // la valeur passée en paramétre est celle de t !!
               (gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG));
              };
            };
          }; // boucle sur les grandeurs lues
                 
                 
        // maintenant les intégrales de volume et en temps
        ent >> toto;
        if (toto != "int_vol_temps_mail")
         { cout << "\nErreur : en lecture de l'entete de l'integration de volume et en temps eventuelle"
                << " on attendait le mot cle int_vol_temps_mail et on a lu "<< toto <<"  !\n";
           cout << "LesMaillages::Lecture_base_info(....)" << flush;
           Sortie(1);
         };
        int integ_vol_t_typeQuel_taille = 0;
        ent >> integ_vol_t_typeQuel_taille;
        // on boucle sur les grandeurs à lire
        // si la grandeur existe déjà, elle est mise à jour, sinon elle est crée
        // mais dans ce cas elle ne changera plus pendant le calcul
        for (int i=1;i<= integ_vol_t_typeQuel_taille;i++)
           { // on lit l'entête d'un type quelconque
             //  -> on crée un grandeur quelconque sans grandeur associé ceci pour lire les entêtes
             TypeQuelconque pour_lire_t(RIEN_TYPEQUELCONQUE);
             TypeQuelconque pour_lire(RIEN_TYPEQUELCONQUE);
             // lecture de l'entête et récup d'enu
             // on utilise: avec création, car il peut s'agire d'une intégrale qui n'est plus active
             // du coup le tableau exitant ne contient pas cette intégrale
             EnuTypeQuelParticulier enu_t =
                            pour_lire_t.Lecture_un_avec_creation_TypeQuelconque_enum_etendu(ent);
             // là on regarde dans le tableau existant, pour voir s'il existe déjà le bon conteneur
             // le test se fait uniquement sur le TypeQuelconque_enum_etendu
             // qui est supposé suffisant comme signature
             int indice_t = integ_vol_t_typeQuel_t.Contient(pour_lire_t);
             if (indice_t)
               {// là il suffit de lire la grandeur associée
                ent >> (*integ_vol_t_typeQuel_t(indice_t).Grandeur_pointee());
               };
             // idem à t
             EnuTypeQuelParticulier enu =
                            pour_lire.Lecture_un_avec_creation_TypeQuelconque_enum_etendu(ent);
             int indice = integ_vol_t_typeQuel.Contient(pour_lire);
             if (indice)
               {// là il suffit de lire la grandeur associée
                ent >> (*integ_vol_t_typeQuel(indice).Grandeur_pointee());
               };
             if (!indice)
               { // sinon c'est plus compliqué car cela signifie qu'il va s'agir d'une grandeur
                 // figée, dont la valeur ne changera pas pendant le calcul
                 // création d'une grandeur associée et lecture des information sur le flot
                 TypeQuelconque::Grandeur* grandeur_t =NevezGrandeurParticuliereEnLecture(enu_t,ent);
                 // création du type quelconque
                 TypeQuelconque typQ_t(pour_lire_t.EnuTypeQuelconque(),pour_lire_t.Enum(),*grandeur_t);
                 delete grandeur_t; // car il ne sert plus à rien
                 TypeQuelconque::Grandeur* grandeur =NevezGrandeurParticuliereEnLecture(enu,ent);
                 // création du type quelconque
                 TypeQuelconque typQ(pour_lire.EnuTypeQuelconque(),pour_lire.Enum(),*grandeur);
                 delete grandeur; // car il ne sert plus à rien
                 // maintenant on va mettre à jour le stockage interne
                 // ici on rajoute à la fin des tableaux, donc cela ne change pas ce qui a été lue
                 // à l'initialisation du .info
                 indice = integ_vol_t_typeQuel_t.Taille()+1;
                 integ_vol_t_typeQuel_t.Change_taille(indice);
                 integ_vol_t_typeQuel.Change_taille(indice);
                 integ_vol_t_typeQuel(indice) = typQ;
                 integ_vol_t_typeQuel_t(indice) = typQ_t;
                 ref_integ_vol_t.Change_taille(indice);
                 // par défaut on met la ref à NULL, ce qui veut dire que la grandeur est
                 // figé, car aucun domaine d'intégration n'a été définit
                 ref_integ_vol_t(indice) = NULL;
               };
             // on va créer ou mettre à jour une grandeur globale associée
             {TypeQuelconque& TQ_t = integ_vol_t_typeQuel_t(indice); // pour simplifier
              TypeQuelconque& TQ = integ_vol_t_typeQuel(indice); // pour simplifier
              // transfert des intégrales finalisées
              // on considère que les grandeurs à tdt doivent être initialisées à celles de t
              (TQ_t.Grandeur_pointee())->Affectation_numerique(*(TQ.Grandeur_pointee()));
              // cas des grandeurs à t: on alimente les grandeurs globales
              // le conteneur qui contient le résultat globalisé
              TypeQuelconque::Grandeur* g_TG_t = TQ_t.Grandeur_pointee();
              const string* nom_de_ref = g_TG_t->Nom_ref();
              #ifdef MISE_AU_POINT
              if (nom_de_ref == NULL)
                 { cout << "\n *** pb dans l'integration  !! "
                        << " nom_de_ref est nul, on ne peut pas continuer  "
                        << "\n LesMaillages::Lecture_base_info(..."<<flush;
                   Sortie(1);
                 };
              #endif
              // récup du pointeur de conteneur éventuel
              const void* pointe =  (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
              if (pointe == NULL)
                // la grandeur n'existe pas on la définie
                 ParaGlob::param->Ajout_grandeur_consultable(&integ_vol_t_typeQuel_t(indice),*nom_de_ref);
              else // sinon on affecte
               {TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
                (gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG_t));
               };
             };
              // cas des grandeurs à tdt
          //             integ_vol_t_typeQuel(i) = integ_vol_t_typeQuel_t(i);
                     
              // on va créer ou mettre à jour une grandeur globale associée
             {TypeQuelconque& TQ = integ_vol_t_typeQuel(indice); // pour simplifier
              // cas des grandeurs à tdt: on alimente les grandeurs globales
              // le conteneur qui contient le résultat globalisé
              TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
              const string* nom_de_ref = g_TG->Nom_ref();
              #ifdef MISE_AU_POINT
              if (nom_de_ref == NULL)
                 { cout << "\n *** pb dans l'integration  !! "
                        << " nom_de_ref est nul, on ne peut pas continuer  "
                        << "\n LesMaillages::Lecture_base_info(..."<<flush;
                   Sortie(1);
                 };
              #endif
              // récup du pointeur de conteneur éventuel
              const void* pointe =  (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
              if (pointe == NULL)
                // la grandeur n'existe pas on la définie
                 ParaGlob::param->Ajout_grandeur_consultable(&integ_vol_t_typeQuel(indice),*nom_de_ref);
              else // sinon on affecte
               {TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
                (gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG));
               };
             };
           }; // boucle sur les grandeurs lues
          // déjà fait
          //        integ_vol_t_typeQuel = integ_vol_t_typeQuel_t; // init

        // ----- cas des statistiques éventuelles-----
        //  utile pour pouvoir post-traiter et également pour le cumul sur le temps
        ent >> toto;
        if (toto != "statistique_mail")
         { cout << "\nErreur : en lecture de l'entete de statistique eventuelle"
                << " on attendait le mot cle statistique_mail et on a lu "<< toto <<"  !\n";
           cout << "LesMaillages::Lecture_base_info(....)" << flush;
           Sortie(1);
         };
        int statistique_typeQuel_taille = 0;
        ent >> statistique_typeQuel_taille;
        // on boucle sur les grandeurs à lire
        // si la grandeur existe déjà, elle est mise à jour, sinon elle est crée
        // mais dans ce cas elle ne changera plus pendant le calcul
        for (int i=1;i<= statistique_typeQuel_taille;i++)
          { // on lit l'entête d'un type quelconque
            //  -> on crée un grandeur quelconque sans grandeur associé ceci pour lire les entêtes
            TypeQuelconque pour_lire(RIEN_TYPEQUELCONQUE);
            TypeQuelconque pour_lire_t(RIEN_TYPEQUELCONQUE);
            // lecture de l'entête et récup d'enu
            // on utilise: avec création, car il peut s'agir d'une statistique qui n'est plus active
            // du coup le tableau existant ne contient pas cette statistique
            EnuTypeQuelParticulier enu_t =
                           pour_lire_t.Lecture_un_avec_creation_TypeQuelconque_enum_etendu(ent);
            int indice_t = statistique_typeQuel_t.Contient(pour_lire_t);
            if (indice_t)
              {// là il suffit de lire la grandeur associée
               ent >> (*statistique_typeQuel_t(indice_t).Grandeur_pointee());
              };
            // normalement le cas a tdt est identique
            EnuTypeQuelParticulier enu =
                           pour_lire.Lecture_un_avec_creation_TypeQuelconque_enum_etendu(ent);
            // là on regarde dans le tableau existant, pour voir s'il existe déjà le bon conteneur
            // le test se fait uniquement sur le TypeQuelconque_enum_etendu
            // qui est supposé suffisant comme signature
            int indice = statistique_typeQuel.Contient(pour_lire);
            if (indice)
              {// là il suffit de lire la grandeur associée
               ent >> (*statistique_typeQuel(indice).Grandeur_pointee());
              };
            if (!indice)
              { // sinon c'est plus compliqué car cela signifie qu'il va s'agir d'une grandeur
                // figée, dont la valeur ne changera pas pendant le calcul
                // création d'une grandeur associée et lecture des information sur le flot
                TypeQuelconque::Grandeur* grandeur_t =NevezGrandeurParticuliereEnLecture(enu_t,ent);
                // création du type quelconque
                TypeQuelconque typQ_t(pour_lire_t.EnuTypeQuelconque(),pour_lire_t.Enum(),*grandeur_t);
                delete grandeur_t; // car il ne sert plus à rien
                TypeQuelconque::Grandeur* grandeur =NevezGrandeurParticuliereEnLecture(enu,ent);
                // création du type quelconque
                TypeQuelconque typQ(pour_lire.EnuTypeQuelconque(),pour_lire.Enum(),*grandeur);
                delete grandeur; // car il ne sert plus à rien


                // maintenant on va mettre à jour le stockage interne
                // ici on rajoute à la fin des tableaux, donc cela ne change pas ce qui a été lue
                // à l'initialisation du .info
                indice_t = statistique_typeQuel_t.Taille()+1;
                indice = statistique_typeQuel.Taille()+1;
                statistique_typeQuel_t.Change_taille(indice_t);
                statistique_typeQuel.Change_taille(indice);
                statistique_typeQuel(indice) = typQ;
                statistique_typeQuel_t(indice_t) = typQ_t;
                ref_statistique.Change_taille(indice);// normalement c'est le même qu'indice_t
                // par défaut on met la ref à NULL, ce qui veut dire que la grandeur est
                // figé, car aucune ref de statistique n'a été définie
                ref_statistique(indice) = NULL;
              };
            // on va créer ou mettre à jour une grandeur globale associée
            {TypeQuelconque& TQ_t = statistique_typeQuel_t(indice); // pour simplifier
             // cas des grandeurs à t: on alimente les grandeurs globales
             // le conteneur qui contient le résultat globalisé
             TypeQuelconque::Grandeur* g_TG_t = TQ_t.Grandeur_pointee();
             const string* nom_de_ref = g_TG_t->Nom_ref();
             #ifdef MISE_AU_POINT
             if (nom_de_ref == NULL)
                { cout << "\n *** pb dans statistique  !! "
                       << " nom_de_ref est nul, on ne peut pas continuer  "
                       << "\n LesMaillages::Lecture_base_info(..."<<flush;
                  Sortie(1);
                };
             #endif
             // récup du pointeur de conteneur éventuel
             const void* pointe =  (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
             if (pointe == NULL)
               // la grandeur n'existe pas on la définie
                ParaGlob::param->Ajout_grandeur_consultable(&statistique_typeQuel_t(indice),*nom_de_ref);
             else // sinon on affecte
              {TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
               (gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG_t));
              };
            };
           // idem pour la grandeur courante
            {TypeQuelconque& TQ = statistique_typeQuel(indice); // pour simplifier
             // cas des grandeurs à tdt: on alimente les grandeurs globales
             // le conteneur qui contient le résultat globalisé
             TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
             const string* nom_de_ref = g_TG->Nom_ref();
             #ifdef MISE_AU_POINT
             if (nom_de_ref == NULL)
                { cout << "\n *** pb dans statistique  !! "
                       << " nom_de_ref est nul, on ne peut pas continuer  "
                       << "\n LesMaillages::Lecture_base_info(..."<<flush;
                  Sortie(1);
                };
             #endif
             // récup du pointeur de conteneur éventuel
             const void* pointe =  (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
             if (pointe == NULL)
               // la grandeur n'existe pas on la définie
                ParaGlob::param->Ajout_grandeur_consultable(&statistique_typeQuel(indice),*nom_de_ref);
             else // sinon on affecte
              {TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
               // la valeur passée en paramétre est celle de t !!
               (gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG));
              };
            };
          }; // boucle sur les grandeurs lues

        // maintenant les statistiques avec cumul  en temps
        ent >> toto;
        if (toto != "statistique_temps_mail")
         { cout << "\nErreur : en lecture de l'entete de la statistique avec cumul en temps eventuelle"
                << " on attendait le mot cle statistique_temps_mail et on a lu "<< toto <<"  !\n";
           cout << "LesMaillages::Lecture_base_info(....)" << flush;
           Sortie(1);
         };
        int statistique_t_typeQuel_taille = 0;
        ent >> statistique_t_typeQuel_taille;
        // on boucle sur les grandeurs à lire
        // si la grandeur existe déjà, elle est mise à jour, sinon elle est crée
        // mais dans ce cas elle ne changera plus pendant le calcul
        for (int i=1;i<= statistique_t_typeQuel_taille;i++)
          { // on lit l'entête d'un type quelconque
            //  -> on crée un grandeur quelconque sans grandeur associé ceci pour lire les entêtes
            TypeQuelconque pour_lire_t(RIEN_TYPEQUELCONQUE);
            TypeQuelconque pour_lire(RIEN_TYPEQUELCONQUE);
            // lecture de l'entête et récup d'enu
            // on utilise: avec création, car il peut s'agir d'une statistique qui n'est plus active
            // du coup le tableau exitant ne contient pas cette statistique
            EnuTypeQuelParticulier enu_t =
                           pour_lire_t.Lecture_un_avec_creation_TypeQuelconque_enum_etendu(ent);
            // là on regarde dans le tableau existant, pour voir s'il existe déjà le bon conteneur
            // le test se fait uniquement sur le TypeQuelconque_enum_etendu
            // qui est supposé suffisant comme signature
            int indice_t = statistique_t_typeQuel_t.Contient(pour_lire_t);
            if (indice_t)
              {// là il suffit de lire la grandeur associée
               ent >> (*statistique_t_typeQuel_t(indice_t).Grandeur_pointee());
              };
            // idem à t
            EnuTypeQuelParticulier enu =
                           pour_lire.Lecture_un_avec_creation_TypeQuelconque_enum_etendu(ent);
            int indice = statistique_t_typeQuel.Contient(pour_lire);
            if (indice)
              {// là il suffit de lire la grandeur associée
               ent >> (*statistique_t_typeQuel(indice).Grandeur_pointee());
              };
            if (!indice)
              { // sinon c'est plus compliqué car cela signifie qu'il va s'agir d'une grandeur
                // figée, dont la valeur ne changera pas pendant le calcul
                // création d'une grandeur associée et lecture des information sur le flot
                TypeQuelconque::Grandeur* grandeur_t =NevezGrandeurParticuliereEnLecture(enu_t,ent);
                // création du type quelconque
                TypeQuelconque typQ_t(pour_lire_t.EnuTypeQuelconque(),pour_lire_t.Enum(),*grandeur_t);
                delete grandeur_t; // car il ne sert plus à rien
                TypeQuelconque::Grandeur* grandeur =NevezGrandeurParticuliereEnLecture(enu,ent);
                // création du type quelconque
                TypeQuelconque typQ(pour_lire.EnuTypeQuelconque(),pour_lire.Enum(),*grandeur);
                delete grandeur; // car il ne sert plus à rien
                // maintenant on va mettre à jour le stockage interne
                // ici on rajoute à la fin des tableaux, donc cela ne change pas ce qui a été lue
                // à l'initialisation du .info
                indice = statistique_t_typeQuel_t.Taille()+1;
                statistique_t_typeQuel_t.Change_taille(indice);
                statistique_t_typeQuel.Change_taille(indice);
                statistique_t_typeQuel(indice) = typQ;
                statistique_t_typeQuel_t(indice) = typQ_t;
                ref_statistique_t.Change_taille(indice);
                // par défaut on met la ref à NULL, ce qui veut dire que la grandeur est
                // figé, car aucune ref de noeuds  n'a été définie
                ref_statistique_t(indice) = NULL;
              };
            // on va créer ou mettre à jour une grandeur globale associée
            {TypeQuelconque& TQ_t = statistique_t_typeQuel_t(indice); // pour simplifier
             TypeQuelconque& TQ = statistique_t_typeQuel(indice); // pour simplifier
             // transfert des statistiques finalisées
             // on considère que les grandeurs à tdt doivent être initialisées à celles de t
             (TQ_t.Grandeur_pointee())->Affectation_numerique(*(TQ.Grandeur_pointee()));
             // cas des grandeurs à t: on alimente les grandeurs globales
             // le conteneur qui contient le résultat globalisé
             TypeQuelconque::Grandeur* g_TG_t = TQ_t.Grandeur_pointee();
             const string* nom_de_ref = g_TG_t->Nom_ref();
             #ifdef MISE_AU_POINT
             if (nom_de_ref == NULL)
                { cout << "\n *** pb dans l'integration  !! "
                       << " nom_de_ref est nul, on ne peut pas continuer  "
                       << "\n LesMaillages::Lecture_base_info(..."<<flush;
                  Sortie(1);
                };
             #endif
             // récup du pointeur de conteneur éventuel
             const void* pointe =  (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
             if (pointe == NULL)
               // la grandeur n'existe pas on la définie
                ParaGlob::param->Ajout_grandeur_consultable(&statistique_t_typeQuel_t(indice),*nom_de_ref);
             else // sinon on affecte
              {TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
               (gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG_t));
              };
            };

             // on va créer ou mettre à jour une grandeur globale associée
            {TypeQuelconque& TQ = statistique_t_typeQuel(indice); // pour simplifier
             // cas des grandeurs à tdt: on alimente les grandeurs globales
             // le conteneur qui contient le résultat globalisé
             TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
             const string* nom_de_ref = g_TG->Nom_ref();
             #ifdef MISE_AU_POINT
             if (nom_de_ref == NULL)
                { cout << "\n *** pb dans statistique avec cuml en temps  !! "
                       << " nom_de_ref est nul, on ne peut pas continuer  "
                       << "\n LesMaillages::Lecture_base_info(..."<<flush;
                  Sortie(1);
                };
             #endif
             // récup du pointeur de conteneur éventuel
             const void* pointe =  (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
             if (pointe == NULL)
               // la grandeur n'existe pas on la définie
                ParaGlob::param->Ajout_grandeur_consultable(&statistique_t_typeQuel(indice),*nom_de_ref);
             else // sinon on affecte
              {TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
               (gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG));
              };
            };
          }; // boucle sur les grandeurs lues

	     break;
	    }
     default :
	    { cout << "\nErreur : valeur incorrecte du type de sauvegarde !\n";
	      cout << "LesMaillages::Lecture_base_info(....)"
			         << " cas= " << cas << flush;
	      Sortie(1);
     };
	  };
 };
//   écriture base info   
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void LesMaillages::Ecriture_base_info(ofstream& sort,const int cas)
  { sort << "\n ****les_maillages:_nombre= " << nbMaillageTotal ;
    for (int i1 = 1; i1<= nbMaillageTotal; i1++)
      tabMaillage(i1)->Ecriture_base_info(sort,cas);

    switch (cas)
     { case 2 : // ----------- sauvegarde uniquement de se qui varie --------------------
      { // ----- cas des grandeurs intégrés éventuelles-----
        //  utile pour pouvoir post-traiter et également pour le cumul sur le temps
        // 1) les intégrales de volume
        sort << "\n\n int_vol_mail ";
        int integ_vol_typeQuel_taille = integ_vol_typeQuel.Taille();
        if (integ_vol_typeQuel_taille == 0)
          sort << 0; else sort << integ_vol_typeQuel_taille;
        sort << " ";
        for (int i=1;i<= integ_vol_typeQuel_taille;i++)
        // il faut que l'on sauvegarde à t et tdt sinon au restart les grandeurs à tdt n'existe pas
          sort << "\n" << integ_vol_typeQuel_t(i) << " "<<integ_vol_typeQuel(i);
        // 2) les intégrales de volume et de temps
        sort << "\n int_vol_temps_mail ";
        int integ_vol_t_typeQuel_taille = integ_vol_t_typeQuel.Taille();
        if (integ_vol_t_typeQuel_taille == 0) sort << 0; else  sort <<integ_vol_t_typeQuel_taille;
        sort << " ";
        for (int i=1;i<= integ_vol_t_typeQuel_taille;i++)
          sort << "\n" << integ_vol_t_typeQuel_t(i)<< " "<<integ_vol_t_typeQuel(i);

        // ----- cas des grandeurs statistique éventuelles-----
        //  utile pour pouvoir post-traiter et également pour le cumul sur le temps
        // 1) les statistiques sur des ref de noeuds
        sort << "\n\n statistique_mail ";
        int statistique_typeQuel_taille = statistique_typeQuel.Taille();
        if (statistique_typeQuel_taille == 0)
          sort << 0; else sort << statistique_typeQuel_taille;
        sort << " ";
        for (int i=1;i<= statistique_typeQuel_taille;i++)
        // il faut que l'on sauvegarde à t et tdt sinon au restart les grandeurs à tdt n'existe pas
          sort << "\n" << statistique_typeQuel_t(i) << " "<<statistique_typeQuel(i);
        // 2) les statistiques avec cumul sur le temps
        sort << "\n statistique_temps_mail ";
        int statistique_t_typeQuel_taille = statistique_t_typeQuel.Taille();
        if (statistique_t_typeQuel_taille == 0) sort << 0; else  sort <<statistique_t_typeQuel_taille;
        sort << " ";
        for (int i=1;i<= statistique_t_typeQuel_taille;i++)
          sort << "\n" << statistique_t_typeQuel_t(i)<< " "<<statistique_t_typeQuel(i);;
       }
     };

   };
     
// sortie du schemaXML: en fonction de enu  
void LesMaillages::SchemaXML_LesMaillages(ofstream& sort,const Enum_IO_XML enu) const
 { switch (enu)  
    {case XML_TYPE_GLOBAUX:
 	   { // cas des classes de base
 	     DeuxEntiers toto;
 	     toto.SchemaXML_DeuxEntiers(sort,enu);
       Maillage::SchemaXML_Maillages(sort,enu) ;
       break;		
      }
     case XML_IO_POINT_INFO:
      {// cas de def de  LesMaillages
       sort  << "\n      <xs:element name=\"LesMaillages\" >"
  	          << "\n        <xs:complexType>"
  	          << "\n          <xs:annotation>"
  	          << "\n            <xs:documentation> une suite de maillages </xs:documentation>"
  	          << "\n          </xs:annotation>"
             << "\n          <xs:sequence>"
             << "\n            <xs:element name=\"Maillage\" type=\"Maillage\" "
 	           << "\n                        minOccurs=\"1\" maxOccurs=\"unbounded\" />"
             << "\n          </xs:sequence>"
  	          << "\n        </xs:complexType>"
             << "\n      </xs:element>";
     // def de Maillage
//     SchemaXML_Maillage(sort,niveau);
         break;		
      }
    };
 };

// ------ informations utiles par exemples pour la visualisation
     // retourne les dimensions minis et maxi suivant les axes du repère
     // absolu du maillage numéro nbmail (en faite le calcul est fondé
     // uniquement sur la position des noeuds du maillage
     // le premier vecteur contient les minimums
     // le deuxième vecteur contient les maximums     
Tableau <Vecteur>  LesMaillages::Taille_boite(int nbmail)
    { 
      #ifdef MISE_AU_POINT
        // vérification que le numéro de maillage est correcte
        if ((	nbmail <= 0) || (nbmail > nbMaillageTotal)) 	 
          { cout << "\n erreur, le numéro de maillage demandé est érroné,"
                 << " nbmail = " << nbmail
                 << " \n LesMaillages::Taille_boite(int nbmail) " ;
            Sortie(1);     
           }
      #endif
      return tabMaillage(nbmail)->Taille_boiteMail();
     };
     
     // dans le cas ou aucun numéro de maillage n'est fournis
     // c'est l'encombrement de tous les maillages qui est fourni
Tableau <Vecteur>  LesMaillages::Taille_boite()
    { if (nbMaillageTotal == 0)
        // cas particulier ou aucun maillage n'est définit
        { Tableau <Vecteur> toto(2);
          return toto;
         } 
      // l'objectif est de balayer tous les maillages
      // tout d'abord initialisation du tableau de retour sur le premier
      // maillage
      Tableau <Vecteur>  tabsortie = tabMaillage(1)->Taille_boiteMail();
      for (int i1 = 2; i1<= nbMaillageTotal; i1++)
         { // récupération du tableau calculé
           Tableau <Vecteur> tabinter = tabMaillage(i1)->Taille_boiteMail();
           // différent tests
           int dima = tabsortie(1).Taille();
           for (int it=1;it<=dima;it++)
            { if (tabsortie(1)(it) > tabinter(1)(it))
                tabsortie(1)(it) = tabinter(1)(it);
              if (tabsortie(2)(it) < tabinter(2)(it))
                tabsortie(2)(it) = tabinter(2)(it);
             }
           }
       // retour
       return tabsortie;          
     };
     
    // mise à jour des boites d'encombrements des éléments, qui contiennent des éléments frontières
    // et des éléments frontières eux-même
void LesMaillages::Mise_a_jour_boite_encombrement_elem_front(Enum_dure temps)
	{for (int i1 = 1; i1<= nbMaillageTotal; i1++)
      { // tout d'abord les boites des éléments: on passe en revue tous les éléments 
        int nbelmax = Nombre_element(i1);
        for (int jel = 1; jel <= nbelmax; jel++)
         { // récup de l'élément
           Element& elem = tabMaillage(i1)->Element_mail(jel);
           // on regarde si l'élément contient des éléments frontières
           if (elem.Existe_frontiere())
             elem.Boite_encombre_element(temps);
         };
        // maintenant on s'occupe des frontières
        LaLIST <Front>* lisfrontmail = listFrontiere(i1); // pour simplifier
        LaLIST <Front>::iterator il,ilfin=lisfrontmail->end(); 
        for (il=lisfrontmail->begin();il != ilfin; il++)
          (*il).Boite_encombrement_frontiere(temps);
      };
	};
     
// crée et ramene pour tous les maillages, la liste des éléments qui contiennent chaque noeud
// mis à jour lorsque lors de la création des frontières
const Tableau < const Tableau <List_io < Element* > > *>&  LesMaillages::Indice()
 { tous_indices.Change_taille(nbMaillageTotal);
   for (int i1 = 1; i1<= nbMaillageTotal; i1++)
     { tous_indices(i1)= &(tabMaillage(i1)->Maillage::Indice());};
   return tous_indices;
 };

// -----------------------------------------------------
// |   utilitaires de manipulation de maillage         |--
// -----------------------------------------------------

// création de maillage quadratiques incomplets à partir de maillages linéaires. 
// En fait il y création de maillages identiques aux maillages déjà existants, les éléments qui sont de types
// linéaires  sont remplacés par des éléments quadratiques incomplets correspondants.
// Il y a création de références correspondantes
void LesMaillages::CreeMaillagesQuadratiques_a_partir_des_lineaires(LesReferences* lesRef)
  { // création de la liste qui sert pour repérer les maillages  créés
    list <DeuxEntiers>  tab_lin_vers_comp;
    // tout d'abord on parcours les différents maillages pour sélectionner ceux qui sont a traiter
    int nb_final_maillage = nbMaillageTotal; // contiend le nombre final de maillage tenant compte des complets
    for (int im=1;im<=nbMaillageTotal;im++)
      if (tabMaillage(im)->Contient_lineaire())
        { nb_final_maillage++; 
          tab_lin_vers_comp.push_back(DeuxEntiers(im,nb_final_maillage));
        };
    // dans le cas où des maillages linéaires existent, création de nouveaux maillages
    nbMaillageTotal = nb_final_maillage;
    // on vérifie et augmente éventuellement la taille du nombre de maillage
    while (nbMaillageTotal > nbPortion) // il faut agrandir le tableau de maillage
      { nbPortion = nbPortion+nbEnreg; 
        tabMaillage.Change_taille(nbPortion);
      };
    // maintenant on passe en revue les maillages candidats
    list<DeuxEntiers>::iterator il,ifin= tab_lin_vers_comp.end();
    for (il=tab_lin_vers_comp.begin();il!=ifin;il++)
     { // on commence par créé le futur maillage quadratique à l'identique du maillage linéaire
       // original, il y a ici création de nouveau noeud et élément
       // on utilise un nouveau nom de maillage construit a partir de l'ancien
       string nvnom= tabMaillage((*il).un)->NomDuMaillage() + "_nevez"; 
       while (NumMaillage(nvnom)) // si le maillage existe déjà , on rajoute un _nevez
         // on utilise un nouveau nom de maillage construit a partir de l'ancien
         nvnom +=  "_nevez";
       tabMaillage((*il).deux)=new Maillage(mapNomMail,(*il).deux, nvnom,*tabMaillage((*il).un));
       // création de références identiques aux cas du maillage initial
       const Reference* ref1 = lesRef->Init_et_Premiere();
       list <Reference * > list_inter_ref; // une liste intermédiaire de travail
       // l'opération s'effectue en deux temps, car pendant que l'on parcours la liste 
       // des références existantes, on ne peut pas en ajouter sous peine de casser le mécanisme de parcours
       //  1) donc premier temps on enregistre
       do { if(ref1->Nbmaille() == (*il).un)
             // on a trouvé une référence à considérer
             { // on crée une référence identique
               Reference* ref_nv = ref1->Nevez_Ref_copie();
               // on met à jour le numéro de maillage associé
               ref_nv->Change_Nbmaille((*il).deux);
               list_inter_ref.push_back(ref_nv);
               // on intègre la référence dans lesRéférences
//               lesRef->Ajout_reference(ref_nv);
              }
            ref1 =  lesRef->Reference_suivante();  // la référence suivante  
            } while (ref1 != NULL);
       //  2) deuxième temps on enregistre
       list <Reference * >::iterator kl,klfin=list_inter_ref.end();
       for (kl=list_inter_ref.begin();kl != klfin; kl++)
       	  lesRef->Ajout_reference((*kl)); 
       // On transforme les éléments quadratiques incomplet du nouveau maillage en quadratiques
       // complets. Les références sont également transformés en cohérence.
       tabMaillage((*il).deux)->Transfo_lin_quadraIncomp(*lesRef); 
      }
   };

// création de maillage quadratiques complets à la place des maillages incomplet
// les éléments qui sont de types quadratiques incomplets sont remplacés par des éléments
// quadratiques complets correspondants.
// Il y a création de références correspondantes
void LesMaillages::CreeMaillagesQuadratiquesComplets_a_partir_des_incomplets(LesReferences* lesRef)
  { // création de la liste qui sert pour repérer les maillages complets créés
    list <DeuxEntiers>  tab_quadra_inc_vers_comp;
    // tout d'abord on parcours les différents maillages pour sélectionner ceux qui sont a traiter
    int nb_final_maillage = nbMaillageTotal; // contiend le nombre final de maillage tenant compte des complets
    for (int im=1;im<=nbMaillageTotal;im++)
      if (tabMaillage(im)->Contient_quadratique_incomplet())
        { nb_final_maillage++; 
          tab_quadra_inc_vers_comp.push_back(DeuxEntiers(im,nb_final_maillage));
         }
    // dans le cas où des maillages de quadratiques incomplet existent, création de nouveaux maillages
    nbMaillageTotal = nb_final_maillage;
    while (nbMaillageTotal > nbPortion) // il faut agrandir le tableau de maillage
      { nbPortion = nbPortion+nbEnreg; 
        tabMaillage.Change_taille(nbPortion);
       };
    // maintenant on passe en revue les maillages candidats
    list<DeuxEntiers>::iterator il,ifin= tab_quadra_inc_vers_comp.end();
    for (il=tab_quadra_inc_vers_comp.begin();il!=ifin;il++)
     { // on commence par créé le futur maillage complet à l'identique du maillage incomplet
       // original, il y a ici création de nouveau noeud et élément
       // on utilise un nouveau nom de maillage construit a partir de l'ancien
       string nvnom= tabMaillage((*il).un)->NomDuMaillage() + "_nevez"; 
       while (NumMaillage(nvnom)) // si le maillage existe déjà , on rajoute un _nevez
         // on utilise un nouveau nom de maillage construit a partir de l'ancien
         nvnom +=  "_nevez";
       tabMaillage((*il).deux)=new Maillage(mapNomMail,(*il).deux, nvnom,*tabMaillage((*il).un));
       // création de références identiques aux cas du maillage initial
       const Reference* ref1 = lesRef->Init_et_Premiere();
       list <Reference * > list_inter_ref; // une liste intermédiaire de travail
       // l'opération s'effectue en deux temps, car pendant que l'on parcours la liste 
       // des références existantes, on ne peut pas en ajouter sous peine de casser le mécanisme de parcours
       //  1) donc premier temps on enregistre
       do { if(ref1->Nbmaille() == (*il).un)
             // on a trouvé une référence à considérer
             { // on crée une référence identique
               Reference* ref_nv = ref1->Nevez_Ref_copie();
               // on met à jour le numéro de maillage associé
               ref_nv->Change_Nbmaille((*il).deux);
               list_inter_ref.push_back(ref_nv);
               // on intègre la référence dans lesRéférences
//               lesRef->Ajout_reference(ref_nv);
              }
            ref1 =  lesRef->Reference_suivante();  // la référence suivante  
            } while (ref1 != NULL);
       //  2) deuxième temps on enregistre
       list <Reference * >::iterator kl,klfin=list_inter_ref.end();
       for (kl=list_inter_ref.begin();kl != klfin; kl++)
       	  lesRef->Ajout_reference((*kl)); 
       // On transforme les éléments quadratiques incomplet du nouveau maillage en quadratiques
       // complets. Les références sont également transformés en cohérence.
       tabMaillage((*il).deux)->Transfo_quadraIncomp_quadraComp(*lesRef); 
      }
   };
          
// Affiche les donnees des maillages dans des fichiers dont le nom est construit à partir du nom de 
// chaque maillage au format  ".her" et ".lis"
// le paramètre optionnel indique le numéro du maillage à afficher, s'il vaut -1, on affiche tous les maillages
void LesMaillages::Affiche_maillage_dans_her_lis(Enum_dure temps,LesReferences &lesRef,int imail)
 { if (imail == -1)
     {// cas de l'affichage de tous les maillages, on passe en revue les différents maillages
      for (int im=1;im<=nbMaillageTotal;im++)
        tabMaillage(im)->Affiche_dans_her_lis(lesRef,temps);
      }
    else
     {// cas de l'affichage d'un maillage particulier
      if ((imail < 1)||(imail > nbMaillageTotal))
        { cout << "\n erreur dans l'affichage d'un maillage en format .her et .lis"
               << "\n le numero propose: " << imail << " de maillage n'existe pas !! " 
               << "\n LesMaillages::Affiche_maillage_dans_her_lis(LesReferences &lesRef,int imail)";
          Sortie(1);     
         }
      tabMaillage(imail)->Affiche_dans_her_lis(lesRef,temps);
      }  
  };

// relocalisation des points milieux des arrêtes des éléments quadratiques
void LesMaillages::RelocPtMilieuMailleQuadra()
  { // on passe en revue les différents maillages 
    for (int im=1;im<=nbMaillageTotal;im++)
      tabMaillage(im)->RelocPtMilieuMailleQuadra();
   };

// création et ajout d'un nouveau maillage en fonction d'un nom et d'une liste 
// d'éléments et de noeuds
// *** il n'y a pas de création de nouveaux noeuds et de nouveaux éléments,
// ce sont les éléments et noeuds passés en paramètres qui sont ceux du maillage créé
// >> ramène le numéro du nouveau maillage
int LesMaillages::Creation_nouveau_maillage
    (list <Noeud*>& li_noeud,list <Element*>& list_elem,const string& nom_maillage)
 { if (ParaGlob::NiveauImpression() >= 4)
     cout << " debut de l'ajout d'un nouveau maillage " << flush;
   // recherche d'un numéro du maillage
   nbMaillageTotal++;
   if (nbMaillageTotal > nbPortion) // il faut agrandir le tableau de maillage
             { nbPortion = nbPortion+nbEnreg; 
               tabMaillage.Change_taille(nbPortion);
             };
   int nbElem= list_elem.size();       
   tabMaillage(nbMaillageTotal) = new Maillage (mapNomMail,paraGlob->Dimension()
                                                  ,li_noeud,list_elem
                                                  ,nbMaillageTotal,nom_maillage);
   // indique le nb de maillage pour l'enregistrement des prochaines references 
   lesRef->NbMaille(nbMaillageTotal); 
   if (ParaGlob::NiveauImpression() >= 4)
     cout << " fin de l'ajout d'un nouveau maillage " << flush;
   // retour du numéro de maillage
   return nbMaillageTotal;
 };

// suppression d'un maillage existant
// par défaut, tous les noeuds et éléments du maillage sont supprimés
// si sans_conservation_noeuds_elements est false: les noeuds et les éléments ne sont pas supprimés
// mais ils ne sont plus référencés dans ce maillage !
void LesMaillages::Suppression_maillage( const string& nom_maillage,const bool sans_conservation_noeuds_elements)
{ // on commence par récupérer le numéro du maillage
  int num_mail = NumMaillage(nom_maillage);
  if (num_mail != 0 ) // sinon il n'y a rien n'a supprimer
   { if (ParaGlob::NiveauImpression() >= 4)
        cout << " delet of the mesh " << nom_maillage << flush ;
     // on supprime le maillage
     //    Dans le cas particulier où l'on veut garder les noeuds et éléments, on l'indique au maillage
     //    avant sa suppression
     if(!sans_conservation_noeuds_elements)
        tabMaillage(num_mail)->Preparation_destruction_avec_conservation_noeuds_elements();
     delete tabMaillage(num_mail);
     // 1) il faut également supprimer les références qui sont relative au maillage que l'on vient de supprimer
     // on commence par stocker la liste des ref à supprimer, on ne les supprime pas à la volée
     // de manière à ne pas modifier les bornes de l'algo de parcours
     // 2) il faut changer de numéro de maillage, toutes les ref qui sont pour les maillages après le maillage supprimé
     bool avec_diminution_num_maillage = true;
     lesRef->Supprime_tour_lesRef_un_maillage(num_mail,avec_diminution_num_maillage);
     // la map des noms
     mapNomMail.erase(nom_maillage);
    
     // -- maintenant il faut que l'on gère tous les tableaux internes qui sont relatifs aux maillages
     // on retasse les tableaux
     nbMaillageTotal--;
     //   le tableau de maillage
     for (int i = num_mail;i<= nbMaillageTotal;i++)
       {tabMaillage(i) = tabMaillage(i+1);
        tabMaillage(i)->Change_numero_maillage(i); // changement du numéro de maillage
       };
     tabMaillage(nbMaillageTotal+1)=NULL;
     //   les frontières si elles ont été construite
     if (listFrontiere.Taille() != 0)
      {for (int i = num_mail;i<= nbMaillageTotal;i++)
        {tabMaillage(i) = tabMaillage(i+1);
         listFrontiere(i) = listFrontiere(i+1);
         tt_noeud_front(i) = tt_noeud_front(i+1);
        };
       listFrontiere.Change_taille(nbMaillageTotal);
       tt_noeud_front.Change_taille(nbMaillageTotal);
      };
     // le nombre de domaine esclave
     if (num_mail <= domEsclave )
       // il faut diminuer le nombre d'esclave
       domEsclave--;
    
   };
};

 
// création de maillage par extrusion
// Il y a création de références correspondantes
void LesMaillages::CreeMaillageExtrusion2D3D(LesReferences* lesRef)
  { // création de la liste qui sert pour repérer les maillages complets créés
    list <DeuxEntiers>  tab_quadra_inc_vers_comp;
    // tout d'abord on parcours les différents maillages pour sélectionner ceux qui sont a traiter
    int nb_final_maillage = nbMaillageTotal; // contiend le nombre final de maillage tenant compte des complets
    for (int im=1;im<=nbMaillageTotal;im++)
      if (tabMaillage(im)->Contient_quadratique_incomplet())
        { nb_final_maillage++; 
          tab_quadra_inc_vers_comp.push_back(DeuxEntiers(im,nb_final_maillage));
         }
    // dans le cas où des maillages de quadratiques incomplet existent, création de nouveaux maillages
    nbMaillageTotal = nb_final_maillage;
    while (nbMaillageTotal > nbPortion) // il faut agrandir le tableau de maillage
      { nbPortion = nbPortion+nbEnreg; 
        tabMaillage.Change_taille(nbPortion);
       };
    // maintenant on passe en revue les maillages candidats
    list<DeuxEntiers>::iterator il,ifin= tab_quadra_inc_vers_comp.end();
    for (il=tab_quadra_inc_vers_comp.begin();il!=ifin;il++)
     { // on commence par créé le futur maillage complet à l'identique du maillage incomplet
       // original, il y a ici création de nouveau noeud et élément
       // on utilise un nouveau nom de maillage construit a partir de l'ancien
       string nvnom= tabMaillage((*il).un)->NomDuMaillage() + "_nevez"; 
       while (NumMaillage(nvnom)) // si le maillage existe déjà , on rajoute un _nevez
         // on utilise un nouveau nom de maillage construit a partir de l'ancien
         nvnom +=  "_nevez";
       tabMaillage((*il).deux)=new Maillage(mapNomMail,(*il).deux, nvnom,*tabMaillage((*il).un));
       // création de références identiques aux cas du maillage initial
       const Reference* ref1 = lesRef->Init_et_Premiere();
       list <Reference * > list_inter_ref; // une liste intermédiaire de travail
       // l'opération s'effectue en deux temps, car pendant que l'on parcours la liste 
       // des références existantes, on ne peut pas en ajouter sous peine de casser le mécanisme de parcours
       //  1) donc premier temps on enregistre
       do { if(ref1->Nbmaille() == (*il).un)
             // on a trouvé une référence à considérer
             { // on crée une référence identique
               Reference* ref_nv = ref1->Nevez_Ref_copie();
               // on met à jour le numéro de maillage associé
               ref_nv->Change_Nbmaille((*il).deux);
               list_inter_ref.push_back(ref_nv);
               // on intègre la référence dans lesRéférences
//               lesRef->Ajout_reference(ref_nv);
              }
            ref1 =  lesRef->Reference_suivante();  // la référence suivante  
            } while (ref1 != NULL);
       //  2) deuxième temps on enregistre
       list <Reference * >::iterator kl,klfin=list_inter_ref.end();
       for (kl=list_inter_ref.begin();kl != klfin; kl++)
       	  lesRef->Ajout_reference((*kl)); 
       // On transforme les éléments quadratiques incomplet du nouveau maillage en quadratiques
       // complets. Les références sont également transformés en cohérence.
       tabMaillage((*il).deux)->Transfo_quadraIncomp_quadraComp(*lesRef); 
      }
   };
      
// définition interactive de listes de références
void LesMaillages::CreationInteractiveListesRef(LesReferences* lesRef)   
	{  //  on récupère le nombre de maillage actuellement actif
    int nb_maillages_actifs_initiaux = nbMaillageTotal;
    cout << "\n il y a " << nb_maillages_actifs_initiaux << " maillages a considerer \n";
    // on va boucler sur les maillages et définir des ref pour chaque maillages
    for (int imail = 1; imail <= nb_maillages_actifs_initiaux; imail++)
      tabMaillage(imail)->CreationInteractiveListesRef(lesRef);
	};   
     
// modification de l'orientation d'éléments
void LesMaillages::Modif_orientation_element(int cas_orientation,LesReferences* lesRef)   
	{  //  on récupère le nombre de maillage actuellement actif
    int nb_maillages_actifs_initiaux = nbMaillageTotal;
    cout << "\n il y a " << nb_maillages_actifs_initiaux << " maillages a considerer \n";
    switch(cas_orientation)
     { case 1: case 2: case 3: // cas d'une orientation automatique des maillages:
       { // on vérifie et augmente éventuellement la taille du nombre de maillage
         while (nbMaillageTotal > nbPortion)
           { nbPortion = nbPortion+nbEnreg; 
             tabMaillage.Change_taille(nbPortion);
            };

         // on va boucler sur les maillages et définir de nouveaux maillages identiques
         for (int imail = 1; imail <= nb_maillages_actifs_initiaux; imail++)
          { // il y a ici création de nouveau noeud et élément
            // on utilise un nouveau nom de maillage construit a partir de l'ancien
            int imailnew = imail+nb_maillages_actifs_initiaux;
            string nvnom= tabMaillage(imail)->NomDuMaillage() + "_nevez"; 
            while (NumMaillage(nvnom)) // si le maillage existe déjà , on rajoute un _nevez
              // on utilise un nouveau nom de maillage construit a partir de l'ancien
              nvnom +=  "_nevez";
            tabMaillage(imailnew)=new Maillage(mapNomMail,imailnew, nvnom,*tabMaillage(imail));
            nbMaillageTotal++; // on signale qu'il y a un maillage supplémentaire
            // création de références identiques aux cas du maillage initial
            const Reference* ref1 = lesRef->Init_et_Premiere();
            list <Reference * > list_inter_ref; // une liste intermédiaire de travail
            // l'opération s'effectue en deux temps, car pendant que l'on parcours la liste 
            // des références existantes, on ne peut pas en ajouter sous peine de casser le mécanisme de parcours
            //  1) donc premier temps on enregistre
            do { if(ref1->Nbmaille() == imail)
                  // on a trouvé une référence à considérer
                  { // on crée une référence identique
                    Reference* ref_nv = ref1->Nevez_Ref_copie();
                    // on met à jour le numéro de maillage associé
                    ref_nv->Change_Nbmaille(imailnew);
                    list_inter_ref.push_back(ref_nv);
                  };
                 ref1 =  lesRef->Reference_suivante();  // la référence suivante  
                 } while (ref1 != NULL);
            //  2) deuxième temps on enregistre
            list <Reference * >::iterator kl,klfin=list_inter_ref.end();
            for (kl=list_inter_ref.begin();kl != klfin; kl++)
    	          lesRef->Ajout_reference((*kl)); 
            // on modifie l'orientation du nouveau maillage en fonction du cas
            tabMaillage(imailnew)->Modif_orientation_element(cas_orientation,lesRef);
          };
         break;
       }
       case -1: // uniquement vérification 
       { // on va boucler sur les maillages 
         for (int imail = 1; imail <= nb_maillages_actifs_initiaux; imail++)
           tabMaillage(imail)->Modif_orientation_element(cas_orientation,lesRef);
         break;
       }
       default:
         cout << "\n erreur le cas : " << cas_orientation
              << " n'est pas actuellement pris en compte"
              << "\n LesMaillages::Modif_orientation_element(...";
         Sortie(1);     
     };
	};   
 
// Collapse des éléments supperposés, c-a-d identiques, dans le cas où il en existe
void LesMaillages::Collapse_element_supperpose(LesReferences* lesRef)
{  //  on récupère le nombre de maillage actuellement actif
    int nb_maillages_actifs_initiaux = nbMaillageTotal;
    cout << "\n il y a " << nb_maillages_actifs_initiaux << " maillages a considerer \n";
    // on vérifie et augmente éventuellement la taille du nombre de maillage
    while (nbMaillageTotal > nbPortion)
     { nbPortion = nbPortion+nbEnreg;
       tabMaillage.Change_taille(nbPortion);
     };
    
    // on va boucler sur les maillages et définir de nouveaux maillages identiques
    for (int imail = 1; imail <= nb_maillages_actifs_initiaux; imail++)
    { // il y a ici création de nouveau noeud et élément
        // on utilise un nouveau nom de maillage construit a partir de l'ancien
        int imailnew = imail+nb_maillages_actifs_initiaux;
        string nvnom= tabMaillage(imail)->NomDuMaillage() + "_nevez";
        while (NumMaillage(nvnom)) // si le maillage existe déjà , on rajoute un _nevez
          // on utilise un nouveau nom de maillage construit a partir de l'ancien
          nvnom +=  "_nevez";
        tabMaillage(imailnew)=new Maillage(mapNomMail,imailnew, nvnom,*tabMaillage(imail));
        nbMaillageTotal++; // on signale qu'il y a un maillage supplémentaire
        // création de références identiques aux cas du maillage initial
        const Reference* ref1 = lesRef->Init_et_Premiere();
        list <Reference * > list_inter_ref; // une liste intermédiaire de travail
        // l'opération s'effectue en deux temps, car pendant que l'on parcours la liste
        // des références existantes, on ne peut pas en ajouter sous peine de casser le mécanisme de parcours
        //  1) donc premier temps on enregistre
        do { if(ref1->Nbmaille() == imail)
            // on a trouvé une référence à considérer
        { // on crée une référence identique
            Reference* ref_nv = ref1->Nevez_Ref_copie();
            // on met à jour le numéro de maillage associé
            ref_nv->Change_Nbmaille(imailnew);
            list_inter_ref.push_back(ref_nv);
        };
            ref1 =  lesRef->Reference_suivante();  // la référence suivante
        } while (ref1 != NULL);
        //  2) deuxième temps on enregistre
        list <Reference * >::iterator kl,klfin=list_inter_ref.end();
        for (kl=list_inter_ref.begin();kl != klfin; kl++)
            lesRef->Ajout_reference((*kl));
        // on fusionne les noeuds
        tabMaillage(imailnew)->Collapse_element_superpose(lesRef);
    };
    
};

// collapse de noeuds très proche: appartenant à des éléments différents
// rayon : donne la distance maxi entre les noeuds qui doivent être collapsé
void LesMaillages::Collapse_noeuds_proches(double rayon, LesReferences* lesRef)
{  //  on récupère le nombre de maillage actuellement actif
    int nb_maillages_actifs_initiaux = nbMaillageTotal;
    cout << "\n il y a " << nb_maillages_actifs_initiaux << " maillages a considerer \n";
    // on vérifie et augmente éventuellement la taille du nombre de maillage
    while (nbMaillageTotal > nbPortion)
     { nbPortion = nbPortion+nbEnreg;
       tabMaillage.Change_taille(nbPortion);
     };
    
    // on va boucler sur les maillages et définir de nouveaux maillages identiques
    for (int imail = 1; imail <= nb_maillages_actifs_initiaux; imail++)
    { // il y a ici création de nouveau noeud et élément
        // on utilise un nouveau nom de maillage construit a partir de l'ancien
        int imailnew = imail+nb_maillages_actifs_initiaux;
        string nvnom= tabMaillage(imail)->NomDuMaillage() + "_nevez";
        while (NumMaillage(nvnom)) // si le maillage existe déjà , on rajoute un _nevez
          // on utilise un nouveau nom de maillage construit a partir de l'ancien
          nvnom +=  "_nevez";
        tabMaillage(imailnew)=new Maillage(mapNomMail,imailnew, nvnom,*tabMaillage(imail));
        nbMaillageTotal++; // on signale qu'il y a un maillage supplémentaire
        // création de références identiques aux cas du maillage initial
        const Reference* ref1 = lesRef->Init_et_Premiere();
        list <Reference * > list_inter_ref; // une liste intermédiaire de travail
        // l'opération s'effectue en deux temps, car pendant que l'on parcours la liste
        // des références existantes, on ne peut pas en ajouter sous peine de casser le mécanisme de parcours
        //  1) donc premier temps on enregistre
        do { if(ref1->Nbmaille() == imail)
            // on a trouvé une référence à considérer
        { // on crée une référence identique
            Reference* ref_nv = ref1->Nevez_Ref_copie();
            // on met à jour le numéro de maillage associé
            ref_nv->Change_Nbmaille(imailnew);
            list_inter_ref.push_back(ref_nv);
        };
            ref1 =  lesRef->Reference_suivante();  // la référence suivante
        } while (ref1 != NULL);
        //  2) deuxième temps on enregistre
        list <Reference * >::iterator kl,klfin=list_inter_ref.end();
        for (kl=list_inter_ref.begin();kl != klfin; kl++)
            lesRef->Ajout_reference((*kl));
        // on fusionne les noeuds
        tabMaillage(imailnew)->Collapse_noeuds_proches(rayon,lesRef);
    };
    
};

// création d'un nouveau maillage issue de la fusion de maillages existants
// nom_mails_a_fusionner : la liste des maillages à fusionner
// new_mail              : le nom du nouveau maillage à construire
// NB: si new_mail correspond à un maillage déjà existant, il y a fusion de ce maillage
//     avec les autres, sans création d'un nouveau maillage
void LesMaillages::Fusion_maillages(List_io < string >& nom_mails_a_fusionner,const string& new_mail
                      ,LesReferences* lesRef)
{  // on va commencer par créer un nouveau maillage 
   if (ParaGlob::NiveauImpression() >= 4)
     cout << "   debut d'une operation de fusion de maillage  " << flush;
   // on regarde s'il s'agit d'une fusion avec un maillage existant ou non:
   Maillage* nevez_mail_ = NULL; // est renseigné dans le if suivant
   bool creation_nouveau_maillage = false;
   if (NumMaillage(new_mail) == 0)
    { // le retour est nulle: cas d'un nouveau maillage, on va créer un nouveau maillage
      // recherche d'un numéro du maillage
      nbMaillageTotal++;
      if (nbMaillageTotal > nbPortion) // il faut agrandir le tableau de maillage
       { nbPortion = nbPortion+nbEnreg; 
         tabMaillage.Change_taille(nbPortion);
       };
      // le premier maillage est vide
      int dim = ParaGlob::Dimension();
      tabMaillage(nbMaillageTotal) = new Maillage(mapNomMail,nbMaillageTotal,dim,new_mail);
      nevez_mail_ = (tabMaillage(nbMaillageTotal)); // pour simplifier
      creation_nouveau_maillage = true;
    }
   else
    { // il s'agit ici d'un maillage qui existe déjà
      nevez_mail_ = (tabMaillage(NumMaillage(new_mail)));    
    };
   // on récupère le maillage de base, qui intègrera les autres
   Maillage& nevez_mail = *nevez_mail_;
 
   // avant de faire l'opération de fusion, on va faire un traitement spécial pour les
   // références automatiques E_tout, N_tout, F_tout, A_tout, P_tout, G_tout
   {Tableau <string> tab_tout(6);
    tab_tout(1) = "E_tout";tab_tout(2) = "N_tout"; tab_tout(3) = "F_tout";
    tab_tout(4) = "A_tout";tab_tout(5) = "P_tout"; tab_tout(6) = "G_tout";
    int idmail = NumMaillage(new_mail);
    for (int i=1;i<= 6; i++)
     {string& nreftout= tab_tout(i);
      if (lesRef->Existe(nreftout,idmail))
        { const Reference& ref1 = lesRef->Trouve(nreftout,idmail); // récup de la ref
          Reference* ref2 = ref1.Nevez_Ref_copie(); // on crée une ref identique
          string nevez_nom=nreftout+"_1";int num=1; // on cherche un nom qui n'existe pas encore
          while (lesRef->Existe(nevez_nom,idmail))
            {nevez_nom += "_"+ChangeEntierSTring(num);num++;};
          ref2->Change_nom(nevez_nom); // change le nom de la nouvelle ref
          lesRef->Ajout_reference(ref2); // ajout de la ref
          if (ParaGlob::NiveauImpression() > 0)
              cout << "\n >>> attention la reference " << nreftout << " du maillage "
                   << nevez_mail.NomDuMaillage() << " a un nouveau nom "<< nevez_nom;
        };
     };
   };
 
   // maintenant on va passer en revue tous les maillages à fusionner
   List_io < string >::iterator il,ilfin=nom_mails_a_fusionner.end();
   for (il = nom_mails_a_fusionner.begin();il != ilfin;il++)
    { // récup du numéro de maillage,
      // et éventuellement on passe le maillage identique à new_mail
// debug
//cout << "\n maillage de la liste à fusionner " << (*il) << " newmail= "<<new_mail << flush;
// fin debug
      
      if (*(il) != new_mail)
       { int num_mail_a_fusion = NumMaillage(*(il));
         Maillage& mail_a_fusion = *(tabMaillage(num_mail_a_fusion));
// debug
//cout << "\n *il " << (*il) << " newmail= "<<new_mail
//     << " num_mail_a_fusion= "<<num_mail_a_fusion << " NomDuMaillage() " << mail_a_fusion.NomDuMaillage() << flush;
// fin debug
         // constitution de la liste de noeuds
         Tableau<Noeud *>& tabN = mail_a_fusion.Tab_noeud();
         int nbN = tabN.Taille();list <Noeud *>  li_Noe;
         for (int i=1;i<=nbN;i++)
           li_Noe.push_back(tabN(i));
         // constitution de la liste d'éléments
         Tableau<Element *>& tabE = mail_a_fusion.Tab_element();
         int nbE = tabE.Taille();list <Element *>  li_Elem;
         for (int i=1;i<=nbE;i++)
           li_Elem.push_back(tabE(i));
         // on récupère les références associées à ce maillage
         list <const Reference*> lref; // la liste qui contiendra les ref recherchées
         const Reference* ref1 = lesRef->Init_et_Premiere();
         // on parcours la liste pour récupérer les ref appartenant au maillage
         do { if(ref1->Nbmaille() == num_mail_a_fusion)
             // on a trouvé une référence à considérer
             {// si l'on est dans le cas de la fusion avec un maillage existant
              // on regarde s'il y a déjà une ref avec le même nom dans le maillage
              // si oui on change le nom de la ref à ajouter
              string ajout="";int num=0;
              if (!creation_nouveau_maillage)
                {while (lesRef->Existe((ref1->Nom()+ajout),NumMaillage(new_mail)))
                   {num++;ajout = "_"+ChangeEntierSTring(num);
// debug
//cout << "\n (ref1->Nom()+ajout)" << (ref1->Nom()+ajout) << flush;
// fin debug
                   
                   
                   };
                };
              // on crée la référence à ajouter
              Reference* ref2 = ref1->Nevez_Ref_copie(); // on crée une ref identique
              ref2->Change_nom(ref1->Nom()+ajout);
              lref.push_back(ref2);
              // on averti que le nom de la référence a changé
              if ((ParaGlob::NiveauImpression() > 0) && (ajout != ""))
                 cout << "\n >>> attention la reference "<<ref1->Nom()<<" du maillage "
                      << mail_a_fusion.NomDuMaillage() << " a un nouveau nom "<< (ref1->Nom()+ajout);
// debug
//cout << "\n ref2= " << ref2->Nom() << " num maille "<< ref2->Nbmaille() << flush;
// fin debug
             };
// debug
//cout << "\n " << ref1->Nom() << " num maille "<< ref1->Nbmaille() << flush;
// fin debug
                ref1 =  lesRef->Reference_suivante();  // la référence suivante
             } while (ref1 != NULL);

         // appel de la méthode de fusion
         nevez_mail.Ajout_elements_et_noeuds(li_Noe,li_Elem,&lref,lesRef);
       };
    };

   if (ParaGlob::NiveauImpression() >= 4)
     cout << "\n   fin de l'operation de fusion de maillage  " << flush;
};


// création d'un nouveau maillage issue d'un maillages existants et d'une ref d'éléments
// le nouveau maillage = les éléments de la ref
void LesMaillages::Cree_sous_maillage(int num_mail,LesReferences* lesRef, string nom_ref,const string& new_mail)
{  // on va commencer par créer un nouveau maillage
   if (ParaGlob::NiveauImpression() >= 4)
     cout << "   debut d'une operation de creation de sous-maillage  " << flush;
   //  on va créer un nouveau maillage
   // recherche d'un numéro du maillage
   nbMaillageTotal++;
   if (nbMaillageTotal > nbPortion) // il faut agrandir le tableau de maillage
    { nbPortion = nbPortion+nbEnreg; 
      tabMaillage.Change_taille(nbPortion);
    };
   // le premier maillage est vide
   int dim = ParaGlob::Dimension();
   // si le nom du nouveau maillage existe déjà, on met nevez en suffixe
   string nvnom(new_mail); // init
   while (NumMaillage(nvnom))
      // on utilise un nouveau nom de maillage construit a partir de l'ancien
      nvnom +=  "_nevez";
 
   // on commence par créé le futur maillage à l'identique du maillage contenant la ref
   // originale, il y a ici création de nouveaux noeuds et éléments
//   tabMaillage(nbMaillageTotal) = new Maillage(mapNomMail,nbMaillageTotal,dim,nvnom);
	  tabMaillage(nbMaillageTotal) = new Maillage (mapNomMail,nbMaillageTotal,nvnom,*tabMaillage(nbMaillageTotal-1));
   Maillage*  nevez_mail_ = (tabMaillage(nbMaillageTotal)); // pour simplifier
   // pour simplifier
   Maillage& nevez_mail = *nevez_mail_;
   // création de références identiques aux cas du maillage initial
   const Reference* ref1 = lesRef->Init_et_Premiere();
   list <Reference * > list_inter_ref; // une liste intermédiaire de travail
   // l'opération s'effectue en deux temps, car pendant que l'on parcours la liste 
   // des références existantes, on ne peut pas en ajouter sous peine de casser le mécanisme de parcours
   //  1) donc premier temps on enregistre
   do { // on crée une référence identique
        Reference* ref_nv = ref1->Nevez_Ref_copie();
        // on met à jour le numéro de maillage associé
        ref_nv->Change_Nbmaille(nbMaillageTotal);
        list_inter_ref.push_back(ref_nv);
        ref1 =  lesRef->Reference_suivante();  // la référence suivante
      } while (ref1 != NULL);
   //  2) deuxième temps on enregistre
   list <Reference * >::iterator kl,klfin=list_inter_ref.end();
   for (kl=list_inter_ref.begin();kl != klfin; kl++)
   	  lesRef->Ajout_reference((*kl)); 
   //  puis, pour le nouveau maillage,
   //  on restreint le maillage aux seuls éléments de la référence passée en paramètre
   // toutes les infos relatives à des éléments supprimés, sont également supprimés
   nevez_mail.Restreint_sous_maillage(lesRef, nom_ref);

   if (ParaGlob::NiveauImpression() >= 4)
     cout << "\n   fin de l'operation de creation de sous-maillage  " << flush;
};

// création d'éléments SFE en fonction d'éléments classiques
void LesMaillages::CreationMaillageSFE()  // on passe en revue les différents maillages 
  { // création de la liste qui sert pour repérer les maillages  créés
    list <DeuxEntiers>  tab_tri_vers_sfe;
    // tout d'abord on parcours les différents maillages pour sélectionner ceux qui sont a traiter
    int nb_final_maillage = nbMaillageTotal; // contiend le nombre final de maillage tenant compte des complets
    for (int im=1;im<=nbMaillageTotal;im++)
      if (tabMaillage(im)->OKPourTransSfe())
        { nb_final_maillage++; 
          tab_tri_vers_sfe.push_back(DeuxEntiers(im,nb_final_maillage));
        };
    // dans le cas où des maillages candidats existent, création de nouveaux maillages
    nbMaillageTotal = nb_final_maillage;
    // on vérifie et augmente éventuellement la taille du nombre de maillage
    while (nbMaillageTotal > nbPortion) // il faut agrandir le tableau de maillage
      { nbPortion = nbPortion+nbEnreg; 
        tabMaillage.Change_taille(nbPortion);
      };
    // maintenant on passe en revue les maillages candidats
    list<DeuxEntiers>::iterator il,ifin= tab_tri_vers_sfe.end();
    for (il=tab_tri_vers_sfe.begin();il!=ifin;il++)
     { // on commence par créer le futur maillage SFE à l'identique du maillage triangulaire
       // original, il y a ici création de nouveau noeud et élément
       // on utilise un nouveau nom de maillage construit a partir de l'ancien
       string nvnom= tabMaillage((*il).un)->NomDuMaillage() + "_nevez"; // init
       while (NumMaillage(nvnom)) // si le maillage existe déjà , on rajoute un _nevez
         // on utilise un nouveau nom de maillage construit a partir de l'ancien
         nvnom +=  "_nevez";
      
       tabMaillage((*il).deux)=new Maillage(mapNomMail,(*il).deux, nvnom,*tabMaillage((*il).un));
       // création de références identiques aux cas du maillage initial
       const Reference* ref1 = lesRef->Init_et_Premiere();
       list <Reference * > list_inter_ref; // une liste intermédiaire de travail
       // l'opération s'effectue en deux temps, car pendant que l'on parcours la liste 
       // des références existantes, on ne peut pas en ajouter sous peine de casser le mécanisme de parcours
       //  1) donc premier temps on enregistre
       do { if(ref1->Nbmaille() == (*il).un)
             // on a trouvé une référence à considérer
             { // on crée une référence identique
               Reference* ref_nv = ref1->Nevez_Ref_copie();
               // on met à jour le numéro de maillage associé
               ref_nv->Change_Nbmaille((*il).deux);
               list_inter_ref.push_back(ref_nv);
				         };
            ref1 =  lesRef->Reference_suivante();  // la référence suivante  
          } while (ref1 != NULL);
       //  2) deuxième temps on enregistre
       list <Reference * >::iterator kl,klfin=list_inter_ref.end();
       for (kl=list_inter_ref.begin();kl != klfin; kl++)
       	  lesRef->Ajout_reference((*kl)); 
       // On transforme les éléments triangulaire  du nouveau maillage en SFE
       // Les références sont conservées, car a priori identiques 
       tabMaillage((*il).deux)->CreationMaillageSFE(); 
      }
   };
 
// renumérotation des noeuds de tous les  maillages en même temps, + prise en compte
// des conditions linéaires qui existent entre les noeuds 
// attention, ne peut fonctionner que si les maillages ont des relations entre eux,
//sinon l'arbre de descendance ne sera pas complet !!
// ramène false si rien n'a changé, vrai sinon
    // si le pointeur d'assemblage est non nulle, cela veut dire que l'on veut également une mise à jour
    // globale des pointeurs d'assemblages (ce qui est différent de la méthode : MiseAJourPointeurAssemblage(
    //                                       qui agit maillage après maillage)
    // si le pointeur d'assemblage est non nulle et le drapeau: sans_changement_num_noeud = true
    // cela signifie que l'on désire uniquement une renumérotation de pointeur sans les noeuds
// ramène dans tous les cas les nouvelles largeurs en ddl
//  nouvelles_largeur_en_ddl.un = la largeur totale
//  nouvelles_largeur_en_ddl.deux = la demie largeur
//  nouvelles_largeur_en_ddl.trois = la demie largeur maximale pour la partie éléments finis
//                                   uniquement (sans les CLL)

    // ramène dans tous les cas les nouvelles largeurs en ddl
    //  nouvelles_largeur_en_ddl.un = la largeur totale résultante
    //  nouvelles_largeur_en_ddl.deux = la demie largeur totale résultante
    //  nouvelles_largeur_en_ddl.trois = la demie largeur maximale pour la partie éléments finis
    //                                   uniquement (sans les CLL)
    //
bool LesMaillages::Renumerotation(LesReferences& lesRef,const Tableau <Tableau <Condilineaire> >& tab_condCLL
                                  ,TroisEntiers&  nouvelles_largeur_en_ddl
                                  ,const Nb_assemb* nb_casAssemb,bool sans_changement_num_noeud)
{    // pour effectuer la renumérotation il est nécessaire de créer un tableau global de tous les noeuds et
   // de tous les éléments, de manière à pouvoir les gérer en même temps
   // a1) on calcul les nombres maxi
   int nb_noeud = 0; int nb_element = 0;
   for (int imail=1;imail<=nbMaillageTotal;imail++)
   	{ nb_noeud += tabMaillage(imail)->Nombre_noeud();
   	  nb_element += tabMaillage(imail)->Nombre_element();
   	};
	  // a2) on crée maintenant les éléments frontières car cela utilise les numéros des noeuds, qui vont être changé
   // mais ce n'est pas toujours bien de recréer les frontières, car on peut avoir des grandeurs qui dépendent des frontières
   // comme par exemple les éléments de contact: si on refait les frontières, il faut refaire les éléments de contact
   // or la renumérotation n'a pas à changer les frontières en elles-mêmes
   // donc on adopte une création conditionnelle
   if ((listFrontiere.Taille() == 0) || (tt_noeud_front.Taille() == 0))
      LesMaillages::CreeElemFront(); // on crée les éléments frontières
 
   // b) on crée les tableaux
   Tableau <Noeud *> t_noe(nb_noeud); // le tableau global de noeuds
   Tableau <int > t_oldNumNoeud(nb_noeud); // tableau des anciens numéros de noeuds
   Tableau<Element *> t_elem(nb_element); // le tableau global des éléments	
   // c) on rempli les tableaux en changeant les numéros des noeuds (pour avoir une seule numérotation)
   //    normalement cela n'influe pas sur les éléments car eux ils contiennent des tableaux de pointeur de noeuds
   int numGlobNoeud=1; int numGlobEle = 1;
   for (int imil=1;imil<=nbMaillageTotal;imil++)
   	{ int nbn = tabMaillage(imil)->Nombre_noeud();
   	  Tableau<Noeud *>& tab_noeud = tabMaillage(imil)->Tab_noeud();
   	  for (int inoe = 1; inoe <= nbn; inoe++,numGlobNoeud++)
   	  	{ t_noe(numGlobNoeud) = tab_noeud(inoe);
   	  	  t_oldNumNoeud(numGlobNoeud) = tab_noeud(inoe)->Num_noeud();
   	  	  t_noe(numGlobNoeud)->Change_num_noeud(numGlobNoeud);
   	  	};
   	  int nb_ele = tabMaillage(imil)->Nombre_element();
   	  Tableau<Element *>& tab_element = tabMaillage(imil)->Tab_element();
   	  for (int iel = 1; iel <= nb_ele; iel++,numGlobEle++)
   	  	{ t_elem(numGlobEle) = tab_element(iel);
   	  	};
   	};
   // avant tout changement on calcul la largeur initiale due aux conditions linéaires
   // celle-ci n'est valide que dans le cas où tous les noeuds ont des numéros différents
   // ce qui est le cas maintenant
   int taille_tab_cll = tab_condCLL.Taille();
   int largeur_initiale_CLL = 0; // init
   for (int i = 1; i<= taille_tab_cll;i++)
     { Tableau <Condilineaire>& condCLL = tab_condCLL(i);
       int taille = condCLL.Taille();
       for (int j=1;j<= taille;j++)
         largeur_initiale_CLL=MaX(largeur_initiale_CLL,condCLL(j).DiffMaxiNumeroNoeud());
     };
   if ((ParaGlob::NiveauImpression() > 4)
       || ((nb_casAssemb == NULL)&&(ParaGlob::NiveauImpression() > 0))
         )
    { cout << "\n pour l'ensemble des conditions linaires: via une numerotation unique pour tous les maillages, "
           << " la 1/2 largeur de bande en noeud initiale est "
           << largeur_initiale_CLL << flush;
    };


   bool nouvelle_numerotation = false; // pour le contrôle de la fin
   // on calcul le point de départ
   Tableau < LaLIST_io <Noeud* > > t_voisin; // def du tableau des voisins des noeuds
   list < list < Maillage::Noeud_degre  > >  lis_descent; // stockage des descendants
   bool calcul_ok = false; // init par défaut
   Noeud* noe_dep = Maillage::Point_de_depart(t_elem,t_noe,tt_noeud_front,t_voisin,lis_descent,tab_condCLL,calcul_ok);
   if (calcul_ok) // on ne continue que si c'est ok
     {// on appelle l'algorithme de Cuthill Mac Kee
      Tableau <Noeud* > tab_N_final =  Maillage::Cuthill_Mac_Kee(nb_noeud,noe_dep,t_voisin,lis_descent);
      // --- maintenant on regarde l'évolution de la largeur de bande en noeud
      // tout d'abord la largeur initiale
      int largeur_initiale	 = Maillage::LargeurBandeEnNoeuds(t_elem);
      // on change la numérotation
      for (int ia=1;ia <= nb_noeud; ia++)
         tab_N_final(ia)->Change_num_noeud(ia);
      // nouvelle largeur de bande
      int largeur_Cuthill = Maillage::LargeurBandeEnNoeuds(t_elem);
      // idem pour les CLL
      int largeur_Cuthill_CLL = 0; // init
      for (int i = 1; i<= taille_tab_cll;i++)
        { Tableau <Condilineaire>& condCLL = tab_condCLL(i);
          int taille = condCLL.Taille();
          for (int j=1;j<= taille;j++)
            largeur_Cuthill_CLL=MaX(largeur_Cuthill_CLL,condCLL(j).DiffMaxiNumeroNoeud());
        };
      // on change en numérotation inverse : Cuthill Mac Kee inverse
      // car on pense qu'a priori c'est celle-là qui sera la meilleur
   /////   Tableau <Noeud* > tab_N_inverse(tab_N_final);
      for (int ia=1;ia <= nb_noeud; ia++)
         {tab_N_final(ia)->Change_num_noeud(1+nb_noeud-ia);
   // avec les modifs que j'ai fait après la ligne qui suit ne sert plus ???
   /////       tab_N_inverse(1+nb_noeud-ia) = tab_N_final(ia);
         };
      int largeur_Cuthill_inverse = Maillage::LargeurBandeEnNoeuds(t_elem);
      // idem pour les CLL
      int largeur_Cuthill_inverse_CLL = 0; // init
      for (int i = 1; i<= taille_tab_cll;i++)
        { Tableau <Condilineaire>& condCLL = tab_condCLL(i);
          int taille = condCLL.Taille();
          for (int j=1;j<= taille;j++)
            largeur_Cuthill_inverse_CLL=MaX(largeur_Cuthill_inverse_CLL,condCLL(j).DiffMaxiNumeroNoeud());
        };
      if ((ParaGlob::NiveauImpression() > 3)
       || ((nb_casAssemb == NULL)&&(ParaGlob::NiveauImpression() > 0))
         )
       { cout << "\n $$ Premiere etape: optimisation sur l'ensemble des maillages sous forme d'un seul groupe $$ ";
         cout << "\n pour l'ensemble des maillages: 1/2 largeur de bande en noeud,  initiale= " << largeur_initiale
              << "\n partie conditions lineaires initiales : " << largeur_initiale_CLL
              << " --> maxi des deux: " << MaX(largeur_initiale_CLL, largeur_initiale)
              << " \n apres l'algo de Cuthill Mac Kee= " << largeur_Cuthill
              << ", conditions lineaires : " << largeur_Cuthill_CLL
              << " --> maxi des deux: " << MaX(largeur_Cuthill_CLL, largeur_Cuthill)
              << " \n en Cuthill Mac Kee inverse= " << largeur_Cuthill_inverse
              << ", conditions lineaires : " << largeur_Cuthill_inverse_CLL
              << " --> maxi des deux: " << MaX(largeur_Cuthill_inverse_CLL, largeur_Cuthill_inverse)<<  flush ;
       };
      // normalement le dernier est le meilleur, en tout cas il est meilleur que le cas 2
      
      // ----- dernières opérations: on regarde si effectivement il faut appliquer la nouvelle
      // ----- numérotation
      int demi_largeur_totale=MaX(largeur_Cuthill_inverse_CLL, largeur_Cuthill_inverse);
      
      if (MaX(largeur_initiale_CLL, largeur_initiale)
          < MaX(largeur_Cuthill_inverse_CLL, largeur_Cuthill_inverse))
   //   if (largeur_initiale < largeur_Cuthill_inverse)
        // bizarre, cela veut dire qu'il faut revenir à la forme initiale
        { for (int ia=1;ia <= nb_noeud; ia++)
            t_noe(ia)->Change_num_noeud(t_oldNumNoeud(ia));
          demi_largeur_totale = MaX(largeur_initiale_CLL, largeur_initiale);
        }
      else if (MaX(largeur_Cuthill_CLL, largeur_Cuthill)
           < MaX(largeur_Cuthill_inverse_CLL, largeur_Cuthill_inverse)  )
   //   else if (largeur_Cuthill < largeur_Cuthill_inverse  )
        // bizarre, cela veut dire qu'il faut revenir à la forme de Cuthill directe
        { nouvelle_numerotation = true;
          //  on met la numérotation définitive relativement au  tableau directe
          Tableau <int> num_courant(nbMaillageTotal); // tableau des numéros courant de noeud
                                                  // pour chaque maillage
          for (int ia=1;ia <= nb_noeud; ia++)
   // je ne comprend pas ce que j'ai fait. je modifie en faisant ce que je pense être bon ???
   ////modifié   	     { Noeud* noe = tab_N_final(ia); // pour simplifier
   ////modifié   	       int num = (num_courant(noe->Num_Mail())++);
   ////modifié   	       noe->Change_num_noeud(num);
   ////modifié   	      };
             tab_N_final(ia)->Change_num_noeud(ia);
          demi_largeur_totale = MaX(largeur_Cuthill_CLL, largeur_Cuthill);
        }
      else
        // c'est le cas normale
        { nouvelle_numerotation=true;
          //  on met la numérotation définitive relativement au  tableau inverse
   // là je ne comprend pas ce que j'ai fait, car la numérotation inverse a déjà été faite donc il n'y a rien
   // à faire, je comment donc la suite

   ////       Tableau <int> num_courant(nbMaillageTotal); // tableau des numéros courant de noeud
   ////                                               // pour chaque maillage
   ////       for (int ia=1;ia <= nb_noeud; ia++)
   ////   	     { Noeud* noe = tab_N_inverse(ia); // pour simplifier
   ////   	       int num = (num_courant(noe->Num_Mail())++);
   ////   	       noe->Change_num_noeud(num);
   ////   	      };
        };
      
      // on calcule si demandé, la largeur de bande en ddl qui résulte de la nouvelle numérotation
      // avant de changer les numéros de noeuds
      // et la mise à jour des pointeurs d'assemblages
      Tableau <Noeud*> tab_N_final_final;// ne sert que pour le cas nb_casAssemb != NULL
      if (nouvelle_numerotation && (nb_casAssemb != NULL))
       { // on garde en mémoire la numérotation des noeuds, dans l'ordre de tab_N_final
         // car on ne connait pas exactement le cheminement précédent de ce qui est retenue au final
         tab_N_final_final.Change_taille(nb_noeud);
         for (int i=1;i<=nb_noeud;i++)
           tab_N_final_final(tab_N_final(i)->Num_noeud()) = tab_N_final(i);
         // on met à jour les pointeurs d'assemblage en suivant le nouvel ordre de noeud
         MiseAJourPointeurAssemblage_interne(*nb_casAssemb,tab_N_final_final);
         // on calcul la largeur finale
         int demi = 0; int total = 0;
         int cumule = 0;
         // cas des CLL:
         for (int i = 1; i<= taille_tab_cll;i++)
           { Tableau <Condilineaire>& condCLL = tab_condCLL(i);
             int taille = condCLL.Taille();
             for (int j=1;j<= taille;j++)
                condCLL(j).Largeur_Bande(demi,total,*nb_casAssemb);
           };
         // on s'occupe des maillages
         int demi_pour_mail=0; int total_pour_mail=0;
         for (int imil=1;imil<=nbMaillageTotal;imil++)
            {int demi_inter=0; int total_inter=0;
             tabMaillage(imil)->Largeur_Bande(demi_inter,total_inter,*nb_casAssemb);
             demi_pour_mail = MaX(demi_pour_mail,demi_inter);
             total_pour_mail =MaX(total_pour_mail,total_inter);
            };
         // on garde les maxi
         demi = MaX(demi,demi_pour_mail);
         total =MaX(total,total_pour_mail);
         // enregistrement
         nouvelles_largeur_en_ddl.deux = demi;
         nouvelles_largeur_en_ddl.un = total;
         nouvelles_largeur_en_ddl.trois = demi_pour_mail;
        
         if (ParaGlob::NiveauImpression() > 2)
         cout << "\n $$$  ==>> opti. glob. numerot. $$$ "
                   << " 1/2 larg. ddl ==> " <<  demi
                   << " larg. totale ==> " << total;
//cout << "\n entrer une valeur pour continuer ";
//int toto; cin >> toto;
       };
    
      // dans le cas d'une nouvelle numérotation + dans le cas où on veut un changement
      // de numérotation effectif dans les noeuds
      // ->> introduction de la nouvelle numérotation dans les noeuds et mise à jour des reférences
      if ((nouvelle_numerotation) && (!sans_changement_num_noeud)) 
       // il faut donc redéfinir une numérotation pour chaque maillage. Celle-ci
       // ne sera pas aussi optimum que dans le cas d'un seul maillage, mais elle devrait
       // être meilleure
       //   -- un tableau d'indice qui donne le nouveau numéro en cours pour chaque maillage
       { Tableau<int> num_noeu_par_maillage(nbMaillageTotal,0);
         //   un nouveau tableau intermédiaire tel que le noeud t_noe_ordonnee(i), a le numéro i
         Tableau <Noeud *> t_noe_ordonnee(nb_noeud); // le tableau global de noeuds
         for (int ia=1;ia <= nb_noeud; ia++)
          { Noeud* noe = t_noe(ia); // pour simplifier
            t_noe_ordonnee(noe->Num_noeud()) = noe;
          };
         //   si nouvelle numérotation est vrai, on parcourt le tableau et on renumérote à la volée
         //   la méthode revient à compresser la numérotation pour chaque maillage de manière a
         //   rester dans les limites du nombre de noeud pour chaque maillage
         for (int ia=1;ia <= nb_noeud; ia++)
           { Noeud* noe = t_noe_ordonnee(ia); // pour simplifier
             int num_mail = noe->Num_Mail();
             num_noeu_par_maillage(num_mail)++;
      ////--debug
      //cout << "\n debug LesMaillages::Renumerotation( "
      //     << "\n num_noeu_par_maillage("<<num_mail<<")= "<< num_noeu_par_maillage(num_mail)<<flush;
      ////--- fin debug
             noe->Change_num_noeud(num_noeu_par_maillage(num_mail));
           };

         // Maintenant on s'occupe des références et de la numérotation définitive
         // si on a introduit une nouvelle numérotation
         // -- on s'occupe des numéros de référence
         //  1) on définit un tableau par maillage qui contient les nouveaux numéros
         //       t_nv_num(j)(i) est pour le maillage j, le nouveau numéro du noeud
         //       qui avait auparavant le numéro "i"
         Tableau <Tableau <int> > t_nv_num(nbMaillageTotal); // nouveau num/ au ancien
         for (int iml=1; iml<= nbMaillageTotal;iml++)
           t_nv_num(iml).Change_taille(tabMaillage(iml)->Nombre_noeud()); // init
         for (int ia=1;ia <= nb_noeud; ia++)
          { Noeud* noe = t_noe(ia); // pour simplifier, on utilise t_noe et non t_noe_ordonnee
             // car ensuite on utilise t_oldNumNoeud qui suit le même ordre que t_noe
      // //--debug
      // cout << "\n debug LesMaillages::Renumerotation( "
      //      << "\n noe->Num_Mail()= "<<noe->Num_Mail() <<", ia= "<< ia
      //      << " noe->Num_noeud()= "<<noe->Num_noeud()
      //      << " t_oldNumNoeud(ia)= "<< t_oldNumNoeud(ia) << flush;
      ////--- fin debug
             t_nv_num(noe->Num_Mail())(t_oldNumNoeud(ia))=noe->Num_noeud();
          };
         //   2) maintenant on change les références
         for (int idmail=1;idmail<=nbMaillageTotal;idmail++)
            lesRef.Mise_a_jour_ref_noeud(t_nv_num(idmail),idmail);

         // --- on reconstruit les tableaux de pointeurs de noeuds dans chaque maillage
         //  a) on crée un tableau intermédiaire de tous les tableaux de noeuds
         Tableau <Tableau <Noeud *> *> t_t_noeud(nbMaillageTotal);
         for (int iml=1; iml<= nbMaillageTotal;iml++)
           t_t_noeud(iml) = &(tabMaillage(iml)->Tab_noeud()); // init
         //  b) on le remplit
         for (int ia=1;ia <= nb_noeud; ia++)
          { Noeud* noe = t_noe_ordonnee(ia); // pour simplifier
            (*t_t_noeud(noe->Num_Mail()))(noe->Num_noeud()) = noe;
          };
       };
    
       // affichage du résultat et éventuellement deuxième étape concernant le 
       // changement des pointeurs d'assemblage
       if (nouvelle_numerotation)
        {if (nb_casAssemb == NULL) // cas sans changement des pointeurs
         // si on ne veut pas changer les pointeurs d'assemblage dans la foulée
         // on met une information sur la largeur de bande nouvelle, en noeud,
         // qui découle de la nouvelle numérotation (et non de l'assemblage)
          {
          
           int largeur_finale_CLL = 0; // init
           for (int i = 1; i<= taille_tab_cll;i++)
             { Tableau <Condilineaire>& condCLL = tab_condCLL(i);
               int taille = condCLL.Taille();
               for (int j=1;j<= taille;j++)
                 largeur_finale_CLL=MaX(largeur_finale_CLL,condCLL(j).DiffMaxiNumeroNoeud());
             };
           if (ParaGlob::NiveauImpression() > 0)
            { cout << "\n pour l'ensemble des conditions linaires: la 1/2 largeur de bande en noeud, finale est "
                   << largeur_finale_CLL << flush;
            };

          
          
 // non c'est débile, car on n'a pas fait de nouvelle numérotation en ddl, donc cela ne sert à rien de les imprimer
 // et au niveau de la numérotation en noeud, c'est déja visualisé
/*
          int demi = 0; int total = 0;
            int cumule = 0;
            // on est quand même obligé de considérer un cas d'assemblage, on prend le dernier
            // par défaut
            // on récupère le nombre actuel de cas d'assemblage
            int nb_actuel = tab_nb_assemb;
            #ifdef MISE_AU_POINT
            if (nb_actuel == 0)
             {cout << "\n erreur Renumerotation : pas de cas d'assemblage encore defini !! "
                   << " la renumerotation n'est pas possible ....";
              Sortie(1);
             };
            #endif
            Nb_assemb  nbAssemble(nb_actuel);

            // cas des CLL:
            for (int i = 1; i<= taille_tab_cll;i++)
             { Tableau <Condilineaire>& condCLL = tab_condCLL(i);
               int taille = condCLL.Taille();
               for (int j=1;j<= taille;j++)
                  condCLL(j).Largeur_Bande(demi,total,nbAssemble);
             };

            // on s'occupe des maillages
            int demi_pour_mail=0; int total_pour_mail=0;
            for (int imil=1;imil<=nbMaillageTotal;imil++)
               {int demi_inter=0; int total_inter=0;
                tabMaillage(imil)->Largeur_Bande(demi_inter,total_inter,nbAssemble);
                demi_pour_mail = MaX(demi_pour_mail,demi_inter);
                total_pour_mail =MaX(total_pour_mail,total_inter);
               };
            // on garde les maxi
            demi = MaX(demi,demi_pour_mail);
            total =MaX(total,total_pour_mail);
            // enregistrement
            nouvelles_largeur_en_ddl.deux = demi;
            nouvelles_largeur_en_ddl.un = total;
            nouvelles_largeur_en_ddl.trois = demi_pour_mail;

            // affichage du résultat
            if (ParaGlob::NiveauImpression() >= 3)
            cout << "\n $$$  =>> opti. glob.  numerot. $$$ "
                      << " 1/2 larg. ddl => " <<  demi
                      << " larg. totale => " << total
                      << flush;
*/




          }
         else // sinon c'est le cas où on veut changer les pointeurs d'assemblage
          {// deuxième partie pour les pointeurs d'assemblage:
           // on doit mettre à jour le tableau t_i_n pour les pointeurs d'assemblage
           // concernant uniquement les numéros de noeuds
           // --> deux cas suivant que l'on ne veut pas enregistrer la nouvelle numérotation
           //     des noeuds ou non
           if (sans_changement_num_noeud)
            { // mise à jour des numéros de noeud, on revient aux numéros initiaux
              // on revient au numéro initiaux
              for (int i=1;i<=nb_noeud;i++)
                t_noe(i)->Change_num_noeud(t_oldNumNoeud(i));
              // pour chaque noeud, tab_N_final(i) correspond au noeud qui avait le numéro i ancien
              //   et qui a maintenant le numéro tab_N_final(i)->Num_noeud()
              // mise à jour de t_i_n
              MiseAJourTableau_t_i_n(*nb_casAssemb,tab_N_final_final);
            }
           else
            {MiseAJourTableau_t_i_n(*nb_casAssemb,tab_N_final_final);
            };
          };
       }
       else 
       {// on remet néanmoins l'ancienne numérotation, car elle a changé
        int nbN = t_noe.Taille();
        for (int i=1;i<=nbN;i++)
          t_noe(i)->Change_num_noeud(t_oldNumNoeud(i));
        if (ParaGlob::NiveauImpression() >= 3)
            cout << "\n $$$  au final numerot. idem $$$ " << flush;
        nouvelle_numerotation = false;
        calcul_ok = true;
       };

     };
   // retour
   return (calcul_ok && nouvelle_numerotation);
 
 };

// renumérotation des noeuds maillages par maillage,
// === sans prise en compte de conditions linéaires ===
// en sortie les maillages sont mis à jour si la nouvelle numérotation conduit à une largeur de bande
// plus faible que la largeur initiale: en noeuds
// ramène: false si rien n'a changé (à cause d'un pb ou parce que la renumérotation n'est pas meilleure)
//         vrai sinon
bool LesMaillages::Renumerotation(LesReferences& lesRef)
{  // on crée les éléments frontières car cela utilise les numéros des noeuds, qui vont être changé
   // mais ce n'est pas toujours bien de recréer les frontières, car on peut avoir des grandeurs
   // qui dépendent des frontières
   // comme par exemple les éléments de contact: si on refait les frontières,
   // il faut refaire les éléments de contact
   // or la renumérotation n'a pas à changer les frontières en elles-mêmes
   // donc on adopte une création conditionnelle
   if ((listFrontiere.Taille() == 0) || (tt_noeud_front.Taille() == 0))
      LesMaillages::CreeElemFront(); // on crée les éléments frontières
 
   // on passe en revue tous les maillages pour une renumérotation individuelle
   bool calcul_ok = false; // init par défaut

   Tableau <Tableau <Condilineaire> > condCLL; // un tableau vide pour l'appel
   for (int imail=1;imail<=nbMaillageTotal;imail++)
      { if (ParaGlob::NiveauImpression() > 2)
           cout << "\n ===>> traitement du maillage: " << tabMaillage(imail)->NomDuMaillage();
        bool inter = tabMaillage(imail)->Renumerotation(lesRef,condCLL);
        calcul_ok = calcul_ok || inter;
      };

   // retour
   return calcul_ok ;
 };

// indique aux éléments un niveau de précision de calcul désiré pour les prochains calculs
// precision = 0 : aucune précision demandée, precision >=0 : précision maximale demandée
void LesMaillages::Drapeau_preparation_calcul_precis(int precision)
	{for (int i1 = 1; i1<= nbMaillageTotal; i1++)
      { int nbelmax = Nombre_element(i1);
        Maillage* maillage =  tabMaillage(i1); // pour simplifier
        for (int jel = 1; jel <= nbelmax; jel++)
         { maillage->Element_mail(jel).Drapeau_preparation_calcul_precis(precision);};
		    };
 };
	 
// on s'occupe de mettre à jour les types de pb et les ddl types associés
void LesMaillages::Mise_a_jour_type_pb_type_associe_ddl()
{ types_de_problemes.clear();
  ddl_representatifs_des_physiques.clear();
  for (int i = 1; i<= nbMaillageTotal; i++)
   {
    {//const list <EnumElemTypeProblem >& type_pb = (tabMaillage(i))->Types_de_problemes(); // pour simplifier
     const Tableau <EnumElemTypeProblem >& type_pb = (tabMaillage(i))->Types_de_problemes(); // pour simplifier
//     list <EnumElemTypeProblem>::const_iterator il,ilfin=type_pb.end();
//     for (il=type_pb.begin();il != ilfin;il++)
     int taill = type_pb.Taille();
     for (int j=1;j<=taill;j++)
      if (find(types_de_problemes.begin(),types_de_problemes.end(),type_pb(j)) == types_de_problemes.end())
         types_de_problemes.push_back(type_pb(j));//(*il);
    };
    {//const list <Enum_ddl >& type_ddl = (tabMaillage(i))->Ddl_representatifs_des_physiques(); // pour simplifier
     //list <Enum_ddl>::const_iterator il,ilfin=type_ddl.end();
     //for (il=type_ddl.begin();il != ilfin;il++)
     const Tableau <Enum_ddl >& type_ddl = (tabMaillage(i))->Ddl_representatifs_des_physiques(); // pour simplifier
     int taill = type_ddl.Taille();
     for (int j=1;j<=taill;j++)
      if (find(ddl_representatifs_des_physiques.begin(),ddl_representatifs_des_physiques.end()
         ,type_ddl(j)) == ddl_representatifs_des_physiques.end())
         ddl_representatifs_des_physiques.push_back(type_ddl(j));
    };
   };
  types_de_problemes.sort(); types_de_problemes.unique();
  ddl_representatifs_des_physiques.sort(); ddl_representatifs_des_physiques.unique();
};

    // --- utilitaires pour calculs particuliers-------

//     Tableau <TypeQuelconque>  integ_vol_typeQuel,  integ_vol_typeQuel_t;
//     Tableau <const Reference*>   ref_integ_vol; // les références associées
//     // 2) intégration de volume et en temps: donc on commule le delta
//     Tableau <TypeQuelconque>  integ_vol_t_typeQuel,  integ_vol_t_typeQuel_t;
//     Tableau <const Reference*>  ref_integ_vol_t; // les références associées
//    LesReferences* lesRef; // references


// calcul des diverses intégrations: volume et volume + temps,
// alimentation des grandeurs globales associées
void LesMaillages::Integration()
{ // on passe en revue les références de volumes a intégrer
// Tableau <const Reference*>   ref_integ_vol; // les références associées

  // les références sont ordonnées par apparition dans le fichier .info
  // des intégrales, ceci permet de repérer les bonnes grandeurs à cummuler
  int taill = ref_integ_vol.Taille();
  for (int rang_integ =1;rang_integ<= taill;rang_integ++)
   if (ref_integ_vol(rang_integ) != NULL) // si null cela veut que l'on n'intègre pas
     // l'intégrale stockée reste fixe pendant le calcul
   { const ReferenceNE * ref = ((ReferenceNE *) ref_integ_vol(rang_integ));
     // initialisation du conteneur relatif à chaque ref
     TypeQuelconque& TQ = integ_vol_typeQuel(rang_integ); // pour simplifier
     // le conteneur qui contient le résultat globalisé
     TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
     g_TG->InitParDefaut(); // on initialise le conteneur
    
     // cumule des valeurs: on récupère les infos à partir des éléments concernés
     int ref_Taille=ref->Taille();
     for (int jj= 1; jj<= ref_Taille; jj++)
         {int nbb = ref->Numero(jj) ; // le numero de l'element dans le maillage
          int nnn = ref->Nbmaille(); // le numero du maillage
          // recup de l'element
          Element * poi = & Element_LesMaille(nnn,nbb);
          // demande a l'element des infos
          const Tableau <TypeQuelconque>* tab_Q = poi->Integ_vol_typeQuel();
          const Tableau <int>& index_integ = *(poi->Index_Integ_vol_typeQuel());
          // la grandeur à cumuler c'est celle qui a le bon indexe
          int indice = index_integ.Contient(rang_integ);
          *(g_TG) += *((*tab_Q)(indice).Grandeur_pointee());
          
// -- les deux lignes d'avant sont a priori équivalentes aux lignes qui suivent
//          int nb_integ = tab_Q->Taille(); // le nombre d'intégrale à considérer
//          for (int iteg = 1;iteg <= nb_integ;iteg++)
//           {if ((index_integ)(iteg)==rang_integ) // si l'index est négatif, on ne cumule pas
//            // cela veut aussi dire que l'intégrale est figée
//              // sinon si on a le bon index: on cumule l'intégrale
//             {*(g_TG) += *((*tab_Q)(iteg).Grandeur_pointee());
//              break;
//             };
//           };

         };
     // maintenant il s'agit d'alimenter les grandeurs globales

     // on récupère le pointeur correspondant à la grandeur correspondant au nom
     // de référence
     const string* nom_de_ref = g_TG->Nom_ref();
     #ifdef MISE_AU_POINT
     if (nom_de_ref == NULL)
        { cout << "\n *** pb dans l'integration  !! "
               << " nom_de_ref est nul, on ne peut pas continuer  "
               << "\n LesMaillages::Integration()"<<flush;
          Sortie(1);
        };
     #endif
     // récup du pointeur de conteneur
     const void* pointe =  (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
     #ifdef MISE_AU_POINT
     if (pointe == NULL)
       { cout << "\n *** pb dans l'integration  !! "
              << " la variable globale  "<< (*nom_de_ref)
              << ", n'est pas disponible, on ne peut pas continuer  "
               << "\n LesMaillages::Integration()"<<flush;
          Sortie(1);
       };
     #endif
     // on l'affecte
//// --- debug
//cout <<  "\n debug LesMaillages::Integration()  "
//     << " \n valeur de l'integral: " << g_TG->Nom_ref()
//     << " ::  " <<  *(g_TG) << flush;
//
//// -- fin debug
     
     
     
     TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
     *(gr_quelc->Grandeur_pointee()) = *(g_TG);
   };
  // même chose pour les intégrales en volume et en temps
  int taill1 = ref_integ_vol_t.Taille();
  for (int rang_integ =1;rang_integ<= taill1;rang_integ++)
   if (ref_integ_vol_t(rang_integ) != NULL) // si null cela veut que l'on n'intègre pas
     // l'intégrale stockée reste fixe pendant le calcul
   { const ReferenceNE * ref = ((ReferenceNE *) ref_integ_vol_t(rang_integ));
     // initialisation du conteneur relatif à chaque ref
     TypeQuelconque& TQ = integ_vol_t_typeQuel(rang_integ); // pour simplifier
     // le conteneur qui contient le résultat globalisé
     TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
     g_TG->InitParDefaut(); // on initialise le conteneur
    
     // cumule des valeurs: on récupère les infos à partir des éléments concernés
     int ref_Taille=ref->Taille();
     for (int jj= 1; jj<= ref_Taille; jj++)
         {int nbb = ref->Numero(jj) ; // le numero de l'element dans le maillage
          int nnn = ref->Nbmaille(); // le numero du maillage
          // recup de l'element
          Element * poi = & Element_LesMaille(nnn,nbb);
          // demande a l'element des infos
          const Tableau <TypeQuelconque>* tab_Q = poi->Integ_vol_t_typeQuel();
          const Tableau <int>&  index_integ = *(poi->Index_Integ_vol_t_typeQuel());
          // la grandeur à cumuler c'est celle qui a le bon indexe
          int indice = index_integ.Contient(rang_integ);
          *(g_TG) += *((*tab_Q)(indice).Grandeur_pointee());

          
// -- les deux lignes d'avant sont a priori équivalentes aux lignes qui suivent
//          int nb_integ = tab_Q->Taille(); // le nombre d'intégrale à considérer
//          for (int iteg = 1;iteg <= nb_integ;iteg++)
//           {if ((index_integ)(iteg)==rang_integ)
//             // sinon si on a le bon index: on cumule l'intégrale
//             {*(g_TG) += *((*tab_Q)(iteg).Grandeur_pointee());
//              break;
//             };
//           };
         };
     // maintenant il s'agit d'alimenter les grandeurs globales

     // on récupère le pointeur correspondant à la grandeur correspondant au nom
     // de référence
     const string* nom_de_ref = g_TG->Nom_ref();
     #ifdef MISE_AU_POINT
     if (nom_de_ref == NULL)
        { cout << "\n *** pb dans l'integration  !! "
               << " nom_de_ref est nul, on ne peut pas continuer  "
               << "\n LesMaillages::Integration()"<<flush;
          Sortie(1);
        };
     #endif
     // récup du pointeur de conteneur
     const void* pointe =  (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
     #ifdef MISE_AU_POINT
     if (pointe == NULL)
       { cout << "\n *** pb dans l'integration  !! "
              << " la variable globale  "<< (*nom_de_ref)
              << ", n'est pas disponible, on ne peut pas continuer  "
               << "\n LesMaillages::Integration()"<<flush;
          Sortie(1);
       };
     #endif
     // on l'affecte
     TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
     *(gr_quelc->Grandeur_pointee()) = *(g_TG);
   };
};


// calcul des diverses statistiques sur des ref de noeuds et avec éventuellement
// cumul sur le temps
// alimentation des grandeurs globales associées
void LesMaillages::CalStatistique()
{ // on passe en revue les références de noeud des statistiques
  {// Tableau <const Reference*>   ref_statistique; // les références associées
   int NB_ref = ref_statistique.Taille();
   if (NB_ref)
    {// on boucle sur les ref
     for (int i_ref =1;i_ref<= NB_ref;i_ref++)
      if (ref_statistique(i_ref) != NULL) // si null cela veut que l'on ne fait rien
        // la statistique stockée reste fixe pendant le calcul
       { const ReferenceNE * ref = ((ReferenceNE *) ref_statistique(i_ref));
         // initialisation du conteneur relatif à chaque ref
         TypeQuelconque& TQ = statistique_typeQuel(i_ref); // pour simplifier
         // le conteneur qui contient le résultat globalisé
         TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
         g_TG->InitParDefaut(); // on initialise le conteneur
         
         int ref_Taille=ref->Taille();
         int i_mail = ref->Nbmaille(); // le numero du maillage
         
         Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) g_TG); // pour simplifier
         Fonction_nD* fct = gr.Fct(); // récupération d'un pointeur de fonction nD

         // différent choix
         if (fct == NULL)
            { // cas d'un stockage pour ddl_etendu
              Ddl_enum_etendu& ddl_enu_eten = pour_statistique_de_ddl(i_ref);// récup du ddl
              // on veut : (1) la somme, (2) la moyenne, (3) le max, (4) le min, (5) le max des | | , (6) le min des | |
              // tab_val(k)    : la grandeur k
              // tab_index(k)  : k= 1 -> le numéro du noeud pour le max
              //                 k= 2 -> le numéro du noeud pour le min
              //                 k= 3 -> le numéro du noeud pour le max des | |
              //                 k= 4 -> le numéro du noeud pour le min des | |
              
              // t10(i), i=1 à 6 --> correspond aux 6 valeurs de statistique == tab_val(k)
              Vecteur& t10 = (gr.ConteneurVecteur());
              t10(4)=t10(6)=ConstMath::tresgrand; // on met les mini très grand
              // t10(i), i=7 à 10 --> correspond aux numéros de noeud, stockés en double au lieu de int
              // == tab_index(k)
              // ceci pour utiliser uniquement un seul conteneur global
              double& tab_pour_MAXI_1 = t10(7);
              double& tab_pour_MAXI_2 = t10(8);
              double& tab_pour_MAXI_3 = t10(9);
              double& tab_pour_MAXI_4 = t10(10);

              // on regarde s'il s'agit d'un ddl pur ou étendu
              if (ddl_enu_eten.Nom_vide())
               // cas d'un ddl pur
               {// récup de l'énumération
                Enum_ddl enu = ddl_enu_eten.Enum();
                // cumule des valeurs: on récupère les infos à partir des noeuds concernés
                for (int jj= 1; jj<= ref_Taille; jj++)
                   {int nbb = ref->Numero(jj) ; // le numero du noeud dans le maillage
                    // récupération du Noeud
                    Noeud& noe =  Noeud_LesMaille(i_mail,nbb);
                    // récup de la valeur du ddl
                    double val_du_ddl = 0.; // init
                    if (noe.Existe_ici(enu))
                      {val_du_ddl = noe.Ddl_noeud_tdt(enu).Valeur();}
                    #ifdef MISE_AU_POINT
                    else
                      {if (ParaGlob::NiveauImpression() >= 4)
                        {if (ParaGlob::Francais())
                          {cout << "\n attention la grandeur " << ddl_enu_eten.Nom_plein()
                                << " n'est pas disponible pour statistique, on met 0 a la place";}
                         else
                          {cout << "\n Warning the quantity  " << ddl_enu_eten.Nom_plein()
                                << " is not available for statistic, the value will be 0 ";};
                        };
                      };
                    #endif
                    // le calcul des grandeurs
                    t10(1) += val_du_ddl;
                    t10(2) += 1.; // on s'en sert ici comme compteur
                    int num_noeud = noe.Num_noeud();
                    if (t10(3) < val_du_ddl)
                     { t10(3) = val_du_ddl;
                       tab_pour_MAXI_1 = num_noeud;
                     };
                    if (t10(4) > val_du_ddl)
                     { t10(4) = val_du_ddl;
                       tab_pour_MAXI_2 = num_noeud;
                     };
                    if (Dabs(t10(5)) < Dabs(val_du_ddl))
                     { t10(5) = val_du_ddl;
                       tab_pour_MAXI_3 = num_noeud;
                     };
                    if (Dabs(t10(6)) > Dabs(val_du_ddl))
                     { t10(6) = val_du_ddl;
                       tab_pour_MAXI_4 = num_noeud;
                     };
                   };
                // calcul de la moyenne
                t10(2) = t10(1) / t10(2);
               }
              else // cas d'un ddl étendu
               {// cumule des valeurs: on récupère les infos à partir des noeuds concernés
                for (int jj= 1; jj<= ref_Taille; jj++)
                   {int nbb = ref->Numero(jj) ; // le numero du noeud dans le maillage
                    // récupération du Noeud
                    Noeud& noe =  Noeud_LesMaille(i_mail,nbb);
                    // récup de la valeur du ddl
                    double val_du_ddl = 0.; // init
                    // on examine tout d'abord le cas particulier des positions
                    bool trouver = false;
                    // on regarde d'abord s'il s'agit d'une info spécifique au contact
                    int posi = ddl_enu_eten.Position()-NbEnum_ddl();
                    switch (posi)
                      { case 123: // "X1_t"
                          { val_du_ddl = noe.Coord1()(1);trouver=true; break;}
                        case 124: // "X2_t"
                          { val_du_ddl = noe.Coord1()(2);trouver=true; break;}
                        case 125: // X3_t
                          { val_du_ddl = noe.Coord1()(3);trouver=true; break;}
                        case 126: // X1_t0
                          { val_du_ddl = noe.Coord0()(1);trouver=true; break;}
                        case 127: // X2_t0
                          { val_du_ddl = noe.Coord0()(2);trouver=true; break;}
                        case 128: // X3_t0
                          { val_du_ddl = noe.Coord0()(3);trouver=true; break;}
                        default: ;// rien
                      };
                    // si ce n'était pas un cas particulier on continue la recherche
                    if (!trouver)
                      // on regarde si la grandeur existe
                      {if (noe.Existe_ici_ddlEtendu(ddl_enu_eten))
                        {val_du_ddl = noe.DdlEtendue(ddl_enu_eten).ConstValeur();}
                      #ifdef MISE_AU_POINT
                      else
                        {if (ParaGlob::NiveauImpression() >= 4)
                          {if (ParaGlob::Francais())
                            {cout << "\n attention la grandeur " << ddl_enu_eten.Nom_plein()
                                  << " n'est pas disponible pour statistique, on met 0 a la place";}
                           else
                            {cout << "\n Warning the quantity  " << ddl_enu_eten.Nom_plein()
                                  << " is not available for statistic, the value will be 0 ";};
                          };
                        };
                      #endif
                     };
                    // le calcul des grandeurs
                    t10(1) += val_du_ddl;
                    t10(2) += 1.; // on s'en sert ici comme compteur
                    int num_noeud = noe.Num_noeud();
                    if (t10(3) < val_du_ddl)
                     { t10(3) = val_du_ddl;
                       tab_pour_MAXI_1 = num_noeud;
                     };
                    if (t10(4) > val_du_ddl)
                     { t10(4) = val_du_ddl;
                       tab_pour_MAXI_2 = num_noeud;
                     };
                    if (Dabs(t10(5)) < Dabs(val_du_ddl))
                     { t10(5) = val_du_ddl;
                       tab_pour_MAXI_3 = num_noeud;
                     };
                    if (Dabs(t10(6)) > Dabs(val_du_ddl))
                     { t10(6) = val_du_ddl;
                       tab_pour_MAXI_4 = num_noeud;
                     };
                   };
                // calcul de la moyenne
                t10(2) = t10(1) / t10(2);
               }
 ////------- debug ---------
// cout << "\n debug statistique: ";
// cout << t10;
 //
 //
 ////------- fin debug --------
               
            }
         else // cas d'un stockage pour fonction nD
            { Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) g_TG); // pour simplifier
              Fonction_nD* fct = gr.Fct(); // récupération de la fonction nD
              // supposons que la fonction nD ramène n valeurs,
              // pour chaque valeur on va avoir pour la valeur i :
              // ((6*(i-1)+1) la somme, ((6*(i-1)+2) la moyenne, ((6*(i-1)+3) le max, ((6*(i-1)+4) le min,
              // ((6*(i-1)+5) -> le numéro du noeud pour le max, ((6*(i-1)+6) -> le numéro du noeud pour le min,
              // donc en tout cela donne 6*n valeurs
              // ensuite on a:
              // (6*n + 1) le max des | |, (6*n + 2) le min des | |,
              // (6*n + 3) -> le numéro du noeud pour le max des | |
              // (6*n + 4) -> le numéro du noeud pour le min des | |
              // d'où un vecteur de taille (6*n + 4)

              // on commence par récupérer les conteneurs des grandeurs à fournir
              
              List_io <Ddl_enum_etendu>& li_enu_scal = fct->Li_enu_etendu_scalaire();
              List_io <TypeQuelconque >& li_quelc = fct->Li_equi_Quel_evolue();
              int nb_composante = fct->NbComposante();

              // t10(i), i=1 à 6 --> correspond aux 6 valeurs de statistique == tab_val(k)
              Vecteur& t6 = (gr.ConteneurVecteur());
              t6(4)=t6(6)=ConstMath::tresgrand; // on met les mini très grand

              // cumule des valeurs: on récupère les infos à partir des noeuds concernés
              for (int jj= 1; jj<= ref_Taille; jj++)
                {int nbb = ref->Numero(jj) ; // le numero du noeud dans le maillage
                 // récupération du Noeud
                 Noeud& noe =  Noeud_LesMaille(i_mail,nbb);
                 
                 // récupération d'une liste d'info
                 // le tableau de retour à la taille de li_enu_scal et contient
                 // les valeurs correspondantes aux Ddl_enum_etendu stockées au noeud
                 //    en fait ici on cumule les ddl pur "et" les ddl_étendue,
                 // li_quelc : est modifié par les valeurs contenues au noeud
                 Tableau <double> tab =  noe.Valeur_multi_et_Tensorielle(li_enu_scal,li_quelc);
                 // récup des valeurs de la fonction
                 Tableau <double> & t_ret = fct->Valeur_FnD_Evoluee(&tab,&li_enu_scal,&li_quelc,NULL,NULL);
                 int num_noeud = noe.Num_noeud();
                 // le calcul des grandeurs sur chaque composante
                 double norme=0;
                 for (int i=1;i<= nb_composante;i++)
                   { int decal = 6*(i-1);
                     double val_composante = t_ret(i);
                     t6(decal+1) += val_composante;
                     t6(decal+2) += 1.; // on s'en sert ici comme compteur
                     if (t6(decal+3) < val_composante)
                      { t6(decal+3) = val_composante;
                        t6(decal+5) = num_noeud;
                      };
                     if (t6(decal+4) > val_composante)
                      { t6(decal+4) = val_composante;
                        t6(decal+6) = num_noeud;
                      };
                     norme +=val_composante*val_composante;
                   };
                 // on traite la norme
                 int decal = 6*nb_composante;
                 norme = sqrt(norme);
                 if (t6(decal+1) < norme)
                  { t6(decal+1) = norme;
                    t6(decal+3) = num_noeud;
                  };
                 if (t6(decal+2) > norme)
                  { t6(decal+2) = norme;
                    t6(decal+4) = num_noeud;
                  };
                };
              // on calcule les moyennes
              for (int i=1;i<= nb_composante;i++)
                 { int decal = 6*(i-1);
                   t6(decal+2) = t6(decal+1)/t6(decal+2);
                 };
            };

        // maintenant il s'agit d'alimenter les grandeurs globales

        // on récupère le pointeur correspondant à la grandeur correspondant au nom
        // de référence
        const string* nom_de_ref = g_TG->Nom_ref();
        #ifdef MISE_AU_POINT
        if (nom_de_ref == NULL)
           { cout << "\n *** pb dans le transfert d'une statistique  !! "
                  << " nom_de_ref est nul, on ne peut pas continuer  "
                  << "\n LesMaillages::CalStatistique()"<<flush;
             Sortie(1);
           };
        #endif
        // récup du pointeur de conteneur
        const void* pointe =  (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
        #ifdef MISE_AU_POINT
        if (pointe == NULL)
          { cout << "\n *** pb dans le transfert d'une statistique  !! "
                 << " la variable globale  "<< (*nom_de_ref)
                 << ", n'est pas disponible, on ne peut pas continuer  "
                  << "\n LesMaillages::CalStatistique()"<<flush;
             Sortie(1);
          };
        #endif
        // on l'affecte
        TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
        *(gr_quelc->Grandeur_pointee()) = *(g_TG);

       };
    
    }; // fin de la boucle sur les ref
  };
  
 // idem pour l'accumulation en temps
  {// Tableau <const Reference*>   ref_statistique_t; // les références associées
   int NB_ref = ref_statistique_t.Taille();
   if (NB_ref)
    {// on boucle sur les ref
     for (int i_ref =1;i_ref<= NB_ref;i_ref++)
      if (ref_statistique_t(i_ref) != NULL) // si null cela veut que l'on ne fait rien
        // la statistique stockée reste fixe pendant le calcul
       { const ReferenceNE * ref = ((ReferenceNE *) ref_statistique_t(i_ref));
         // initialisation du conteneur relatif à chaque ref
         TypeQuelconque& TQ = statistique_t_typeQuel(i_ref); // pour simplifier
         TypeQuelconque& TQ_t = statistique_t_typeQuel_t(i_ref); // le précédent
         // le conteneur qui contient le résultat globalisé
         TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
         g_TG->InitParDefaut(); // on initialise le conteneur
         
         int ref_Taille=ref->Taille();
         int i_mail = ref->Nbmaille(); // le numero du maillage
         
         Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) g_TG); // pour simplifier
         Fonction_nD* fct = gr.Fct(); // récupération d'un pointeur de fonction nD
         
         // le conteneur à t qui contient le résultat globalisé
         TypeQuelconque::Grandeur* g_TG_t = TQ_t.Grandeur_pointee();
         Grandeur_Vecteur_Nommer& gr_t = *((Grandeur_Vecteur_Nommer*) g_TG_t);

         // différent choix
         if (fct == NULL)
            { // cas d'un stockage pour ddl_etendu
              Ddl_enum_etendu& ddl_enu_eten = pour_statistique_t_de_ddl(i_ref);// récup du ddl
              // on veut : (1) la somme, (2) la moyenne, (3) le max, (4) le min, (5) le max des | | , (6) le min des | |
              // tab_val(k)    : la grandeur k
              // tab_index(k)  : k= 1 -> le numéro du noeud pour le max
              //                 k= 2 -> le numéro du noeud pour le min
              //                 k= 3 -> le numéro du noeud pour le max des | |
              //                 k= 4 -> le numéro du noeud pour le min des | |
              
              // t10(i), i=1 à 6 --> correspond aux 6 valeurs de statistique == tab_val(k)
              Vecteur& t10 = (gr.ConteneurVecteur());
              t10(4)=t10(6)=ConstMath::tresgrand; // on met les mini très grand
              // t10(i), i=7 à 10 --> correspond aux numéros de noeud, stockés en double au lieu de int
              // == tab_index(k)
              // ceci pour utiliser uniquement un seul conteneur global
              double& tab_pour_MAXI_1 = t10(7);
              double& tab_pour_MAXI_2 = t10(8);
              double& tab_pour_MAXI_3 = t10(9);
              double& tab_pour_MAXI_4 = t10(10);

              // on regarde s'il s'agit d'un ddl pur ou étendu
              if (ddl_enu_eten.Nom_vide())
               // cas d'un ddl pur
               {// récup de l'énumération
                Enum_ddl enu = ddl_enu_eten.Enum();
                // cumule des valeurs: on récupère les infos à partir des noeuds concernés
                for (int jj= 1; jj<= ref_Taille; jj++)
                   {int nbb = ref->Numero(jj) ; // le numero du noeud dans le maillage
                    // récupération du Noeud
                    Noeud& noe =  Noeud_LesMaille(i_mail,nbb);
                    // récup de la valeur du ddl
                    double val_du_ddl = 0.; // init
                    // on regarde si la grandeur existe
                    if (noe.Existe_ici(enu))
                      {val_du_ddl = noe.Ddl_noeud_tdt(enu).Valeur();}
                    #ifdef MISE_AU_POINT
                    else
                      {if (ParaGlob::NiveauImpression() >= 4)
                        {if (ParaGlob::Francais())
                          {cout << "\n attention la grandeur " << ddl_enu_eten.Nom_plein()
                                << " n'est pas disponible pour statistique cumulee, on met 0 a la place";}
                         else
                          {cout << "\n Warning the quantity  " << ddl_enu_eten.Nom_plein()
                                << " is not available for statistic cumuled, the value will be 0 ";};
                        };
                      };
                    #endif
                    // le calcul des grandeurs
                    t10(1) += val_du_ddl;
                    t10(2) += 1.; // on s'en sert ici comme compteur
                    int num_noeud = noe.Num_noeud();
                    if (t10(3) < val_du_ddl)
                     { t10(3) = val_du_ddl;
                       tab_pour_MAXI_1 = num_noeud;
                     };
                    if (t10(4) > val_du_ddl)
                     { t10(4) = val_du_ddl;
                       tab_pour_MAXI_2 = num_noeud;
                     };
                    if (Dabs(t10(5)) < Dabs(val_du_ddl))
                     { t10(5) = val_du_ddl;
                       tab_pour_MAXI_3 = num_noeud;
                     };
                    if (Dabs(t10(6)) > Dabs(val_du_ddl))
                     { t10(6) = val_du_ddl;
                       tab_pour_MAXI_4 = num_noeud;
                     };
                   };
                // calcul de la moyenne
                t10(2) = t10(1) / t10(2);
                // cumule sur le temps
                Vecteur& t10_t = (gr_t.ConteneurVecteur());
                t10(1) += t10_t(1); t10(2) += t10_t(2);
                t10(3) += t10_t(3); t10(4) += t10_t(4);
                t10(5) += t10_t(5); t10(6) += t10_t(6);
               }
              else // cas d'un ddl étendu
               {// cumule des valeurs: on récupère les infos à partir des noeuds concernés
                for (int jj= 1; jj<= ref_Taille; jj++)
                   {int nbb = ref->Numero(jj) ; // le numero du noeud dans le maillage
                    // récupération du Noeud
                    Noeud& noe =  Noeud_LesMaille(i_mail,nbb);
                    // récup de la valeur du ddl
                    double val_du_ddl = 0.; // init
                    // on examine tout d'abord le cas particulier des positions
                    bool trouver = false;
                    // on regarde d'abord s'il s'agit d'une info spécifique au contact
                    int posi = ddl_enu_eten.Position()-NbEnum_ddl();
                    switch (posi)
                      { case 123: // "X1_t"
                          { val_du_ddl = noe.Coord1()(1);trouver=true; break;}
                        case 124: // "X2_t"
                          { val_du_ddl = noe.Coord1()(2);trouver=true; break;}
                        case 125: // X3_t
                          { val_du_ddl = noe.Coord1()(3);trouver=true; break;}
                        case 126: // X1_t0
                          { val_du_ddl = noe.Coord0()(1);trouver=true; break;}
                        case 127: // X2_t0
                          { val_du_ddl = noe.Coord0()(2);trouver=true; break;}
                        case 128: // X3_t0
                          { val_du_ddl = noe.Coord0()(3);trouver=true; break;}
                        default: ;// rien
                      };
                    // si ce n'était pas un cas particulier on continue la recherche
                    if (!trouver)
                      {if (noe.Existe_ici_ddlEtendu(ddl_enu_eten))
                         {val_du_ddl = noe.DdlEtendue(ddl_enu_eten).ConstValeur();}
                       #ifdef MISE_AU_POINT
                       else
                         {if (ParaGlob::NiveauImpression() >= 4)
                           {if (ParaGlob::Francais())
                             {cout << "\n attention la grandeur " << ddl_enu_eten.Nom_plein()
                                   << " n'est pas disponible pour statistique cumulee, on met 0 a la place";}
                            else
                             {cout << "\n Warning the quantity  " << ddl_enu_eten.Nom_plein()
                                   << " is not available for statistic cumuled, the value will be 0 ";};
                           };
                         };
                       #endif
                      };
                    // le calcul des grandeurs
                    t10(1) += val_du_ddl;
                    t10(2) += 1.; // on s'en sert ici comme compteur
                    int num_noeud = noe.Num_noeud();
                    if (t10(3) < val_du_ddl)
                     { t10(3) = val_du_ddl;
                       tab_pour_MAXI_1 = num_noeud;
                     };
                    if (t10(4) > val_du_ddl)
                     { t10(4) = val_du_ddl;
                       tab_pour_MAXI_2 = num_noeud;
                     };
                    if (Dabs(t10(5)) < Dabs(val_du_ddl))
                     { t10(5) = val_du_ddl;
                       tab_pour_MAXI_3 = num_noeud;
                     };
                    if (Dabs(t10(6)) > Dabs(val_du_ddl))
                     { t10(6) = val_du_ddl;
                       tab_pour_MAXI_4 = num_noeud;
                     };
                   };
                // calcul de la moyenne
                t10(2) = t10(1) / t10(2);
                // cumule sur le temps
                Vecteur& t10_t = (gr_t.ConteneurVecteur());
                t10(1) += t10_t(1); t10(2) += t10_t(2);
                t10(3) += t10_t(3); t10(4) += t10_t(4);
                t10(5) += t10_t(5); t10(6) += t10_t(6);
               };
             // ensuite on cumule sur le temps
               
 ////------- debug ---------
 //cout << "\n debug statistique: ";
 //cout << t10;
 //
 //
 ////------- fin debug --------
               
            }
         else // cas d'un stockage pour fonction nD
            { Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) g_TG); // pour simplifier
              Fonction_nD* fct = gr.Fct(); // récupération de la fonction nD
              // supposons que la fonction nD ramène n valeurs,
              // pour chaque valeur on va avoir pour la valeur i :
              // ((6*(i-1)+1) la somme, ((6*(i-1)+2) la moyenne, ((6*(i-1)+3) le max, ((6*(i-1)+4) le min,
              // ((6*(i-1)+5) -> le numéro du noeud pour le max, ((6*(i-1)+6) -> le numéro du noeud pour le min,
              // donc en tout cela donne 6*n valeurs
              // ensuite on a:
              // (6*n + 1) le max des | |, (6*n + 2) le min des | |,
              // (6*n + 3) -> le numéro du noeud pour le max des | |
              // (6*n + 4) -> le numéro du noeud pour le min des | |
              // d'où un vecteur de taille (6*n + 4)

              // on commence par récupérer les conteneurs des grandeurs à fournir
              List_io <Ddl_enum_etendu>& li_enu_scal = fct->Li_enu_etendu_scalaire();
              List_io <TypeQuelconque >& li_quelc = fct->Li_equi_Quel_evolue();
              int nb_composante = fct->NbComposante();

              // t10(i), i=1 à 6 --> correspond aux 6 valeurs de statistique == tab_val(k)
              Vecteur& t6 = (gr.ConteneurVecteur());
              t6(4)=t6(6)=ConstMath::tresgrand; // on met les mini très grand

              // cumule des valeurs: on récupère les infos à partir des noeuds concernés
              for (int jj= 1; jj<= ref_Taille; jj++)
                {int nbb = ref->Numero(jj) ; // le numero du noeud dans le maillage
                 // récupération du Noeud
                 Noeud& noe =  Noeud_LesMaille(i_mail,nbb);
                 
                 // récupération d'une liste d'info
                 // le tableau de retour à la taille de li_enu_scal et contient
                 // les valeurs correspondantes aux Ddl_enum_etendu stockées au noeud
                 //    en fait ici on cumule les ddl pur "et" les ddl_étendue,
                 // li_quelc : est modifié par les valeurs contenues au noeud
                 Tableau <double> tab =  noe.Valeur_multi_et_Tensorielle(li_enu_scal,li_quelc);
                 // récup des valeurs de la fonction
                 Tableau <double> & t_ret = fct->Valeur_FnD_tab_scalaire(&tab);
                 int num_noeud = noe.Num_noeud();
                 // le calcul des grandeurs sur chaque composante
                 double norme=0;
                 for (int i=1;i<= nb_composante;i++)
                   { int decal = 6*(i-1);
                     double val_composante = t_ret(i);
                     t6(decal+1) += val_composante;
                     t6(decal+2) += 1.; // on s'en sert ici comme compteur
                     if (t6(decal+3) < val_composante)
                      { t6(decal+3) = val_composante;
                        t6(decal+5) = num_noeud;
                      };
                     if (t6(decal+4) > val_composante)
                      { t6(decal+4) = val_composante;
                        t6(decal+6) = num_noeud;
                      };
                     norme +=val_composante*val_composante;
                   };
                 // on traite la norme
                 int decal = 6*nb_composante;
                 norme = sqrt(norme);
                 if (t6(decal+1) < norme)
                  { t6(decal+1) = norme;
                    t6(decal+3) = num_noeud;
                  };
                 if (t6(decal+2) > norme)
                  { t6(decal+2) = norme;
                    t6(decal+4) = num_noeud;
                  };
                };
                
              // on calcule les moyennes et on cumule dans le temps
              // pour les composantes i
              Vecteur& t6_t = (gr_t.ConteneurVecteur());
              for (int i=1;i<= nb_composante;i++)
                { int decal = 6*(i-1);
                  t6(decal+2) = t6(decal+1)/t6(decal+2);
                  // le cumul dans le temps
                  t6(decal+1) += t6_t(decal+1);t6(decal+2) += t6_t(decal+2);
                  t6(decal+3) += t6_t(decal+3);t6(decal+4) += t6_t(decal+4);
                };
              // idem pour les normes
              int decal = 6*nb_composante;
              t6(decal+1) += t6_t(decal+1) ; t6(decal+2) += t6_t(decal+2);
            };

        // maintenant il s'agit d'alimenter les grandeurs globales

        // on récupère le pointeur correspondant à la grandeur correspondant au nom
        // de référence
        const string* nom_de_ref = g_TG->Nom_ref();
        #ifdef MISE_AU_POINT
        if (nom_de_ref == NULL)
           { cout << "\n *** pb dans le transfert d'une statistique cumulee !! "
                  << " nom_de_ref est nul, on ne peut pas continuer  "
                  << "\n LesMaillages::CalStatistique()"<<flush;
             Sortie(1);
           };
        #endif
        // récup du pointeur de conteneur
        const void* pointe =  (ParaGlob::param->GrandeurGlobal(*nom_de_ref));
        #ifdef MISE_AU_POINT
        if (pointe == NULL)
          { cout << "\n *** pb dans le transfert d'une statistique cumulee !! "
                 << " la variable globale  "<< (*nom_de_ref)
                 << ", n'est pas disponible, on ne peut pas continuer  "
                  << "\n LesMaillages::CalStatistique()"<<flush;
             Sortie(1);
          };
        #endif
        // on l'affecte
        TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
        *(gr_quelc->Grandeur_pointee()) = *(g_TG);

       };
    
    }; // fin de la boucle sur les ref
  };
   
};

  // mise à jour des repères d'anisotropie
void LesMaillages::Mise_a_jour_repere_anisotropie
       (DiversStockage* divers,LesFonctions_nD*  lesFonctionsnD)
 {  // l'idée est d'éviter de stocker les infos déjà présentes dans DiversStockage ...
    // on reprend le caneva de la méthode LesMaillages::Completer
    // par contre on considère que tous les dimensionnements sont corrects
    // cas de la définition de repère d'anisotropie
    int divers_TabRepAnisotrope_Taille=divers->TabRepAnisotrope().Taille();
    for (int ii=1;ii<= divers_TabRepAnisotrope_Taille;ii++)
     {  string nomRepAnisotrope = (divers->TabRepAnisotrope())(ii).NomRef(); // recup du nom de la ref
        const BlocDdlLim<BlocGen_6_0>& div_TabRepAnisotrope = (divers->TabRepAnisotrope())(ii);
        const Reference & refG = lesRef->Trouve(nomRepAnisotrope,div_TabRepAnisotrope.NomMaillage()); // recup de la reference
        const ReferenceNE & ref = (ReferenceNE &) refG;
        int ref_Taille=ref.Taille();
        // creation d'un bloc general contenant des informations
        // n= nombre de string, m nombre de double
        BlocGen bloc(5,0) ; // par defaut
        string nom_inter("repere_anisotropie_");
        bloc.Change_nom(1,nom_inter); // le mot clé
        // ensuite le type l'identificateur de repere
        bloc.Change_nom(2,div_TabRepAnisotrope.Nom(2));
        // ensuite le type de repere
        bloc.Change_nom(3,div_TabRepAnisotrope.Nom(3));
        // puis la méthode de définition du repère
        bloc.Change_nom(4,div_TabRepAnisotrope.Nom(4));
        // un string qui contient le nom de la fonction nD
        bloc.Change_nom(5,div_TabRepAnisotrope.Nom(6));
        // puis on alimente les éléments concernés par ces calculs
////--- debug
//cout << "\n -- debug LesMaillages::Completer( ";
//bloc.Affiche(); cout << endl;
////--- fin debug
        for (int jj= 1; jj<= ref_Taille; jj++)
            {int nbb = ref.Numero(jj) ; // le numero de l'element dans le maillage
             int nnn = ref.Nbmaille(); // le numero du maillage
             // recup de l'element
             Element * poi = & Element_LesMaille(nnn,nbb);
             // demande a l'element de se completer
             poi->Mise_a_jour_repere_anisotropie(bloc,lesFonctionsnD);
            };
     };

 
 };


    // initialisation par défaut de tous les conteneurs aux noeuds
    // de tous les maillages
    // contenant li_restreinte_TQ et li_restreinte_ddl
    // ces conteneurs sont supposés déjà existés
    // typiquement si le conteneurs est un scalaire, on met 0
void LesMaillages::Init_par_defaut_conteneurs(List_io < TypeQuelconque >& li_restreinte_TQ
                                              )
  {List_io < TypeQuelconque >::iterator il,ilfin=li_restreinte_TQ.end();
  
   for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
      for (int i2 = 1; i2 <= nbnoeudmax; i2++)
        { // recup du noeud
          Noeud * noo = & Noeud_LesMaille(i1,i2);
          // on parcours la liste
          for (il = li_restreinte_TQ.begin(); il != ilfin;il++)
            {TypeQuelconque_enum_etendu enuTypeQuelconque = (*il).EnuTypeQuelconque();
             TypeQuelconque& tyqN = noo->ModifGrandeur_quelconque(enuTypeQuelconque);
             tyqN.Grandeur_pointee()->InitParDefaut();
            };
         }
      }
   };

// idem pour une seule grandeur
void LesMaillages::Init_par_defaut_conteneurs(TypeQuelconque_enum_etendu enuTypeQuelconque)
  {for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
      for (int i2 = 1; i2 <= nbnoeudmax; i2++)
        { // recup du noeud
          Noeud * noo = & Noeud_LesMaille(i1,i2);
          TypeQuelconque& tyqN = noo->ModifGrandeur_quelconque(enuTypeQuelconque);
          tyqN.Grandeur_pointee()->InitParDefaut();

        };
    };
  };

  
  
  
  
  
  
  
  
 
