// FICHIER : Maillage.cp
// CLASSE : Maillage

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


#include "Maillage.h"
# include <iostream>
using namespace std;  //introduces namespace std
#include <stdlib.h>
#include "Sortie.h"
#include <stdio.h>
#include <vector>
#include "List_io.h"
#include "CharUtil.h"
#ifndef SYSTEM_MAC_OS_X_unix
   #include "Frontier.h"
#endif
#include "ConstMath.h"
#include "ReferenceNE.h"
#include "ReferenceAF.h"
#include "Util.h"
#include "MvtSolide.h"
#include "Basiques.h"
#include <limits>


// définition interactive de listes de références 
void Maillage::CreationInteractiveListesRef(LesReferences* lesRef)   
 { string reponse="";
	  bool fr = ParaGlob::Francais(); // pour simplifier
   while ((reponse != "f")&&(reponse != "fi")&&(reponse != "fin"))
  	{ // def de la liste des types de références voulues
  	  list <string > list_typeReference;
	    Enum_ddl enu_ddl; // associé aux pt d'integ nécessite un enuméré associé
  	  list <string >::iterator it; 
  	  string typeReference="";
  	  while (!((typeReference == "f")||(typeReference == "fi")||(typeReference == "fin")))
      {// on initialise les listes de ref utilisées pour la def des nouvelles ref
       // de manière à ne pas utiliser les refs déjà définies
       list_refIn.clear();
       list_refOut.clear();
// debug
// cout << "\n effacement de list_refIn et list_refOut " << endl;
// fin debug
        
 	  	  // affichage du menu du type de référence voulu
 	  	  if (list_typeReference.size()!= 0)
 	  	   { if (fr) {cout << "\n type actuellement enregistre ";}
			       else    {cout << "\n type(s) already read ";};
 	  	     for (it=list_typeReference.begin();it!=list_typeReference.end();it++)
 	  	        cout << " " << *it;
 	  	   };
 	  	  if (fr)
        {cout << "\n ref de noeuds                                (rep no) "
 	  	         << "\n ref d'elements                               (rep el) "
 	  	         << "\n ref de faces                                 (rep fa) "
 	  	         << "\n ref d'arretes                                (rep ar) "
 	  	         << "\n ref de pt d'integration d'element            (rep pt) "
 	  	         << "\n toutes les ref de frontiere                  (rep tfr) "
 	  	         << "\n effacer la liste actuelle                    (rep ef) "
 	  	         << "\n fin def des types de ref voulu               (rep f) "
 	  	         << "\n reponses : (il peut y en avoir plusieurs differentes)   ";
        }
		     else 	  	      
		      {cout << "\n reference of nodes                           (rep no) "
 	  	         << "\n reference of elements                        (rep el) "
 	  	         << "\n reference of facets                          (rep fa) "
 	  	         << "\n reference of edges                           (rep ar) "
 	  	         << "\n reference of integration points              (rep pt) "
 	  	         << "\n all the references of the boundary           (rep tfr) "
 	  	         << "\n deletion of the registered references        (rep ef) "
 	  	         << "\n end of the def of the type of ref            (rep f) "
 	  	         << "\n answer : (you can set several different )   ";
        };
		  			 		 
 	  	  typeReference=lect_return_defaut(false,"f");
 	  	  if ((typeReference=="no")||(typeReference=="el")||(typeReference=="fa")
 	  	      ||(typeReference=="ar")||(typeReference=="pt"))
 	  	     { if (find(list_typeReference.begin(),list_typeReference.end(),typeReference) == list_typeReference.end())
 	  	        {list_typeReference.push_back(typeReference);}
 	  	       else
 	  	        {if (fr){cout << "\n type deja enregistre !! on n'en tient pas compte ";}
				        else   {cout << "\n ype already registered  !! we don't  consider this choice  ";};
					        }; 
 	  	      }
 	  	  else if (typeReference=="tfr")
		        {// là on crée directement les références et on continue
			        CreationRefFrontiere(*lesRef);
////--- debug
//cout << "\n debug Maillage::CreationInteractiveListesRef( ";
//lesRef->Affiche(1);
//
////--- fin debug
          }
 	  	  else if (typeReference=="ef")
 	  	     list_typeReference.erase(list_typeReference.begin(),list_typeReference.end()); 
 	  	  else if ((typeReference == "f")||(typeReference == "fi")||(typeReference == "fin"))
 	  	  	{ // fin demandé: on ne fait rien
 	  	  	}
 	  	  else 
 	  	  	{if (fr){cout << "\n mauvais choix lu : " << typeReference << ", verifiez la syntaxe et recommencez ";}
			      else   {cout << "\n bad choice  : " << typeReference << ", check your answer ";}
 	  	  	};
 	  	};
     // définition du nom des références
     string nomref; string rep = "";
     bool existe_demande_pti = false;
     if (fr){cout << "\n \n ---- acquisition des noms de references ---- ";}
	    else  {cout << "\n \n ---- reading of the reference names ---- ";}
     list <string > list_nomReference; 	
     list <string >::iterator il, ilfin = list_typeReference.end();
		
	    // si la liste est non vide on continue
	    if (	list_typeReference.size()!= 0)
	     {while ((rep != "f")&&(rep != "fi")&&(rep != "fin"))
  	  	  { // affichage du menu du type de référence voulu
  	  	    list <string >::iterator il;
 	  	     if (list_typeReference.size()!= 0)
 	  	      { if (fr){cout << "\n liste de nom de reference actuellement enregistre ";}
			          else {cout << "\n list of the already registered reference names  ";}
 	  	        for (il=list_nomReference.begin();il!=list_nomReference.end();il++)
 	  	            cout << " " << *il;
 	  	      };
		        for (il = list_typeReference.begin();il != ilfin; il++)
        	  {if (*il == "no")
        	    { bool nom_correcte = false;
        	      while (!nom_correcte)
        		      {if (fr){cout << "\n nom de la reference de noeud ? ";}else{cout << "\n name of the node reference ? ";};
                 nomref= lect_chaine();
        	        nomref = "N_"+nomref;
        	        if (!(lesRef->Existe(nomref,idmail)))
        	          {list_nomReference.push_back(nomref);
        	           nom_correcte=true;
        	          }
        	        else
        	     	    { if (fr){cout << "\n la reference " << nomref << " existe deja, choissez un autre nom ";}
                     else   {cout << "\n the reference " << nomref << " already exists, choose another name  ";};
					              };
        		      }; // fin du while
             }
        	   else if (*il == "el")
             { bool nom_correcte = false;
        	      while (!nom_correcte)
        		      {if (fr){cout << "\n nom de la reference d'element ? "; nomref= lect_chaine();}
				             else {cout << "\n name of the element reference  ? "; nomref= lect_chaine();};
        	        nomref = "E_"+nomref;
        	        if (!(lesRef->Existe(nomref,idmail)))
        	          {list_nomReference.push_back(nomref);
        	           nom_correcte=true;
        	          }
        	        else
        	     	    { if (fr){cout << "\n la reference " << nomref << " existe deja, choissez un autre nom ";}
					                else   {cout << "\n the reference " << nomref << " already exists, choose another name  ";};
					              };
        		      }; // fin du while
        	    }
        	   else if (*il == "fa")
        	    { bool nom_correcte = false;
        	      while (!nom_correcte)
        		      {if (fr){cout << "\n nom de la reference de face ? "; nomref= lect_chaine();}
				             else {cout << "\n name of the facet reference  ? "; nomref= lect_chaine();};
        	        nomref = "F_"+nomref;
        	        if (!(lesRef->Existe(nomref,idmail)))
        	          {list_nomReference.push_back(nomref);
        	           nom_correcte=true;
        	          }
        	        else
        	     	   { if (fr){cout << "\n la reference " << nomref << " existe deja, choissez un autre nom ";}
					               else   {cout << "\n the reference " << nomref << " already exists, choose another name  ";};
					             };
        		      }; // fin du while
        	    }
        	   else if (*il == "ar")
        	    { bool nom_correcte = false;
        	      while (!nom_correcte)
        		      {if (fr){cout << "\n nom de la reference d'arrete ? "; nomref= lect_chaine();}
				             else {cout << "\n name of the edge reference  ? "; nomref= lect_chaine();};
        	        nomref = "A_"+nomref;
        	        if (!(lesRef->Existe(nomref,idmail)))
        	         {list_nomReference.push_back(nomref);
        	          nom_correcte=true;
        	         }
        	        else
        	     	   { if (fr){cout << "\n la reference " << nomref << " existe deja, choissez un autre nom ";}
					               else   {cout << "\n the reference " << nomref << " already exists, choose another name  ";};
					             };
        		      }; // fin du while
        	    }
        	   else if (*il == "pt")
        	    { bool nom_correcte = false;
        	      while (!nom_correcte)
        		      {if (fr){cout << "\n nom de la reference de point d'integration ? " << endl; }
				             else {cout << "\n name of integration point reference  ? "<< endl;};
				             nomref= lect_chaine();
        	        string nomddl="";
        	        nomref = "G_"+nomref;
        	        if (!(lesRef->Existe(nomref,idmail)))
        	         {list_nomReference.push_back(nomref);
        	          while (!ExisteEnum_ddl(nomddl))
        	           { if (fr) {cout << "\n donnez un nom d'un ddl de base associe aux points d'integration  ";
									             cout << "\n liste de ddl possible : " << endl;}
						                else 	{cout << "\n give a dof name associated to this integration point   ";
									             cout << "\n list of possible dof  : " << endl;};
        	             for (int i=1;i<nombre_maxi_de_type_de_ddl;i++)
        	                cout << Nom_ddl(Enum_ddl(i)) << " ";
        	             if (fr) {cout << "\n nom du ddl ? " << endl ;}else{cout << "\n name of the dof ? " << endl ;};
						                nomddl= lect_chaine();
        	             if (!ExisteEnum_ddl(nomddl))
        	              { if (fr) {cout << "\n nom de ddl incorrecte, recommencez ! " << endl;}
							                  else {cout << "\n wrong name for the dof, test another name !  " << endl;};
							                };
        	           };
        	          enu_ddl = Id_nom_ddl(nomddl);
        	          nom_correcte=true;
        	          existe_demande_pti = true; // pour la sortie d'info par la suite
        	         }
                 else
        	     	   { if (fr){cout << "\n la reference " << nomref << " existe deja, choissez un autre nom "<< endl;}
					               else   {cout << "\n the reference " << nomref << " already exists, choose another name  "<< endl;};
					             };
                }; // fin du while
        	    }
        	  };
 	  	     if (fr){cout << "\n voulez vous                    "
 	  	                  << "\n effacer la liste actuelle  et recommencer la def des nom    (rep efc) "
 	  	                  << "\n fin                                                         (rep f) " << endl;
                 }
 	  	     else   {cout << "\n do you want to delete the already registered "
 	  	                  << "\n list and define again the list of reference names           (rep efc) " 	  	       
 	  	                  << "\n end                                                         (rep f) " << endl;
				             };
 	  	     rep = lect_return_defaut(false,"f");
 	  	     if (rep == "efc")
 	  	  	   {list_nomReference.clear();
 	  	       enu_ddl = NU_DDL;
 	  	  	   };
  	  	  }; // fin du choix des noms

	      // s'il y a une demande de ref de pt integ sortie éventuelle d'information
	      if (existe_demande_pti)
      	 { string dem = "";
          list <string >::iterator il, ilfin = list_typeReference.end();
          for (il = list_typeReference.begin(); il!=ilfin;il++)
          	{if (*il == "pt")
               while ((dem != "f")&&(dem != "fi")&&(dem != "fin"))
          	    { List_io <Ddl_enum_etendu> li_inter; li_inter.push_back(Ddl_enum_etendu(enu_ddl)); // liste de travail 
          	    
          	      if (fr){cout << "\n ---- information concernant les pt d'integ existant ------ "
          	                  << "\n les coor d'un pt d'integ d'un ele choisit par numero (elem+integ)   (rep chnbe ) "
          	                  << "\n les coor d'un pt d'integ d'un ele choisit le plus pres de           (rep npres ) "
          	                  << "\n tous les coor des pt d'integ  d'un elem choisit par numero          (rep lespti ) "
          	                  << "\n fin                                                                 (f )" << endl;
								                }
          	      else   {cout << "\n -- information concerning the existing integration points  ------ "
          	                  << "\n the coord of an integ pt, choosen by its number+elem number         (rep chnbe ) "
          	                  << "\n the coordinates of an integ pt, choosen with a nearest point        (rep npres ) "
          	                  << "\n all the coord of an integ pt of an elem, choosen by its elem number (rep lespti ) "
          	                  << "\n end                                                                 (f )" << endl;
								                };
          	      dem= lect_return_defaut(false,"f");
          	      int nbe, nbpti;
          	      if (dem == "chnbe")
          	  	    { if (fr){cout << "\n num element ? " << endl;}else{cout << "\n element number  ? " << endl;};
						              nbe=(int)lect_double();
          	         if ((nbe > 0) || (nbe <= tab_noeud.Taille()))
          	     	    {if (fr){cout << "\n num pt integ ? " << endl;}else{cout << "\n integretion number  ? " << endl;}; 
						                nbpti=(int)lect_double();
          	         		// vérification de l'existence d'un point d'intégration correspondant à un ddl
		                    bool erreur=false;
		                    if (tab_element(nbe)->Existe_pt_integ (nbpti,enu_ddl))
		              	      { Coordonnee M = tab_element(nbe)->CoordPtInteg(TEMPS_0 ,enu_ddl,nbpti,erreur);
		                       if (!erreur)
		              	          {cout << "\n " << M << "\n ";}
		              	        else {if (fr){cout << "\n ** erreur en sortie du point ?? " << endl;}
							                        else{cout << "\n ** error in output of the point  ?? " << endl;};
							                       };
		              	      }
		                    else
		                     {if (fr){cout << " num de pt d'integ non correcte, recommencez !" << endl;}
							                 else {cout << " bad number of integ pt, start again !" << endl;};
                       };
                     }
          	         else	{if (fr){cout << " num d'element non correcte, recommencez !"<< endl;}
							                  else {cout << " bad number of element, start again !" << endl;};
                        }; 
          	  	    }
          	      else if (dem == "npres")
          	  	    { int dima = ParaGlob::Dimension();
          	  	      Coordonnee xi(dima);
                    if (fr){cout << "\n coordonnee d'un point dans la matiere !! ("<< dima <<" nombre(s)) ? ";}
						              else   {cout << "\n coordinate of a point in the material !! ("<< dima <<" number(s)) ? ";};
                    for(int j=1;j<=dima;j++) cin >> xi(j);
                    std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );// purge de cin
                    Maillage::NBelemEtptInteg nu = Element_le_plus_proche(TEMPS_0,li_inter,xi);
                    bool erreur=false;
                    if (nu.nbElem != 0)  
		              	    { Coordonnee M = tab_element(nu.nbElem)->CoordPtInteg(TEMPS_0 ,enu_ddl,nu.nbPtInteg,erreur);
		                     if (!erreur)
		              	        {cout << "\n element: " <<nu.nbElem << ", pt_integ: "  <<nu.nbPtInteg << "\n "<< M << "\n ";}
                       else {if (fr){cout << "\n ** erreur en sortie du point ?? ";}
							                      else   {cout << "\n ** error in the output of the point ?? ";};
                            };
		              	    }
		                  else
		             	     { if (fr){ cout << "\n on n'a pas trouve d'element contenant ce point, le point est peut-etre en dehors"
		             	                     << " de la matiere ! , recommencez avec un point dans la matiere. ";
									                     }
							                else   { cout << "\n we do not find an element that contains the point, perhaps the point is outside  "
		             	                     << " the material ! , try again with a point inside the material. ";
									                     };
                     };
          	  	    }
          	      else if (dem == "lespti")
          	  	    { cout << "\n num element ? " << endl; nbe=(int)lect_double();
          	         if ((nbe > 0) || (nbe <= tab_noeud.Taille()))
          	     	    { int nbpti = tab_element(nbe)->NbPtInteg(enu_ddl);
          	            bool erreur=false;
          	            for (int i=1;i<=nbpti;i++)
          	            cout << "\n pti "<<i << " : " << tab_element(nbe)->CoordPtInteg(TEMPS_0 ,enu_ddl,i,erreur)
          	                 << "\n ";
          	     	    }
          	         else	{if (fr){cout << " num d'element non correcte, recommencez !";}
						                    else   {cout << " wrong number of element, try again !";}
						                   };
          	  	    }
          	      else if (dem == "f") {}
          	      else
          	       {if (fr){cout << "\n syntaxe non correcte recommencez ! ";}
						             else   {cout << "\n wrong syntaxes, try again ! ";}
						            };
          	    }; //-- fin du while
          	}; //-- fin de la boucle sur les type de ref
      	 }; // -- fin du if demande pti
      
       // def de la méthode pour définir la liste d'éléments associé à la référence
       string methode="";
       list <string> list_methode; 
       int dima = ParaGlob::Dimension();
       
       while ((methode != "f")&&(methode != "fi")&&(methode != "fin"))
        {// affichage du menu du type de référence voulu
      	  switch (dima)
      	  	{case 3:
					        if (fr)
						         {cout  << "\n pres d'un plan                                 (rep pres_plan) "
      	               << "\n d'un cote du plan                              (rep cote_plan) "
      	               << "\n entre deux plans //                            (rep entre_plans) "
                      << "\n entre  plan // +- distance                     (rep entre_plans_dist) "
      	               << "\n pres d'un cylindre                             (rep pres_cylindre) "
      	               << "\n a l'interieur d'un cylindre                    (rep in_cylindre) "
      	               << "\n a l'exterieur cylindre                         (rep ex_cylindre) "
      	               << "\n entre deux cylindres //                        (rep entre_cylindres) "
      	               << "\n pres d'une sphere                              (rep pres_sphere) "
      	               << "\n dans une sphere                                (rep in_sphere) "
      	               << "\n a l'exterieur d'une sphere                     (rep ex_sphere) "
      	               << "\n entre deux spheres concentriques               (rep entre_spheres) "
                      << "\n entre deux spheres concentriques               (rep entre_spheres) "
//      	               << "\n pres d'un parallelepipede                      (rep pres_para) "
//      	               << "\n dans une parallelepipede                       (rep in_para) "
//      	               << "\n a l'exterieur d'une parallelepipede            (rep ex_para) "
//      	               << "\n entre deux parallelepipedes                    (rep entre_para) "
      	               << "\n pres d'un point                                (rep pres_point) "
      	               << "\n pres d'une droite                              (rep pres_droite) "
         	  	         << "\n pres d'un cercle                               (rep pres_cercle) "
         	  	         << "\n addition d'une ref deja existante              (rep in_ref) "
         	  	         << "\n hors une ref dejà existante                    (rep out_ref) "
         	  	         << "\n ordonner N et ptint / project sur une droite   (rep ord_droite ) ";
      	          break;     
      	       	}
					        else 	
					          {cout  << "\n near a plane                                   (rep pres_plan) "
      	               << "\n on one side of a plane                         (rep cote_plan) "
      	               << "\n between two planes  //                         (rep entre_plans) "
                      << "\n between plane // +- distance                   (rep entre_plans_dist) "
      	               << "\n near a cylinder                                (rep pres_cylindre) "
      	               << "\n inside a cylinder                              (rep in_cylindre) "
      	               << "\n outside a cylinder                             (rep ex_cylindre) "
      	               << "\n between two  cylinders  //                     (rep entre_cylindres) "
      	               << "\n near a sphere                                  (rep pres_sphere) "
      	               << "\n into a sphere                                  (rep in_sphere) "
      	               << "\n outside a sphere                               (rep ex_sphere) "
      	               << "\n between two concentric spheres                 (rep entre_spheres) "
//      	               << "\n pres d'un parallelepipede                      (rep pres_para) "
//      	               << "\n dans une parallelepipede                       (rep in_para) "
//      	               << "\n a l'exterieur d'une parallelepipede            (rep ex_para) "
//      	               << "\n entre deux parallelepipedes                    (rep entre_para) "
      	               << "\n near a point                                   (rep pres_point) "
      	               << "\n near a line                                    (rep pres_droite) "
         	  	         << "\n near a cercle                                  (rep pres_cercle) "
         	  	         << "\n addition of an already existing reference      (rep in_ref) "
         	  	         << "\n outside to an already existing reference       (rep out_ref) "
         	  	         << "\n sort N and Gauss points / projection on a line (rep ord_droite ) ";
      	          break;     
      	       	}
      	  	 case 2:
				         if (fr)
         	  	  { cout << "\n pres d'un point                                (rep pres_point) "
         	  	         << "\n pres d'une droite                              (rep pres_droite) "
         	  	         << "\n d'un cote d'une droite                         (rep cote_droite) "
         	  	         << "\n entre deux droites //                          (rep entre_droites) "
                      << "\n entre droite //  +- distance                   (rep entre_droites_dist) "
         	  	         << "\n pres d'un cercle                               (rep pres_cercle) "
         	  	         << "\n a l'interieur d'un cercle                      (rep in_cercle) "
         	  	         << "\n a l'exterieur d'un cercle                      (rep ex_cercle) "
         	  	         << "\n entre deux cercles concentriques               (rep entre_cercles) "
         	  	         << "\n addition d'une ref deja existante              (rep in_ref) "
							               << "\n hors une ref dejà existante                    (rep out_ref) "
         	  	         << "\n ordonner N et ptint / project sur une droite   (rep ord_droite ) ";
 //        	  	       << "\n pres d'un rectangle                            (rep pres_rec) "
 //        	  	       << "\n a l'interieur d'un rectangle                   (rep in_rec) "
 //        	  	       << "\n a l'exterieur d'un rectangle                   (rep ex_rec) "
 //        	  	       << "\n entre deux rectangles                          (rep entre_rec) ";
         	  	    break;
         	  	  }
					        else 	
					          { cout  << "\n near a point                                   (rep pres_point) "
      	                << "\n near a line                                    (rep pres_droite) "
         	  	          << "\n on one side of a line                          (rep cote_droite) "
         	  	          << "\n between two lines //                           (rep entre_droites) "
                       << "\n between  line //  +- distance                  (rep entre_droites_dist) "
								               << "\n near a cercle                                  (rep pres_cercle) "
         	  	          << "\n inside a  cercle                               (rep in_cercle) "
         	  	          << "\n outside a cercle                               (rep ex_cercle) "
         	  	          << "\n between two concentric cercles                 (rep entre_cercles) "
         	  	          << "\n addition of an already existing reference      (rep in_ref) "
         	  	          << "\n outside to an already existing reference       (rep out_ref) "
         	  	          << "\n sort N and Gauss points / projection on a line (rep ord_droite ) ";
 //        	  	        << "\n pres d'un rectangle                            (rep pres_rec) "
 //        	  	        << "\n a l'interieur d'un rectangle                   (rep in_rec) "
 //        	  	        << "\n a l'exterieur d'un rectangle                   (rep ex_rec) "
 //        	  	        << "\n entre deux rectangles                          (rep entre_rec) ";
      	          break;     
      	       	}
      	  	 case 1:
				         if (fr)
         	  	  { cout << "\n pres d'un point                                 (rep pres_point) "
         	  	         << "\n d'un cote d'un point                            (rep cote_point) "
         	  	         << "\n entre deux points                               (rep entre_points) "
                      << "\n entre  point  +- distance                       (rep entre_points_dist) "
         	  	         << "\n addition d'une ref deja existante               (rep in_ref) "
							               << "\n hors une ref dejà existante                     (rep out_ref) "
         	  	         << "\n ordonner N et ptint / project sur l'axe         (rep ord_droite ) ";
         	  	    break;
               }
					        else
         	  	  { cout << "\n near a point                                    (rep pres_point) "
         	  	         << "\n on one side of a point                          (rep cote_point) "
         	  	         << "\n between two points                              (rep entre_points) "
                      << "\n between point +-  distance                      (rep entre_points_dist) "
         	  	         << "\n addition of an already existing reference       (rep in_ref) "
         	  	         << "\n outside to an already existing reference        (rep out_ref) "
         	  	         << "\n sort N and Gauss points / projection on the axe (rep ord_droite ) ";
         	  	    break;
         	  	  }
      	  	};
      	       
      	  if (fr){cout << "\n effacer la liste des methode             (rep ef) "
      	               << "\n fin def methodes                         (rep f) ";}
      	  else   {cout << "\n clear the list of method                 (rep ef) "
      	               << "\n end def methods                          (rep f) ";};
      	  if (list_methode.size()!=0)     
      	    {if (fr) { cout << "\n (pour info: list actuellement enreg: ";}
				        else    { cout << "\n (for info: list currently stored: ";};
            for (it=list_methode.begin();it!=list_methode.end();it++)
                   cout << " " << *it;
            cout << " ) ";
				       };   
      	   
         if (fr) {cout << "\n reponses : (il peut y en avoir plusieurs )   "<< endl;}
			      else    {cout << "\n answers : (several if needed )   "<< endl;}
      	  methode= lect_return_defaut(false,"f");  // lecture
      	  if (methode=="ef")
     	     {list_methode.erase(list_methode.begin(),list_methode.end());}
      	  else  
      	   {switch (dima)
	      	    {case 1 :
				            if ((methode == "pres_point")||(methode == "cote_point")
                  ||(methode == "entre_points")||(methode == "entre_points_dist")
   				           ||(methode == "ord_droite") ||(methode == "in_ref")||(methode == "out_ref"))
    	 	  	           { list_methode.push_back(methode);} 
                else if ((methode == "f") || (methode == "fi") || (methode != "fin")) { } // on ne fait rien
    	 	  	      else
    	 	  	  	     {if (fr) {cout << "\n mauvais choix lu : " << methode << ", verifiez la syntaxe et recommencez ";}
   				            else {cout << "\n wrong choice read : " << methode << ", take a look on the syntaxes or spelling and do it again ";}
					          };
	 	 	  	      break;
   			       case 2 :
   				         if ((methode == "pres_point")||(methode == "pres_droite")||(methode == "cote_droite")
                   ||(methode == "entre_droites")||(methode == "entre_droites_dist")
         	  	     ||(methode == "pres_cercle")||(methode == "in_cercle")||(methode == "ex_cercle")||(methode == "entre_cercles")
         	  	     ||(methode == "pres_rec")||(methode == "in_rec")||(methode == "ex_rec")||(methode == "entre_rec")
         	  	     ||(methode == "ord_droite")  ||(methode == "in_ref")||(methode == "out_ref"))
    	 	  	           { list_methode.push_back(methode);} 
	 	 	  	        else if ((methode == "f") || (methode == "fi") || (methode != "fin")) { } // on ne fait rien
	 	 	  	        else
    	 	  	  	     {if (fr) {cout << "\n mauvais choix lu : " << methode << ", verifiez la syntaxe et recommencez ";}
   				            else {cout << "\n wrong choice read : " << methode << ", take a look on the syntaxes or spelling and do it again ";}
   				           };
    	 	  	    break;
   			       case 3 :
   				         if ((methode == "pres_plan")||(methode == "cote_plan")||(methode == "entre_plans")
                  ||(methode == "entre_plans_dist")
      	  	        ||(methode == "pres_cylindre")||(methode == "in_cylindre")||(methode == "ex_cylindre")||(methode == "entre_cylindres")
      	  	        ||(methode == "pres_sphere")||(methode == "in_sphere")||(methode == "ex_sphere")||(methode == "entre_spheres")
 //     	  	      ||(methode == "pres_para")||(methode == "in_para")||(methode == "ex_para")||(methode == "entre_para")
      	  	        ||(methode == "pres_point")||(methode == "pres_droite")||(methode == "pres_cercle")
      	  	        ||(methode == "ord_droite")  ||(methode == "in_ref")||(methode == "out_ref"))
 	 	  	             { list_methode.push_back(methode);}
                else if ((methode == "f") || (methode == "fi") || (methode != "fin")) { } // on ne fait rien
	 	 	  	        else
    	 	  	  	    {if (fr) {cout << "\n mauvais choix lu : " << methode << ", verifiez la syntaxe et recommencez ";}
   				           else {cout << "\n wrong choice read : " << methode << ", take a look on the syntaxes or spelling and do it again ";}
   				          };
              break;
            };
          };
       };
       // on récupère pour le passe en interne la liste des références existantes
		     lesRefin = lesRef; // sert pour InitInRef(), ExeInRef (), InitOutRef(), ExeOutRef()
		     // execution en fonction des réponses
       try  // on met le calcul sous surveillance au cas d'un fausse manip
       {switch (dima)
      	  { case 1: CalculListRef_1D(list_nomReference,lesRef,list_methode,enu_ddl); break;
      	    case 2: CalculListRef_2D(list_nomReference,lesRef,list_methode,enu_ddl); break;
      	    case 3: CalculListRef_3D(list_nomReference,lesRef,list_methode,enu_ddl); break;
      	  };
       }
       catch (ErrSortieFinale)
            // cas d'une direction voulue vers la sortie
            // on relance l'interuption pour le niveau supérieur
          { ErrSortieFinale toto;
            throw (toto);
          }
       catch ( ... )
        { if (fr) {cout << "\n erreur dans la constitution des listes, recommencer ou modifer ";}
		        else    {cout << "\n error in the constitution of lists, try again or modify something ";}
        };
	     }; 														
      
	    if (fr) {cout << "\n fin def reference ?                                 (rep f) "
			                << "\n (ou n'importe quoi d'autre si l'on veut continuer ) " << endl;
	             reponse = lect_return_defaut(false,"f");;
              }
	    else    { cout << "\n end def reference ?                                 (rep f) "
			                 << "\n (or anything else if you want to continue  ) " << endl;
	              reponse = lect_return_defaut(false,"f");;
             } 
  	};
 };

// calcul des listes de références en fonction de la demande:
// list_nomReference: contient les types de refs que l'on veut
// list_methode:  contient la ou les méthodes que l'on veut utiliser 
//  cas 1D 
void  Maillage::CalculListRef_1D(list<string>& list_nomReference,LesReferences* lesRef
                                ,list<string>& list_methode,const Enum_ddl & enu_ddl)
	{ // def des listes de noeuds et d'éléments à considérer: ces listes diminuent à mesure que l'on
	  // appliques des contraintes
	  // au début on part avec tous les noeuds et éléments
	  list <Noeud *> list_noeud_restant;
	  int nbnoeud = tab_noeud.Taille(); 
	  for (int ne = 1; ne <= nbnoeud; ne++) 
	     list_noeud_restant.push_back(tab_noeud(ne));
	  list <Element *> list_element_restant;
	  int nbelement = tab_element.Taille(); 
	  for (int nel = 1; nel <= nbelement; nel++) 
	     list_element_restant.push_back(tab_element(nel));
	  // def des listes de faces, arêtes, pt integ, là on démarre avec des listes vides et
	  // on rempli la liste avec la première contrainte, puis avec les autres contraintes on diminue la liste
	  // les booleen sont utiliser pour savoir si c'est la première contrainte ou pas
	  list <NBelemEtFace> list_elemFace_restant; bool premLpti = true;
	  list <NBelemEtArete> list_elemArrete_restant; bool premLface = true;
	  list <NBelemEtptInteg> list_elemPtin_restant; bool premLarrete = true; 
	  bool fr = ParaGlob::Francais(); // pour simplifier
	   	     	  
	  // on balaie la liste des méthodes
	  list<string>::iterator il,ilfin=list_methode.end();
	  for (il = list_methode.begin();il!=ilfin;il++)
	  	  { string methode = *il;
	  	    if (methode == "pres_point" )
	  	     { initConditionPresDe = & Maillage::InitPresPoint; 
	  	       ExeConditionPresDe = & Maillage::ExePresPoint;
	  	       // appel de la fonction générique
	  	       PresDe(list_nomReference,list_noeud_restant,list_element_restant,enu_ddl
      	               ,list_elemPtin_restant,premLpti,list_elemFace_restant,premLface
      	               ,list_elemArrete_restant,premLarrete);
				     }
		     else if (    (methode == "cote_point")||(methode == "entre_points")
                 || (methode == "entre_point_dist")
					            ||(methode == "in_ref")||(methode == "out_ref")
               )
      	   // sinon c'est du type Toutdedans
      	   { if (methode == "cote_point")
              { initConditionToutDedans = & Maillage::InitCotePoint;
                ExeConditionToutDedans = & Maillage::ExeCotePoint;
              }
            else if (methode == "entre_point")
              { initConditionToutDedans = & Maillage::InitEntrePoint;
                ExeConditionToutDedans = & Maillage::ExeEntrePoint;
              }
            else if (methode == "entre_point_dist")
              { initConditionToutDedans = & Maillage::InitEntrePoint_avec_distance;
                ExeConditionToutDedans = & Maillage::ExeEntrePoint_avec_distance;
              }
      	     else if (methode == "in_ref")
              { initConditionToutDedans = & Maillage::InitInRef;
                ExeConditionToutDedans = & Maillage::Exe_In_out_avecRefExistantes;
              }
      	     else if (methode == "out_ref")
              { initConditionToutDedans = & Maillage::InitOutRef;
                ExeConditionToutDedans = & Maillage::Exe_In_out_avecRefExistantes;
              }
	  	        // appel de la fonction générique
	  	        ToutDedans(list_nomReference,list_noeud_restant,list_element_restant,enu_ddl
      	               ,list_elemPtin_restant,premLpti,list_elemFace_restant,premLface
      	               ,list_elemArrete_restant,premLarrete);
      	   }
      	  else if (methode == "ord_droite") {} // on ne fait rien ici, ce sera au deuxième balayage
      	  else 
      	  	{ if (fr) {cout << "\n desole, la condition " << methode << " n'est pas encore implantee " 
      	  	                << " il faut se plaindre  !! ";}
            else 	 {cout << "\n sorry, the method " << methode << " is not yet implemented  "
      	  	                << " you must complain  !! ";}
		        };
	  	}; //-- fin du balayage 1) des méthodes

	  // on balaie une seconde fois la liste des méthodes, pour voir si éventuellement il faut ordonner
	  // une liste de noeuds ou de points d'intégration
	  for (il = list_methode.begin();il!=ilfin;il++)
	  	{ string methode = *il;
	  	  if (methode == "ord_droite")
           { // on regarde s'il faut ordonner des noeuds et des pt d'integ, ou un des deux, ou aucun
             list<string>::const_iterator ie,iefin=list_nomReference.end();
             bool ordo_noeud = false; bool ordo_ptinteg = false;
             for (ie=list_nomReference.begin();ie!=iefin;ie++)
             	{ if ((*ie)[0] == 'N') ordo_noeud = true;
             	  if ((*ie)[0] == 'G') ordo_ptinteg = true;
             	};
             if (ordo_noeud || ordo_ptinteg)	
                  InitOrdonneLigne();  // on initialise que s'il y a quelque chose à faire
             if (ordo_noeud && ordo_ptinteg)
	  	      { OrdonneLigne(list_noeud_restant,list_elemPtin_restant,enu_ddl);}
	  	     else if (ordo_noeud) 
	  	      { list <NBelemEtptInteg> toto; // une liste vide qui ne sera pas ordonnée
	  	        OrdonneLigne(list_noeud_restant,toto,enu_ddl);
	  	      }
	  	     else if (ordo_ptinteg) 
	  	      { list <Noeud *> titi; // une liste vide qui ne sera pas ordonnée
	  	        OrdonneLigne(titi,list_elemPtin_restant,enu_ddl);
	  	      };
           }
	  	};
      // constitution des références
      EnregRef(list_nomReference,list_noeud_restant,list_elemPtin_restant,list_element_restant
               ,list_elemFace_restant,list_elemArrete_restant,lesRef);
	};
	 
// calcul des listes de références en fonction de la demande:
// list_nomReference: contient les types de refs que l'on veut
// list_methode:  contient la ou les méthodes que l'on veut utiliser 
//  cas 2D
void Maillage::CalculListRef_2D(list<string>& list_nomReference,LesReferences* lesRef
                                ,list<string>& list_methode,const Enum_ddl & enu_ddl)
	{ // def des listes de noeuds et d'éléments à considérer: ces listes diminuent à mesure que l'on
	  // appliques des contraintes
	  // au début on part avec tous les noeuds et éléments
	  list <Noeud *> list_noeud_restant;
	  int nbnoeud = tab_noeud.Taille(); 
	  for (int ne = 1; ne <= nbnoeud; ne++) 
	     list_noeud_restant.push_back(tab_noeud(ne));
	  list <Element *> list_element_restant;
	  int nbelement = tab_element.Taille(); 
	  for (int nel = 1; nel <= nbelement; nel++) 
	     list_element_restant.push_back(tab_element(nel));
	  // def des listes de faces, arêtes, pt integ, là on démarre avec des listes vides et
	  // on rempli la liste avec la première contrainte, puis avec les autres contraintes on diminue la liste
	  // les booleen sont utiliser pour savoir si c'est la première contrainte ou pas
	  list <NBelemEtFace> list_elemFace_restant; bool premLpti = true;
	  list <NBelemEtArete> list_elemArrete_restant; bool premLface = true;
	  list <NBelemEtptInteg> list_elemPtin_restant; bool premLarrete = true; 
	  bool fr = ParaGlob::Francais(); // pour simplifier
	   	     	  
	  // on balaie une première fois la liste des méthodes
	  list<string>::iterator il,ilfin=list_methode.end();
	  for (il = list_methode.begin();il!=ilfin;il++)
	  	{ string methode = *il;
	  	  if ((methode == "pres_point")||(methode == "pres_droite")||(methode == "pres_cercle")
      	  	 ||(methode == "pres_rec"))
           { if (methode == "pres_point" )
	  	      { initConditionPresDe = & Maillage::InitPresPoint; 
	  	        ExeConditionPresDe = & Maillage::ExePresPoint;
	  	      }
	  	     else if (methode == "pres_droite") 
	  	      { initConditionPresDe = & Maillage::InitPresLigne; 
	  	        ExeConditionPresDe = & Maillage::ExePresLigne;
	  	      }
	  	     else if (methode == "pres_cercle") 
	  	      { initConditionPresDe = & Maillage::InitPresCercle; 
	  	        ExeConditionPresDe = & Maillage::ExePresCercle;
	  	      }
	  	     // appel de la fonction générique
	  	     PresDe(list_nomReference,list_noeud_restant,list_element_restant,enu_ddl
      	               ,list_elemPtin_restant,premLpti,list_elemFace_restant,premLface
      	               ,list_elemArrete_restant,premLarrete);
           }
      	  else  if (  (methode == "cote_droite")||(methode == "entre_droites")
                   ||(methode == "entre_droites_dist")
      	  	         ||(methode == "in_cercle")||(methode == "ex_cercle")||(methode == "entre_cercles")
					              ||(methode == "in_ref")||(methode == "out_ref")
                  )
      	   // sinon c'est du type Toutdedans
      	   { if (methode == "cote_droite")
	  	      { initConditionToutDedans = & Maillage::InitCoteDroite; 
	  	        ExeConditionToutDedans = & Maillage::ExeCoteDroite;
	  	      }
      	     else if (methode == "entre_droites")
	  	      { initConditionToutDedans = & Maillage::InitEntreDroite; 
	  	        ExeConditionToutDedans = & Maillage::ExeEntreDroite;
	  	      }
            else if (methode == "entre_droites_dist")
          { initConditionToutDedans = & Maillage::InitEntreDroite_avec_distance;
            ExeConditionToutDedans = & Maillage::ExeEntreDroite_avec_distance;
          }
      	     else if (methode == "in_cercle")
	  	      { initConditionToutDedans = & Maillage::InitDansCercle; 
	  	        ExeConditionToutDedans = & Maillage::ExeDansCercle;
	  	      }
      	     else if (methode == "ex_cercle")
	  	      { initConditionToutDedans = & Maillage::InitDansCercle; 
	  	        ExeConditionToutDedans = & Maillage::ExeOutCercle;
	  	      }
      	     else if (methode == "entre_cercles")
	  	      { initConditionToutDedans = & Maillage::InitEntreCercles; 
	  	        ExeConditionToutDedans = & Maillage::ExeEntreCercles;
	  	      }
      	     else if (methode == "in_ref")
	  	      { initConditionToutDedans = & Maillage::InitInRef; 
	  	        ExeConditionToutDedans = & Maillage::Exe_In_out_avecRefExistantes;
	  	      }
      	     else if (methode == "out_ref")
	  	      { initConditionToutDedans = & Maillage::InitOutRef; 
	  	        ExeConditionToutDedans = & Maillage::Exe_In_out_avecRefExistantes;
	  	      }
	  	     // appel de la fonction générique
	  	     ToutDedans(list_nomReference,list_noeud_restant,list_element_restant,enu_ddl
      	               ,list_elemPtin_restant,premLpti,list_elemFace_restant,premLface
      	               ,list_elemArrete_restant,premLarrete);
      	   }
      	  else if (methode == "ord_droite") {} // on ne fait rien ici, ce sera au deuxième balayage
      	  else 
      	  	{ if (fr) {cout << "\n desole, la condition " << methode << " n'est pas encore implantee " 
      	  	                << " il faut se plaindre  !! ";}
				  else 	 {cout << "\n sorry, the method " << methode << " is not yet implemented  " 
      	  	                << " you must complain  !! ";}
		       }; 
	  	}; //-- fin du balayage des méthodes

	  // on balaie une seconde fois la liste des méthodes, pour voir si éventuellement il faut ordonner
	  // une liste de noeuds ou de points d'intégration
	  for (il = list_methode.begin();il!=ilfin;il++)
	  	{ string methode = *il;
	  	  if (methode == "ord_droite")
           { // on regarde s'il faut ordonner des noeuds et des pt d'integ, ou un des deux, ou aucun
             list<string>::const_iterator ie,iefin=list_nomReference.end();
             bool ordo_noeud = false; bool ordo_ptinteg = false;
             for (ie=list_nomReference.begin();ie!=iefin;ie++)
             	{ if ((*ie)[0] == 'N') ordo_noeud = true;
             	  if ((*ie)[0] == 'G') ordo_ptinteg = true;
             	};
             if (ordo_noeud || ordo_ptinteg)	
                  InitOrdonneLigne();  // on initialise que s'il y a quelque chose à faire
             if (ordo_noeud && ordo_ptinteg)
	  	      { OrdonneLigne(list_noeud_restant,list_elemPtin_restant,enu_ddl);}
	  	     else if (ordo_noeud) 
	  	      { list <NBelemEtptInteg> toto; // une liste vide qui ne sera pas ordonnée
	  	        OrdonneLigne(list_noeud_restant,toto,enu_ddl);
	  	      }
	  	     else if (ordo_ptinteg) 
	  	      { list <Noeud *> titi; // une liste vide qui ne sera pas ordonnée
	  	        OrdonneLigne(titi,list_elemPtin_restant,enu_ddl);
	  	      };
           }
	  	};
      // constitution des références
      EnregRef(list_nomReference,list_noeud_restant,list_elemPtin_restant,list_element_restant
               ,list_elemFace_restant,list_elemArrete_restant,lesRef);
	};

// calcul des listes de références en fonction de la demande:
// list_nomReference: contient les types de refs que l'on veut
// list_methode:  contient la ou les méthodes que l'on veut utiliser 
//  cas 3D
void Maillage::CalculListRef_3D(list<string>& list_nomReference,LesReferences* lesRef
                                ,list<string>& list_methode,const Enum_ddl & enu_ddl)
	{ // def des listes de noeuds et d'éléments à considérer: ces listes diminuent à mesure que l'on
	  // appliques des contraintes
	  // au début on part avec tous les noeuds et éléments
	  list <Noeud *> list_noeud_restant;
	  int nbnoeud = tab_noeud.Taille(); 
	  for (int ne = 1; ne <= nbnoeud; ne++) 
	     list_noeud_restant.push_back(tab_noeud(ne));
	  list <Element *> list_element_restant;
	  int nbelement = tab_element.Taille(); 
	  for (int nel = 1; nel <= nbelement; nel++) 
	     list_element_restant.push_back(tab_element(nel));
	  // def des listes de faces, arêtes, pt integ, là on démarre avec des listes vides et
	  // on rempli la liste avec la première contrainte, puis avec les autres contraintes on diminue la liste
	  // les booleen sont utiliser pour savoir si c'est la première contrainte ou pas
	  list <NBelemEtFace> list_elemFace_restant; bool premLpti = true;
	  list <NBelemEtArete> list_elemArrete_restant; bool premLface = true;
	  list <NBelemEtptInteg> list_elemPtin_restant; bool premLarrete = true; 
	  bool fr = ParaGlob::Francais(); // pour simplifier
	   	     	  
	  // on balaie une première fois la liste des méthodes
	  list<string>::iterator il,ilfin=list_methode.end();
	  for (il = list_methode.begin();il!=ilfin;il++)
	  	{ string methode = *il;
	  	  if ((methode == "pres_plan")||(methode == "pres_cylindre")||(methode == "pres_sphere")
//      	  	     ||(methode == "pres_para")
      	  	     ||(methode == "pres_point")||(methode == "pres_cercle")||(methode == "pres_droite"))
           { if (methode == "pres_point" )
	  	      { initConditionPresDe = & Maillage::InitPresPoint; 
	  	        ExeConditionPresDe = & Maillage::ExePresPoint;
	  	      }
	  	     else if (methode == "pres_droite") 
	  	      { initConditionPresDe = & Maillage::InitPresLigne; 
	  	        ExeConditionPresDe = & Maillage::ExePresLigne;
	  	      }
	  	     else if (methode == "pres_cercle") 
	  	      { initConditionPresDe = & Maillage::InitPresCercle; 
	  	        ExeConditionPresDe = & Maillage::ExePresCercle;
	  	      }
	  	     else if (methode == "pres_plan") 
	  	      { initConditionPresDe = & Maillage::InitPresPlan; 
	  	        ExeConditionPresDe = & Maillage::ExePresPlan;
	  	      }
	  	     else if (methode == "pres_cylindre") 
	  	      { initConditionPresDe = & Maillage::InitPresCylindre; 
	  	        ExeConditionPresDe = & Maillage::ExePresCylindre;
	  	      }
	  	     else if (methode == "pres_sphere") 
	  	      { initConditionPresDe = & Maillage::InitPresSphere; 
	  	        ExeConditionPresDe = & Maillage::ExePresSphere;
	  	      }
//	  	     else if (methode == "pres_para") 
//	  	      { cout << "\n methode " << methode << " non encore implante, il faut se plaindre !! ";
//	  	      }
	  	     // appel de la fonction générique
	  	     PresDe(list_nomReference,list_noeud_restant,list_element_restant,enu_ddl
      	               ,list_elemPtin_restant,premLpti,list_elemFace_restant,premLface
      	               ,list_elemArrete_restant,premLarrete);
           }
      	  else  if ((methode == "cote_plan")||(methode == "entre_plans")||(methode == "entre_plans_dist")
      	  	        ||(methode == "in_cylindre")||(methode == "ex_cylindre")||(methode == "entre_cylindres")
      	  	        ||(methode == "in_sphere")||(methode == "ex_sphere")||(methode == "entre_spheres")
					             ||(methode == "in_ref")||(methode == "out_ref")
//      	  	     ||(methode == "in_para")||(methode == "ex_para")||(methode == "entre_para")
      	  	     )
      	   // sinon c'est du type Toutdedans
      	   { if (methode == "cote_plan")
	  	      { initConditionToutDedans = & Maillage::InitCotePlan; 
	  	        ExeConditionToutDedans = & Maillage::ExeCotePlan;
	  	      }
      	     else if (methode == "entre_plans")
	  	      { initConditionToutDedans = & Maillage::InitEntrePlan; 
	  	        ExeConditionToutDedans = & Maillage::ExeEntrePlan;
	  	      }
            else if (methode == "entre_plans_dist")
          { initConditionToutDedans = & Maillage::InitEntrePlan_avec_distance;
            ExeConditionToutDedans = & Maillage::ExeEntrePlan_avec_distance;
          }
            else if (methode == "in_cylindre")
	  	      { initConditionToutDedans = & Maillage::InitDansCylindre; 
	  	        ExeConditionToutDedans = & Maillage::ExeDansCylindre;
	  	      }
      	     else if (methode == "ex_cylindre")
	  	      { initConditionToutDedans = & Maillage::InitDansCylindre; 
	  	        ExeConditionToutDedans = & Maillage::ExeOutCylindre;
	  	      }
      	     else if (methode == "entre_cylindres")
	  	      { initConditionToutDedans = & Maillage::InitEntreCylindre;
	  	        ExeConditionToutDedans = & Maillage::ExeEntreCylindre;
	  	      }
      	     else if (methode == "in_sphere")
	  	      { initConditionToutDedans = & Maillage::InitDansSphere; 
	  	        ExeConditionToutDedans = & Maillage::ExeDansSphere;
	  	      }
      	     else if (methode == "ex_sphere")
	  	      { initConditionToutDedans = & Maillage::InitDansSphere; 
	  	        ExeConditionToutDedans = & Maillage::ExeOutSpheres;
	  	      }
      	     else if (methode == "entre_spheres")
	  	      { initConditionToutDedans = & Maillage::InitEntreSpheres; 
	  	        ExeConditionToutDedans = & Maillage::ExeEntreSpheres;
	  	      }
      	     else if (methode == "in_ref")
	  	      { initConditionToutDedans = & Maillage::InitInRef; 
	  	        ExeConditionToutDedans = & Maillage::Exe_In_out_avecRefExistantes;
	  	      }
      	     else if (methode == "out_ref")
	  	      { initConditionToutDedans = & Maillage::InitOutRef; 
	  	        ExeConditionToutDedans = & Maillage::Exe_In_out_avecRefExistantes;
	  	      }
//      	     else if (methode == "in_para")
//	  	      { cout << "\n methode " << methode << " non encore implante, il faut se plaindre !! ";
//	  	      }
//      	     else if (methode == "ex_para")
//	  	      { cout << "\n methode " << methode << " non encore implante, il faut se plaindre !! ";
//	  	      }
//      	     else if (methode == "entre_paras")
//	  	      { cout << "\n methode " << methode << " non encore implante, il faut se plaindre !! ";
//	  	      }
	  	     // appel de la fonction générique
	  	     ToutDedans(list_nomReference,list_noeud_restant,list_element_restant,enu_ddl
      	               ,list_elemPtin_restant,premLpti,list_elemFace_restant,premLface
      	               ,list_elemArrete_restant,premLarrete);
      	   }
      	  else if (methode == "ord_droite") {} // on ne fait rien ici, ce sera au deuxième balayage
      	  else 
      	  	{ if (fr) {cout << "\n desole, la condition " << methode << " n'est pas encore implantee " 
      	  	                << " il faut se plaindre  !! ";}
				  else 	 {cout << "\n sorry, the method " << methode << " is not yet implemented  " 
      	  	                << " you must complain  !! ";}
		       }; 
	  	}; //-- fin du balayage des méthodes

	  // on balaie une seconde fois la liste des méthodes, pour voir si éventuellement il faut ordonner
	  // une liste de noeuds ou de points d'intégration
	  for (il = list_methode.begin();il!=ilfin;il++)
	  	{ string methode = *il;
	  	  if (methode == "ord_droite")
           { // on regarde s'il faut ordonner des noeuds et des pt d'integ, ou un des deux, ou aucun
             list<string>::const_iterator ie,iefin=list_nomReference.end();
             bool ordo_noeud = false; bool ordo_ptinteg = false;
             for (ie=list_nomReference.begin();ie!=iefin;ie++)
             	{ if ((*ie)[0] == 'N') ordo_noeud = true;
             	  if ((*ie)[0] == 'G') ordo_ptinteg = true;
             	};
             if (ordo_noeud || ordo_ptinteg)	
                  InitOrdonneLigne();  // on initialise que s'il y a quelque chose à faire
             if (ordo_noeud && ordo_ptinteg)
	  	      { OrdonneLigne(list_noeud_restant,list_elemPtin_restant,enu_ddl);}
	  	     else if (ordo_noeud) 
	  	      { list <NBelemEtptInteg> toto; // une liste vide qui ne sera pas ordonnée
	  	        OrdonneLigne(list_noeud_restant,toto,enu_ddl);
	  	      }
	  	     else if (ordo_ptinteg) 
	  	      { list <Noeud *> titi; // une liste vide qui ne sera pas ordonnée
	  	        OrdonneLigne(titi,list_elemPtin_restant,enu_ddl);
	  	      };
           }
	  	};
   // constitution des références
   EnregRef(list_nomReference,list_noeud_restant,list_elemPtin_restant,list_element_restant
            ,list_elemFace_restant,list_elemArrete_restant,lesRef);
	};


// fonction générique pour des condition PresDe
void Maillage::PresDe(const list<string>& list_nomReference, list <Noeud *>& list_noeud_restant
      	               ,list <Element *>& list_element_restant,const Enum_ddl & enu_ddl
      	               ,list <NBelemEtptInteg>& list_elemPtin_restant,bool& premLpti
      	               ,list <NBelemEtFace>& list_elemFace_restant,bool& premLface
      	               ,list <NBelemEtArete>& list_elemArrete_restant,bool& premLarrete) 
	{ // a) on commence par initialiser la condition
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  double dist = 0.;
	  // puis on appelle la fonction d'initialisation
	  (this->*initConditionPresDe)(dist);
	  
	  // b) deuxième temps, on exécute la condition associée (il doit y en avoir qu'une
	  //    car avant chaque condition il faut appeler init !!)
	  //    par contre la condition peut-être appliquée plusieurs fois
	
	  // on balaie la liste des nom de ref pour savoir quel type de ref on cherche
	  list<string>::const_iterator al,alfin = list_nomReference.end();
	  
	  for (al=list_nomReference.begin();al!=alfin;al++)
         if ((*al)[0] == 'N')
           {// cas d'une liste de noeuds: on balaie la liste et on cherche
            list <Noeud *>::iterator nit,nits;
            // on calcul à chaque fois la borne finale car elle peut changer dans la boucle
            nit = list_noeud_restant.begin(); nits = nit; // init	
            while (nits != list_noeud_restant.end())
            	{ nit = nits; nits++; // nits pointeur sur le suivant
            	  // on supprime si la condition n'est pas remplie
            	  Coordonnee M=(*nit)->Coord0();
            	  bool condi = (this->*ExeConditionPresDe)(dist,M);
            	  if (!condi)
            	     list_noeud_restant.erase(nit);
            	};            	
           }
         else if ((*al)[0] == 'E')  
           {// cas d'une liste d'éléments: on balaie la liste et on cherche
            // il faut que un des noeuds de l'élément remplit la condition
            list <Element *>::iterator nit,nits;
            // on calcul à chaque fois la borne finale car elle peut changer dans la boucle
            nit = list_element_restant.begin(); nits = nit; // init	
            while (nits != list_element_restant.end())
            	{ nit = nits; nits++; // nits pointeur sur le suivant
            	  // recup du tableau de noeuds de l'élément
            	  const Tableau<Noeud *>& t_N = (*nit)->Tab_noeud();
            	  int nbne = t_N.Taille();
            	  bool condition = false; // par défaut
            	  for (int ie=1;ie<=nbne;ie++)
            	   { Coordonnee M=t_N(ie)->Coord0();
            	     condition = (this->*ExeConditionPresDe)(dist,M);
            	   };
            	  // on supprime si la condition n'est pas remplie
            	  if (!condition)  
            	     list_element_restant.erase(nit);
            	};
           }
         else if ((*al)[0] == 'G')  
           {// cas d'une liste de point d'intégration d'éléments: on balaie la liste des éléments 
            // et dedans la liste des points d'intégration et on cherche
            if (premLpti)  // cas d'une première contrainte
             {// on va balayer tous les éléments existant
              int nbne = tab_element.Taille();
              for (int ine=1;ine<=nbne;ine++)
               { Element& el = *(tab_element(ine));
                 // recup du nombre de point d'intégration de l'élément
            	    int nbpti = el.NbPtInteg(enu_ddl);
            	    // on boucle sur les pt d'integ
            	    for (int ipt = 1;ipt<=nbpti;ipt++)
            	  	  { bool erreur =false;
            	  	    Coordonnee Mpti0 = el.CoordPtInteg(TEMPS_0,enu_ddl,ipt,erreur);
            	  	    if (erreur)
            	  	      { if (fr) {cout << "\n erreur bizarre, on ne peut pas trouver les coordoonees t0 du pt d'integ "
            	  	                      << ipt << "de l'element " << el.Num_elt() << " du maillage " 
            	  	                      << el.Num_maillage() << " on ne le test donc pas pour la liste des pt d'integ ! ";
						    	                     }		 
                        else    {cout << "\n strange error, we cannot find the coordinates at t0 of the gauss point "
            	  	                      << ipt << "of the element " << el.Num_elt() << " of the mesh " 
            	  	                      << el.Num_maillage() << " so, we do not test it, for the list of integ points ! ";
						    			                   };		 
            	  	  	   }
            	  	    else
            	  	  	   { // cas ok
            	           bool condition = (this->*ExeConditionPresDe)(dist,Mpti0);
            	  	  	     NBelemEtptInteg nu; nu.nbElem=el.Num_elt(); nu.nbPtInteg = ipt;
            	           if (condition) 
            	             { list_elemPtin_restant.push_back(nu);};  // première fois on ajoute
            	  	  	   };
            	  	  }; //-- fin de la boucle des pt d'integ
               }; //-- fin de la boucle sur tous les éléments
              // on signale pour la suite qu'une contrainte a déjà été appliqué 
              premLpti = false;
             }
            else // cas d'une contrainte qui n'est pas la première
             {// on boucle sur les éléments déjà enregistrée
              list <NBelemEtptInteg>::iterator nit,nits;
              // on calcul à chaque fois la borne finale car elle peut changer dans la boucle
              nit = list_elemPtin_restant.begin(); nits = nit; // init	
              while (nits != list_elemPtin_restant.end())
            	  {nit = nits; nits++; // nits pointeur sur le suivant
//              for (nit=list_elemPtin_restant.begin();nit!=list_elemPtin_restant.end();nit++)
            	   Element& el = *(tab_element((*nit).nbElem)); // récup élément
            	   int ipt = (*nit).nbPtInteg; // récup le pt d'integ
            	   bool erreur =false;
            	   Coordonnee Mpti0 = el.CoordPtInteg(TEMPS_0,enu_ddl,ipt,erreur);
            	   if (erreur)
            	  	    { if (fr) {cout << "\n erreur bizarre, on ne peut pas trouver les coordoonees t0 du pt d'integ "
            	  	                    << ipt << "de l'element " << el.Num_elt() << " du maillage " 
            	  	                    << el.Num_maillage() << " on ne le test donc pas pour la liste des pt d'integ ! ";
						    	         }		 
                      else    {cout << "\n strange error, we cannot find the coordinates at t0 of the gauss point "
            	  	                    << ipt << "of the element " << el.Num_elt() << " of the mesh " 
            	  	                    << el.Num_maillage() << " so, we do not test it, for the list of integ points ! ";
						    			                 };		 
                    }
            	   else
            	  	   { // cas ok pour la gestion d'erreur
            	        bool condition = (this->*ExeConditionPresDe)(dist,Mpti0);
            	  	     NBelemEtptInteg nu; nu.nbElem=el.Num_elt(); nu.nbPtInteg = ipt;
            	        if (!condition)
            	          // il ne satisfait pas la contrainte, on  le supprime
            	       	  {list_elemPtin_restant.erase(nit);};
            	  	   };
            	  };
             }; //-- fin du test sur première contrainte ou pas
           }
         else if ((*al)[0] == 'F')  
           {// cas d'une liste de face d'éléments: on balaie la liste des éléments 
            // et dedans la liste des faces et on cherche
            if (premLface)  // cas d'une première contrainte
             {// on va balayer tous les éléments existant
              int nbne = tab_element.Taille();
              for (int ine=1;ine<=nbne;ine++)
               { Element& el = *(tab_element(ine));
		               ElemGeomC0& elgeom = el.ElementGeometrique(); // récup de l'élément géométrique
		               const Tableau<Tableau<int> > nonf = elgeom.Nonf(); // récup de la connection des faces
            	    int nbptface = nonf.Taille();
            	    const Tableau<Noeud *>& t_N = el.Tab_noeud(); // récup du tableau de noeud de l'élément
            	    // on boucle sur les faces
            	    for (int iface = 1;iface<=nbptface;iface++)
            	     { // on regarde si un des noeuds de la face remplit la condition
            	       int nbnoeudface = nonf(iface).Taille();
            	       for (int ino = 1; ino<= nbnoeudface; ino++)
            	        { Coordonnee M = (t_N(nonf(iface)(ino)))->Coord0();
            	          bool condition = (this->*ExeConditionPresDe)(dist,M);
            	          if (condition) 
            	       	   { NBelemEtFace nu; nu.nbElem = el.Num_elt(); nu.nbFace = iface;
            	             list_elemFace_restant.push_back(nu);
            	             break; // pour éviter d'enregistrer n fois la même face
            	       	   };
                     };
            	     };
               }; //-- fin de la boucle sur tous les éléments
////--- debug
//   cout << "\n Maillage::PresDe(..";
//   cout << "\n list finale de face après traitement : nb face ="<< list_elemFace_restant.size() << endl;
////--- fin debug
              // on signale pour la suite qu'une contrainte a déjà été appliqué
              premLface = false;
             }
            else // cas d'une contrainte qui n'est pas la première
             {// on boucle sur les éléments déjà enregistrée
              list <NBelemEtFace>::iterator nit,nits;
              // on calcul à chaque fois la borne finale car elle peut changer dans la boucle
              nit = list_elemFace_restant.begin(); nits = nit; // init	
              while (nits != list_elemFace_restant.end())
            	 {nit = nits; nits++; // nits pointeur sur le suivant
//              for (nit=list_elemFace_restant.begin();nit!=list_elemFace_restant.end();nit++)
               Element& el = *(tab_element((*nit).nbElem)); // récup élément
		             ElemGeomC0& elgeom = el.ElementGeometrique(); // récup de l'élément géométrique
		             const Tableau<Tableau<int> > nonf = elgeom.Nonf(); // récup de la connection des faces
            	  const Tableau<Noeud *>& t_N = el.Tab_noeud(); // récup du tableau de noeud de l'élément
            	  bool condition = false; // a priori
            	  int iface = (*nit).nbFace;
            	  // on regarde si un des noeuds de la face rempli la condition
            	  int nbnoeudface = nonf(iface).Taille();
            	  for (int ino = 1; ino<= nbnoeudface; ino++)
            	   { Coordonnee M = (t_N(nonf(iface)(ino)))->Coord0();
            	     condition = (this->*ExeConditionPresDe)(dist,M);
            	     if (condition)
            	          break;
            	   };
            	  if (!condition)
            	    // cas où la condition n'est pas satisfaite on supprime  l'élément
            	    {list_elemFace_restant.erase(nit);};
            	};
             }; //-- fin du test sur première contrainte ou pas
           }
         else if ((*al)[0] == 'A')  
           {// cas d'une liste de d'arêtes d'éléments: on balaie la liste des éléments 
            // et dedans la liste des arêtes et on cherche
            if (premLarrete)  // cas d'une première contrainte
             {// on va balayer tous les éléments existant
              int nbne = tab_element.Taille();
              for (int ine=1;ine<=nbne;ine++)
               { Element& el = *(tab_element(ine));
		               ElemGeomC0& elgeom = el.ElementGeometrique(); // récup de l'élément géométrique
		               const Tableau<Tableau<int> > nons = elgeom.NonS(); // récup de la connection des arêtes
            	    int nbptarr = nons.Taille();
            	    const Tableau<Noeud *>& t_N = el.Tab_noeud(); // récup du tableau de noeud de l'élément
            	    // on boucle sur les arêtes
            	    for (int iarr = 1;iarr <=nbptarr;iarr++)
            	     { // on regarde si un des noeuds de l'arête remplit la condition
            	       int nbnoeudarr = nons(iarr).Taille();
            	       for (int ino = 1; ino<= nbnoeudarr; ino++)
            	        { Coordonnee M = (t_N(nons(iarr)(ino)))->Coord0();
            	          bool condition = (this->*ExeConditionPresDe)(dist,M);
            	          if (condition) 
            	       	   { NBelemEtArete nu; nu.nbElem = el.Num_elt(); nu.nbArete = iarr;
            	             list_elemArrete_restant.push_back(nu);
            	             break; // pour éviter d'enregistrer n fois la même arête
            	       	   };
            	        };
            	     };
               }; //-- fin de la boucle sur tous les éléments
              // on signale pour la suite qu'une contrainte a déjà été appliqué 
              premLarrete = false;
             }
            else // cas d'une contrainte qui n'est pas la première
             {// on boucle sur les éléments déjà enregistrée
              list <NBelemEtArete>::iterator nit,nits;
              // on calcul à chaque fois la borne finale car elle peut changer dans la boucle
              nit = list_elemArrete_restant.begin(); nits = nit; // init	
              while (nits != list_elemArrete_restant.end())
            	  { nit = nits; nits++; // nits pointeur sur le suivant
//              for (nit=list_elemArrete_restant.begin();nit!=list_elemArrete_restant.end();nit++)
            	    Element& el = *(tab_element((*nit).nbElem)); // récup élément
		               ElemGeomC0& elgeom = el.ElementGeometrique(); // récup de l'élément géométrique
		               const Tableau<Tableau<int> > nons = elgeom.NonS(); // récup de la connection des arêtes
            	    const Tableau<Noeud *>& t_N = el.Tab_noeud(); // récup du tableau de noeud de l'élément
            	    bool condition = false; // a priori
            	    int iarr = (*nit).nbArete;
            	    // on regarde si un des noeuds de l'arête remplit la condition
            	    int nbnoeudarr = nons(iarr).Taille();
            	    for (int ino = 1; ino<= nbnoeudarr; ino++)
            	     { Coordonnee M = (t_N(nons(iarr)(ino)))->Coord0();
            	       condition = (this->*ExeConditionPresDe)(dist,M);
            	       if (condition)
            	               break;
            	     };
            	    if (!condition)
            	      // cas où la condition n'est pas satisfaite on supprime  l'élément
            	      {list_elemArrete_restant.erase(nit);};
            	  };
             }; //-- fin du test sur première contrainte ou pas
           }
		
	};
	 
// fonction générique pour des condition "tout dedans"
void Maillage::ToutDedans(const list<string>& list_nomReference, list <Noeud *>& list_noeud_restant
      	               ,list <Element *>& list_element_restant,const Enum_ddl & enu_ddl
      	               ,list <NBelemEtptInteg>& list_elemPtin_restant,bool& premLpti
      	               ,list <NBelemEtFace>& list_elemFace_restant,bool& premLface
      	               ,list <NBelemEtArete>& list_elemArrete_restant,bool& premLarrete)
	{ // a) on commence par initialiser la condition
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  // puis on appelle la fonction d'initialisation
	  (this->*initConditionToutDedans)();
	  
	  // b) deuxième temps, on exécute la condition associée (il doit y en avoir qu'une
	  //    car avant chaque condition il faut appeler init !!)
	  //    par contre la condition peut-être appliquée plusieurs fois
	
	  // on balaie la liste des nom de ref pour savoir quel type de ref on cherche
	  list<string>::const_iterator al,alfin = list_nomReference.end();
	  
	  for (al=list_nomReference.begin();al!=alfin;al++)
         if ((*al)[0] == 'N')
           {// cas d'une liste de noeuds: on balaie la liste et on cherche
            list <Noeud *>::iterator nit,nits;
            Tableau <Coordonnee > t_coor(1); // tableau de travail
            // on calcul à chaque fois la borne finale car elle peut changer dans la boucle
            nit = list_noeud_restant.begin(); nits = nit; // init	
            while (nits != list_noeud_restant.end())
            	{ nit = nits; nits++; // nits pointeur sur le suivant
            	  // on supprime si la condition n'est pas remplie
            	  t_coor(1)=(*nit)->Coord0();
            	  bool condi = (this->*ExeConditionToutDedans)(t_coor);
            	  if (!condi)
            	     list_noeud_restant.erase(nit);
            	};
           }
         else if ((*al)[0] == 'E')  
           {// cas d'une liste d'éléments: on balaie la liste et on cherche
            // il faut que tous les noeuds de l'élément remplisse la condition
            list <Element *>::iterator nit,nits;
            // on calcul à chaque fois la borne finale car elle peut changer dans la boucle
            nit = list_element_restant.begin(); nits = nit; // init	
            while (nits != list_element_restant.end())
            	{ nit = nits; nits++; // nits pointeur sur le suivant
            	  // recup du tableau de noeuds de l'élément
            	  const Tableau<Noeud *>& t_N = (*nit)->Tab_noeud();
            	  int nbne = t_N.Taille();
            	  bool condition = false; // par défaut
            	  // on définit le tableau de coordonnées de tous les noeuds 
            	  Tableau <Coordonnee > t_coor(nbne);
            	  for (int ie=1;ie<=nbne;ie++)
            	   { t_coor(ie)=t_N(ie)->Coord0();};
            	  // on vérifie la condition 
            	  condition = (this->*ExeConditionToutDedans)(t_coor);
            	  // on supprime si la condition n'est pas remplie
            	  if (!condition)  
            	     list_element_restant.erase(nit);
            	};
           }
         else if ((*al)[0] == 'G')  
           {// cas d'une liste de point d'intégration d'éléments: on balaie la liste des éléments 
            // et dedans la liste des points d'intégration et on cherche
            Tableau <Coordonnee > t_coor(1); // tableau de travail
            if (premLpti)  // cas d'une première contrainte
             {// on va balayer tous les éléments existant
              int nbne = tab_element.Taille();
              for (int ine=1;ine<=nbne;ine++)
               { Element& el = *(tab_element(ine));
                 // recup du nombre de point d'intégration de l'élément
            	    int nbpti = el.NbPtInteg(enu_ddl);
            	    // on boucle sur les pt d'integ
            	    for (int ipt = 1;ipt<=nbpti;ipt++)
            	  	  { bool erreur =false;
            	  	    t_coor(1) = el.CoordPtInteg(TEMPS_0,enu_ddl,ipt,erreur);
            	  	    if (erreur)
            	  	     { if (fr) {cout << "\n erreur bizarre, on ne peut pas trouver les coordoonees t0 du pt d'integ "
            	  	                     << ipt << "de l'element " << el.Num_elt() << " du maillage "
            	  	                     << el.Num_maillage() << " on ne le test donc pas pour la liste des pt d'integ ! ";
						    	                    }
                       else    {cout << "\n strange error, we cannot find the coordinates at t0 of the gauss point "
            	  	                     << ipt << "of the element " << el.Num_elt() << " of the mesh "
            	  	                     << el.Num_maillage() << " so, we do not test it, for the list of integ points ! ";
						    			                  };
            	  	  	  }
                    else
            	  	  	  { // cas ok
            	          bool condition = (this->*ExeConditionToutDedans)(t_coor);
            	  	  	    NBelemEtptInteg nu; nu.nbElem=el.Num_elt(); nu.nbPtInteg = ipt;
            	          if (condition) 
            	           { list_elemPtin_restant.push_back(nu);};  // première fois on ajoute
            	  	  	  };
            	  	  }; //-- fin de la boucle des pt d'integ
               }; //-- fin de la boucle sur tous les éléments
              // on signale pour la suite qu'une contrainte a déjà été appliqué 
              premLpti = false;
             }
            else // cas d'une contrainte qui n'est pas la première
             {// on boucle sur les éléments déjà enregistrée
              list <NBelemEtptInteg>::iterator nit,nits;
              // on calcul à chaque fois la borne finale car elle peut changer dans la boucle
              nit = list_elemPtin_restant.begin(); nits = nit; // init	
              while (nits != list_elemPtin_restant.end())
            	  { nit = nits; nits++; // nits pointeur sur le suivant
//               for (nit=list_elemPtin_restant.begin();nit!=list_elemPtin_restant.end();nit++)
            	    Element& el = *(tab_element((*nit).nbElem)); // récup élément
            	    int ipt = (*nit).nbPtInteg; // récup le pt d'integ
            	    bool erreur =false;
            	    t_coor(1) = el.CoordPtInteg(TEMPS_0,enu_ddl,ipt,erreur);
            	    if (erreur)
            	  	  { if (fr) {cout << "\n erreur bizarre, on ne peut pas trouver les coordoonees t0 du pt d'integ "
            	  	                  << ipt << "de l'element " << el.Num_elt() << " du maillage " 
            	  	                  << el.Num_maillage() << " on ne le test donc pas pour la liste des pt d'integ ! ";
                            }		 
                    else    {cout << "\n strange error, we cannot find the coordinates at t0 of the gauss point "
            	  	                  << ipt << "of the element " << el.Num_elt() << " of the mesh "
            	  	                  << el.Num_maillage() << " so, we do not test it, for the list of integ points ! ";
									                   };
            	  	  }
            	    else
            	  	  { // cas ok pour la gestion d'erreur
            	       bool condition = (this->*ExeConditionToutDedans)(t_coor);
            	  	    NBelemEtptInteg nu; nu.nbElem=el.Num_elt(); nu.nbPtInteg = ipt;
            	       if (!condition)
            	        // il ne satisfait pas la contrainte, on  le supprime
            	       	{list_elemPtin_restant.erase(nit);};
            	  	  };
            	  };
             }; //-- fin du test sur première contrainte ou pas
           }
         else if ((*al)[0] == 'F')  
           {// cas d'une liste de face d'éléments: on balaie la liste des éléments 
            // et dedans la liste des faces et on cherche
            if (premLface)  // cas d'une première contrainte
             {// on va balayer tous les éléments existant
              int nbne = tab_element.Taille();
              for (int ine=1;ine<=nbne;ine++)
               { Element& el = *(tab_element(ine));
		               ElemGeomC0& elgeom = el.ElementGeometrique(); // récup de l'élément géométrique
		               const Tableau<Tableau<int> > nonf = elgeom.Nonf(); // récup de la connection des faces
            	    int nbptface = nonf.Taille();
            	    const Tableau<Noeud *>& t_N = el.Tab_noeud(); // récup du tableau de noeud de l'élément
            	    // on boucle sur les faces
            	    for (int iface = 1;iface<=nbptface;iface++)
            	     { // on regarde si tous les noeuds de la face remplissent la condition
            	       int nbnoeudface = nonf(iface).Taille();
            	       Tableau <Coordonnee> t_coor(nbnoeudface); // tableau intermédiaire
            	       bool condition = true; // condition vraie par défaut
            	       for (int ino = 1; ino<= nbnoeudface; ino++)
            	         t_coor(ino) = (t_N(nonf(iface)(ino)))->Coord0();
            	       // on update la condition
            	       condition = (this->*ExeConditionToutDedans)(t_coor);
            	       if (condition)
            	       	{NBelemEtFace nu; nu.nbElem = el.Num_elt(); nu.nbFace = iface;
            	         list_elemFace_restant.push_back(nu);
            	       	};
            	     };
               }; //-- fin de la boucle sur tous les éléments
              // on signale pour la suite qu'une contrainte a déjà été appliqué 
              premLface = false;
////--- debug
//   cout << "\n Maillage::ToutDedans(..";
//   cout << "\n PREMIER PASSAGE: list finale de face après traitement : nb face ="<< list_elemFace_restant.size() << endl;
////--- fin debug
             }
            else // cas d'une contrainte qui n'est pas la première
             {// on boucle sur les éléments déjà enregistrée
              list <NBelemEtFace>::iterator nit,nits;
              // on calcul à chaque fois la borne finale car elle peut changer dans la boucle
              nit = list_elemFace_restant.begin(); nits = nit; // init	
              while (nits != list_elemFace_restant.end())
            	  { nit = nits; nits++; // nits pointeur sur le suivant
//               for (nit=list_elemFace_restant.begin();nit!=list_elemFace_restant.end();nit++)
            	    Element& el = *(tab_element((*nit).nbElem)); // récup élément
		               ElemGeomC0& elgeom = el.ElementGeometrique(); // récup de l'élément géométrique
		               const Tableau<Tableau<int> > nonf = elgeom.Nonf(); // récup de la connection des faces
            	    const Tableau<Noeud *>& t_N = el.Tab_noeud(); // récup du tableau de noeud de l'élément
            	    bool condition = true; // a priori
            	    int iface = (*nit).nbFace;
            	    // on regarde si tous les noeuds de la face remplissent la condition
            	    int nbnoeudface = nonf(iface).Taille();
            	    Tableau <Coordonnee> t_coor(nbnoeudface); // tableau intermédiaire
            	    for (int ino = 1; ino<= nbnoeudface; ino++)
            	      t_coor(ino) = (t_N(nonf(iface)(ino)))->Coord0();
            	    // on update la condition
            	    condition = (this->*ExeConditionToutDedans)(t_coor);
            	    if (!condition)
            	     // cas où la condition n'est pas satisfaite on supprime  l'élément
            	     {list_elemFace_restant.erase(nit);};
            	  };
////--- debug
//   cout << "\n Maillage::ToutDedans(..";
//   cout << "\n PASSAGE SECONDAIRE: list finale de face après traitement : nb face ="<< list_elemFace_restant.size() << endl;
////--- fin debug
             }; //-- fin du test sur première contrainte ou pas
           }
         else if ((*al)[0] == 'A')  
           {// cas d'une liste d'arêtes d'éléments: on balaie la liste des éléments 
            // et dedans la liste des arêtes et on cherche
            if (premLarrete)  // cas d'une première contrainte
             {// on va balayer tous les éléments existant
              int nbne = tab_element.Taille();
              for (int ine=1;ine<=nbne;ine++)
               { Element& el = *(tab_element(ine));
		               ElemGeomC0& elgeom = el.ElementGeometrique(); // récup de l'élément géométrique
		               const Tableau<Tableau<int> > nons = elgeom.NonS(); // récup de la connection des arêtes
            	    int nbptarr = nons.Taille();
            	    const Tableau<Noeud *>& t_N = el.Tab_noeud(); // récup du tableau de noeud de l'élément
            	    // on boucle sur les arêtes
            	    for (int iarr = 1;iarr <=nbptarr;iarr++)
            	     { // on regarde si un des noeuds de l'arête est près du point
            	       int nbnoeudarr = nons(iarr).Taille();
            	       Tableau <Coordonnee> t_coor(nbnoeudarr); // tableau intermédiaire
            	       for (int ino = 1; ino<= nbnoeudarr; ino++)
            	          t_coor(ino) = (t_N(nons(iarr)(ino)))->Coord0();
            	       bool condition = (this->*ExeConditionToutDedans)(t_coor);
            	       if (condition)
            	        	{NBelemEtArete nu; nu.nbElem = el.Num_elt(); nu.nbArete = iarr;
            	          list_elemArrete_restant.push_back(nu);
            	       	 };
                  };
               }; //-- fin de la boucle sur tous les éléments
              // on signale pour la suite qu'une contrainte a déjà été appliqué 
              premLarrete = false;
             }
            else // cas d'une contrainte qui n'est pas la première
             {// on boucle sur les éléments déjà enregistrée
              list <NBelemEtArete>::iterator nit,nits;
              // on calcul à chaque fois la borne finale car elle peut changer dans la boucle
              nit = list_elemArrete_restant.begin(); nits = nit; // init	
              while (nits != list_elemArrete_restant.end())
            	  { nit = nits; nits++; // nits pointeur sur le suivant
//               for (nit=list_elemArrete_restant.begin();nit!=list_elemArrete_restant.end();nit++)
            	    Element& el = *(tab_element((*nit).nbElem)); // récup élément
		               ElemGeomC0& elgeom = el.ElementGeometrique(); // récup de l'élément géométrique
		               const Tableau<Tableau<int> > nons = elgeom.NonS(); // récup de la connection des arêtes
            	    const Tableau<Noeud *>& t_N = el.Tab_noeud(); // récup du tableau de noeud de l'élément
            	    bool condition = false; // a priori
            	    int iarr = (*nit).nbArete;
            	    // on regarde si un des noeuds de l'arête est près du point
            	    int nbnoeudarr = nons(iarr).Taille();
            	    Tableau <Coordonnee> t_coor(nbnoeudarr); // tableau intermédiaire
            	    for (int ino = 1; ino<= nbnoeudarr; ino++)
            	      t_coor(ino) = (t_N(nons(iarr)(ino)))->Coord0();
            	    condition = (this->*ExeConditionToutDedans)(t_coor);
            	    if (!condition)
            	     // cas où la condition n'est pas satisfaite on supprime  l'élément
            	      {list_elemArrete_restant.erase(nit);};
            	  };
             }; //-- fin du test sur première contrainte ou pas
           }
		
	};

// constitution des références
void Maillage::EnregRef(const list<string>& list_nomReference,list <Noeud *>& list_noeud_restant
                      ,list <NBelemEtptInteg>& list_elemPtin_restant,list <Element *>& list_element_restant
                      ,list <NBelemEtFace>& list_elemFace_restant,list <NBelemEtArete>& list_elemArrete_restant
                      ,LesReferences* lesRef)
	{
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  // on balaie la liste des nom de ref 
	  list<string>::const_iterator ag,agfin = list_nomReference.end();
	  for (ag=list_nomReference.begin();ag!=agfin;ag++)
	  	if ((*ag)[0] == 'N')
	  	  { // cas d'une liste de noeuds
	  	    // mise en place de la condition d'appartenance ou d'exclusion à des références existantes
        Exe_In_out_avecRefExistantes_N(list_noeud_restant);
        // on crée la nouvelle référence  que s'il reste des noeuds
        if (list_noeud_restant.size() != 0)
	  	    	{ // mise en place de la condition d'appartenance ou d'exclusion à des références existantes
				       Exe_In_out_avecRefExistantes_N(list_noeud_restant);
           // on ordonne et supprime les noeuds redondants
           //list_noeud_restant.sort();list_noeud_restant.unique();
				       // création d'un tableau de numéros de noeuds
	  	    	  Tableau<int> tab(list_noeud_restant.size());
	  	    	  list <Noeud *>::iterator itn,itnfin=list_noeud_restant.end();
	  	    	  int i=1;
	  	    	  for (itn=list_noeud_restant.begin();itn!=itnfin;itn++,i++)
	  	    	     tab(i)=(*itn)->Num_noeud();
				       ReferenceNE*  refN = new ReferenceNE(tab,idmail,1,(*ag));// construction de la référence
	  	    	  lesRef->Ajout_reference( refN);
	  	    	  if (fr) {cout << "\n enregistrement ref noeuds " << (*ag) << " de " << tab.Taille() << " item " << endl;}
				 else    {cout << "\n storage of nodes reference " << (*ag) << " of " << tab.Taille() << " item " << endl;};
	  	    	};
	  		}
	  	else if ((*ag)[0] == 'E')
	  	  { // cas d'une liste d'éléments
	  	    // mise en place de la condition d'appartenance ou d'exclusion à des références existantes
        Exe_In_out_avecRefExistantes_E(list_element_restant);
        // on crée la nouvelle référence  que s'il reste des éléments
	  	    if (list_element_restant.size() != 0)
	  	    	{// on ordonne et supprime les noeuds redondants
          //list_element_restant.sort();list_element_restant.unique();
          // création d'un tableau de numéros d'éléments
	  	    	 Tableau<int> tab(list_element_restant.size());
	  	    	 list <Element *>::iterator itn,itnfin=list_element_restant.end();
	  	    	 int i=1;
	  	    	 for (itn=list_element_restant.begin();itn!=itnfin;itn++,i++)
	  	    	   tab(i)=(*itn)->Num_elt();
	  	    	 ReferenceNE* refN = new ReferenceNE(tab,idmail,2,(*ag));// création de la référence
	  	    	 lesRef->Ajout_reference( refN);
	  	    	 if (fr) {cout << "\n enregistrement ref elements " << (*ag) << " de " << tab.Taille() << " item " << endl;}
				      else    {cout << "\n storage of elements reference " << (*ag) << " of " << tab.Taille() << " item " << endl;};
	  	    	};
	  		 }
	  	else if ((*ag)[0] == 'G')
	  	  { // cas d'une liste de points d'intégration d'éléments
	  	    // mise en place de la condition d'appartenance ou d'exclusion à des références existantes
        Exe_In_out_avecRefExistantes_G(list_elemPtin_restant);
        // on crée la nouvelle référence  que s'il reste des pti 
	  	    if (list_elemPtin_restant.size() != 0)
	  	    	{// on supprime les refs redondantes, mais comme on gère deux listes, on fait le travail à la main
          //list_elemPtin_restant.sort();list_elemPtin_restant.unique();
          // création d'un tableau de numéros d'éléments
	  	    	 Tableau<int> tabelem(list_elemPtin_restant.size());
	  	    	 Tableau<int> tabpti(list_elemPtin_restant.size()); // idem pour les pti
	  	    	 list <NBelemEtptInteg >::iterator itn,itnfin=list_elemPtin_restant.end();
	  	    	 int i=1;
	  	    	 for (itn=list_elemPtin_restant.begin();itn!=itnfin;itn++,i++)
	  	    	   {tabelem(i)=(*itn).nbElem;tabpti(i) = (*itn).nbPtInteg;};
	  	    	 ReferenceAF*  refAF = new ReferenceAF(tabelem,tabpti,idmail,6,(*ag));// création de la référence
	  	    	 lesRef->Ajout_reference( refAF);
	  	    	 if (fr) {cout << "\n enregistrement ref pt integ " << (*ag) << " de " << tabelem.Taille() << " item " << endl;}
				      else    {cout << "\n storage of integ points reference " << (*ag) << " of " << tabelem.Taille() << " item " << endl;};
	  	    	};
	  		 }
	  	else if ((*ag)[0] == 'F')
	  	  { // cas d'une liste de face d'éléments
	  	    // mise en place de la condition d'appartenance ou d'exclusion à des références existantes
				    Exe_In_out_avecRefExistantes_F(list_elemFace_restant);
        // on crée la nouvelle ref que s'il reste des faces
	  	    if (list_elemFace_restant.size() != 0)
	  	    	{ // on ordonne et supprime les noeuds redondants
           //list_elemFace_restant.sort();list_elemFace_restant.unique();
           // création d'un tableau de numéros d'éléments
	  	    	  Tableau<int> tabelem(list_elemFace_restant.size());
	  	    	  Tableau<int> tabface(list_elemFace_restant.size()); // idem pour les face
	  	    	  list <NBelemEtFace >::iterator itn,itnfin=list_elemFace_restant.end();
	  	    	  int i=1;
	  	    	  for (itn=list_elemFace_restant.begin();itn!=itnfin;itn++,i++)
	  	    	   {tabelem(i)=(*itn).nbElem;tabface(i) = (*itn).nbFace;};
	  	    	  ReferenceAF* refAF = new ReferenceAF(tabelem,tabface,idmail,3,(*ag));// création de la référence
	  	    	  lesRef->Ajout_reference( refAF);
	  	    	  if (fr) {cout << "\n enregistrement ref faces " << (*ag) << " de " << tabelem.Taille() << " item " << endl;}
				       else    {cout << "\n storage of facets reference " << (*ag) << " of " << tabelem.Taille() << " item " << endl;};
           if (ParaGlob::NiveauImpression()> 7)
            { for (int i=1; i<= tabelem.Taille(); i++)
                {int Ne = refAF->NumeroElem(i);
                 int Nf = refAF->NumeroFA(i);
                 Element * el =  tab_element(Ne);
                 ElFrontiere* fron = el->Frontiere_surfacique(Nf,true);
                 fron->Affiche(TEMPS_0);
                };
            };
	  	    	};
	  		}
	  	else if ((*ag)[0] == 'A')
	  	  { // cas d'une liste d'arêtes d'éléments
	  	    // mise en place de la condition d'appartenance ou d'exclusion à des références existantes
        Exe_In_out_avecRefExistantes_A(list_elemArrete_restant);
        // on crée la nouvelle référence  que s'il reste des arêtes d'éléments
	  	    if (list_elemArrete_restant.size() != 0)
	  	    	{// on ordonne et supprime les noeuds redondants
          //list_elemArrete_restant.sort();list_elemArrete_restant.unique();
          // création d'un tableau de numéros d'éléments
	  	    	 Tableau<int> tabelem(list_elemArrete_restant.size());
	  	    	 Tableau<int> tabarr(list_elemArrete_restant.size()); // idem pour les arêtes
	  	    	 list <NBelemEtArete >::iterator itn,itnfin=list_elemArrete_restant.end();
	  	    	 int i=1;
	  	    	 for (itn=list_elemArrete_restant.begin();itn!=itnfin;itn++,i++)
	  	    	   {tabelem(i)=(*itn).nbElem;tabarr(i) = (*itn).nbArete;};
	  	    	 ReferenceAF*  refAF = new ReferenceAF(tabelem,tabarr,idmail,4,(*ag));// création de la référence
	  	    	 lesRef->Ajout_reference( refAF);
	  	    	 if (fr) {cout << "\n enregistrement ref aretes " << (*ag) << " de " << tabelem.Taille() << " item " << endl;}
				      else    {cout << "\n storage of edges reference " << (*ag) << " of " << tabelem.Taille() << " item " << endl;};
	  	    	};
	  		 }
		
	};

// recherche près d'un point
// def interactive du point et de la distance
void Maillage::InitPresPoint(double& dist)
	{ int dima = ParaGlob::Dimension();
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  Coordonnee poin(dima); 
	  if (fr) {cout << "\n -- condition : près d'un point ---- "<< endl;
				  } 
	  else    {cout << "\n -- condition : near a point ---- "<< endl;
				  }; 
 
   // acquisition d'un point
   poin = Acquisition_interactive_point();
	  if (fr) {cout << "\n distance au point  (on retient la partie positive) " << endl;}
	  else    {cout << "\n distance to the point (only the absolute value will be kept) " << endl;}
	  dist=lect_double();
	  dist = Dabs(dist);
	  t_poi.Change_taille(1);
	  t_poi(1) = poin;
	};

// exécution de la condition : ramène true si ok, false sinon
bool Maillage::ExePresPoint(const double& dist,const Coordonnee& M) const
	{ return  ((M - t_poi(1)).Norme() < dist);     	        
	};	
        
// recherche d'un coté d'un point (en 1D) 
void Maillage::InitCotePoint()
	{ int dima = ParaGlob::Dimension();
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  Coordonnee poin1(dima),poin2(dima); 
	  if (fr) {cout << "\n -- condition : d'un cote d'un point (en 1D) ---- "<< endl;
				  } 
	  else    {cout << "\n -- condition : on one side of a point (in 1D) ---- " << endl;
				  }; 
   // acquisition d'un point
   poin1 = Acquisition_interactive_point();
  
	  if (fr) {cout << "\n donner un second point qui positionne le cote que l'on veut garder " << endl;
				  }
	  else    {cout << "\n give a second point which locate the side " << endl;
				  };
   // acquisition d'un point
   poin2 = Acquisition_interactive_point();
  
	  t_poi.Change_taille(2);
	  t_poi(1) = poin1;
	  t_poi(2) = poin2;
	};
// ramène true si tous les points sont du même coté que t_poi(2) 
bool Maillage::ExeCotePoint(const Tableau <Coordonnee> & t_M) const
 	{ int tMtaille = t_M.Taille();
 	  // on regarde si c'est ok pour tous les points 
 	  for (int i=1;i<=tMtaille;i++)
 	    if ((t_M(i) - t_poi(1)) * (t_poi(2)-t_poi(1)) < 0) 
 	       return false;
 	  // sinon c'est ok
 	  return true;  
 	};

// recherche entre deux points (1D) 
void Maillage::InitEntrePoint()
	{ int dima = ParaGlob::Dimension();
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  Coordonnee poin1(dima),poin2(dima); 
	  if (fr) {cout << "\n -- condition : entre deux points (en 1D) ---- "; 
	           cout << "\n  premier point "  << endl;
				  } 
	  else    {cout << "\n -- condition : between two points (in 1D) ---- "; 
	           cout << "\n  first point "  << endl;
				  }; 
   // acquisition d'un point
   poin1 = Acquisition_interactive_point();

	  if (fr) {cout << "\n second point  " << endl;}
	  else    {cout << "\n  second point " << endl;}
   // acquisition d'un point
   poin2 = Acquisition_interactive_point();

	  t_poi.Change_taille(2);
	  t_poi(1) = poin1;
	  t_poi(2) = poin2;
	};
// ramène true si tous les points sont entre t_poi(1) et t_poi(2)
bool Maillage::ExeEntrePoint(const Tableau <Coordonnee> & t_M)const
 	{ int tMtaille = t_M.Taille();
 	  // on regarde si c'est ok pour tous les points 
 	  for (int i=1;i<=tMtaille;i++)
 	    if ((t_M(i) - t_poi(1)) * (t_poi(2)-t_M(i)) > 0) 
 	       return false;
 	  // sinon c'est ok
 	  return true;  
 	};

// recherche entre deux points (1D) _avec_distance
void Maillage::InitEntrePoint_avec_distance()
 { int dima = ParaGlob::Dimension();
   bool fr = ParaGlob::Francais(); // pour simplifier
   Coordonnee poin1(dima),poin2(dima);
   if (fr) {cout << "\n -- condition : entre point (en 1D) +- une distance ---- ";
            cout << "\n  point median: "  << endl;
      }
   else    {cout << "\n -- condition : between point (in 1D) +- a distance ---- ";
            cout << "\n  median point "  << endl;
      };
   // acquisition d'un point
   Coordonnee A = Acquisition_interactive_point();
   double dist=0.;
   if (fr) {cout << "\n distance au point median (on retient la partie positive) " << endl;}
   else    {cout << "\n distance to the median point (only the absolute value will be kept) " << endl;}
   dist=lect_double();
   dist = Dabs(dist);
   // on va déplacer le plan via sa normale
   poin1(1)  = A(1) - dist;
   poin2(1)  = A(1) + dist;
   t_poi.Change_taille(2);
   t_poi(1) = poin1;
   t_poi(2) = poin2;
 };
// ramène true si tous les points sont entre t_poi(1) et t_poi(2) _avec_distance
bool Maillage::ExeEntrePoint_avec_distance(const Tableau <Coordonnee> & t_M)const
  { int tMtaille = t_M.Taille();
    // on regarde si c'est ok pour tous les points
    for (int i=1;i<=tMtaille;i++)
      if ((t_M(i) - t_poi(1)) * (t_poi(2)-t_M(i)) > 0)
         return false;
    // sinon c'est ok
    return true;
  };

// recherche près d'une ligne
void Maillage::InitPresLigne(double& dist)
	{ int dima = ParaGlob::Dimension();
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  Coordonnee poin1(dima),poin2(dima);
	  if (fr) {cout << "\n -- condition : pres d'une ligne ---- "; 
	           cout << "\n la ligne est defini par deux points "<< endl;
				  }
	  else    {cout << "\n -- condition : near a line ---- "; 
	           cout << "\n the line is defined by two points  " << endl;
				  };
   // acquisition d'un point
   poin1 = Acquisition_interactive_point();
	  if (fr) {cout << "\n  second point  " << endl;}
	  else    {cout << "\n  second point  " << endl;}
   // acquisition d'un point
   poin2 = Acquisition_interactive_point();
	  dist=0.;
	  if (fr) {cout << "\n distance à la ligne (on retient la partie positive) " << endl;}
	  else    {cout << "\n distance to the line (only the absolute value will be kept) " << endl;}
	  dist=lect_double(); cout << " distance lue: "<< dist << flush;
	  dist = Dabs(dist);
	  t_droit.Change_taille(1);
	  t_droit(1).change_donnees(poin1,(poin2-poin1));
	};
bool Maillage::ExePresLigne(const double& dist,const Coordonnee& M) const
	{ return (t_droit(1).Distance_a_la_droite(M) < dist);
	};
	
// recherche près d'un cercle
void Maillage::InitPresCercle(double& dist)
	{ int dima = ParaGlob::Dimension();
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  Coordonnee centre(dima); 
	  if (fr) {cout << "\n -- condition : pres d'un cercle ---- "; 
	           cout << "\n centre du cercle  " << endl;
				  }
	  else    {cout << "\n -- condition : near a cercle ---- "; 
	           cout << "\n  cercle center  " << endl;
				  };
   // acquisition d'un point
   centre = Acquisition_interactive_point();
	  double rayon=0.;
	  if (fr) {cout << "\n rayon  (on retient la partie positive) " << endl;}
	  else    {cout << "\n radius (only the absolute value will be kept) " << endl;}
	  rayon=lect_double();
	  rayon = Dabs(rayon);
	  t_cercle.Change_taille(1,Cercle(dima));
	  t_cercle(1).change_donnees(centre,rayon,NULL);
	  dist=0.;
	  if (fr) {cout << "\n distance au cercle (on retient la partie positive) " << endl;}
	  else    {cout << "\n distance to the cercle (only the absolute value will be kept) " << endl;}
	  dist=lect_double();
	  dist = Dabs(dist);
	};

bool Maillage::ExePresCercle(const double& dist,const Coordonnee& M) const
	{ return (t_cercle(1).Distance_au_Cercle(M) < dist);
	};
	
// recherche près d'un plan
void Maillage::InitPresPlan( double& dist)
	{ int dima = ParaGlob::Dimension();
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  Coordonnee poin(dima);
	  if (fr) {cout << "\n -- condition : pres d'un plan ---- " << endl;
				  }
	  else    {cout << "\n -- condition : near a plane ---- " << endl;
				  };
  
   // acquisition d'un plan
   Plan pl = Acquisition_interactive_plan();
	  t_plan.Change_taille(1);
	  t_plan(1)=pl; //.change_donnees(poin,normal);
	  dist=0.;
	  if (fr) {cout << "\n distance au plan (on retient la partie positive) " << endl;}
	  else    {cout << "\n distance to the plane (only the absolute value will be kept) " << endl;}
	  dist=lect_double();
	  dist = Dabs(dist);
	};

bool Maillage::ExePresPlan(const double& dist,const Coordonnee& M) const
	{ return (t_plan(1).Distance_au_plan(M) < dist);
	};

// recherche près d'un cylindre
void Maillage::InitPresCylindre(double& dist)
	{ int dima = ParaGlob::Dimension();
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  Coordonnee centre(dima); 
	  if (fr) {cout << "\n -- condition : pres d'un cylindre  ---- "; 
	           cout << "\n un point de l'axe du cylindre  " << endl;
				  }
	  else    {cout << "\n -- condition : near a cylinder  ---- "; 
	           cout << "\n  a point belonging to the axis of the cylinder  " << endl;
				  };
   // acquisition d'un point
   centre = Acquisition_interactive_point();
	  double rayon=0.;
	  cout << "\n rayon du cylindre (on retient la partie positive) " << endl;
   rayon=lect_double();
	  rayon = Dabs(rayon); cout << " rayon retenu: "<< rayon << endl;
	  
	  Coordonnee axe(dima); 
	  if (fr) {cout << "\n coordonnee du vecteur definissant  l'axe du cylindre ("<< dima << " reels) " << endl;}
	  else    {cout << "\n coordinate of the vector of the axis of the cylinder ("<< dima << " reals) " << endl;};
   // acquisition d'un vecteur=direction
   axe = Acquisition_interactive_vecteur();
	  Cercle cer(centre,rayon,&axe);

	  t_cylindre.Change_taille(1);
	  t_cylindre(1).change_donnees(cer);
	  dist=0.;
	  if (fr) {cout << "\n distance au cylindre (on retient la partie positive) " << endl;}
	  else    {cout << "\n distance to the cylinder (only the absolute value will be kept) " << endl;}
	  dist=lect_double();
	  dist = Dabs(dist);
	};

bool Maillage::ExePresCylindre(const double& dist,const Coordonnee& M) const
	{ return (t_cylindre(1).Distance_au_Cylindre(M) < dist);
	};

// recherche près d'un cylindre
void Maillage::InitPresSphere(double& dist)
	{ int dima = ParaGlob::Dimension();
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  Coordonnee centre(dima); 
	  if (fr) {cout << "\n -- condition : pres d'une sphere ---- "; 
	           cout << "\n centre de la sphere  " << endl;
				  }
	  else    {cout << "\n -- condition : near a sphere ---- "; 
	           cout << "\n the sphere center  " << endl;
				  };
   // acquisition d'un point
   centre = Acquisition_interactive_point();
	  double rayon=0.;
	  if (fr) {cout << "\n rayon de la sphere (on retient la partie positive) " << endl;}
	  else    {cout << "\n radius of the sphere (only the absolute value will be kept) " << endl;};	  
	  rayon=lect_double();
	  rayon = Dabs(rayon);

	  t_sphere.Change_taille(1);
	  t_sphere(1).change_donnees(centre,rayon);
	  dist=0.;
	  if (fr) {cout << "\n distance a la sphere  (on retient la partie positive) " << endl;}
	  else    {cout << "\n distance to the sphere (only the absolute value will be kept) " << endl;}
	  dist=lect_double();
	  dist = Dabs(dist);
	};

bool Maillage::ExePresSphere(const double& dist,const Coordonnee& M) const
	{ return (t_sphere(1).Distance_a_sphere(M) < dist);
	};
        
// recherche d'un coté d'un plan 
 void Maillage::InitCotePlan()
	{ int dima = ParaGlob::Dimension();
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  Coordonnee poin(dima); 
	  if (fr) {cout << "\n -- condition : d'un cote d'un plan ---- "
                 << "\n le plan: " << endl;
				  }
	  else    {cout << "\n -- condition : on one side of a plane ---- ";
	           cout << "\n the plane:  " << endl;
				  }

   // acquisition d'un plan
   Plan pl = Acquisition_interactive_plan();
   t_plan.Change_taille(1);
   t_plan(1)=pl; //.change_donnees(poin,normal);

	  t_poi.Change_taille(1);
	  if (fr) {cout << "\n un point d'un cote du plan  " << endl;}
	  else    {cout << "\n a point on one side of the plane  " << endl;}
   poin = Acquisition_interactive_point();
	  t_poi(1)=poin;
	};
// ramène true si tous les points sont du même coté que t_poi(1) du plan
 bool Maillage::ExeCotePlan(const Tableau <Coordonnee> & t_M)const
 	{ int tMtaille = t_M.Taille();
 	  for (int i=1;i<=tMtaille;i++)
 	    if (!(t_plan(1).DuMemeCote(t_poi(1),t_M(i)))) 
 	       return false;
 	  // sinon c'est ok
 	  return true;  
 	};

// condition entre plans
 void Maillage::InitEntrePlan()
	{ int dima = ParaGlob::Dimension();
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  if (fr) {cout << "\n -- condition : entre deux plans // ---- ";
	           cout << "\n  premier plan  " << endl;
				  }
	  else    {cout << "\n -- condition : between two planes // ---- "; 
	           cout << "\n  first plane  " << endl;
				  }
   // acquisition d'un plan
   Plan pl = Acquisition_interactive_plan();
	  t_plan.Change_taille(1);
	  t_plan(1) = pl; //.change_donnees(poin,normal);
	  t_poi.Change_taille(1);
	  if (fr) {cout << "\n un point du second  plan  "<< endl;}
	  else    {cout << "\n a point of the second plane  "<< endl;}
   // acquisition d'un point
   Coordonnee poin(Acquisition_interactive_point());
	  t_poi(1)=poin;
	};
 // ramène true si tous les points sont entre les deux plans
 bool Maillage::ExeEntrePlan(const Tableau <Coordonnee> & t_M)const
 	{ int tMtaille = t_M.Taille();
 	  // on regarde si d'une part les points sont du même coté que t_poi(1) et 
 	  // d'autre part si la distance du points au premier plan est <= à celle de t_poi(1)
 	  double dist = t_plan(1).Distance_au_plan(t_poi(1));
 	  for (int i=1;i<=tMtaille;i++)
 	    if (!(t_plan(1).DuMemeCote(t_poi(1),t_M(i)) && (t_plan(1).Distance_au_plan(t_M(i)) < dist ))) 
 	       return false;
 	  // sinon c'est ok
 	  return true;  
 	};

// condition entre plans _avec_distance
 void Maillage::InitEntrePlan_avec_distance()
 { int dima = ParaGlob::Dimension();
   bool fr = ParaGlob::Francais(); // pour simplifier
   if (fr) {cout << "\n -- condition : entre un plan +- une distance  ---- ";
            cout << "\n  le plan median: " << endl;
      }
   else    {cout << "\n -- condition : between a plane +- a distance ---- ";
            cout << "\n  the median plane  " << endl;
      }
   // acquisition d'un plan
   Plan pl = Acquisition_interactive_plan();
   double dist=0.;
   if (fr) {cout << "\n distance au plan (on retient la partie positive) " << endl;}
   else    {cout << "\n distance to the plane (only the absolute value will be kept) " << endl;}
   dist=lect_double();
   dist = Dabs(dist);
   // on va déplacer le plan via sa normale
   const Coordonnee& A = pl.PointPlan();
   const Coordonnee& N = pl.Vecplan();
   Coordonnee Ap = A - dist*N;
   pl.Change_ptref(Ap); // nouveau pt de ref du plan
   // maintenant le point idem entre plan originale
   Coordonnee poin = A + 2.*dist*N;
   // on enregistre
   t_plan.Change_taille(1);
   t_plan(1) = pl;
   t_poi.Change_taille(1);
   t_poi(1)=poin;
 };
 // ramène true si tous les points sont entre les deux plans _avec_distance
 bool Maillage::ExeEntrePlan_avec_distance(const Tableau <Coordonnee> & t_M)const
  { int tMtaille = t_M.Taille();
    // on regarde si d'une part les points sont du même coté que t_poi(1) et
    // d'autre part si la distance du points au premier plan est <= à celle de t_poi(1)
////-- debug
//cout << "\n debug Maillage::ExeEntrePlan_avec_distance( \n"
//     << t_plan(1) << "\n point " << t_poi(1);
//
////--- fin debug
    double dist = t_plan(1).Distance_au_plan(t_poi(1));
    for (int i=1;i<=tMtaille;i++)
      if (!(t_plan(1).DuMemeCote(t_poi(1),t_M(i)) && (t_plan(1).Distance_au_plan(t_M(i)) < dist )))
         return false;
    // sinon c'est ok
    return true;
  };

// condition dans ou dehors un cylindre 
 void Maillage::InitDansCylindre()
	{ int dima = ParaGlob::Dimension();
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  if (fr) {cout << "\n -- condition : dans ou a l'exterieur d'un cylindre ---- ";
	           cout << "\n un point de l'axe du cylindre  " << endl;
				  }
	  else    {cout << "\n -- condition : inside or outside a cylinder  ---- "; 
	           cout << "\n  a point belonging to the axis of the cylinder  " << endl;
				  };
   // acquisition d'un point
   Coordonnee centre(Acquisition_interactive_point());
	  double rayon=0.;
	  if (fr) {cout << "\n rayon du cylindre (on retient la partie positive) " << endl;}
	  else    {cout << "\n radius of the cylinder (only the absolute value will be kept) " << endl;};	  
	  rayon=lect_double();
	  rayon = Dabs(rayon); cout << " rayon retenu: "<< rayon << endl;
	  
	  if (fr) {cout << "\n le vecteur definissant  l'axe des cylindres  " << endl;}
	  else    {cout << "\n the vector of the axis of the cylinders  " << endl;};
   // acquisition d'un vecteur=direction
   Coordonnee axe(Acquisition_interactive_vecteur());
	  Cercle cer(centre,rayon,&axe);

	  t_cylindre.Change_taille(1);
	  t_cylindre(1).change_donnees(cer);
	};
 // ramène true si tous les points sont dans le cylindre
 bool Maillage::ExeDansCylindre(const Tableau <Coordonnee> & t_M)const
 	{ int tMtaille = t_M.Taille();
 	  for (int i=1;i<=tMtaille;i++)
 	    if (!(t_cylindre(1).Dedans(t_M(i)))) 
 	       return false;
 	  // sinon c'est ok
 	  return true;  
 	};
// ramène true si tous les points sont à l'extérieur du cylindre
bool Maillage::ExeOutCylindre(const Tableau <Coordonnee> & t_M)const
 	{ int tMtaille = t_M.Taille();
 	  for (int i=1;i<=tMtaille;i++)
 	    if ((t_cylindre(1).Dedans(t_M(i)))) 
 	       return false;
 	  // sinon c'est ok
 	  return true;  
 	};
        
// condition entre deux cylindre
void Maillage::InitEntreCylindre()
	{ int dima = ParaGlob::Dimension();
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  if (fr) {cout << "\n -- condition : entre deux cylindres ---- ";
	           cout << "\n un point de l'axe des deux cylindres  " << endl;
				  }
	  else    {cout << "\n -- condition : between two cylinders  ---- "; 
	           cout << "\n a point belonging to the axis of the cylinders  " << endl;
				  };
   // acquisition d'un point
   Coordonnee centre(Acquisition_interactive_point());
	  double rayon1=0.;
	  if (fr) {cout << "\n rayon du premier cylindre (on retient la partie positive) " << endl;}
	  else    {cout << "\n radius of the first cylinder (only the absolute value will be kept) " << endl;};	  
	  rayon1=lect_double();
	  rayon1 = Dabs(rayon1);
	  double rayon2=0.; 
	  if (fr) {cout << "\n rayon du second cylindre (on retient la partie positive) " << endl;}
	  else    {cout << "\n radius of the second cylinder (only the absolute value will be kept) " << endl;};	  
	  rayon2=lect_double();
	  rayon2 = Dabs(rayon2);
	  if (fr) {cout << "\n vecteur definissant  l'axe des cylindres  " << endl;}
	  else    {cout << "\n  vector of the axis of the cylinders  " << endl;};
   // acquisition d'un vecteur=direction
   Coordonnee axe(Acquisition_interactive_vecteur());
	  Cercle cer1(centre,MaX(rayon1,rayon2),&axe);
	  Cercle cer2(centre,MiN(rayon1,rayon2),&axe);

	  t_cylindre.Change_taille(2);
	  t_cylindre(1).change_donnees(cer1);
	  t_cylindre(2).change_donnees(cer2);
	};
// ramène true si tous les points sont entre les deux cylindres
bool Maillage::ExeEntreCylindre(const Tableau <Coordonnee> & t_M) const
 	{ int tMtaille = t_M.Taille();
 	  // on regarde si d'une part les points sont à l'intérieur du cylindre (le plus grand) et 
 	  // a l'extérieur du plus petit
 	  for (int i=1;i<=tMtaille;i++)
 	    if (   (!(t_cylindre(1).Dedans(t_M(i))))
 	         || ((t_cylindre(2).Dedans(t_M(i)))) )
 	       return false;
 	  // sinon c'est ok
 	  return true;  
 	};
 	
// condition dans ou dehors d'une sphére 
void Maillage::InitDansSphere()
	{ int dima = ParaGlob::Dimension();
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  if (fr) {cout << "\n -- condition : dans ou a l'exterieur d'une sphere ---- ";
	           cout << "\n le centre de la sphere  " << endl;
				  }
	  else    {cout << "\n -- condition : inside or outside of a sphere ---- "; 
	           cout << "\n the sphere center  " << endl;
				  };
   // acquisition d'un point
   Coordonnee centre(Acquisition_interactive_point());
	  double rayon=0.;
	  if (fr) {cout << "\n rayon de la sphere (on retient la partie positive) " << endl;}
	  else    {cout << "\n radius of the sphere (only the absolute value will be kept) " << endl;};
	  rayon=lect_double();
	  rayon = Dabs(rayon);

	  t_sphere.Change_taille(1);
	  t_sphere(1).change_donnees(centre,rayon);
	};

// ramène true si tous les points sont dans la sphère
bool Maillage::ExeDansSphere(const Tableau <Coordonnee> & t_M)const
 	{ int tMtaille = t_M.Taille();
 	  for (int i=1;i<=tMtaille;i++)
 	    if (!(t_sphere(1).Dedans(t_M(i)))) 
 	       return false;
 	  // sinon c'est ok
 	  return true;  
 	};
// ramène true si tous les points sont à l'extérieur de la sphère
bool Maillage::ExeOutSpheres(const Tableau <Coordonnee> & t_M)const
 	{ int tMtaille = t_M.Taille();
 	  for (int i=1;i<=tMtaille;i++)
 	    if ((t_sphere(1).Dedans(t_M(i)))) 
 	       return false;
 	  // sinon c'est ok
 	  return true;  
 	};
        
// condition entre deux sphères concentriques
void Maillage::InitEntreSpheres()
	{ int dima = ParaGlob::Dimension();
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  if (fr) {cout << "\n -- condition : entre deux spheres ---- ";
	           cout << "\n  le centre des spheres  " << endl;
				  }
	  else    {cout << "\n -- condition :between two spheres ---- "; 
	           cout << "\n the center of the spheres  " << endl;
				  };
   // acquisition d'un point
   Coordonnee centre(Acquisition_interactive_point());
	  double rayon1=0.;
	  if (fr) {cout << "\n rayon de la premiere sphere (on retient la partie positive) " << endl;}
	  else    {cout << "\n radius of the first sphere (only the absolute value will be kept) " << endl;};
	  rayon1=lect_double();
	  rayon1 = Dabs(rayon1);
	  double rayon2=0.;
	  if (fr) {cout << "\n rayon de la seconde sphere (on retient la partie positive) " << endl;}
	  else    {cout << "\n radius of the second sphere (only the absolute value will be kept) " << endl;};
	  rayon2=lect_double();
	  rayon2 = Dabs(rayon2);

	  t_sphere.Change_taille(2);
	  t_sphere(1).change_donnees(centre,MaX(rayon1,rayon2));
	  t_sphere(2).change_donnees(centre,MiN(rayon1,rayon2));
	};
// ramène true si tous les points sont entre les deux  sphères
bool Maillage::ExeEntreSpheres(const Tableau <Coordonnee> & t_M)const
 	{ int tMtaille = t_M.Taille();
 	  // on regarde si d'une part les points sont à l'intérieur de la sphère 1 (la plus grande) et 
 	  // a l'extérieur de la  plus petite
 	  for (int i=1;i<=tMtaille;i++)
 	    if (   (!(t_sphere(1).Dedans(t_M(i))))
 	         || ((t_sphere(2).Dedans(t_M(i)))) )
 	       return false;
 	  // sinon c'est ok
 	  return true;  
 	};
        
// condition du même coté d'une droite
void Maillage::InitCoteDroite()
	{ int dima = ParaGlob::Dimension();
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  //Coordonnee poin1(dima),poin2(dima);
	  if (fr) {cout << "\n -- condition : d'un meme cote d'une droite (2D) ---- "; 
	           cout << "\n def de la ligne: " << endl;
				  } 
	  else    {cout << "\n -- condition : on one side of a line (2D) ---- "; 
	           cout << "\n the line :  " << endl;
				  }; 
   // acquisition d'une droite
   Droite dr(Acquisition_interactive_droite());
	  t_droit.Change_taille(1);
	  t_droit(1)=dr; //change_donnees(poin1,(poin2-poin1));
	  t_poi.Change_taille(1);
	  if (fr) {cout << "\n un point d'un cote de la droite  " << endl;}
	  else    {cout << "\n a point on one side of the line   " << endl;};
   // acquisition d'un point
   Coordonnee poin(Acquisition_interactive_point());
	  t_poi(1)=poin;
	};

// ramène true si tous les points sont du même coté que t_poi(1) de la droite (en 2D uniquement)
bool Maillage::ExeCoteDroite(const Tableau <Coordonnee> & t_M)const
 	{ int tMtaille = t_M.Taille();
 	  for (int i=1;i<=tMtaille;i++)
 	    if (!(t_droit(1).DuMemeCote(t_poi(1),t_M(i)))) 
 	       return false;
 	  // sinon c'est ok
 	  return true;  
 	};
        
// condition entre 2 droites (en 2D seulement)
void Maillage::InitEntreDroite()
   {  int dima = ParaGlob::Dimension();
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  if (fr) {cout << "\n -- condition : entre deux droite (2D) ---- ";
	           cout << "\n la premiere ligne: " << endl;
				  } 
	  else    {cout << "\n -- condition : between two lines (2D) ---- "; 
	           cout << "\n the first line: " << endl;
				  } 
   // acquisition d'une droite
   Droite dr(Acquisition_interactive_droite());
	  t_droit.Change_taille(1);
	  t_droit(1)=dr; //
	  t_poi.Change_taille(1);
	  if (fr) {cout << "\n un point de la seconde droite (//)  " << endl;}
	  else    {cout << "\n a point belonging to the second line (//)  " << endl;};
   // acquisition d'un point
   Coordonnee poin(Acquisition_interactive_point());
	  t_poi(1)=poin;
	};

// ramène true si tous les points sont entre les 2 droites (en 2D uniquement)
bool Maillage::ExeEntreDroite(const Tableau <Coordonnee> & t_M)const
 	{ int tMtaille = t_M.Taille();
 	  // on regarde si d'une part les points sont du même coté que t_poi(1) et 
 	  // d'autre part si la distance du points à la première droite est <= à celle de t_poi(1)
 	  double dist = t_droit(1).Distance_a_la_droite(t_poi(1));
 	  for (int i=1;i<=tMtaille;i++)
 	    if (!(t_droit(1).DuMemeCote(t_poi(1),t_M(i)) && (t_droit(1).Distance_a_la_droite(t_M(i)) < dist ))) 
 	       return false;
 	  // sinon c'est ok
 	  return true;  
 	};

// condition entre 2 droites (en 2D seulement) _avec_distance
void Maillage::InitEntreDroite_avec_distance()
   {  int dima = ParaGlob::Dimension();
   bool fr = ParaGlob::Francais(); // pour simplifier
   if (fr) {cout << "\n -- condition : entre  droite (2D) +- une distance ---- ";
            cout << "\n la  ligne mediane : " << endl;
      }
   else    {cout << "\n -- condition : between line (2D) +- a distance---- ";
            cout << "\n the mediane line: " << endl;
      }
   // acquisition d'une droite
   Droite dr(Acquisition_interactive_droite());
   const Coordonnee& A = dr.PointDroite();
   // retourne le vecteur directeur de la droite (de norme = 1 )
   const Coordonnee& U = dr.VecDroite();
   double dist=0.;
   if (fr) {cout << "\n distance a la droite (on retient la partie positive) " << endl;}
   else    {cout << "\n distance to the line (only the absolute value will be kept) " << endl;}
   dist=lect_double();
   dist = Dabs(dist);
   Coordonnee Ap = A - dist * U;
   dr.Change_ptref(Ap);
   Coordonnee poin = A + 2.*dist * U;
   // enreg
   t_droit.Change_taille(1);
   t_droit(1)=dr; //
   t_poi.Change_taille(1);
   t_poi(1)=poin;
 };

// ramène true si tous les points sont entre les 2 droites (en 2D uniquement) _avec_distance
bool Maillage::ExeEntreDroite_avec_distance(const Tableau <Coordonnee> & t_M)const
  { int tMtaille = t_M.Taille();
    // on regarde si d'une part les points sont du même coté que t_poi(1) et
    // d'autre part si la distance du points à la première droite est <= à celle de t_poi(1)
    double dist = t_droit(1).Distance_a_la_droite(t_poi(1));
    for (int i=1;i<=tMtaille;i++)
      if (!(t_droit(1).DuMemeCote(t_poi(1),t_M(i)) && (t_droit(1).Distance_a_la_droite(t_M(i)) < dist )))
         return false;
    // sinon c'est ok
    return true;
  };

// condition dans ou dehors un cercle (en 2D seulement)
void Maillage::InitDansCercle()
	{ int dima = ParaGlob::Dimension();
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  if (fr) {cout << "\n -- condition : dans ou a l'exterieur d'un cercle (2D) ---- ";
	           cout << "\n le centre du cercle : " << endl;
				 }
	  else    {cout << "\n -- condition : inside or outside a cercle  (2D) ---- "; 
	           cout << "\n the cercle center: " << endl;
				 }
   // acquisition d'un point
   Coordonnee centre(Acquisition_interactive_point());
	  double rayon=0.;
	  if (fr) {cout << "\n rayon du cercle (on retient la partie positive) "<< endl; }
	  else    {cout << "\n radius of the cercle (only the absolute value will be kept) "<< endl; };
	  rayon=lect_double();
	  rayon = Dabs(rayon);

	  t_cercle.Change_taille(1,Cercle(dima));
	  t_cercle(1).change_donnees(centre,rayon,NULL);
	};

// ramène true si tous les points sont dans le cercle (en 2D seulement)
bool Maillage::ExeDansCercle(const Tableau <Coordonnee> & t_M)const
 	{ int tMtaille = t_M.Taille();
 	  for (int i=1;i<=tMtaille;i++)
 	    if (!(t_cercle(1).Dedans(t_M(i)))) 
 	       return false;
 	  // sinon c'est ok
 	  return true;  
 	};
// ramène true si tous les points sont à l'extérieur du cercle (en 2D seulement)
bool Maillage::ExeOutCercle(const Tableau <Coordonnee> & t_M)const
 	{ int tMtaille = t_M.Taille();
 	  for (int i=1;i<=tMtaille;i++)
 	    if ((t_cercle(1).Dedans(t_M(i)))) 
 	       return false;
 	  // sinon c'est ok
 	  return true;  
 	};
        
// condition entre cercles concentriques (en 2D seulement)
void Maillage::InitEntreCercles()
	{ int dima = ParaGlob::Dimension();
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  if (fr) {cout << "\n -- condition : entre deux cercles concentriques ---- ";
	           cout << "\n centre des cercle:  " << endl;
				 } 
	  else    {cout << "\n -- condition : between two concentric cercles ---- "; 
	           cout << "\n the center of the cercles: " << endl;
				 }; 
   // acquisition d'un point
   Coordonnee centre(Acquisition_interactive_point());
	  double rayon1=0.;
	  if (fr) {cout << "\n rayon du premier cercle (on retient la partie positive) "<< endl; }
	  else    {cout << "\n radius of the first cercle (only the absolute value will be kept) "<< endl; };
	  rayon1=lect_double();
	  rayon1 = Dabs(rayon1);
	  double rayon2=0.;
	  if (fr) {cout << "\n rayon du second cercle (on retient la partie positive) " << endl;}
	  else    {cout << "\n radius of the second cercle (only the absolute value will be kept) "<< endl; };
	  rayon2=lect_double();
	  rayon2 = Dabs(rayon2);

	  t_cercle.Change_taille(2,Cercle(dima));
	  t_cercle(1).change_donnees(centre,MaX(rayon1,rayon2),NULL);
	  t_cercle(2).change_donnees(centre,MiN(rayon1,rayon2),NULL);
	};
// ramène true si tous les points sont entre les deux  cercles concentriques
bool Maillage::ExeEntreCercles(const Tableau <Coordonnee> & t_M)const
 	{ int tMtaille = t_M.Taille();
 	  // on regarde si d'une part les points sont à l'intérieur du cercle  1 (le plus grand) et 
 	  // a l'extérieur du  plus petit
 	  for (int i=1;i<=tMtaille;i++)
 	    if (   (!(t_cercle(1).Dedans(t_M(i))))
 	         || ((t_cercle(2).Dedans(t_M(i)))) )
 	       return false;
 	  // sinon c'est ok
 	  return true;  
 	};

// acquisition d'un plan
Plan Maillage::Acquisition_interactive_plan()
 { int dima = ParaGlob::Dimension();
   bool fr = ParaGlob::Francais(); // pour simplifier
   Coordonnee poin(dima);
   Coordonnee normal(dima);
   if (fr) {cout << "\n coordonnee d'un point du premier plan ("<< dima << " reels) "
                 << "\n ou un noeud -> rep: noeud= <un num noeud> "
                 << "\n ou 3 noeuds pour tout le plan "
                 << "\n       -> noeudi= <num1>  <num2>  <num3>"
            << endl;
           }
   else    {cout << "\n coordinates of a point of the first plane ("<< dima << " reals) "
                 << "\n or one node -> answer: noeud= <un num noeud> "
                 << "\n or 3 nodes for the whole plane "
                 << "\n       -> noeudi= <num1>  <num2>  <num3>"
                 << endl;
            }
   int c=getchar();
   string inter("");// une chaîne vide
   string rep;
   std::getline (std::cin,rep);
   if (isalnum(c)|| (c=='-')) // si jamais on a lu quelque chose de viable dans c on le rajoute
     {inter.push_back(c);
      rep = inter + rep;
     };
   // si la taille de rep == 0 cela veut dire que c'est un retour chariot
//    if (rep.size()==0)
   char * chh = (char*)rep.c_str();
   #ifndef ENLINUX_STREAM
       istringstream flux (chh);
   #else
       istrstream flux (chh);
   #endif
   if(strstr(chh,"oeud=")!=0)
    {int numn; string toto;
     flux >> toto >> numn;
     cout << "\n numero de noeud lu "<< numn;
     poin = tab_noeud(numn)->Coord0();
     cout << "\n --> coordonnees lues: "; poin.Affiche_1(cout) ;
     if (fr) {cout << "\n coordonnees de la normale du  plan ("<< dima << " reels) " << endl;}
     else    {cout << "\n coordinates of the plane normal  ("<< dima << " reals) " << endl;}
     for (int i = 1; i<= dima; i++) cin  >> normal(i);
     cout << "\n --> normale lue: "; normal.Affiche_1(cout) ;
     std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );// purge de cin
    }
   else if(strstr(chh,"oeudi=")!=0)
    { int n1,n2,n3; string toto;
      flux >> toto >> n1 >>  n2 >>  n3;
      cout << "\n numeros de noeud lu "<< n1 <<", "<<n2<<", "<<n3 ;
      poin = tab_noeud(n1)->Coord0();
      // on fait le produit vectoriel pour la normale
      Coordonnee v1( tab_noeud(n2)->Coord0() - poin);
      Coordonnee v2( tab_noeud(n3)->Coord0() - poin);
      normal = Util::ProdVec_coor(v1,v2);
    }
   else
    { for (int i = 1; i<= dima; i++) flux  >> poin(i);
      cout << "\n --> coordonnees lues: "; poin.Affiche_1(cout) ;
      if (fr) {cout << "\n coordonnees de la normale du  plan ("<< dima << " reels) " << endl;}
      else    {cout << "\n coordinates of the plane normal  ("<< dima << " reals) " << endl;}
      for (int i = 1; i<= dima; i++) cin  >> normal(i);
      cout << "\n --> normale lue: "; normal.Affiche_1(cout) ;
      std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );// purge de cin

    };
  
   Plan pl(poin,normal);
   return pl;
 };

// acquisition d'un point
Coordonnee Maillage::Acquisition_interactive_point()
 { int dima = ParaGlob::Dimension();
   bool fr = ParaGlob::Francais(); // pour simplifier
   Coordonnee poin(dima);
   if (fr) {cout << "\n coordonnee d'un point  ("<< dima << " reels) "
                 << "\n ou un noeud -> rep: noeud= <un num noeud> "
            << flush;
           }
   else    {cout << "\n coordinates of a point  ("<< dima << " reals) "
                 << "\n or one node -> answer: noeud= <un num noeud> "
                 << flush;
            }
   using namespace std;
   // on passe un caractère, *** je ne sais pas pourquoi *** pour que getline fonctionne !! (pas d'indication au niveau de rdstate
//   cout << "\n cin.iostat good(): "<< cin.good() << " eof: "<< cin.eof()
//        << " fail: "<< cin.fail() << " bad: "<< cin.bad()
//        << "\n rdstate(): " << cin.rdstate() << endl;
   int c=getchar();
   string inter("");// une chaîne vide
   string rep;
   std::getline (std::cin,rep);
   if (isalnum(c) || (c=='-')) // si jamais on a lu quelque chose de viable dans c on le rajoute
    {inter.push_back(c);
//     cout << "\n** valeur de c "<< c << flush;
     rep = inter + rep;
    };
     // si la taille de rep == 0 cela veut dire que c'est un retour chariot
//     if (rep.size()==0)
   char * chh = (char*)rep.c_str();
   #ifndef ENLINUX_STREAM
       istringstream flux (chh);
   #else
       istrstream flux (chh);
   #endif
   if(strstr(chh,"oeud=")!=0)
    {int numn; string toto;
     flux >> toto >> numn;
     cout << "\n numero de noeud lu "<< numn;
     poin = tab_noeud(numn)->Coord0();
    }
   else
    { for (int i = 1; i<= dima; i++) flux  >> poin(i);
      cout << "\n --> coordonnees lues: "; poin.Affiche_1(cout) ;
    };
   return poin;
 };

// acquisition d'une droite
Droite Maillage::Acquisition_interactive_droite()
 { int dima = ParaGlob::Dimension();
   bool fr = ParaGlob::Francais(); // pour simplifier
   Coordonnee poin1(dima);
   // --- le premier point ----
   if (fr) {cout << "\n coordonnee d'un point de la droite ("<< dima << " reels) "
                 << "\n ou un noeud -> rep: noeud= <un num noeud> "
            << endl;
           }
   else    {cout << "\n coordinates of a point of the line ("<< dima << " reals) "
                 << "\n or one node -> answer: noeud= <un num noeud> "
                 << endl;
            }
   using namespace std;
   {// on passe un caractère, *** je ne sais pas pourquoi *** pour que getline fonctionne !! (pas d'indication au niveau de rdstate
//   cout << "\n cin.iostat good(): "<< cin.good() << " eof: "<< cin.eof()
//        << " fail: "<< cin.fail() << " bad: "<< cin.bad()
//        << "\n rdstate(): " << cin.rdstate() << endl;
    int c=getchar();
    string inter("");// une chaîne vide
    string rep;
    std::getline (std::cin,rep);
    if (isalnum(c)) // si jamais on a lu quelque chose de viable dans c on le rajoute
      {inter.push_back(c);
       rep = inter + rep;
      };
     // si la taille de rep == 0 cela veut dire que c'est un retour chariot
//     if (rep.size()==0)
    char * chh = (char*)rep.c_str();
    #ifndef ENLINUX_STREAM
        istringstream flux (chh);
    #else
        istrstream flux (chh);
    #endif
    if(strstr(chh,"oeud=")!=0)
     {int numn; string toto;
      flux >> toto >> numn;
      cout << "\n numero de noeud lu "<< numn;
      poin1 = tab_noeud(numn)->Coord0();
     }
    else
     { for (int i = 1; i<= dima; i++) flux  >> poin1(i);
       cout << "\n --> coordonnees lues: "; poin1.Affiche_1(cout) ;
     };
   };
   // --- le second point ----
   Coordonnee poin2(dima);
   if (fr) {cout << "\n coordonnee du second point de la droite ("<< dima << " reels) "
                 << "\n ou un noeud -> rep: noeud= <un num noeud> "
            << endl;
           }
   else    {cout << "\n coordinates of the second point of the line ("<< dima << " reals) "
                 << "\n or one node -> answer: noeud= <un num noeud> "
                 << endl;
            }
   {// on passe un caractère, *** je ne sais pas pourquoi *** pour que getline fonctionne !! (pas d'indication au niveau de rdstate
//   cout << "\n cin.iostat good(): "<< cin.good() << " eof: "<< cin.eof()
//        << " fail: "<< cin.fail() << " bad: "<< cin.bad()
//        << "\n rdstate(): " << cin.rdstate() << endl;
    int c=getchar();
    string inter("");// une chaîne vide
    string rep;
    std::getline (std::cin,rep);
    if (isalnum(c)|| (c=='-')) // si jamais on a lu quelque chose de viable dans c on le rajoute
      {inter.push_back(c);
       rep = inter + rep;
      };
     // si la taille de rep == 0 cela veut dire que c'est un retour chariot
//     if (rep.size()==0)
    char * chh = (char*)rep.c_str();
    #ifndef ENLINUX_STREAM
        istringstream flux (chh);
    #else
        istrstream flux (chh);
    #endif
    if(strstr(chh,"oeud=")!=0)
     {int numn; string toto;
      flux >> toto >> numn;
      cout << "\n numero de noeud lu "<< numn;
      poin2 = tab_noeud(numn)->Coord0();
     }
    else
     { for (int i = 1; i<= dima; i++) flux  >> poin2(i);
       cout << "\n --> coordonnees lues: "; poin2.Affiche_1(cout) ;
     };
   };
   Coordonnee V(poin2-poin1);
   Droite dl(poin1,V);
   return dl;
 };

// acquisition d'un vecteur=direction
Coordonnee Maillage::Acquisition_interactive_vecteur()
 { int dima = ParaGlob::Dimension();
   bool fr = ParaGlob::Francais(); // pour simplifier
   Coordonnee V(dima);
   if (fr) {cout << "\n coordonnee du vecteur ("<< dima << " reels) "
                 << "\n ou 2 noeuds pour tout le plan "
                 << "\n       -> noeudi= <num1>  <num2> "
            << endl;
           }
   else    {cout << "\n coordinates of a the vector ("<< dima << " reals) "
                 << "\n or 2 nodes for the whole plane "
                 << "\n       -> noeudi= <num1>  <num2> "
                 << endl;
            }
   int c=getchar();
   string inter("");// une chaîne vide
   string rep;
   std::getline (std::cin,rep);
   if (isalnum(c) || (c=='-')) // si jamais on a lu quelque chose de viable dans c on le rajoute
     {inter.push_back(c);
      rep = inter + rep;
     };
    // si la taille de rep == 0 cela veut dire que c'est un retour chariot
//    if (rep.size()==0)
   char * chh = (char*)rep.c_str();
   #ifndef ENLINUX_STREAM
       istringstream flux (chh);
   #else
       istrstream flux (chh);
   #endif
   if(strstr(chh,"noeudi=")!=0)
    {
      Coordonnee poin1(dima);
      Coordonnee poin2(dima);
      int n1,n2; string toto;
      flux >> toto >> n1 >>  n2 ;
      cout << "\n numeros de noeud lu "<< n1 <<", "<<n2 ;
      poin1 = tab_noeud(n1)->Coord0();
      poin2 = tab_noeud(n2)->Coord0();
      V = poin2-poin1;
    }
   else
    { for (int i = 1; i<= dima; i++) flux  >> V(i);
      cout << "\n --> coordonnees lues: "; V.Affiche_1(cout) ;
    };

   return V;
 };


// condition d'appartenance  à une référence existante 
void Maillage::InitInRef()
	{ bool fr = ParaGlob::Francais(); // pour simplifier
	  string nom_ref; const Reference * refIn = NULL;
	  bool demande_fin = false;
	  while (!demande_fin) 
	   {if (fr) {cout << "\n -- condition : appartenance a une reference  ---- ";
	             cout << "\n    nom de la reference existante ? (seules les ref de "
		                 << "\n    meme type seront comparees) " << endl;
					        }
	    else    {cout << "\n -- condition : belonging to an already existing reference  ---- ";
	             cout << "\n    name of the reference ? (only a reference of a "
		                 << "\n    same type can be used) " << endl;
					        };
	    nom_ref=lect_return_defaut(true,"f");
		   if (nom_ref == "f" ) {demande_fin = true;}
	      // sinon on essaie de récupérer la référence
	    else if (!(lesRefin->Existe(nom_ref,idmail)))
		    {if (fr) {cout << "\n le nom lue " << nom_ref << " ne correspond pas a une reference existante "
			                  << " donnez un autre nom ou taper f pour finir ";
						         }
		     else    {cout << "\n the input name " << nom_ref << " does not belong to an existing reference "
			                  << " give another name, or f for leaving ";
               };
      }
		   else 
		    { // on récupère la référence
        refIn =  &(lesRefin->Trouve(nom_ref,idmail)); 
        list_refIn.push_back(refIn);
        demande_fin=true; // seul cas où tout est ok
      } 	
		 };	
	};
// ramène true si tous les points appartiennent à la ref
//bool Maillage::ExeInRef (const Tableau <Coordonnee> & t_M)const
// { //const ReferenceNE & refi = *((ReferenceNE *) refIn);
   // on récupère tous les noeuds de la référence


//  };
// condition d'exclusion à une référence existante 
void Maillage::InitOutRef()
	{ bool fr = ParaGlob::Francais(); // pour simplifier
	  string nom_ref; const Reference * refOut = NULL;
	  bool demande_fin = false;
	  while (!demande_fin) 
	   {if (fr) {cout << "\n -- condition : hors d'une reference  ---- ";
	             cout << "\n    nom de la reference existante ? (seules les ref de "
		                 << "\n    meme type seront comparees) " << endl;
					        }
	    else    {cout << "\n -- condition : out of to an already existing reference  ---- ";
	             cout << "\n    name of the reference ? (only a reference of a "
		                 << "\n    same type can be used) " << endl;
					        };
     nom_ref=lect_return_defaut(true,"f");
		   if (nom_ref == "f" ) {demande_fin = true;}
	      // sinon on essaie de récupérer la référence
     else if (!(lesRefin->Existe(nom_ref,idmail)))
		    {if (fr) {cout << "\n le nom lue " << nom_ref << " ne correspond pas a une reference existante "
			                  << " donnez un autre nom ou taper f pour finir ";
               }
		     else    {cout << "\n the input name " << nom_ref << " does not belong to an existing reference "
			                  << " give another name, or f for leaving ";
               }
			   }
		   else
		    { // on récupère la référence
        refOut =  &(lesRefin->Trouve(nom_ref,idmail));
        list_refOut.push_back(refOut);
			     demande_fin=true; // seul cas où tout est ok
      }
		  };
	};

// 1) une fonction qui ne fait rien, mais est là pour que le tout fonctionne normalement
bool Maillage::Exe_In_out_avecRefExistantes(const Tableau <Coordonnee> & t_M)const
 {return true;}; // ne fait rien
 
// 2) fonctions qui réellement font quelque chose: utilisées dans la méthode EnregRef
//  a - cas des ref de noeuds
void Maillage::Exe_In_out_avecRefExistantes_N(list <Noeud *>& list_noeud_restant)
{ 
   // ---- cas des ref in
  list <Noeud *> liste_finale_in;
  { // on commence par concaténer l'ensemble des noeuds des refs In
    list <const Reference*>::iterator lref,lref_fin= list_refIn.end();
    for (lref=list_refIn.begin();lref != lref_fin; lref++)
	    {// on ne continue que si c'est une ref de noeud, du même maillage
	     if (((*lref)->Indic() == 1) && ((*lref)->Nbmaille() == idmail))
		     {  ReferenceNE * refi = ((ReferenceNE *) (*lref));
		        const Tableau<int>& tab_num = refi->Tab_num();
			       int tailmax = tab_num.Taille();
			       for (int i=1;i<=tailmax;i++)
			         {liste_finale_in.push_back(tab_noeud(tab_num(i)));};
			    };
	    };
    // on trie et on supprime les doublons
	   liste_finale_in.sort();
	   liste_finale_in.unique();
  }; 
	 list <Noeud *>::iterator lf_in_deb=liste_finale_in.begin();
	 list <Noeud *>::iterator lf_in_end=liste_finale_in.end();
   // ---- cas des ref out
	 list <Noeud *> liste_finale_out;
  { // on commence par concaténer l'ensemble des noeuds des refs out
    list <const Reference*>::iterator lref,lref_fin= list_refOut.end();
	   for (lref=list_refOut.begin();lref != lref_fin; lref++)
	    { // on ne continue que si c'est une ref de noeud, du même maillage
	      if (((*lref)->Indic() == 1) && ((*lref)->Nbmaille() == idmail))
		      {  ReferenceNE * refi = ((ReferenceNE *) (*lref));
		         const Tableau<int>& tab_num = refi->Tab_num();
			        int tailmax = tab_num.Taille();
			        for (int i=1;i<=tailmax;i++)
			          {liste_finale_out.push_back(tab_noeud(tab_num(i)));};
			     };
	    };
    // on trie et on supprime les doublons
    liste_finale_out.sort();
	   liste_finale_out.unique();
	 }; 
	 list <Noeud *>::iterator lf_out_deb=liste_finale_out.begin();
	 list <Noeud *>::iterator lf_out_end=liste_finale_out.end();
		
////--- debug
//   cout << "\n Maillage::Exe_In_out_avecRefExistantes_N(..";
//   cout << "\n list in ";
//   list < Noeud*>::iterator lnn;
//	for (lnn=lf_in_deb;lnn != lf_in_end; lnn++)
//	 cout  << (*lnn)->Num_noeud() << " ";
//   cout << "\n list out ";
//	for (lnn=lf_out_deb;lnn != lf_out_end; lnn++)
//	 cout  << (*lnn)->Num_noeud() << " ";
//   cout << "\n list finale avant traitement ";
//	for (lnn=list_noeud_restant.begin();lnn != list_noeud_restant.end(); lnn++)
//	 cout  << (*lnn)->Num_noeud() << " ";
////--- fin debug


   // ---- application	
  // on passe en revue les noeuds et on regarde s'ils font partie d'une des listes In 
	 // et s'ils sont en dehors des out
	 bool liste_finale_in_a_considerer = liste_finale_in.size();
	 bool liste_finale_out_a_considerer = liste_finale_out.size();
////--- debug
//	 cout  << "liste_finale_in_a_considerer" << liste_finale_in_a_considerer
//        << "liste_finale_out_a_considerer" << liste_finale_out_a_considerer << endl;
////--- fin debug
	 list <Noeud*>::iterator li;
  list <Noeud*> liinter(list_noeud_restant);
  int nb_trouve_in=0; int nb_trouve_out=0;
	 // comme on supprime en cours de route des ref de noeuds on recalcul la borne sup à chaque passage
	 for (li=list_noeud_restant.begin();li != list_noeud_restant.end();li++)
	  { bool deja_supprime = false; // pour indiquer si un element a déjà ete supprimer, ce qui evite une double
////--- fin debug
//	 cout  << "(*li)->Num_noeud()=" << (*li)->Num_noeud() << endl;
//  cout << "\n taper un lettre "; string unelettre ; cin >> unelettre;
////--- fin debug
     if (liste_finale_in_a_considerer) // prise en compte que si la liste est non vide
	      {if (find(lf_in_deb, lf_in_end, *li) == lf_in_end)
	        // on n'a pas trouvé de noeud appartenant à la liste, on supprime le noeud
		       {//list <Noeud*>::iterator toto = li;
          liinter.remove(*li);//
//          list_noeud_restant.remove(*li);
          nb_trouve_in++;deja_supprime=true;
         }
       };
	    if ((liste_finale_out_a_considerer)&&(!deja_supprime)) // prise en compte que si la liste est non vide
	      {if (find(lf_out_deb, lf_out_end, *li) != lf_out_end)
	        // on a  trouvé un noeud appartenant à la liste, on supprime le noeud
		       {//list_noeud_restant.erase(li);
          liinter.remove(*li);//
          nb_trouve_out++;
         };
        };
   };
 
 list_noeud_restant = liinter;
 
  if (ParaGlob::NiveauImpression() > 4)
    { if (liste_finale_in_a_considerer)
        cout << "\n "<<nb_trouve_in<<" elements ajoutes a partir  des refs in ";
      if (liste_finale_out_a_considerer)
        cout << "\n "<<nb_trouve_out<<" elements supprimes a partir des refs out ";
      cout << endl;
    };
 };
//  b - cas des ref d'éléments
void Maillage::Exe_In_out_avecRefExistantes_E(list <Element *>& list_element_restant)
{ 
   // ---- cas des ref in
  list <Element *> liste_finale_in;
  { // on commence par concaténer l'ensemble des Elements des refs In
    list <const Reference*>::iterator lref,lref_fin= list_refIn.end();
    for (lref=list_refIn.begin();lref != lref_fin; lref++)
	    {// on ne continue que si c'est une ref de Element, du même maillage
	     if (((*lref)->Indic() == 2) && ((*lref)->Nbmaille() == idmail))
		     {  ReferenceNE * refi = ((ReferenceNE *) (*lref));
		        const Tableau<int>& tab_num = refi->Tab_num();
			       int tailmax = tab_num.Taille();
			       for (int i=1;i<=tailmax;i++)
			         {liste_finale_in.push_back(tab_element(tab_num(i)));};
			    };
	    };
    // on trie et on supprime les doublons
	   liste_finale_in.sort();
	   liste_finale_in.unique();
  }; 
	 list <Element *>::iterator lf_in_deb=liste_finale_in.begin();
	 list <Element *>::iterator lf_in_end=liste_finale_in.end();
   // ---- cas des ref out
	 list <Element *> liste_finale_out;
  { // on commence par concaténer l'ensemble des Elements des refs out
    list <const Reference*>::iterator lref,lref_fin= list_refOut.end();
	   for (lref=list_refOut.begin();lref != lref_fin; lref++)
	    { // on ne continue que si c'est une ref de Element, du même maillage
	      if (((*lref)->Indic() == 2) && ((*lref)->Nbmaille() == idmail))
		      {  ReferenceNE * refi = ((ReferenceNE *) (*lref));
		         const Tableau<int>& tab_num = refi->Tab_num();
			        int tailmax = tab_num.Taille();
			        for (int i=1;i<=tailmax;i++)
			          {liste_finale_out.push_back(tab_element(tab_num(i)));};
			     };
	    };
    // on trie et on supprime les doublons
    liste_finale_out.sort();
	   liste_finale_out.unique();
	 }; 
	 list <Element *>::iterator lf_out_deb=liste_finale_out.begin();
	 list <Element *>::iterator lf_out_end=liste_finale_out.end();
		
////--- debug
//   cout << "\n Maillage::Exe_In_out_avecRefExistantes_N(..";
//   cout << "\n list in ";
//   list < Element*>::iterator lnn;
//	for (lnn=lf_in_deb;lnn != lf_in_end; lnn++)
//	 cout  << (*lnn)->Num_Element() << " ";
//   cout << "\n list out ";
//	for (lnn=lf_out_deb;lnn != lf_out_end; lnn++)
//	 cout  << (*lnn)->Num_Element() << " ";
//   cout << "\n list finale avant traitement ";
//	for (lnn=list_element_restant.begin();lnn != list_element_restant.end(); lnn++)
//	 cout  << (*lnn)->Num_Element() << " ";
////--- fin debug


   // ---- application	
  // on passe en revue les Elements et on regarde s'ils font partie d'une des listes In
	 // et s'ils sont en dehors des out
	 bool liste_finale_in_a_considerer = liste_finale_in.size();
	 bool liste_finale_out_a_considerer = liste_finale_out.size();
	 list <Element*>::iterator li;
  int nb_trouve_in=0; int nb_trouve_out=0;
	 // comme on supprime en cours de route des ref de Elements on recalcul la borne sup à chaque passage
	 for (li=list_element_restant.begin();li != list_element_restant.end();li++)
	  { bool deja_supprime = false; // pour indiquer si un element a déjà ete supprimer, ce qui evite une double
     if (liste_finale_in_a_considerer) // prise en compte que si la liste est non vide
	      if (find(lf_in_deb, lf_in_end, *li) == lf_in_end)
	        // on n'a pas trouvé de Element appartenant à la liste, on supprime le Element
		       {list_element_restant.erase(li);nb_trouve_in++;deja_supprime=true;}
	    if ((liste_finale_out_a_considerer)&&(!deja_supprime)) // prise en compte que si la liste est non vide
	      if (find(lf_out_deb, lf_out_end, *li) != lf_out_end)
	        // on a  trouvé un Element appartenant à la liste, on supprime le Element
		       {list_element_restant.erase(li);nb_trouve_out++;}
   };
 
  if (ParaGlob::NiveauImpression() > 4)
    { if (liste_finale_in_a_considerer)
        cout << "\n "<<nb_trouve_in<<" elements ajoutes a partir  des refs in ";
      if (liste_finale_out_a_considerer)
        cout << "\n "<<nb_trouve_out<<" elements supprimes a partir des refs out ";
      cout << endl;
    };
 };

//  c - cas des ref de points d'intégration 
void Maillage::Exe_In_out_avecRefExistantes_G(list <NBelemEtptInteg>& list_elemPtin_restant)
{ 
   // ---- cas des ref in pour les pti
  list <NBelemEtptInteg >  liste_finale_in;
  { // on commence par concaténer l'ensemble des pti des refs In
    list <const Reference*>::iterator lref,lref_fin= list_refIn.end();
    for (lref=list_refIn.begin();lref != lref_fin; lref++)
	    {// on ne continue que si c'est une ref de pti, du même maillage
	     if (((*lref)->Indic() == 6) && ((*lref)->Nbmaille() == idmail))
		     {  ReferenceAF * refi = ((ReferenceAF *) (*lref));
          const Tableau<int>& tab_elem = refi->Tab_Elem();
          const Tableau<int>& tab_fa = refi->Tab_FA();
			       int tailmax = tab_elem.Taille();
			       for (int i=1;i<=tailmax;i++)
			         { NBelemEtptInteg nu; nu.nbElem = tab_elem(i); nu.nbPtInteg = tab_fa(i);
              liste_finale_in.push_back(nu);
            };
			    };
	    };
    // on trie et on supprime les doublons
	   liste_finale_in.sort();
	   liste_finale_in.unique();
  }; 
	 list <NBelemEtptInteg >::iterator lf_in_deb=liste_finale_in.begin();
	 list <NBelemEtptInteg >::iterator lf_in_end=liste_finale_in.end();
   // ---- cas des ref out
	 list <NBelemEtptInteg > liste_finale_out;
  { // on commence par concaténer l'ensemble des pti des refs out
    list <const Reference*>::iterator lref,lref_fin= list_refOut.end();
	   for (lref=list_refOut.begin();lref != lref_fin; lref++)
	    { // on ne continue que si c'est une ref de pti, du même maillage
	      if (((*lref)->Indic() == 6) && ((*lref)->Nbmaille() == idmail))
		      {  ReferenceAF * refi = ((ReferenceAF *) (*lref));
           const Tableau<int>& tab_elem = refi->Tab_Elem();
           const Tableau<int>& tab_fa = refi->Tab_FA();
			        int tailmax = tab_elem.Taille();
			        for (int i=1;i<=tailmax;i++)
			         { NBelemEtptInteg nu; nu.nbElem = tab_elem(i); nu.nbPtInteg = tab_fa(i);
              liste_finale_out.push_back(nu);
            };
			     };
	    };
    // on trie et on supprime les doublons
    liste_finale_out.sort();
	   liste_finale_out.unique();
	 }; 
	 list <NBelemEtptInteg >::iterator lf_out_deb=liste_finale_out.begin();
	 list <NBelemEtptInteg >::iterator lf_out_end=liste_finale_out.end();
		
////--- debug
//
////--- debug
//   cout << "\n Maillage::Exe_In_out_avecRefExistantes_F(..";
//   cout << "\n list in ";
//   list < NBelemEtptInteg>::iterator lnn;
//	  for (lnn=lf_in_deb;lnn != lf_in_end; lnn++)
//	    cout  << (*lnn).nbElem << " "<< (*lnn).nbPtInteg << " ";
//   cout << "\n list out ";
//	  for (lnn=lf_out_deb;lnn != lf_out_end; lnn++)
//	    cout  << (*lnn).nbElem << " "<< (*lnn).nbPtInteg << " ";
//   cout << "\n list finale avant traitement ";
//	  for (lnn=list_elemPtin_restant.begin();lnn != list_elemPtin_restant.end(); lnn++)
//	    cout  << (*lnn).nbElem << " "<< (*lnn).nbPtInteg << " ";
////--- fin debug


   // ---- application	
  // on passe en revue les pti et on regarde s'ils font partie d'une des listes In 
	 // et s'ils sont en dehors des out
	 bool liste_finale_in_a_considerer = liste_finale_in.size();
	 bool liste_finale_out_a_considerer = liste_finale_out.size();
	 list <NBelemEtptInteg>::iterator li;
  int nb_trouve_in=0; int nb_trouve_out=0;
	 // comme on supprime en cours de route des ref de face on recalcul la borne sup à chaque passage
	 for (li=list_elemPtin_restant.begin();li != list_elemPtin_restant.end();li++)
	  { bool deja_supprime = false; // pour indiquer si un element a déjà ete supprimer, ce qui evite une double
     if (liste_finale_in_a_considerer) // prise en compte que si la liste est non vide
	      if (find(lf_in_deb, lf_in_end, *li) == lf_in_end)
	        // on n'a pas trouvé de face appartenant à la liste, on supprime le pti
		       {list_elemPtin_restant.erase(li);nb_trouve_in++;deja_supprime=true;}
	    if ((liste_finale_out_a_considerer)&&(!deja_supprime)) // prise en compte que si la liste est non vide
	      if (find(lf_out_deb, lf_out_end, *li) != lf_out_end)
	        // on a  trouvé une face appartenant à la liste, on supprime le pti
		       {list_elemPtin_restant.erase(li);nb_trouve_out++;}
   };
 
  if (ParaGlob::NiveauImpression() > 4)
    { if (liste_finale_in_a_considerer)
        cout << "\n "<<nb_trouve_in<<" elements ajoutes a partir  des refs in ";
      if (liste_finale_out_a_considerer)
        cout << "\n "<<nb_trouve_out<<" elements supprimes a partir des refs out ";
      cout << endl;
    };
////--- debug
//   cout << "\n Maillage::Exe_In_out_avecRefExistantes_F(..";
//   cout << "\n list finale après traitement ";
//	  for (lnn=list_elemFace_restant.begin();lnn != list_elemFace_restant.end(); lnn++)
//	    cout  << (*lnn).nbElem << " "<< (*lnn).nbPtInteg << " ";
////--- fin debug
 };
//  d - cas des ref des faces
void Maillage::Exe_In_out_avecRefExistantes_F(list <NBelemEtFace>& list_elemFace_restant)
{ 
   // ---- cas des ref in pour les faces
  list <NBelemEtFace >  liste_finale_in;
  { // on commence par concaténer l'ensemble des faces des refs In
    list <const Reference*>::iterator lref,lref_fin= list_refIn.end();
    for (lref=list_refIn.begin();lref != lref_fin; lref++)
	    {// on ne continue que si c'est une ref de face, du même maillage
	     if (((*lref)->Indic() == 3) && ((*lref)->Nbmaille() == idmail))
		     {  ReferenceAF * refi = ((ReferenceAF *) (*lref));
          const Tableau<int>& tab_elem = refi->Tab_Elem();
          const Tableau<int>& tab_fa = refi->Tab_FA();
			       int tailmax = tab_elem.Taille();
			       for (int i=1;i<=tailmax;i++)
			         { NBelemEtFace nu; nu.nbElem = tab_elem(i); nu.nbFace = tab_fa(i);
              liste_finale_in.push_back(nu);
            };
			    };
	    };
    // on trie et on supprime les doublons
	   liste_finale_in.sort();
	   liste_finale_in.unique();
  }; 
	 list <NBelemEtFace >::iterator lf_in_deb=liste_finale_in.begin();
	 list <NBelemEtFace >::iterator lf_in_end=liste_finale_in.end();
   // ---- cas des ref out
	 list <NBelemEtFace > liste_finale_out;
  { // on commence par concaténer l'ensemble des faces des refs out
    list <const Reference*>::iterator lref,lref_fin= list_refOut.end();
	   for (lref=list_refOut.begin();lref != lref_fin; lref++)
	    { // on ne continue que si c'est une ref de face, du même maillage
	      if (((*lref)->Indic() == 3) && ((*lref)->Nbmaille() == idmail))
		      {  ReferenceAF * refi = ((ReferenceAF *) (*lref));
           const Tableau<int>& tab_elem = refi->Tab_Elem();
           const Tableau<int>& tab_fa = refi->Tab_FA();
			        int tailmax = tab_elem.Taille();
			        for (int i=1;i<=tailmax;i++)
			         { NBelemEtFace nu; nu.nbElem = tab_elem(i); nu.nbFace = tab_fa(i);
              liste_finale_out.push_back(nu);
            };
			     };
	    };
    // on trie et on supprime les doublons
    liste_finale_out.sort();
	   liste_finale_out.unique();
	 }; 
	 list <NBelemEtFace >::iterator lf_out_deb=liste_finale_out.begin();
	 list <NBelemEtFace >::iterator lf_out_end=liste_finale_out.end();
		
////--- debug
//
////--- debug
//   cout << "\n Maillage::Exe_In_out_avecRefExistantes_F(..";
//   cout << "\n list in ";
//   list < NBelemEtFace>::iterator lnn;
//	  for (lnn=lf_in_deb;lnn != lf_in_end; lnn++)
//	    cout  << (*lnn).nbElem << " "<< (*lnn).nbFace << " ";
//   cout << "\n list out ";
//	  for (lnn=lf_out_deb;lnn != lf_out_end; lnn++)
//	    cout  << (*lnn).nbElem << " "<< (*lnn).nbFace << " ";
//   cout << "\n list finale avant traitement ";
//	  for (lnn=list_elemFace_restant.begin();lnn != list_elemFace_restant.end(); lnn++)
//	    cout  << (*lnn).nbElem << " "<< (*lnn).nbFace << " ";
////--- fin debug


   // ---- application	
  // on passe en revue les faces et on regarde s'ils font partie d'une des listes In 
	 // et s'ils sont en dehors des out
	 bool liste_finale_in_a_considerer = liste_finale_in.size();
	 bool liste_finale_out_a_considerer = liste_finale_out.size();
	 list <NBelemEtFace>::iterator li;
  int nb_trouve_in=0; int nb_trouve_out=0;
	 // comme on supprime en cours de route des ref de face on recalcul la borne sup à chaque passage
	 for (li=list_elemFace_restant.begin();li != list_elemFace_restant.end();li++)
	  { bool deja_supprime = false; // pour indiquer si un element a déjà ete supprimer, ce qui evite une double
     if (liste_finale_in_a_considerer) // prise en compte que si la liste est non vide
	      if (find(lf_in_deb, lf_in_end, *li) == lf_in_end)
	        // on n'a pas trouvé de face appartenant à la liste, on supprime le face
		       {list_elemFace_restant.erase(li);nb_trouve_in++;deja_supprime=true;}
	    if ((liste_finale_out_a_considerer)&&(!deja_supprime)) // prise en compte que si la liste est non vide
	      if (find(lf_out_deb, lf_out_end, *li) != lf_out_end)
	        // on a  trouvé une face appartenant à la liste, on supprime le face
		       {list_elemFace_restant.erase(li);nb_trouve_out++;}
   };
  if (ParaGlob::NiveauImpression() > 4)
    { if (liste_finale_in_a_considerer)
        cout << "\n "<<nb_trouve_in<<" faces ajoutes a partir  des refs in ";
      if (liste_finale_out_a_considerer)
        cout << "\n "<<nb_trouve_out<<" faces supprimes a partir des refs out ";
      cout << endl;
    };
 
////--- debug
//   cout << "\n Maillage::Exe_In_out_avecRefExistantes_F(..";
//   cout << "\n list finale après traitement ";
//	  for (lnn=list_elemFace_restant.begin();lnn != list_elemFace_restant.end(); lnn++)
//	    cout  << (*lnn).nbElem << " "<< (*lnn).nbFace << " ";
////--- fin debug
 };
//  e - cas des ref des arêtes d'éléments
void Maillage::Exe_In_out_avecRefExistantes_A(list <NBelemEtArete>& list_elemArrete_restant)
{ 
   // ---- cas des ref in pour les arêtes
  list <NBelemEtArete >  liste_finale_in;
  { // on commence par concaténer l'ensemble des arêtes des refs In
    list <const Reference*>::iterator lref,lref_fin= list_refIn.end();
    for (lref=list_refIn.begin();lref != lref_fin; lref++)
	    {// on ne continue que si c'est une ref de arêtes, du même maillage
	     if (((*lref)->Indic() == 4) && ((*lref)->Nbmaille() == idmail))
		     {  ReferenceAF * refi = ((ReferenceAF *) (*lref));
          const Tableau<int>& tab_elem = refi->Tab_Elem();
          const Tableau<int>& tab_fa = refi->Tab_FA();
			       int tailmax = tab_elem.Taille();
			       for (int i=1;i<=tailmax;i++)
			         { NBelemEtArete nu; nu.nbElem = tab_elem(i); nu.nbArete = tab_fa(i);
              liste_finale_in.push_back(nu);
            };
			    };
	    };
    // on trie et on supprime les doublons
	   liste_finale_in.sort();
	   liste_finale_in.unique();
  }; 
	 list <NBelemEtArete >::iterator lf_in_deb=liste_finale_in.begin();
	 list <NBelemEtArete >::iterator lf_in_end=liste_finale_in.end();
   // ---- cas des ref out
	 list <NBelemEtArete > liste_finale_out;
  { // on commence par concaténer l'ensemble des arêtes des refs out
    list <const Reference*>::iterator lref,lref_fin= list_refOut.end();
	   for (lref=list_refOut.begin();lref != lref_fin; lref++)
	    { // on ne continue que si c'est une ref de arête, du même maillage
	      if (((*lref)->Indic() == 4) && ((*lref)->Nbmaille() == idmail))
		      {  ReferenceAF * refi = ((ReferenceAF *) (*lref));
           const Tableau<int>& tab_elem = refi->Tab_Elem();
           const Tableau<int>& tab_fa = refi->Tab_FA();
			        int tailmax = tab_elem.Taille();
			        for (int i=1;i<=tailmax;i++)
			         { NBelemEtArete nu; nu.nbElem = tab_elem(i); nu.nbArete = tab_fa(i);
              liste_finale_out.push_back(nu);
            };
			     };
	    };
    // on trie et on supprime les doublons
    liste_finale_out.sort();
	   liste_finale_out.unique();
	 }; 
	 list <NBelemEtArete >::iterator lf_out_deb=liste_finale_out.begin();
	 list <NBelemEtArete >::iterator lf_out_end=liste_finale_out.end();
		
////--- debug
//
////--- debug
//   cout << "\n Maillage::Exe_In_out_avecRefExistantes_F(..";
//   cout << "\n list in ";
//   list < NBelemEtArete>::iterator lnn;
//	  for (lnn=lf_in_deb;lnn != lf_in_end; lnn++)
//	    cout  << (*lnn).nbElem << " "<< (*lnn).nbArete << " ";
//   cout << "\n list out ";
//	  for (lnn=lf_out_deb;lnn != lf_out_end; lnn++)
//	    cout  << (*lnn).nbElem << " "<< (*lnn).nbArete << " ";
//   cout << "\n list finale avant traitement ";
//	  for (lnn=list_elemArrete_restant.begin();lnn != list_elemArrete_restant.end(); lnn++)
//	    cout  << (*lnn).nbElem << " "<< (*lnn).nbArete << " ";
////--- fin debug


   // ---- application	
  // on passe en revue les arêtes et on regarde s'ils font partie d'une des listes In
	 // et s'ils sont en dehors des out
	 bool liste_finale_in_a_considerer = liste_finale_in.size();
	 bool liste_finale_out_a_considerer = liste_finale_out.size();
  int nb_trouve_in=0; int nb_trouve_out=0;
	 list <NBelemEtArete>::iterator li;
	 // comme on supprime en cours de route des ref de arête on recalcul la borne sup à chaque passage
	 for (li=list_elemArrete_restant.begin();li != list_elemArrete_restant.end();li++)
	  { bool deja_supprime = false; // pour indiquer si un element a déjà ete supprimer, ce qui evite une double
     if (liste_finale_in_a_considerer) // prise en compte que si la liste est non vide
	      if (find(lf_in_deb, lf_in_end, *li) == lf_in_end)
	        // on n'a pas trouvé de arête appartenant à la liste, on supprime le arête
		       {list_elemArrete_restant.erase(li);nb_trouve_in++;deja_supprime=true;}
	    if ((liste_finale_out_a_considerer)&&(!deja_supprime)) // prise en compte que si la liste est non vide
	      if (find(lf_out_deb, lf_out_end, *li) != lf_out_end)
	        // on a  trouvé une arête appartenant à la liste, on supprime le arête
		       {list_elemArrete_restant.erase(li);nb_trouve_out++;}
   };
 
  if (ParaGlob::NiveauImpression() > 4)
    { if (liste_finale_in_a_considerer)
        cout << "\n "<<nb_trouve_in<<" aretes ajoutes a partir  des refs in ";
      if (liste_finale_out_a_considerer)
        cout << "\n "<<nb_trouve_out<<" aretes supprimes a partir des refs out ";
      cout << endl;
    };
////--- debug
//   cout << "\n Maillage::Exe_In_out_avecRefExistantes_F(..";
//   cout << "\n list finale après traitement ";
//	  for (lnn=list_elemArrete_restant.begin();lnn != list_elemArrete_restant.end(); lnn++)
//	    cout  << (*lnn).nbElem << " "<< (*lnn).nbArete << " ";
////--- fin debug
 };

// dans le cas particulier d'une ligne, on peut ordonner certaines listes résultantes / à la lignes
// il s'agit des noeuds et des pt d'integ: on les ordonnes par rapport à leurs projections sur la lignes
void Maillage::InitOrdonneLigne()
	{ int dima = ParaGlob::Dimension();
	  bool fr = ParaGlob::Francais(); // pour simplifier
	  Coordonnee poin1(dima),poin2(dima);
	  if (fr) {cout << "\n -- condition : ordonne noeuds et pt integ par rapport a la projection sur une  ligne ---- "; 
	           cout << "\n la ligne est defini par deux points ";
	           cout << "\n  premier point:  " << endl;
	           // acquisition d'un point
            poin1 = Acquisition_interactive_point();
	           cout << "\n  second point:  " << endl;
				  }
	  else    {cout << "\n -- condition : sorting of the nodes and integ pt relatively to their projections on a line  ---- "; 
	           cout << "\n the line is defined by two points  ";
	           cout << "\n  first point  " << endl;
            // acquisition d'un point
            poin1 = Acquisition_interactive_point();
	           cout << "\n  second point  " << endl;
				  };
   // acquisition d'un point
   poin2 = Acquisition_interactive_point();
	  t_droit.Change_taille(1);
	  t_droit(1).change_donnees(poin1,(poin2-poin1));
	};
void Maillage::OrdonneLigne(list <Noeud *>& list_noeud_restant,list <NBelemEtptInteg>& list_elemPtin_restant
                            ,const Enum_ddl & enu_ddl)
{ // --- cas des noeuds ---
  bool fr = ParaGlob::Francais(); // pour simplifier
  // on crée un tableau des noeuds restants
  if (list_noeud_restant.size() != 0)	  
	 {int nbtn = list_noeud_restant.size();
	  Tableau <Noeud *> tab_n(nbtn);
	  list <Noeud *>::iterator il,ilfin=list_noeud_restant.end();
	  int i=1;
	  for (il = list_noeud_restant.begin();il != ilfin;il++,i++)
	     tab_n(i) = *il;
	  // maintenant on crée une liste de Entier_et_Double qui contient le numéro dans le tableau et la coordonnée
	  // curviligne de la projection 
	  list <Entier_et_Double> list_curvi;
	  // on rempli la liste
	  Droite & dr = t_droit(1); // pour simplifier
	  for (int i=1;i<=nbtn;i++) 
	  	{ Coordonnee M = tab_n(i)->Coord0();
	  	  Coordonnee Mp = dr.Projete(M);
	  	  double xcurv = (Mp-dr.PointDroite()) * dr.VecDroite();
	  	  list_curvi.push_front(Entier_et_Double(i,xcurv));
	  	};
	  // on ordonne la liste
	  list_curvi.sort();
	  // on reconstruit la liste de noeud restant
	  list_noeud_restant.clear();
	  list <Entier_et_Double>::iterator ia,iafin= list_curvi.end();	  
	  for (ia=list_curvi.begin();ia!=iafin;ia++)
	    list_noeud_restant.push_front(tab_n((*ia).n));
	 }; // encapsulation 
	  
	  // --- cas des points d'intégrations ---
  if (list_elemPtin_restant.size() != 0)	   
	 {list <Entier_et_Double> list_curvi; 	
	  // on crée un tableau des ptint
	  int nbptint = list_elemPtin_restant.size();
	  Tableau <NBelemEtptInteg> tab_ptint(nbptint);

	  list <NBelemEtptInteg>::iterator jl,jlfin=list_elemPtin_restant.end();
	  int j=1;
	  for (jl = list_elemPtin_restant.begin();jl != jlfin;jl++,j++)
	     tab_ptint(j) = *jl;
	  // maintenant on crée une liste de Entier_et_Double qui contient le numéro dans le tableau et la coordonnée
	  // curviligne de la projection:  
	  list_curvi.clear();  // en fait on utilise la précédente liste
	  // on rempli la liste
	  Droite & dr = t_droit(1); // pour simplifier
	  for (int i=1;i<=nbptint;i++) 
	  	{ Element& el = *(tab_element(tab_ptint(i).nbElem));
	  	  bool erreur =false;
	  	  Coordonnee M = el.CoordPtInteg(TEMPS_0,enu_ddl,tab_ptint(i).nbPtInteg,erreur);
          if (erreur)
            { int num = tab_ptint(i).nbPtInteg;
              if (fr) {cout << "\n erreur bizarre, on ne peut pas trouver les coordoonees t0 du pt d'integ "
                            << num << "de l'element " << el.Num_elt() << " du maillage " 
                            << el.Num_maillage() << " on arrete d'ordonner les pt d'integ ! ! ";
							 }		 
              else    {cout << "\n strange error, we cannot find the coordinates at t0 of the gauss point "
                            << num << "of the element " << el.Num_elt() << " of the mesh " 
                            << el.Num_maillage() << " we stop the process of sorting the integ pt  ! ! ";
							 }		 
              return;     
            }
	  	  Coordonnee Mp = dr.Projete(M);
	  	  double xcurv = (Mp-dr.PointDroite()) * dr.VecDroite();
	  	  list_curvi.push_front(Entier_et_Double(i,xcurv));
	  	};
	  // on ordonne la liste
	  list_curvi.sort();
	  // on reconstruit la liste des ptinteg restants
	  list_elemPtin_restant.clear();
	  list <Entier_et_Double>::iterator ja,jafin= list_curvi.end();	  
	  for (ja=list_curvi.begin();ja!=jafin;ja++)
	    list_elemPtin_restant.push_front(tab_ptint((*ja).n));
	 }; // encapsulation
	};
        

//- il faut faire la doc en ligne d'herehz++
//- il faut mettre un ordre pour sauvegarder le nouveau maillage
//- mettre un sous-ordre dans l'algo, qui a pour objet de rien faire au niveau algo mettre de faire 
//  l'exécution des choses prévu dans les classes utilisées: ici les maillages	
 
 
 
 
 
 
 
 
