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

//#include "Debug.h"

#include "GeomPentaQComp.h"
#include <math.h>
#include "GeomSeg.h"
#include "GeomTriangle.h"
#include "GeomQuadrangle.h"
#include "MathUtil.h"
#include "GeomPentaL.h"

// constructeur
//  la dimension est 3, on a nbi pt d'integration ( 6 par défaut), 18 noeuds et 5 faces, 9 aretes
GeomPentaQComp::GeomPentaQComp(int nbi) :
    GeomPentaCom(nbi,18,QUADRACOMPL)
   {  // coordonnees dans l'élément de référence des noeuds 
      ptelem(1) = Coordonnee(0.,0.,-1.);    ptelem(2) = Coordonnee(1.,0.,-1.); 
      ptelem(3) = Coordonnee(0.,1.,-1.);   ptelem(4) = Coordonnee(0.,0.,1.);
      ptelem(5) = Coordonnee(1.,0.,1.);    ptelem(6) = Coordonnee(0.,1.,1.);
      ptelem(7)  = Coordonnee(0.5,0.,-1.);  ptelem(8)  = Coordonnee(0.5,0.5,-1.); 
      ptelem(9)  = Coordonnee(0,0.5,-1.);  ptelem(10) = Coordonnee(0.,0.,0.);
      ptelem(11) = Coordonnee(1.,0.,0.);    ptelem(12) = Coordonnee(0.,1.,0);
      ptelem(13) = Coordonnee(0.5,0.,1.);   ptelem(14) = Coordonnee(0.5,0.5,1.); 
      ptelem(15) = Coordonnee(0.,0.5,1.);   ptelem(16) = Coordonnee(0.5,0.,0.);
      ptelem(17) = Coordonnee(0.5,0.5,0.);   ptelem(18) = Coordonnee(0.,0.5,0.); 
      // définition de la numérotation locale de l'élément de direction inverse
      INVCONNEC(1)  = 1; INVCONNEC(2)  = 3; INVCONNEC(3)   = 2;
      INVCONNEC(4)  = 4; INVCONNEC(5)  = 6; INVCONNEC(6)   = 5;
      INVCONNEC(7)  = 9; INVCONNEC(8)  = 8; INVCONNEC(9)   = 7;
      INVCONNEC(10) = 10;INVCONNEC(11) = 12; INVCONNEC(12) = 11;
      INVCONNEC(13) = 15;INVCONNEC(14) = 14; INVCONNEC(15) = 13;
      INVCONNEC(16) = 18;INVCONNEC(17) = 17; INVCONNEC(18) = 16;
      // le tableau des tranches
      IND.Change_taille(5); 
      IND(1)=6; // les sommets
      IND(2)=3; // les 4 noeuds quadratiques de la face du dessous
      IND(3)=3;	 // les 3 noeuds quadratiques verticaux
      IND(4)=3;	 // les 3 noeuds quadratiques de la face du dessus
      IND(5)=3;	 // les 3 noeuds centraux des faces quadrangulaire quadratique

      //--------------------------------
      //def des arretes
      //--------------------------------
      int nbill =2;  // nb de pt d'integ par ligne
      int nbnel =3;   // nb de noeud du segment
      seg(1) = new GeomSeg(nbill,nbnel);
      for (int il=2;il<= NBSE; il++)  // ici NBSE = 9
           seg(il) = seg(1);
      // def des tableaux de connection des noeuds  des aretes
      for (int i =1;i<=NBSE;i++) NONS(i).Change_taille(nbnel);
      // la description est fait selon le fichier EIMail
      NONS(1)(1) = 1;NONS(1)(2) = 7;NONS(1)(3) = 2;
      NONS(2)(1) = 2;NONS(2)(2) = 8;NONS(2)(3) = 3;
      NONS(3)(1) = 3;NONS(3)(2) = 9;NONS(3)(3) = 1;
      NONS(4)(1) = 1;NONS(4)(2) = 10;NONS(4)(3) = 4;
      NONS(5)(1) = 2;NONS(5)(2) = 11;NONS(5)(3) = 5;
      NONS(6)(1) = 3;NONS(6)(2) = 12;NONS(6)(3) = 6;
      NONS(7)(1) = 4;NONS(7)(2) = 13;NONS(7)(3) = 5;
      NONS(8)(1) = 5;NONS(8)(2) = 14;NONS(8)(3) = 6;
      NONS(9)(1) = 6;NONS(9)(2) = 15;NONS(9)(3) = 4;
      //--------------------------------
      //def des faces
      //--------------------------------
      // 1) tout d'abord les faces verticales quadrangulaire
      int nbqis =4;  // nb de pt d'integ par facee
      int nbqnes =9;   // nb de noeud de la face
      face(2) = new GeomQuadrangle(nbqis,nbqnes);
      face(3) = face(2);
      face(5) = face(2);
      // 2) puis les faces haut et bas triangulairesv
      int nbtis =3;  // nb de pt d'integ par facee
      int nbtnes =6;   // nb de noeud de la face
      face(1) = new GeomTriangle(nbtis,nbtnes);
      face(4) = face(1);
      // def des tableaux de connection des noeuds  des faces
      // 1) les quadrangles
      NONF(2).Change_taille(nbqnes);NONF(3).Change_taille(nbqnes);
      NONF(5).Change_taille(nbqnes);
      // 2) les triangles
      NONF(1).Change_taille(nbtnes);NONF(4).Change_taille(nbtnes);
      
      // connection entre les noeuds des faces et les noeuds des elements
      NONF(1)(1)= 1; NONF(1)(2)= 3; NONF(1)(3)= 2; NONF(1)(4)= 9;
      NONF(1)(5)= 8; NONF(1)(6)= 7; 

      NONF(2)(1)= 1;NONF(2)(2)= 4; NONF(2)(3)= 6;NONF(2)(4)= 3;
      NONF(2)(5)= 10;NONF(2)(6)= 15; NONF(2)(7)= 12;NONF(2)(8)= 9; NONF(2)(9)= 18;

      NONF(3)(1)= 1; NONF(3)(2)= 2;NONF(3)(3)= 5;NONF(3)(4)= 4;
      NONF(3)(5)= 7; NONF(3)(6)= 11;NONF(3)(7)= 13;NONF(3)(8)= 10; NONF(3)(9)= 16;

      NONF(4)(1)= 4; NONF(4)(2)= 5; NONF(4)(3)= 6; NONF(4)(4)= 13;
      NONF(4)(5)= 14; NONF(4)(6)= 15; 

      NONF(5)(1)= 2; NONF(5)(2)= 3;NONF(5)(3)= 6;NONF(5)(4)= 5;
      NONF(5)(5)= 8; NONF(5)(6)= 12;NONF(5)(7)= 14;NONF(5)(8)= 11; NONF(5)(9)= 17;


      // triangulation des différentes  faces
      // on se sert d'une part de l'élément de référence de chaque face
      // puis de la connection les faces par rapport à celle de l'élément
      // ici c'est le même élément pour toutes les faces
      // on est obligé de boucler sur tous les indices et de faire
      // de l'adressage indirecte
      for (int isf=1;isf<= NBFE; isf++)  // boucle sur les faces
       {// 1) récup du tableau de l'élément de référence de la face
        const Tableau<Tableau<Tableau<int> > > & tabi = face(isf)->Trian_lin();
        int nbtria = tabi(1).Taille(); // nombre de triangle par face 
        NONFt(isf).Change_taille(nbtria);
         for (int if1=1;if1<= nbtria; if1++)  // boucle sur les triangles de la face
          { NONFt(isf)(if1).Change_taille(3);
            for (int in1=1;in1<= 3; in1++)  // boucle sur les noeuds du triangle
              NONFt(isf)(if1)(in1) = NONF(isf)(tabi(1)(if1)(in1));
            }
         }   

      // fonctions d'interpolation globales aux points d'intégrations
      for (int ptint=1;ptint<= nbi; ptint++)
             tabPhi(ptint) = Phi_point( ptInteg(ptint));
      // derivees des fonctions d'interpolations aux points d'intégrations
      for (int ptint=1;ptint<= nbi; ptint++)
             tabDPhi(ptint) = Dphi_point( ptInteg(ptint));
    // ---- constitution du tableau Extrapol ----- 
    Calcul_extrapol(nbi);              

};


// destructeur
GeomPentaQComp::~GeomPentaQComp() 
  { delete seg(1);
    delete face(1); delete face(2);
   };
// constructeur de copie
GeomPentaQComp::GeomPentaQComp(const GeomPentaQComp& a) :
  GeomPentaCom(a)
   { // la copie des parties pointées est à la charge de la classe spécifique
     // definition des  faces
     face(1) = new GeomTriangle(*((GeomTriangle*)(a.face(1))));
     face(4) = face(1);
     face(2) = new GeomQuadrangle(*((GeomQuadrangle*)(a.face(2))));
     face(3) = face(2);
     face(5) = face(2);
     // def des segments
     seg(1) = new GeomSeg(*((GeomSeg*)(a.seg(1)))) ;
     for (int il=2;il<= NBSE; il++)
           seg(il) = seg(1);
   };    
    
// création d'élément identiques : cette fonction est analogue à la fonction new
// elle y fait d'ailleurs appel. l'implantation est spécifique dans chaque classe
// dérivée
// pt est le pointeur qui est affecté par la fonction 
ElemGeomC0 * GeomPentaQComp::newElemGeomC0(ElemGeomC0 * pt) 
  { pt = new GeomPentaQComp(*this);
    return pt; 
   };

//--------- cas de coordonnees locales quelconques ---------------- 

    // retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& GeomPentaQComp::Phi_point(const Coordonnee& M)
  {
    #ifdef MISE_AU_POINT	 	   
     // verification de la dimension des coordonnees locales
     if (M.Dimension() != 3)
       { cout << "\n erreur la dimension des coordonnees locales :" << M.Dimension()
              <<"n\'est pas egale a 3 "
             << "\nGeomPentaQComp::Phi(Coordonnee& M)";
        Sortie(1);
      }
    #endif
//    Vecteur phi(NBNE); // tableau des fonctions d'interpolation
    // dimentionnement éventuelle du tableau des fonctions d'interpolation
    phi_M.Change_taille(NBNE); // si la taille est identique -> aucune action

    #ifdef MISE_AU_POINT	 	   
    if (NBNE == 18)
    #endif
      {  int nbnes = 3;  // nombre de noeud par cote du segment
         int nbnef = 6;  // nombre de noeud par face du trianble
         Coordonnee XY(2),Z(1); XY(1) = M(1); XY(2) = M(2); Z(1)=M(3); // coordonnees pour le segment
         //  fonctions d'interpolation
         // on a un triangle dans le plan xy et un segment dans la direction z
         int ne = 1;
         Vecteur tabPhiT(NBNE);
         for (int ifa = 1;ifa<= nbnef; ifa++)
          for (int iz = 1;iz<= nbnes; iz++)
            { tabPhiT(ne) = face(1)->Phi_point(XY)(ifa) * seg(1)->Phi_point(Z)(iz);
             ne++;
             } 
         // numerotation suivant le standard habituel
         Tableau<int> ind;
         ind.Change_taille(NBNE);
// modif le 24sep2007 (sans doute une ancienne numérotation ??), car on balaie d'abord en z puis en xy         
         ind(1)  = 1;  ind(2)  = 4;  ind(3)  = 7;  ind(4)  = 3;  ind(5)  = 6;  ind(6)  = 9; 
         ind(7)  = 10; ind(8)  = 13; ind(9)  = 16; ind(10) = 2; ind(11) = 5; ind(12) = 8; 
         ind(13) = 12;  ind(14) = 15;  ind(15) = 18;  ind(16) = 11; ind(17) = 14; ind(18) = 17; 
//         ind(1)  = 1;  ind(2)  = 2;  ind(3)  = 3;  ind(4)  = 7;  ind(5)  = 8;  ind(6)  = 9; 
//         ind(7)  = 10; ind(8)  = 11; ind(9)  = 12; ind(10) = 16; ind(11) = 17; ind(12) = 18; 
//         ind(13) = 4;  ind(14) = 5;  ind(15) = 6;  ind(16) = 13; ind(17) = 14; ind(18) = 15; 
         
         for (int ne = 1; ne<= NBNE; ne++)
               phi_M(ne) = tabPhiT(ind(ne));
       }  
    #ifdef MISE_AU_POINT	 	   
      else
       {cout << "\n erreur le pentaedre de nombre de noeud NBNE = " << NBNE 
             << "\n n\'est pas implante !! ";
        cout << "\nGeomPentaQComp::Phi(Coordonnee& M) " << endl;     
        Sortie(1);
        }
    #endif
   // retour de phi_M
    return phi_M;    
   };
    // retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& GeomPentaQComp::Dphi_point(const Coordonnee& M)
  {  
   #ifdef MISE_AU_POINT	 	   
     // verification de la dimension des coordonnees locales
     if (M.Dimension() != 3)
       { cout << "\n erreur la dimension des coordonnees locales :" << M.Dimension()
              <<"n\'est pas egale a 3 "
             << "\nGeomPentaQComp::Dphi(Coordonnee& M)";
        Sortie(1);
      }
    #endif
//   Mat_pleine dphi(3,NBNE); // le tableau des derivees
   // le tableau des derivees: redimentionnement si nécessaire
   if ((dphi_M.Nb_ligne() != 3)&&(dphi_M.Nb_colonne() != NBNE))
      dphi_M.Initialise (3,NBNE,0.);
   
    #ifdef MISE_AU_POINT	 	   
    if (NBNE == 18)
    #endif
      {  int nbnes = 3;  // nombre de noeud par cote du segment
         int nbnef = 6;  // nombre de noeud par face du trianble
         Coordonnee XY(2),Z(1); XY(1) = M(1); XY(2) = M(2); Z(1)=M(3); // coordonnees pour le segment
         //  fonctions d'interpolation
         // on a un triangle dans le plan xy et un segment dans la direction z
         int ne = 1;
         Mat_pleine tabDPhiT(3,NBNE);
         for (int ifa = 1;ifa<= nbnef; ifa++)
          for (int iz = 1;iz<= nbnes; iz++)
            { tabDPhiT(1,ne) = face(1)->Dphi_point(XY)(1,ifa) * seg(1)->Phi_point(Z)(iz);
              tabDPhiT(2,ne) = face(1)->Dphi_point(XY)(2,ifa) * seg(1)->Phi_point(Z)(iz);
              tabDPhiT(3,ne) = face(1)->Phi_point(XY)(ifa) * seg(1)->Dphi_point(Z)(1,iz);
              ne++;
             } 
         // numerotation suivant le standard habituel
         Tableau<int> ind;
         ind.Change_taille(NBNE);
// modif le 24sep2007 (sans doute une ancienne numérotation ??), car on balaie d'abord en z puis en xy         
         ind(1)  = 1;  ind(2)  = 4;  ind(3)  = 7;  ind(4)  = 3;  ind(5)  = 6;  ind(6)  = 9; 
         ind(7)  = 10; ind(8)  = 13; ind(9)  = 16; ind(10) = 2; ind(11) = 5; ind(12) = 8; 
         ind(13) = 12;  ind(14) = 15;  ind(15) = 18;  ind(16) = 11; ind(17) = 14; ind(18) = 17; 
//         ind(1)  = 1;  ind(2)  = 2;  ind(3)  = 3;  ind(4)  = 7;  ind(5)  = 8;  ind(6)  = 9; 
//         ind(7)  = 10; ind(8)  = 11; ind(9)  = 12; ind(10) = 16; ind(11) = 17; ind(12) = 18; 
//         ind(13) = 4;  ind(14) = 5;  ind(15) = 6;  ind(16) = 13; ind(17) = 14; ind(18) = 15; 
         
         for (int ne = 1; ne<= NBNE; ne++)
            { dphi_M(1,ne) = tabDPhiT(1,ind(ne));
              dphi_M(2,ne) = tabDPhiT(2,ind(ne));
              dphi_M(3,ne) = tabDPhiT(3,ind(ne));
             } 
       }  
    #ifdef MISE_AU_POINT	 	   
      else
       {cout << "\n erreur le pentaedre de nombre de noeud NBNE = " << NBNE 
             << "\n n\'est pas implante !! ";
        cout << "\nGeomPentaQComp::Phi(Coordonnee& M) " << endl;     
        Sortie(1);
        }
    #endif
            
    // retour des derivees  
    return dphi_M;
   };
   
       
// constitution du tableau Extrapol
void GeomPentaQComp::Calcul_extrapol(int nbi)
{ // cas de l'extrapolation de grandeur des points d'intégrations aux noeuds
  // def du tableau de pondération tab(i)(j) qu'il faut appliquer
  // aux noeuds pour avoir la valeur aux noeuds 
  // val_au_noeud(i) = somme_(de j=indir(i)(1) à indir(i)(taille(indir(i)) )) {tab(i)(j) * val_pt_integ(j) }
  // cas = 1: la valeur au noeud = la valeur au pt d'integ le plus près ou une moyenne des
  //          pt les plus près (si le nb de pt d'integ < nb noeud)
  //  --- pour l'instant seul le cas 1 est implanté  ---
  Tableau<Tableau<int> > &  indir = extrapol(1).indir;  // pour simplifier
  Tableau<Tableau<double > > & tab = extrapol(1).tab;    // pour simplifier
  Tableau <int> indirect(3); // tableau de travail
  //on définit un pentaèdre linéaire qui va nous permettre d'extrapoler
  // pour les nbi >= 6
  GeomPentaL penta(6);

  switch  (nbi)
   { case 2: 
       { // cas avec un point d'intégration en bas puis en haut,  
         
           // tab est supposé être initialisé à 0.
           Tableau <Coordonnee>  gi_B,gi_H; // bases naturelle et duale
           // --- méthode 1 (par défaut), on utilise une extrapolation linéaire dans l'épaisseur
           {Tableau<Tableau<int> > & indir = extrapol(1).indir;  // pour simplifier
            Tableau<Tableau<double > > & tab = extrapol(1).tab;    // pour simplifier
            Tableau <int> indirect(nbi); // tableau de travail: on a 2 pondérations
            indirect(1)=1; indirect(2)=2;
            tab.Change_taille(NBNE);indir.Change_taille(NBNE);
            
            // on traite tous les noeuds de la même manière
            for (int ne=1;ne<=NBNE;ne++)
            { // il nous faut calculer la coordonnée locale theta^3 du noeud
              // les pti ici considérés, sont les extrémités d'un segment
              Coordonnee theta(1); // la coordonnée que l'on cherche
              Vecteur phi_z(2); // le conteneur pour les fonctions d'interpolation
              // suivant z
              Bases_naturel_duales(indirect,gi_B,gi_H);
              Coordonnee O(0.5*(ptInteg(indirect(1))+ptInteg(indirect(2)))); //
              ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_z,theta);
               
              // maintenant on va attribuer au noeud de la facette la valeur extrapolée
              for (int i=1;i<3;i++)
               {tab(ne)(indirect(i))=phi_z(i);
                indir(ne)(i)=indirect(i);
               };
           };
         };
         // --- ancienne méthode
//          // on reporte la valeur au premier pt d'integ, telle quelle aux noeuds du bas
//          for (int ne=1;ne<=3;ne++)
//           {tab(ne)(1)=1.;
//            indir(ne).Change_taille(1); indir(ne)(1)=1;
//           };
//          for (int ne=7;ne<=9;ne++)
//           {tab(ne)(1)=1.;
//            indir(ne).Change_taille(1); indir(ne)(1)=1;
//           };
//          // on reporte la valeur au second pt d'integ, telle quelle aux noeuds du haut
//          for (int ne=4;ne<=6;ne++)
//           {tab(ne)(2)=1.;
//            indir(ne).Change_taille(1); indir(ne)(1)=2;
//           };
//          for (int ne=13;ne<=15;ne++)
//           {tab(ne)(2)=1.;
//            indir(ne).Change_taille(1); indir(ne)(1)=2;
//           };
//          // on reporte la moyenne des valeurs deux pt d'integ	pour les noeuds du milieu
//          for (int ne=10;ne<=12;ne++)
//           {tab(ne)(1)=0.5;tab(ne)(2)=0.5;
//            indir(ne).Change_taille(2); indir(ne)(1)=1;indir(ne)(2)=2;
//           };
//          for (int ne=16;ne<=18;ne++)
//           {tab(ne)(1)=0.5;tab(ne)(2)=0.5;
//            indir(ne).Change_taille(2); indir(ne)(1)=1;indir(ne)(2)=2;
//           };
         break;
       }
     case 3: 
       { // cas avec un point d'intégration à chaque couche,  
         
           // tab est supposé être initialisé à 0.
           Tableau <Coordonnee>  gi_B,gi_H; // bases naturelle et duale
           // --- méthode 1 (par défaut), on utilise une extrapolation linéaire dans l'épaisseur
           {Tableau<Tableau<int> > & indir = extrapol(1).indir;  // pour simplifier
            Tableau<Tableau<double > > & tab = extrapol(1).tab;    // pour simplifier
            Tableau <int> indirect(nbi); // tableau de travail: on a 2 pondérations
            tab.Change_taille(NBNE);indir.Change_taille(NBNE);
            
            // on va travailler par nappe triangulaire de noeuds quadratique
            for (int inappe = 1; inappe < 4; inappe++)
            { // il nous faut calculer la coordonnée locale theta^3 des 6 noeuds
              // les pti ici considérés, sont les extrémités d'un segment
              Coordonnee theta(1); // la coordonnée que l'on cherche
              Vecteur phi_z(2); // le conteneur pour les fonctions d'interpolation
              // pour les 2 premières nappe on utilise les 2 premier pti
              indirect(1)=1; indirect(2)=2;
              if (inappe == 3) // pour la 3ième nappe on utilise les 2 derniers pti
                {indirect(1)=2; indirect(2)=3;}
                
              int nbn_concernes=6;
              Tableau <int> J(nbn_concernes); // les noeuds concernés
              switch (inappe)
               {case 1:
                 {J(1)=1; J(2)=7; J(3)=2; J(4)=8; J(5) = 3; J(6)=9; break;}
                case 2:
                 {J(1)=10; J(2)=16; J(3)=11; J(4)=17; J(5) =12; J(6)=18; break;}
                case 3:
                {J(1)=4; J(2)=13; J(3)=5; J(4)=14; J(5) =6; J(6)=15; break;}
               };
              // on boucle sur les noeuds concernés
              for (int ine = 1;ine<= nbn_concernes; ine++)
               {int ne = J(ine);
                // suivant z
                Bases_naturel_duales(indirect,gi_B,gi_H);
                Coordonnee O(0.5*(ptInteg(indirect(1))+ptInteg(indirect(2)))); //
                ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_z,theta);
                // maintenant on va attribuer au noeud de la facette la valeur extrapolée
                for (int i=1;i<3;i++)
                 {tab(ne)(indirect(i))=phi_z(i);
                  indir(ne)(i)=indirect(i);
                 };
               };
            };
           };
           // --- ancienne méthode
//         // on reporte la valeur au premier pt d'integ, telle quelle aux noeuds du bas
//         for (int ne=1;ne<=3;ne++)
//         	{tab(ne)(1)=1.;
//         	 indir(ne).Change_taille(1); indir(ne)(1)=1;
//         	};
//         for (int ne=7;ne<=9;ne++)
//         	{tab(ne)(1)=1.;
//         	 indir(ne).Change_taille(1); indir(ne)(1)=1;
//         	};
//         // on reporte la valeur au  pt d'integ 3, telle quelle aux noeuds du haut
//         for (int ne=4;ne<=6;ne++)
//         	{tab(ne)(3)=1.;
//         	 indir(ne).Change_taille(1); indir(ne)(1)=3;
//         	};
//         for (int ne=13;ne<=15;ne++)
//         	{tab(ne)(3)=1.;
//         	 indir(ne).Change_taille(1); indir(ne)(1)=3;
//         	};
//         // on reporte la valeur du   pt d'integ 2	pour les noeuds du milieu
//         for (int ne=10;ne<=12;ne++)
//         	{tab(ne)(2)=1;
//         	 indir(ne).Change_taille(1); indir(ne)(1)=2;
//         	};
//         for (int ne=16;ne<=18;ne++)
//         	{tab(ne)(2)=1;
//         	 indir(ne).Change_taille(1); indir(ne)(1)=2;
//         	};
         break;
       }
     case 6: // 3 pt de surface en  bas et en haut
       { // tab est supposé être initialisé à 0.
         Tableau <Coordonnee>  gi_B,gi_H; // bases naturelle et duale
         // --- méthode 1 (par défaut), on utilise une extrapolation linéaire dans l'épaisseur
         // et une extrapolation linéaire dans le plan du triangle
         // donc en fait on extrapole via un pentaèdre linéaire dont les sommets sont au niveau
         // des 6 pti
         
         {Tableau<Tableau<int> > & indir = extrapol(1).indir;  // pour simplifier
          Tableau<Tableau<double > > & tab = extrapol(1).tab;    // pour simplifier
          tab.Change_taille(NBNE);indir.Change_taille(NBNE);
          
          Tableau <int> indirect(nbi); // tableau de travail: on a 6 pondérations
          // même numérotation des pti
          for (int i=1;i<=nbi;i++)
            indirect(i) = i;
          
          // on traite tous les noeuds de la même manière
          for (int ne=1;ne<=NBNE;ne++)
           {// il nous faut calculer les coordonnées locales du noeud
            // sachant que les pti ici considérés, sont aux sommets d'un pentaèdre linéaire orthogonal
            // on peut traiter séparément les coordonnées dans le plan et la coordonnée z

            Coordonnee theta(3); // les coordonnées que l'on cherche
            
            // suivant x et y: calcul de theta^alpha
            {Tableau <int> indirect_local(3); // tableau de travail
             // on considère le triangle des 3 premiers pti
             indirect_local(1) = indirect(1);indirect_local(2) = indirect(2);
             indirect_local(3) = indirect(3);
             Coordonnee theta_loc(2); // le conteneur pour les coordonnées locales en x y
             Tableau <Coordonnee>  gi_loc_B,gi_loc_H; // bases naturelle et duale
             Bases_naturel_duales(indirect_local,gi_loc_B,gi_loc_H);
             Coordonnee O(ptInteg(indirect(1))); //
             Vecteur phi_xy(3); // le conteneur pour les fonctions
             ElemGeomC0::Coor_phi(O,gi_loc_H,ptelem(ne),phi_xy,theta_loc);
             theta(1)=theta_loc(1); // on enregistre
             theta(2)=theta_loc(2); // on enregistre
            }
            
            // suivant z: calcul de theta^3
            {Tableau <int> indirect_local(2); // tableau de travail
             // on considère la ligne du pti 1 -> pti 4
             indirect_local(1) = indirect(1);indirect_local(2) = indirect(4);
             Coordonnee theta_loc(1); // le conteneur pour les coordonnées locales
             Tableau <Coordonnee>  gi_loc_B,gi_loc_H; // bases naturelle et duale
             Bases_naturel_duales(indirect_local,gi_loc_B,gi_loc_H);
             Coordonnee O(0.5*(ptInteg(indirect(1))+ptInteg(indirect(2)))); //
             Vecteur phi_z(2); // le conteneur pour les fonctions d'interpolation
             ElemGeomC0::Coor_phi(O,gi_loc_H,ptelem(ne),phi_z,theta_loc);
             theta(3)=theta_loc(1); // on enregistre
            }
             
            // maintenant on va attribuer au noeud la valeur extrapolée
            // on calcule les fct d'interpolation au noeud ne
            // via ses coordonnées locales theta: on utilise le pentaèdre linéaire
            const Vecteur& phiphi = penta.Phi_point(theta);
            // et on enregistre
            indir(ne).Change_taille(nbi);
            tab(ne).Change_taille(nbi);
            // on boucle sur les pti du pentaèdre linéaire d'interpolation
            for (int i=1;i<7;i++)
             {tab(ne)(indirect(i))=phiphi(i);
              indir(ne)(i)=indirect(i);
             };
           };
         };
         // --- ancienne méthode
//         // on utilise systématiquement le pt d'integ le plus proche
//   	   {  int ne = 1; tab(ne)(1) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=1;
//          ne = 2; tab(ne)(2) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=2;
//          ne = 3; tab(ne)(3) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=3;
//          ne = 4; tab(ne)(4) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=4;
//          ne = 5; tab(ne)(5) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=5;
//          ne = 6; tab(ne)(6) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=6;
//          // pour les noeuds intermédiaires on moyenne les pt d'integ de part et autre
//          ne = 7; tab(ne)(1) = 0.5;tab(ne)(2) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=1;indir(ne)(2)=2;
//          ne = 8; tab(ne)(2) = 0.5;tab(ne)(3) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=2;indir(ne)(2)=3;
//          ne = 9; tab(ne)(1) = 0.5;tab(ne)(3) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=1;indir(ne)(2)=3;
//          ne = 10; tab(ne)(1) = 0.5;tab(ne)(4) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=1;indir(ne)(2)=4;
//          ne = 11; tab(ne)(2) = 0.5;tab(ne)(5) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=2;indir(ne)(2)=5;
//          ne = 12; tab(ne)(3) = 0.5;tab(ne)(6) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=3;indir(ne)(2)=6;
//          ne = 13; tab(ne)(4) = 0.5;tab(ne)(5) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=4;indir(ne)(2)=5;
//          ne = 14; tab(ne)(5) = 0.5;tab(ne)(6) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=5;indir(ne)(2)=6;
//          ne = 15; tab(ne)(6) = 0.5;tab(ne)(4) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=6;indir(ne)(2)=4;
//
//          ne = 16;
//          tab(ne)(1) = 0.25;tab(ne)(2) = 0.25;tab(ne)(4) = 0.25;tab(ne)(5) = 0.25;
//          indir(ne).Change_taille(4);
//          indir(ne)(1)=1;indir(ne)(2)=2;indir(ne)(3)=4;indir(ne)(4)=5;
//          ne = 17;
//          tab(ne)(2) = 0.25;tab(ne)(3) = 0.25;tab(ne)(5) = 0.25;tab(ne)(6) = 0.25;
//          indir(ne).Change_taille(4);
//          indir(ne)(1)=2;indir(ne)(2)=3;indir(ne)(3)=5;indir(ne)(4)=6;
//          ne = 18;
//          tab(ne)(1) = 0.25;tab(ne)(3) = 0.25;tab(ne)(4) = 0.25;tab(ne)(6) = 0.25;
//          indir(ne).Change_taille(4);
//          indir(ne)(1)=1;indir(ne)(2)=3;indir(ne)(3)=4;indir(ne)(4)=6;
          
          break;  
   	 	}  // fin du cas avec 6 pt d'intégration
     case 8: // 4 pt de surface en  bas et en haut
      {
       // tab est supposé être initialisé à 0.
       Tableau <Coordonnee>  gi_B,gi_H; // bases naturelle et duale
/*
       // --- méthode 1 (par défaut), on utilise une extrapolation linéaire dans l'épaisseur
       // et une extrapolation linéaire dans le plan du triangle
       // donc en fait on extrapole via un pentaèdre linéaire dont les sommets sont au niveau
       // de 6 pti
       //             couche du bas                                                 couche du haut
       //               4 points                                                      4 points
       //                 (3)                                                        (6)
       //                 | \                                                        | \
       //                 |  \                                                       |  \
       //                 | 4  \                                                     | 8  \
       //                 |     \                                                    |     \
       //  face 2 ->      |       \   <- face 5                                      |       \
       //                 |      1 \                                                 |      5 \
       //                 |          \                                               |          \
       //                 |           \                                              |           \
       //                 | 2        3  \                                            | 6        7  \
       //                 |______________\                                           |______________\
       //                (1)             (2)                                        (4)             (5)
       //                        ^
       //                        |
       //                      face 3
       
       //                         |zeta
       //                         |
       //                         4----15---6
       //                        /|        *|
       //                       / |      *  |
       //                      /  |    *    |
       //                    13  10-14-18---12----- eta
       //                    /  / *         |
       //                   /   * |         |
       //                  / * /  | 17      |
       //                 5  16   1----9----3
       //                 |  /   /        *
       //                 | /   /       *
       //                 |/   /      *
       //                11   7    8
       //                /|  /   *
       //              xi | /  *
       //                 |/ *
       //                 2
       //
       //
       //
       // face 1 : noeud 1  3  2  9  8  7, face 2 : noeud 1  4  6  3 10  15  12  9 18,
       // face 3 : noeud 1  2  5  4  7 11  13  10 16, face 4 : noeud 4  5   6  13 14  15,
       // face 5 : noeud 2  3  6  5  8  12  14  11 17,
*/
       // on va utiliser un pentaèdre linéaire particulier par face verticale de l'élément
       for (int iface = 1; iface <=3; iface++) // correspond aux faces 2 3 5 de l'élément
        {// pour chaque face on définit les sommets du pentaèdre linéaire
         Tableau <int> indirect(6); // pti concernés
         Tableau <int> J(9); // les noeuds concernés
         int nbn_concernes;

         switch (iface)
           {case 1: // face 2
                    {indirect(1)=4;indirect(2)=2;indirect(3)=1;
                     indirect(4)=8;indirect(5)=6;indirect(6)=5;
                     J(1)=1;  J(2)=4;  J(3)=6;  J(4)=3;
                     J(5)=10; J(6)=15; J(7)=12; J(8)=9;J(9)=18;
                     nbn_concernes = 9;
                     break;
                    }
            case 2: // face 3
                    {indirect(1)=1;indirect(2)=2;indirect(3)=3;
                     indirect(4)=5;indirect(5)=6;indirect(6)=7;
                     nbn_concernes = 6;
                     J(1)=2;  J(2)=5;  J(3)=7;  J(4)=11;
                     J(5)=13;J(6)=16;
                     break;
                    }
            case 3: // face 5
                    {indirect(1)=1;indirect(2)=1;indirect(3)=3;
                     indirect(4)=5;indirect(5)=6;indirect(6)=7;
                     nbn_concernes = 3;
                     J(1)=8;  J(2)=14;J(3)=17;
                     break;
                    }
            default:
               break;
           };
         // on boucle sur les noeuds à traiter
         for (int ine = 1;ine<= nbn_concernes; ine++)
          {int ne = J(ine);
           // il nous faut calculer les coordonnées locales du noeud
           // sachant que les pti ici considérés, sont aux sommets d'un pentaèdre linéaire orthogonal
           // on peut traiter séparément les coordonnées dans le plan et la coordonnée z

           Coordonnee theta(3); // les coordonnées que l'on cherche
           
           // suivant x et y: calcul de theta^alpha
           {Tableau <int> indirect_local(3); // tableau de travail
            // on considère le triangle des 3 premiers pti
            indirect_local(1) = indirect(1);indirect_local(2) = indirect(2);
            indirect_local(3) = indirect(3);
            Coordonnee theta_loc(2); // le conteneur pour les coordonnées locales en x y
            Tableau <Coordonnee>  gi_loc_B,gi_loc_H; // bases naturelle et duale
            Bases_naturel_duales(indirect_local,gi_loc_B,gi_loc_H);
            Coordonnee O(ptInteg(indirect(1))); //
            Vecteur phi_xy(3); // le conteneur pour les fonctions
            ElemGeomC0::Coor_phi(O,gi_loc_H,ptelem(ne),phi_xy,theta_loc);
            theta(1)=theta_loc(1); // on enregistre
            theta(2)=theta_loc(2); // on enregistre
           }
           
           // suivant z: calcul de theta^3
           {Tableau <int> indirect_local(2); // tableau de travail
            // on considère la ligne du pti 1 -> pti 5
            indirect_local(1) = indirect(1);indirect_local(2) = indirect(4);
            Coordonnee theta_loc(1); // le conteneur pour les coordonnées locales
            Tableau <Coordonnee>  gi_loc_B,gi_loc_H; // bases naturelle et duale
            Bases_naturel_duales(indirect_local,gi_loc_B,gi_loc_H);
            Coordonnee O(0.5*(ptInteg(indirect(1))+ptInteg(indirect(2)))); //
            Vecteur phi_z(2); // le conteneur pour les fonctions d'interpolation
            ElemGeomC0::Coor_phi(O,gi_loc_H,ptelem(ne),phi_z,theta_loc);
            theta(3)=theta_loc(1); // on enregistre
           }
            
           // maintenant on va attribuer au noeud la valeur extrapolée
           // on calcule les fct d'interpolation au noeud ne
           // via ses coordonnées locales theta: on utilise le pentaèdre linéaire
           const Vecteur& phiphi = penta.Phi_point(theta);
           // et on enregistre
           indir(ne).Change_taille(6);
           tab(ne).Change_taille(nbi);
           // on boucle sur les pti du pentaèdre linéaire d'interpolation
           for (int i=1;i<7;i++)
            {tab(ne)(indirect(i))=phiphi(i);
             indir(ne)(i)=indirect(i);
            };
         };
       };
                    // --- ancienne méthode
//         // on utilise systématiquement le pt d'integ le plus proche
//   	   {  int ne = 1; tab(ne)(2) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=2;
//          ne = 2; tab(ne)(3) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=3;
//          ne = 3; tab(ne)(4) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=4;
//          ne = 4; tab(ne)(6) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=6;
//          ne = 5; tab(ne)(7) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=7;
//          ne = 6; tab(ne)(8) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=8;
//          // pour les noeuds intermédiaires on moyenne les pt d'integ de part et autre
//          ne = 7; tab(ne)(2) = 0.5;tab(ne)(3) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=2;indir(ne)(2)=3;
//          ne = 8; tab(ne)(3) = 0.5;tab(ne)(4) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=3;indir(ne)(2)=4;
//          ne = 9; tab(ne)(2) = 0.5;tab(ne)(4) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=2;indir(ne)(2)=4;
//          ne = 10; tab(ne)(2) = 0.5;tab(ne)(6) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=2;indir(ne)(2)=6;
//          ne = 11; tab(ne)(3) = 0.5;tab(ne)(7) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=3;indir(ne)(2)=7;
//          ne = 12; tab(ne)(4) = 0.5;tab(ne)(8) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=4;indir(ne)(2)=8;
//          ne = 13; tab(ne)(6) = 0.5;tab(ne)(7) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=6;indir(ne)(2)=7;
//          ne = 14; tab(ne)(7) = 0.5;tab(ne)(8) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=7;indir(ne)(2)=8;
//          ne = 15; tab(ne)(8) = 0.5;tab(ne)(6) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=8;indir(ne)(2)=6;
//
//          ne = 16;
//          tab(ne)(2) = 0.25;tab(ne)(3) = 0.25;tab(ne)(6) = 0.25;tab(ne)(7) = 0.25;
//          indir(ne).Change_taille(4);
//          indir(ne)(1)=2;indir(ne)(2)=3;indir(ne)(3)=6;indir(ne)(4)=7;
//          ne = 17;
//          tab(ne)(3) = 0.25;tab(ne)(4) = 0.25;tab(ne)(7) = 0.25;tab(ne)(8) = 0.25;
//          indir(ne).Change_taille(4);
//          indir(ne)(1)=3;indir(ne)(2)=4;indir(ne)(3)=7;indir(ne)(4)=8;
//          ne = 18;
//          tab(ne)(2) = 0.25;tab(ne)(4) = 0.25;tab(ne)(6) = 0.25;tab(ne)(8) = 0.25;
//          indir(ne).Change_taille(4);
//          indir(ne)(1)=2;indir(ne)(2)=4;indir(ne)(3)=6;indir(ne)(4)=8;
          
          break;  
   	 	}  // fin du cas avec 8 pt d'intégration
     case 9: // 3 * 3pt de surface de  bas  en haut
      {  // tab est supposé être initialisé à 0.
         Tableau <Coordonnee>  gi_B,gi_H; // bases naturelle et duale
         // --- méthode 1 (par défaut), on utilise une extrapolation linéaire dans l'épaisseur
         // on va utiliser les 6 premiers pti pour définir un penta linéaire
         // qui servira pour les noeuds du bas et du milieu
         // NB: en fait pour les noeuds du milieu, compte tenu qu'ils sont
         // exactement au même niveau que les pti 4 5 5, ce sera uniquement ceux là
         // qui seront interpolé,
         // puis avec les pti de 4 à 9 on définit le second penta linéaire
         // pour interpoler les noeuds du haut
         {Tableau<Tableau<int> > & indir = extrapol(1).indir;  // pour simplifier
          Tableau<Tableau<double > > & tab = extrapol(1).tab;    // pour simplifier
          tab.Change_taille(NBNE);indir.Change_taille(NBNE);
                     
          Tableau <int> indirect(nbi); // tableau de travail: on a 6 pondérations
          for (int inappe = 1; inappe <=3; inappe++)
           {Tableau <int> J(9); // les noeuds concernés
            int nbn_concernes;
            switch (inappe)
              {case 1: // nappe de noeuds du bas
                {nbn_concernes = 6;
                 J(1)=1;  J(2)=7;  J(3)=2;  J(4)=8;
                 J(5)=3; J(6)=9;
                 // même numérotation des pti pour les 6 premiers pti
                 for (int i=1;i<=6;i++)
                   indirect(i) = i;
                };
               break;
              case 2: // nappe de noeuds du milieu
                {nbn_concernes = 6;
                 J(1)=10;  J(2)=11;  J(3)=12;J(4)=16;
                 J(5)=17; J(6)=18;
                 // les pti pour le penta linéaire
                 // même numérotation des pti pour les 6 premiers pti
                 for (int i=1;i<=6;i++)
                   indirect(i) = i;
                };
               break;
              case 3: // nappe de noeuds du haut
                {nbn_concernes = 6;
                 J(1)=4;  J(2)=13;  J(3)=5;  J(4)=14;
                 J(5)=6; J(6)=15;
                 // les pti pour le penta linéaire
                 for (int i=1;i<=6;i++)
                   indirect(i) = i+3;
                };
               break;
             default:
               break;
           };
            // on traite tous les noeuds de la même manière
            for (int ine = 1;ine<= nbn_concernes; ine++)
             {int ne = J(ine);
              // il nous faut calculer les coordonnées locales du noeud
              // sachant que les pti ici considérés, sont aux sommets d'un pentaèdre linéaire orthogonal
              // on peut traiter séparément les coordonnées dans le plan et la coordonnée z

              Coordonnee theta(3); // les coordonnées que l'on cherche
              
              // suivant x et y: calcul de theta^alpha
              {Tableau <int> indirect_local(3); // tableau de travail
               // on considère le triangle des 3 premiers pti
               indirect_local(1) = indirect(1);indirect_local(2) = indirect(2);
               indirect_local(3) = indirect(3);
               Coordonnee theta_loc(2); // le conteneur pour les coordonnées locales en x y
               Tableau <Coordonnee>  gi_loc_B,gi_loc_H; // bases naturelle et duale
               Bases_naturel_duales(indirect_local,gi_loc_B,gi_loc_H);
               Coordonnee O(ptInteg(indirect(1))); //
               Vecteur phi_xy(3); // le conteneur pour les fonctions
               ElemGeomC0::Coor_phi(O,gi_loc_H,ptelem(ne),phi_xy,theta_loc);
               theta(1)=theta_loc(1); // on enregistre
               theta(2)=theta_loc(2); // on enregistre
              }
              
              // suivant z: calcul de theta^3
              {Tableau <int> indirect_local(2); // tableau de travail
               // on considère la ligne du pti 1 -> pti 4
               indirect_local(1) = indirect(1);indirect_local(2) = indirect(4);
               Coordonnee theta_loc(1); // le conteneur pour les coordonnées locales
               Tableau <Coordonnee>  gi_loc_B,gi_loc_H; // bases naturelle et duale
               Bases_naturel_duales(indirect_local,gi_loc_B,gi_loc_H);
               Coordonnee O(0.5*(ptInteg(indirect(1))+ptInteg(indirect(2)))); //
               Vecteur phi_z(2); // le conteneur pour les fonctions d'interpolation
               ElemGeomC0::Coor_phi(O,gi_loc_H,ptelem(ne),phi_z,theta_loc);
               theta(3)=theta_loc(1); // on enregistre
              }
               
              // maintenant on va attribuer au noeud la valeur extrapolée
              // on calcule les fct d'interpolation au noeud ne
              // via ses coordonnées locales theta: on utilise le pentaèdre linéaire
              const Vecteur& phiphi = penta.Phi_point(theta);
              // et on enregistre
              indir(ne).Change_taille(nbi);
              tab(ne).Change_taille(nbi);
              // on boucle sur les pti du pentaèdre linéaire d'interpolation
              for (int i=1;i<7;i++)
               {tab(ne)(indirect(i))=phiphi(i);
                indir(ne)(i)=indirect(i);
               };
             };
           }

         };
         
         // --- ancienne méthode
//      // on utilise systématiquement le pt d'integ le plus proche
//    {  int ne = 1; tab(ne)(1) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=1;
//          ne = 2; tab(ne)(2) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=2;
//          ne = 3; tab(ne)(3) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=3;
//          ne = 4; tab(ne)(7) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=7;
//          ne = 5; tab(ne)(8) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=8;
//          ne = 6; tab(ne)(9) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=9;
//          // pour les noeuds intermédiaires on moyenne les pt d'integ de part et autre
//          ne = 7; tab(ne)(1) = 0.5;tab(ne)(2) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=1;indir(ne)(2)=2;
//          ne = 8; tab(ne)(2) = 0.5;tab(ne)(3) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=2;indir(ne)(2)=3;
//          ne = 9; tab(ne)(1) = 0.5;tab(ne)(3) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=1;indir(ne)(2)=3;
//          ne = 10; tab(ne)(4) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=4;
//          ne = 11; tab(ne)(5) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=5;
//          ne = 12; tab(ne)(6) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=6;
//          ne = 13; tab(ne)(7) = 0.5;tab(ne)(8) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=7;indir(ne)(2)=8;
//          ne = 14; tab(ne)(8) = 0.5;tab(ne)(9) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=8;indir(ne)(2)=9;
//          ne = 15; tab(ne)(9) = 0.5;tab(ne)(7) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=9;indir(ne)(2)=7;
//
//          ne = 16; tab(ne)(4) = 0.5;tab(ne)(5) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=4;indir(ne)(2)=5;
//          ne = 17;tab(ne)(5) = 0.5;tab(ne)(6) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=5;indir(ne)(2)=6;
//          ne = 18;tab(ne)(6) = 0.5;tab(ne)(4) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=6;indir(ne)(2)=4;
          break;  
   	 	}  // fin du cas avec 9 pt d'intégration
     case 12: // 3 * 4 pt de surface de  bas  en haut
      {// rappel des pti pour une nappe triangle
       //  4 pti
       //                 (3)
       //                 | \
       //                 |  \
       //                 | 4  \   <- face 5 basse (2) -> (label 4)
       //                 |     \            hautes (2) -> (label 8)
       // face 2 basse->  |       \   <- face 5
       //   (label 1)     |      1 \
       //                 |          \
       // face 2 haute->  |           \  <- face 5 basse (1) -> (label 3)
       //    (label 5)    | 2        3  \          haute (1) -> (label 7)
       //                 |______________\
       //                (1)             (2)
       //                        ^
       //                        |
       //           face 3 basse (label 2), haute (label 6)

       // tab est supposé être initialisé à 0.
       Tableau <Coordonnee>  gi_B,gi_H; // bases naturelle et duale
       {Tableau<Tableau<int> > & indir = extrapol(1).indir;  // pour simplifier
        Tableau<Tableau<double > > & tab = extrapol(1).tab;    // pour simplifier
        tab.Change_taille(NBNE);indir.Change_taille(NBNE);

        // on va utiliser un pentaèdre linéaire particulier par face verticale de l'élément
        for (int ilabel = 1; ilabel <=8; ilabel++) // correspond aux 8 labels de l'élément
         {// pour chaque label on définit les sommets du pentaèdre linéaire
          Tableau <int> indirect(6); // pti concernés
          int nbn_concernes;

          Tableau <int> J(9); // les noeuds concernés

          switch (ilabel)
            {case 1: // sur la face 2 basse
                     {indirect(1)=4;indirect(2)=2;indirect(3)=1;
                      indirect(4)=8;indirect(5)=6;indirect(6)=5;
                      nbn_concernes = 6;
                      J(1)=1;  J(2)=10;  J(3)=12;  J(4)=3;
                      J(5)=9;J(6)=18;
                      break;
                     }
             case 2: // sur la face 3 basse
                     {indirect(1)=1;indirect(2)=2;indirect(3)=3;
                      indirect(4)=5;indirect(5)=6;indirect(6)=7;
                      nbn_concernes = 4;
                      J(1)=7;  J(2)=2;  J(3)=11;J(4)=16;
                      break;
                     }
             case 3: // face 5 basse (1) -> (label 3)
                     {indirect(1)=1;indirect(2)=2;indirect(3)=3;
                      indirect(4)=5;indirect(5)=6;indirect(6)=7;
                      nbn_concernes = 2;
                      J(1)=8;J(2)=17;
                      break;
                        }
             case 4: // face 5 basse (2) -> (label 4) : ne reste aucun noeud
                     {nbn_concernes = 0;
                      break;
                     }
             case 5: // sur la face 2 haute
                     {indirect(1)=8;indirect(2)=6;indirect(3)=5;
                      indirect(4)=12;indirect(5)=10;indirect(6)=9;
                      nbn_concernes = 3;
                      J(1)=4;  J(2)=15;  J(3)=6;
                      break;
                     }
             case 6: // sur la face 3 basse
                     {indirect(1)=5;indirect(2)=6;indirect(3)=7;
                      indirect(4)=9;indirect(5)=10;indirect(6)=11;
                      nbn_concernes = 2;
                      J(1)=13;  J(2)=5;
                      break;
                     }
             case 7: // face 5 haute (1)
                     {indirect(1)=5;indirect(2)=6;indirect(3)=7;
                      indirect(4)=9;indirect(5)=10;indirect(6)=11;
                      nbn_concernes = 1;
                      J(1)=14;
                      break;
                     }
             case 8: // il ne reste aucun noeud
                     {nbn_concernes = 0;
                      break;
                     }
             default:
                break;
               };
             // on traite tous les noeuds de la même manière
             for (int ine = 1;ine<= nbn_concernes; ine++)
                {int ne = J(ine);
                 // il nous faut calculer les coordonnées locales du noeud
                 // sachant que les pti ici considérés, sont aux sommets d'un pentaèdre linéaire orthogonal
                 // on peut traiter séparément les coordonnées dans le plan et la coordonnée z

                 Coordonnee theta(3); // les coordonnées que l'on cherche
                 
                 // suivant x et y: calcul de theta^alpha
                 {Tableau <int> indirect_local(3); // tableau de travail
                  // on considère le triangle des 3 premiers pti
                  indirect_local(1) = indirect(1);indirect_local(2) = indirect(2);
                  indirect_local(3) = indirect(3);
                  Coordonnee theta_loc(2); // le conteneur pour les coordonnées locales en x y
                  Tableau <Coordonnee>  gi_loc_B,gi_loc_H; // bases naturelle et duale
                  Bases_naturel_duales(indirect_local,gi_loc_B,gi_loc_H);
                  Coordonnee O(ptInteg(indirect(1))); //
                  Vecteur phi_xy(3); // le conteneur pour les fonctions
                  ElemGeomC0::Coor_phi(O,gi_loc_H,ptelem(ne),phi_xy,theta_loc);
                  theta(1)=theta_loc(1); // on enregistre
                  theta(2)=theta_loc(2); // on enregistre
                 }
                 
                 // suivant z: calcul de theta^3
                 {Tableau <int> indirect_local(2); // tableau de travail
                  // on considère la ligne du pti 1 -> pti 4
                  indirect_local(1) = indirect(1);indirect_local(2) = indirect(4);
                  Coordonnee theta_loc(1); // le conteneur pour les coordonnées locales
                  Tableau <Coordonnee>  gi_loc_B,gi_loc_H; // bases naturelle et duale
                  Bases_naturel_duales(indirect_local,gi_loc_B,gi_loc_H);
                  Coordonnee O(0.5*(ptInteg(indirect(1))+ptInteg(indirect(2)))); //
                  Vecteur phi_z(2); // le conteneur pour les fonctions d'interpolation
                  ElemGeomC0::Coor_phi(O,gi_loc_H,ptelem(ne),phi_z,theta_loc);
                  theta(3)=theta_loc(1); // on enregistre
                 }
                  
                 // maintenant on va attribuer au noeud la valeur extrapolée
                 // on calcule les fct d'interpolation au noeud ne
                 // via ses coordonnées locales theta: on utilise le pentaèdre linéaire
                 const Vecteur& phiphi = penta.Phi_point(theta);
                 // et on enregistre
                 indir(ne).Change_taille(nbi);
                 tab(ne).Change_taille(nbi);
                 // on boucle sur les pti du pentaèdre linéaire d'interpolation
                 for (int i=1;i<7;i++)
                  {tab(ne)(indirect(i))=phiphi(i);
                   indir(ne)(i)=indirect(i);
                  };
                };
            };
          };

         // --- ancienne méthode
//         // on utilise systématiquement le pt d'integ le plus proche
//   	   {  int ne = 1; tab(ne)(2) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=2;
//          ne = 2; tab(ne)(3) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=3;
//          ne = 3; tab(ne)(4) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=4;
//          ne = 4; tab(ne)(10) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=10;
//          ne = 5; tab(ne)(11) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=11;
//          ne = 6; tab(ne)(12) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=12;
//          // pour les noeuds intermédiaires on moyenne les pt d'integ de part et autre
//          ne = 7; tab(ne)(2) = 0.5;tab(ne)(3) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=2;indir(ne)(2)=3;
//          ne = 8; tab(ne)(3) = 0.5;tab(ne)(4) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=3;indir(ne)(2)=4;
//          ne = 9; tab(ne)(2) = 0.5;tab(ne)(4) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=2;indir(ne)(2)=4;
//          ne = 10; tab(ne)(6) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=6;
//          ne = 11; tab(ne)(7) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=7;
//          ne = 12; tab(ne)(8) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=8;
//          ne = 13; tab(ne)(10) = 0.5;tab(ne)(11) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=10;indir(ne)(2)=11;
//          ne = 14; tab(ne)(11) = 0.5;tab(ne)(12) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=11;indir(ne)(2)=12;
//          ne = 15; tab(ne)(12) = 0.5;tab(ne)(10) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=12;indir(ne)(2)=10;
//
//          ne = 16; tab(ne)(6) = 0.5;tab(ne)(7) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=6;indir(ne)(2)=7;
//          ne = 17;tab(ne)(7) = 0.5;tab(ne)(8) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=7;indir(ne)(2)=8;
//          ne = 18;tab(ne)(8) = 0.5;tab(ne)(6) = 0.5;
//          indir(ne).Change_taille(2); indir(ne)(1)=8;indir(ne)(2)=6;
          
          break;  
   	 	}  // fin du cas avec 12 pt d'intégration
     case 18: // 3 * 6 pt de surface de  bas  en haut
      {// rappel des pti pour une nappe triangle
       //  6 pti
       //
       //                 (3)
       //                 | \
       //                 |  \
       // face 2 basse->  | 6  \  <- face 5 basse droite -> (label 6)
       //   gauche (1)    |     \           hautes droite -> (label 12)
       //   droite (2)    |       \  <- face 5
       // face 2 haute->  |  2   1  \
       //   gauche (7)    |          \
       //   droite (8)    |           \  <- face 5 basse gauche -> (label 5)
       //                 | 4    3    5 \          haute gauche -> (label 11)
       //                 |______________\
       //                (1)             (2)
       //                   ^        ^
       //                   |        |
       // face 3 basse  gauche(3) droite (4)
       //        haute  gauche(9) droite (10)

        // tab est supposé être initialisé à 0.
        Tableau <Coordonnee>  gi_B,gi_H; // bases naturelle et duale
        {Tableau<Tableau<int> > & indir = extrapol(1).indir;  // pour simplifier
         Tableau<Tableau<double > > & tab = extrapol(1).tab;    // pour simplifier
         tab.Change_taille(NBNE);indir.Change_taille(NBNE);

         // on va utiliser un pentaèdre linéaire particulier par face verticale de l'élément
         for (int ilabel = 1; ilabel <=12; ilabel++) // correspond aux 12 labels de l'élément
          {// pour chaque label on définit les sommets du pentaèdre linéaire
           Tableau <int> indirect(6); // pti concernés
           int nbn_concernes;

           Tableau <int> J(9); // les noeuds concernés

           switch (ilabel)
             {case 1: // sur la face 2 basse gauche
                      {indirect(1)=2;indirect(2)=1;indirect(3)=6;
                       indirect(4)=8;indirect(5)=7;indirect(6)=12;
                       nbn_concernes = 4;
                       J(1)=9;  J(2)=3;  J(3)=12;J(4)=18;
                       break;
                      }
              case 2: // sur la face 2 basse droite
                      {indirect(1)=2;indirect(2)=4;indirect(3)=3;
                       indirect(4)=8;indirect(5)=10;indirect(6)=9;
                       nbn_concernes = 2;
                       J(1)=1;  J(2)=10;
                       break;
                      }
              case 3: // face 3 basse gauche
                      {indirect(1)=2;indirect(2)=4;indirect(3)=3;
                       indirect(4)=8;indirect(5)=10;indirect(6)=9;
                       nbn_concernes = 2;
                       J(1)=7;J(2)=16;
                       break;
                      }
              case 4: // face 3 basse droite
                      {indirect(1)=1;indirect(2)=3;indirect(3)=5;
                       indirect(4)=7;indirect(5)=9;indirect(6)=11;
                       nbn_concernes = 2;
                       J(1)=2; J(2) = 11;
                       break;
                      }
              case 5: // face 5 basse gauche
                      {indirect(1)=1;indirect(2)=3;indirect(3)=5;
                       indirect(4)=7;indirect(5)=9;indirect(6)=11;
                       nbn_concernes = 2;
                       J(1)=8;J(2) = 17;
                       break;
                      }
              case 6: // face 5 basse droite
                      {indirect(1)=2;indirect(2)=1;indirect(3)=6;
                       indirect(4)=8;indirect(5)=7;indirect(6)=12;
                       nbn_concernes = 0;
                       break;
                      }
              case 7: // face 2 haute gauche
                      {indirect(1)=8;indirect(2)=7;indirect(3)=12;
                       indirect(4)=14;indirect(5)=13;indirect(6)=18;
                       nbn_concernes = 2;
                       J(1)=6; J(2)=15;
                       break;
                      }
              case 8: // face 2 haute droite
                      {indirect(1)=8;indirect(2)=10;indirect(3)=9;
                       indirect(4)=14;indirect(5)=16;indirect(6)=15;
                       nbn_concernes = 1;
                       J(1)=4;
                       break;
                      }
              case 9: // face 3 haute gauche
                      {indirect(1)=8;indirect(2)=10;indirect(3)=9;
                       indirect(4)=14;indirect(5)=16;indirect(6)=15;
                       nbn_concernes = 1;
                       J(1)=13;
                       break;
                      }
              case 10: // face 3 haute droite
                      {indirect(1)=7;indirect(2)=9;indirect(3)=11;
                       indirect(4)=13;indirect(5)=15;indirect(6)=17;
                       nbn_concernes = 1;
                       J(1)=5;
                       break;
                      
              case 11: // face 5 haute gauche
                      {indirect(1)=8;indirect(2)=10;indirect(3)=9;
                       indirect(4)=14;indirect(5)=16;indirect(6)=15;
                       nbn_concernes = 1;
                       J(1)=14;
                       break;
                      }
              case 12: // face 5 haute droite
                      {nbn_concernes = 0;
                       break;
                      }
              default:
                 break;
             };
           // on traite tous les noeuds de la même manière
           for (int ine = 1;ine<= nbn_concernes; ine++)
              {int ne = J(ine);
               // il nous faut calculer les coordonnées locales du noeud
               // sachant que les pti ici considérés, sont aux sommets d'un pentaèdre linéaire orthogonal
               // on peut traiter séparément les coordonnées dans le plan et la coordonnée
               Coordonnee theta(3); // les coordonnées que l'on cherche
               
               // suivant x et y: calcul de theta^alpha
               {Tableau <int> indirect_local(3); // tableau de travail
                // on considère le triangle des 3 premiers pti
                indirect_local(1) = indirect(1);indirect_local(2) = indirect(2);
                indirect_local(3) = indirect(3);
                Coordonnee theta_loc(2); // le conteneur pour les coordonnées locales en x y
                Tableau <Coordonnee>  gi_loc_B,gi_loc_H; // bases naturelle et duale
                Bases_naturel_duales(indirect_local,gi_loc_B,gi_loc_H);
                Coordonnee O(ptInteg(indirect(1))); //
                Vecteur phi_xy(3); // le conteneur pour les fonctions
                ElemGeomC0::Coor_phi(O,gi_loc_H,ptelem(ne),phi_xy,theta_loc);
                theta(1)=theta_loc(1); // on enregistre
                theta(2)=theta_loc(2); // on enregistre
               }
               
               // suivant z: calcul de theta^3
               {Tableau <int> indirect_local(2); // tableau de travail
                // on considère la ligne du pti 1 -> pti 4
                indirect_local(1) = indirect(1);indirect_local(2) = indirect(4);
                Coordonnee theta_loc(1); // le conteneur pour les coordonnées locales
                Tableau <Coordonnee>  gi_loc_B,gi_loc_H; // bases naturelle et duale
                Bases_naturel_duales(indirect_local,gi_loc_B,gi_loc_H);
                Coordonnee O(0.5*(ptInteg(indirect(1))+ptInteg(indirect(2)))); //
                Vecteur phi_z(2); // le conteneur pour les fonctions d'interpolation
                ElemGeomC0::Coor_phi(O,gi_loc_H,ptelem(ne),phi_z,theta_loc);
                theta(3)=theta_loc(1); // on enregistre
               }
                
               // maintenant on va attribuer au noeud la valeur extrapolée
               // on calcule les fct d'interpolation au noeud ne
               // via ses coordonnées locales theta: on utilise le pentaèdre linéaire
               const Vecteur& phiphi = penta.Phi_point(theta);
               // et on enregistre
               indir(ne).Change_taille(nbi);
               tab(ne).Change_taille(nbi);
               // on boucle sur les pti du pentaèdre linéaire d'interpolation
               for (int i=1;i<7;i++)
                {tab(ne)(indirect(i))=phiphi(i);
                 indir(ne)(i)=indirect(i);
                };
              };
          };
          };
        };

          // --- ancienne méthode
//         // on utilise systématiquement le pt d'integ le plus proche
//   	   {  int ne = 1; tab(ne)(4) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=4;
//          ne = 2; tab(ne)(5) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=5;
//          ne = 3; tab(ne)(6) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=6;
//          ne = 4; tab(ne)(16) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=16;
//          ne = 5; tab(ne)(17) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=17;
//          ne = 6; tab(ne)(18) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=18;
//          ne = 7; tab(ne)(3) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=3;
//          ne = 8; tab(ne)(1) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=1;
//          ne = 9; tab(ne)(2) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=2;
//          ne = 10; tab(ne)(10) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=10;
//          ne = 11; tab(ne)(11) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=11;
//          ne = 12; tab(ne)(12) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=12;
//          ne = 13; tab(ne)(15) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=15;
//          ne = 14; tab(ne)(13) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=13;
//          ne = 15; tab(ne)(14) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=14;
//
//          ne = 16; tab(ne)(9) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=9;
//          ne = 17; tab(ne)(7) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=7;
//          ne = 18; tab(ne)(8) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=8;
          
          break;  
   	 	}  // fin du cas avec 18 pt d'intégration
          
     default:
       { cout << "\n erreur le nombre de point d'integration demande :" << nbi <<"n\'est pas implante "
              << "\nGeomTriangle::Calcul_extrapol(..";
         Sortie(1);
       };
   };

}; 
        
  
       
  
 
  
  
  




  



