// FICHIER Enum_ddl.cp


// 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 "Enum_ddl.h"
# include "ParaGlob.h"

# include <iostream>
using namespace std;  //introduces namespace std
#include <stdlib.h>
#include "Sortie.h"
//#ifdef SYSTEM_MAC_OS_X
//  #include <stringfwd.h> // a priori ce n'est pas portable
//#el
#if defined  SYSTEM_MAC_OS_CARBON
  #include <stringfwd.h> // a priori ce n'est pas portable
#else  
  #include <string.h> // pour le flot en memoire centrale
#endif
#include <string>


#ifndef  Enum_ddl_deja_inclus

//-------------------------- def des grandeurs statiques ---------------------
// du au jeux d'inline, les grandeurs statiques sont définis dans un fichier à part
//      Enum_ddl_var_static.cc
// 
// il s'agit des variables: map_Enum_ddl, et remplir_map
//-------------------------- fin def des grandeurs statiques ---------------------

  // le constructeur qui rempli effectivement la map
#ifndef MISE_AU_POINT
  inline 
#endif
  ClassPourEnum_ddl::ClassPourEnum_ddl() : 
    il(),ilfin()
  { // remplissage de la map
    map_Enum_ddl["X1"]=X1;
    map_Enum_ddl["X2"]=X2;
    map_Enum_ddl["X3"]=X3;
    map_Enum_ddl["EPAIS"]=EPAIS;
    map_Enum_ddl["TEMP"]=TEMP;
    map_Enum_ddl["UX"]=UX;
    map_Enum_ddl["UY"]=UY;
    map_Enum_ddl["UZ"]=UZ;
    map_Enum_ddl["V1"]=V1;
    map_Enum_ddl["V2"]=V2;
    map_Enum_ddl["V3"]=V3;
    map_Enum_ddl["PR"]=PR;
    map_Enum_ddl["GAMMA1"]=GAMMA1;
    map_Enum_ddl["GAMMA2"]=GAMMA2;
    map_Enum_ddl["GAMMA3"]=GAMMA3;
    map_Enum_ddl["SIG11"]=SIG11;
    map_Enum_ddl["SIG22"]=SIG22;
    map_Enum_ddl["SIG33"]=SIG33;
    map_Enum_ddl["SIG12"]=SIG12;
    map_Enum_ddl["SIG23"]=SIG23;
    map_Enum_ddl["SIG13"]=SIG13;
    map_Enum_ddl["ERREUR"]=ERREUR;
    map_Enum_ddl["EPS11"]=EPS11;
    map_Enum_ddl["EPS22"]=EPS22;
    map_Enum_ddl["EPS33"]=EPS33;
    map_Enum_ddl["EPS12"]=EPS12;
    map_Enum_ddl["EPS23"]=EPS23;
    map_Enum_ddl["EPS13"]=EPS13;
    map_Enum_ddl["DEPS11"]=DEPS11;
    map_Enum_ddl["DEPS22"]=DEPS22;
    map_Enum_ddl["DEPS33"]=DEPS33;
    map_Enum_ddl["DEPS12"]=DEPS12;
    map_Enum_ddl["DEPS23"]=DEPS23;
    map_Enum_ddl["DEPS13"]=DEPS13;
    map_Enum_ddl["PROP_CRISTA"]=PROP_CRISTA;
    map_Enum_ddl["DELTA_TEMP"]=DELTA_TEMP;
    map_Enum_ddl["FLUXD1"]=FLUXD1;
    map_Enum_ddl["FLUXD2"]=FLUXD2;
    map_Enum_ddl["FLUXD3"]=FLUXD3;
    map_Enum_ddl["R_TEMP"]=R_TEMP;
    map_Enum_ddl["GRADT1"]=GRADT1;
    map_Enum_ddl["GRADT2"]=GRADT2;
    map_Enum_ddl["GRADT3"]=GRADT3;
    map_Enum_ddl["DGRADT1"]=DGRADT1;
    map_Enum_ddl["DGRADT2"]=DGRADT2;
    map_Enum_ddl["DGRADT3"]=DGRADT3;
    map_Enum_ddl["R_X1"]=R_X1;
    map_Enum_ddl["R_X2"]=R_X2;
    map_Enum_ddl["R_X3"]=R_X3;
    map_Enum_ddl["R_EPAIS"]=R_EPAIS;
    map_Enum_ddl["R_V1"]=R_V1;
    map_Enum_ddl["R_V2"]=R_V2;
    map_Enum_ddl["R_V3"]=R_V3;
    map_Enum_ddl["R_GAMMA1"]=R_GAMMA1;
    map_Enum_ddl["R_GAMMA2"]=R_GAMMA2;
    map_Enum_ddl["R_GAMMA3"]=R_GAMMA3;
    map_Enum_ddl["NU_DDL"]=NU_DDL;
    // définition des itérators de travail
    ilfin = map_Enum_ddl.end();
  };

#ifndef MISE_AU_POINT
  inline 
#endif
string Nom_ddl (Enum_ddl id_nom)
// Retourne le nom du degre de liberte associe
// a l'identificateur de type enumere id_nom
{
	string result="";
	switch (id_nom)
	{case X1 :    result="X1";break;
		case X2 :    result="X2";break;
		case X3 :    result="X3";break;
		case EPAIS : result="EPAIS";break;
		case TEMP :  result="TEMP";break;
		case UX :    result="UX";break;
		case UY :    result="UY";break;
		case UZ :    result="UZ";break;
		case V1 :    result="V1";break;
		case V2 :    result="V2";break;
		case V3 :    result="V3";break;
		case PR :    result="PR";break;
		case GAMMA1 :result="GAMMA1";break;
		case GAMMA2 :result="GAMMA2";break;
		case GAMMA3 :result="GAMMA3";break;
		case SIG11 : result="SIG11";break;
		case SIG22 : result="SIG22";break;
		case SIG33 : result="SIG33";break;
		case SIG12 : result="SIG12";break;
		case SIG23 : result="SIG23";break;
		case SIG13 : result="SIG13";break;
		case ERREUR :result="ERREUR";break;
		case EPS11 : result="EPS11";break;
		case EPS22 : result="EPS22";break;
		case EPS33 : result="EPS33";break;
		case EPS12 : result="EPS12";break;
		case EPS23 : result="EPS23";break;
		case EPS13 : result="EPS13";break;
		case DEPS11 : result="DEPS11";break;
		case DEPS22 : result="DEPS22";break;
		case DEPS33 : result="DEPS33";break;
		case DEPS12 : result="DEPS12";break;
		case DEPS23 : result="DEPS23";break;
		case DEPS13 : result="DEPS13";break;
		case PROP_CRISTA : result="PROP_CRISTA";break;
		case DELTA_TEMP : result="DELTA_TEMP";break;
		case FLUXD1 : result="FLUXD1";break;
		case FLUXD2 : result="FLUXD2";break;
		case FLUXD3 : result="FLUXD3";break;
		case R_TEMP : result="R_TEMP";break;
		case GRADT1 : result="GRADT1";break;
		case GRADT2 : result="GRADT2";break;
		case GRADT3 : result="GRADT3";break;
		case DGRADT1 : result="DGRADT1";break;
		case DGRADT2 : result="DGRADT2";break;
		case DGRADT3 : result="DGRADT3";break;
		case R_X1 : result="R_X1";break;
		case R_X2 : result="R_X2";break;
		case R_X3 : result="R_X3";break;
		case R_EPAIS : result="R_EPAIS";break;
		case R_V1 : result="R_V1";break;
		case R_V2 : result="R_V2";break;
		case R_V3 : result="R_V3";break;
		case R_GAMMA1 : result="R_GAMMA1";break;
		case R_GAMMA2 : result="R_GAMMA2";break;
		case R_GAMMA3 : result="R_GAMMA3";break;
		case NU_DDL :result="NU_DDL";break;
		default :
		   {cout << "\nErreur : valeur incorrecte du type Enum_ddl !\n";
			   cout << "NOM_DDL(Enum_ddl ) \n";
			   Sortie(1);
     }
 };
	return result;
	
};

/*#ifndef MISE_AU_POINT
  inline 
#endif
Enum_ddl  Id_nom_ddl (const char* nom)
// Retourne la variable de type enumere associee au nom du degre
// de liberte nom
// Retourne la variable de type enumere associe au nom nom_TypeQuelconque
{	// on vérifie si la variable de type enumere existe
	map < string, Enum_ddl , std::less < string> >& maa=ClassPourEnum_ddl::map_Enum_ddl;
    ClassPourEnum_ddl::remplir_map.il = maa.find(nom);
    if (ClassPourEnum_ddl::remplir_map.il == ClassPourEnum_ddl::remplir_map.ilfin)
	   {// on vérifie si la variable de type enumere existe
		cout << "\nErreur : nom du degre de liberte inconnu ! ("
		     << nom << ") \n";
		cout << "ID_NOM_DDL(char* ) \n";
		Sortie(1);
	   };
	 // retour de la grandeur 
	 return (*(ClassPourEnum_ddl::remplir_map.il)).second;  
};
*/

#ifndef MISE_AU_POINT
  inline 
#endif
Enum_ddl  Id_nom_ddl (const string& nom)
// Retourne la variable de type enumere associee au nom du degre
// de liberte nom
// Retourne la variable de type enumere associe au nom nom_TypeQuelconque
{	// on vérifie si la variable de type enumere existe
	 map < string, Enum_ddl , std::less < string> >& maa=ClassPourEnum_ddl::map_Enum_ddl;
  ClassPourEnum_ddl::remplir_map.il = maa.find(nom);
  if (ClassPourEnum_ddl::remplir_map.il == ClassPourEnum_ddl::remplir_map.ilfin)
	   {// on vérifie si la variable de type enumere existe
		   cout << "\nErreur : nom du degre de liberte inconnu ! ("
		        << nom << ") \n";
     cout << "ID_NOM_DDL(const string& ) \n";
		   Sortie(1);
	   };
	 // retour de la grandeur 
	 return (*(ClassPourEnum_ddl::remplir_map.il)).second;  
};

/*// retourne true si l'identificateur existe, false sinon
#ifndef MISE_AU_POINT
  inline 
#endif
bool ExisteEnum_ddl(const char* nom)
  {	
   return ( ClassPourEnum_ddl::map_Enum_ddl.find(nom) 
            != ClassPourEnum_ddl::remplir_map.ilfin);
	
};
*/	
// retourne true si l'identificateur existe, false sinon (cas d'un string)
#ifndef MISE_AU_POINT
  inline 
#endif
bool ExisteEnum_ddl(const string& nom)
  {return ( ClassPourEnum_ddl::map_Enum_ddl.find(nom) 
            != ClassPourEnum_ddl::remplir_map.ilfin);
  };
            
// ramene true si le ddl fait parti d'une liste
// fonction de la dimension du pb: par exemple : X1 ou UY ou VZ
// dans le cas contraire , exemple: T ou EPAIS ramene false
#ifndef MISE_AU_POINT
  inline 
#endif
bool FoncDim(const string& nom)
  {	// on récupère tout d'abord l'énuméré
    Enum_ddl enu = Id_nom_ddl(nom);
    return FoncDim(enu);
  };



// ramene true si le ddl fait parti d'une liste
// fonction de la dimension du pb: par exemple : X1 ou UY ou VZ
// dans le cas contraire , exemple: T ou EPAIS ramene false
// mais ici avec l'énumération
#ifndef MISE_AU_POINT
  inline 
#endif
bool FoncDim(Enum_ddl id_ddl)
  {	bool res;
    switch (id_ddl)
     {  case  X1 : res=true;break;
        case  X2 :res=true;break;
        case  X3 :res=true;break;
        case  EPAIS :res=false;break;
        case  TEMP :res=false;break;
        case  UX :res=true;break;
        case  UY :res=true;break;
        case  UZ :res=true;break;
        case  V1 :res=true;break;
        case  V2 :res=true;break;
        case  V3 :res=true;break;
        case  PR :res=false;break;
        case  GAMMA1 :res=true;break;
        case  GAMMA2 :res=true;break;
        case  GAMMA3 :res=true;break;
        case  SIG11 :res=true;break;
        case  SIG22 :res=true;break;
        case  SIG33 :res=true;break;
        case  SIG12 :res=true;break;
        case  SIG23 :res=true;break;
        case  SIG13 :res=true;break;
        case  ERREUR :res=false;break;
        case  EPS11 :res=true;break;
        case  EPS22 :res=true;break;
        case  EPS33 :res=true;break;
        case  EPS12 :res=true;break;
        case  EPS23 :res=true;break;
        case  EPS13 :res=true;break;
        case  DEPS11 :res=true;break;
        case  DEPS22 :res=true;break;
        case  DEPS33 :res=true;break;
        case  DEPS12 :res=true;break;
        case  DEPS23 :res=true;break;
        case  DEPS13 :res=true;break;
        case  PROP_CRISTA :res=false;break;
        case  DELTA_TEMP :res=false;break;
        case  FLUXD1 :res=true;break;
        case  FLUXD2 :res=true;break;
        case  FLUXD3 :res=true;break;
        case  R_TEMP :res=false;break;
        case  GRADT1 :res=true;break;
        case  GRADT2 :res=true;break;
        case  GRADT3 :res=true;break;
        case  DGRADT1 :res=true;break;
        case  DGRADT2 :res=true;break;
        case  DGRADT3 :res=true;break;
        case  R_X1: res=true;break;
        case  R_X2: res=true;break;
        case  R_X3: res=true;break;
        case  R_EPAIS: res=false;break;
        case  R_V1: res=true;break;
        case  R_V2: res=true;break;
        case  R_V3: res=true;break;
        case  R_GAMMA1: res=true;break;
        case  R_GAMMA2: res=true;break;
        case  R_GAMMA3: res=true;break;
        case  NU_DDL :res=false;break;
        default :
          { cout << "\nErreur : valeur incorrecte du type Enum_ddl: "
			              << Nom_ddl(id_ddl) << " !\n";
            cout << "FoncDim(Enum_ddl id_ddl)\n";
            Sortie(1);}
     };
	   return res;
  };

// ramene le tableau de tous les ddl correspondant au type du  ddl passé en paramètre
// ceci en fonction de la dimension (par exemple pour un COORDONNEE, ramène
// les dim ddl correspondant aux composantes 
#ifndef MISE_AU_POINT
  inline 
#endif
Tableau<Enum_ddl> TableauTypeDdl(Enum_ddl id_ddl)
  { // récup du premier ddl de la famille
    Enum_ddl premddl = PremierDdlFamille(id_ddl);
    // récup de la dimension
    int dim = ParaGlob::Dimension();
    // fabrication du tableau
    Tableau<Enum_ddl> ta(1);
    switch (dim)
     { case 1: // dans tous les cas il n'y a qu'une seule grandeur
        {ta(1)=premddl; break;}
       case 2:
        {int taille=NombreElementFoncDim(TypeGrandeur(premddl));
         ta.Change_taille(taille);  int  posi = premddl -1;
         if ((premddl == SIG11)||(premddl==EPS11)||(premddl==DEPS11))
           // cas particulier des tenseurs
           {ta(1)=Enum_ddl(1+posi);ta(2)=Enum_ddl(2+posi);
            ta(3)=Enum_ddl(4+posi);
           }
         else  // cas ou ça se suit
           for (int i=1;i<=taille;i++) ta(i)=Enum_ddl(i+posi);
         break;
        }
       case 3:// on crée le tableau en fonction du type de grandeur
        {int taille=NombreElementFoncDim(TypeGrandeur(premddl));
         ta.Change_taille(taille);  int  posi = premddl -1;
         for (int i=1;i<=taille;i++) ta(i)=Enum_ddl(i+posi);
         break;
        }
      };
   return ta;   
};

// ramene le tableau des ddl mobile correspondant au type du  ddl passé en paramètre
// ceci en fonction de la dimension (par exemple pour un COORDONNEE, ramène
// les dim ddl correspondant aux composantes
// par rapport à TableauTypeDdl() la différence concerne le cas axi
// pour ce cas: X3=constant, U3=V3=Gamma3=0 ==> donc ne font pas partie du tableau retour
#ifndef MISE_AU_POINT
  inline 
#endif
Tableau<Enum_ddl> TableauTypeDdlmobileAvecAxi(Enum_ddl id_ddl)
  { // récup du premier ddl de la famille
    Enum_ddl premddl = PremierDdlFamille(id_ddl);
    // récup de la dimension
    int dim = ParaGlob::Dimension();
    // fabrication du tableau
    Tableau<Enum_ddl> ta(1);
    switch (dim)
     { case 1: // dans tous les cas il n'y a qu'une seule grandeur
        {ta(1)=premddl; break;}
       case 2:
        {int taille=NombreElementFoncDim(TypeGrandeur(premddl));
         ta.Change_taille(taille);  int  posi = premddl -1;
         if ((premddl == SIG11)||(premddl==EPS11)||(premddl==DEPS11))
           // cas particulier des tenseurs
           {ta(1)=Enum_ddl(1+posi);ta(2)=Enum_ddl(2+posi);
            ta(3)=Enum_ddl(4+posi);
           }
         else  // cas ou ça se suit
           for (int i=1;i<=taille;i++) ta(i)=Enum_ddl(i+posi);
         break;
        }
       case 3:// on crée le tableau en fonction du type de grandeur
        {EnumTypeGrandeur enutype = TypeGrandeur(premddl);
         int taille = 0; // init
         if ((enutype == COORDONNEE) && (ParaGlob::AxiSymetrie()))
          // dans ce cas on ne garde que 2 composante
          {taille = 2;}
         else // sinon
          { taille=NombreElementFoncDim(enutype);};
         ta.Change_taille(taille);  int  posi = premddl -1;
         for (int i=1;i<=taille;i++) ta(i)=Enum_ddl(i+posi);
         break;
        }
      };
   return ta;   
};


// indique si le ddl est compatible avec la dimension
#ifndef MISE_AU_POINT
  inline 
#endif
bool CompatDim(const string& nom)
  {	bool res;
    int dim = ParaGlob::Dimension();
    res = true; // bon a priori, par exemple pour temp, epais, p etc..
    switch (dim)
     { case 3: res = true; break;
       case 2:
        {// on récupère tout d'abord l'énuméré
         Enum_ddl enu = Id_nom_ddl(nom);
         switch (enu)
          {case X3: res=false;break;
           case UZ: res=false;break;
           case V3: res=false;break;
           case GAMMA3: res=false;break;
           case SIG33: res=false;break;
           case SIG23: res=false;break;
           case SIG13: res=false;break;
           case EPS33: res=false;break;
           case EPS23: res=false;break;
           case EPS13: res=false;break;
           case DEPS33: res=false;break;
           case DEPS23: res=false;break;
           case DEPS13: res=false;break;
           case R_X3: res=false;break;
           case R_EPAIS: res=true;break;
           case R_V3: res=false;break;
           case R_GAMMA3: res=false;break;
           case FLUXD3 :res=false;break;
           case GRADT3 :res=false;break;
           case DGRADT3 :res=false;break;
           default: res=true; break;
          };
         break;
        }
       case 1:
        {// on récupère tout d'abord l'énuméré
         Enum_ddl enu = Id_nom_ddl(nom);
         switch (enu)
         {case  X2 :res=false;break;
          case  X3 :res=false;break;
          case  UY :res=false;break;
          case  UZ :res=false;break;
          case  V2 :res=false;break;
          case  V3 :res=false;break;
          case  GAMMA2 :res=false;break;
          case  GAMMA3 :res=false;break;
          case  SIG22 :res=false;break;
          case  SIG33 :res=false;break;
          case  SIG12 :res=false;break;
          case  SIG23 :res=false;break;
          case  SIG13 :res=false;break;
          case  EPS22 :res=false;break;
          case  EPS33 :res=false;break;
          case  EPS12 :res=false;break;
          case  EPS23 :res=false;break;
          case  EPS13 :res=false;break;
          case  DEPS22 :res=false;break;
          case  DEPS33 :res=false;break;
          case  DEPS12 :res=false;break;
          case  DEPS23 :res=false;break;
          case  DEPS13 :res=false;break;
          case  R_X2: res=false;break;
          case  R_X3: res=false;break;
          case  R_EPAIS: res=true;break;
          case  R_V2: res=false;break;
          case  R_V3: res=false;break;
          case  R_GAMMA2: res=false;break;
          case  R_GAMMA3: res=false;break;
          case  FLUXD2 :res=false;break;
          case  FLUXD3 :res=false;break;
          case  GRADT2 :res=false;break;
          case  GRADT3 :res=false;break;
          case  DGRADT2 :res=false;break;
          case  DGRADT3 :res=false;break;
          default: res=true; break;
         };
	        break;
	       }
 	   }; // fin du switch sur la dimension
	   return res;
  };

// indique si le ddl est compatible avec la dimension
#ifndef MISE_AU_POINT
  inline 
#endif
bool CompatDim(const Enum_ddl id_ddl)
  {	bool res;
    int dim = ParaGlob::Dimension();
    res = true; // bon a priori, par exemple pour temp, epais, p etc..
    switch (dim)
     { case 3: res = true; break;
       case 2:
        {// on récupère tout d'abord l'énuméré
         switch (id_ddl)
          {case X3: res=false;break;
           case UZ: res=false;break;
           case V3: res=false;break;
           case GAMMA3: res=false;break;
           case SIG33: res=false;break;
           case SIG23: res=false;break;
           case SIG13: res=false;break;
           case EPS33: res=false;break;
           case EPS23: res=false;break;
           case EPS13: res=false;break;
           case DEPS33: res=false;break;
           case DEPS23: res=false;break;
           case DEPS13: res=false;break;
           case R_X3: res=false;break;
           case R_EPAIS: res=true;break;
           case R_V3: res=false;break;
           case R_GAMMA3: res=false;break;
           case FLUXD3 :res=false;break;
           case GRADT3 :res=false;break;
           case DGRADT3 :res=false;break;
           default: res=true; break;
          };
         break;
        }  
       case 1:
        {// on récupère tout d'abord l'énuméré
         switch (id_ddl)
         {case  X2 :res=false;break;
          case  X3 :res=false;break;
          case  UY :res=false;break;
          case  UZ :res=false;break;
          case  V2 :res=false;break;
          case  V3 :res=false;break;
          case  GAMMA2 :res=false;break;
          case  GAMMA3 :res=false;break;
          case  SIG22 :res=false;break;
          case  SIG33 :res=false;break;
          case  SIG12 :res=false;break;
          case  SIG23 :res=false;break;
          case  SIG13 :res=false;break;
          case  EPS22 :res=false;break;
          case  EPS33 :res=false;break;
          case  EPS12 :res=false;break;
          case  EPS23 :res=false;break;
          case  EPS13 :res=false;break;
          case  DEPS22 :res=false;break;
          case  DEPS33 :res=false;break;
          case  DEPS12 :res=false;break;
          case  DEPS23 :res=false;break;
          case  DEPS13 :res=false;break;
          case  R_X2: res=false;break;
          case  R_X3: res=false;break;
          case  R_EPAIS: res=true;break;
          case  R_V2: res=false;break;
          case  R_V3: res=false;break;
          case  R_GAMMA2: res=false;break;
          case  R_GAMMA3: res=false;break;
          case  FLUXD2 :res=false;break;
          case  FLUXD3 :res=false;break;
          case  GRADT2 :res=false;break;
          case  GRADT3 :res=false;break;
          case  DGRADT2 :res=false;break;
          case  DGRADT3 :res=false;break;
          default: res=true; break;
	        };
	        break;
	       }
 	  }; // fin du switch sur la dimension
   return res;
  };


// retour le type de grandeur auquel apartient l'énumération
// par exemple : UY : apartiend à un COORDONNEE
// SIG12 : à un tenseur, TEMP : à un scalaire
#ifndef MISE_AU_POINT
  inline 
#endif
EnumTypeGrandeur TypeGrandeur(Enum_ddl id_nom)
{	EnumTypeGrandeur res;
	 switch (id_nom)
     {  case  X1 : res=COORDONNEE;break;
        case  X2 :res=COORDONNEE;break;
        case  X3 :res=COORDONNEE;break;
        case  EPAIS :res=SCALAIRE;break;
        case  TEMP :res=SCALAIRE;break;
        case  UX :res=COORDONNEE;break;
        case  UY :res=COORDONNEE;break;
        case  UZ :res=COORDONNEE;break;
        case  V1 :res=COORDONNEE;break;
        case  V2 :res=COORDONNEE;break;
        case  V3 :res=COORDONNEE;break;
        case  PR :res=SCALAIRE;break;
        case  GAMMA1 :res=COORDONNEE;break;
        case  GAMMA2 :res=COORDONNEE;break;
        case  GAMMA3 :res=COORDONNEE;break;
        case  SIG11 :res=TENSEUR;break;
        case  SIG22 :res=TENSEUR;break;
        case  SIG33 :res=TENSEUR;break;
        case  SIG12 :res=TENSEUR;break;
        case  SIG23 :res=TENSEUR;break;
        case  SIG13 :res=TENSEUR;break;
        case  ERREUR :res=SCALAIRE;break;
        case  EPS11 :res=TENSEUR;break;
        case  EPS22 :res=TENSEUR;break;
        case  EPS33 :res=TENSEUR;break;
        case  EPS12 :res=TENSEUR;break;
        case  EPS23 :res=TENSEUR;break;
        case  EPS13 :res=TENSEUR;break;
        case  DEPS11 :res=TENSEUR;break;
        case  DEPS22 :res=TENSEUR;break;
        case  DEPS33 :res=TENSEUR;break;
        case  DEPS12 :res=TENSEUR;break;
        case  DEPS23 :res=TENSEUR;break;
        case  DEPS13 :res=TENSEUR;break;
        case  PROP_CRISTA :res=SCALAIRE;break;
        case  DELTA_TEMP :res=SCALAIRE;break;
        case  FLUXD1 :res=COORDONNEE;break;
        case  FLUXD2 :res=COORDONNEE;break;
        case  FLUXD3 :res=COORDONNEE;break;
        case  R_TEMP :res=SCALAIRE;break;
        case  GRADT1 :res=COORDONNEE;break;
        case  GRADT2 :res=COORDONNEE;break;
        case  GRADT3 :res=COORDONNEE;break;
        case  DGRADT1 :res=COORDONNEE;break;
        case  DGRADT2 :res=COORDONNEE;break;
        case  DGRADT3 :res=COORDONNEE;break;
        case  R_X1 :res=COORDONNEE;break;
        case  R_X2 :res=COORDONNEE;break;
        case  R_X3 :res=COORDONNEE;break;
        case  R_EPAIS :res=SCALAIRE;break;
        case  R_V1 :res=COORDONNEE;break;
        case  R_V2 :res=COORDONNEE;break;
        case  R_V3 :res=COORDONNEE;break;
        case  R_GAMMA1 :res=COORDONNEE;break;
        case  R_GAMMA2 :res=COORDONNEE;break;
        case  R_GAMMA3 :res=COORDONNEE;break;
        case  NU_DDL :res=RIEN_TYPEGRANDEUR;break;
        default :
         {cout << "\nErreur : valeur incorrecte du type Enum_ddl: "
               << Nom_ddl(id_nom) << " !\n";
			       cout << "TypeGrandeur(Enum_ddl id_ddl) \n";
			       Sortie(1);}
     };
	 return res;
};	


// test si les deux ddl sont de la même famille dimensionnelle, par exemple X1 et X3, ou SIG11 et SIG22
// ramène true si oui, false sinon
#ifndef MISE_AU_POINT
  inline 
#endif
bool Meme_famille(Enum_ddl a,Enum_ddl b)
 { if (a==b) return true; // cas de la même valeur
   // on regarde les formes numériques
       // cas des Xi
   if ( ((a==X1)||(a==X2)||(a==X3))
      &&((b==X1)||(b==X2)||(b==X3)))
        return true; 
       // cas des Ui
   if ( ((a==UX)||(a==UY)||(a==UZ))
      &&((b==UX)||(b==UY)||(b==UZ)))
        return true; 
       // cas des Vi
   if ( ((a==V1)||(a==V2)||(a==V3))
      &&((b==V1)||(b==V2)||(b==V3)))
        return true; 
       // cas des GAMMAI
   if ( ((a==GAMMA1)||(a==GAMMA2)||(a==GAMMA3))
      &&((b==GAMMA1)||(b==GAMMA2)||(b==GAMMA3)))
        return true; 
       // cas des sigmai
   if ( (a>= SIG11) && (a<= SIG13)
      && (b>= SIG11) && (b<= SIG13))
        return true; 
       // cas des epsiloni
   if ( (a>= EPS11) && (a<= EPS13)
      && (b>= EPS11) && (b<= EPS13))
        return true;
       // cas des depsiloni
   if ( (a>= DEPS11) && (a<= DEPS13)
      && (b>= DEPS11) && (b<= DEPS13))
        return true; 
        // cas des températures
   if ( ((a == TEMP) || (a == DELTA_TEMP))
         && ((b == TEMP) || (b == DELTA_TEMP)))
        return true;
       // cas des densités de flux thermique
   if ( ((a==FLUXD1)||(a==FLUXD2)||(a==FLUXD3))
      &&((b==FLUXD1)||(b==FLUXD2)||(b==FLUXD3)))
        return true;
       // cas des réactions à la température
   if ( (a==R_TEMP) && (b==R_TEMP) )
        return true; 
       // cas des gradients thermiques
   if ( ((a==GRADT1)||(a==GRADT2)||(a==GRADT3))
      &&((b==GRADT1)||(b==GRADT2)||(b==GRADT3)))
        return true;
       // cas des vitesses de gradient thermique
   if ( ((a==DGRADT1)||(a==DGRADT2)||(a==DGRADT3))
      &&((b==DGRADT1)||(b==DGRADT2)||(b==DGRADT3)))
        return true;

       // cas des réaction sur les Xi
   if ( ((a==R_X1)||(a==R_X2)||(a==R_X3))
      &&((b==R_X1)||(b==R_X2)||(b==R_X3)))
        return true; 
       // cas des réaction sur les Vi
   if ( ((a==R_V1)||(a==R_V2)||(a==R_V3))
      &&((b==R_V1)||(b==R_V2)||(b==R_V3)))
        return true; 
       // cas des réaction sur les GAMMAI
   if ( ((a==R_GAMMA1)||(a==R_GAMMA2)||(a==R_GAMMA3))
      &&((b==R_GAMMA1)||(b==R_GAMMA2)||(b==R_GAMMA3)))
        return true; 
       // cas des réaction sur  EPAIS
   if ( (a==R_EPAIS) && (b==R_EPAIS) )
        return true; 
   // sinon non de la même famille      
   return false;       
  };


// ramène le premier ddl de la même famille
#ifndef MISE_AU_POINT
  inline 
#endif
Enum_ddl PremierDdlFamille(Enum_ddl a)
 {  switch (a)
     {	case X1 : return(X1); break;
       case X2 : return(X1); break;
       case X3 : return(X1); break;
       case EPAIS : return(EPAIS); break;
       case TEMP : return(TEMP); break;
       case UX : return(UX); break;
       case UY : return(UX); break;
       case UZ : return(UX); break;
       case V1 : return(V1); break;
       case V2 : return(V1); break;
       case V3 : return(V1); break;
       case PR : return(PR); break;
       case GAMMA1 : return(GAMMA1); break;
       case GAMMA2 : return(GAMMA1); break;
       case GAMMA3 : return(GAMMA1); break;
       case SIG11 : return(SIG11); break;
       case SIG22 : return(SIG11); break;
       case SIG33 : return(SIG11); break;
       case SIG12 : return(SIG11); break;
       case SIG23 : return(SIG11); break;
       case SIG13 : return(SIG11); break;
       case ERREUR : return(ERREUR); break;
       case EPS11 : return(EPS11); break;
       case EPS22 : return(EPS11); break;
       case EPS33 : return(EPS11); break;
       case EPS12 : return(EPS11); break;
       case EPS23 : return(EPS11); break;
       case EPS13 : return(EPS11); break;
       case DEPS11 : return(DEPS11); break;
       case DEPS22 : return(DEPS11); break;
       case DEPS33 : return(DEPS11); break;
       case DEPS12 : return(DEPS11); break;
       case DEPS23 : return(DEPS11); break;
       case DEPS13 : return(DEPS11); break;
       case PROP_CRISTA : return(PROP_CRISTA); break;
       case DELTA_TEMP : return(DELTA_TEMP); break;
       case FLUXD1 : return(FLUXD1); break;
       case FLUXD2 : return(FLUXD1); break;
       case FLUXD3 : return(FLUXD1); break;
       case R_TEMP : return(R_TEMP); break;
       case GRADT1 : return(GRADT1); break;
       case GRADT2 : return(GRADT1); break;
       case GRADT3 : return(GRADT1); break;
       case DGRADT1 : return(DGRADT1); break;
       case DGRADT2 : return(DGRADT1); break;
       case DGRADT3 : return(DGRADT1); break;
       case R_X1 : return(R_X1); break;
       case R_X2 : return(R_X1); break;
       case R_X3 : return(R_X1); break;
       case R_EPAIS : return(R_EPAIS); break;
       case R_V1 : return(R_V1); break;
       case R_V2 : return(R_V1); break;
       case R_V3 : return(R_V1); break;
       case R_GAMMA1 : return(R_GAMMA1); break;
       case R_GAMMA2 : return(R_GAMMA1); break;
       case R_GAMMA3 : return(R_GAMMA1); break;
       case NU_DDL : return(NU_DDL); break;
       default :
         {cout << "\nErreur : valeur incorrecte du type Enum_ddl: "
               << a;
          cout << "\nEnum_ddl PremierDdlFamille(Enum_ddl a)\n";
          Sortie(1);
         }
     };
    Sortie(1); // cas qui n'arrive jamais, c'est pour faire taire le compilo
    return NU_DDL; //
 };

// ramène un nom générique pour la famille de ddl du même type
#ifndef MISE_AU_POINT
  inline 
#endif
string  NomGeneric(Enum_ddl a)
 {  string result="";
    switch (a)
     {case X1 : result="Xi"; break;
      case X2 : result="Xi"; break;
      case X3 : result="Xi"; break;
      case EPAIS : result="EPAIS"; break;
      case TEMP : result="TEMP"; break;
      case UX : result="Ui"; break;
      case UY : result="Ui"; break;
      case UZ : result="Ui"; break;
      case V1 : result="Vi"; break;
      case V2 : result="Vi"; break;
      case V3 : result="Vi"; break;
      case PR : result="PR"; break;
      case GAMMA1 : result="GAMMAi"; break;
      case GAMMA2 : result="GAMMAi"; break;
      case GAMMA3 : result="GAMMAi"; break;
      case SIG11 : result="Sigmaij"; break;
      case SIG22 : result="Sigmaij"; break;
      case SIG33 : result="Sigmaij"; break;
      case SIG12 : result="Sigmaij"; break;
      case SIG23 : result="Sigmaij"; break;
      case SIG13 : result="Sigmaij"; break;
      case ERREUR : result="ERREUR"; break;
      case EPS11 : result="Epsilonij"; break;
      case EPS22 : result="Epsilonij"; break;
      case EPS33 : result="Epsilonij"; break;
      case EPS12 : result="Epsilonij"; break;
      case EPS23 : result="Epsilonij"; break;
      case EPS13 : result="Epsilonij"; break;
      case DEPS11 : result="Dij"; break;
      case DEPS22 : result="Dij"; break;
      case DEPS33 : result="Dij"; break;
      case DEPS12 : result="Dij"; break;
      case DEPS23 : result="Dij"; break;
      case DEPS13 : result="Dij"; break;
      case PROP_CRISTA : result="PROP_CRISTA"; break;
      case DELTA_TEMP : result="DELTA_TEMP"; break;
      case FLUXD1 : result="FLUXD"; break;
      case FLUXD2 : result="FLUXD"; break;
      case FLUXD3 : result="FLUXD"; break;
      case R_TEMP : result="R_TEMP"; break;
      case GRADT1 : result="GRADT"; break;
      case GRADT2 : result="GRADT"; break;
      case GRADT3 : result="GRADT"; break;
      case DGRADT1 : result="DGRADT"; break;
      case DGRADT2 : result="DGRADT"; break;
      case DGRADT3 : result="DGRADT"; break;
      case R_X1 : result="R_Xi"; break;
      case R_X2 : result="R_Xi"; break;
      case R_X3 : result="R_Xi"; break;
      case R_EPAIS : result="R_EPAIS"; break;
      case R_V1 : result="R_Vi"; break;
      case R_V2 : result="R_Vi"; break;
      case R_V3 : result="R_Vi"; break;
      case R_GAMMA1 : result="R_GAMMAi"; break;
      case R_GAMMA2 : result="R_GAMMAi"; break;
      case R_GAMMA3 : result="R_GAMMAi"; break;
      case NU_DDL : result="NU_DDL"; break;
      default :
         {cout << "\nErreur : valeur incorrecte du type Enum_ddl: "
               << a;
          cout << "\nEnum_ddl NomGeneric(Enum_ddl a)\n";
          Sortie(1);
         }
     };
    return result; //
 };
 

// test si le ddl appartient à la combinaison donné par cas
// cas : spécifie la combinaison : =1 -> combinaison X V GAMMA
#ifndef MISE_AU_POINT
  inline 
#endif
bool Dans_combinaison(int cas,Enum_ddl enu)
  {bool retour; 
   switch (cas)
	   { case 0 : retour = false; break;
		    case 1 : // cas de l'association X V GAMMA
       { Enum_ddl a = PremierDdlFamille(enu);
         if ((a==X1)||(a==V1)||(a==GAMMA1))
           retour = true; else retour = false;
         break;
       }
      default :
         {cout << "\nErreur : cas de combinaison non encore implanté, cas= " 
               << cas
               << "\n Dans_combinaison(int cas,Enum_ddl a) \n";
          Sortie(1);
         }
	   };
	  return retour;
  };

// récupération d'un enum de grandeurs quelconques équivalentes
// -> retour particulier si il y a une équivalence particulière en grandeur évoluée par exemple
// sinon, un retour sur un scalaire de type enum_évolué, qui contient de toute manière
// les ddl de base
// -> ramène UN_DDL_ENUM_ETENDUE s'il n'y a pas d'équivalent spécifique
#ifndef MISE_AU_POINT
  inline
#endif
EnumTypeQuelconque Equi_Enum_ddl_en_enu_quelconque(Enum_ddl a)
 {  EnumTypeQuelconque result;
    switch (a)
     {case X1 : case X2 : case X3 : result=POSITION_GEOMETRIQUE; break;
      case EPAIS : result=UN_DDL_ENUM_ETENDUE; break;
      case TEMP : result=UN_DDL_ENUM_ETENDUE; break;
      case UX : case UY : case UZ : result=DEPLACEMENT; break;
      case V1 : case V2 : case V3 : result=VITESSE; break;
      case PR : result=UN_DDL_ENUM_ETENDUE; break;
      case GAMMA1 : result=UN_DDL_ENUM_ETENDUE; break;
      case GAMMA2 : result=UN_DDL_ENUM_ETENDUE; break;
      case GAMMA3 : result=UN_DDL_ENUM_ETENDUE; break;
      case SIG11 :  case SIG22 : case SIG33 : case SIG12 :
      case SIG23 : case SIG13 : result=CONTRAINTE_COURANTE; break;
      case ERREUR : result=UN_DDL_ENUM_ETENDUE; break;
      case EPS11 : case EPS22 : case EPS33 : case EPS12 :
      case EPS23 : case EPS13 : result=DEFORMATION_COURANTE; break;
      case DEPS11 : case DEPS22 : case DEPS33 : case DEPS12 :
      case DEPS23 : case DEPS13 : result=VITESSE_DEFORMATION_COURANTE; break;
      case PROP_CRISTA : result=UN_DDL_ENUM_ETENDUE; break;
      case DELTA_TEMP : result=UN_DDL_ENUM_ETENDUE; break;
      case FLUXD1 : case FLUXD2 : case FLUXD3 : result=FLUXD; break;
      case R_TEMP : result=UN_DDL_ENUM_ETENDUE; break;
      case GRADT1 : case GRADT2 : case GRADT3 : result=GRADT; break;
      case DGRADT1 : case DGRADT2 : case DGRADT3 : result=DGRADT; break;
      case R_X1 : result=UN_DDL_ENUM_ETENDUE; break;
      case R_X2 : result=UN_DDL_ENUM_ETENDUE; break;
      case R_X3 : result=UN_DDL_ENUM_ETENDUE; break;
      case R_EPAIS : result=UN_DDL_ENUM_ETENDUE; break;
      case R_V1 : result=UN_DDL_ENUM_ETENDUE; break;
      case R_V2 : result=UN_DDL_ENUM_ETENDUE; break;
      case R_V3 : result=UN_DDL_ENUM_ETENDUE; break;
      case R_GAMMA1 : result=UN_DDL_ENUM_ETENDUE; break;
      case R_GAMMA2 : result=UN_DDL_ENUM_ETENDUE; break;
      case R_GAMMA3 : result=UN_DDL_ENUM_ETENDUE; break;
      case NU_DDL : result=UN_DDL_ENUM_ETENDUE; break;
      default :
         {cout << "\nErreur : valeur incorrecte du type Enum_ddl: "
               << a;
          cout << "\nEnum_ddl NomGeneric(Enum_ddl a)\n";
          Sortie(1);
         }
     };
    return result; //
};







// ramène  tous les membres d'une même combinaison de la même dimension
// y compris "a"
// cas : spécifie la combinaison :
//   =0 -> pas de combinaison, ramène "a"
//   =1 -> combinaison X V GAMMA
#ifndef MISE_AU_POINT
  inline 
#endif
Tableau <Enum_ddl> MemeCombinaison(int cas,Enum_ddl a)
  { Tableau <Enum_ddl> t_ret;
    switch (cas)
      { case 0 : // cas pas d'association
         {  t_ret.Change_taille(1); // dimmensionnement du tableau de retour
            t_ret(1)=a;
            break;
         }
        case 1 : // cas de l'association X V GAMMA
         {  t_ret.Change_taille(3); // dimmensionnement du tableau de retour
            Enum_ddl b = PremierDdlFamille(a);
            #ifdef MISE_AU_POINT
             if ( (X1 != b) && (V1 != b) && (GAMMA1 != b))
                // erreur
                {cout << "\nErreur : ddl ne faisant pas partie de la combinaison 1, "
                      <<  Nom_ddl(a) 
                      << "\n Tableau <Enum_ddl> MemeCombinaison(int cas,Enum_ddl a) \n";
                 Sortie(1);
                };
            #endif
            t_ret(1) = Enum_ddl(X1 + (a-b));
            t_ret(2) = Enum_ddl(V1 + (a-b));
            t_ret(3) = Enum_ddl(GAMMA1 + (a-b));
            break;
         }
        default :
         {cout << "\nErreur : cas de combinaison non encore implanté, cas= "
               << cas
               << "\n Tableau <Enum_ddl> MemeCombinaison(int cas,Enum_ddl a) \n";
          Sortie(1);
         }
      };
    return t_ret;
  };


#ifndef MISE_AU_POINT
  inline 
#endif
// ramène tous les membres d'une même combinaison, pour i=1 à dim
Tableau <Enum_ddl> Combinaison(int cas)
  { Tableau <Enum_ddl> t_ret;
	   switch (cas)
	    {case 0 : // cas pas d'association
       { t_ret.Change_taille(0); // dimmensionnement du tableau de retour
         break;
       }
		    case 1 : // cas de l'association X V GAMMA
		     { int dim = ParaGlob::Dimension();
		       t_ret.Change_taille(3*dim); // dimmensionnement du tableau de retour
			      switch (dim)
           { case 3: t_ret(3) = X3; t_ret(3+dim) = V3;t_ret(3+2*dim) = GAMMA3;
             case 2: t_ret(2) = X2; t_ret(2+dim) = V2;t_ret(2+2*dim) = GAMMA2;
             case 1: t_ret(1) = X1; t_ret(1+dim) = V1;t_ret(1+2*dim) = GAMMA1;
           }; 
//		    t_ret(1) = X1; t_ret(1+dim) = V1;t_ret(1+2*dim) = GAMMA1;
//		    if (dim==1) break;
//		    t_ret(2) = X2; t_ret(2+dim) = V2;t_ret(2+2*dim) = GAMMA2;
//		    if (dim==2) break;
//		    t_ret(3) = X3; t_ret(3+dim) = V3;t_ret(3+2*dim) = GAMMA3;
		       break;
		     }
		    default :
		     {cout << "\nErreur : cas de combinaison non encore implanté, cas= "
             << cas
             << "\n Tableau <Enum_ddl> Combinaison(int cas) \n";
			     Sortie(1);
       }
     };
	   return t_ret;
  };


// passage de Ui en Xi, c-a-d : UX -> X1, UY -> X2, UZ -> X3
#ifndef MISE_AU_POINT
  inline 
#endif
Enum_ddl UxyzXi(Enum_ddl en)
  {  if (en == UX) 
        en = X1; 
     else if(en == UY) 
        en = X2; 
     else if(en == UZ) 
        en = X3;
     else
	      {
        cout << "\nErreur : nom du degre de liberte " << Nom_ddl(en)
             << " , different de UX ou UY ou UZ !\n";
        cout << "UxyzXi(Enum_ddl en) \n";
        Sortie(1);
	      };
	    return en;
  };

// passage inverse
#ifndef MISE_AU_POINT
  inline 
#endif
Enum_ddl XiUxyz(Enum_ddl en)
  {  if (en == X1 ) 
        en = UX; 
     else if(en == X2) 
        en = UY; 
     else if(en == X3) 
        en = UZ;
     else
	     {
        cout << "\nErreur : nom du degre de liberte " << Nom_ddl(en)
             << " , different de X1 ou X2 ou X3 !\n";
        cout << "XiUxyzi(Enum_ddl en) \n";
        Sortie(1);
      };
	    return en;
  };
//----------- pour les Coordonnee --------------
// retourne l'indice en fonction de l'enum et du nbcomposante
// pour une grandeur de type Coordonnee, sinon erreur
#ifndef MISE_AU_POINT
  inline
#endif
int Indice_coor(Enum_ddl a,int nbcomposantes)
  {return a-PremierDdlFamille(a)+1;};

// fonction donnant dans l'ordre des ddl de contraintes, les indices correspondant
// des tenseurs, ceci en fonction du nombre de composante de tenseur
// en retour un tableau : (i)(1) et (i)(2) -> l'indices du tenseur correspondant
// au i ième ddl de containte à partir de SIG11 
#ifndef MISE_AU_POINT
  inline 
#endif
Tableau2 <int> OrdreContrainte(int nbcomposantes)
  { // def du tableau de retour
    Tableau2 <int> ordre(nbcomposantes,2,0); 
      
    switch (nbcomposantes)
      {
       case 1 : 
        ordre(1,1) = 1; // -> SIG11
        ordre(1,2) = 1; //   "
        break;
       case 3 : // cas symétrique
        ordre(1,1) = 1; // -> SIG11
        ordre(1,2) = 1; //    "
        ordre(2,1) = 2; // -> SIG22
        ordre(2,2) = 2; //    "
        ordre(3,1) = 1; // -> SIG12
        ordre(3,2) = 2; //    "
        break;
       case 6 :
        ordre(1,1) = 1; // -> SIG11
        ordre(1,2) = 1; //    "
        ordre(2,1) = 2; // -> SIG22
        ordre(2,2) = 2; //    "
        ordre(3,1) = 3; // -> SIG33
        ordre(3,2) = 3; //    "
        ordre(4,1) = 1; // -> SIG12
        ordre(4,2) = 2; //    "
        ordre(5,1) = 2; // -> SIG23
        ordre(5,2) = 3; //    "
        ordre(6,1) = 1; // -> SIG13
        ordre(6,2) = 3; //    "
        break;
       case 9 :
       // ***** erreur il ne doit pas y avoir le cas de 9 valeurs
       // car cela n'a rien à voire avec les enum_ddl
       // il s'agit en fait de l'utilisation des fonctions OdVect et idx_i et idx_j
       // des tenseurs donc à revoir !!
        cout << "\nErreur : valeur incorrecte du nombre de composantes !\n"
             << " \n nombre = 9 ";
        cout << "\n OrdreContrainte(int nbcomposantes) \n";
        Sortie(1);
       
        
         /* // initialisation avec 9 valeurs différentes correspodantes aux trois
         // lignes : (1,1) (1,2) (1,3) ; (2,1) (2,2) (2,3) ; (3,1) (3,2) (3,3) 
        ordre(1,1) = 1; // -> SIG11
        ordre(1,2) = 1; //    "
        ordre(2,1) = 1; // -> SIG12
        ordre(2,2) = 2; //    "
        ordre(3,1) = 1; // -> SIG13
        ordre(3,2) = 3; //    "
        ordre(4,1) = 2; // -> SIG21
        ordre(4,2) = 1; //    "
        ordre(5,1) = 2; // -> SIG22
        ordre(5,2) = 2; //    "
        ordre(6,1) = 2; // -> SIG23
        ordre(6,2) = 3; //    "
        ordre(7,1) = 3; // -> SIG31
        ordre(7,2) = 1; //    "
        ordre(8,1) = 3; // -> SIG32
        ordre(8,2) = 2; //    "
        ordre(9,1) = 3; // -> SIG33
        ordre(9,2) = 3; //    "*/
        break;
       default :
          {cout << "\nErreur : valeur incorrecte du nombre de composantes !\n";
           cout << "OrdreContrainte(int nbcomposantes) \n";
           Sortie(1);
          }
      };
    return ordre;
  };
// idem en fonction du nombre de composantes
// fonction très rapide qui pointe sur des tableaux déjà construits
#ifndef MISE_AU_POINT
  inline 
#endif
const Tableau2 <int>& OrdreContrainteR(int nbcomposantes)
  {switch (nbcomposantes)
    { case 1 : return OrdreContrainte1; break;
      case 3 : return OrdreContrainte3; break; 
      case 6 : return OrdreContrainte6; break; 
		    default :
		     {cout << "\nErreur : valeur incorrecte du nombre de composantes : "
			          <<  nbcomposantes << "  !\n";
        cout << "OrdreContrainteR(int nbcomposantes) \n";
        Sortie(1);
       }
    };
	  return OrdreContrainte1; // pour taire le compilo !!
	 };

// donne directement le premier et le second indice en fonction de l'enum et du nbcomposante
// pour les tenseurs sigma ou epsilon ou Depsilon
#ifndef MISE_AU_POINT
  inline 
#endif
Deuxentiers_enu IJind(Enum_ddl a,int nbcomposantes)
 { Enum_ddl b = a; 
   if ( PremierDdlFamille(a) == EPS11)
      b = Enum_ddl(SIG11 + (a-EPS11)); // transfo en équivalent sigma
   if ( PremierDdlFamille(a) == DEPS11)
      b = Enum_ddl(SIG11 + (a-DEPS11)); // transfo en équivalent sigma
   Deuxentiers_enu ret; ret.i=-1; ret.j=-1;
   switch (nbcomposantes)
    { case 1:
        switch (b)
         { case SIG11: ret.i=1; ret.j=1;break;
	          default :
             {cout << "\nErreur : valeur incorrecte de l'énumération en fonction du nombre de composantes : "
                   << "enu= " << Nom_ddl(a) << " nbcomposantes " << nbcomposantes << "  !\n";
              cout << "IJind(Enum_ddl a,int nbcomposantes)\n";
              Sortie(1);
             }
         };
         break;     
      case 3:
        switch (b)
         { case SIG11: ret.i=1; ret.j=1;break;
           case SIG22: ret.i=2; ret.j=2;break;
           case SIG12: ret.i=1; ret.j=2;break;
	          default :
            {cout << "\nErreur : valeur incorrecte de l'énumération en fonction du nombre de composantes : "
                  << "enu= " << Nom_ddl(a) << " nbcomposantes " << nbcomposantes << "  !\n";
             cout << "IJind(Enum_ddl a,int nbcomposantes)\n";
             Sortie(1);
            }
         };
         break;     
      case 6:
        switch (b)
         { case SIG11: ret.i=1; ret.j=1;break;
           case SIG22: ret.i=2; ret.j=2;break;
           case SIG33: ret.i=3; ret.j=3;break;
           case SIG12: ret.i=1; ret.j=2;break;
           case SIG23: ret.i=2; ret.j=3;break;
           case SIG13: ret.i=1; ret.j=3;break;
	          default :
		           {cout << "\nErreur : valeur incorrecte de l'énumération en fonction du nombre de composantes : "
			                << "enu= " << Nom_ddl(a) << " nbcomposantes " << nbcomposantes << "  !\n";
              cout << "IJind(Enum_ddl a,int nbcomposantes)\n";
              Sortie(1);
             }
         };
         break;     
	     default :
       {cout << "\nErreur : valeur incorrecte du nombre de composantes : "
             <<  nbcomposantes << "  !\n";
        cout << "IJind(Enum_ddl a,int nbcomposantes)\n";
        Sortie(1);
       }
    };
   return ret;
 };

// passage de enum_ddl vers des réactions enum_ddl correspondantes
// exemple X1 -> R_X1 etc..
#ifndef MISE_AU_POINT
  inline 
#endif
Enum_ddl Vers_enum_reac(Enum_ddl id_nom)
 { Enum_ddl result;
   switch (id_nom)
    {case X1 :    result=R_X1;break;
     case X2 :    result=R_X2;break;
     case X3 :    result=R_X3;break;
     case EPAIS : result=R_EPAIS;break;
     case V1 :    result=R_V1;break;
     case V2 :    result=R_V2;break;
     case V3 :    result=R_V3;break;
     case GAMMA1 :result=R_GAMMA1;break;
     case GAMMA2 :result=R_GAMMA2;break;
     case GAMMA3 :result=R_GAMMA3;break;
     case TEMP :result=R_TEMP;break;
     default :
       {cout << "\nErreur : enum de reaction non implante pour le ddl : " << Nom_ddl(id_nom) << "!\n";
        cout << "Vers_enum_reac(Enum_ddl ) \n";
        Sortie(1);
       }
	   };
	  return result;
 };

// opération inverse: exemple R_X1 -> X1
#ifndef MISE_AU_POINT
  inline 
#endif
Enum_ddl Enum_reac_vers_enum(Enum_ddl id_nom)
 { Enum_ddl result;
   switch (id_nom)
     { case R_X1 :    result=X1;break;
       case R_X2 :    result=X2;break;
       case R_X3 :    result=X3;break;
       case R_EPAIS : result=EPAIS;break;
       case R_V1 :    result=V1;break;
       case R_V2 :    result=V2;break;
       case R_V3 :    result=V3;break;
       case R_GAMMA1 :result=GAMMA1;break;
       case R_GAMMA2 :result=GAMMA2;break;
       case R_GAMMA3 :result=GAMMA3;break;
       case R_TEMP :result=TEMP;break;
       default :
         {cout << "\nErreur : enum de reaction non implante pour le ddl : " << Nom_ddl(id_nom) << "!\n";
          cout << "Enum_reac_vers_enum(Enum_ddl ) \n";
          Sortie(1);
         }
     };
	  return result;
 };
  
// indique si un ddl est un ddl de  réaction on non
#ifndef MISE_AU_POINT
  inline 
#endif
bool Ddl_reaction(Enum_ddl id_ddl)
  {	bool res;
    switch (id_ddl)
     {  case R_X1: res=true;break;
        case R_X2: res=true;break;
        case R_X3: res=true;break;
        case R_EPAIS: res=true;break;
        case R_V1: res=true;break;
        case R_V2: res=true;break;
        case R_V3: res=true;break;
        case R_GAMMA1: res=true;break;
        case R_GAMMA2: res=true;break;
        case R_GAMMA3: res=true;break;
        case R_TEMP: res=true;break;
		      default : res = false; break;
	    }
	   return res;
  };


   // surcharge de l'operator de lecture
#ifndef MISE_AU_POINT
  inline 
#endif
istream & operator >> (istream & entree, Enum_ddl& a)
 { char nom_Enum_ddl[nbmax_caractere_enum_ddl+5];
   entree >> nom_Enum_ddl;
   a = Id_nom_ddl ( nom_Enum_ddl);
   return entree;
 };
   
   // surcharge de l'operator d'ecriture
#ifndef MISE_AU_POINT
  inline 
#endif
ostream & operator << (ostream & sort, const Enum_ddl& a)
    { // on ecrit la forme caractère
       sort << setw (nbmax_caractere_enum_ddl+2) << Nom_ddl(a) << " ";
       return sort;      
    };

#endif





