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

#include <iomanip>
#include <algorithm>
#include "CharUtil.h"
#include "Coordonnee2.h"
#include "ConstMath.h"
#include "MathUtil.h"
#include "Banniere.h"
#include "TypeQuelconqueParticulier.h"

// choix de l'isovaleur à visualiser calculée à partir des grandeurs évoluées aux points d'intégrations
void Isovaleurs_Gid::ChoixIsovaleur_tensorielle_ptinteg(const string& choix)
 { // tout d'abord on traite le cas de tous les isovaleurs
   if (choix=="to")
    { tabelement_evoluee_retenu = tabelement_evoluee;
      return; 
     }
   else if (choix=="de")
    { // on prend le premier élément de chaque maillage et on statut en fonction de son type
      int nbmail = tabelement_evoluee.Taille();
      for (int imail = 1;imail<=nbmail;imail++)
       {List_io < TypeQuelconque >& element_evoluee = tabelement_evoluee(imail); // pour simplifier
        List_io < TypeQuelconque >& element_evoluee_retenu = tabelement_evoluee_retenu(imail); // pour simplifier
        List_io < TypeQuelconque >::iterator iq,iqfin=element_evoluee.end();
        List_io < TypeQuelconque >::iterator iqev,iqevfin;
        Element& ele = lesMail->Element_LesMaille(imail,1);
        Element::Signature signa =  ele.Signature_element();
        switch (signa.id_problem)
         { case MECA_SOLIDE_DEFORMABLE:  
           {// c'est avec les types évoluées que l'on travaille, on sort la contrainte et la déformation courante
            // tout d'abord les grandeurs communes:
            //   a) on sort les contraintes 
            for (iq=element_evoluee.begin();iq!=iqfin;iq++) 
                      {if ((*iq).EnuTypeQuelconque()== CONTRAINTE_COURANTE) break;};
            if (iq != iqfin) 
             { // on enregistre s'il n'existe pas déjà
               iqevfin=element_evoluee_retenu.end();
               for (iqev=element_evoluee_retenu.begin();iqev!=iqevfin;iqev++) 
                      {if ((*iqev).EnuTypeQuelconque()== CONTRAINTE_COURANTE) break;};
               if (iqev == iqevfin)element_evoluee_retenu.push_back(*iq);
              };
            //   b) et les déformations
            for (iq=element_evoluee.begin();iq!=iqfin;iq++) 
                      {if ((*iq).EnuTypeQuelconque()== DEFORMATION_COURANTE) break;};
            if (iq != iqfin) 
             { // on enregistre s'il n'existe pas déjà
               iqevfin=element_evoluee_retenu.end();
               for (iqev=element_evoluee_retenu.begin();iqev!=iqevfin;iqev++) 
                      {if ((*iqev).EnuTypeQuelconque()== DEFORMATION_COURANTE) break;};
               if (iqev == iqevfin) element_evoluee_retenu.push_back(*iq);
              }; 
            // puis choix en fonction de l'évolution temporelle
            switch  (Evolution_temporelle_du_calcul(ParaGlob::param->TypeCalcul_maitre()))
             { case DYNAMIQUE:
                { // on sort les vitesses de déformation 
                  for (iq=element_evoluee.begin();iq!=iqfin;iq++) 
                      {if ((*iq).EnuTypeQuelconque()== VITESSE_DEFORMATION_COURANTE) break;};
                  if (iq != iqfin) 
                   { // on enregistre s'il n'existe pas déjà
                     iqevfin=element_evoluee_retenu.end();
                     for (iqev=element_evoluee_retenu.begin();iqev!=iqevfin;iqev++) 
                            {if ((*iqev).EnuTypeQuelconque()== VITESSE_DEFORMATION_COURANTE) break;};
                     if (iqev == iqevfin) element_evoluee_retenu.push_back(*iq);
                    }; 
                  break;
                 }
               default: break; // pour les autres cas, pour l'instant on ne fait rien
              };
             break;
            } //-- fin du cas MECA_SOLIDE_DEFORMABLE
           default: 
             cout << "\n pour l'instant pas de parametre par defaut pour les pt integ !! "
                << "\n pour le type de problem : " << NomElemTypeProblem(signa.id_problem) 
                << "\n on continue sur le cas general ";
          };
         }; //-- fin de la boucle sur les maillages 
       return;          
     };  
   // maintenant on traite le cas interactif
   string rep;
   bool choix_valide = false;   
   cout << "\n  choix d'isovaleur (grandeurs evoluees) aux pt d'integ a visualiser ";
   int nbmail = tabelement_evoluee.Taille();
   // update du tableau evolues à visualiser si nécessaire
   if (tabelement_evoluee_retenu.Taille() != nbmail)
       tabelement_evoluee_retenu.Change_taille(nbmail);
   for (int imail = 1;imail<=nbmail;imail++)
    {// on ne traite que s'il y a des grandeurs disponibles
     if (tabelement_evoluee(imail).size() != 0 )
     {choix_valide=false;
      while (!choix_valide) // premier while
      {try 
        { cout << "\n (0 ou f ou fin) fin choix grandeurs tensorielles ";
          cout << "\n listes de type de grandeur tensorielles a visualiser ";
          // affichage des grandeurs retenues si la liste n'est pas vide
          if ((tabelement_evoluee_retenu(imail)).size())
                 { cout << "\n Maillage nb: " << imail << "\n  liste des types de grandeurs enregistres:   ";  
                   List_io < TypeQuelconque >::iterator iet,ietfin = (tabelement_evoluee_retenu(imail)).end();
                   for (iet=(tabelement_evoluee_retenu(imail)).begin();iet!=ietfin;iet++)
                     cout << ((*iet).EnuTypeQuelconque()).NomPlein() << " " ;
                   cout << endl;  
                  };
          cout << "\n Maillage nb: " << imail << " liste des types de grandeurs tensorielles disponibles ";
          List_io < TypeQuelconque >::iterator iet,ietfin = (tabelement_evoluee(imail)).end();
          for (iet=(tabelement_evoluee(imail)).begin();iet!=ietfin;iet++)
                     cout << "\n " << ((*iet).EnuTypeQuelconque().NomPlein()) ;
          // le menu
          cout << "\n donner la grandeur a visulaliser "
               << "\n (to) toutes les grandeurs "
               << "\n (de) les grandeurs par defaut"
               << "\n (une liste de grandeurs tensorielles) "
               << "\n (ef)               pour effacer la liste "
               << "\n (0 ou f ou fin)    fin choix grandeur tensorielle "
               << "\n reponse ?  ";
          rep = lect_return_defaut(false,"f");
          if (rep == "fin_prog") Sortie(1);
          if (rep == "to")
           {// cas de toutes les grandeurs
            tabelement_evoluee_retenu(imail) = tabelement_evoluee(imail);
            choix_valide=false;
            };
          // sinon
          if ((rep == "0") || (rep == "f") || (rep == "fin")) 
              {choix_valide=true;}
          else if (rep=="ef")
            { tabelement_evoluee_retenu(imail).erase(tabelement_evoluee_retenu(imail).begin(),
                      tabelement_evoluee_retenu(imail).end());
              }
          else if (rep=="de")
           {List_io < TypeQuelconque >& element_evoluee = tabelement_evoluee(imail); // pour simplifier
            List_io < TypeQuelconque >& element_evoluee_retenu = tabelement_evoluee_retenu(imail); // pour simplifier
            List_io < TypeQuelconque >::iterator iq,iqfin=element_evoluee.end();
            List_io < TypeQuelconque >::iterator iqev,iqevfin;
            Element& ele = lesMail->Element_LesMaille(imail,1);
            Element::Signature signa =  ele.Signature_element();
            switch (signa.id_problem)
             { case MECA_SOLIDE_DEFORMABLE:
                 {// c'est avec les types évoluées que l'on travaille, on sort la contrainte et la déformation courante
                  // tout d'abord les grandeurs communes:
                  //   a) on sort les contraintes
                  for (iq=element_evoluee.begin();iq!=iqfin;iq++)
                            {if ((*iq).EnuTypeQuelconque()== CONTRAINTE_COURANTE) break;};
                  if (iq != iqfin)
                   { // on enregistre s'il n'existe pas déjà
                     iqevfin=element_evoluee_retenu.end();
                     for (iqev=element_evoluee_retenu.begin();iqev!=iqevfin;iqev++)
                        {if ((*iqev).EnuTypeQuelconque()== CONTRAINTE_COURANTE) break;};
                     if (iqev == iqevfin)element_evoluee_retenu.push_back(*iq);
                    };
                  //   b) et les déformations
                  for (iq=element_evoluee.begin();iq!=iqfin;iq++)
                            {if ((*iq).EnuTypeQuelconque()== DEFORMATION_COURANTE) break;};
                  if (iq != iqfin)
                    { // on enregistre s'il n'existe pas déjà
                      iqevfin=element_evoluee_retenu.end();
                      for (iqev=element_evoluee_retenu.begin();iqev!=iqevfin;iqev++)
                        {if ((*iqev).EnuTypeQuelconque()== DEFORMATION_COURANTE) break;};
                      if (iqev == iqevfin) element_evoluee_retenu.push_back(*iq);
                     };
                  // puis choix en fonction de l'évolution temporelle
                  switch  (Evolution_temporelle_du_calcul(ParaGlob::param->TypeCalcul_maitre()))
                   { case DYNAMIQUE:
                      { // on sort les vitesses de déformation
                        for (iq=element_evoluee.begin();iq!=iqfin;iq++)
                            {if ((*iq).EnuTypeQuelconque()== VITESSE_DEFORMATION_COURANTE) break;};
                        if (iq != iqfin)
                         { // on enregistre s'il n'existe pas déjà
                           iqevfin=element_evoluee_retenu.end();
                           for (iqev=element_evoluee_retenu.begin();iqev!=iqevfin;iqev++)
                              {if ((*iqev).EnuTypeQuelconque()== VITESSE_DEFORMATION_COURANTE) break;};
                           if (iqev == iqevfin) element_evoluee_retenu.push_back(*iq);
                          };
                        break;
                       }
                     default: break; // pour les autres cas, pour l'instant on ne fait rien
                   };
                  break;
                 } //-- fin du cas MECA_SOLIDE_DEFORMABLE
               default:
                  cout << "\n pour l'instant pas de parametre par defaut pour les pt integ !! "
                       << "\n pour le type de problem : " << NomElemTypeProblem(signa.id_problem) 
                       << "\n on continue sur le cas general ";
             };
            }
          else if (TypeQuelconque_enum_etendu::VerifExistence(rep) ) // vérif que c'est une grandeur possible
            { // maintenant on vérifie qu'elle appartient à la liste des grandeurs disponibles
              TypeQuelconque a(TypeQuelconque_enum_etendu::RecupTypeQuelconque_enum_etendu(rep)); // création d'un type quelconque sans grandeur
              List_io<TypeQuelconque>& tpg_ret = (tabelement_evoluee_retenu(imail)); // pour simplifier
              List_io<TypeQuelconque>& tpg = (tabelement_evoluee(imail)); // pour simplifier
              if (find(tpg.begin(),tpg.end(),a) != tpg.end())
                { // il existe -> enregistrement
                  List_io<TypeQuelconque>::iterator il = find(tpg.begin(),tpg.end(),a); // récup du réel type
                  // s'il n'existe pas déjà on l'enregistre vraiment
                  if (find(tpg_ret.begin(),tpg_ret.end(),a) == tpg_ret.end())
                       tpg_ret.push_back(*il);
                  }
              else
                { cout << "\n erreur, grandeur non disponible !, recommencez ";};
             }
          }
        catch (ErrSortieFinale)
             // cas d'une direction voulue vers la sortie
             // on relance l'interuption pour le niveau supérieur
           { ErrSortieFinale toto;
             throw (toto);
           }
        catch (...)// erreur en lecture
          {  cout << "\n Erreur dans la lecture evolues !!, "
                  << "\n redonnez une bonne valeur"
                  << "\n ou taper fin_prog pour arreter le programme"; 
             choix_valide=false;
           }
      } //-- fin du premier while 
      tabelement_evoluee_retenu(imail).sort(); // on ordonne
      tabelement_evoluee_retenu(imail).unique();// on supprime les doublons                           
      }; //-- fin de if (tabelement_typeParti(imail).size() != 0 )                          
     };//-- fin de la boucle sur les maillages  
  };  
  
// choix de l'isovaleur à visualiser calculée à partir des grandeurs quelconques aux points d'intégrations
void Isovaleurs_Gid::ChoixIsovaleur_quelc_ptinteg(const string& choix)
 { // tout d'abord on traite le cas de tous les isovaleurs
   if (choix=="to")
    { tabelement_typeParti_retenu = tabelement_typeParti;
      return;
     }
   else if (choix=="de")
    { // pour l'instant aucun éléments par défaut
      return;
     };  
   // maintenant on traite le cas interactif   
   bool choix_valide = false;
   string rep;
   cout << "\n  choix d'isovaleur aux pt d'integ a visualiser (de type grandeurs particulieres) ";
   int nbmail = tabelement_typeParti.Taille();
   // update du tableau de ddl à visualiser si nécessaire
   if (tabelement_typeParti_retenu.Taille() != nbmail)
       tabelement_typeParti_retenu.Change_taille(nbmail);

   for (int imail = 1;imail<=nbmail;imail++)
    {// on ne traite que s'il y a des grandeurs disponibles
     if (tabelement_typeParti(imail).size() != 0 )
     {choix_valide=false;
      while (!choix_valide) // premier while
      {try 
        { cout << "\n (0 ou f ou fin) fin choix grandeurs particulieres ";
          cout << "\n listes de type de grandeur particuliere a visualiser ";
          // affichage des ddl retenues si la liste n'est pas vide
          if ((tabelement_typeParti_retenu(imail)).size())
                 { cout << "\n Maillage nb: " << imail << "\n  liste des types de grandeurs enregistres:   ";  
                   List_io < TypeQuelconque >::iterator iet,ietfin = (tabelement_typeParti_retenu(imail)).end();
                   for (iet=(tabelement_typeParti_retenu(imail)).begin();iet!=ietfin;iet++)
                     cout << ((*iet).EnuTypeQuelconque().NomPlein()) << " " ;
                   cout << endl;  
                  };
          cout << "\n Maillage nb: " << imail << " liste des types de grandeur particuliere disponibles ";
          List_io < TypeQuelconque >::iterator iet,ietfin = (tabelement_typeParti(imail)).end();
          for (iet=(tabelement_typeParti(imail)).begin();iet!=ietfin;iet++)
                     cout << "\n " << ((*iet).EnuTypeQuelconque().NomPlein()) ;
          cout << "\n donner la grandeur particuliere a visulaliser "
               << "\n (to) tous les grandeurs particulieres "
               << "\n ou une liste de grandeurs particulieres "
               << "\n (0 ou f ou fin) fin choix de grandeurs particulieres "
               << "\n reponse ?  ";
          rep = lect_return_defaut(false,"f");
          if (rep == "fin_prog") Sortie(1);
          if (rep == "to")
           {// cas de tous les ddl
            tabelement_typeParti_retenu(imail) = tabelement_typeParti(imail);
            choix_valide=false;
            };
          // sinon
          if ((rep == "0") || (rep == "f") || (rep == "fin")) 
              {choix_valide=true;}
          else if (TypeQuelconque_enum_etendu::VerifExistence(rep) ) // vérif que c'est une grandeur possible
            { // maintenant on vérifie qu'elle appartient à la liste des grandeurs disponibles
              TypeQuelconque a(TypeQuelconque_enum_etendu::RecupTypeQuelconque_enum_etendu(rep)); // création d'un type quelconque sans grandeur
              List_io<TypeQuelconque>& tpg_ret = (tabelement_typeParti_retenu(imail)); // pour simplifier
              List_io<TypeQuelconque>& tpg = (tabelement_typeParti(imail)); // pour simplifier
              if (find(tpg.begin(),tpg.end(),a) != tpg.end())
                { // il existe -> enregistrement
                  List_io<TypeQuelconque>::iterator il = find(tpg.begin(),tpg.end(),a); // récup du réel type
                  // s'il n'existe pas déjà on l'enregistre vraiment
                  if (find(tpg_ret.begin(),tpg_ret.end(),a) == tpg_ret.end())
                       tpg_ret.push_back(*il);
                  }
              else
                { cout << "\n erreur, grandeur non disponible !, recommencez ";};
             }
          }
        catch (ErrSortieFinale)
             // cas d'une direction voulue vers la sortie
             // on relance l'interuption pour le niveau supérieur
           { ErrSortieFinale toto;
             throw (toto);
           }
        catch (...)// erreur en lecture
          {  cout << "\n Erreur dans la lecture de grandeur particuliere !!, "
                  << "\n redonnez une bonne valeur"
                  << "\n ou taper fin_prog pour arreter le programme"; 
             choix_valide=false;
           }
      } //-- fin du premier while 
      tabelement_typeParti_retenu(imail).sort(); // on ordonne
      tabelement_typeParti_retenu(imail).unique();// on supprime les doublons 
      }; //-- fin de if (tabelement_typeParti(imail).size() != 0 )                          
     }//-- fin de la boucle sur les maillages   
  };
  
// choix de grandeur existantes aux points d'intégrations et à ramener aux noeuds
// pour préparer une visualisation d'isovaleurs
void Isovaleurs_Gid::TransfertGrandeursPtIntegAuNoeud()
 { cout << "\n transfert aux noeuds (rep o ou n) ";
   string rep; rep = lect_o_n(false);
   if (rep == "o") 
     { transfert_au_noeud = true; cout << "\n transfert aux noeuds enregistre ";}
   else 
     { transfert_au_noeud = false; cout << "\n transfert aux noeuds desactives ";};
/*   // on signale que les ddl étendues autres que pur ne seront pas transférés  
   // on boucle sur les maillages
   int nb_mail=lesMail->NbMaillage();
   for (int imail=1;imail<=nb_mail;imail++)
       { // pour les ddl on crée soit une liste de ddl pur soit un type quelconque scalaire
         // seul le premier cas peut-être traité directement, sinon il faut utiliser un type interne
         // ce choix est fait pour éviter de multiplier les types de stockage au niveau des noeuds
         // on ne veut pas de type Ddl_enum_etendu qui nécessitera un indressage indirecte très couteux
         List_io < Ddl_enum_etendu >& element_type_ddl_retenu = tabelement_type_ddl_retenu(imail);
         List_io < Ddl_enum_etendu >::iterator ilddl,ilddlfin=element_type_ddl_retenu.end();
         List_io < Enum_ddl > lienu;
         for (ilddl=element_type_ddl_retenu.begin(); ilddl != ilddlfin; ilddl++)
          { if (!(*ilddl).Nom_vide())
              // c'est un ddl non pur
              { cout << "\n ** attention, le ddl " << (*ilddl).Nom() 
                     << " ne sera pas transfere aux noeuds, si l'on veut cette grandeur, il faut la definir "
                     << " aux niveaux des grandeurs tensorielles ou particulieres !! ";
                };
            };         
        }; */ 

  };
  
// initialisation de l'exécution du  transferts
void Isovaleurs_Gid::InitPremierIncrExecutionTransfertAuxNoeuds() 
 { if (transfert_au_noeud)
    {// cas du premier incrément et que l'on veut un transfert
     // l'objectif est d'initialiser de manière a doc les noeuds (introduire les grandeurs)
     // on boucle sur les maillages
     int nb_mail=lesMail->NbMaillage();
     for (int imail=1;imail<=nb_mail;imail++)
      { lesMail->AjoutConteneurAuNoeud(imail,glob_elem_ddl_retenu,tab_quelconque);
      };
    };
 };
      
// définition interactives des paramètres généraux des isovaleurs
void Isovaleurs_Gid::ParametresGeneraux(const string& choix)
 { // tout d'abord on traite le cas de tous les isovaleurs
   if (choix=="to")
    { ddlSurY_1D = true;
      return;
     };
   // maintenant on traite le cas interactif   
   bool choix_valide = false;
   cout << "\n  parametre par defaut ? : dans le cas d'element 1D, ddl sortie en y,"
        << "\n  composantes des tenseurs dans le repere absolu,"
        << "   (rep 'o') pour accepter ces parametres sinon autre ";
   string rep;
   cout << "\n reponse ? "; rep = lect_return_defaut(true,"o");
   if (rep != "o") 
    {// cas d'un choix autre que standart
     while (!choix_valide)
      {
       try 
        {cout 
         << "\n (0) (ou f ou fin) fin modif "
         << "\n (1) ddl selon y dans le cas 1D "
         << "\n (2) sortie des tenseurs dans le repere absolu (par defaut) "
         << "\n (3) sortie des tenseurs dans un repere ad hoc, qui depend du type d'element ";
         cout << "\n \n reponse ? ";
         rep = lect_return_defaut(false,"f");
         if (rep == "fin_prog") Sortie(1);
         if ((rep == "0")||(rep == "f")||(rep == "fin")) 
            { choix_valide = true;}
          // sinon
         else
          {int num = ChangeEntier(rep);
           if (num == 0) {choix_valide=true;}
           else if ((num >= 1)&&(num<=3))
           { choix_valide=false;
             switch (num)
              { case 1:  //ddl selon y dans le cas 1D
                { cout << "\n sortie ddl selon y ? (rep o ou n) ";
                  rep = lect_o_n(false);
                  if (rep == "o") {ddlSurY_1D=true; cout << "\n enregistrement sortie selon y ";}
                  else {ddlSurY_1D=false; cout << "\n enregistrement sortie selon x ";};
                  break;
                 }
               case 2:  //en absolue
                { absolue = true;
                  break;
                 }
               case 3:  // repère ad hoc
                { absolue = false;
                  break;
                 }
              }
             } 
           else { cout << "\n Erreur on attendait un entier entre 0 et 3 !!, "
                      << "\n redonnez une bonne valeur"
                      << "\n ou taper fin_prog pour arreter le programme"; 
                  choix_valide=false;
                 }
            }
          }      
       catch (ErrSortieFinale)
            // cas d'une direction voulue vers la sortie
            // on relance l'interuption pour le niveau supérieur
          { ErrSortieFinale toto;
            throw (toto);
          }
       catch (...)// erreur de lecture
       {  cout << "\n Erreur on attendait un des mots cles proposés !!, "
                      << "\n redonnez une bonne valeur"
                      << "\n ou taper fin_prog pour arreter le programme"; 
              choix_valide=false;
        }
       } //-- fin du while
    }      
  };

// sortie de l'entête des isovaleurs de grandeurs definis aux pt integ pour des grandeurs quelconques
// et également tout simplement aux noeuds
// sert pour les sorties aux pt integ et aux noeuds
    // -- 1) le programme général quelque soit la structure (simple, tableau, list ... ) de la grandeur quelconque
    // drap_noeud = false  ---> sortie aux pt integ, =true  ---> sortie aux noeuds
void Isovaleurs_Gid::EnteteSortieIsovaleurs_G_Quelconque(ostream & sort,TypeQuelconque& typ,bool drap_noeud)
 { EnumTypeGrandeur enugrandeur = typ.EnuTypeGrandeur();
   // maintenant on regarde s'il s'agit d'une seule grandeur ou d'un tableau
   EnumType2Niveau  enuStructure = typ.Const_Grandeur_pointee()->Type_structure_grandeurAssocie();
   
   switch (enuStructure)
   	{ case TYPE_SIMPLE: 
       { int dima = 0; 
         switch (enugrandeur)
            { case TENSEURBB: 
               { dima= Abs(((Grandeur_TenseurBB*) typ.Grandeur_pointee())->ConteneurTenseur()->Dimension());break; }                 
              case TENSEURHH:
               { dima= Abs(((Grandeur_TenseurHH*) typ.Grandeur_pointee())->ConteneurTenseur()->Dimension());break; }  
              case COORDONNEE: 
               { dima= Abs(((Grandeur_coordonnee*) typ.Grandeur_pointee())->ConteneurCoordonnee()->Dimension());break; }
              case SCALAIRE: case SCALAIRE_ENTIER: case SCALAIRE_DOUBLE:  
               { dima = 1; break;}
              // le cas par défaut sera géré dans  EnteteSortieIsovaleurs_G_Quelconque_TYPE_SIMPLE
              default: break;
            };//-- fin du  switch (enugrandeur)
         string nom_typeQuelconque((typ.EnuTypeQuelconque().NomPlein()));
         if (drap_noeud)  nom_typeQuelconque += "_N";
         EnteteSortieIsovaleurs_G_Quelconque_TYPE_SIMPLE(sort,*(typ.Grandeur_pointee()),nom_typeQuelconque,dima);
         break;
       }
   	  case TABLEAU_T: 
       {  switch (enugrandeur)
            { case TENSEURHH:
               { Tab_Grandeur_TenseurHH& tab_tensHH =  *((Tab_Grandeur_TenseurHH*) typ.Grandeur_pointee());
                 int taille = tab_tensHH.Taille();
                 // on boucle, et on sort une entête pour chaque tenseur
                 for (int i=1;i<=taille;i++)
                   { int dima = Abs(tab_tensHH(i).Dimension());
                     string nom_typeQuelconque=(typ.EnuTypeQuelconque().NomPlein())+ChangeEntierSTring(i);
                     if (drap_noeud)  nom_typeQuelconque += "_N";
                 	 EnteteSortieIsovaleurs_G_Quelconque_TYPE_SIMPLE(sort,*(typ.Grandeur_pointee()),nom_typeQuelconque,dima);
                 	};
                 break; 
               }
              case SCALAIRE: case SCALAIRE_ENTIER: case SCALAIRE_DOUBLE: 
               { // dans ce cas EnteteSortieIsovaleurs_G_Quelconque_TYPE_SIMPLE est conçu pour
                 // pour sortir directement l'entête des n scalaires 
           // !!! non ça ne marche pas on modifie      
                 //int dima = 1;
                 //string nom_typeQuelconque=NomTypeQuelconque_court(typ.EnuTypeQuelconque());   
                 //if (drap_noeud)  nom_typeQuelconque += "_N";
                 //EnteteSortieIsovaleurs_G_Quelconque_TYPE_SIMPLE(sort,*(typ.Grandeur_pointee()),nom_typeQuelconque,dima);
                 Tab_Grandeur_scalaire_double& tab_scal =  *((Tab_Grandeur_scalaire_double*) typ.Grandeur_pointee());
                 int taille = tab_scal.Taille();
                 // on boucle, et on sort une entête pour chaque scalaire
                 for (int i=1;i<=taille;i++)
                   { int dima = 1;
                     string nom_typeQuelconque=(typ.EnuTypeQuelconque().NomPlein())+ChangeEntierSTring(i);
                     if (drap_noeud)  nom_typeQuelconque += "_N";
                 	 EnteteSortieIsovaleurs_G_Quelconque_TYPE_SIMPLE(sort,*(typ.Grandeur_pointee()),nom_typeQuelconque,dima);
                 	};
                 break; 
               }
              case COORDONNEE:
               { Tab_Grandeur_Coordonnee& tab_coor =  *((Tab_Grandeur_Coordonnee*) typ.Grandeur_pointee());
                 int taille = tab_coor.Taille();
                 // on boucle, et on sort une entête pour chaque coordonnée
                 for (int i=1;i<=taille;i++)
                   { int dima = tab_coor(i).Dimension();
                     string nom_typeQuelconque=(typ.EnuTypeQuelconque().NomPlein())+ChangeEntierSTring(i);
                     if (drap_noeud)  nom_typeQuelconque += "_N";
                 	 EnteteSortieIsovaleurs_G_Quelconque_TYPE_SIMPLE(sort,*(typ.Grandeur_pointee()),nom_typeQuelconque,dima);
                 	};
                 break; 
               }
              default:
                cout << "\n attention : cas de sortie de grandeur tableau non implantee (mais il suffit de le demander !!) "; 
                typ.Grandeur_pointee()->Ecriture_grandeur(sort);
                cout << "\n Isovaleurs_Gid::EnteteSortieIsovaleurs_G_Quelconque(... ";
            };//-- fin du  switch (enugrandeur)
         break;
       }
      default:            
        cout << "\n attention : cas de sortie de grandeur de type secondaire " << NomType2Niveau(enuStructure) 
             << " non implantee (mais il suffit de le demander !!) "; 
        typ.Grandeur_pointee()->Ecriture_grandeur(sort);
        cout << "\n Isovaleurs_Gid::EnteteSortieIsovaleurs_G_Quelconque(... ";
   	}; 
 };

// -- 2) le programme spécifique pour "une" grandeur de base (utilisé en 1))
void Isovaleurs_Gid::EnteteSortieIsovaleurs_G_Quelconque_TYPE_SIMPLE
         (ostream & sort,const TypeQuelconque::Grandeur& grandeur,const string nom_typeQuelconque, int dima)
 { EnumTypeGrandeur enugrandeur = grandeur.Type_grandeurAssocie();
   sort << "\n ResultDescription \"";
   switch (enugrandeur)
     { case TENSEURBB: 
       {switch (dima)
         {case 3:{sort << nom_typeQuelconque << "\" Matrix "; 
                  sort << "\n     ComponentNames \"A11\", \"A22\", \"A33\", \"A12\", \"A23\", \"A13\" ";
                  break;}
          case 2:
          {sort << nom_typeQuelconque << "\" PlainDeformationMatrix  "; 
           sort << "\n     ComponentNames \"A11\", \"A22\", \"A12\", \"A33\" "; break;}
          case 1:
          {sort << nom_typeQuelconque << "\" Scalar "; break;}
          default: { cout << "\n dimension inconsistante de tenseurBB = " << dima
                          << " la sortie sera inexploitable sur Gid ";
                     if (ParaGlob::NiveauImpression() > 5) cout << "\n Isovaleurs_Gid::ExeOrdre(...";
                    };
          }
        break;                  
        }
      case TENSEURHH:
      {switch (dima)
         {case 3:{sort << nom_typeQuelconque << "\" Matrix "; 
                  sort << "\n     ComponentNames \"A11\", \"A22\", \"A33\", \"A12\", \"A23\", \"A13\" ";
                  break;}
          case 2:
          {sort << nom_typeQuelconque << "\" PlainDeformationMatrix  "; 
           sort << "\n     ComponentNames \"A11\", \"A22\", \"A12\", \"A33\" "; break;}
          case 1:
          {sort << nom_typeQuelconque << "\" Scalar "; break;}
          default: { cout << "\n dimension inconsistante de tenseurHH = " << dima
                          << " la sortie sera inexploitable sur Gid ";
                     if (ParaGlob::NiveauImpression() > 5) 
                        cout << "\n Isovaleurs_Gid::EnteteSortieIsovaleurs_G_Quelconque(...";
                    };
          }                
       break; 
       }  
      case COORDONNEE: 
       {switch (dima)
           {case 3: case 2: // dans le cas dim 2 on rajoute un 0
                    {sort << nom_typeQuelconque << "\" Vector "; 
                     sort << "\n     ComponentNames \"U1\", \"U2\", \"U3\" "; break;}
            case 1: {sort << nom_typeQuelconque << "\" Scalar "; break;} 
            default: { cout << "\n dimension inconsistante de Coordonnee = " << dima
                            << " la sortie sera inexploitable sur Gid ";
                       if (ParaGlob::NiveauImpression() > 5) 
                          cout << "\n Isovaleurs_Gid::EnteteSortieIsovaleurs_G_Quelconque(...";
                      }; 
            };                
        break;
        }
      case SCALAIRE: case SCALAIRE_ENTIER: case SCALAIRE_DOUBLE:  
        { sort << nom_typeQuelconque << "\" Scalar "; break;}
      default :
        {// sinon on sort n scalaires correspondant aux n scalaires composants la grandeur
         int nbmax = grandeur.NbMaxiNumeroOrdre();
         if (nbmax != 0)
            sort << nom_typeQuelconque +ChangeEntierSTring(1) << "\" Scalar ";
         for (int i=2;i<=nbmax;i++)
          { sort << "\n ResultDescription \"";
            sort << nom_typeQuelconque+ChangeEntierSTring(i)<< "\" Scalar ";
           };
         }
     };//-- fin du  switch (enugrandeur)
 };   



// sortie d'une grandeurs quelconque aux pt integ
    // -- a) le programme général quelque soit la structure (simple, tableau, list ... ) de la grandeur quelconque
void Isovaleurs_Gid::SortieGrandeursQuelconque(ostream & sort,const TypeQuelconque& typ)
 { // on regarde s'il s'agit d'une seule grandeur ou d'un tableau
   EnumType2Niveau  enuStructure = typ.Const_Grandeur_pointee()->Type_structure_grandeurAssocie();
   
   switch (enuStructure)
   	{ case TYPE_SIMPLE: 
       { int dima = 0; 
         switch (typ.EnuTypeGrandeur())
            { case TENSEURBB: 
               { dima= Abs(((Grandeur_TenseurBB*) typ.Const_Grandeur_pointee())->RefConteneurTenseur().Dimension());break; }                 
              case TENSEURHH:
               { dima= Abs(((Grandeur_TenseurHH*) typ.Const_Grandeur_pointee())->RefConteneurTenseur().Dimension());break; }  
              case COORDONNEE: 
               { dima= Abs(((Grandeur_coordonnee*) typ.Const_Grandeur_pointee())->ConteneurCoordonnee()->Dimension());break; }
              case SCALAIRE: case SCALAIRE_ENTIER: case SCALAIRE_DOUBLE:  
               { dima = 1; break;}
              // le cas par défaut sera géré dans  SortieGrandeursQuelconque_TYPE_SIMPLE
              default: break;
            };//-- fin du  switch (enugrandeur)
         SortieGrandeursQuelconque_TYPE_SIMPLE(sort,*(typ.Const_Grandeur_pointee()),dima);
         break;
       }
   	  case TABLEAU_T: 
       {  switch (typ.EnuTypeGrandeur())
            { case TENSEURHH:
               { Tab_Grandeur_TenseurHH& tab_tensHH =  *((Tab_Grandeur_TenseurHH*) typ.Const_Grandeur_pointee());
                 int taille = tab_tensHH.Taille();
                 // on boucle, et on sort  chaque tenseur
                 for (int i=1;i<=taille;i++)
                   { int dima = Abs(tab_tensHH(i).Dimension());
                     SortieGrandeursQuelconque_TYPE_SIMPLE(sort,tab_tensHH.Grandeur_TenseurHH_associee(i),dima);
                 	};
                 break; 
               }
              case SCALAIRE: case SCALAIRE_ENTIER: case SCALAIRE_DOUBLE: 
               { int dima = 1;
                 Tab_Grandeur_scalaire_double& tab_Gdouble =  *((Tab_Grandeur_scalaire_double*) typ.Const_Grandeur_pointee());
                 int taille = tab_Gdouble.Taille();
                 // on boucle, et on sort  chaque tenseur
                 for (int i=1;i<=taille;i++)
                   SortieGrandeursQuelconque_TYPE_SIMPLE(sort,tab_Gdouble.Grandeur_scalaire_associee(i),dima);
                 break; 
               }
              case COORDONNEE:
               { Tab_Grandeur_Coordonnee& tab_coor =  *((Tab_Grandeur_Coordonnee*) typ.Const_Grandeur_pointee());
                 int taille = tab_coor.Taille();
                 // on boucle, et on sort  chaque coordonnée
                 for (int i=1;i<=taille;i++)
                   { int dima = tab_coor(i).Dimension();
                     SortieGrandeursQuelconque_TYPE_SIMPLE(sort,tab_coor.Grandeur_Coordonnee_associee(i),dima);
                 	};
                 break; 
               }
              default:
                cout << "\n attention : cas de sortie de grandeur tableau non implantee (mais il suffit de le demander !!) "; 
                typ.Const_Grandeur_pointee()->Ecriture_grandeur(sort);
                cout << "\n Isovaleurs_Gid::EnteteSortieIsovaleurs_G_Quelconque(... ";
            };//-- fin du  switch (enugrandeur)
         break;
       }
      default:            
        cout << "\n attention : cas de sortie de grandeur de type secondaire " << NomType2Niveau(enuStructure) 
             << " non implantee (mais il suffit de le demander !!) "; 
        typ.Const_Grandeur_pointee()->Ecriture_grandeur(sort);
        cout << "\n Isovaleurs_Gid::EnteteSortieIsovaleurs_G_Quelconque(... ";
   	}; 
 };

// -- b) le programme spécifique pour "une" grandeur de base (utilisé en a))
void Isovaleurs_Gid::SortieGrandeursQuelconque_TYPE_SIMPLE(ostream & sort,const TypeQuelconque::Grandeur& grandeur,int dima)
  {  
     switch (grandeur.Type_grandeurAssocie())
       { case TENSEURBB: 
          { const TenseurBB& t_BB =  ((Grandeur_TenseurBB*) &grandeur)->RefConteneurTenseur();
            switch (dima)  
             {case 1: sort << setw(ParaGlob::NbdigdoGR())  << setprecision(ParaGlob::NbdigdoGR()) << t_BB(1,1) << " "; break;
              case 2: { sort << setw(ParaGlob::NbdigdoGR()) << setprecision(ParaGlob::NbdigdoGR()) << t_BB(1,1) << " ";
                        sort << setw(ParaGlob::NbdigdoGR()) << setprecision(ParaGlob::NbdigdoGR()) << t_BB(2,2) << " ";
                        sort << setw(ParaGlob::NbdigdoGR()) << setprecision(ParaGlob::NbdigdoGR()) << t_BB(1,2) << " " 
                             <<  " 0. "; break;
                       };
              case 3: { sort << setw(ParaGlob::NbdigdoGR()) << setprecision(ParaGlob::NbdigdoGR()) << t_BB(1,1) << " ";
                        sort << setw(ParaGlob::NbdigdoGR()) << setprecision(ParaGlob::NbdigdoGR()) << t_BB(2,2) << " ";
                        sort << setw(ParaGlob::NbdigdoGR()) << setprecision(ParaGlob::NbdigdoGR()) << t_BB(3,3) << " "; 
                        sort << setw(ParaGlob::NbdigdoGR()) << setprecision(ParaGlob::NbdigdoGR()) << t_BB(1,2) << " ";
                        sort << setw(ParaGlob::NbdigdoGR()) << setprecision(ParaGlob::NbdigdoGR()) << t_BB(2,3) << " ";
                        sort << setw(ParaGlob::NbdigdoGR()) << setprecision(ParaGlob::NbdigdoGR()) << t_BB(1,3) << " "; break;
                       };
              default: cout << "\n erreur !! Isovaleurs_Gid::SortieGrandeursQuelconque_TYPE_SIMPLE(.."; Sortie(1);         
            	};
           break;                  
           }
         case TENSEURHH:
          { const TenseurHH& t_BB =  ((Grandeur_TenseurHH*) &grandeur)->RefConteneurTenseur();
            switch (dima)  
             {case 1: sort << setw(ParaGlob::NbdigdoGR())  << setprecision(ParaGlob::NbdigdoGR()) << t_BB(1,1) << " "; break;
              case 2: { sort << setw(ParaGlob::NbdigdoGR()) << setprecision(ParaGlob::NbdigdoGR()) << t_BB(1,1) << " ";
                        sort << setw(ParaGlob::NbdigdoGR()) << setprecision(ParaGlob::NbdigdoGR()) << t_BB(2,2) << " ";
                        sort << setw(ParaGlob::NbdigdoGR()) << setprecision(ParaGlob::NbdigdoGR()) << t_BB(1,2) << " " 
                             <<  " 0. "; break;
                       };
              case 3: { sort << setw(ParaGlob::NbdigdoGR()) << setprecision(ParaGlob::NbdigdoGR()) << t_BB(1,1) << " ";
                        sort << setw(ParaGlob::NbdigdoGR()) << setprecision(ParaGlob::NbdigdoGR()) << t_BB(2,2) << " ";
                        sort << setw(ParaGlob::NbdigdoGR()) << setprecision(ParaGlob::NbdigdoGR()) << t_BB(3,3) << " "; 
                        sort << setw(ParaGlob::NbdigdoGR()) << setprecision(ParaGlob::NbdigdoGR()) << t_BB(1,2) << " ";
                        sort << setw(ParaGlob::NbdigdoGR()) << setprecision(ParaGlob::NbdigdoGR()) << t_BB(2,3) << " ";
                        sort << setw(ParaGlob::NbdigdoGR()) << setprecision(ParaGlob::NbdigdoGR()) << t_BB(1,3) << " "; break;
                       };
              default: cout << "\n erreur !! Isovaleurs_Gid::SortieGrandeursQuelconque_TYPE_SIMPLE(.."; Sortie(1);         
            	};
           break;                  
           }
         case COORDONNEE: 
          {grandeur.Grandeur_brut(sort,ParaGlob::NbdigdoGR());
           if (dima==2) sort << " 0. ";
           break;
          }
         case SCALAIRE: case SCALAIRE_ENTIER: case SCALAIRE_DOUBLE:  
           { double vale = grandeur.GrandeurNumOrdre(1); // récup du scalaire
             sort << setw(ParaGlob::NbdigdoGR()) << setprecision(ParaGlob::NbdigdoGR()) << vale << " ";
             break;}
         default:
           cout << "\n erreur !! Isovaleurs_Gid::SortieGrandeursQuelconque_TYPE_SIMPLE(.."
                << "\n le type de grandeur " << NomTypeGrandeur(grandeur.Type_grandeurAssocie())
                << " n'est pas pris en compte!! " << flush ;
         Sortie(1);
         
       };//-- fin du  switch (enugrandeur)
    };   


// initialisation les différentes listes internes qui globalisent tous les maillages
void Isovaleurs_Gid::GlobalisationListSurTousLesMaillagesPourLesNoeuds()
  { // on initialise toutes les listes globales
    glob_noe_ddl_retenu.clear();
    glob_noeud_ddl_etendu_retenu.clear();
    glob_noeud_evol_retenu.clear();
    glob_elem_ddl_retenu.clear();
    glob_elem_evol_retenu.clear();
    glob_elem_Parti_retenu.clear();
    // on passe en revue tous les maillages pour crées les listes globales des grandeurs 
    int nb_mail = tabnoeud_type_ddl_retenu.Taille(); // dim des maillages, via un tableau arbitraire
    for (int imail=1;imail<= nb_mail;imail++)
      { // on merge les listes (il faut qu'avant chaque merge, les listes soient ordonnées)
        // comme l'ordre merge ajoute les listes mais en détruisant la liste initiale, on crée une liste intermédiaire
        tabnoeud_type_ddl_retenu(imail).sort();
        List_io < Ddl_enum_etendu > interDddlenumetendu(tabnoeud_type_ddl_retenu(imail));        
        glob_noe_ddl_retenu.merge(interDddlenumetendu);
        
        tabnoeud_type_ddlEtendu_retenu(imail).sort();
        List_io < Ddl_enum_etendu > inter2Dddlenumetendu(tabnoeud_type_ddlEtendu_retenu(imail));
        glob_noeud_ddl_etendu_retenu.merge(inter2Dddlenumetendu);

        tabnoeud_evoluee_retenu(imail).sort();
        List_io < TypeQuelconque > internoeudevolretenu(tabnoeud_evoluee_retenu(imail));
              
        glob_noeud_evol_retenu.merge(internoeudevolretenu);

        tabelement_type_ddl_retenu(imail).sort();
        List_io < Ddl_enum_etendu > interelemDddlenumetendu(tabelement_type_ddl_retenu(imail));
        glob_elem_ddl_retenu.merge(interelemDddlenumetendu);
        
        tabelement_evoluee_retenu(imail).sort();
        List_io < TypeQuelconque > interelemevolretenu(tabelement_evoluee_retenu(imail));
        glob_elem_evol_retenu.merge(interelemevolretenu);
        
        tabelement_typeParti_retenu(imail).sort();
        List_io < TypeQuelconque > interelempartiretenu(tabelement_typeParti_retenu(imail));        
        glob_elem_Parti_retenu.merge(interelempartiretenu);
        // on ordonne
        glob_noe_ddl_retenu.sort(); 
        glob_noeud_ddl_etendu_retenu.sort();
        glob_noeud_evol_retenu.sort();
        glob_elem_ddl_retenu.sort();
        glob_elem_evol_retenu.sort();
        glob_elem_Parti_retenu.sort();	
        // on supprime les doublons
        glob_noe_ddl_retenu.unique(); 	
        glob_noeud_ddl_etendu_retenu.unique();
        glob_noeud_evol_retenu.unique();
        glob_elem_ddl_retenu.unique();
        glob_elem_evol_retenu.unique();
        glob_elem_Parti_retenu.unique();
    	};
    // on met à jour le tableau de pointeur global
    if (glob_elem_evol_retenu.size()!=0) {tab_quelconque(1)= &glob_elem_evol_retenu;}
    else                                 {tab_quelconque(1)= NULL;};
    if (glob_elem_Parti_retenu.size()!=0){tab_quelconque(2)= &glob_elem_Parti_retenu;}
    else                                 {tab_quelconque(2)= NULL;};
    
    	
    // on définit les tableaux d'indicateurs de sortie de grandeurs
    for (int imai=1;imai<= nb_mail;imai++)
     { // initialisation des tableaux d'indicateurs
       List_io < bool >& g_noeud_type_ddl_asortir = t_g_noeud_ddl_asortir(imai); // pour simplifier
       g_noeud_type_ddl_asortir.clear();
       List_io < bool >& g_noeud_ddl_etendu_asortir = t_g_noeud_ddl_etendu_asortir(imai); // pour simplifier
       g_noeud_ddl_etendu_asortir.clear();
       List_io < bool >& g_noeud_evoluee_asortir = t_g_noeud_evoluee_asortir(imai); // pour simplifier
       g_noeud_evoluee_asortir.clear();
       List_io < bool >& g_element_ddl_asortir = t_g_elem_ddl_asortir(imai); // pour simplifier
       g_element_ddl_asortir.clear();
       List_io < bool >& g_element_evoluee_asortir = t_g_elem_evoluee_asortir(imai); // pour simplifier
       g_element_evoluee_asortir.clear();
       List_io < bool >& g_element_typeParti_asortir = t_g_elem_typeParti_asortir(imai); // pour simplifier
       g_element_typeParti_asortir.clear();
       // on passe en revue les grandeurs à sortir et on met à jour les indicateurs en conséquence

       // .. pour les ddl  aux noeuds 
       List_io < Ddl_enum_etendu >& noeud_type_ddl_retenu = tabnoeud_type_ddl_retenu(imai); // pour simplifier
       List_io < Ddl_enum_etendu >::iterator i1,i1fin=glob_noe_ddl_retenu.end();
       for (i1=glob_noe_ddl_retenu.begin();i1!=i1fin;i1++)
         if (find(noeud_type_ddl_retenu.begin(),noeud_type_ddl_retenu.end(),(*i1)) == noeud_type_ddl_retenu.end())
               {g_noeud_type_ddl_asortir.push_back(false);} // cas où le ddl initiaux n'existent pas pour le maillage considéré
         else  {g_noeud_type_ddl_asortir.push_back(true);}; // cas où le ddl initiaux existent également pour le maillage considéré

       {// .. pour les ddl étendues définis aux noeuds
        List_io < Ddl_enum_etendu >& noeud_type_ddlEtendu_retenu = tabnoeud_type_ddlEtendu_retenu(imai); // pour simplifier
        List_io < Ddl_enum_etendu >::iterator i1,i1fin=glob_noeud_ddl_etendu_retenu.end();
        for (i1=glob_noeud_ddl_etendu_retenu.begin();i1!=i1fin;i1++)
          if (find(noeud_type_ddlEtendu_retenu.begin(),noeud_type_ddlEtendu_retenu.end(),(*i1)) == noeud_type_ddlEtendu_retenu.end())
                {g_noeud_ddl_etendu_asortir.push_back(false);} // cas où le ddl étendu n'existe pas pour le maillage considéré
          else  {g_noeud_ddl_etendu_asortir.push_back(true);}; // cas où le ddl étendu existe également pour le maillage considéré
       };
       
       {// .. pour les types évoluées définis aux noeuds
        List_io < TypeQuelconque >& noeud_evoluee_retenu = tabnoeud_evoluee_retenu(imai); // pour simplifier
        List_io < TypeQuelconque >::iterator i1,i1fin=glob_noeud_evol_retenu.end();
        for (i1=glob_noeud_evol_retenu.begin();i1!=i1fin;i1++)
          if (find(noeud_evoluee_retenu.begin(),noeud_evoluee_retenu.end(),(*i1)) == noeud_evoluee_retenu.end())
                {g_noeud_evoluee_asortir.push_back(false);} // cas où le type évolué n'existe pas pour le maillage considéré
          else  {g_noeud_evoluee_asortir.push_back(true);}; // cas où le type évolué existe également pour le maillage considéré
       };

       // .. pour les ddl venant d'un transfert aux noeuds des grandeurs aux pt d'integ
       List_io < Ddl_enum_etendu >& element_type_ddl_retenu = tabelement_type_ddl_retenu(imai); // pour simplifier
       List_io < Ddl_enum_etendu >::iterator j1,j1fin=glob_elem_ddl_retenu.end();
       for (j1=glob_elem_ddl_retenu.begin();j1!=j1fin;j1++)
         if (find(element_type_ddl_retenu.begin(),element_type_ddl_retenu.end(),(*j1))== element_type_ddl_retenu.end())
               {g_element_ddl_asortir.push_back(false);} // cas où le ddl global n'existe pas pour le maillage considéré
         else  {g_element_ddl_asortir.push_back(true);}; // cas où le ddl global existe également pour le maillage considéré

       // .. pour les types évolulées venant d'un transfert aux noeuds des grandeurs aux pt d'integ
       List_io < TypeQuelconque >& element_evoluee_retenu = tabelement_evoluee_retenu(imai); // pour simplifier
       List_io < TypeQuelconque >::iterator k1,k1fin=glob_elem_evol_retenu.end();
       for (k1=glob_elem_evol_retenu.begin();k1!=k1fin;k1++)
         if (find(element_evoluee_retenu.begin(),element_evoluee_retenu.end(),(*k1))== element_evoluee_retenu.end())
               {g_element_evoluee_asortir.push_back(false);} // cas où le ddl évolué global n'existe pas pour le maillage considéré
         else  {g_element_evoluee_asortir.push_back(true);}; // cas où le ddl évolué global existe également pour le maillage considéré

       // .. pour les types particuliers aux elements venant d'un transfert aux noeuds
       List_io < TypeQuelconque >& element_typeParti_retenu = tabelement_typeParti_retenu(imai); // pour simplifier
       List_io < TypeQuelconque >::iterator m1,m1fin=glob_elem_Parti_retenu.end();
       for (m1=glob_elem_Parti_retenu.begin();m1!=m1fin;m1++)
         if (find(element_typeParti_retenu.begin(),element_typeParti_retenu.end(),(*m1))== element_typeParti_retenu.end())
               {g_element_typeParti_asortir.push_back(false);} // cas où le ddl évolué global n'existe pas pour le maillage considéré
         else  {g_element_typeParti_asortir.push_back(true);}; // cas où le ddl évolué global existe également pour le maillage considéré 
     };
	};

// vérification que le transfert peut se faire (pas de doublon de grandeurs)
// c'est un cas particulier où on veut aux noeuds, les grandeurs déjà définies au pti d'élément: normalement
// ce n'est pas courant avec gid, car gid le fait tout seul... mais c'est possible,
// du coup, on utilise la même procédure de vérification que gmsh
void Isovaleurs_Gid::VerificationTransfertPossible()
 {  // l'objectif est de vérifier qu'il n'y a pas deux grandeurs identiques  au niveau des types quelconques et évoluées
    // (ce qui posera des pb au niveau des moyennes aux noeuds)
    int nb_mail = tabnoeud_type_ddl_retenu.Taille(); // dim des maillages, via un tableau arbitraire
    for (int imail=1;imail<= nb_mail;imail++)
      { List_io < TypeQuelconque >& element_evoluee_retenu =  tabelement_evoluee_retenu(imail);
        List_io < TypeQuelconque >& element_typeParti_retenu = tabelement_typeParti_retenu(imail);
        List_io < TypeQuelconque >& noe_typeParti_retenu = tabnoeud_evoluee_retenu(imail);
        // on ordonne
        element_evoluee_retenu.sort();
        element_typeParti_retenu.sort();
        noe_typeParti_retenu.sort();
        // a priori il y a peu d'éléments donc on compare
        List_io < TypeQuelconque >::iterator i1,i1end = element_evoluee_retenu.end();
        i1=element_evoluee_retenu.begin();
        List_io < TypeQuelconque >::iterator j1,j1end = element_typeParti_retenu.end();
        j1=element_typeParti_retenu.begin();
        List_io < TypeQuelconque >::iterator k1,k1end = noe_typeParti_retenu.end();
        k1=noe_typeParti_retenu.begin();
        for (i1=element_evoluee_retenu.begin(); i1 != i1end; i1++)
          for (j1=element_typeParti_retenu.begin();j1 != j1end; j1++)
            for (k1=noe_typeParti_retenu.begin();k1 != k1end; k1++)
             { if ((*i1)==(*j1))
                {cout << "\n attention *** probleme concernant le transfert aux noeuds il ne faut pas avoir deux grandeurs identiques, or ici "
                      << "\n on a la grandeurs : " << ((*i1).EnuTypeQuelconque().NomPlein()) << " en double !! "
                      << "\n on supprime l'un d'eux ";
                 element_typeParti_retenu.erase(j1);
                };
               if ((*i1)==(*k1))
                {cout << "\n attention *** probleme concernant le transfert aux noeuds il ne faut pas avoir deux grandeurs identiques, or ici "
                      << "\n on a la grandeurs : " << ((*i1).EnuTypeQuelconque().NomPlein()) << " en double !! "
                      << "\n on supprime l'un d'eux ";
                 noe_typeParti_retenu.erase(k1);
                };
               if ((*j1)==(*k1))
                {cout << "\n attention *** probleme concernant le transfert aux noeuds il ne faut pas avoir deux grandeurs identiques, or ici "
                      << "\n on a la grandeurs : " << ((*j1).EnuTypeQuelconque().NomPlein()) << " en double !! "
                      << "\n on supprime l'un d'eux ";
                 noe_typeParti_retenu.erase(k1);
                };
             };
      };

    // de plus, il ne faut pas qu'il y ait la même  grandeur de type évoluées définis aux noeuds, qui soit également définit pour le transfert
    // des pti aux noeud, ou en ddl pur
    // (cela posera des pb au niveau des moyennes aux noeuds, et de nom de fichier de sortie)
    for (int imail=1;imail<= nb_mail;imail++)
      { List_io < Ddl_enum_etendu >& noe_ddl_retenu =  tabnoeud_type_ddl_retenu(imail);
        List_io < Ddl_enum_etendu >& noe_ddlEtendu_retenu = tabnoeud_type_ddlEtendu_retenu(imail);
        List_io < Ddl_enum_etendu >& element_type_ddl_retenu = tabelement_type_ddl_retenu(imail);
        // on ordonne
        noe_ddl_retenu.sort();
        noe_ddlEtendu_retenu.sort();
        element_type_ddl_retenu.sort();
        // a priori il y a peu d'éléments donc on compare
        List_io < Ddl_enum_etendu >::iterator i1,i1end = noe_ddl_retenu.end();
        i1=noe_ddl_retenu.begin();
        List_io < Ddl_enum_etendu >::iterator j1,j1end = noe_ddlEtendu_retenu.end();
        j1=noe_ddlEtendu_retenu.begin();
        List_io < Ddl_enum_etendu >::iterator k1,k1end = element_type_ddl_retenu.end();
        k1=element_type_ddl_retenu.begin();
        for (i1=noe_ddl_retenu.begin(); i1 != i1end; i1++)
          for (j1=noe_ddlEtendu_retenu.begin();j1 != j1end; j1++)
           for (k1=element_type_ddl_retenu.begin();k1 != k1end; k1++)
         { if ((*i1)==(*j1))
            {cout << "\n attention *** probleme concernant le transfert aux noeuds il ne faut pas avoir deux grandeurs identiques, or ici "
                  << "\n on a la grandeurs : " << (((*i1).Nom_vide()) ? Nom_ddl((*i1).Enum()) : (*i1).Nom() )
                  << " en double !! "
                  << "\n on supprime l'un d'eux ";
                noe_ddlEtendu_retenu.erase(j1);
            };
           if ((*i1)==(*k1))
            {cout << "\n attention *** probleme concernant le transfert aux noeuds il ne faut pas avoir deux grandeurs identiques, or ici "
                  << "\n on a la grandeurs : " << (((*i1).Nom_vide()) ? Nom_ddl((*i1).Enum()) : (*i1).Nom() )
                  << " en double !! "
                  << "\n on supprime l'un d'eux ";
             element_type_ddl_retenu.erase(k1);
            };
           if ((*j1)==(*k1))
            {cout << "\n attention *** probleme concernant le transfert aux noeuds il ne faut pas avoir deux grandeurs identiques, or ici "
                  << "\n on a la grandeurs : " << (((*j1).Nom_vide()) ? Nom_ddl((*j1).Enum()) : (*j1).Nom() )
                  << " en double !! "
                  << "\n on supprime l'un d'eux ";
             element_type_ddl_retenu.erase(k1);
            };
         };
      };
 };