// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL  : gerardrio56@free.fr
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.

#include "LesMaillages.h"
#include "ElemMeca.h"
#include "ReferenceNE.h"
#include "ReferenceAF.h"
#include "MathUtil.h"
#include "ConstMath.h"
#include "LaLIST.H"
#include "CharUtil.h"
#include "TypeQuelconqueParticulier.h"

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


// Constructeur
    // constructeur par défaut
LesMaillages::LesMaillages():
  tabMaillage(0),listFrontiere(),t_i_n(0)
  ,tab_nb_assemb(0),tt_noeud_front(),tous_indices()
  ,nbEnreg(0),nbMaillageTotal(0),nbPortion(0),entreePrinc(NULL),paraGlob(NULL)
  ,lesRef(NULL),domEsclave(0),mapNomMail()
  ,ddl_representatifs_des_physiques(),types_de_problemes()
  ,integ_vol_typeQuel(),integ_vol_typeQuel_t(),ref_integ_vol()
  ,integ_vol_t_typeQuel(),integ_vol_t_typeQuel_t(),ref_integ_vol_t()
  ,statistique_typeQuel(),statistique_typeQuel_t(),ref_statistique()
  ,pour_statistique_de_ddl()
  ,statistique_t_typeQuel(),statistique_t_typeQuel_t(),ref_statistique_t()
  ,pour_statistique_t_de_ddl()
#ifdef UTILISATION_MPI
  ,temps_transfert_long(),v_integ(),temps_serialisation()
  // pour les i/o
  ,buffer_ioBI_MPI(),tailles_buffer_ioBI_MPI(),offset_maillage()
#endif

    { cout << "\n erreur: ce constructeur ne doit pas etre utilise !!"
           << "\n LesMaillages::LesMaillages()";
      Sortie(1);     
     };   

LesMaillages::LesMaillages(UtilLecture * ent,ParaGlob * para,LesReferences* Ref) :
/*  nbEnreg(para->NombreMaillage()),  // Nombre initial de maillage est determine
  // dans les parametres globaux
  tabMaillage(nbEnreg) // def du tableau de maillage */
  tabMaillage(5),listFrontiere(),t_i_n()
  ,tab_nb_assemb(0),tt_noeud_front(),tous_indices()
  ,mapNomMail()
  ,ddl_representatifs_des_physiques(),types_de_problemes()
  ,integ_vol_typeQuel(),integ_vol_typeQuel_t(),ref_integ_vol()
  ,integ_vol_t_typeQuel(),integ_vol_t_typeQuel_t(),ref_integ_vol_t()
  ,statistique_typeQuel(),statistique_typeQuel_t(),ref_statistique()
  ,pour_statistique_de_ddl()
  ,statistique_t_typeQuel(),statistique_t_typeQuel_t(),ref_statistique_t()
  ,pour_statistique_t_de_ddl()
#ifdef UTILISATION_MPI
  ,temps_transfert_long(),v_integ(),temps_serialisation()
  // pour les i/o
  ,buffer_ioBI_MPI(),tailles_buffer_ioBI_MPI(),offset_maillage()
#endif
  {    lesRef = Ref;
       // mise à jour de la map qui fait la liaison nom de maillage <=> numéro de maillage
       lesRef->MiseAJourMap(mapNomMail);
       entreePrinc = ent;
       nbEnreg = 5;
       nbMaillageTotal = 0 ;  // pour l'instant pas de maillage
       nbPortion = nbEnreg ;
       paraGlob = para;
       domEsclave = 0; // a priori pas de maillage esclave           
  };
  
//constructeur de copie
LesMaillages::LesMaillages(const LesMaillages& a)
    { cout << "\n erreur: pour l'instant ce constructeur ne doit pas etre utilise !!"
           << "\n LesMaillages::LesMaillages(const LesMaillages& a)";
      Sortie(1);     
     };   
  
  
// Destructeur  
LesMaillages::~LesMaillages()
  { int tabMaillage_Taille=tabMaillage.Taille();
    if (tabMaillage_Taille>=1)
     for (int i=1;i<= tabMaillage_Taille;i++)
      {if (tabMaillage(i)!=NULL)
       {delete  tabMaillage(i);tabMaillage(i)=NULL;}
      };
  };
  
// METHODES PUBLIQUES :
// lecture des maillages et des references s'y rapportant
void LesMaillages::LectureLesMaillages()   
 { if (ParaGlob::NiveauImpression() >= 4)
     cout << " debut de la lecture des maillages " << endl;
   // --- rechercher d'un premier maillage maillage
   int lectureEnCour = 0;
   // lecture du premier maillage obligatoire
   if ((strstr(entreePrinc->tablcar,"noeuds")!=NULL) ||
        (strstr(entreePrinc->tablcar,"nom_maillage")!=NULL))
     { if (ParaGlob::NiveauImpression() >= 5)
          cout << " lecture du premier maillage " << endl;
       tabMaillage(1) = new Maillage (mapNomMail,1,paraGlob->Dimension());
       // indique que les prochaines references seront pour le maillage 1
       lesRef->NbMaille(1); 
       tabMaillage(1)->LectureMaillage(entreePrinc,*lesRef);
       // opération d'affinage
       tabMaillage(1)->LectureEtApplicationAffinage(entreePrinc,*lesRef);
       // init du nombre de maillage
       nbMaillageTotal = 1 ;
/*////------- debug
//cout << "\n debug1 LesMaillages::LectureLesMaillages ";
//{
//    map < string, int , std::less <string> >::iterator id1, idfin=mapNomMail.end();
//    for (id1=mapNomMail.begin();id1!=idfin;id1++)
//      cout << "\n "<<(*id1).first << " , " << (*id1).second ;
//    cout << endl;
////     mapNomMail;
// 
//};*/
     }
   else
     { cout << " *** erreur dans la lecture du premier maillage " << '\n';
       cout << " un premier maillage est obligatoire !!! " << '\n';
       Sortie(1);
     };
   // --- recherche s'il y a d'autres maillages
	  // tout d'abord on passe le numéro de version si besoin est:
	  if (strstr(entreePrinc->tablcar,"version:")!=NULL)
	     entreePrinc->NouvelleDonnee();
   if ((strstr(entreePrinc->tablcar,"noeuds")!=NULL) ||
         (strstr(entreePrinc->tablcar,"nom_maillage")!=NULL)) 
      do { nbMaillageTotal++;
          #ifdef ETUDIANT_LIMITATION
           if (nbMaillageTotal > nb_maxi_maillage)
            { cout << "\n nombre maxi de maillage autorisé atteind " << nb_maxi_maillage;
              Sortie(1);
             }
          #endif       
           if (nbMaillageTotal > nbPortion) // il faut agrandir le tableau de maillage
             { nbPortion = nbPortion+nbEnreg; 
               tabMaillage.Change_taille(nbPortion);
             };
           tabMaillage(nbMaillageTotal) = new Maillage (mapNomMail,nbMaillageTotal,paraGlob->Dimension());
           // indique le nb de maillage pour l'enregistrement des prochaines references 
           lesRef->NbMaille(nbMaillageTotal); 
           //lect des autres MAILlages
           if (ParaGlob::NiveauImpression() >= 5)
              cout << " lecture du maillage nb: " << nbMaillageTotal << endl;
           tabMaillage(nbMaillageTotal)->LectureMaillage(entreePrinc,*lesRef);
/*////------- debug
//cout << "\n debug2 LesMaillages::LectureLesMaillages ";
//{
//    map < string, int , std::less <string> >::iterator id1, idfin=mapNomMail.end();
//    for (id1=mapNomMail.begin();id1!=idfin;id1++)
//      cout << "\n "<<(*id1).first << " , " << (*id1).second ;
//    cout << endl;
////     mapNomMail;
// 
//};*/
           // on demande au maillage de lire éventuellement des rotation, collapse etc.
           // --> opération d'affinage, juste pour ce maillage
           tabMaillage(nbMaillageTotal)->LectureEtApplicationAffinage(entreePrinc,*lesRef);
           // maintenant on regarde si l'on veut une fusion avec le maillage précédent
           if (strstr(entreePrinc->tablcar,"fusion_avec_le_maillage_precedent_")!=NULL)
            {// si oui on appel la méthode de fusion pour le maillage précédent
             List_io < string > nom_mails_a_fusionner; // on crée une liste qui sert pour l'appel général
             nom_mails_a_fusionner.push_back(tabMaillage(nbMaillageTotal)->NomDuMaillage());
             int nbMaillageTotal_save = nbMaillageTotal;
             Fusion_maillages(nom_mails_a_fusionner,tabMaillage(nbMaillageTotal-1)->NomDuMaillage(),lesRef);
             // on vérifie qu'il n'y a pas eu de nouveau maillage créé durant la fusion
             if (nbMaillageTotal != nbMaillageTotal_save)
               { cout << "\n erreur, il y a eu un nouveau maillage cree, ce n'est pas normal, la suite est impossible "
                      << "\n LesMaillages::LectureLesMaillages() " << endl ;
                 Sortie(1);
               };
////------- debug
//cout << "\n debug LesMaillages::LectureLesMaillages : avant le delete";
//lesRef->Affiche(2,0);
////----- fin debug
//{
//    map < string, int , std::less <string> >::iterator id1, idfin=mapNomMail.end();
//    for (id1=mapNomMail.begin();id1!=idfin;id1++)
//      cout << "\n "<<(*id1).first << " , " << (*id1).second ;
//    cout << endl;
////     mapNomMail;
// 
//};
             // maintenant on va supprimer le maillage que l'on vient de lire
             Suppression_maillage(tabMaillage(nbMaillageTotal)->NomDuMaillage());
////------- debug
//cout << "\n debug LesMaillages::LectureLesMaillages : après le delete ";
//lesRef->Affiche(2,0);
//{
//    map < string, int , std::less <string> >::iterator id1, idfin=mapNomMail.end();
//    for (id1=mapNomMail.begin();id1!=idfin;id1++)
//      cout << "\n "<<(*id1).first << " , " << (*id1).second ;
//    cout << endl;
////     mapNomMail;
// 
//};
	            entreePrinc->NouvelleDonnee(); // on prépare la nouvelle lecture
             // après la fusion, on peut encore avoir de l'affinage
             // on demande au maillage de lire éventuellement des rotation, collapse etc.
             // --> opération d'affinage
             tabMaillage(nbMaillageTotal)->LectureEtApplicationAffinage(entreePrinc,*lesRef);
            };
/*////------- debug
//cout << "\n debug LesMaillages::LectureLesMaillages après LectureEtApplicationAffinage ";
//{
//    map < string, int , std::less <string> >::iterator id1, idfin=mapNomMail.end();
//    for (id1=mapNomMail.begin();id1!=idfin;id1++)
//      cout << "\n "<<(*id1).first << " , " << (*id1).second ;
//    cout << endl;
////     mapNomMail;
// 
//};*/
       
           if ((strstr(entreePrinc->tablcar,"noeuds")!=NULL) ||
             (strstr(entreePrinc->tablcar,"nom_maillage")!=NULL)) {lectureEnCour = 1;}
           else                                                   {lectureEnCour = 0;};
         } while (lectureEnCour == 1);
     // fin de la lecture des maillages les uns après les autres
//---- essai d'une renumérotation globale
	  //--- on regarde si l'on demande une renumérotation globale de tous les maillages
	  //   n'est actif que s'il y a plusieurs maillages, 
   if (strstr(entreePrinc->tablcar,"renumerotation_tous_maillages_")!=NULL)
//     if (nbMaillageTotal != 1)
       { if (ParaGlob::NiveauImpression() >= 5)
              cout << " renumerotation globale de tous les noeuds de tous les maillages "  << endl;				  
         // on définit un tableau vide de conditions linéaires (ne sert pas ici)
         Tableau <Tableau <Condilineaire> >  condCLL;
         // appel de l'utilitaire dans lesMaillages avec les conditions linéaire éventuelles
         TroisEntiers  nouvelles_largeur_en_ddl;
         this->Renumerotation(*lesRef,condCLL,nouvelles_largeur_en_ddl);
         entreePrinc->NouvelleDonnee(); // positionnement sur une nouvelle info
       };
//     else
//      { if (ParaGlob::NiveauImpression() >= 5)
//              cout << " il n'y a qu'un seul maillage, doncrenumerotation globale de tous les noeuds de tous les maillages "  << endl;				  
//
  
     
	  
   // --- on examine le cas où il y a une distinction domaine esclave/ou non 
//      if ((strstr(entreePrinc->tablcar,"domaine_esclave")!=NULL) && (nbMaillageTotal != 1))
   if (strstr(entreePrinc->tablcar,"domaine_esclave")!=NULL) 
       // cas ou l'on a des domaines esclaves, lecture du nombre
       { entreePrinc->NouvelleDonnee(); 
         if (ParaGlob::NiveauImpression() >= 5)
              cout << " lecture du nombre de domaines esclaves "  << endl;
         *(entreePrinc->entree) >> domEsclave; // lecture du nombre
         if (ParaGlob::NiveauImpression() >= 5) cout << domEsclave  << endl;
         if ((domEsclave <1) || (domEsclave > nbMaillageTotal))
          // domEsclave doit etre > 0 et < nbMaillageTotal, s'il = nbMaillageTotal
          // on n'a aucun maillage maitre -> pb, sauf s'il y a de l'auto contact, c'est géré par le contact
          { cout << "\n le nombre de maillage esclave lu : " << domEsclave
                 << ", n\'est pas acceptable, (nbMaillageTotal = " << nbMaillageTotal << " )"
                 << endl;
            entreePrinc->MessageBuffer("** lecture des domaines esclaves **");
            throw (UtilLecture::ErrNouvelleDonnee(-1));
            Sortie(1);
           };
         entreePrinc->NouvelleDonnee(); // positionnement sur une nouvelle info
       };
//		 // --- vérification obsolète mais que l'on conserve pour l'instant 
//   if ((paraGlob->TypeCalcul() == NON_DYNA_CONT) && (domEsclave < 1))
//       { cout << "\n erreur, le type de calcul : NON_DYNA_CONT necessite d\'avoir plusieurs"
//              << " maillages et de savoir le nombre de domaine esclave !! "
//              << "\n LesMaillages::LectureLesMaillages() " << endl;
//         entreePrinc->MessageBuffer("** lecture des domaines esclaves **");
//         throw (UtilLecture::ErrNouvelleDonnee(-1));
//         Sortie(1);     
//       };      
   // --- on vérifie que les références sont correctes
   const Reference*  refG = lesRef->Init_et_Premiere();
   while (refG != NULL)
     { // on définit la référence réelle
       // et on voit s'il n'y a pas d'erreur lorsque l'on essaie d'utiliser la référence
       // 1- cas des noeuds
       if ( refG->Indic() == 1)
         { const ReferenceNE & ref = (ReferenceNE &) (*refG);   
           int ref_Taille=ref.Taille();
            for (int j= 1; j<= ref_Taille; j++)
             {int nb = ref.Numero(j) ; // le numero du dans le maillage
              int nn = ref.Nbmaille(); // le numero du maillage
              // on tente de récupérer le noeud, ce qui permet de vérifier son existence
              try {Noeud& toto = Noeud_LesMaille(nn,nb);}
              // si le noeud n'existe pas il y a une erreur qui est récupérer
              catch (ErrSortie erreur)
               { // cas d'un noeud n'existant pas
                 cout << "\n erreur dans la verification de la liste : " ;
                 ref.Affiche();
                 cout << "\n peut-etre que le noeud nb : " << nb << " du maillage : " << nn 
                      << " n'existe pas ? " << endl;
                 Sortie(-1); // on force la sortie
               };
             };
         };
       // 2- cas des éléments
       if ( refG->Indic() == 2)
         { const ReferenceNE & ref = (ReferenceNE &) (*refG);   
           int ref_Taille=ref.Taille();
            for (int j= 1; j<= ref_Taille; j++)
             {int nb = ref.Numero(j) ; // le numero de l'element dans le maillage
              int nn = ref.Nbmaille(); // le numero du maillage
              // on tente de récupérer l'élément, ce qui permet de vérifier son existence
              try {Element& toto = Element_LesMaille(nn,nb);}
              // si l'élément n'existe pas il y a une erreur qui est récupérer
              catch (ErrSortie erreur)
               { // cas d'un élément n'existant pas
                 cout << "\n erreur dans la verification de la liste : " ;
                 ref.Affiche();
                 cout << "\n peut-etre que l'element nb : " << nb << " du maillage : " << nn 
                      << " n'existe pas ? " << endl;
                 Sortie(-1); // on force la sortie
               };
             };
         };
       // 3- cas des faces ou des arrêtes
       if (( refG->Indic() == 3) || ( refG->Indic() == 4))
         { const ReferenceAF & ref = (ReferenceAF &) (*refG);   
           int ref_Taille=ref.Taille();
            for (int j= 1; j<= ref_Taille; j++)
             {int nb = ref.NumeroElem(j) ; // le numero de l'element dans le maillage
              int nn = ref.Nbmaille(); // le numero du maillage
              // on tente de récupérer l'élément, ce qui permet de vérifier son existence
              try {Element& toto = Element_LesMaille(nn,nb);}
              // si l'élément n'existe pas il y a une erreur qui est récupérer
              catch (ErrSortie erreur)
               { // cas d'un élément n'existant pas
                 cout << "\n erreur dans la verification de la liste : " ;
                 ref.Affiche();
                 cout << "\n peut-etre que l'element nb : " << nb << " du maillage : " << nn 
                      << " n'existe pas ? " << endl;
                 Sortie(-1); // on force la sortie
               };
             };
         };
     
       refG = lesRef->Reference_suivante();
     };
   // on s'occupe de mettre à jour les types de pb et les ddl types associés
   Mise_a_jour_type_pb_type_associe_ddl();
   
#ifdef UTILISATION_MPI
   // pour les i/o retardées on va dimensionner les buffer
   buffer_ioBI_MPI.Change_taille(nbMaillageTotal);
   for (int i=1;i<=nbMaillageTotal;i++)
     {
     
     }
   
   
   
   
//   int taille_mail = buffer_io_MPI(i).Taille();
//   Tableau < char * > & buffer_io_MPI_i = buffer_io_MPI(i); // pour simplifier
//   for (int j=1;j<=taille_mail;j++)
//     if (buffer_io_MPI_i(j) != NULL)
//       {delete buffer_io_MPI_i(j);
//        buffer_io_MPI_i(j) = NULL;
//       };
#endif

  
  if (ParaGlob::NiveauImpression() >= 4)
     cout << " fin de la lecture des maillages " << endl; 
 };
 
// affichage et definition interactive des commandes 
void LesMaillages::Info_commande_lesMaillages()
 {  // def des maillages
//    int lectureEnCour = 0;
    // def d'un premier maillage 
    tabMaillage(1) = new Maillage (mapNomMail,1,paraGlob->Dimension());
    cout << "\n# ----- definition des maillages ----- ";  
    cout << "\n# def des fichiers de maillage  ";
	   string rep="_";

	   if (rep != "f")
      {ofstream & sort = *(entreePrinc->Commande_pointInfo()); // pour simplifier
	      sort << "\n#--------------------------------------"
            << "\n#| definition du (ou des) maillage(s) |"
            << "\n#--------------------------------------";
       cout << "\n dans le fichier de commande final, on utilisera de preference une inclusion "
                << "\n d'un fichier qui contiendra le maillage (ou plusieurs fichiers pour plusieurs maillages\n";

       while ((Minuscules(rep) != "f")&&(Minuscules(rep) != "0"))
       {
       try 
        { cout
               << "\n (0 ou f)  (fin)               "
               << "\n (1) (defaut) inclusion de fichier et affinage    "
               << "\n (2)  fusion des deux precedents maillages "
//               << "\n (3)  renumerotation de tous les maillages "
//               << "\n (4 ou ? ) exemple - informations sur fichier ! "
               << "\n (3 ou ? ) exemple - informations sur fichier ! "
               << "\n  ";
          if (rep != "f")
             rep = lect_return_defaut(false,"1");

          if ((Minuscules(rep) == "f") || (Minuscules(rep) == "0"))// sortie directe
            break;
          int num = ChangeEntier(rep);
          if (Minuscules(rep) == "?")
            num = 3; //4;
          bool choix_valide=false;
          if ((num >= 0)&&(num<=3))
             { choix_valide=true; }
          else { cout << "\n Erreur on attendait un entier entre 0 et 3 !!, "
                      << "\n redonnez une bonne valeur"
                      << "\n ou taper f ou 0 pour arreter le programme"; 
                 choix_valide=false;
               }
          switch (num)
           { case 0:  // sortie
               { break;} // normalement cela a déjà été filtré avant
             case 1:  // inclusion de fichier et affinage
	              { string repi;
                 while (Minuscules(repi) != "f")
                  {// indique que les prochaines references seront pour le maillage 1, systématiquement 
                   lesRef->NbMaille(1); int cas = 1;
                   tabMaillage(1)->Info_commande_Maillages(entreePrinc,*lesRef, cas);
                   nbMaillageTotal = 1 ;
		                 cout << "\n autre fichier ou fin (rep o ou f) ";
                   repi = lect_return_defaut(false,"f");
			               };
                sort << "\n \n ";
                break;
               }		
             case 2:  // fusion des deux precedents maillages
               { sort << "\n fusion_avec_le_maillage_precedent_ ";
                 int cas = 3; // on rappelle l'affinage en fin de maillage
                 tabMaillage(1)->Info_commande_Maillages(entreePrinc,*lesRef, cas);
                 break;}
//             case 3:  // renumerotation de tous les maillages
//             { sort << "\n renumerotation_tous_maillages_ ";
//               break;}
             case 3:  // exemple - informations sur fichier
	              { cout << "\n on se reportera a la documentation pour une information precise "
                      << " ici il y a sortie sur le fichier .info d'exemple et d'infos succintes ";
 	               sort << "\n# exemples: tout d'abord l'inclusion, "
	                     << "\n# 2 solutions equivalentes : soit deux fichiers par maillage -> exemple"
	                     << "\n# < nom_de_maillage.her # fichier qui contiend le maillage"
	                     << "\n# < nom_de_maillage.lis # fichier qui contiend les references "
	                     << "\n#                            soit un seul fichier par maillage -> exemple"
	                     << "\n# < nom_de_maillage.her # fichier qui contiend le maillage"
	                     << "\n \n# maintenant on presente un exemple de contenu de mailage correspondant aux choix propose"
	                     << "\n#------------------------------ exemple de contenu maillage -----------------";
	                // indique que les prochaines references seront pour le maillage 1
	                lesRef->NbMaille(1);int cas = 2;
	                tabMaillage(1)->Info_commande_Maillages(entreePrinc,*lesRef, cas);
	                nbMaillageTotal = 1 ;

                 sort << "\n#-------------------------- fin  exemple de contenu maillage -----------------\n \n ";
                 break;
	              };
             default:
               cout << "\n le cas "<<rep<<" n'est pas  traite !!, bizarre, il faut se plaindre !! ";
           };
        }
       catch (ErrSortieFinale)
            // cas d'une direction voulue vers la sortie
            // on relance l'interuption pour le niveau supérieur
          { ErrSortieFinale toto;
            throw (toto);
          }
       catch (...)//(UtilLecture::ErrNouvelleDonnee erreur)
        {  cout << "\n Erreur on attendait un des mots cles proposes !!, "
                << "\n redonnez une bonne valeur"
                << "\n ou taper f ou 0 pour sortir "; 
        };
       }; //-- fin du while
       // --- domaines esclaves éventuelles
       cout << "\n def d'un nombre de domaine(s) esclave(s) rep: o ou n (defaut) ? ";
       rep = lect_return_defaut(false,"n");
       if (Minuscules(rep) == "o")
         {int nb=0;
          cout << "\n nombre ? (un entier) ";
          nb= (int) lect_double();
          sort << "\n\n  domaine_esclave "
               << "\n#--------------------------------------------------------------------"
               << "\n#  definition du nombre de domaine esclave             |"
               << "\n#--------------------------------------------------------------------\n"
               << nb << " ";
         };
       sort << flush;
      };
  
 };
  
 // affiche sur la sortie standard les differents maillage
void LesMaillages::Affiche () const 
 { cout << '\n'<< '\n'
   << " --------- CAS des maillages ---------" << '\n' << '\n';  // en tete
   cout << '\n'<< "il y a " << nbMaillageTotal << " maillages " << '\n' ;
   for (int i = 1; i<= nbMaillageTotal; i++)
    {  cout << " *** maillage numero = " << i << '\n';
       (tabMaillage(i))->Affiche();
       // pas d'affichage des types de calcul car c'est déjà dans chaque maillage
    } 
   // ----- cas des grandeurs intégrés éventuelles-----
   cout << "\n\n int_vol_mail ";
   int integ_vol_typeQuel_taille = integ_vol_typeQuel.Taille();
   if (integ_vol_typeQuel_taille == 0) cout << 0; else cout << integ_vol_typeQuel_taille;
   cout << " ";
   for (int i=1;i<= integ_vol_typeQuel_taille;i++)
     cout << "\n" << integ_vol_typeQuel_t(i) ;
  
   cout << "\n int_vol_temps_mail ";
   int integ_vol_t_typeQuel_taille = integ_vol_t_typeQuel.Taille();
   if (integ_vol_t_typeQuel_taille == 0) cout << 0; else  cout <<integ_vol_t_typeQuel_taille;
   cout << " ";
   for (int i=1;i<= integ_vol_t_typeQuel_taille;i++)
     cout << "\n" << integ_vol_t_typeQuel_t(i);
     
   // ----- cas des statistiques éventuelles-----
   cout << "\n\n statistique_mail ";
   int statistique_typeQuel_taille = statistique_typeQuel.Taille();
   if (statistique_typeQuel_taille == 0) cout << 0; else cout << statistique_typeQuel_taille;
   cout << " ";
   for (int i=1;i<= statistique_typeQuel_taille;i++)
     cout << "\n" << statistique_typeQuel_t(i) ;
  
   cout << "\n statistique_temps_mail ";
   int statistique_t_typeQuel_taille = statistique_t_typeQuel.Taille();
   if (statistique_t_typeQuel_taille == 0) cout << 0; else  cout <<statistique_t_typeQuel_taille;
   cout << " ";
   for (int i=1;i<= statistique_t_typeQuel_taille;i++)
     cout << "\n" << statistique_t_typeQuel_t(i);

   cout << '\n' << "-------- fin des maillages ------" << '\n';
  };
 
 // Affiche les donnees du maillage dans le fichier de nom nom_fichier
 // au format du fichier ".her"
void LesMaillages::Affiche (char* ) const 
{  }; 

// test si toutes les informations des maillages sont completes
// = true -> complet
// = false -> incomplet
bool LesMaillages::Complet()
  { bool res = true;
    for ( int i=1; i<= nbMaillageTotal;i++)
      res = res &&  tabMaillage(i)->Complet();
    return res;
  };    
      
// introduction des lois de comportement dans les elements qui le necessite
//    des sections pour les poutres etc c-a-d , completer les elements
// avec les donnees qui ont ete acquises apres la lecture du maillage
// def des tableaux de ddl dans les noeuds
// def des pointeurs d'assemblage dans les noeuds
void LesMaillages::Completer(DiversStockage* divers,LesLoisDeComp* lesLois
                             ,LesFonctions_nD*  lesFonctionsnD )
  { 
    // cas des dilatations thermiques
    int divers_TabDila_Taille=divers->TabCoefDila().Taille();
    for (int ii=1;ii<= divers_TabDila_Taille;ii++)
     {  string nomDila = (divers->TabCoefDila())(ii).NomRef(); // recup du nom de la ref
        const BlocDdlLim<BlocScal_ou_fctnD>& div_Dila = (divers->TabCoefDila())(ii);
        // soit c'est une valeur fixe soit une fonction nD
        double val = 0; // init par défaut
        string nom_fct_nD("_"); // ""
        if (div_Dila.Val() != NULL) // cas d'une valeur fixe
          { val = *(div_Dila.Val());} // recup de la valeur
        else if (div_Dila.Fct_nD() != NULL) // cas d'une fonction nD
          { nom_fct_nD = *(div_Dila.Fct_nD());}
        else // sinon il y a un pb
          { cout << "\n *** erreur de definition de la dilatation les infos lues ne sont pas correctes: ";
            div_Dila.Affiche();
            Sortie(1);
          };
        const Reference & refG = lesRef->Trouve(nomDila,div_Dila.NomMaillage()); // recup de la reference
        // vérif que la référence s'adresse à des éléments
        if ( refG.Indic() != 2)
          { // erreur la référence ne concerne pas des éléments
            cout << "\n erreur la reference " << refG.Nom() << " ne concerne pas des elements ";
            cout << " \n cas des donnees relatives aux masses volumiques ";
            cout << "\n LesMaillages::Completer( .... ";
            Sortie(1);
           };
        const ReferenceNE & ref = (ReferenceNE &) refG;   
        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);
             // creation d'un bloc general contenant des informations
             BlocGen bloc(2,1);
             bloc.Change_nom(1,"dilatation_thermique");
             bloc.Change_nom(2,nom_fct_nD); // s'il contient "_" cela veut dire : pas de fctnD
             bloc.Change_val(1, val);
             // demande a l'element de se completer
             poi = poi->Complete(bloc,lesFonctionsnD);
             if (poi == NULL)
               { // cas d'un probleme 
                 cout << "\n erreur la dilatation thermique n'est pas adapte a l\'element ";
                 poi = & Element_LesMaille(nnn,nbb);
                 cout << "\n element " << poi->Geometrie() << poi->Interpolation();
                 cout << "\n LesMaillages::Completer( etc ... " << endl;
                 Sortie(1);
               };
            } 
      };  
  
    // cas des lois de comportement
    int lesLois_TabRefLoi_Taille = lesLois->TabRefLoi().Taille();
    for (int i=1;i<= lesLois_TabRefLoi_Taille;i++)
      { string nomLoi = (lesLois->TabRefLoi())(i).st2;
        // recup de la reference
        const LesLoisDeComp::RefLoi & refloi = (lesLois->TabRefLoi())(i); // ref de loi        
        const Reference& refG = lesRef->Trouve(refloi.st1,(refloi.nom_maillage));
        // vérif que la référence s'adresse à des éléments
        if ( refG.Indic() != 2)
          { // erreur la référence ne concerne pas des éléments
            cout << "\n erreur la reference " << refG.Nom() << " ne concerne pas des elements ";
            cout << " \n cas des donnees relatives aux lois de comportement ";
            cout << "\n LesMaillages::Completer( .... ";
            Sortie(1);
           };
        const ReferenceNE & ref = (ReferenceNE &) refG;   
        int ref_Taille=ref.Taille();
        for (int j= 1; j<= ref_Taille; j++)
            {int nb = ref.Numero(j) ; // le numero de l'element dans le maillage
             int nn = ref.Nbmaille(); // le numero du maillage
             // le pointeur le loi
             LoiAbstraiteGeneral * pt = lesLois->PtLoi_abstraite(nomLoi);
             if (pt == NULL)
             	{ // cas d'un pointeur en retour null, la loi n'existe pas
             	  cout << "\n *** erreur en lecture: la loi de nom : " << nomLoi
             	       << " n'existe pas !! revoyez vos donnees ";
                  if (ParaGlob::NiveauImpression() > 5)
                       cout << "\n LesMaillages::Completer( ... ";     
             	  Sortie(1);     
             	}
             // attribution du pointeur
             Element_LesMaille(nn,nb).DefLoi(pt);
           } 
       }
    // cas des sections d' elements
    int divers_TabSect_Taille=divers->TabSect().Taille();
    for (int ii=1;ii<= divers_TabSect_Taille;ii++)
     {  //string nomSect = (divers->TabSect())(ii).nomref; // recup du nom de la ref
        string nomSect = (divers->TabSect())(ii).NomRef(); // recup du nom de la ref
        //double val = (divers->TabSect())(ii).val; // recup de la valeur
        const BlocDdlLim<BlocScal_ou_fctnD>& div_sect = (divers->TabSect())(ii);
        // soit c'est une valeur fixe soit une fonction nD
        double val = 0; // init par défaut
        string nom_fct_nD("_"); // ""
        if (div_sect.Val() != NULL) // cas d'une valeur fixe
          { val = *(div_sect.Val());} // recup de la valeur
        else if (div_sect.Fct_nD() != NULL) // cas d'une fonction nD
          { nom_fct_nD = *(div_sect.Fct_nD());}
        else // sinon il y a un pb
          { cout << "\n *** erreur de definition de la section les infos lues ne sont pas correctes: ";
            div_sect.Affiche();
            Sortie(1);
          };
        const Reference & refG = lesRef->Trouve(nomSect,div_sect.NomMaillage()); // recup de la reference
        // vérif que la référence s'adresse à des éléments
        if ( refG.Indic() != 2)
          { // erreur la référence ne concerne pas des éléments
            cout << "\n erreur la reference " << refG.Nom() << " ne concerne pas des elements ";
            cout << " \n cas des donnees relatives aux sections ";
            cout << "\n LesMaillages::Completer( .... ";
            Sortie(1);
           };
        const ReferenceNE & ref = (ReferenceNE &) refG;   
        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);
             // creation d'un bloc general contenant des informations
             BlocGen bloc(2,1);
             bloc.Change_nom(1,"sections");
             bloc.Change_nom(2,nom_fct_nD); // s'il contient "_" cela veut dire : pas de fctnD
             bloc.Change_val(1, val);
             // demande a l'element de se completer
             poi = poi->Complete(bloc,lesFonctionsnD);
             if (poi == NULL)
               { // cas d'un probleme 
                 cout << "\n erreur la section n'est pas adapte a l\'element ";
                 poi = & Element_LesMaille(nnn,nbb);
                 cout << "\n element " << poi->Geometrie() << poi->Interpolation();
                 cout << "\n LesMaillages::Completer( etc ... " << endl;
                 Sortie(1);
               };
            } 
      }
   
    // cas des variation de section d' elements
    int divers_TabVarSect_Taille=divers->TabVarSect().Taille();
    for (int ii=1;ii<= divers_TabVarSect_Taille;ii++)
     {  string nomVarSect = (divers->TabVarSect())(ii).NomRef(); // recup du nom de la ref
        const BlocDdlLim<BlocScal>& div_varsect = (divers->TabVarSect())(ii);
        double val = div_varsect.Val(); // recup de la valeur
        const Reference & refG = lesRef->Trouve(nomVarSect,div_varsect.NomMaillage()); // recup de la reference
        // vérif que la référence s'adresse à des éléments
        if ( refG.Indic() != 2)
          { // erreur la référence ne concerne pas des éléments
            cout << "\n erreur la reference " << refG.Nom() << " ne concerne pas des elements ";
            cout << " \n cas des donnees relatives aux variations de sections ";
            cout << "\n LesMaillages::Completer( .... ";
            Sortie(1);
           };
        const ReferenceNE & ref = (ReferenceNE &) refG;   
        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);
             // creation d'un bloc general contenant des informations
             BlocGen bloc(1,1);
             bloc.Change_nom(1,"variation_section");
             bloc.Change_val(1, val);
             // demande a l'element de se completer
             poi = poi->Complete(bloc,lesFonctionsnD);
             if (poi == NULL)
               { // cas d'un probleme 
                 cout << "\n erreur la variation de section n'est pas adapte a l\'element ";
                 poi = & Element_LesMaille(nnn,nbb);
                 cout << "\n element " << poi->Geometrie() <<" "<< poi->Interpolation()<<" "<<poi->TypeProblem();
                 cout << "\n LesMaillages::Completer( etc ... " << endl;
                 Sortie(1);
                }                        
            } 
      };
   
    // cas des epaisseurs d' elements
    int divers_TabEpaiss_Taille=divers->TabEpaiss().Taille();
    for (int ii=1;ii<= divers_TabEpaiss_Taille;ii++)
     {  string nomSect = (divers->TabEpaiss())(ii).NomRef(); // recup du nom de la ref
        const BlocDdlLim<BlocScal_ou_fctnD>& div_epai = (divers->TabEpaiss())(ii);
        // soit c'est une valeur fixe soit une fonction nD
        double val = 0; // init par défaut
        string nom_fct_nD("_"); // ""
        if (div_epai.Val() != NULL) // cas d'une valeur fixe
          { val = *(div_epai.Val());} // recup de la valeur
        else if (div_epai.Fct_nD() != NULL) // cas d'une fonction nD
          { nom_fct_nD = *(div_epai.Fct_nD());}
        else // sinon il y a un pb
          { cout << "\n *** erreur de definition de l'epaisseur les infos lues ne sont pas correctes: ";
            div_epai.Affiche();
            Sortie(1);
          };

        const Reference& refG = lesRef->Trouve(nomSect,div_epai.NomMaillage()); // recup de la reference
        // vérif que la référence s'adresse à des éléments
        if ( refG.Indic() != 2)
          { // erreur la référence ne concerne pas des éléments
            cout << "\n erreur la référence " << refG.Nom() << " ne concerne pas des éléments ";
            cout << " \n cas des données relatives aux épaisseurs d'éléments ";
            cout << "\n LesMaillages::Completer( .... ";
            Sortie(1);
           };
        const ReferenceNE & ref = (ReferenceNE &) refG;   
        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);
             // creation d'un bloc general contenant des informations
             BlocGen bloc(2,1);
             bloc.Change_nom(1,"epaisseurs");
             bloc.Change_nom(2,nom_fct_nD); // s'il contient "_" cela veut dire : pas de fctnD
             bloc.Change_val(1, val);
             // demande a l'element de se completer
             poi = poi->Complete(bloc,lesFonctionsnD);
             if (poi == NULL)
               { // cas d'un probleme 
                 cout << "\n erreur l\'epaisseur n'est pas adapte a l\'element ";
                 poi = & Element_LesMaille(nnn,nbb);
                 cout << "\n element " << poi->Geometrie() << poi->Interpolation();
                 cout << "\n LesMaillages::Completer( etc ... " << endl;
                 Sortie(1);
               };
            } 
      }
    // cas des largeurs d' elements
    int divers_TabLargeurs_Taille=divers->TabLargeurs().Taille();
    for (int ii=1;ii<= divers_TabLargeurs_Taille;ii++)
     {  string nomSect = (divers->TabLargeurs())(ii).NomRef(); // recup du nom de la ref
        const BlocDdlLim<BlocScal_ou_fctnD>& div_larg = (divers->TabLargeurs())(ii);
        // soit c'est une valeur fixe soit une fonction nD
        double val = 0; // init par défaut
        string nom_fct_nD("_"); // ""
        if (div_larg.Val() != NULL) // cas d'une valeur fixe
          { val = *(div_larg.Val());} // recup de la valeur
        else if (div_larg.Fct_nD() != NULL) // cas d'une fonction nD
          { nom_fct_nD = *(div_larg.Fct_nD());}
        else // sinon il y a un pb
          { cout << "\n *** erreur de definition de la largeur les infos lues ne sont pas correctes: ";
            div_larg.Affiche();
            Sortie(1);
          };
        const Reference& refG = lesRef->Trouve(nomSect,div_larg.NomMaillage()); // recup de la reference
        // vérif que la référence s'adresse à des éléments
        if ( refG.Indic() != 2)
          { // erreur la référence ne concerne pas des éléments
            cout << "\n erreur la référence " << refG.Nom() << " ne concerne pas des éléments ";
            cout << " \n cas des données relatives aux largeurs d'éléments ";
            cout << "\n LesMaillages::Completer( .... ";
            Sortie(1);
           };
        const ReferenceNE & ref = (ReferenceNE &) refG;   
        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);
             // creation d'un bloc general contenant des informations
             BlocGen bloc(2,1);
             bloc.Change_nom(2,nom_fct_nD); // s'il contient "_" cela veut dire : pas de fctnD
             bloc.Change_nom(1,"largeurs");
             bloc.Change_val(1, val);
             // demande a l'element de se completer
             poi = poi->Complete(bloc,lesFonctionsnD);
             if (poi == NULL)
               { // cas d'un probleme 
                 cout << "\n erreur la largeur n'est pas adapte a l\'element ";
                 poi = & Element_LesMaille(nnn,nbb);
                 cout << "\n element " << poi->Geometrie() << poi->Interpolation();
                 cout << "\n LesMaillages::Completer( etc ... " << endl;
                 Sortie(1);
               };
            } 
      }
    // cas des masses volumique d' elements
    int divers_TabMasseVolu_Taille=divers->TabMasseVolu().Taille();
    for (int ii=1;ii<= divers_TabMasseVolu_Taille;ii++)
     {  string nomMasseVol = (divers->TabMasseVolu())(ii).NomRef(); // recup du nom de la ref
        const BlocDdlLim<BlocScal_ou_fctnD>& div_massevolu = (divers->TabMasseVolu())(ii);
        // soit c'est une valeur fixe soit une fonction nD
        double val = 0; // init par défaut
        string nom_fct_nD("_"); // ""
        if (div_massevolu.Val() != NULL) // cas d'une valeur fixe
          { val = *(div_massevolu.Val());} // recup de la valeur
        else if (div_massevolu.Fct_nD() != NULL) // cas d'une fonction nD
          { nom_fct_nD = *(div_massevolu.Fct_nD());}
        else // sinon il y a un pb
          { cout << "\n *** erreur de definition de la masse volumique les infos lues ne sont pas correctes: ";
            div_massevolu.Affiche();
            Sortie(1);
          };
        const Reference & refG = lesRef->Trouve(nomMasseVol,div_massevolu.NomMaillage()); // recup de la reference
        // vérif que la référence s'adresse à des éléments
        if ( refG.Indic() != 2)
          { // erreur la référence ne concerne pas des éléments
            cout << "\n erreur la référence " << refG.Nom() << " ne concerne pas des éléments ";
            cout << " \n cas des données relatives aux masses volumiques ";
            cout << "\n LesMaillages::Completer( .... ";
            Sortie(1);
           };
        const ReferenceNE & ref = (ReferenceNE &) refG;   
        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);
             // creation d'un bloc general contenant des informations
             BlocGen bloc(2,1);
             bloc.Change_nom(1,"masse_volumique");
             bloc.Change_nom(2,nom_fct_nD); // s'il contient "_" cela veut dire : pas de fctnD
             bloc.Change_val(1, val);
             // demande a l'element de se completer
             poi = poi->Complete(bloc,lesFonctionsnD);
             if (poi == NULL)
               { // cas d'un probleme 
                 cout << "\n erreur la masse volumique n'est pas adapte a l\'element ";
                 poi = & Element_LesMaille(nnn,nbb);
                 cout << "\n element " << poi->Geometrie() << poi->Interpolation();
                 cout << "\n LesMaillages::Completer( etc ... " << endl;
                 Sortie(1);
               };
            } 
      }

    // cas des gestions d'hourglass d'elements
    int divers_TabGesHourglass_Taille=divers->TabGesHourglass().Taille();
    for (int ii=1;ii<= divers_TabGesHourglass_Taille;ii++)
     {  string nomGesHourglass = (divers->TabGesHourglass())(ii).NomRef(); // recup du nom de la ref
        const BlocDdlLim<BlocGen_3_1>& div_GesHourglass = (divers->TabGesHourglass())(ii);
 //       double val = div_GesHourglass.Val(); // recup de la valeur
        const Reference & refG = lesRef->Trouve(nomGesHourglass,div_GesHourglass.NomMaillage()); // recup de la reference
        // vérif que la référence s'adresse à des éléments
        if ( refG.Indic() != 2)
          { // erreur la référence ne concerne pas des éléments
            cout << "\n erreur la référence " << refG.Nom() << " ne concerne pas des éléments ";
            cout << " \n cas des données relatives aux gestions des modes d'hourglass ";
            cout << "\n LesMaillages::Completer( .... ";
            Sortie(1);
           };
        const ReferenceNE & ref = (ReferenceNE &) refG;   
        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);
             // creation d'un bloc general contenant des informations
             BlocGen bloc(1,2);
             bloc.Change_nom(1,div_GesHourglass.Nom(2));
             bloc.Change_val(1, div_GesHourglass.Val(1));
				         // récupération éventuelle de la loi si besoin
				         LoiAbstraiteGeneral * loiHourglass = NULL;
				 
				         if (  (Id_Nom_StabHourglass(div_GesHourglass.Nom(2).c_str()) == STABHOURGLASS_PAR_COMPORTEMENT)
                || (Id_Nom_StabHourglass(div_GesHourglass.Nom(2).c_str()) == STABHOURGLASS_PAR_COMPORTEMENT_REDUIT))
				             // le pointeur le loi
                 {  loiHourglass = lesLois->PtLoi_abstraite(div_GesHourglass.Nom(3));};
             // demande a l'element de se completer
             poi  = poi->Complet_Hourglass(loiHourglass,bloc);
             if (poi == NULL)
               { // cas d'un probleme 
                 cout << "\n erreur la gestion d'hourglass: " << div_GesHourglass << "  n'est pas adapte a l\'element ";
                 poi = & Element_LesMaille(nnn,nbb);
                 cout << "\n element " << poi->Geometrie() << poi->Interpolation();
                 cout << "\n LesMaillages::Completer( etc ... " << endl;
                 Sortie(1);
                }
            };
      };

    // cas des intégrales sur le volume
    int divers_TabIntegVol_Taille=divers->TabIntegVol().Taille();
    // on redimentionne les tableaux de sauvegardes
    integ_vol_typeQuel.Change_taille(divers_TabIntegVol_Taille);
    integ_vol_typeQuel_t.Change_taille(divers_TabIntegVol_Taille);
    ref_integ_vol.Change_taille(divers_TabIntegVol_Taille);
    for (int ii=1;ii<= divers_TabIntegVol_Taille;ii++)
     {  string nomIntegVol = (divers->TabIntegVol())(ii).NomRef(); // recup du nom de la ref
        const BlocDdlLim<BlocGen_3_0>& div_IntegVol = (divers->TabIntegVol())(ii);
        const Reference & refG = lesRef->Trouve(nomIntegVol,div_IntegVol.NomMaillage()); // recup de la reference
        // vérif que la référence s'adresse à des éléments
        if ( refG.Indic() != 2)
          { // erreur la référence ne concerne pas des éléments
            cout << "\n erreur la référence " << refG.Nom() << " ne concerne pas des éléments ";
            cout << " \n cas des données relatives aux integrations sur le volume ";
            cout << "\n LesMaillages::Completer( .... ";
            Sortie(1);
           };
        const ReferenceNE & ref = (ReferenceNE &) refG;
        // creation d'un bloc general contenant des informations
        // n= nombre de string, m nombre de double
        BlocGen bloc(4,1) ; // par defaut
////--- debug
//cout << "\n -- debug LesMaillages::Completer( ";
//div_IntegVol.Affiche(); cout << endl;
////--- fin debug
        string nom_inter("integrale_sur_volume_");
        bloc.Change_nom(1,nom_inter); // le type d'intégrale: de volume  ici
        bloc.Change_nom(2,div_IntegVol.Nom(2)); // mot clé : ex: un_ddl_etendu_
        bloc.Change_nom(3,div_IntegVol.Nom(3)); // ex: le nom du ddl : ex UX
        // construction d'un nom qui servira à discriminer les différents conteneurs 
        string nom_ref("int_vol_");// init
        if ((div_IntegVol.NomMaillage() == NULL) // cas d'un seule maillage
            && (nbMaillageTotal==1)) // enregistré
           {nom_ref +=(refG.Nom());}
        else if (div_IntegVol.NomMaillage() != NULL) // cas de plusieurs maillages
           {nom_ref += (*div_IntegVol.NomMaillage())+"_"+(refG.Nom());}
        else // sinon pb
          { cout << "\n erreur il manque le nom de maillage alors qu'il y a plusieurs maillages en cours ";
            cout << " \n cas des données relatives aux integrations sur le volume ";
            cout << "\n LesMaillages::Completer( .... ";
            Sortie(1);
           };
      
        bloc.Change_val(1,ii); // on indique le numéro du stockage global
        // on commence par définir le conteneur global qui sera stocké dans LesMaillages
        ref_integ_vol(ii) = &refG;
        if (bloc.Nom(2) == "un_ddl_etendu_")
           { // il s'agit d'une intégrale d'un ddl étendu de nom: bloc.Nom(3)
             nom_ref += "_ddl_etendu_"+bloc.Nom(3);
             Ddl_etendu ddl(Ddl_enum_etendu(bloc.Nom(3))) ;// on crée un ddl ad hoc
             Grandeur_Ddl_etendu grand_courant(ddl,nom_ref);// le conteneur ad hoc
             // on ajoute éventuellement un TypeQuelconque_enum_etendu s'il n'existe pas
             // et on récupère un exemplaire
             TypeQuelconque_enum_etendu enuType =
                     TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
                               (INTEG_SUR_VOLUME,nom_ref,SCALAIRE_DOUBLE);
//             TypeQuelconque typQ(INTEG_SUR_VOLUME,EPS11,grand_courant);
             TypeQuelconque typQ(enuType,EPS11,grand_courant);
             integ_vol_typeQuel(ii) = (typQ);
             // et on ajoute une grandeur globale qui sera indexée par le nom de référence
             ParaGlob::param->Ajout_grandeur_consultable(&typQ,nom_ref);
             // idem pour la grandeur à t
             string nom_ref_t = nom_ref + "_t_";
             Ddl_etendu ddl_t(Ddl_enum_etendu(bloc.Nom(3))) ;// on crée un ddl ad hoc
             Grandeur_Ddl_etendu grand_courant_t(ddl_t,nom_ref_t);// le conteneur ad hoc
             // on ajoute éventuellement un TypeQuelconque_enum_etendu s'il n'existe pas
             // et on récupère un exemplaire
             TypeQuelconque_enum_etendu enuType_t =
                     TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
                               (INTEG_SUR_VOLUME,nom_ref_t,SCALAIRE_DOUBLE);
//             TypeQuelconque typQ_t(INTEG_SUR_VOLUME,EPS11,grand_courant_t);
             TypeQuelconque typQ_t(enuType_t,EPS11,grand_courant_t);
             integ_vol_typeQuel_t(ii) = (typQ_t);
             // et on ajoute une grandeur globale qui sera indexée par le nom de référence
             ParaGlob::param->Ajout_grandeur_consultable(&typQ_t,nom_ref_t);
           }
         else if (bloc.Nom(2) == "une_fonction_nD_")
           { // il s'agit d'une intégrale d'une fonction nD de nom: bloc.Nom(3)
             nom_ref += "_fct_nD_"+bloc.Nom(3);
             // on récupère le pointeur de fonction correspondant:
             Fonction_nD * fct = lesFonctionsnD->Trouve(bloc.Nom(3));
             int nb_composante = fct->NbComposante();
             Grandeur_Vecteur_Nommer grand_courant(nom_ref,nb_composante,fct);
             // on ajoute éventuellement un TypeQuelconque_enum_etendu s'il n'existe pas
             // et on récupère un exemplaire
             TypeQuelconque_enum_etendu enuType =
                     TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
                               (INTEG_SUR_VOLUME,nom_ref,VECTEUR);
//             TypeQuelconque typQ(INTEG_SUR_VOLUME,EPS11,grand_courant);
             TypeQuelconque typQ(enuType,EPS11,grand_courant);
             integ_vol_typeQuel(ii) = (typQ);
             // et on ajoute une grandeur globale qui sera indexée par le nom de référence
             ParaGlob::param->Ajout_grandeur_consultable(&typQ,nom_ref);
             // idem pour la grandeur à t
             string nom_ref_t = nom_ref + "_t_";
             Grandeur_Vecteur_Nommer grand_courant_t(nom_ref_t,nb_composante,fct);
             // on ajoute éventuellement un TypeQuelconque_enum_etendu s'il n'existe pas
             // et on récupère un exemplaire
             TypeQuelconque_enum_etendu enuType_t =
                     TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
                               (INTEG_SUR_VOLUME,nom_ref_t,VECTEUR);
//             TypeQuelconque typQ_t(INTEG_SUR_VOLUME,EPS11,grand_courant_t);
             TypeQuelconque typQ_t(enuType_t,EPS11,grand_courant_t);
             integ_vol_typeQuel_t(ii) = (typQ_t);
             // et on ajoute une grandeur globale qui sera indexée par le nom de référence
             ParaGlob::param->Ajout_grandeur_consultable(&typQ_t,nom_ref_t);
////--- debug
//cout << "\n -- debug LesMaillages::Completer( ";
//if (nom_ref_t == "int_vol_E_tout_fct_nD_fct1_t_")
// { const void* pointe =  (ParaGlob::param->GrandeurGlobal(nom_ref_t));
//   TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
//   cout << "\n gr_quelc= "<< (*gr_quelc) << endl;
//   Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier
//   cout << "\n gr.NbMaxiNumeroOrdre()= "<<gr.NbMaxiNumeroOrdre() << endl;
// }
////cout << "\n (typQ_t)= "<<(typQ_t) << " nom_ref_t= "<<nom_ref_t << endl;
// cout << endl;
////--- fin debug
           };
        bloc.Change_nom(4,nom_ref); // on indique le nom de référencement global
////--- debug
//cout << "\n -- debug LesMaillages::Completer( ";
//bloc.Affiche(); cout << endl;
////--- fin debug
        // puis on alimente les éléments concernés par ces calculs
        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 de se completer
             poi = poi->Complete(bloc,lesFonctionsnD);
             if (poi == NULL)
               { // cas d'un probleme 
                 cout << "\n erreur l'integration de ";bloc.Affiche();
                 cout << " n'est pas adapte a l\'element ";
                 poi = & Element_LesMaille(nnn,nbb);
                 cout << "\n element " << poi->Geometrie() << poi->Interpolation();
                 cout << "\n LesMaillages::Completer( etc ... " << endl;
                 Sortie(1);
               };
            };
        ref_integ_vol(ii)= &refG; // sauvegarde
     };
   
    // cas des intégrales sur le volume et le temps
    int divers_TtabIntegVol_et_temps_Taille=divers->TtabIntegVol_et_temps().Taille();
    // on redimentionne les tableaux de sauvegardes
    integ_vol_t_typeQuel.Change_taille(divers_TtabIntegVol_et_temps_Taille);
    integ_vol_t_typeQuel_t.Change_taille(divers_TtabIntegVol_et_temps_Taille);
    ref_integ_vol_t.Change_taille(divers_TtabIntegVol_et_temps_Taille);
    for (int ii=1;ii<= divers_TtabIntegVol_et_temps_Taille;ii++)
     {  string nomIntegVol = (divers->TtabIntegVol_et_temps())(ii).NomRef(); // recup du nom de la ref
        const BlocDdlLim<BlocGen_3_0>& div_IntegVol = (divers->TtabIntegVol_et_temps())(ii);
        const Reference & refG = lesRef->Trouve(nomIntegVol,div_IntegVol.NomMaillage()); // recup de la reference
        // vérif que la référence s'adresse à des éléments
        if ( refG.Indic() != 2)
          { // erreur la référence ne concerne pas des éléments
            cout << "\n erreur la référence " << refG.Nom() << " ne concerne pas des éléments ";
            cout << " \n cas des données relatives aux integrations sur le volume et le temps ";
            cout << "\n LesMaillages::Completer( .... ";
            Sortie(1);
           };
        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(4,1) ; // par defaut
        string nom_inter("integrale_sur_vol_et_temps_");
        bloc.Change_nom(1,nom_inter); // le type d'intégrale: de volume  ici
        bloc.Change_nom(2,div_IntegVol.Nom(2));
        bloc.Change_nom(3,div_IntegVol.Nom(3));
        // construction d'un nom qui servira à discriminer les différents conteneurs 
        string nom_ref("int_vol_temps_");// init
        if ((div_IntegVol.NomMaillage() == NULL) // cas d'un seule maillage
            && (nbMaillageTotal==1)) // enregistré
           {nom_ref +=(refG.Nom());}
        else if (div_IntegVol.NomMaillage() != NULL) // cas de plusieurs maillages
           {nom_ref += (*div_IntegVol.NomMaillage())+"_"+(refG.Nom());}
        else // sinon pb
          { cout << "\n erreur il manque le nom de maillage alors qu'il y a plusieurs maillages en cours ";
            cout << " \n cas des données relatives aux integrations sur le volume et le temps ";
            cout << "\n LesMaillages::Completer( .... ";
            Sortie(1);
           };
        bloc.Change_val(1,ii); // on indique le numéro du stockage global
        // on commence par définir le conteneur global qui sera stocké dans LesMaillages
        ref_integ_vol_t(ii) = &refG;
        if (bloc.Nom(2) == "un_ddl_etendu_")
           { // il s'agit d'une intégrale d'un ddl étendu de nom: bloc.Nom(3)
             nom_ref += "_ddl_etendu_"+bloc.Nom(3);
             Ddl_etendu ddl(Ddl_enum_etendu(bloc.Nom(3))) ;// on crée un ddl ad hoc
             Grandeur_Ddl_etendu grand_courant(ddl,nom_ref);// le conteneur ad hoc
             // on ajoute éventuellement un TypeQuelconque_enum_etendu s'il n'existe pas
             // et on récupère un exemplaire
             TypeQuelconque_enum_etendu enuType =
                     TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
                               (INTEG_SUR_VOLUME_ET_TEMPS,nom_ref,SCALAIRE_DOUBLE);
//             TypeQuelconque typQ(INTEG_SUR_VOLUME_ET_TEMPS,EPS11,grand_courant);
             TypeQuelconque typQ(enuType,EPS11,grand_courant);
             integ_vol_t_typeQuel(ii) = (typQ);
             // et on ajoute une grandeur globale qui sera indexée par le nom de référence
             ParaGlob::param->Ajout_grandeur_consultable(&typQ,nom_ref);
             // idem pour la grandeur à t
             string nom_ref_t = nom_ref + "_t_";
             Ddl_etendu ddl_t(Ddl_enum_etendu(bloc.Nom(3))) ;// on crée un ddl ad hoc
             Grandeur_Ddl_etendu grand_courant_t(ddl,nom_ref_t);// le conteneur ad hoc
             // on ajoute éventuellement un TypeQuelconque_enum_etendu s'il n'existe pas
             // et on récupère un exemplaire
             TypeQuelconque_enum_etendu enuType_t =
                     TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
                               (INTEG_SUR_VOLUME_ET_TEMPS,nom_ref_t,SCALAIRE_DOUBLE);
//             TypeQuelconque typQ_t(INTEG_SUR_VOLUME_ET_TEMPS,EPS11,grand_courant_t);
             TypeQuelconque typQ_t(enuType_t,EPS11,grand_courant_t);
             integ_vol_t_typeQuel_t(ii) = (typQ_t);
             // et on ajoute une grandeur globale qui sera indexée par le nom de référence
             ParaGlob::param->Ajout_grandeur_consultable(&typQ_t,nom_ref_t);
           }
         else if (bloc.Nom(2) == "une_fonction_nD_")
           { // il s'agit d'une intégrale d'une fonction nD de nom: bloc.Nom(3)
             nom_ref += "_fct_nD_"+bloc.Nom(3);
             // on récupère le pointeur de fonction correspondant:
             Fonction_nD * fct = lesFonctionsnD->Trouve(bloc.Nom(3));
             int nb_composante = fct->NbComposante();
             Grandeur_Vecteur_Nommer grand_courant(nom_ref,nb_composante,fct);
             // on ajoute éventuellement un TypeQuelconque_enum_etendu s'il n'existe pas
             // et on récupère un exemplaire
             TypeQuelconque_enum_etendu enuType =
                     TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
                               (INTEG_SUR_VOLUME_ET_TEMPS,nom_ref,VECTEUR);
//             TypeQuelconque typQ(INTEG_SUR_VOLUME_ET_TEMPS,EPS11,grand_courant);
             TypeQuelconque typQ(enuType,EPS11,grand_courant);
             integ_vol_t_typeQuel(ii) = (typQ);
             // et on ajoute une grandeur globale qui sera indexée par le nom de référence
             ParaGlob::param->Ajout_grandeur_consultable(&typQ,nom_ref);
             // idem pour la grandeur à t
             string nom_ref_t = nom_ref + "_t_";
             Grandeur_Vecteur_Nommer grand_courant_t(nom_ref_t,nb_composante,fct);
             // on ajoute éventuellement un TypeQuelconque_enum_etendu s'il n'existe pas
             // et on récupère un exemplaire
             TypeQuelconque_enum_etendu enuType_t =
                     TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
                               (INTEG_SUR_VOLUME_ET_TEMPS,nom_ref_t,VECTEUR);
//             TypeQuelconque typQ_t(INTEG_SUR_VOLUME_ET_TEMPS,EPS11,grand_courant_t);
             TypeQuelconque typQ_t(enuType_t,EPS11,grand_courant_t);
             integ_vol_t_typeQuel_t(ii) = (typQ_t);
             // et on ajoute une grandeur globale qui sera indexée par le nom de référence
             ParaGlob::param->Ajout_grandeur_consultable(&typQ_t,nom_ref_t);
           };
        bloc.Change_nom(4,nom_ref); // on indique le nom de référencement global
        // 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 = poi->Complete(bloc,lesFonctionsnD);
             if (poi == NULL)
               { // cas d'un probleme 
                 cout << "\n erreur l'integration de ";bloc.Affiche();
                 cout << " n'est pas adapte a l\'element ";
                 poi = & Element_LesMaille(nnn,nbb);
                 cout << "\n element " << poi->Geometrie() << poi->Interpolation();
                 cout << "\n LesMaillages::Completer( etc ... " << endl;
                 Sortie(1);
               };
            };
     };
   
    // cas de la stabilisation transversale de membrane et ou de biel
    int divers_TabStabMembBiel_Taille=divers->TabStabMembBiel().Taille();
    // on redimentionne les tableaux de sauvegardes
    for (int ii=1;ii<= divers_TabStabMembBiel_Taille;ii++)
     {  string nomStabMembBiel = (divers->TabStabMembBiel())(ii).NomRef(); // recup du nom de la ref
        // on récupère la taille réel du conteneur
        int nb_info = (divers->TabStabMembBiel())(ii).DimNom();
        // creation d'un bloc general contenant des informations
        // n= nombre de string, m nombre de double
        BlocGen bloc(nb_info,0) ; // par defaut
        // on récupère le bloc gen qui est par défaut de type 4,0 mais en fait est peut-être différent
        // via la lecture. Comme on ramène un pointeur, on récupère le vrai bloc lu, modifié éventuellement en taille
        const BlocDdlLim<BlocGen_4_0>& div_TabStabMembBiel = (divers->TabStabMembBiel())(ii);
        const Reference & refG = lesRef->Trouve(nomStabMembBiel,div_TabStabMembBiel.NomMaillage()); // recup de la reference
        // vérif que la référence s'adresse à des éléments
        if ( refG.Indic() != 2)
          { // erreur la référence ne concerne pas des éléments
            cout << "\n erreur la référence " << refG.Nom() << " ne concerne pas des éléments ";
            cout << " \n cas des données relatives a la stabilisation transversale de membrane ou de biel ";
            cout << "\n LesMaillages::Completer( .... ";
            Sortie(1);
           };
        const ReferenceNE & ref = (ReferenceNE &) refG;   
        int ref_Taille=ref.Taille();
        string nom_inter("stabilisation_transvers_membrane_biel_");
        bloc.Change_nom(1,nom_inter); // le mot clé
        // ensuite le type de stabilisation
        bloc.Change_nom(2,div_TabStabMembBiel.Nom(2));
        // puis un des deux mots clés :  "une_valeur_numerique_" ou  "une_fonction_nD_"
        bloc.Change_nom(3,div_TabStabMembBiel.Nom(3));
        // un string qui contient: soit la valeur numérique, soit le nom de la fonction nD
        bloc.Change_nom(4,div_TabStabMembBiel.Nom(4));
        // s'il y a des infos supplémentaires, on les recopie
        if (nb_info > 4)
         for (int i=4;i<=nb_info;i++)
           bloc.Change_nom(i,div_TabStabMembBiel.Nom(i));
        
        // 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 = poi->Complete(bloc,lesFonctionsnD);
            };
     };

   
//    // retourne le tableau  sur la définition d'un repère d'anisotropie aux éléments
//    const Tableau < BlocDdlLim<BlocGen_5_0> >& TabRepAnisotrope() const {return tabRepAnisotrope;};
    // cas de la définition de repère d'anisotropie
    int divers_TabRepAnisotrope_Taille=divers->TabRepAnisotrope().Taille();
    // on redimentionne les tableaux de sauvegardes
    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
        // vérif que la référence s'adresse à des éléments
        if ( refG.Indic() != 2)
          { // erreur la référence ne concerne pas des éléments
            cout << "\n erreur la reference " << refG.Nom() << " ne concerne pas des elements ";
            cout << " \n cas des donnees relatives a la definition de repere d'anisotropie ";
            cout << "\n LesMaillages::Completer( .... ";
            Sortie(1);
           };
        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 = poi->Complete(bloc,lesFonctionsnD);
            };
     };


    // cas de statistique d'une ref de noeuds pour une grandeur quelconque
    int divers_TabStatistique_Taille=divers->TabStatistique().Taille();
    // on redimentionne les tableaux de sauvegardes
    statistique_typeQuel.Change_taille(divers_TabStatistique_Taille);
    statistique_typeQuel_t.Change_taille(divers_TabStatistique_Taille);
    ref_statistique.Change_taille(divers_TabStatistique_Taille);
    pour_statistique_de_ddl.Change_taille(divers_TabStatistique_Taille);
    for (int ii=1;ii<= divers_TabStatistique_Taille;ii++)
     {  string nomStatistique = (divers->TabStatistique())(ii).NomRef(); // recup du nom de la ref
        const BlocDdlLim<BlocGen_3_0>& div_Statistique = (divers->TabStatistique())(ii);
        const Reference & refG = lesRef->Trouve(nomStatistique,div_Statistique.NomMaillage()); // recup de la reference
        // vérif que la référence s'adresse à des noeuds
        if ( refG.Indic() != 1)
          { // erreur la référence ne concerne pas des éléments
            cout << "\n erreur la reference " << refG.Nom() << " ne concerne pas des Noeuds ";
            cout << " \n cas des donnees relatives aux statistiques ";
            cout << "\n LesMaillages::Completer( .... ";
            Sortie(1);
           };
        const ReferenceNE & ref = (ReferenceNE &) refG;
        // creation d'un bloc general contenant des informations
        // n= nombre de string, m nombre de double
        BlocGen bloc(4,1) ; // par defaut
   ////--- debug
   //cout << "\n -- debug LesMaillages::Completer( ";
   //div_Statistique.Affiche(); cout << endl;
   ////--- fin debug
        string nom_inter("statistique_");
        bloc.Change_nom(1,nom_inter); // le type de statistique
        bloc.Change_nom(2,div_Statistique.Nom(2)); // mot clé : ex: un_ddl_etendu_
        bloc.Change_nom(3,div_Statistique.Nom(3)); // ex: le nom du ddl : ex UX
        // construction d'un nom qui servira à discriminer les différents conteneurs
        string nom_ref("statistique_");// init
        if ((div_Statistique.NomMaillage() == NULL) // cas d'un seule maillage
            && (nbMaillageTotal==1)) // enregistré
           {nom_ref +=(refG.Nom());}
        else if (div_Statistique.NomMaillage() != NULL) // cas de plusieurs maillages
           {nom_ref += (*div_Statistique.NomMaillage())+"_"+(refG.Nom());}
        else // sinon pb
          { cout << "\n erreur il manque le nom de maillage alors qu'il y a plusieurs maillages en cours ";
            cout << " \n cas des donnees relatives aux statistiques sur ref de noeuds ";
            cout << "\n LesMaillages::Completer( .... ";
            Sortie(1);
           };
     
        bloc.Change_val(1,ii); // on indique le numéro du stockage global
        // on commence par définir le conteneur global qui sera stocké dans LesMaillages
        ref_statistique(ii) = &refG;
        if (bloc.Nom(2) == "un_ddl_etendu_")
           { // il s'agit d'une statistique d'un ddl étendu de nom: bloc.Nom(3)
             nom_ref += "_ddl_etendu_"+bloc.Nom(3);
             // on sauvegarde le Ddl_enum_etendu associé
             pour_statistique_de_ddl(ii) = Ddl_enum_etendu(bloc.Nom(3));
             // on définit le conteneur résultat: on stocke un vecteur, car pour un ddl -> 10 valeurs
             Grandeur_Vecteur_Nommer gvec_courant(nom_ref,10);
             // on ajoute éventuellement un TypeQuelconque_enum_etendu s'il n'existe pas
             // et on récupère un exemplaire
             TypeQuelconque_enum_etendu enuType =
                     TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
                               (STATISTIQUE,nom_ref,VECTEUR);
             TypeQuelconque typQ(enuType,X1,gvec_courant);
             statistique_typeQuel(ii) = (typQ); // stockage interne à LesMaillages
             // et on ajoute une grandeur globale qui sera indexée par le nom de référence
             ParaGlob::param->Ajout_grandeur_consultable(&typQ,nom_ref);
             
             // idem pour la grandeur à t
             string nom_ref_t = nom_ref + "__t_";
             // on définit le conteneur résultat: on stocke un vecteur, car pour un ddl -> 10 valeurs
             Grandeur_Vecteur_Nommer gvec_courant_t(nom_ref_t,10);
             // on ajoute éventuellement un TypeQuelconque_enum_etendu s'il n'existe pas
             // et on récupère un exemplaire
             TypeQuelconque_enum_etendu enuType_t =
                     TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
                               (STATISTIQUE,nom_ref_t,VECTEUR);
             TypeQuelconque typQ_t(enuType_t,X1,gvec_courant_t);
             statistique_typeQuel_t(ii) = (typQ_t); // stockage interne à LesMaillages
             // et on ajoute une grandeur globale qui sera indexée par le nom de référence
             ParaGlob::param->Ajout_grandeur_consultable(&typQ_t,nom_ref_t);
          }
        else if (bloc.Nom(2) == "une_fonction_nD_")
          { // il s'agit d'une statistique d'une fonction nD de nom: bloc.Nom(3)
            nom_ref += "_fct_nD_"+bloc.Nom(3);
            // on récupère le pointeur de fonction correspondant:
            Fonction_nD * fct = lesFonctionsnD->Trouve(bloc.Nom(3));
            int nb_composante = fct->NbComposante();
            int dim_necessaire = (6*nb_composante + 4); // cf. la méthode CalStatistique()
            Grandeur_Vecteur_Nommer grand_courant(nom_ref,dim_necessaire,fct);
            // on ajoute éventuellement un TypeQuelconque_enum_etendu s'il n'existe pas
            // et on récupère un exemplaire
            TypeQuelconque_enum_etendu enuType =
                    TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
                              (STATISTIQUE,nom_ref,VECTEUR);
            TypeQuelconque typQ(enuType,X1,grand_courant);
            statistique_typeQuel(ii) = (typQ);
            // et on ajoute une grandeur globale qui sera indexée par le nom de référence
            ParaGlob::param->Ajout_grandeur_consultable(&typQ,nom_ref);
            // idem pour la grandeur à t
            string nom_ref_t = nom_ref + "__t_";
            Grandeur_Vecteur_Nommer grand_courant_t(nom_ref_t,dim_necessaire,fct);
            // on ajoute éventuellement un TypeQuelconque_enum_etendu s'il n'existe pas
            // et on récupère un exemplaire
            TypeQuelconque_enum_etendu enuType_t =
                    TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
                              (STATISTIQUE,nom_ref_t,VECTEUR);
            TypeQuelconque typQ_t(enuType_t,X1,grand_courant_t);
            statistique_typeQuel_t(ii) = (typQ_t); // stockage interne à LesMaillages
            // et on ajoute une grandeur globale qui sera indexée par le nom de référence
            ParaGlob::param->Ajout_grandeur_consultable(&typQ_t,nom_ref_t);
   ////--- debug
   //cout << "\n -- debug LesMaillages::Completer( ";
   //if (nom_ref_t == "int_vol_E_tout_fct_nD_fct1_t_")
   // { const void* pointe =  (ParaGlob::param->GrandeurGlobal(nom_ref_t));
   //   TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
   //   cout << "\n gr_quelc= "<< (*gr_quelc) << endl;
   //   Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier
   //   cout << "\n gr.NbMaxiNumeroOrdre()= "<<gr.NbMaxiNumeroOrdre() << endl;
   // }
   ////cout << "\n (typQ_t)= "<<(typQ_t) << " nom_ref_t= "<<nom_ref_t << endl;
   // cout << endl;
   ////--- fin debug
              };
        bloc.Change_nom(4,nom_ref); // on indique le nom de référencement global
   ////--- debug
   //cout << "\n -- debug LesMaillages::Completer( ";
   //bloc.Affiche(); cout << endl;
   ////--- fin debug

// arrêt des opérations ici .....
//
//           // puis on alimente les éléments concernés par ces calculs
//           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 de se completer
//                poi = poi->Complete(bloc,lesFonctionsnD);
//                if (poi == NULL)
//                  { // cas d'un probleme
//                    cout << "\n erreur l'integration de ";bloc.Affiche();
//                    cout << " n'est pas adapte a l\'element ";
//                    poi = & Element_LesMaille(nnn,nbb);
//                    cout << "\n element " << poi->Geometrie() << poi->Interpolation();
//                    cout << "\n LesMaillages::Completer( etc ... " << endl;
//                    Sortie(1);
//                  };
//               };
        };
      
    // cas des statistiques sur des ref de noeuds avec cumul en  temps
    int divers_TabStatistique_et_temps_Taille=divers->TabStatistique_et_temps().Taille();
    // on redimentionne les tableaux de sauvegardes
    statistique_t_typeQuel.Change_taille(divers_TabStatistique_et_temps_Taille);
    statistique_t_typeQuel_t.Change_taille(divers_TabStatistique_et_temps_Taille);
    ref_statistique_t.Change_taille(divers_TabStatistique_et_temps_Taille);
    pour_statistique_t_de_ddl.Change_taille(divers_TabStatistique_et_temps_Taille,NU_DDL);
    for (int ii=1;ii<= divers_TabStatistique_et_temps_Taille;ii++)
     {  string nomStatistique = (divers->TabStatistique_et_temps())(ii).NomRef(); // recup du nom de la ref
        const BlocDdlLim<BlocGen_3_0>& div_Statistique = (divers->TabStatistique_et_temps())(ii);
        const Reference & refG = lesRef->Trouve(nomStatistique,div_Statistique.NomMaillage()); // recup de la reference
        // vérif que la référence s'adresse à des noeuds
        if ( refG.Indic() != 1)
          { // erreur la référence ne concerne pas des noeuds
            cout << "\n erreur la reference " << refG.Nom() << " ne concerne pas des noeuds ";
            cout << " \n cas des donnees relatives aux statistiques de ref de noeuds avec cumul en temps ";
            cout << "\n LesMaillages::Completer( .... ";
            Sortie(1);
           };
        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(4,1) ; // par defaut
        string nom_inter("statistique_et_temps_");
        bloc.Change_nom(1,nom_inter); // le type de statistique
        bloc.Change_nom(2,div_Statistique.Nom(2));
        bloc.Change_nom(3,div_Statistique.Nom(3));
        // construction d'un nom qui servira à discriminer les différents conteneurs
        string nom_ref("statistique_temps_");// init
        if ((div_Statistique.NomMaillage() == NULL) // cas d'un seule maillage
            && (nbMaillageTotal==1)) // enregistré
           {nom_ref +=(refG.Nom());}
        else if (div_Statistique.NomMaillage() != NULL) // cas de plusieurs maillages
           {nom_ref += (*div_Statistique.NomMaillage())+"_"+(refG.Nom());}
        else // sinon pb
          { cout << "\n erreur il manque le nom de maillage alors qu'il y a plusieurs maillages en cours ";
            cout << " \n cas des données relatives aux statistiques sur des ref de noeuds avec cumul en temps ";
            cout << "\n LesMaillages::Completer( .... ";
            Sortie(1);
           };
        bloc.Change_val(1,ii); // on indique le numéro du stockage global
        // on commence par définir le conteneur global qui sera stocké dans LesMaillages
        ref_statistique_t(ii) = &refG;
        if (bloc.Nom(2) == "un_ddl_etendu_")
           { // il s'agit d'une statistique d'un ddl étendu de nom: bloc.Nom(3)
             nom_ref += "_ddl_etendu_"+bloc.Nom(3);
             // on sauvegarde le Ddl_enum_etendu associé
             pour_statistique_t_de_ddl(ii) = Ddl_enum_etendu(bloc.Nom(3));
             // on définit le conteneur résultat: on stocke un vecteur, car pour un ddl -> 10 valeurs
             Grandeur_Vecteur_Nommer gvec_courant(nom_ref,10);
             // on ajoute éventuellement un TypeQuelconque_enum_etendu s'il n'existe pas
             // et on récupère un exemplaire
             TypeQuelconque_enum_etendu enuType =
                     TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
                               (STATISTIQUE_ET_TEMPS,nom_ref,VECTEUR);
             TypeQuelconque typQ(enuType,X1,gvec_courant);
             statistique_t_typeQuel(ii) = (typQ); // stockage interne à LesMaillages
             // et on ajoute une grandeur globale qui sera indexée par le nom de référence
             ParaGlob::param->Ajout_grandeur_consultable(&typQ,nom_ref);
             // idem pour la grandeur à t
             string nom_ref_t = nom_ref + "__t_";
             // on définit le conteneur résultat: on stocke un vecteur, car pour un ddl -> 10 valeurs
             Grandeur_Vecteur_Nommer gvec_courant_t(nom_ref_t,10);
             // on ajoute éventuellement un TypeQuelconque_enum_etendu s'il n'existe pas
             // et on récupère un exemplaire
             TypeQuelconque_enum_etendu enuType_t =
                     TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
                               (STATISTIQUE_ET_TEMPS,nom_ref_t,VECTEUR);
             TypeQuelconque typQ_t(enuType_t,X1,gvec_courant_t);
             statistique_t_typeQuel_t(ii) = (typQ_t); // stockage interne à LesMaillages
             // et on ajoute une grandeur globale qui sera indexée par le nom de référence
             ParaGlob::param->Ajout_grandeur_consultable(&typQ_t,nom_ref_t);
           }
        else if (bloc.Nom(2) == "une_fonction_nD_")
           { // il s'agit d'une statistique d'une fonction nD de nom: bloc.Nom(3)
             nom_ref += "_fct_nD_"+bloc.Nom(3);
             // on récupère le pointeur de fonction correspondant:
             Fonction_nD * fct = lesFonctionsnD->Trouve(bloc.Nom(3));
             int nb_composante = fct->NbComposante();
             int dim_necessaire = (6*nb_composante + 4); // cf. la méthode CalStatistique()
             Grandeur_Vecteur_Nommer grand_courant(nom_ref,dim_necessaire,fct);
             // on ajoute éventuellement un TypeQuelconque_enum_etendu s'il n'existe pas
             // et on récupère un exemplaire
             TypeQuelconque_enum_etendu enuType =
                     TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
                               (STATISTIQUE_ET_TEMPS,nom_ref,VECTEUR);
             TypeQuelconque typQ(enuType,X1,grand_courant);
             statistique_t_typeQuel(ii) = (typQ);
             // et on ajoute une grandeur globale qui sera indexée par le nom de référence
             ParaGlob::param->Ajout_grandeur_consultable(&typQ,nom_ref);
             // idem pour la grandeur à t
             string nom_ref_t = nom_ref + "__t_";
             Grandeur_Vecteur_Nommer grand_courant_t(nom_ref_t,dim_necessaire,fct);
             // on ajoute éventuellement un TypeQuelconque_enum_etendu s'il n'existe pas
             // et on récupère un exemplaire
             TypeQuelconque_enum_etendu enuType_t =
                     TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
                               (STATISTIQUE_ET_TEMPS,nom_ref_t,VECTEUR);
             TypeQuelconque typQ_t(enuType_t,X1,grand_courant_t);
             statistique_t_typeQuel_t(ii) = (typQ_t); // stockage interne à LesMaillages
             // et on ajoute une grandeur globale qui sera indexée par le nom de référence
             ParaGlob::param->Ajout_grandeur_consultable(&typQ_t,nom_ref_t);
           };
        bloc.Change_nom(4,nom_ref); // on indique le nom de référencement global
//           // 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 = poi->Complete(bloc,lesFonctionsnD);
//                if (poi == NULL)
//                  { // cas d'un probleme
//                    cout << "\n erreur l'integration de ";bloc.Affiche();
//                    cout << " n'est pas adapte a l\'element ";
//                    poi = & Element_LesMaille(nnn,nbb);
//                    cout << "\n element " << poi->Geometrie() << poi->Interpolation();
//                    cout << "\n LesMaillages::Completer( etc ... " << endl;
//                    Sortie(1);
//                  };
//               };
     };
      


    // cas des tableaux de ddl pour les noeuds
//    InitPositionAssemblage(nb_assemb);
  };

// ramene le nombre total de ddl du pb
int LesMaillages::NbTotalDdlActifs() const
  { // init du nombre de ddl actifs du pb
    int nb = 0;
    // puis boucle sur les maillages et les noeuds
    for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
      for (int i2 = 1; i2 <= nbnoeudmax; i2++)
        nb += Noeud_LesMaille(i1,i2).Nombre_var_ddl_actives(); 
      } 
    return nb;        
   };
    
// ramene le nombre total de ddl actifs du pb
// pour un type de ddl donné, dans le cas de type
// vectoriel on cumule les ddl de l'ensemble de la dimension
int LesMaillages::NbTotalDdlActifs(Enum_ddl enum_ddl) const
  { // init du nombre de ddl actifs du pb
    int nb = 0;
    // puis boucle sur les maillages et les noeuds
    for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
      for (int i2 = 1; i2 <= nbnoeudmax; i2++)
        nb += Noeud_LesMaille(i1,i2).Nombre_var_ddl_actives(enum_ddl); 
      } 
    return nb;        
   };
    
// ramene le nombre total de points d'intégration correspondant à un ddl donné
int LesMaillages::NbTotalPtInteg(Enum_ddl enum_ddl) const
  { // init du nombre de points d'intégration
    int nb = 0;
    // puis boucle sur les maillages et les éléments
    for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { int nbelmax = tabMaillage(i1)->Nombre_element();
      for (int i2 = 1; i2 <= nbelmax; i2++)
        nb += Element_LesMaille_const(i1,i2).NbPtInteg(enum_ddl); 
      } 
    return nb;        
   };
    
// ramene le nombre total de grandeurs génératrices, calculées aux points d'intégrations,
//  correspondant à un ddl donné.
int LesMaillages::NbTotalGrandeursGeneratrices(Enum_ddl enum_ddl) const
  { // init du nombre de grandeurs génératrices
    int nb = 0;
    // puis boucle sur les maillages et les éléments
    for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { int nbelmax = tabMaillage(i1)->Nombre_element();
      for (int i2 = 1; i2 <= nbelmax; i2++)
      	{ // on récupère le nombre de points d'intégrations
      	  int nbptinteg = Element_LesMaille_const(i1,i2).NbPtInteg(enum_ddl);
      	  // on récupère le nombre de grandeurs génératrices pour le ddl
      	  int nbGG = Element_LesMaille_const(i1,i2).NbGrandeurGene(enum_ddl);
      	  // calcul
      	  nb += nbptinteg * nbGG;
      	}
      } 
    return nb;        
   };		 
		 		 
//récupération d'une grandeur vectoriel de dimension, la dimension
// de l'espace, défini au noeud et transféré dans un vecteur global
// qui cumule de manière séquentielle toutes les grandeurs
// en entrée : enum_ddl donne le type de la grandeur à récupérer
// en fait de la première composante
// duree : indique à quel temps doit s'effectuer le transfert, t=0 ou t ou tdt
// enum_actif : le transfert s'effectue que si le ddl enum_actif est actif
// ce qui permet la différentiation entre les différents ddl
// vect : est le vecteur global de stockage qui normalement a été 
// au préalable dimensionné avec NbTotalDdlActifs(Enum_ddl enum_ddl)
// Important: pour chaque famille de ddl, les ddl sont classés de manière croissante, ce qui signifie
//  que c'est l'ordre des pointeurs d'assemblage si et seulement si, ces ddl ont été rangés dans les noeuds
//  au préalable 
// en retour : une référence sur vect
Vecteur & LesMaillages::Vect_loc_vers_glob(Enum_dure duree,Enum_ddl enum_actif
                                           ,Vecteur& vect,Enum_ddl enum_ddl,const Nb_assemb& nb_casAssemb)
{ // recup de la dimension
  int dimen = ParaGlob::Dimension();
  // dans le cas axisymétrique il n'y a pas de variation suivant le dernier axe
  if (ParaGlob::AxiSymetrie())
    dimen--;
  // 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);
          // on regarde si le ddl existe et que le ddl actif est actif
          if ((noo->Existe_ici(enum_ddl)) && (noo->En_service(enum_actif))
                                          && (noo->UneVariable(enum_actif)))
           {int iglob = 1+noo->PosiAssemb(nb_casAssemb.n);
            // dans le cas où enum_ddl == X1, on regarde s'il ne faut pas associer l'épaisseur
            // l'épaisseur n'est associée que si elle est une variable
            int decal = 0;
            switch (duree)
               { case TEMPS_0   :
                   { for (int ii=1; ii<= dimen; ii++,decal++)
                       vect(iglob+decal) = noo->Valeur_0(Enum_ddl(ii-1 + enum_ddl) );
                     if ((enum_ddl == X1) &&  noo->Existe_ici(EPAIS) && (noo->UneVariable(EPAIS)))
                       {vect(iglob+decal) = noo->Valeur_0(EPAIS);decal++;};
                     break;
                    }   
                 case TEMPS_t   : 
                   { for (int ii=1; ii<= dimen; ii++,decal++)
                       vect(iglob+decal) = noo->Valeur_t(Enum_ddl(enum_ddl + ii-1));
                     if ((enum_ddl == X1) &&  noo->Existe_ici(EPAIS) && (noo->UneVariable(EPAIS)))
                       {vect(iglob+decal) = noo->Valeur_t(EPAIS);decal++;};
                     break;
                    }   
                 case TEMPS_tdt : 
                   { for (int ii=1; ii<= dimen; ii++,decal++)
                       vect(iglob+decal) = noo->Valeur_tdt(Enum_ddl(enum_ddl + ii-1));
                     if ((enum_ddl == X1) &&  noo->Existe_ici(EPAIS) && (noo->UneVariable(EPAIS)))
                       {vect(iglob+decal) = noo->Valeur_tdt(EPAIS);decal++;};
                     break;
                    }   
                 default :
                    cout << "\nErreur : valeur incorrecte du type Enum_dure !\n";
                    cout << "LesMaillages::Vect_loc_vers_glob(Enum_dure... \n";
                    Sortie(1);
              }
           };
        }
   }
 return vect;
};

// fonction inverse de Vect_loc_vers_glob, il s'agit ici de passer
// de la grandeur globale aux grandeurs locale
void LesMaillages::Vect_glob_vers_local(Enum_dure duree,Enum_ddl enum_actif
                                        ,const Vecteur& vect,Enum_ddl enum_ddl,const Nb_assemb& nb_casAssemb)
{ // recup de la dimension
  int dimen = ParaGlob::Dimension();
  // dans le cas axisymétrique il n'y a pas de variation suivant le dernier axe
  if (ParaGlob::AxiSymetrie())
    dimen--;
    
  // 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 ddl existe et que le ddl actif est actif
          if ((noo->Existe_ici(enum_ddl)) && (noo->En_service(enum_actif))
                                          && (noo->UneVariable(enum_actif)))
           {int iglob = 1+noo->PosiAssemb(nb_casAssemb.n);
            // dans le cas où enum_ddl == X1, on regarde s'il ne faut pas associer l'épaisseur
            // l'épaisseur n'est associée que si elle est une variable
            int decal = 0;
            switch (duree)
               { case TEMPS_0   :
                   { for (int ii=1; ii<= dimen; ii++,decal++)
                       noo->Change_val_0(Enum_ddl(ii-1 + enum_ddl),vect(iglob+decal));
                     if ((enum_ddl == X1) &&  noo->Existe_ici(EPAIS) && (noo->UneVariable(EPAIS)))
                       {noo->Change_val_0(EPAIS,vect(iglob+decal));decal++;};
                     break;
                    }   
                 case TEMPS_t   : 
                   { for (int ii=1; ii<= dimen; ii++,decal++)
                       noo->Change_val_t(Enum_ddl(ii-1 + enum_ddl),vect(iglob+decal));
                     if ((enum_ddl == X1) &&  noo->Existe_ici(EPAIS) && (noo->UneVariable(EPAIS)))
                       {noo->Change_val_t(EPAIS,vect(iglob+decal));decal++;};
                     break;
                    }   
                 case TEMPS_tdt : 
                   { for (int ii=1; ii<= dimen; ii++,decal++)
                       noo->Change_val_tdt(Enum_ddl(ii-1 + enum_ddl),vect(iglob+decal));
                     if ((enum_ddl == X1) &&  noo->Existe_ici(EPAIS) && (noo->UneVariable(EPAIS)))
                       {noo->Change_val_tdt(EPAIS,vect(iglob+decal));decal++;};
                     break;
                    }   
                 default :
                   cout << "\nErreur : valeur incorrecte du type Enum_dure !\n";
                   cout << "LesMaillages::Vect_glob_vers_local(Enum_dure... \n";
                   Sortie(1);
              }; // fin du switch
           };
        }; // fin de la boucle sur les noeuds d'un maillage
    }; // fin de la boucle sur les maillages
};

 
//récupération d'une grandeur vectoriel de dimension, la dimension
// de l'espace, défini au noeud et transféré dans un vecteur global
// qui cumule de manière séquentielle toutes les grandeurs
// en entrée : tab_enum_ddl donne le tableau des type de la grandeur à récupérer
// en fait de la première composante
// duree : indique à quel temps doit s'effectuer le transfert, t=0 ou t ou tdt
// tab_enum_actif : pour chaque élément tab_enum_ddl(i), le transfert s'effectue que si
// le ddl tab_enum_actif(i) est actif
// ce qui permet la différentiation entre les différents ddl
// vect : est le vecteur global de stockage qui normalement a été 
// au préalable dimensionné avec somme des NbTotalDdlActifs(Enum_ddl enum_ddl), avec enum_ddl
// qui balaie l'ensemble des éléments de tab_enum_ddl
// Important: pour chaque famille de ddl, les ddl sont classés de manière croissante, ce qui signifie
//  que c'est l'ordre des pointeurs d'assemblage si et seulement si, ces ddl ont été rangés dans les noeuds
//  au préalable 
// en retour : une référence sur vect
Vecteur & LesMaillages::Vect_loc_vers_glob(Enum_dure duree,const Tableau <Enum_ddl>& tab_enum_actif
                                           ,Vecteur& vect,const Tableau <Enum_ddl>& tab_enum_ddl
                                           ,const Nb_assemb& nb_casAssemb)
{ // recup de la dimension
  int dimen = ParaGlob::Dimension();
  // dans le cas axisymétrique il n'y a pas de variation suivant le dernier axe
  if (ParaGlob::AxiSymetrie())
    dimen--;
 
  int taill_tab = tab_enum_ddl.Taille();
  #ifdef MISE_AU_POINT
  if (taill_tab != tab_enum_actif.Taille())
   {cout << "\n *** erreur , la dimension: "<<tab_enum_actif.Taille()
         <<" du tableau Tableau <Enum_ddl> tab_enum_actif est differente "
         << " de la taille: "<<taill_tab <<" du tableau Tableau <Enum_ddl> tab_enum_ddl "
         << "\n LesMaillages::Vect_loc_vers_glob( ..."<<endl;
    Sortie(1);
   };
  #endif
  // 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);
          // on boucle sur les ddl
          for (int i=1;i<= taill_tab;i++)
           {Enum_ddl enum_actif=tab_enum_actif(i);
            Enum_ddl enum_ddl = tab_enum_ddl(i);
            // on regarde si le ddl existe et que le ddl actif est actif
            if ((noo->Existe_ici(enum_ddl)) && (noo->En_service(enum_actif))
                                            && (noo->UneVariable(enum_actif)))
              {int iglob = 1+noo->PosiAssemb(nb_casAssemb.n);
               // dans le cas où enum_ddl == X1, on regarde s'il ne faut pas associer l'épaisseur
               // l'épaisseur n'est associée que si elle est une variable
               int decal = 0;
               switch (duree)
                  { case TEMPS_0   :
                      { for (int ii=1; ii<= dimen; ii++,decal++)
                          vect(iglob+decal) = noo->Valeur_0(Enum_ddl(ii-1 + enum_ddl) );
                        if ((enum_ddl == X1) &&  noo->Existe_ici(EPAIS) && (noo->UneVariable(EPAIS)))
                          {vect(iglob+decal) = noo->Valeur_0(EPAIS);decal++;};
                        break;
                       }
                    case TEMPS_t   :
                      { for (int ii=1; ii<= dimen; ii++,decal++)
                          vect(iglob+decal) = noo->Valeur_t(Enum_ddl(enum_ddl + ii-1));
                        if ((enum_ddl == X1) &&  noo->Existe_ici(EPAIS) && (noo->UneVariable(EPAIS)))
                          {vect(iglob+decal) = noo->Valeur_t(EPAIS);decal++;};
                        break;
                       }
                    case TEMPS_tdt :
                      { for (int ii=1; ii<= dimen; ii++,decal++)
                          vect(iglob+decal) = noo->Valeur_tdt(Enum_ddl(enum_ddl + ii-1));
                        if ((enum_ddl == X1) &&  noo->Existe_ici(EPAIS) && (noo->UneVariable(EPAIS)))
                          {vect(iglob+decal) = noo->Valeur_tdt(EPAIS);decal++;};
                        break;
                       }
                    default :
                      cout << "\nErreur : valeur incorrecte du type Enum_dure !\n";
                      cout << "LesMaillages::Vect_loc_vers_glob(Enum_dure... \n";
                      Sortie(1);
                  };
              };
           };
        };
    }
  return vect;
};

// fonction inverse de Vect_loc_vers_glob, il s'agit ici de passer
// de la grandeur globale aux grandeurs locale
void LesMaillages::Vect_glob_vers_local(Enum_dure duree,const Tableau <Enum_ddl>& tab_enum_actif
                                    ,const Vecteur& vect,const Tableau <Enum_ddl>& tab_enum_ddl
                                    ,const Nb_assemb& nb_casAssemb)
{ // recup de la dimension
  int dimen = ParaGlob::Dimension();
  // dans le cas axisymétrique il n'y a pas de variation suivant le dernier axe
  if (ParaGlob::AxiSymetrie())
    dimen--;
  int ivect = 1; // position global  

  int taill_tab = tab_enum_ddl.Taille();
  #ifdef MISE_AU_POINT
  if (taill_tab != tab_enum_actif.Taille())
   {cout << "\n *** erreur , la dimension: "<<tab_enum_actif.Taille()
         <<" du tableau Tableau <Enum_ddl> tab_enum_actif est differente "
         << " de la taille: "<<taill_tab <<" du tableau Tableau <Enum_ddl> tab_enum_ddl "
         << "\n LesMaillages::Vect_glob_vers_local( ..."<<endl;
    Sortie(1);
   };
  #endif
  // 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 boucle sur les ddl
          for (int i=1;i<= taill_tab;i++)
           {Enum_ddl enum_actif=tab_enum_actif(i);
            Enum_ddl enum_ddl = tab_enum_ddl(i);
            int iglob = 1+noo->PosiAssemb(nb_casAssemb.n);
            // on regarde si le ddl existe et que le ddl actif est actif
            if ((noo->Existe_ici(enum_ddl)) && (noo->En_service(enum_actif))
                                            && (noo->UneVariable(enum_actif)))
             {// dans le cas où enum_ddl == X1, on regarde s'il ne faut pas associer l'épaisseur
              // l'épaisseur n'est associée que si elle est une variable
              int decal = 0;
              switch (duree)
                 { case TEMPS_0   :
                     { for (int ii=1; ii<= dimen; ii++,decal++)
                         noo->Change_val_0(Enum_ddl(ii-1 + enum_ddl),vect(iglob+decal));
                       if ((enum_ddl == X1) &&  noo->Existe_ici(EPAIS) && (noo->UneVariable(EPAIS)))
                         {noo->Change_val_0(EPAIS,vect(iglob+decal));decal++;};
                       break;
                      }   
                   case TEMPS_t   : 
                     { for (int ii=1; ii<= dimen; ii++,decal++)
                         noo->Change_val_t(Enum_ddl(ii-1 + enum_ddl),vect(iglob+decal));
                       if ((enum_ddl == X1) &&  noo->Existe_ici(EPAIS) && (noo->UneVariable(EPAIS)))
                         {noo->Change_val_t(EPAIS,vect(iglob+decal));decal++;};
                       break;
                      }   
                   case TEMPS_tdt : 
                     { for (int ii=1; ii<= dimen; ii++,decal++)
                         noo->Change_val_tdt(Enum_ddl(ii-1 + enum_ddl),vect(iglob+decal));
                       if ((enum_ddl == X1) &&  noo->Existe_ici(EPAIS) && (noo->UneVariable(EPAIS)))
                         {noo->Change_val_tdt(EPAIS,vect(iglob+decal));decal++;};
                       break;
                      }   
                   default :
                     cout << "\nErreur : valeur incorrecte du type Enum_dure !\n";
                     cout << "LesMaillages::Vect_glob_vers_local(Enum_dure... \n";
                     Sortie(1);
                 };
             };
           };
        };
    };
};



//récupération d'une grandeur scalaire 
// défini au noeud et transféré dans un vecteur global
// qui cumule de manière séquentielle toutes les grandeurs
// en entrée : enum_ddl donne le type de la grandeur à récupérer
// duree : indique à quel temps doit s'effectuer le transfert, t=0 ou t ou tdt
// enum_actif : le transfert s'effectue que si le ddl enum_actif est actif
// ce qui permet la différentiation entre les différents ddl
// vect : est le vecteur global de stockage qui a la dimension du vecteur solution
// pour le cas d'assemblage nb_casAssemb
// en retour : une référence sur vect
Vecteur & LesMaillages::Scalaire_loc_vers_glob(Enum_dure duree,Enum_ddl enum_actif
                                                 ,Vecteur& vect,Enum_ddl enum_ddl
                                                 ,const Nb_assemb& nb_casAssemb)
{ // 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);
          if (noo->Existe_ici(enum_actif)) // ellimine les noeuds non concernés
           {// on regarde si le ddl existe et que le ddl actif est actif
            if ((noo->Existe_ici(enum_ddl)) && (noo->En_service(enum_actif))
                                            && (noo->UneVariable(enum_actif)))
             {int iglob = 1+noo->PosiAssemb(nb_casAssemb.n);
              switch (duree)
               { case TEMPS_0   : {vect(iglob) = noo->Valeur_0(enum_ddl); break;}
                 case TEMPS_t   : {vect(iglob) = noo->Valeur_t(enum_ddl); break;}
                 case TEMPS_tdt : {vect(iglob) = noo->Valeur_tdt(enum_ddl); break;}
                 default :
                  cout << "\nErreur : valeur incorrecte du type Enum_dure !\n";
                  cout << "LesMaillages::Scalaire_loc_vers_glob(Enum_dure... \n";
                  Sortie(1);
                }
             };
           }
         } 
      }
   return vect;          
 };

// fonction inverse de Scalaire_loc_vers_glob, il s'agit ici de passer
// de la grandeur globale à la grandeur locale
void LesMaillages::Scalaire_glob_vers_local(Enum_dure duree,Enum_ddl enum_actif
                                                 ,Vecteur& vect,Enum_ddl enum_ddl
                                                 ,const Nb_assemb& nb_casAssemb)
{ // 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);
          if (noo->Existe_ici(enum_actif)) // élimine les noeuds non concernés
           {// on regarde si le ddl existe et que le ddl actif est actif
            if ((noo->Existe_ici(enum_ddl)) && (noo->En_service(enum_actif))
                                            && (noo->UneVariable(enum_actif)))
             {int iglob = 1+noo->PosiAssemb(nb_casAssemb.n);
              switch (duree)
               { case TEMPS_0   : {noo->Change_val_0(enum_ddl,vect(iglob)); break;}
                 case TEMPS_t   : {noo->Change_val_t(enum_ddl,vect(iglob)); break;}
                 case TEMPS_tdt : {noo->Change_val_tdt(enum_ddl,vect(iglob)); break;}
                 default :
                  cout << "\nErreur : valeur incorrecte du type Enum_dure !\n";
                  cout << "LesMaillages::Scalaire_glob_vers_local(Enum_dure... \n";
                  Sortie(1);
               };
             }
           }
         } 
      }       
   }; 

//  fonctions idem que pour les ddl : mais pour un Ddl_etendu
Vecteur & LesMaillages::Scalaire_loc_vers_glob(Enum_ddl enum_actif
                      ,Vecteur& vect,const Ddl_enum_etendu& enum_ddl_etend
                      ,const Nb_assemb& nb_casAssemb)
{ // 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);
          if (noo->Existe_ici(enum_actif)) // ellimine les noeuds non concernés
            // on regarde si le ddl existe et que le ddl actif est actif
           {int iglob = 1+noo->PosiAssemb(nb_casAssemb.n);
            if ((noo->Existe_ici_ddlEtendu(enum_ddl_etend)) && (noo->En_service(enum_actif)))
                vect(iglob) = (noo->DdlEtendue(enum_ddl_etend)).ConstValeur();
           }
         } 
      }
   return vect;          
 };

//  fonctions idem que pour les ddl : mais pour un Ddl_etendu
void LesMaillages::Scalaire_glob_vers_local(Enum_ddl enum_actif
                        ,Vecteur& vect,const Ddl_enum_etendu& enum_ddl_etend
                        ,const Nb_assemb& nb_casAssemb)
{
//  #ifdef MISE_AU_POINT
//  // on vérifie qu'il y a le bon nombre d'informations
//  int nb_info = 0;
//  for (int i1 = 1; i1<= nbMaillageTotal; i1++)
//     nb_info += tabMaillage(i1)->Nombre_noeud();
//  if (vect.Taille() != nb_info)
//     {cout << "\nerreur en affectation de grandeurs vers les maillages: vecteur globale ";
//      cout << " dim vecteur = " << vect.Taille() << " alorq qu'il faut  " << nb_info <<'\n';
//      cout << "\n LesMaillages::Scalaire_glob_vers_local(Enum_ddl enum_actif" << endl;
//      Sortie(1);
//     };
//  #endif
  // 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);
          int iglob = 1+noo->PosiAssemb(nb_casAssemb.n);
          if ((noo->Existe_ici_ddlEtendu(enum_ddl_etend)) && (noo->En_service(enum_actif)))
          	  // on récupère le ddl étendu pour le modifier
          	  (noo->ModifDdl_etendu(enum_ddl_etend)).Valeur() = vect(iglob);
         } 
      }       
   }; 

// fonctions idem que pour les ddl_etendu : mais pour une grandeur quelconque
Vecteur & LesMaillages::Quelconque_loc_vers_glob
                     (Enum_ddl enum_actif,Vecteur& vect,const TypeQuelconque& type_generique
                     ,const Nb_assemb& nb_casAssemb)
//Vecteur & LesMaillages::Scalaire_loc_vers_glob(Enum_ddl enum_actif
//                      ,Vecteur& vect,const Ddl_enum_etendu& enum_ddl_etend)
{ int dim = ParaGlob::Dimension(); // dimension du pb
  // 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);
          int iglob = 1+noo->PosiAssemb(nb_casAssemb.n);
          // on regarde si le conteneur existe, si oui on transfert, si non, on passe les valeurs
          TypeQuelconque_enum_etendu enuq = type_generique.EnuTypeQuelconque();
          if (noo->Existe_ici(enum_actif)) // ellimine les noeuds non concernés
           {if ((noo->Existe_ici(enuq)) && (noo->En_service(enum_actif)))
             {// dépend du type de grandeur
              EnumTypeGrandeur enuGrandeur = type_generique.EnuTypeGrandeur();
              switch (enuGrandeur)
               {case COORDONNEE:
                 {TypeQuelconque& typQ = noo->ModifGrandeur_quelconque(enuq); // récup du conteneur du noeud
                  // récup de la grandeur
                  Grandeur_coordonnee* gcoor = (Grandeur_coordonnee*) typQ.Grandeur_pointee();
                  Coordonnee& conoe = *(gcoor->ConteneurCoordonnee()); // les coordonnées
                  switch (dim) // on rempli le vecteur
                   { case 3: vect(iglob)=conoe(3);iglob++;
                     case 2: vect(iglob)=conoe(2);iglob++;
                     case 1: vect(iglob)=conoe(1);iglob++;
                   };
                 }
                default:
                 cout << "\n ** erreur, pour l'instant le transfert depuis les noeuds de "
                      << (enuq.NomPlein()) << " n'est pas implante ... le demander !! "
                      << "\n LesMaillages::Quelconque_loc_vers_glob(..."<<endl;
                 Sortie(1);
               }
             }
//            else //on ne fait que décaler le pointeur dans le vecteur pour la suite
//              { ivect += dim;};
           };
        };
    };
   return vect;          
 };

// fonctions idem que pour les ddl_etendu : mais pour une grandeur quelconque
void LesMaillages::Quelconque_glob_vers_local
                 (Enum_ddl enum_actif,Vecteur& vect,const TypeQuelconque& type_generique
                 ,const Nb_assemb& nb_casAssemb)
{ int dim = ParaGlob::Dimension(); // dimension du pb
  if(ParaGlob::AxiSymetrie())
    dim--; // en axisymétrie on récupère uniquement les forces en x et y
  int nb_val_typeQuelconque = type_generique.NbMaxiNumeroOrdre();
  // 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);
          // on regarde si le conteneur existe, si oui on transfert, si non, on passe les valeurs
          TypeQuelconque_enum_etendu enuq = type_generique.EnuTypeQuelconque();
          if (noo->Existe_ici(enum_actif)) // ellimine les noeuds non concernés
           {int iglob = 1+noo->PosiAssemb(nb_casAssemb.n);
////-------- debug
//if (!((noo->Existe_ici(enuq)) && (noo->En_service(enum_actif))))
// {cout << "\n debug LesMaillages::Quelconque_glob_vers_local( ";
//  cout << "\n enuq: " << enuq.NomPlein()<< " noo->Existe_ici(enuq) "<< (noo->Existe_ici(enuq))
//      << "\n enum_actif: " << Nom_ddl(enum_actif) << " noo->En_service(enum_actif) " << noo->En_service(enum_actif)
//      << flush;
// };
////-------- fin debug

            if ((noo->Existe_ici(enuq)) && (noo->En_service(enum_actif)))
            {// dépend du type de grandeur
             EnumTypeGrandeur enuGrandeur = type_generique.EnuTypeGrandeur();
             switch (enuGrandeur)
              {case COORDONNEE:
                {TypeQuelconque& typQ = noo->ModifGrandeur_quelconque(enuq); // récup du conteneur du noeud
                 // récup de la grandeur
                 Grandeur_coordonnee* gcoor = (Grandeur_coordonnee*) typQ.Grandeur_pointee();
                 Coordonnee& conoe = *(gcoor->ConteneurCoordonnee()); // les coordonnées
                 switch (dim) // on rempli les coordonnées
                  { case 3: conoe(3)=vect(iglob+2);
                    case 2: conoe(2)=vect(iglob+1);
                    case 1: conoe(1)=vect(iglob);
                  };
                 break;
                }
               default:
                cout << "\n ** erreur, pour l'instant le transfert vers les noeuds de "
                     << (enuq.NomPlein()) << " n'est pas implante ... le demander !! "
                     << "\n LesMaillages::Quelconque_glob_vers_local(..."<<endl;
                Sortie(1);
              }
             }
//            else //on ne fait que décaler le pointeur dans le vecteur pour la suite
//             { ivect += nb_val_typeQuelconque;};
           };
        };
    };
}; 

// retourne la liste des types de ddl principaux actuellement utilisé
// aux noeuds pour chaque maillage, la liste est exhaustive
// elle contiend tous les types au moins une fois utilisée
// cela ne signifie pas que le ddl en question soit présent
// pour tous les noeud du maillage considéré
// - le tableau de retour est indicé par le numéro de maillage correspondant
// - il y a une liste par maillage
Tableau <List_io <Ddl_enum_etendu> > LesMaillages::Les_type_de_ddl_par_noeud(bool absolue)
  { // def de la liste de retour
    Tableau <List_io <Ddl_enum_etendu> >  tab_ret_enum(nbMaillageTotal);
    // on boucle sur les maillages
    for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { // vecteur intermédiaire dont la taille peut augmenter
      List_io <Enum_ddl> tab_enu_final;
      // on boucle sur les noeuds
      int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
      for (int i2 = 1; i2 <= nbnoeudmax; i2++)
        { // recup du noeud
          Noeud * noo = & Noeud_LesMaille(i1,i2);
          // recup du tableau de type de ddl associé
          List_io <Enum_ddl> tab_enum_ddl(noo->Les_type_de_ddl(absolue));
          tab_enum_ddl.sort(); // ordonne la liste
          tab_enu_final.merge(tab_enum_ddl); // ajout de la liste
          tab_enu_final.unique(); // supprime les doublons
         };
      // mise à jour du tableau global 
		    List_io <Ddl_enum_etendu> tab_enu_etendu_final;
		    List_io <Ddl_enum_etendu> tab_inter =  Ddl_enum_etendu::TransfoList_io(tab_enu_final);
		    tab_inter.sort();
		    tab_enu_etendu_final.merge(tab_inter);tab_enu_etendu_final.unique();
      tab_ret_enum(i1) = tab_enu_etendu_final; 
     }
    return tab_ret_enum; // retour du tableau        
  };		

// retourne la liste des types de ddl étendu actuellement utilisé
// aux noeuds pour chaque maillage, la liste est exhaustive
// elle contiend tous les types au moins une fois utilisée
// cela ne signifie pas que le ddl en question soit présent
// pour tous les noeud du maillage considéré
// - le tableau de retour est indicé par le numéro de maillage correspondant
// - il y a une liste par maillage
Tableau <List_io <Ddl_enum_etendu> > LesMaillages::Les_type_de_ddl_etendu_par_noeud(bool absolue)
  { // def de la liste de retour
    Tableau <List_io <Ddl_enum_etendu> >  tab_ret_enum(nbMaillageTotal);
    // on boucle sur les maillages
    for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { // vecteur intermédiaire dont la taille peut augmenter pour les ddl étendus
		    List_io <Ddl_enum_etendu> tab_enu_etendu_final;
      // on boucle sur les noeuds
      int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
      for (int i2 = 1; i2 <= nbnoeudmax; i2++)
        { // recup du noeud
          Noeud * noo = & Noeud_LesMaille(i1,i2);
			       // recup du tableau de type de ddl  étendues
			       List_io <Ddl_enum_etendu> tab_enum_etendu_ddl(noo->Les_type_de_ddl_etendu( absolue));
          tab_enum_etendu_ddl.sort(); // ordonne la liste
          tab_enu_etendu_final.merge(tab_enum_etendu_ddl); // ajout de la liste
          tab_enu_etendu_final.unique(); // supprime les doublons
         };
      // mise à jour du tableau global 
      tab_ret_enum(i1) = tab_enu_etendu_final; 
     }
    return tab_ret_enum; // retour du tableau        
  };

		
// retourne la liste des types quelconque actuellement utilisé
// aux noeuds pour chaque maillage, la liste est exhaustive
// elle contiend tous les types au moins une fois utilisée
// cela ne signifie pas que le ddl en question soit présent
// pour tous les noeud du maillage considéré
// - le tableau de retour est indicé par le numéro de maillage correspondant
// - il y a une liste par maillage
Tableau <List_io <TypeQuelconque> > LesMaillages::Les_type_de_TypeQuelconque_par_noeud(bool absolue)
  { // def de la liste de retour
    Tableau <List_io <TypeQuelconque> >  tab_ret_enum(nbMaillageTotal);
    // grandeurs de travail
    int dim = ParaGlob::Dimension();
    Coordonnee coor(dim); // un type coordonnee typique
    // maintenant on définit une grandeur typique de type Grandeur_coordonnee
    Grandeur_coordonnee gt(coor);
    TypeQuelconque typQ(VECT_REAC_N,X1,gt);
//    // idem pour la variation de position entre t et t+dt
//    TypeQuelconque typQ2(DELTA_XI,X1,gt);

    // on boucle sur les maillages
    for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { // vecteur intermédiaire dont la taille peut augmenter pour les ddl étendus
		    List_io <TypeQuelconque> tab_enu_etendu_final;
      // on boucle sur les noeuds
      int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
      for (int i2 = 1; i2 <= nbnoeudmax; i2++)
        { // recup du noeud
          Noeud * noo = & Noeud_LesMaille(i1,i2);
			       // recup du tableau de tous les TypeQuelconque disponibles au noeud
			       List_io <TypeQuelconque> tab_enum_etendu_ddl(noo->Les_TypeQuelconque(absolue));

          // --- on rajoute les réactions par défaut
          // sous forme d'un vecteur
          tab_enum_etendu_ddl.push_back(typQ);
//  Pour l'instant ce n'est pas fini donc on met en commentaire, sinon c'est pas clair
// pour l'utilisateur !!
//          // --- on ajoute le delta des positions
//          tab_enum_etendu_ddl.push_back(typQ2);
          // -- on traite
          tab_enum_etendu_ddl.sort(); // ordonne la liste
          tab_enu_etendu_final.merge(tab_enum_etendu_ddl); // ajout de la liste
          tab_enu_etendu_final.unique(); // supprime les doublons
         };
      // mise à jour du tableau global 
      tab_ret_enum(i1) = tab_enu_etendu_final; 
     }
    return tab_ret_enum; // retour du tableau        
  };

    // intro de certains conteneurs internes en relation par exemple avec les demandes de visualisation
    // ou autre
    // exemple: si VECT_REAC_N qui est un type quelconque, a été choisit
    // il faut qu'il soit présent aux noeuds, alors qu'il est alimenter par les ddl pur ...
    // on introduit donc le type quelconque associé
    // NB: le conteneur passé en paramètre ne sert que pour localiser les grandeurs
void LesMaillages::Intro_Conteneurs_internes_noeud_relier_auto_autres_grandeur
                 ( const List_io < TypeQuelconque > & glob_noeud_evol_retenu)
{

  // grandeurs de travail
  int dim = ParaGlob::Dimension();
  Coordonnee coor(dim); // un type coordonnee typique
  // maintenant on définit une grandeur typique de type Grandeur_coordonnee
  Grandeur_coordonnee gt(coor);
  TypeQuelconque typQ2(VECT_REAC_N,X1,gt);
  List_io <TypeQuelconque>::const_iterator il,ilfin=glob_noeud_evol_retenu.end();
  
 
  for (int i= 1;i<= nbMaillageTotal; i++)
    {for (il=glob_noeud_evol_retenu.begin();il != ilfin; il++)
      { TypeQuelconque_enum_etendu enuQ = (*il).EnuTypeQuelconque();

        // on passe en revue les types concernés
        if (enuQ == VECT_REAC_N)
           // il faut alors vérifier que le conteneur existe aux noeuds
           {// on boucle sur les noeuds
            int nbnoeudmax = tabMaillage(i)->Nombre_noeud();
            for (int i2 = 1; i2 <= nbnoeudmax; i2++)
              { // recup du noeud
                Noeud * noo = & Noeud_LesMaille(i,i2);
                if (!(noo->Existe_ici(enuQ)))
                 // cas où on n'a pas le type présent, on l'introduit
                 {noo->AjoutUnTypeQuelconque(typQ2);};
              };
           };
      };
    };

};

    // idem que Intro_Conteneurs_internes_noeud_relier_auto_autres_grandeur
    // mais ciblé en fonction d'un tableau indicé sur les maillages
void LesMaillages::Intro_Conteneurs_internes_noeud_relier_auto_autres_grandeur
                   ( const Tableau < List_io < TypeQuelconque > > & tab_noeud_evol_retenu)
{

  // grandeurs de travail
  int dim = ParaGlob::Dimension();
  Coordonnee coor(dim); // un type coordonnee typique
  // maintenant on définit une grandeur typique de type Grandeur_coordonnee
  Grandeur_coordonnee gt(coor);
  TypeQuelconque typQ2(VECT_REAC_N,X1,gt);
 
  for (int i= 1;i<= nbMaillageTotal; i++)
    {List_io <TypeQuelconque>::const_iterator il,ilfin=tab_noeud_evol_retenu(i).end();
     for (il=tab_noeud_evol_retenu(i).begin();il != ilfin; il++)
      {TypeQuelconque_enum_etendu enuQ = (*il).EnuTypeQuelconque();

       // on passe en revue les types concernés
       if (enuQ == VECT_REAC_N)
         // il faut alors vérifier que le conteneur existe aux noeuds
         {// on boucle sur les noeuds
          int nbnoeudmax = tabMaillage(i)->Nombre_noeud();
          for (int i2 = 1; i2 <= nbnoeudmax; i2++)
            { // recup du noeud
              Noeud * noo = & Noeud_LesMaille(i,i2);
              if (!(noo->Existe_ici(enuQ)))
               // cas où on n'a pas le type présent, on l'introduit
               {noo->AjoutUnTypeQuelconque(typQ2);};
            };
         };
      };
    };

};

// retourne la liste des types de ddl actuellement utilisé
// aux éléments pour chaque maillage, la liste est exhaustive
// elle contiend tous les types au moins une fois utilisée
// cela ne signifie pas que le ddl en question soit présent
// pour tous les éléments du maillage considéré
// - le tableau de retour est indicé par le numéro de maillage correspondant
// - il y a une liste par maillage
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
Tableau <List_io <Ddl_enum_etendu> > LesMaillages::Les_type_de_ddl_par_element(bool absolue)
  { // def de la liste de retour
    Tableau <List_io <Ddl_enum_etendu> >  tab_ret_enum(nbMaillageTotal);
    // on boucle sur les maillages
    for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { // vecteur intermédiaire dont la taille peut augmenter
      List_io <Ddl_enum_etendu> tab_enu_final;
      // on définit une liste de signature d'élément, ce qui permet de tester que les types d'éléments différents
      list <Element::Signature> list_signature_elem;
      // on boucle sur les elements 
      int nbelementmax = tabMaillage(i1)->Nombre_element();
      for (int i2 = 1; i2 <= nbelementmax; i2++)
        { // recup du element
          Element * nee = & Element_LesMaille(i1,i2);
          // recup du tableau de type de ddl associé
          // on regarde si un élément de même type n'a pas déjà été considéré
          if (find(list_signature_elem.begin(),list_signature_elem.end(),nee->Signature_element())==list_signature_elem.end())
           { // nouveau type d'élément , on récupère les données particulières
             List_io <Ddl_enum_etendu> tab_enum_ddl(nee->Les_type_de_ddl_internes(absolue));
             tab_enu_final.sort(); // ordonne la liste
             tab_enu_final.merge(tab_enum_ddl); // ajout de la liste
             tab_enu_final.unique(); // supprime les doublons
             // on ajoute la signature
             list_signature_elem.push_back(nee->Signature_element());
            };
         } 
      // mise à jour du tableau global  
      tab_ret_enum(i1) = tab_enu_final;   
      }
    return tab_ret_enum; // retour du tableau        
    };
    		
// retourne la liste des grandeurs évoluées interne actuellement utilisés
// par les éléments, c'est-à-dire comme les ddl mais directement sous forme de vecteur, tenseurs ..., 
// la liste est exhaustive, elle contiend tous les types au moins une fois utilisée
// cela ne signifie pas que la donnée particulière en question soit présent
// pour tous les éléments du maillage considéré
// - le tableau de retour est indicé par le numéro de maillage correspondant
// - il y a une liste par maillage
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
Tableau <List_io <TypeQuelconque> > LesMaillages::Les_type_de_donnees_evolues_internes_par_element(bool absolue)
  { // def de la liste de retour
    Tableau <List_io <TypeQuelconque> >  tab_ret_enum(nbMaillageTotal);
    // on définit une liste de signature d'élément, ce qui permet de tester que les types d'éléments différents
    list <Element::Signature> list_signature_elem;
    // on boucle sur les maillages
    for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { // liste intermédiaire dont la taille peut augmenter
      List_io <TypeQuelconque> tab_enu_final;
      list_signature_elem.clear();
      // on boucle sur les elements 
      int nbelementmax = tabMaillage(i1)->Nombre_element();
      for (int i2 = 1; i2 <= nbelementmax; i2++)
        { // recup de  l'element
          Element * nee = & Element_LesMaille(i1,i2);
          // on regarde si un élément de même type n'a pas déjà été considéré
          if (find(list_signature_elem.begin(),list_signature_elem.end(),nee->Signature_element())==list_signature_elem.end())
           { // nouveau type d'élément , on récupère les données particulières
             // les opérations qui suivent sont assez longues mais normalement n'arrives pas souvent
             // recup du tableau de type de données particulières associées
             List_io <TypeQuelconque> tab_enum_parti(nee->Les_type_evolues_internes(absolue));
             tab_enu_final.sort(); // ordonne la liste
             tab_enum_parti.sort(); // idem la nouvelle
             tab_enu_final.merge(tab_enum_parti); // ajout de la liste
             tab_enu_final.unique(); // supprime les doublons
             // on ajoute la signature
             list_signature_elem.push_back(nee->Signature_element());
            };
         }; 
      // mise à jour du tableau global  
      tab_ret_enum(i1) = tab_enu_final;   
      };
    return tab_ret_enum; // retour du tableau        
    };		
    		
// retourne la liste des types de données particulières actuellement utilisés
// aux éléments pour chaque maillage, la liste est exhaustive
// elle contiend tous les types au moins une fois utilisée
// cela ne signifie pas que la donnée particulière en question soit présent
// pour tous les éléments du maillage considéré
// - le tableau de retour est indicé par le numéro de maillage correspondant
// - il y a une liste par maillage
Tableau <List_io <TypeQuelconque> > LesMaillages::Les_type_de_donnees_particulieres_par_element(bool absolue)
  { // def de la liste de retour
    Tableau <List_io <TypeQuelconque> >  tab_ret_enum(nbMaillageTotal);
    // on boucle sur les maillages
    for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { // vecteur intermédiaire dont la taille peut augmenter
      List_io <TypeQuelconque> tab_enu_final;
      // on définit une liste de signature d'élément, ce qui permet de tester que les types d'éléments différents
      list <Element::Signature> list_signature_elem;
      // on boucle sur les elements
      int nbelementmax = tabMaillage(i1)->Nombre_element();
      for (int i2 = 1; i2 <= nbelementmax; i2++)
        { // recup du element
          Element * nee = & Element_LesMaille(i1,i2);
          // on regarde si un élément de même type n'a pas déjà été considéré
          if (find(list_signature_elem.begin(),list_signature_elem.end(),nee->Signature_element())==list_signature_elem.end())
           { // nouveau type d'élément , on récupère les données particulières
             // les opérations qui suivent sont assez longues mais normalement n'arrives pas souvent
             // recup du tableau de type de données particulières associées
             List_io <TypeQuelconque> tab_enum_parti(nee->Les_types_particuliers_internes(absolue));
             tab_enu_final.sort(); // ordonne la liste
             tab_enu_final.merge(tab_enum_parti); // ajout de la liste
             tab_enu_final.unique(); // supprime les doublons
             // on ajoute la signature
             list_signature_elem.push_back(nee->Signature_element());
            };
         }; 
      // mise à jour du tableau global  
      tab_ret_enum(i1) = tab_enu_final;   
      };
//----- debug
// cout << "\n debug LesMaillages::Les_type_de_donnees_particulieres_par_element "
//      << tab_ret_enum << endl;
// ------ fin debug
   
   
    return tab_ret_enum; // retour du tableau        
    };		
     
// Au niveau des noeuds: transfert des coordonnées de grandeurs vectorielles à des grandeurs évoluées
// stockée sous forme de grandeurs TypeQuelconque
//  exemple: les réactions qui sont naturellement stockée en composantes
// le principe est que ce passage s'effectue si les conteneurs existent au niveau des noeuds
void LesMaillages::PassageInterneDansNoeud_composantes_vers_vectorielles()
{
  int dim = ParaGlob::Dimension(); // dimension du pb
  if(ParaGlob::AxiSymetrie())
    dim--; // en axisymétrie on récupère uniquement les forces en x et y
  // on boucle sur les maillages puis sur 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);
          // --- cas des réactions:
         {// on regarde si le conteneur existe, si oui on transfert, si non, on passe les valeurs
          EnumTypeQuelconque enuq = VECT_REAC_N;
          if ((noo->Existe_ici(enuq)) && (noo->Existe_ici(R_X1)))
           {TypeQuelconque& typQ = noo->ModifGrandeur_quelconque(enuq); // récup du conteneur du noeud
            // récup de la grandeur
            Grandeur_coordonnee* gcoor = (Grandeur_coordonnee*) typQ.Grandeur_pointee();
            Coordonnee& conoe = *(gcoor->ConteneurCoordonnee()); // les coordonnées
            switch (dim) // on rempli les coordonnées
             { case 3: conoe(3)=noo->Valeur_tdt(R_X3);
               case 2: conoe(2)=noo->Valeur_tdt(R_X2);
               case 1: conoe(1)=noo->Valeur_tdt(R_X1);
             };
           };
          };
        };
    };
};

// retourne la liste des types de grandeur quelconque actuellement utilisé
// aux faces élément pour chaque maillage, la liste est exhaustive
// elle contiend tous les types au moins une fois utilisée
// cela ne signifie pas que la grandeur en question soit présent
// pour tous les éléments du maillage considéré
// - le tableau de retour est indicé par le numéro de maillage correspondant
// - il y a une liste par maillage
Tableau <List_io <TypeQuelconque> > LesMaillages::Les_type_de_donnees_evolues_internes_par_face_element(bool absolue)
  { // def de la liste de retour
    Tableau <List_io <TypeQuelconque> >  tab_ret_enum(nbMaillageTotal);
    // on boucle sur les maillages
    for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { // vecteur intermédiaire dont la taille peut augmenter
      List_io <TypeQuelconque> tab_enu_final;
      // on définit une liste de signature d'élément, ce qui permet de tester que les types d'éléments différents
      list <Element::Signature> list_signature_elem;
      // on boucle sur les elements
      int nbelementmax = tabMaillage(i1)->Nombre_element();
      for (int i2 = 1; i2 <= nbelementmax; i2++)
        { // recup du element
          Element * nee = & Element_LesMaille(i1,i2);
          // on regarde si un élément de même type n'a pas déjà été considéré
          if (find(list_signature_elem.begin(),list_signature_elem.end(),nee->Signature_element())==list_signature_elem.end())
           { // nouveau type d'élément , on récupère les données particulières
             // les opérations qui suivent sont assez longues mais normalement n'arrives pas souvent
             // recup du tableau de type de données particulières associées
             List_io <TypeQuelconque> tab_enum_parti(nee->Les_type_quelconque_de_face(absolue));
             tab_enu_final.sort(); // ordonne la liste
             tab_enu_final.merge(tab_enum_parti); // ajout de la liste
             tab_enu_final.unique(); // supprime les doublons
             // on ajoute la signature
             list_signature_elem.push_back(nee->Signature_element());
            };
         };
      // mise à jour du tableau global
      tab_ret_enum(i1) = tab_enu_final;
      };
//----- debug
// cout << "\n debug LesMaillages::Les_type_de_donnees_evolues_internes_par_face_element "
//      << tab_ret_enum << endl;
// ------ fin debug
   
   
    return tab_ret_enum; // retour du tableau
    };
    
// retourne la liste des types de grandeur quelconque actuellement utilisé
// aux arêtes élément pour chaque maillage, la liste est exhaustive
// elle contiend tous les types au moins une fois utilisée
// cela ne signifie pas que la grandeur en question soit présent
// pour tous les éléments du maillage considéré
// - le tableau de retour est indicé par le numéro de maillage correspondant
Tableau <List_io <TypeQuelconque> > LesMaillages::Les_type_de_donnees_evolues_internes_par_arete_element(bool absolue)
  { // def de la liste de retour
    Tableau <List_io <TypeQuelconque> >  tab_ret_enum(nbMaillageTotal);
    // on boucle sur les maillages
    for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { // vecteur intermédiaire dont la taille peut augmenter
      List_io <TypeQuelconque> tab_enu_final;
      // on définit une liste de signature d'élément, ce qui permet de tester que les types d'éléments différents
      list <Element::Signature> list_signature_elem;
      // on boucle sur les elements
      int nbelementmax = tabMaillage(i1)->Nombre_element();
      for (int i2 = 1; i2 <= nbelementmax; i2++)
        { // recup du element
          Element * nee = & Element_LesMaille(i1,i2);
          // on regarde si un élément de même type n'a pas déjà été considéré
          if (find(list_signature_elem.begin(),list_signature_elem.end(),nee->Signature_element())==list_signature_elem.end())
           { // nouveau type d'élément , on récupère les données particulières
             // les opérations qui suivent sont assez longues mais normalement n'arrives pas souvent
             // recup du tableau de type de données particulières associées
             List_io <TypeQuelconque> tab_enum_parti(nee->Les_type_quelconque_de_arete(absolue));
             tab_enu_final.sort(); // ordonne la liste
             tab_enu_final.merge(tab_enum_parti); // ajout de la liste
             tab_enu_final.unique(); // supprime les doublons
             // on ajoute la signature
             list_signature_elem.push_back(nee->Signature_element());
            };
         };
      // mise à jour du tableau global
      tab_ret_enum(i1) = tab_enu_final;
      };
//----- debug
// cout << "\n debug LesMaillages::Les_type_de_donnees_evolues_internes_par_arete_element "
//      << tab_ret_enum << endl;
// ------ fin debug
   
   
    return tab_ret_enum; // retour du tableau
    };


// initialisation d'un ou ne plusieurs nouveaux cas d'assemblage
// ramène le numéro du premier nouveau cas d'assemblage
Nb_assemb LesMaillages::InitNouveauCasAssemblage(int nb_cas)
  { // on récupère le nombre actuel de cas d'assemblage
    int nb_actuel = tab_nb_assemb;
    // on parcours les noeuds pour les dimensionner aux nouveaux cas d'assemblage
    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);
          // initialisation
          noo->InitNouveauCasAssemb(nb_cas);
         }
     }
     // dans le cas ou nb_cas est null pb
     #ifdef MISE_AU_POINT
      if (nb_cas == 0) 	 
        { cout << "\n erreur, le nombre de nouveau cas d'assemblage demandé est nul !!"
                 << " \n LesMaillages::InitNouveauCasAssemblage(int nb_cas) " ;
            Sortie(1);     
           }
     #endif
     // mise à jour du nombre de cas d'assemblage
     tab_nb_assemb += nb_cas;
     // mise à jour du tableau t_i_n
     t_i_n.Change_taille(tab_nb_assemb);
     // retour du premier nouveau cas d'assemblage
     nb_actuel++;
     return Nb_assemb(nb_actuel);         
   };

// met a jour les pointeurs d'assemblage dans les noeuds
// et enregistre les ddl_actifs et leurs ordres au niveau des noeuds
// a effectuer si l'on a changer de nb de noeuds, de nb de ddl, de nb de maillage
// casAssemb : donne le cas d'assemblage qui est a considérer
void LesMaillages::MiseAJourPointeurAssemblage(const Nb_assemb& casAssemb)
  { // pour la construction du tableau t_i_n pour le cas d'assemblage
    // on utilise une liste intermédiaire car on ne connait pas le nombre d'élément final
    list <Posi_ddl_noeud>  list_in ;
    // definition de la position globale  d'assemblage
    int pointeur=0 ;  // position d'assemblage
    int nb_assemb = casAssemb.n;
    bool absolue = true; // par défaut on travaille en absolu, mais en fait
             // cela n'a pas d'importance ici, car on n'utilise que le type
    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);
          // enregistrement des variables ddl actives
          noo->Enreg_ordre_variable_ddl_actives(nb_assemb);
          // on change le pointeur
          noo->ChangePosiAssemb(pointeur,nb_assemb);
          // récup de tous les ddl du noeud
          List_io <Enum_ddl> list_ddl = noo->Les_type_de_ddl(absolue);
          // on définit le tableau d'indexage t_in
          List_io <Enum_ddl>::iterator ie,iefin=list_ddl.end();
          for(ie=list_ddl.begin();ie!=iefin;ie++)
           { if (noo->En_service(*ie) && noo->UneVariable(*ie))
             // si le ddl est en service on l'enregistre
             {Posi_ddl_noeud posi(i1,*ie,noo->Num_noeud());
              list_in.push_back(posi);
              pointeur++; 
              }
            }
         }
     }
    // construction du tableau t_i_n pour le cas d'assemblage
    // NB:   t_i_n (i)(j) -> donne les infos pour retrouver le ddl numéro j du cas de charge i
    // le numéro j correspond au pointeur d'assemblage c-a-d la position du ddl dans l'assemblage
    Tableau <Posi_ddl_noeud> & t_in = t_i_n(nb_assemb); // pour simplifier
    int taille_tab = (int) list_in.size(); // la taille finale
    t_in.Change_taille(taille_tab); int i;
    list<Posi_ddl_noeud>::iterator ile; 
    for (i=1,ile=list_in.begin();i<=taille_tab;i++,ile++)
        t_in(i) = (*ile);
   };

// met a jour les pointeurs d'assemblage dans les noeuds pour un cas d'assemblage
// a effectuer si l'on a changer de nb de noeuds, de nb de ddl, de nb de maillage
// casAssemb : donne le cas d'assemblage qui est a considérer
// ici, l'assemblage suit l'ordre du tableau de noeud passé en paramètre
// le tableau de noeuds rassemble tous les noeuds des maillages mais avec une numérotation propre
// NB:   t_i_n (i)(j) -> donne les infos pour retrouver le ddl numéro j du cas de charge i
// le numéro j correspond au pointeur d'assemblage c-a-d la position du ddl dans l'assemblage
// verif_maillage: si true: on vérifie que les numéros de noeuds sont possibles pour le maillage
//         mais cette vérification n'est pas effectuée si verif_maillage est false: c'est utile
//         dans une phase transitoire de fabrication de t_i_n: bien noter que dans ce cas le tableau
//         t_i_n n'est pas utilisable

void LesMaillages::MiseAJourPointeurAssemblage_interne
         (const Nb_assemb& casAssemb,Tableau <Noeud* >& tab_N_final
         ,bool verif_maillage)
  { // pour la construction du tableau t_i_n pour le cas d'assemblage
    // on utilise une liste intermédiaire car on ne connait pas le nombre d'élément final
    list <Posi_ddl_noeud>  list_in ;
    // definition de la position globale  d'assemblage
    int pointeur=0 ;  // position d'assemblage
    int nb_assemb = casAssemb.n;
    bool absolue = true; // par défaut on travaille en absolu, mais en fait
             // cela n'a pas d'importance ici, car on n'utilise que le type
    int nb_noeud = tab_N_final.Taille();
    
    for (int i = 1; i<= nb_noeud; i++)
      { // recup du noeud
        Noeud * noo = tab_N_final(i);
//if (noo->Num_noeud() != i)
// cout << "\n debug LesMaillages::MiseAJourPointeurAssemblage_interne "
//      << " noo->Num_noeud()= "<< noo->Num_noeud() << " i= " << i << endl;
      
        // enregistrement des variables ddl actives
        noo->Enreg_ordre_variable_ddl_actives(nb_assemb);
        // on change le pointeur
        noo->ChangePosiAssemb(pointeur,nb_assemb);
        // récup de tous les ddl du noeud
        List_io <Enum_ddl> list_ddl = noo->Les_type_de_ddl(absolue);
        // on définit le tableau d'indexage t_in
        List_io <Enum_ddl>::iterator ie,iefin=list_ddl.end();
        for(ie=list_ddl.begin();ie!=iefin;ie++)
         { if (noo->En_service(*ie) && noo->UneVariable(*ie))
           // si le ddl est en service on l'enregistre
           {Posi_ddl_noeud posi(noo->Num_Mail(),*ie,noo->Num_noeud());
            list_in.push_back(posi);
            pointeur++;
           }
        };
     };
    // construction du tableau t_i_n pour le cas d'assemblage
    Tableau <Posi_ddl_noeud> & t_in = t_i_n(nb_assemb); // pour simplifier
    int taille_tab = (int) list_in.size(); // la taille finale
    t_in.Change_taille(taille_tab); int i;
    list<Posi_ddl_noeud>::iterator ile;
    for (i=1,ile=list_in.begin();i<=taille_tab;i++,ile++)
       { t_in(i) = (*ile);
// debug
//  // on vérifie que le maillage correspondant contient bien le noeud pointé
//  if (t_in(i).Nb_noeud() > tabMaillage(t_in(i).Nb_maillage())->Nombre_noeud())
//    cout << "\n debug LesMaillages::MiseAJourPointeurAssemblage_interne "
//         << " (t_in(i).Nb_noeud() > tabMaillage(t_in(i).Nb_maillage())->Nombre_noeud()) "
//         << " t_in(i).Nb_noeud()= "<< t_in(i).Nb_noeud()
//         << " tabMaillage(t_in(i).Nb_maillage())->Nombre_noeud()= "<< tabMaillage(t_in(i).Nb_maillage())->Nombre_noeud();
// fin debug
       };
       
    // vérification éventuelle du tableau t_i_n
    if (verif_maillage)
      {for (int j=1;j<=taille_tab;j++)
         if (t_in(j).Nb_noeud() > tabMaillage(t_in(j).Nb_maillage())->Nombre_noeud())
           { cout << "\n erreur !! LesMaillages::MiseAJourPointeurAssemblage_interne "
                  << " le tableau t_i_n est incorrecte -> il y aura des problemes d'assemblage ";
             #ifdef MISE_AU_POINT
             cout << "\n cas d'assemblage nb= " << nb_assemb << ", ddl nb_global= " << j
                  << " \n (t_in(j).Nb_noeud() > tabMaillage(t_in(j).Nb_maillage())->Nombre_noeud()) "
                  << " \n t_in(j).Nb_noeud()= "<< t_in(j).Nb_noeud()
                  << " tabMaillage(t_in(j).Nb_maillage())->Nombre_noeud()= "<< tabMaillage(t_in(j).Nb_maillage())->Nombre_noeud();
             Sortie(1);
             #endif
           };
      };
       
   };

// remise à jour des tableaux de pointeurs t_i_n uniquement, due à un changement de numéro de noeud
// en fonction d'un changement de num de noeud (mais pas de changement de pointeur d'assemblage
// 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()
// NB:   t_i_n (i)(j) -> donne les infos pour retrouver le ddl numéro j du cas de charge i
// le numéro j correspond au pointeur d'assemblage c-a-d la position du ddl dans l'assemblage
void LesMaillages::MiseAJourTableau_t_i_n(const Nb_assemb& nb_casAssemb,Tableau <Noeud* >& tab_N_final)
 { int nb_assemb = nb_casAssemb.n;
   // le tableau t_i_n pour le cas d'assemblage
   Tableau <Posi_ddl_noeud> & t_in = t_i_n(nb_assemb); // pour simplifier
//      pour mémoire un élément Posi_ddl_noeud // données
//        int nb_maillage; // le numéro du maillage
//        int nb_noeud;    // le numéro du noeud
//        Enum_ddl enu;    // l'identifieur du ddl

   int taille_tab = t_in.Taille();
   for (int i=1;i<= taille_tab;i++)
    { int ancien_num_noeud = t_in(i).Nb_noeud();
      int nouveau_num_noeud = tab_N_final(ancien_num_noeud)->Num_noeud();
      t_in(i).Nb_noeud() = nouveau_num_noeud;
////--- vérif debug
//Coordonnee co = Noeud_LesMaille(t_in(i).Nb_maillage(),t_in(i).Nb_noeud()).Coord0();
//if (i==taille_tab)
//  cout << "\n debug LesMaillages::MiseAJourTableau_t_i_n "<< co << endl;
////-- fin debug

     // on vérifie que le maillage correspondant contient bien le noeud pointé
     if (nouveau_num_noeud > tabMaillage(t_in(i).Nb_maillage())->Nombre_noeud())
       { cout << "\n erreur** LesMaillages::MiseAJourTableau_t_i_n "
              << " le tableau t_i_n est incorrecte -> il y aura des problemes d'assemblage ";
         #ifdef MISE_AU_POINT
         cout << "\n cas d'assemblage nb= " << nb_assemb << ", ddl nb_global= " << i
              << " \n (t_in(i).Nb_noeud() > tabMaillage(t_in(i).Nb_maillage())->Nombre_noeud()) "
              << " \n t_in(i).Nb_noeud()= "<< t_in(i).Nb_noeud()
              << " tabMaillage(t_in(i).Nb_maillage())->Nombre_noeud()= "<< tabMaillage(t_in(i).Nb_maillage())->Nombre_noeud();
         Sortie(1);
         #endif
       };

    };
 };


// mise a zero de tous les ddl actifs autres que les deplacements
// si indic = false; pas de creation des tableaux a t+dt
// si indic = true; creation des tableaux a t+dt
// cas = true; les coordonnées à t et éventuellement à t+dt sont initialisées
//             aux valeurs de t=0, sinon on ne les modifies pas
void LesMaillages::ZeroDdl(bool indic,bool cas)
  { 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);
//          if (i2 >= 583)
//           {
//          //debug
//          cout << "\n debug LesMaillages::ZeroDdl ";
//          cout << "\n pb coordonnee 2 noeud 583 ";
//          // fin debug
//           }
          if (indic) // construit les tableaux de ddl a t+dt selon indic
            noo->Travail_tdt();
         
//          if ((i2 >= 583)&&(!(tabMaillage(1)->Noeud_mail(583).ExisteCoord2())))
//           {
//          //debug
//          cout << "\n debug LesMaillages::ZeroDdl ";
//          cout << "\n pb coordonnee 2 noeud 583 ";
//          // fin debug
//           }
         
         
          noo->ZeroVariablesDdl(cas);  
         } 
      }       
////debug
//cout << "\n debug LesMaillages::ZeroDdl ";
//cout << "\n coordonnees0 du noeud 583 ";
//tabMaillage(1)->Noeud_mail(583).Coord0().Affiche();
//
//tabMaillage(1)->Noeud_mail(583).Coord2().Affiche();
//// fin debug
   };
    
// ramene la demi largeur de bande en ddl et la largeur de bande
// casAssemb : donne le cas d'assemblage qui est a considérer
void LesMaillages::Largeur_Bande(int& demi, int& total,const Nb_assemb& casAssemb)
  { int demib =0;
    int totalb = 0;
    demi = 0; total = 0; 
    for (int i1 = 1; i1<= nbMaillageTotal; i1++)
      { demib =0;
        totalb = 0;
        tabMaillage(i1)->Largeur_Bande(demib,totalb,casAssemb);
        if (demib > demi) demi = demib;
        if (totalb > total ) total = totalb;
      }  
   };
    
// méthode permettant le calcul des matrices de connexion pour chaque
// élément ceci par rapport à la numérotation absolu des ddl
// casAssemb : donne le cas d'assemblage qui est a considérer
    // les petites matrices sont carrées, ils sont définit par un tableau ligne qui contiend
    // la position d'un terme de la petite matrice dans la grande matrice
    // exemple : pet_mat(k)(i), pet_mat(k)(j) : indique le numéro de ligne  et le numéro de colonne 
    //           d'un élément non nul dans la grande matrice

void LesMaillages::Table_connexion
	    (Tableau < Tableau <int> >& pet_mat_mat,const Nb_assemb& casAssemb) const 
 { // calcul du nombre d'élément totaux
   int nbelem=0;
   for (int i = 1; i<= nbMaillageTotal; i++)
     nbelem +=  Nombre_element(i);
   // on dimensionne le tableau en conséquence
   pet_mat_mat.Change_taille(nbelem);
   // récup du numéro d'assemblage
   int nb_casAssemb = casAssemb.n;
   // on passe en revue tous les éléments et on rempli de tableau
   for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { 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);
         Tableau <int> & tabb = (pet_mat_mat(jel)); // simplification
         const Tableau<Noeud *>& tab_noeud = elem.Tab_noeud (); // recup tab_noeud
         const DdlElement & tab_ddl = elem.TableauDdl(); // tableau des ddl
         // dimensionnement du tableau de connexion
         tabb.Change_taille(tab_ddl.NbDdl());
         
         // differents indices de lignes
         int iloc, inoeud ; 
         // boucle sur les noeuds de l'element
         int inoeud_max = tab_noeud.Taille(); 
         for ( inoeud=1,iloc=1; inoeud<= inoeud_max; inoeud++)
          {Noeud& noei = *(tab_noeud(inoeud)); // simplification
           // boucle sur les ddl du noeudElement
           int ni_nbddl = tab_ddl.NbDdl(inoeud);
           for (int i = 1;i<= ni_nbddl ;i++,iloc++)
             // enregistrement de la position si le pointeur d'assemblage est valide
             { int pt = noei.Pointeur_assemblage(tab_ddl(inoeud,i),nb_casAssemb);
               if (pt != -1)
                  tabb(iloc) =  pt;
              }    
           } // fin de la boucle sur les noeuds de l'élément
                  
         } // fin de la boucle sur les éléments d'un maillage
     } // fin de la boucle sur les maillages
  };

// actualisation des ddl et des grandeurs actives de t+dt vers t      
void LesMaillages::TdtversT()
  {// tout d'abord on s'occupe des ddl
   for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
      for (int i2 = 1; i2 <= nbnoeudmax; i2++)
        Noeud_LesMaille(i1,i2).TdtversT();
    };
   // puis on s'occupe des é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);
          elem.TdtversT();
         }
    }
   
   // cas des intégrales et on alimente les grandeurs globales
   {int taille = integ_vol_typeQuel.Taille();
    for (int il =1;il <= taille ;il++)
     if (ref_integ_vol(il) != NULL) // si NULL => la grandeur reste fixe et n'est pas intégrée
      {TypeQuelconque& TQ_t = integ_vol_typeQuel_t(il); // pour simplifier
       TypeQuelconque& TQ = integ_vol_typeQuel(il); // pour simplifier
       // transfert des intégrales finalisées
       (TQ_t.Grandeur_pointee())->Affectation_numerique(*(TQ.Grandeur_pointee()));
// !! non ce sera fait dans l'intégration, et il vaut mieux garder une valeur correcte
//        TQ.Grandeur_pointee()->InitParDefaut(); // on initialise pour le prochain calcul
       // cas des grandeurs à t: on alimente les grandeurs globales
       // le conteneur qui contient le résultat globalisé
       // --> au début les grandeurs auront les mêmes valeurs à t et tdt
       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::TdtversT()"<<endl;
            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::TdtversT()"<<endl;
            Sortie(1);
         };
       #endif
       // on l'affecte
       TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
       (gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG_t));
      };
   };

   // on réinitialise également les grandeurs à 0, car le calcul est fait dans les éléments
   // et le stockage à t est sauvegardé dans les éléments, du coup si on n'initialise pas ici
   // au final on aura 2 fois l'intégrale à chaque pas de temps !!
   {int taille = integ_vol_t_typeQuel.Taille();
    for (int il =1;il <= taille ;il++)
     if (ref_integ_vol_t(il) != NULL) // si ==NULL => la grandeur reste fixe et n'est pas intégrée
      {TypeQuelconque& TQ_t = integ_vol_t_typeQuel_t(il); // pour simplifier
       TypeQuelconque& TQ = integ_vol_t_typeQuel(il); // pour simplifier
       // transfert des intégrales finalisées
       (TQ_t.Grandeur_pointee())->Affectation_numerique(*(TQ.Grandeur_pointee()));
// !! non ce sera fait dans l'intégration, et il vaut mieux garder une valeur correcte
//       TQ.Grandeur_pointee()->InitParDefaut(); // on initialise pour le prochain calcul
       // cas des grandeurs à t: on alimente les grandeurs globales
       // le conteneur qui contient le résultat globalisé
       // --> au début les grandeurs auront les mêmes valeurs à t et tdt
       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::TdtversT()"<<endl;
            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::TdtversT()"<<endl;
            Sortie(1);
         };
       #endif
       // on l'affecte
       TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
       (gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG_t));
      };
   };
      
   // cas des statistiques et on alimente les grandeurs globales
   {int taille = statistique_typeQuel.Taille();
    for (int il =1;il <= taille ;il++)
     if (ref_statistique(il) != NULL) // si NULL => la grandeur reste fixe et n'est pas calculée
      {TypeQuelconque& TQ_t = statistique_typeQuel_t(il); // pour simplifier
       TypeQuelconque& TQ = statistique_typeQuel(il); // pour simplifier
       // transfert des statistiques finalisées
       (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é
       // --> au début les grandeurs auront les mêmes valeurs à t et tdt
       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::TdtversT()"<<endl;
            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 statistique  !! "
                << " la variable globale  "<< (*nom_de_ref)
                << ", n'est pas disponible, on ne peut pas continuer  "
                 << "\n LesMaillages::TdtversT()"<<endl;
            Sortie(1);
         };
       #endif
       // on l'affecte
       TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
       (gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG_t));
      };
   };

   // on réinitialise également les grandeurs à 0, car le calcul est fait dans les éléments
   // et le stockage à t est sauvegardé dans les éléments, du coup si on n'initialise pas ici
   // au final on aura 2 fois l'intégrale à chaque pas de temps !!
   {int taille = statistique_t_typeQuel.Taille();
    for (int il =1;il <= taille ;il++)
     if (ref_statistique_t(il) != NULL) // si ==NULL => la grandeur reste fixe et n'est pas intégrée
      {TypeQuelconque& TQ_t = statistique_t_typeQuel_t(il); // pour simplifier
       TypeQuelconque& TQ = statistique_t_typeQuel(il); // pour simplifier
       // transfert des statistiques finalisées
       (TQ_t.Grandeur_pointee())->Affectation_numerique(*(TQ.Grandeur_pointee()));
// !! non ce sera fait dans l'intégration, et il vaut mieux garder une valeur correcte
//       TQ.Grandeur_pointee()->InitParDefaut(); // on initialise pour le prochain calcul
       // cas des grandeurs à t: on alimente les grandeurs globales
       // le conteneur qui contient le résultat globalisé
       // --> au début les grandeurs auront les mêmes valeurs à t et tdt
       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 avec cumul en temps  !! "
                 << " nom_de_ref est nul, on ne peut pas continuer  "
                 << "\n LesMaillages::TdtversT()"<<endl;
            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 statistique avec cumul en temps  !! "
                << " la variable globale  "<< (*nom_de_ref)
                << ", n'est pas disponible, on ne peut pas continuer  "
                 << "\n LesMaillages::TdtversT()"<<endl;
            Sortie(1);
         };
       #endif
       // on l'affecte
       TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
       (gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG_t));
      };
   };


  };
   
// actualisation des ddl et des grandeurs actives de t vers tdt      
void LesMaillages::TversTdt()
  {// tout d'abord on s'occupe des ddl
   for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
      for (int i2 = 1; i2 <= nbnoeudmax; i2++)
        Noeud_LesMaille(i1,i2).TversTdt();
    };
   // puis on s'occupe des é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);
          elem.TversTdt();
         }
    };

   // -- cas des intégrales de volumes
   // on réinitialise les grandeurs qui vont être calculée
   // ceux à t ne changent pas
   {int taille = integ_vol_typeQuel.Taille();
    for (int il =1;il <= taille ;il++)
     if (ref_integ_vol(il) != NULL) // si == NULL => la grandeur reste fixe et n'est pas intégrée
      {TypeQuelconque& TQ = integ_vol_typeQuel(il); // pour simplifier
       TypeQuelconque& TQ_t = integ_vol_typeQuel_t(il); // pour simplifier
       // transfert des intégrales finalisées
       (TQ.Grandeur_pointee())->Affectation_numerique(*(TQ_t.Grandeur_pointee()));
// !! non ce sera fait dans l'intégration, et il vaut mieux garder une valeur correcte
//       TQ.Grandeur_pointee()->InitParDefaut();
       // cas des grandeurs à tdt: on alimente les grandeurs globales
       // le conteneur qui contient le résultat globalisé
       // donc on le remet à du pas précédent à t
       TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
       TypeQuelconque::Grandeur* g_TG_t = TQ_t.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::TversTdt()"<<endl;
            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::TversTdT()"<<endl;
            Sortie(1);
         };
       #endif
       // on l'affecte
       TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
       (gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG_t));
      };
   };
   
   // -- cas des intégrales de volumes et en temps
   // on réinitialise également les grandeurs à 0, car le calcul est fait dans les éléments
   // et le stockage à t est sauvegardé dans les éléments, du coup si on n'initialise pas ici
   // au final on aura 2 fois l'intégrale à la fin du pas de temps !!
   // par contre avant l'initialisation, on met à jour la variable globale
   {int taille = integ_vol_t_typeQuel.Taille();
    for (int il =1;il <= taille ;il++)
     if (ref_integ_vol_t(il) != NULL) // si NULL => la grandeur reste fixe et n'est pas intégrée
      {TypeQuelconque& TQ_t = integ_vol_t_typeQuel_t(il); // pour simplifier
       TypeQuelconque& TQ = integ_vol_t_typeQuel(il); // pour simplifier
       // on remet à t les grandeurs globales
       TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
       TypeQuelconque::Grandeur* g_TG_t = TQ_t.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::TdtversT()"<<endl;
            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::TversTdT()"<<endl;
            Sortie(1);
         };
       #endif
       // on réaffecte la grandeur à tdt à la valeur de t
       TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
       (gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG_t));
// !! non ce sera fait dans l'intégration, et il vaut mieux garder une valeur correcte
//       // maintenant on initialise le conteneur local
//       TQ.Grandeur_pointee()->InitParDefaut(); // on initialise pour le prochain calcul
      };
   };


   // -- cas des statistiques sur des ref de noeuds
   // on réinitialise les grandeurs qui vont être calculée
   // ceux à t ne changent pas
   {int taille = statistique_typeQuel.Taille();
    for (int il =1;il <= taille ;il++)
     if (ref_statistique(il) != NULL) // si == NULL => la grandeur reste fixe et n'est pas intégrée
      {TypeQuelconque& TQ = statistique_typeQuel(il); // pour simplifier
       TypeQuelconque& TQ_t = statistique_typeQuel_t(il); // pour simplifier
       // transfert des intégrales finalisées
       (TQ.Grandeur_pointee())->Affectation_numerique(*(TQ_t.Grandeur_pointee()));
// !! non ce sera fait dans l'intégration, et il vaut mieux garder une valeur correcte
//       TQ.Grandeur_pointee()->InitParDefaut();
       // cas des grandeurs à tdt: on alimente les grandeurs globales
       // le conteneur qui contient le résultat globalisé
       // donc on le remet à du pas précédent à t
       TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
       TypeQuelconque::Grandeur* g_TG_t = TQ_t.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::TversTdt()"<<endl;
            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::TversTdT()"<<endl;
            Sortie(1);
         };
       #endif
       // on l'affecte
       TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
       (gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG_t));
      };
   };
      
   // -- cas des statistiques sur des refs de noeuds avec cumul en temps

//**** à voir si c'est vrai pour les statistiques

   // on réinitialise également les grandeurs à 0, car le calcul est fait dans les éléments
   // et le stockage à t est sauvegardé dans les éléments, du coup si on n'initialise pas ici
   // au final on aura 2 fois l'intégrale à la fin du pas de temps !!
   // par contre avant l'initialisation, on met à jour la variable globale
   
   {int taille = statistique_t_typeQuel.Taille();
    for (int il =1;il <= taille ;il++)
     if (ref_statistique_t(il) != NULL) // si NULL => la grandeur reste fixe
      {TypeQuelconque& TQ_t = statistique_t_typeQuel_t(il); // pour simplifier
       TypeQuelconque& TQ = statistique_t_typeQuel(il); // pour simplifier
       // on remet à t les grandeurs globales
       TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee();
       TypeQuelconque::Grandeur* g_TG_t = TQ_t.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 cumul en temps !! "
                 << " nom_de_ref est nul, on ne peut pas continuer  "
                 << "\n LesMaillages::TdtversT()"<<endl;
            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 statistique avec cumul en temps !! "
                << " la variable globale  "<< (*nom_de_ref)
                << ", n'est pas disponible, on ne peut pas continuer  "
                 << "\n LesMaillages::TversTdT()"<<endl;
            Sortie(1);
         };
       #endif
       // on réaffecte la grandeur à tdt à la valeur de t
       TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
       (gr_quelc->Grandeur_pointee())->Affectation_numerique(*(g_TG_t));
// !! non ce sera fait dans l'intégration, et il vaut mieux garder une valeur correcte
//       // maintenant on initialise le conteneur local
//       TQ.Grandeur_pointee()->InitParDefaut(); // on initialise pour le prochain calcul
      };
   };
  };
      
// actualisation des ddl actifs a t+dt, a partir du resultat de la resolution
// casAssemb : donne le cas d'assemblage qui est a considérer
void LesMaillages::PlusDelta_tdt(Vecteur& sol,const Nb_assemb& casAssemb)
  { // on balaie le tableau d'indexage
    Tableau <Posi_ddl_noeud> & ti_n =  t_i_n(casAssemb.n); // pour simplifier
    int ti_nTaille = ti_n.Taille();
    for (int i=1;i<=ti_nTaille;i++)
     { Posi_ddl_noeud& a = ti_n(i);
       Noeud_LesMaille(a.Const_Nb_maillage(),a.Const_Nb_noeud()).Ajout_val_tdt(a.Const_Enu(),sol(i));
     };
  };
   
// actualisation des ddl actifs a t, a partir du resultat de la resolution
// casAssemb : donne le cas d'assemblage qui est a considérer
void LesMaillages::PlusDelta_t(Vecteur& sol,const Nb_assemb& casAssemb)
  { // on balaie le tableau d'indexage
    Tableau <Posi_ddl_noeud> & ti_n =  t_i_n(casAssemb.n); // pour simplifier
    int ti_nTaille = ti_n.Taille();
    for (int i=1;i<=ti_nTaille;i++)
     { Posi_ddl_noeud& a = ti_n(i);
       Noeud_LesMaille(a.Const_Nb_maillage(),a.Const_Nb_noeud()).Ajout_val_t(a.Const_Enu(),sol(i));
     };
  };

// récupération du vecteur correspondant à l'incrément de déplacement entre t et tdt
// en paramètre le vecteur vide et en sortie le vecteur rempli
// casAssemb : donne le cas d'assemblage qui est a considérer
Vecteur& LesMaillages::RecupDepde_tatdt(Vecteur& sol,const Nb_assemb& casAssemb)
  { // on balaie le tableau d'indexage
    Tableau <Posi_ddl_noeud> & ti_n =  t_i_n(casAssemb.n); // pour simplifier
    int ti_nTaille = ti_n.Taille();
    for (int i=1;i<=ti_nTaille;i++)
     { Posi_ddl_noeud& a = ti_n(i);
       Noeud & noe = Noeud_LesMaille(a.Const_Nb_maillage(),a.Const_Nb_noeud());
       sol(i) = noe.Valeur_tdt(a.Const_Enu()) - noe.Valeur_t(a.Const_Enu());
     };
    return sol;   
  };

// changement des ddl à tdt par ceux correspondant au vecteur passé en paramètre
// casAssemb : donne le cas d'assemblage qui est a considérer
void LesMaillages::ChangeDdla_tdt(Vecteur& sol,const Nb_assemb& casAssemb)
  { // on balaie le tableau d'indexage
    Tableau <Posi_ddl_noeud> & ti_n =  t_i_n(casAssemb.n); // pour simplifier
    int ti_nTaille = ti_n.Taille();
    for (int i=1;i<=ti_nTaille;i++)
     { Posi_ddl_noeud& a = ti_n(i);
       Noeud_LesMaille(a.Const_Nb_maillage(),a.Const_Nb_noeud()).Change_val_tdt(a.Const_Enu(),sol(i));
     };
  };

// retrouver le ddl correspondant  a un pointeur de position
// d'assemblage, le nb du noeud et du maillage
// insol = le pointeur de position dans l'assemblage;
// ddl = le ddl en sortie;  a t+dt  si elle il existe
// sinon la valeur a t
// casAssemb : donne le cas d'assemblage qui est a considérer
Ddl  LesMaillages::NoeudIndice(int inSol,int& nbNoeud, int& nbMaillage,const Nb_assemb& casAssemb)
   { // on utilise le tableau d'indexage
     Posi_ddl_noeud& a = t_i_n(casAssemb.n)(inSol);
     nbNoeud = a.Const_Nb_noeud(); nbMaillage = a.Const_Nb_maillage();
     Noeud & noe = Noeud_LesMaille(a.Const_Nb_maillage(),a.Const_Nb_noeud());
     if (noe.Tdt())
       return noe.Ddl_noeud_tdt(a.Const_Enu());
     else
       return noe.Ddl_noeud_t(a.Const_Enu());
   };
// idem en ramenant en plus la valeur du ddl a 0
Ddl  LesMaillages::NoeudIndice(int inSol,int& nbNoeud, int& nbMaillage, double& val0
                               ,const Nb_assemb& casAssemb)
   { // on utilise le tableau d'indexage
     Posi_ddl_noeud& a = t_i_n(casAssemb.n)(inSol);
     nbNoeud = a.Const_Nb_noeud(); nbMaillage = a.Const_Nb_maillage();
     Noeud & noe = Noeud_LesMaille(a.Const_Nb_maillage(),a.Const_Nb_noeud());
     val0=noe.Valeur_0(a.Const_Enu());
     if (noe.Tdt())
       return noe.Ddl_noeud_tdt(a.Const_Enu());
     else
       return noe.Ddl_noeud_t(a.Const_Enu());
   };
  
// creation des elements frontiere: cela n'a lieu qu'une seule fois
// si les frontières existent déjà, --> aucune action, --> ramène 0
// sinon il y a réellement création, et --> ramène 1
// NB: il s'agit ici des frontière minimales permettant de représenter toute la frontière
// Ainsi:
// en 1D on retrouve:
//    - des points uniquement
// en 2D on retrouve :
//    - des segments dans le cas d'une surface  (les noeuds sont exclus car intégrés aux lignes)
//    - points et segment pour les lignes
// en 2D axi, on retrouve :
//    - des segments dans le cas d'une surface  (les noeuds sont exclus car intégrés aux lignes)
//    - points et segment pour les lignes
// en 3D, on retrouve
//    - des faces pour les éléments volumique (noeuds et lignes sont exclus)
//    - une face et des lignes pour les éléments 2D (pas de noeuds)

int LesMaillages::CreeElemFront()
  { int retour = 0;
  
    if ((listFrontiere.Taille() == 0) || (tt_noeud_front.Taille() == 0))
     {  for (int nbmail=1;nbmail<=nbMaillageTotal;nbmail++)
           tabMaillage(nbmail)->CreeElemFront();
        listFrontiere.Change_taille(nbMaillageTotal);
        tt_noeud_front.Change_taille(nbMaillageTotal);
        for (int nbmail=1;nbmail<=nbMaillageTotal;nbmail++)
          {listFrontiere(nbmail) = tabMaillage(nbmail)->ListFront();
           tt_noeud_front(nbmail) = &(tabMaillage(nbmail)->Tab_noeud_front());
          };
        retour = 1;
     }
    else
     {retour = 0;};
//// pour le débug
//for (int nbmail=1;nbmail<=nbMaillageTotal;nbmail++)
//  {int nbfront = listFrontiere(nbmail)->size();
//   cout << "\n maillage " << nbmail << " -------- ";
//   LaLIST <Front>::iterator iff,iffin = listFrontiere(nbmail)->end();
//   iff=listFrontiere(nbmail)->begin();
////   for (iff=listFrontiere(nbmail)->begin();iff !=iffin;iff++)
//   Front& titi = (*iff);
//      titi.Affiche(); cout << "\n";
//
//  };
//   
// Sortie(1);
//// fin débug

//// pour le débug
//for (int nbmail=1;nbmail<=nbMaillageTotal;nbmail++)
//  {int nbfront = listFrontiere(nbmail)->size();
//   cout << "\n maillage " << nbmail << " -------- ";
//   LaLIST <Front>::iterator iff,iffin = listFrontiere(nbmail)->end();
//   for (iff=listFrontiere(nbmail)->begin();iff !=iffin;iff++) 
//      {(*iff).Affiche(); cout << "\n";};
//  };
// Sortie(1);       
//// fin débug

    // retour
    return retour;
  };
   
// ramene le tableau des noeuds des frontières des maillages esclaves
Tableau < Tableau <Noeud*> *> LesMaillages::Tab_noeud_frontiere_esclave()
   { Tableau < Tableau <Noeud*> *> ret(domEsclave);
     #ifdef UTILISATION_MPI
       if (ParaGlob::Monde()->rank() == 0)
     #endif
     if ((domEsclave)&&(ParaGlob::NiveauImpression()>2))
       cout << "\n >>>> Information maillages : ";
     for (int i=1;i<=domEsclave;i++)
       {ret(i) = tt_noeud_front(i);
        #ifdef UTILISATION_MPI
          if (ParaGlob::Monde()->rank() == 0)
        #endif
        if (ParaGlob::NiveauImpression()>2)
         cout << "\n il y a "<<ret(i)->Taille()
              << " noeuds esclaves possible sur front. du maillage " << i ;
       
       };
     return ret;
    }; 
   
// calcul et ramene le tableau de tous les noeuds des maillages esclaves 
// noeuds de la frontière et noeuds internes
// s'ils existent, sinon le tableau est vide
// le tableau n'est pas sauvegarde
const Tableau<Noeud *> LesMaillages::Esclave()
  {  // tout d'abord on cherche la taille du tableau
     int tail = 0;
     for (int i=1;i<= domEsclave;i++)
        tail += tabMaillage(i)->Nombre_noeud();
//        tail += tabMaillage(i)->Nombre_noeud();
     // dimensionnement du tableau
     Tableau<Noeud *> tab(tail);
     // remplissage du tableau
     int indice =1;
     for (int i=1;i<= domEsclave;i++)
        {int nbnimax = tabMaillage(i)->Nombre_noeud();
		   for (int j=1; j<= nbnimax;j++,indice++)
           tab(indice) = &(tabMaillage(i)->Noeud_mail(j));
			};  
     // retour
     return tab;                    
   };

// création forcée en 3D de toutes les frontières lignes (non traités par CreeElemFront())
// qui appartiennent à la frontière globales, ceci uniquement pour les éléments volumiques
// - Ces frontières ne sont pas intégrées dans la liste de frontière minimale
// - une même ligne peut appartenir à plusieurs éléments finis, elle n'est donc pas ici
//   définit de manière unique (contrairement aux frontières minimales)
// NB: cela n'a lieu qu'une seule fois
// si les frontières existent déjà, --> aucune action, --> ramène 0
// sinon il y a réellement création, et --> ramène 1
int LesMaillages::CreeListFrontiere_ligne_3D()
   { int retour = 0;
   
     if (listFrontiere_ligne_3D.Taille() == 0)
      {  for (int nbmail=1;nbmail<=nbMaillageTotal;nbmail++)
            tabMaillage(nbmail)->CreeListFrontiere_ligne_3D();
         listFrontiere_ligne_3D.Change_taille(nbMaillageTotal);
         for (int nbmail=1;nbmail<=nbMaillageTotal;nbmail++)
           {listFrontiere_ligne_3D(nbmail) = tabMaillage(nbmail)->ListFront_ligne_3D();
           };
         retour = 1;
      }
     else
      {retour = 0;};
 //// pour le débug
 //for (int nbmail=1;nbmail<=nbMaillageTotal;nbmail++)
 //  {int nbfront = listFrontiere(nbmail)->size();
 //   cout << "\n maillage " << nbmail << " -------- ";
 //   LaLIST <Front>::iterator iff,iffin = listFrontiere(nbmail)->end();
 //   iff=listFrontiere(nbmail)->begin();
 ////   for (iff=listFrontiere(nbmail)->begin();iff !=iffin;iff++)
 //   Front& titi = (*iff);
 //      titi.Affiche(); cout << "\n";
 //
 //  };
 //
 // Sortie(1);
 //// fin débug

 //// pour le débug
 //for (int nbmail=1;nbmail<=nbMaillageTotal;nbmail++)
 //  {int nbfront = listFrontiere(nbmail)->size();
 //   cout << "\n maillage " << nbmail << " -------- ";
 //   LaLIST <Front>::iterator iff,iffin = listFrontiere(nbmail)->end();
 //   for (iff=listFrontiere(nbmail)->begin();iff !=iffin;iff++)
 //      {(*iff).Affiche(); cout << "\n";};
 //  };
 // Sortie(1);
 //// fin débug

     // retour
     return retour;
   };

// inactive  tous les ddl et les données
void LesMaillages::Inactive_ddl_et_donnees()
 { for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
      for (int i2 = 1; i2 <= nbnoeudmax; i2++)
        Noeud_LesMaille(i1,i2).Met_hors_service();
     }   
  };  
// inactive  tous les ddl mais pas les données
void LesMaillages::Inactive_ddl()
 { for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
      for (int i2 = 1; i2 <= nbnoeudmax; i2++)
        Noeud_LesMaille(i1,i2).Met_hors_service_ddl();
     }
  };
// inactive les ddl primaires
void LesMaillages::Inactive_ddl_primaire()  
 { for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { int nbelementmax = tabMaillage(i1)->Nombre_element();
      for (int i2 = 1; i2 <= nbelementmax; i2++)
        Element_LesMaille(i1,i2).Inactive_ddl_primaire();
     }   
  };  
// active les ddl primaires 
void LesMaillages::Active_ddl_primaire()
 { for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { int nbelementmax = tabMaillage(i1)->Nombre_element();
      for (int i2 = 1; i2 <= nbelementmax; i2++)
        Element_LesMaille(i1,i2).Active_ddl_primaire();
     }    
  };  
// introduction des ddl de contraintes si cela veut dire quelques chose
// pour l'élément
void LesMaillages::Plus_ddl_Sigma()
 { 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)
           ((ElemMeca&) elem).Plus_ddl_Sigma();
         }
     }   
  };  
// inactivation des ddls de contraintes si cela veut dire quelques chose
// pour l'élément
void LesMaillages::Inactive_ddl_Sigma()
 { 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)
            ((ElemMeca&) elem).Inactive_ddl_Sigma();
         }
     }   
  };  
// activation des ddls de contraintes si cela veut dire quelques chose
// pour l'élément
void LesMaillages::Active_ddl_Sigma()
 { 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)
            ((ElemMeca&) elem).Active_ddl_Sigma();
         }
     }   
  };  
// activation du premier  ddl de contraintes si cela veut dire quelques chose
// pour l'élément
void LesMaillages::Active_premier_ddl_Sigma()
 { 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)
            ((ElemMeca&) elem).Active_premier_ddl_Sigma();
         }
     }   
  };  

// introduction des ddl d'erreur si cela veut dire quelques chose
// pour l'élément
void LesMaillages::Plus_ddl_Erreur()
 { 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)
           ((ElemMeca&) elem).Plus_ddl_Erreur();
         }
     }   
  };  
// inactivation des ddls d'erreur si cela veut dire quelques chose
// pour l'élément
void LesMaillages::Inactive_ddl_Erreur()
 { 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)
            ((ElemMeca&) elem).Inactive_ddl_Erreur();
         }
     }   
  };  
// activation des ddls d'erreur si cela veut dire quelques chose
// pour l'élément
void LesMaillages::Active_ddl_Erreur()
 { 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)
            ((ElemMeca&) elem).Active_ddl_Erreur();
         }
     }   
  };  


// active un ddl particulier
void LesMaillages::Active_un_ddl_particulier(Enum_ddl en)
{ 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 ddl existe
         if (noo->Existe_ici(en))
           // si oui on l'active
           noo->Met_en_service(en);
       };
   };
};

// inactive un ddl particulier
void LesMaillages::Inactive_un_ddl_particulier(Enum_ddl en)
{ 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 ddl existe
         if (noo->Existe_ici(en))
           // si oui on l'active
           noo->Met_hors_service(en);
       };
   };
};

// d'une manière plus générique une fonction pour activer une série de ddl
// donnée par un identificateur, si c'est une grandeur vectoriel c'est l'ensemble
// des ddl du vecteur qui sont inactivé. 
void LesMaillages::Active_un_type_ddl_particulier(Enum_ddl eni)
 { // on retient le premier ddl de la famille
   Enum_ddl en = PremierDdlFamille(eni);
   // il y a deux versions suivant que le ddl est une grandeur vectorielle ou pas
   if (FoncDim(en))
     // oui c'est une fonction vectorielle
    { // recup de la dimension
      int dimen = ParaGlob::Dimension();
      // dans le cas où le calcul est axisymétrique on décrémente de 1
      if (ParaGlob::AxiSymetrie()) 
           dimen--;
      // création du tableau de ddl de travail
      Tableau <Enum_ddl> taben(dimen); 
      for (int ii=1; ii<= dimen; ii++) 
        taben(ii) = Enum_ddl(en + ii-1); 
      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 ddl existe
              if (noo->Existe_ici(en))
                // si oui on l'active
                noo->Met_en_service(taben);
              // dans le cas où en = X1, on regarde le cas des épaisseurs
              // celles-ci sont par exemple utilisées pour les coques et plaques et correspondent
              // à une dimension du même ordre que Xi
              if (en == X1)
                if ( noo->Existe_ici(EPAIS) &&   noo->UneVariable(EPAIS))
                  noo->Met_en_service(EPAIS);
             } 
          }
      }
    else // cas où il s'agit d'une grandeur scalaire
      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 ddl existe
              if (noo->Existe_ici(en))
                // si oui on l'active
                noo->Met_en_service(en);
             } 
          }
  };  
//idem pour un tableau
void LesMaillages::Active_un_type_ddl_particulier(Tableau <Enum_ddl>& tab_en)
 { int tab_enTaille = tab_en.Taille();
   for (int it=1;it<=tab_enTaille;it++) Active_un_type_ddl_particulier(tab_en(it));
   }; 
//idem pour une liste
void LesMaillages::Active_un_type_ddl_particulier(const list <Enum_ddl>& list_en)
 { list <Enum_ddl>::const_iterator il,ilfin=list_en.end();
   for (il = list_en.begin();il != ilfin;il++) Active_un_type_ddl_particulier((*il));
 };

// idem la fonction Active_ddl_noeud mais ici pour l'inactivation
void LesMaillages::Inactive_un_type_ddl_particulier(Enum_ddl eni)  
 { // on retient le premier ddl de la famille
   Enum_ddl en = PremierDdlFamille(eni);
   // il y a deux versions suivant que le ddl est une grandeur vectorielle ou pas
   if (FoncDim(en))
     // oui c'est une fonction vectorielle
    { // recup de la dimension
      int dimen = ParaGlob::Dimension();
      // dans le cas où le calcul est axisymétrique on décrémente de 1
      if (ParaGlob::AxiSymetrie()) 
           dimen--;
      // création du tableau de ddl de travail
      Tableau <Enum_ddl> taben(dimen); 
      for (int ii=1; ii<= dimen; ii++) 
        taben(ii) = Enum_ddl(en + ii-1); 
      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 ddl existe
              if (noo->Existe_ici(en))
                // si oui on l'inactive
                noo->Met_hors_service(taben);
              // dans le cas où en = X1, on regarde le cas des épaisseurs
              // celles-ci sont par exemple utilisées pour les coques et plaques et correspondent
              // à une dimension du même ordre que Xi
              if (PremierDdlFamille(en) == X1)
                if ( noo->Existe_ici(EPAIS) &&   noo->UneVariable(EPAIS))
                  noo->Met_hors_service(EPAIS);
             } 
          }
      }
    else // cas où il s'agit d'une grandeur scalaire
      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 ddl existe
              if (noo->Existe_ici(en))
                // si oui on l'inactive
                noo->Met_hors_service(en);
             } 
          }
  };  
//idem pour un tableau
void LesMaillages::Inactive_un_type_ddl_particulier(Tableau <Enum_ddl>& tab_en)
 { int tab_enTaille = tab_en.Taille();
   for (int it=1;it<=tab_enTaille;it++) Inactive_un_type_ddl_particulier(tab_en(it));
   }; 
//idem pour une liste
void LesMaillages::Inactive_un_type_ddl_particulier(const list <Enum_ddl>& list_en)
 { list <Enum_ddl>::const_iterator il,ilfin=list_en.end();
   for (il = list_en.begin();il != ilfin;il++) Inactive_un_type_ddl_particulier((*il));
 };

// Calcul de l'erreur  sur l'ensemble des éléments
// type indique le type d'erreur retenue
// type = 1 : cas d'un calcul aux moindres carrés
// et retour un tableau de tableau de grandeurs sur les maillages en cours
//      ret(i) : concerne le maillage i
//      ret(i)(1) : somme des erreurs sur l'ensemble des éléments: est homogêne à
//                  un |delta contrainte| * domaine
//      ret(i)(2) : somme de la grandeur de ref du calcul d'erreur sur l'ensemble des
//                  éléments: est homogêne à une |contrainte| * domaine
//      ret(i)(3) : le maxi pour les tous les éléments de |delta contrainte| * domaine
//      ret(i)(4) : le maxi pour les tous les éléments de |contrainte| * domaine
//      ret(i)(5) : le maxi pour les tous les éléments de l'erreur relative
Tableau <Tableau <double > >  LesMaillages::ErreurSurChaqueElement(int type)
 { double errElemRelative; // variable de travail
   Tableau <Tableau <double > >  ret(nbMaillageTotal); // init du tableau de retour
   
   for (int i1 = 1; i1<= nbMaillageTotal; i1++)
    { int nbelementmax = tabMaillage(i1)->Nombre_element();
      double ErreurTot = 0.; // erreur totale
      ret(i1).Change_taille(5);
      double numerateur,denominateur;
      double numtot = 0.; double denotot = 0.;
      double maxi_numerateur = 0.; double maxi_denominateur = 0.;
      double maxi_relatif = 0.;
      for (int i2 = 1; i2 <= nbelementmax; i2++)
        { Element & elem = Element_LesMaille(i1,i2);
          if (elem.Id_TypeProblem() == MECA_SOLIDE_DEFORMABLE)
            { // calcul des elements d'erreur
              ((ElemMeca&) elem).ErreurElement(type,errElemRelative
                            ,numerateur,denominateur);
              numtot += numerateur; denotot += denominateur;
              maxi_numerateur = DabsMaX(maxi_numerateur,numerateur);
              maxi_denominateur = DabsMaX(maxi_denominateur, denominateur);
              double relatif = 0.;
              if (Dabs(denominateur) > ConstMath::petit)
                { relatif = numerateur/denominateur;}
              else
                { relatif = numerateur; }; // on prend les valeurs non relatives si
              maxi_relatif = DabsMaX(maxi_relatif, relatif);
            };
         };
      ret(i1)(1)=numtot;
      ret(i1)(2)=denotot;
      ret(i1)(3)=maxi_numerateur;
      ret(i1)(4)=maxi_denominateur;
//      ret(i1)(5)=maxi_relatif;
     }
  
  // maintenant on va calculer la vraie erreur relative et on l'attribue aux éléments
  for (int i1 = 1; i1<= nbMaillageTotal; i1++)
   { int nbelementmax = tabMaillage(i1)->Nombre_element();
     double maxi_relatif = 0.;
     for (int i2 = 1; i2 <= nbelementmax; i2++)
       { Element & elem = Element_LesMaille(i1,i2);
         if (elem.Id_TypeProblem() == MECA_SOLIDE_DEFORMABLE)
           { double erreur_absolue = ((ElemMeca&) elem).Erreur_sigma();
             double erreur_relative = erreur_absolue/ret(i1)(4);
             ((ElemMeca&) elem).Change_erreur_relative(erreur_relative);
             maxi_relatif = DabsMaX(maxi_relatif, erreur_relative);
           };
        };
     ret(i1)(5)=maxi_relatif;
    };
     
////--- debug
//cout << "\n debug LesMaillages::ErreurSurChaqueElement "
//     << "\n Int_(delta sig)^2= " << numtot << ", int_sig^2= "<<denotot<<endl;
////---fin debug
   return ret;
  };  
    
     
// lecture de donnée en fonction d'un indicateur : type
// type = 1 , on lit les tenseurs de contrainte
// type = 2 , on lit les déplacements
void   LesMaillages::LectureDonneesExternes(const int type ,const string& nomMaillage)
 { // tout d'abord on cré un tableau d'indicateur qui est utilisé pour l'initialisatione
   // des noeuds de manière à éviter plusieurs fois la même opération
   static Tableau<bool> indicTravail_t(nbMaillageTotal,false);

   // cas des contraintes
   if (type == 1)
    { // on parcours les éléments pour trouver le bon fichier
      int i1;
      for (i1 = 1; i1<= nbMaillageTotal; i1++)
        // on regarde si le nom de maillage correspond
        if ( tabMaillage(i1)->NomDuMaillage() == nomMaillage)
           break;
      if (i1 ==  nbMaillageTotal+1)
       { cout << "\n erreur, on n'a pas trouve un nom de maillage utilisable pour la lecture de "
              << "\n de donnees externes sur fichier !";
         entreePrinc->MessageBuffer("  LesMaillages::LectureDonneesExternes(...");     
         throw (UtilLecture::ErrNouvelleDonnee(-1));     
         Sortie(1);     
        }    
      // on initialise le travail à t, nécessaire pour le calcul des métriques avec
      // les coordonnées à t
      if (!indicTravail_t(i1))
       { Travail_t(i1);
         ZeroDdl(false); // mise à zéro des ddl sauf les déplacements qui sont = coord0
         // et mémorisation 
         indicTravail_t(i1) = true; 
        }     
      // maintenant passage de l'entête
      entreePrinc->NouvelleDonnee();
      int toto,nbe;
      *(entreePrinc->entree)  >> toto >> nbe;
      // passage des identificateurs des contraintes
      entreePrinc->NouvelleDonnee(); 
      // lecture des données pour chaque élément
      int nbelementmax = tabMaillage(i1)->Nombre_element();
      // vérif du nombre d'élément
      if (nbe != nbelementmax)
        { // cas d'une différence 
          cout << "\n erreur (1) dans la lecture externe des contraintes, le nombre d'element interne"
               << "\n au calcul, et le nombre externe sur fichier est different!";
          entreePrinc->MessageBuffer("  LesMaillages::LectureDonneesExternes(...");     
          throw (UtilLecture::ErrNouvelleDonnee(-1));     
          Sortie(1);
        }                        
      for (int i2 = 1; i2 <= nbelementmax; i2++)
         { // lecture d'un premier enregistrement
           entreePrinc->NouvelleDonnee();
           Element & elem = Element_LesMaille(i1,i2);
           // lecture du type d'élément (ne sert à rien ici)
           int typelem;
           *(entreePrinc->entree)  >> typelem;
           // lecture des contraintes
           if (elem.Id_TypeProblem() == MECA_SOLIDE_DEFORMABLE)
                 ((ElemMeca&) elem).LectureContraintes(entreePrinc);
          }
     }
   // cas des déplacements
   if (type == 2)
    { // on parcours les éléments pour trouver le bon fichier
      int i1;
      for (i1 = 1; i1<= nbMaillageTotal; i1++)
        // on regarde si le nom de maillage correspond
        if ( tabMaillage(i1)->NomDuMaillage() == nomMaillage)
           break;
      // on initialise le travail à t, nécessaire pour le calcul des métriques avec
      // les coordonnées à t
      if (!indicTravail_t(i1))
       { Travail_t(i1);
         ZeroDdl(false); // mise à zéro des ddl sauf les déplacements qui sont = coord0
         // et mémorisation 
         indicTravail_t(i1) = true; 
        }     
      // maintenant on lit le nombre de déplacements enregistrés dans le fichier
      entreePrinc->NouvelleDonnee();
      int nbenreg;
      *(entreePrinc->entree)  >> nbenreg;
      // récup du nombre de noeud du maillage
      int nbnoeudmax = tabMaillage(i1)->Nombre_noeud();
      if (nbnoeudmax != nbenreg)
        { // cas d'une différence 
          cout << "\n erreur (2) dans la lecture externe des contraintes, le nombre de noeuds interne"
               << "\n au calcul, et le nombre externe sur fichier est different!";
          cout << "\n LesMaillages::LectureDonneesExternes( etc ... " << endl;
          entreePrinc->MessageBuffer("  LesMaillages::LectureDonneesExternes(...");     
          throw (UtilLecture::ErrNouvelleDonnee(-1));     
          Sortie(1);
        }                        
      // lecture des données pour chaque noeud
      for (int i2 = 1; i2 <= nbnoeudmax; i2++)
         { // lecture d'un premier enregistrement
           entreePrinc->NouvelleDonnee();
           Noeud_LesMaille(i1,i2).LectureDeplacements(entreePrinc);
         }
     }       
 };
  
     
// mise en place du travail à t  sur les maillages
// indique que l'on va utiliser les ddl en 0, t
// si les grandeurs en tdt existaient, elles sont supprimées
void LesMaillages::Travail_t()
  { 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);
          // construit les tableaux de ddl a t
          noo->Travail_t();
         } 
      }       
   };

// mise en place du travail à t tdt sur les maillages
// indique que l'on va utiliser les ddl en 0, t, tdt
void LesMaillages::Travail_tdt()
  { 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);
          // construit les tableaux de ddl a t
          noo->Travail_tdt();
         }
      }
   };


// idem pour un maillage donné de numéro num
void LesMaillages::Travail_t(int num)
  {   int nbnoeudmax = tabMaillage(num)->Nombre_noeud();
      for (int i2 = 1; i2 <= nbnoeudmax; i2++)
        { // recup du noeud
          Noeud * noo = & Noeud_LesMaille(num,i2);
          // construit les tableaux de ddl a t
          noo->Travail_t();
         } 
   };
  
// définition des coordonnées à t identiques à ceux à t=0,
void LesMaillages::Insert_coord1()
  { 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);
          // construit les coordonnées de ddl a t
          noo->Insert_coord1();
         }
      }    
   };
        
// ramène le maximum de variation de coordonnée entre t et tdt de tous les noeuds du maillage
double LesMaillages::Max_var_dep_t_a_tdt() const
 { double ret=0.;
   for (int i1 = 1; i1<= nbMaillageTotal; i1++)
     ret=MaX(tabMaillage(i1)->Max_var_dep_t_a_tdt(),ret);
    return ret;  
  };
  
// ramène le minimum de la distance entre deux noeuds de l'ensemble des éléments pour tous les maillages
double LesMaillages::Min_dist2Noeud_des_elements(Enum_dure temps) const
 { double ret=ConstMath::tresgrand;
   for (int i1 = 1; i1<= nbMaillageTotal; i1++)
     ret=MiN(tabMaillage(i1)->Min_dist2Noeud_des_elements(temps),ret);
    return ret;  
  };