
// 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 "GeomQuadrangle.h"
#include "GeomSeg.h"
#include <math.h>
#include "MathUtil.h"

// constructeur
// dimension 2, nbi pt integ, nbne noeuds, 1 face, 4 aretes
// sans_extrapole : cas particulier pour lequel on ne construit pas le
// tableau d'extrapolation: nécessaire pour justement définir ce tableau pour
// des éléments particuliers (ex: hexaèdre) en évitant une boucle récurcive
// via l'utilisation de sous-éléments particuliers (quadrangle, hexaèdre etc.)
GeomQuadrangle::GeomQuadrangle(int nbi, int nbne,int sans_extrapole) :
     ElemGeomC0(2,nbi,nbne,1,4,QUADRANGLE,RIEN_INTERPOL) 
    ,phi_M(),dphi_M()
  {  // definition de la face
     face(1) = this;
     NONF(1).Change_taille(NBNE);
     for (int i=1;i<=NBNE;i++)
        NONF(1)(i) = i;
     // définition de la numérotation locale de l'élément de direction inverse
     switch  (NBNE)
        { case 4: 
            { INVCONNEC(1) = 1;INVCONNEC(2) = 4;
              INVCONNEC(3) = 3;INVCONNEC(4) = 2;
				  // le tableau des tranches
				  IND.Change_taille(1); IND(1)=4;	
              break;
             }  
          case 8: 
             { INVCONNEC(1) = 1;INVCONNEC(2) = 4; INVCONNEC(3) = 3;INVCONNEC(4) = 2;
               INVCONNEC(5) = 8;INVCONNEC(6) = 7; INVCONNEC(7) = 6;INVCONNEC(8) = 5;
//             { INVCONNEC(1) = 2;INVCONNEC(2) = 1; INVCONNEC(3) = 4;INVCONNEC(4) = 3;
//               INVCONNEC(5) = 5;INVCONNEC(6) = 8; INVCONNEC(7) = 7;INVCONNEC(8) = 6;
				   // le tableau des tranches
				   IND.Change_taille(2); IND(1)=4;IND(2)=4;	
               break;
              }  
         case 9: 
             { INVCONNEC(1) = 1;INVCONNEC(2) = 4; INVCONNEC(3) = 3;INVCONNEC(4) = 2;
               INVCONNEC(5) = 8;INVCONNEC(6) = 7; INVCONNEC(7) = 6;INVCONNEC(8) = 5;
//             { INVCONNEC(1) = 2;INVCONNEC(2) = 1; INVCONNEC(3) = 4;INVCONNEC(4) = 3;
//               INVCONNEC(5) = 5;INVCONNEC(6) = 8; INVCONNEC(7) = 7;INVCONNEC(8) = 6;
               INVCONNEC(9) = 9;
				   // le tableau des tranches
				   IND.Change_taille(3); IND(1)=4;IND(2)=4;IND(3)=1;	
               break;
              }  
          case 6: 
             { INVCONNEC(1) = 2;INVCONNEC(2) = 1; INVCONNEC(3) = 4;INVCONNEC(4) = 3;
               INVCONNEC(5) = 5;INVCONNEC(6) = 6; 
				   // le tableau des tranches
				   IND.Change_taille(2); IND(1)=4;IND(2)=2;	
               break;
              }  
         case 16: 
             { INVCONNEC(1)  = 1; INVCONNEC(2)  = 4;  INVCONNEC(3)  = 3; INVCONNEC(4)  = 2;
               INVCONNEC(5)  = 12;INVCONNEC(6)  = 11; INVCONNEC(7)  = 10;INVCONNEC(8)  = 9;
               INVCONNEC(9)  = 8; INVCONNEC(10) = 7;  INVCONNEC(11) = 6; INVCONNEC(12) = 5;
               INVCONNEC(13) = 13;INVCONNEC(14) = 16; INVCONNEC(15) = 15;INVCONNEC(16) = 14;
				   // le tableau des tranches
				   IND.Change_taille(3); IND(1)=4;IND(2)=8;IND(3)=4;	
              break;
              }  
		  default :
            { cout << "\n erreur le nombre de noeud demande :" << NBNE <<" n\'est"
                   << " pas implante "
                   << "\nGeomQuadrangle::GeomQuadrangle(int nbi, int nbne)";
              Sortie(1);
             }
        }     
     //------------------------------------------------------
     //cas des points d'integration
     //------------------------------------------------------
     if  ((Nbi() == 1) || (Nbi() == 4) || (Nbi() == 9) || (Nbi() == 16))
      {  // definition des cotes
         int nbil = (int) sqrt((double)Nbi());
         // on met 2 noeuds par défaut au lieu de sqrt(nbne) , mais cela n'a pas d'importance pour
         // le calcul des points et poids d'intégration
         GeomSeg b(nbil,2);
         // definition des points et des poids
         int ni = 1;
         for (int niy = 1; niy<= nbil; niy++)
            for (int nix = 1; nix<= nbil; nix++)
              { WI(ni) = b.Wi(nix) * b.Wi(niy);
                ptInteg(ni) =
                     Coordonnee(b.CoorPtInteg(nix)(1),b.CoorPtInteg(niy)(1));
                ni++;
               }
       }
     else
       {cout << "\n erreur le quadrangle de nombre de  point d\'integration " << Nbi() 
             << " n\'est pas implante !! ";
        cout << "\nGeomQuadrangle::GeomQuadrangle(int nbi, int nbne) " << endl;     
        Sortie(1);
        }
       
      //
     //-------------------------------------------------------------
     //cas d'un quadrangle bilineaire ou quadratique/cubique complet
     //-------------------------------------------------------------
     if ( ((NBNE == 4) || (NBNE == 9)|| (NBNE == 16))     && 
         ((Nbi() == 1) || (Nbi() == 4) || (Nbi() == 9) || (Nbi() == 16)) )
      {  // definition des cotes
         int nbil = (int) sqrt((double)Nbi()); // point d'integration par cote
         int nbnes;  // nombre de noeud par cote
         if (NBNE == 4) nbnes = 2; 
         else if (NBNE == 9) nbnes = 3;
         else nbnes = 4;
         seg(1) = new GeomSeg(nbil,nbnes);
         for (int il=2;il<= 4; il++)
           seg(il) = seg(1);
         // def des tableaux de connection des noeuds  des cotes
         if (NBNE == 4)
           { for (int i =1;i<=4;i++) NONS(i).Change_taille(2);
             NONS(1)(1) = 1;NONS(1)(2) = 2;NONS(2)(1) = 2;NONS(2)(2) = 3;
             NONS(3)(1) = 3;NONS(3)(2) = 4;NONS(4)(1) = 4;NONS(4)(2) = 1;
            }   
         else if (NBNE == 9)
           { for (int i =1;i<=4;i++) NONS(i).Change_taille(3);
             NONS(1)(1) = 1;NONS(1)(2) = 5;NONS(1)(3) = 2;
             NONS(2)(1) = 2;NONS(2)(2) = 6;NONS(2)(3) = 3;
             NONS(3)(1) = 3;NONS(3)(2) = 7;NONS(3)(3) = 4;
             NONS(4)(1) = 4;NONS(4)(2) = 8;NONS(4)(3) = 1;
            }   
         else if (NBNE == 16)
           { for (int i =1;i<=4;i++) NONS(i).Change_taille(4);
             NONS(1)(1) = 1;NONS(1)(2) = 5;NONS(1)(3) = 6;NONS(1)(4) = 2;
             NONS(2)(1) = 2;NONS(2)(2) = 7;NONS(2)(3) = 8;NONS(2)(4) = 3;
             NONS(3)(1) = 3;NONS(3)(2) = 9;NONS(3)(3) = 10;NONS(3)(4) = 4;
             NONS(4)(1) = 4;NONS(4)(2) = 11;NONS(4)(3) = 12;NONS(4)(4) = 1;
            }   
           
         //  des fonctions d'interpolation, et des derivees
         int ne = 1;
         Tableau <Vecteur> tabPhiT(tabPhi);
         Tableau < Mat_pleine > tabDPhiT(tabDPhi);
         for (int iy = 1;iy<= nbnes; iy++)
           for (int ix =1;ix<=nbnes;ix++)
            { int ni = 1;
              for (int niy = 1; niy<= nbil; niy++)
                for (int nix = 1; nix<= nbil; nix++)
                  { tabPhiT(ni)(ne) = (seg(1)->Phi(nix))(ix) * seg(1)->Phi(niy)(iy);
                    tabDPhiT(ni)(1,ne) = seg(1)->Dphi(nix)(1,ix) * seg(1)->Phi(niy)(iy);
                    tabDPhiT(ni)(2,ne) = seg(1)->Phi(nix)(ix) * seg(1)->Dphi(niy)(1,iy);
                    ni++;
                   }
               ne++;
             } 
         // numerotation suivant le standard habituel
         Tableau<int> ind;
         if (nbnes == 2)  // cas bilineaire
          {id_interpol=LINEAIRE;
           for (int ni=1;ni<=Nbi();ni++)
            { //cout << "\nni = " << ni;
              ind.Change_taille(4);
              ind(1) = 1; ind(2) = 2; ind(3) = 4; ind(4) = 3;
              for (int ne = 1; ne<= 4; ne++)
               { for (int ii=1;ii<=2;ii++)
                   {tabDPhi(ni)(ii,ne) = tabDPhiT(ni)(ii,ind(ne));
                    //cout << "tph(" << ii << "," << ne << ")=" << tabDPhi(ni)(ii,ne);
                    }
                 //cout << "\n";   
                 tabPhi(ni)(ne) = tabPhiT(ni)(ind(ne));
                }
             }
           } 
         else if (nbnes == 3)  // cas quadratique complet
          {id_interpol=QUADRACOMPL;     
           for (int ni=1;ni<=Nbi();ni++)
            { ind.Change_taille(9);
              ind(1) = 1; ind(2) = 3; ind(3) = 9; ind(4) = 7;ind(5) = 2;
              ind(6) = 6; ind(7) = 8; ind(8) = 4; ind(9) = 5;
              for (int ne = 1; ne<= 9; ne++)
               { for (int ii=1;ii<=2;ii++)
                   tabDPhi(ni)(ii,ne) = tabDPhiT(ni)(ii,ind(ne));
                 tabPhi(ni)(ne) = tabPhiT(ni)(ind(ne));
                }
             }
            } 
         else if (nbnes == 4)  // cas cubique complet
          {id_interpol=CUBIQUE;     
           for (int ni=1;ni<=Nbi();ni++)
            { ind.Change_taille(16);
              ind(1) = 1; ind(2) = 4; ind(3) = 16; ind(4) = 13;ind(5) = 2;
              ind(6) = 3; ind(7) = 8; ind(8) = 12; ind(9) = 15;
              ind(10) = 14; ind(11) = 9; ind(12) = 5; ind(13) = 6;
              ind(14) = 7; ind(15) = 11; ind(16) = 10; 
              for (int ne = 1; ne<= 16; ne++)
               { for (int ii=1;ii<=2;ii++)
                   tabDPhi(ni)(ii,ne) = tabDPhiT(ni)(ii,ind(ne));
                 tabPhi(ni)(ne) = tabPhiT(ni)(ind(ne));
                }
             }
            } 
        //  définition des coordonnées des noeuds
        //  et de la triangulation
         if (NBNE == 4)
          { ptelem(1) = Coordonnee(-1.,-1.);
            ptelem(2) = Coordonnee(1.,-1.);
            ptelem(3) = Coordonnee(1.,1.);
            ptelem(4) = Coordonnee(-1.,1.);
            // triangulation de la face
            NONFt(1).Change_taille(2); // 2 face linéaires pour la face quadrangle
           // trois noeuds pour chaque triangle linéaire
           for (int ikt=1;ikt<=2;ikt++)   
             NONFt(1)(ikt).Change_taille(3);
           // remplissage de la connexion par rapport à celle de l'élément
           NONFt(1)(1)(1) = 1; NONFt(1)(1)(2) = 2; NONFt(1)(1)(3) = 3; 
           NONFt(1)(2)(1) = 1; NONFt(1)(2)(2) = 3; NONFt(1)(2)(3) = 4; 
           }   
         else if (NBNE == 9)// NBE=9
          { ptelem(1) = Coordonnee(-1.,-1.);
            ptelem(2) = Coordonnee(1.,-1.);
            ptelem(3) = Coordonnee(1.,1.);
            ptelem(4) = Coordonnee(-1.,1.);
            ptelem(5) = Coordonnee(0,-1.);
            ptelem(6) = Coordonnee(1.,0);
            ptelem(7) = Coordonnee(0.,1.);
            ptelem(8) = Coordonnee(-1.,0.);
            ptelem(9) = Coordonnee(0,0.);
            // triangulation de la face
            NONFt(1).Change_taille(8); // 8 face linéaires pour la face quadrangle
            // trois noeuds pour chaque triangle linéaire
            for (int ikt=1;ikt<=8;ikt++)   
               NONFt(1)(ikt).Change_taille(3);
            // remplissage de la connexion par rapport à celle de l'élément
            NONFt(1)(1)(1) = 8; NONFt(1)(1)(2) = 5; NONFt(1)(1)(3) = 9; 
            NONFt(1)(2)(1) = 5; NONFt(1)(2)(2) = 6; NONFt(1)(2)(3) = 9; 
            NONFt(1)(3)(1) = 9; NONFt(1)(3)(2) = 6; NONFt(1)(3)(3) = 7; 
            NONFt(1)(4)(1) = 8; NONFt(1)(4)(2) = 9; NONFt(1)(4)(3) = 7; 
            NONFt(1)(5)(1) = 1; NONFt(1)(5)(2) = 5; NONFt(1)(5)(3) = 8; 
            NONFt(1)(6)(1) = 5; NONFt(1)(6)(2) = 2; NONFt(1)(6)(3) = 6; 
            NONFt(1)(7)(1) = 6; NONFt(1)(7)(2) = 3; NONFt(1)(7)(3) = 7; 
            NONFt(1)(8)(1) = 8; NONFt(1)(8)(2) = 7; NONFt(1)(8)(3) = 4; 
          }   
         else if (NBNE == 16)// NBE=16
          { double a = 2./3.;
            ptelem(1) = Coordonnee(-1.,-1.);
            ptelem(2) = Coordonnee(1.,-1.);
            ptelem(3) = Coordonnee(1.,1.);
            ptelem(4) = Coordonnee(-1.,1.);
            ptelem(5) = Coordonnee(-a,-1.);
            ptelem(6) = Coordonnee(a,-1.);
            ptelem(7) = Coordonnee(1.,-a);
            ptelem(8) = Coordonnee(1.,a);
            ptelem(9) = Coordonnee(a,1.);
            ptelem(10) = Coordonnee(-a,1.);
            ptelem(11) = Coordonnee(-1.,a);
            ptelem(12) = Coordonnee(-1.,-a);
            ptelem(13) = Coordonnee(-a,-a);
            ptelem(14) = Coordonnee(a,-a);
            ptelem(15) = Coordonnee(a,a);
            ptelem(16) = Coordonnee(-a,a);
            // triangulation de la face
            NONFt(1).Change_taille(18); // 18 faces linéaires pour la face quadrangle
            // trois noeuds pour chaque triangle linéaire
            for (int ikt=1;ikt<=18;ikt++)   
               NONFt(1)(ikt).Change_taille(3);
            // remplissage de la connexion par rapport à celle de l'élément
            NONFt(1)(1)(1) = 1; NONFt(1)(1)(2) = 5; NONFt(1)(1)(3) = 12; 
            NONFt(1)(2)(1) = 5; NONFt(1)(2)(2) = 13; NONFt(1)(2)(3) = 12; 
            NONFt(1)(3)(1) = 5; NONFt(1)(3)(2) = 6; NONFt(1)(3)(3) = 13; 
            NONFt(1)(4)(1) = 6; NONFt(1)(4)(2) = 14; NONFt(1)(4)(3) = 13; 
            NONFt(1)(5)(1) = 6; NONFt(1)(5)(2) = 2; NONFt(1)(5)(3) = 14; 
            NONFt(1)(6)(1) = 2; NONFt(1)(6)(2) = 7; NONFt(1)(6)(3) = 14; 
            NONFt(1)(7)(1) = 12; NONFt(1)(7)(2) = 13; NONFt(1)(7)(3) = 11; 
            NONFt(1)(8)(1) = 13; NONFt(1)(8)(2) = 16; NONFt(1)(8)(3) = 11; 
            NONFt(1)(9)(1) = 13; NONFt(1)(9)(2) = 14; NONFt(1)(9)(3) = 16; 
            NONFt(1)(10)(1) = 14; NONFt(1)(10)(2) = 15; NONFt(1)(10)(3) = 16; 
            NONFt(1)(11)(1) = 14; NONFt(1)(11)(2) = 7; NONFt(1)(11)(3) = 15; 
            NONFt(1)(12)(1) = 7; NONFt(1)(12)(2) = 8; NONFt(1)(12)(3) = 15; 
            NONFt(1)(13)(1) = 11; NONFt(1)(13)(2) = 16; NONFt(1)(13)(3) = 4; 
            NONFt(1)(14)(1) = 16; NONFt(1)(14)(2) = 10; NONFt(1)(14)(3) = 4; 
            NONFt(1)(15)(1) = 16; NONFt(1)(15)(2) = 15; NONFt(1)(15)(3) = 10; 
            NONFt(1)(16)(1) = 15; NONFt(1)(16)(2) = 9; NONFt(1)(16)(3) = 10; 
            NONFt(1)(17)(1) = 15; NONFt(1)(17)(2) = 8; NONFt(1)(17)(3) = 9; 
            NONFt(1)(18)(1) = 8; NONFt(1)(18)(2) = 3; NONFt(1)(18)(3) = 9; 
          }   
          
       }  
     //------------------------------------------------------
     // cas d'un quadrangle quadratique incomplet 8 noeuds
     //------------------------------------------------------
     else if ( (NBNE == 8)     && 
         ((Nbi() == 1) || (Nbi() == 4) || (Nbi() == 9) || (Nbi() == 16)) )
      {  id_interpol=QUADRATIQUE;
         // definition des cotes, qui sont quadratiques
         int nbil =  (int) sqrt((double)Nbi());
         int nbnes = 3; 
         seg(1) = new GeomSeg(nbil,nbnes);
         for (int il=2;il<= 4; il++)
           seg(il) = seg(1);
         // def des tableaux de connection des noeuds des faces et des noeuds des cotes
         for (int i =1;i<=4;i++) NONS(i).Change_taille(3);
         NONS(1)(1) = 1;NONS(1)(2) = 5;NONS(1)(3) = 2;
         NONS(2)(1) = 2;NONS(2)(2) = 6;NONS(2)(3) = 3;
         NONS(3)(1) = 3;NONS(3)(2) = 7;NONS(3)(3) = 4;
         NONS(4)(1) = 4;NONS(4)(2) = 8;NONS(4)(3) = 1;
         // triangulation de la face
         NONFt(1).Change_taille(6); // 6 face linéaires pour la face quadrangle
           // trois noeuds pour chaque triangle linéaire
         for (int ikt=1;ikt<=6;ikt++)   
           NONFt(1)(ikt).Change_taille(3);
           // remplissage de la connexion par rapport à celle de l'élément
         NONFt(1)(1)(1) = 1; NONFt(1)(1)(2) = 5; NONFt(1)(1)(3) = 8; 
         NONFt(1)(2)(1) = 8; NONFt(1)(2)(2) = 5; NONFt(1)(2)(3) = 6; 
         NONFt(1)(3)(1) = 5; NONFt(1)(3)(2) = 2; NONFt(1)(3)(3) = 6; 
         NONFt(1)(4)(1) = 6; NONFt(1)(4)(2) = 3; NONFt(1)(4)(3) = 7; 
         NONFt(1)(5)(1) = 8; NONFt(1)(5)(2) = 6; NONFt(1)(5)(3) = 7; 
         NONFt(1)(6)(1) = 8; NONFt(1)(6)(2) = 7; NONFt(1)(6)(3) = 4; 
         //  définition des coordonnées des noeuds
         ptelem(1) = Coordonnee(-1.,-1.);
         ptelem(2) = Coordonnee(1.,-1.);
         ptelem(3) = Coordonnee(1.,1.);
         ptelem(4) = Coordonnee(-1.,1.);
         ptelem(5) = Coordonnee(0,-1.);
         ptelem(6) = Coordonnee(1.,0);
         ptelem(7) = Coordonnee(0.,1.);
         ptelem(8) = Coordonnee(-1.,0.);
         // definition des points , des fonctions d'interpolation, et des derivees
         double C= 0.25;
         double D= 0.5;
         GeomSeg & a = *((GeomSeg*) seg(1));  // pour commodite
         int ni = 1;
//         for (int NI1=1;NI1<=nbil;NI1++)
//         { double P1= 1.+a.KSI(NI1);
//           double M1= 1.-a.KSI(NI1);
//           for (int NI2=1;NI2<=nbil;NI2++)
//            { double P2= 1.+a.KSI(NI2);
//              double M2= 1.-a.KSI(NI2);
              
         // on suit le même ordre des pt d'integ (d'abord suivant x puis suivant y) 
         // d'où c'est la boucle suivant y qui est la plus extrème     
         for (int NI2=1;NI2<=nbil;NI2++)
          { double P2= 1.+a.KSI(NI2);
            double M2= 1.-a.KSI(NI2);
            for (int NI1=1;NI1<=nbil;NI1++)
            { double P1= 1.+a.KSI(NI1);
              double M1= 1.-a.KSI(NI1);
//          ------------------------------
//          des fonctions d'interpolations
//          ------------------------------
              tabPhi(ni)(1)= -C*M1*M2*(1.+a.KSI(NI1)+a.KSI(NI2));
              tabPhi(ni)(2)= -C*P1*M2*(1.-a.KSI(NI1)+a.KSI(NI2));
              tabPhi(ni)(3)= -C*P1*P2*(1.-a.KSI(NI1)-a.KSI(NI2));
              tabPhi(ni)(4)= -C*M1*P2*(1.+a.KSI(NI1)-a.KSI(NI2));
              tabPhi(ni)(5)= D*M1*P1*M2;
              tabPhi(ni)(6)= D*P1*M2*P2;
              tabPhi(ni)(7)= D*M1*P1*P2;
              tabPhi(ni)(8)= D*M1*M2*P2;
//          -----------------
//          de leurs derivees
//          -----------------
              tabDPhi(ni)(1,1)= C*M2*(2.*a.KSI(NI1)+a.KSI(NI2));
              tabDPhi(ni)(2,1)= C*M1*(a.KSI(NI1)+2.*a.KSI(NI2));
              tabDPhi(ni)(1,2)= C*M2*(2.*a.KSI(NI1)-a.KSI(NI2));
              tabDPhi(ni)(2,2)= -C*P1*(a.KSI(NI1)-2.*a.KSI(NI2));
              tabDPhi(ni)(1,3)= C*P2*(2.*a.KSI(NI1)+a.KSI(NI2));
              tabDPhi(ni)(2,3)= C*P1*(a.KSI(NI1)+2.*a.KSI(NI2));
              tabDPhi(ni)(1,4)= C*P2*(2.*a.KSI(NI1)-a.KSI(NI2));
              tabDPhi(ni)(2,4)= -C*M1*(a.KSI(NI1)-2.*a.KSI(NI2));
              tabDPhi(ni)(1,5)= -M2*a.KSI(NI1);
              tabDPhi(ni)(2,5)= -D*M1*P1;
              tabDPhi(ni)(1,6)= D*M2*P2;
              tabDPhi(ni)(2,6)= -P1*a.KSI(NI2);
              tabDPhi(ni)(1,7)= -P2*a.KSI(NI1);
              tabDPhi(ni)(2,7)= D*M1*P1;
              tabDPhi(ni)(1,8)= -D*M2*P2;
              tabDPhi(ni)(2,8)= -M1*a.KSI(NI2);            
              ni++;
            }
         }  
      }
//    -------------------------------------------------------
//    ------------ cas lineaire/quadratique  -------------
//    -------------------------------------------------------
//  quadratique suivant ksi et lineaire suivant eta
 
     else if ( (NBNE == 6)     && 
         ((Nbi() == 1) || (Nbi() == 4) || (Nbi() == 9) || (Nbi() == 16)) )
      {  id_interpol=LINQUAD;
        // definition des cotes, qui sont quadratiques
         int nbil =  (int) sqrt((double)Nbi());
         int nbnes = 3; 
         seg(1) = new GeomSeg(nbil,nbnes); // quadratique
         seg(2) = new GeomSeg(nbil,2); // lineaire
         seg(3) = seg(1); seg(4) = seg(2);
         // def des tableaux de connection des noeuds des faces et des noeuds des cotes
         NONS(1).Change_taille(3);NONS(2).Change_taille(2);
         NONS(3).Change_taille(3);NONS(4).Change_taille(2);
         NONS(1)(1) = 1;NONS(1)(2) = 5;NONS(1)(3) = 2;
         NONS(2)(1) = 2;NONS(2)(2) = 3;
         NONS(3)(1) = 3;NONS(3)(2) = 6;NONS(3)(3) = 4;
         NONS(4)(1) = 4;NONS(4)(2) = 1;
         // triangulation de la face
         NONFt(1).Change_taille(4); // 4 face linéaires pour la face quadrangle
            // trois noeuds pour chaque triangle linéaire
         for (int ikt=1;ikt<=4;ikt++)   
            NONFt(1)(ikt).Change_taille(3);
         // remplissage de la connexion par rapport à celle de l'élément
         NONFt(1)(1)(1) = 1; NONFt(1)(1)(2) = 6; NONFt(1)(1)(3) = 4; 
         NONFt(1)(2)(1) = 1; NONFt(1)(2)(2) = 5; NONFt(1)(2)(3) = 6; 
         NONFt(1)(3)(1) = 5; NONFt(1)(3)(2) = 3; NONFt(1)(3)(3) = 6; 
         NONFt(1)(4)(1) = 5; NONFt(1)(4)(2) = 2; NONFt(1)(4)(3) = 3; 
        //  définition des coordonnées des noeuds
         ptelem(1) = Coordonnee(-1.,-1.);
         ptelem(2) = Coordonnee(1.,-1.);
         ptelem(3) = Coordonnee(1.,1.);
         ptelem(4) = Coordonnee(-1.,1.);
         ptelem(5) = Coordonnee(0,-1.);
         ptelem(6) = Coordonnee(1.,0);
         // definition des points , des fonctions d'interpolation, et des derivees
         double C= 0.25;
         double D= 0.5;
         GeomSeg & a = *((GeomSeg*) seg(1));  // pour commodite
         int ni = 1;
         for (int NI1=1;NI1<=nbil;NI1++)
         { double P1= 1.+a.KSI(NI1);
           double M1= 1.-a.KSI(NI1);
           for (int NI2=1;NI2<=nbil;NI2++)
            { double P2= 1.+a.KSI(NI2);
              double M2= 1.-a.KSI(NI2);
//          ------------------------------
//          des fonctions d'interpolations
//          ------------------------------
            tabPhi(ni)(1)= -C*a.KSI(NI1)*M1*M2;
            tabPhi(ni)(2)= C*a.KSI(NI1)*P1*M2;
            tabPhi(ni)(3)= C*a.KSI(NI1)*P1*P2;
            tabPhi(ni)(4)= -C*a.KSI(NI1)*M1*P2;
            tabPhi(ni)(5)= D*M1*P1*M2;
            tabPhi(ni)(6)= D*M1*P1*P2;

//          -----------------
//          de leurs derivees 
//          -----------------
            tabDPhi(ni)(1,1)= -C*(1.-2*a.KSI(NI1))*M2;
            tabDPhi(ni)(2,1)= C*a.KSI(NI1)*M1;
            tabDPhi(ni)(1,2)= C*(1.+2.*a.KSI(NI1))*M2;
            tabDPhi(ni)(2,2)= -C*a.KSI(NI1)*P1;
            tabDPhi(ni)(1,3)= C*(1.+2.*a.KSI(NI1))*P2;
            tabDPhi(ni)(2,3)= C*a.KSI(NI1)*P1;
            tabDPhi(ni)(1,4)= -C*(1.-2*a.KSI(NI1))*P2;
            tabDPhi(ni)(2,4)= -C*a.KSI(NI1)*M1;
            tabDPhi(ni)(1,5)= -M2*a.KSI(NI1);
            tabDPhi(ni)(2,5)= -D*M1*P1;
            tabDPhi(ni)(1,6)= -P2*a.KSI(NI1);
            tabDPhi(ni)(2,6)= D*M1*P1;
            ni++;
           }
         }
       }                
      else
       {cout << "\n erreur le quadrangle de nombre de noeud NBNE = " << NBNE 
             << "\n n\'est pas implante !! ";
        cout << "\nGeomQuadrangle::GeomQuadrangle(int nbi, int nbne) " << endl;     
        Sortie(1);
        }
    // ---- constitution du tableau Extrapol -----
    if (!sans_extrapole)
       Calcul_extrapol(nbi);
};

// destructeur
GeomQuadrangle::~GeomQuadrangle() 
  { if ((NBNE == 4) || (NBNE == 9) || (NBNE == 8)|| (NBNE == 16))
      delete seg(1);
    else 
     { delete  seg (1);
       delete seg(2);
      }  
   };
// constructeur de copie
GeomQuadrangle::GeomQuadrangle(const GeomQuadrangle& a) :
  ElemGeomC0(a),phi_M(a.phi_M),dphi_M(a.dphi_M)
   { // la copie des parties pointées est à la charge de la classe spécifique
     // definition de la face
     face(1) = this;
     // def des segments
     if ((NBNE == 4) || (NBNE == 9) || (NBNE == 8) || (NBNE == 16))
       { seg(1) = new GeomSeg(*((GeomSeg*)(a.seg(1)))) ;
         for (int il=2;il<= 4; il++)
           seg(il) = seg(1);
        }
     else 
     { seg (1) = new GeomSeg(*((GeomSeg*)(a.seg(1)))) ;
       seg (2) = new GeomSeg(*((GeomSeg*)(a.seg(2)))) ;
       seg(3) = seg(1); seg(4) = seg(2);
      }  
   };    
    
// 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 * GeomQuadrangle::newElemGeomC0(ElemGeomC0 * pt) 
  { pt = new GeomQuadrangle(*this);
    return pt; 
   };

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

    // retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& GeomQuadrangle::Phi_point(const Coordonnee& M)
  {
    #ifdef MISE_AU_POINT	 	   
     // verification de la dimension des coordonnees locales
     if (M.Dimension() != 2)
       { cout << "\n erreur la dimension des coordonnees locales :" << M.Dimension()
              <<"n\'est pas egale a 2 "
             << "\nGeomQuadrangle::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
    //------------------------------------------------------
    //cas d'un quadrangle bilineaire ou quadratique/cubique complet
    //------------------------------------------------------
    if  ((NBNE == 4) || (NBNE == 9) || (NBNE == 16))  
      {  int nbnes;  // nombre de noeud par cote
         if (NBNE == 4) nbnes = 2; 
         else if (NBNE == 9) nbnes = 3;
         else nbnes = 4;
         Coordonnee X(1),Y(1); X(1) = M(1); Y(1) = M(2); // coordonnees pour le segment
         //  fonctions d'interpolation
         int ne = 1;
         Vecteur tabPhiT(NBNE);
         for (int iy = 1;iy<= nbnes; iy++)
           for (int ix =1;ix<=nbnes;ix++)
            { tabPhiT(ne) = seg(1)->Phi_point(X)(ix) * seg(1)->Phi_point(Y)(iy);
              ne++;
             } 
         // numerotation suivant le standard habituel
         Tableau<int> ind;
         if (nbnes == 2)  // cas bilineaire
          {   ind.Change_taille(4);
              ind(1) = 1; ind(2) = 2; ind(3) = 4; ind(4) = 3;
              for (int ne = 1; ne<= 4; ne++)
                 phi_M(ne) = tabPhiT(ind(ne));
           } 
         else if (nbnes == 3)  // cas quadratique complet     
           { ind.Change_taille(9);
             ind(1) = 1; ind(2) = 3; ind(3) = 9; ind(4) = 7;ind(5) = 2;
             ind(6) = 6; ind(7) = 8; ind(8) = 4; ind(9) = 5;
             for (int ne = 1; ne<= 9; ne++)
                 phi_M(ne) = tabPhiT(ind(ne));
            }
         else if (nbnes == 4)  // cas cubique complet     
           { ind.Change_taille(16);
             ind(1) = 1; ind(2) = 4; ind(3) = 16; ind(4) = 13;ind(5) = 2;
             ind(6) = 3; ind(7) = 8; ind(8) = 12; ind(9) = 15;
             ind(10) = 14; ind(11) = 9; ind(12) = 5; ind(13) = 6;
             ind(14) = 7; ind(15) = 11; ind(16) = 10; 
             for (int ne = 1; ne<= 16; ne++)
                 phi_M(ne) = tabPhiT(ind(ne));
            }
       }  
     //------------------------------------------------------
     // cas d'un quadrangle quadratique incomplet 8 noeuds
     //------------------------------------------------------
     else if  (NBNE == 8) 
      { 
         // inter pour les fonctions d'interpolation
         double C= 0.25;
         double D= 0.5;
         double P1= 1.+ M(1);
         double M1= 1.- M(1);
         double P2= 1.+ M(2);
         double M2= 1.- M(2);
//       ------------------------------
//        fonctions d'interpolations
//       ------------------------------
         phi_M(1)= -C*M1*M2*(1.+ M(1)+ M(2));
         phi_M(2)= -C*P1*M2*(1.- M(1)+ M(2));
         phi_M(3)= -C*P1*P2*(1.- M(1)- M(2));
         phi_M(4)= -C*M1*P2*(1.+ M(1)- M(2));
         phi_M(5)= D*M1*P1*M2;
         phi_M(6)= D*P1*M2*P2;
         phi_M(7)= D*M1*P1*P2;
         phi_M(8)= D*M1*M2*P2;
      }
//    -------------------------------------------------------
//    ------------ cas lineaire/quadratique  -------------
//    -------------------------------------------------------
//  quadratique suivant ksi et lineaire suivant eta
 
     else if (NBNE == 6)
      {  //  inter pour les fonctions d'interpolation,
         double C= 0.25;
         double D= 0.5;
         double P1= 1.+ M(1);
         double M1= 1.- M(1);
         double P2= 1.+ M(2);
         double M2= 1.- M(2);
//       ------------------------------
//       des fonctions d'interpolations
//       ------------------------------
         phi_M(1)= -C* M(1)*M1*M2;
         phi_M(2)= C* M(1)*P1*M2;
         phi_M(3)= C* M(1)*P1*P2;
         phi_M(4)= -C* M(1)*M1*P2;
         phi_M(5)= D*M1*P1*M2;
         phi_M(6)= D*M1*P1*P2;
       }                
      else
       {cout << "\n erreur le quadrangle de nombre de noeud NBNE = " << NBNE 
             << "\n n\'est pas implante !! ";
        cout << "\nGeomQuadrangle::Phi(Coordonnee& M) " << endl;     
        Sortie(1);
        }
    // retour de phi_M
    return phi_M;
   };
    // retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& GeomQuadrangle::Dphi_point(const Coordonnee& M)
  {  
   #ifdef MISE_AU_POINT	 	   
     // verification de la dimension des coordonnees locales
     if (M.Dimension() != 2)
       { cout << "\n erreur la dimension des coordonnees locales :" << M.Dimension()
              <<"n\'est pas egale a 2 "
             << "\nGeomQuadrangle::Dphi(Coordonnee& M)";
        Sortie(1);
      }
    #endif
//   Mat_pleine dphi(2,NBNE); // le tableau des derivees
   // le tableau des derivees: redimentionnement si nécessaire
   if ((dphi_M.Nb_ligne() != 2)&&(dphi_M.Nb_colonne() != NBNE))
      dphi_M.Initialise (2,NBNE,0.);
    //------------------------------------------------------
    //cas d'un quadrangle bilineaire ou quadratique/cubique complet
    //------------------------------------------------------
    if  ((NBNE == 4) || (NBNE == 9) || (NBNE == 16))  
      {  int nbnes;  // nombre de noeud par cote
         if (NBNE == 4) nbnes = 2; 
         else if (NBNE == 9) nbnes = 3;
         else nbnes = 4;
         Coordonnee X(1),Y(1); X(1) = M(1); Y(1) = M(2); // coordonnees pour le segment
         //  derivee des fonctions d'interpolation
         int ne = 1;
         Mat_pleine tabDPhiT(2,NBNE);
         for (int iy = 1;iy<= nbnes; iy++)
           for (int ix =1;ix<=nbnes;ix++)
            { tabDPhiT(1,ne) = seg(1)->Dphi_point(X)(1,ix) * seg(1)->Phi_point(Y)(iy);
              tabDPhiT(2,ne) = seg(1)->Phi_point(X)(ix) * seg(1)->Dphi_point(Y)(1,iy);
              ne++;
             } 
         // numerotation suivant le standard habituel
         Tableau<int> ind;
         if (nbnes == 2)  // cas bilineaire
          {   ind.Change_taille(4);
              ind(1) = 1; ind(2) = 2; ind(3) = 4; ind(4) = 3;
              for (int ne = 1; ne<= 4; ne++)
               { dphi_M(1,ne) = tabDPhiT(1,ind(ne));
                 dphi_M(2,ne) = tabDPhiT(2,ind(ne));
                } 
           } 
         else if (nbnes == 3)  // cas quadratique complet     
           { ind.Change_taille(9);
             ind(1) = 1; ind(2) = 3; ind(3) = 9; ind(4) = 7;ind(5) = 2;
             ind(6) = 6; ind(7) = 8; ind(8) = 4; ind(9) = 5;
             for (int ne = 1; ne<= 9; ne++)
               { dphi_M(1,ne) = tabDPhiT(1,ind(ne));
                 dphi_M(2,ne) = tabDPhiT(2,ind(ne));
                } 
            }
         else if (nbnes == 4)  // cas cubique complet     
           { ind.Change_taille(16);
             ind(1) = 1; ind(2) = 4; ind(3) = 16; ind(4) = 13;ind(5) = 2;
             ind(6) = 3; ind(7) = 8; ind(8) = 12; ind(9) = 15;
             ind(10) = 14; ind(11) = 9; ind(12) = 5; ind(13) = 6;
             ind(14) = 7; ind(15) = 11; ind(16) = 10; 
             for (int ne = 1; ne<= 16; ne++)
               { dphi_M(1,ne) = tabDPhiT(1,ind(ne));
                 dphi_M(2,ne) = tabDPhiT(2,ind(ne));
                } 
            }
       }  
     //------------------------------------------------------
     // cas d'un quadrangle quadratique incomplet 8 noeuds
     //------------------------------------------------------
     else if  (NBNE == 8) 
      { 
         // inter pour les derivees
         double C= 0.25;
         double D= 0.5;
         double P1= 1.+ M(1);
         double M1= 1.- M(1);
         double P2= 1.+ M(2);
         double M2= 1.- M(2);
//       -----------------
//       derivees 
//       -----------------
         dphi_M(1,1)= C*M2*(2.* M(1)+ M(2));
         dphi_M(2,1)= C*M1*( M(1)+2.* M(2));
         dphi_M(1,2)= C*M2*(2.* M(1)- M(2));
         dphi_M(2,2)= -C*P1*( M(1)-2.* M(2));
         dphi_M(1,3)= C*P2*(2.* M(1)+ M(2));
         dphi_M(2,3)= C*P1*( M(1)+2.* M(2));
         dphi_M(1,4)= C*P2*(2.* M(1)- M(2));
         dphi_M(2,4)= -C*M1*( M(1)-2.* M(2));
         dphi_M(1,5)= -M2* M(1);
         dphi_M(2,5)= -D*M1*P1;
         dphi_M(1,6)= D*M2*P2;
         dphi_M(2,6)= -P1* M(2);
         dphi_M(1,7)= -P2* M(1);
         dphi_M(2,7)= D*M1*P1;
         dphi_M(1,8)= -D*M2*P2;
         dphi_M(2,8)= -M1* M(2);
      }
//    -------------------------------------------------------
//    ------------ cas lineaire/quadratique  -------------
//    -------------------------------------------------------
//  quadratique suivant ksi et lineaire suivant eta
 
     else if (NBNE == 6)
      {  //  inter pour les derivees,
         double C= 0.25;
         double D= 0.5;
         double P1= 1.+ M(1);
         double M1= 1.- M(1);
         double P2= 1.+ M(2);
         double M2= 1.- M(2);
//       -----------------
//             derivees 
//       -----------------
         dphi_M(1,1)= -C*(1.-2* M(1))*M2;
         dphi_M(2,1)= C* M(1)*M1;
         dphi_M(1,2)= C*(1.+2.* M(1))*M2;
         dphi_M(2,2)= -C* M(1)*P1;
         dphi_M(1,3)= C*(1.+2.* M(1))*P2;
         dphi_M(2,3)= C* M(1)*P1;
         dphi_M(1,4)= -C*(1.-2* M(1))*P2;
         dphi_M(2,4)= -C* M(1)*M1;
         dphi_M(1,5)= -M2* M(1);
         dphi_M(2,5)= -D*M1*P1;
         dphi_M(1,6)= -P2* M(1);
         dphi_M(2,6)= D*M1*P1;
       }                
      else
       { cout << "\n erreur le nombre de noeud demande :" << NBNE <<"n\'est pas implante "
             << "\nGeomQuadrangle::Dphi(Coordonnee& M)";
        Sortie(1);
      }
    // retour des derivees  
    return dphi_M;
   };
          
// en fonction de coordonnees locales, retourne true si le point est a l'interieur
// de l'element, false sinon
bool GeomQuadrangle::Interieur(const Coordonnee& M)
  { if ((Dabs(M(1)) <= 1.) &&
        (Dabs(M(2)) <= 1.) )                
        return true;
    else
        return false;    
   };
              
// en fonction de coordonnees locales, retourne le point local P, maximum intérieur à l'élément, donc sur la frontière
// dont les coordonnées sont sur la droite GM: c-a-d GP = alpha GM, avec apha maxi et P appartenant à la frontière
// de l'élément, G étant le centre de gravité, sauf si GM est nul, dans ce cas retour de M
Coordonnee GeomQuadrangle::Maxi_Coor_dans_directionGM(const Coordonnee& M)
  { // on recherche du maxi des 2 composantes en valeur absolu
    double xmax = MaX(Dabs(M(1)),Dabs(M(2)));
    if (xmax <= ConstMath::petit) return M;
    // sinon on fait la règle de 3
    Coordonnee P= M/xmax;
    return P;
   }; 
    
// constitution du tableau Extrapol
void GeomQuadrangle::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
  Tableau <Coordonnee>  gi_B,gi_H; // bases naturelle et duale
  Vecteur phi_(3); // le conteneur pour les fonctions d'interpolation
  Coordonnee theta(2); // le conteneur pour les coordonnées locales

  switch  (nbi)
   { case 1: 
       { // cas avec un point d'intégration, quelque soit le nombre de noeuds, 
         // on reporte la valeur au pt d'integ, telle quelle au noeud
         for (int ne=1;ne<=NBNE;ne++)
         	{tab(ne)(1)=1.;
         	 indir(ne).Change_taille(1); indir(ne)(1)=1;
         	};
         break;
       }
   	 case 4:
   	   { // cas avec 4 points d'intégration  
         // on extrapole linéairement vers les  noeuds en considérant à chaque fois les 3 pt d'intégration
         // les plus près
         // --- pour les 4 premiers noeuds c'est identique quelque soit le nombre total de noeud
         {// -- le premier noeud
          int ne = 1; indirect(1)=1;indirect(2)=2;indirect(3)=3; 
          Bases_naturel_duales(indirect,gi_B,gi_H);
          Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
          ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
          tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
          indir(ne).Change_taille(3); 
          indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         }
         {// -- le deuxième noeud
          int ne = 2; indirect(1)=2;indirect(2)=4;indirect(3)=1; 
          Bases_naturel_duales(indirect,gi_B,gi_H);
          Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
          ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
          tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);
          indir(ne).Change_taille(3); 
          indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         }
         {// -- le troisième noeud
          int ne = 3; indirect(1)=4;indirect(2)=3;indirect(3)=2; 
          Bases_naturel_duales(indirect,gi_B,gi_H);
          Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
          ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
          tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3); 
          indir(ne).Change_taille(3); 
          indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         }
         {// -- le quatrième noeud
          int ne = 4; indirect(1)=3;indirect(2)=1;indirect(3)=4; 
          Bases_naturel_duales(indirect,gi_B,gi_H);
          Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
          ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
          tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
          indir(ne).Change_taille(3); 
          indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         }
         switch (NBNE)  // on différencie en fonction du nombre de noeud
         	{ case 4: // quatre noeuds, déjà ok 
         		  break; 
         	  case 6:// quadratique en x et linéaire en y
         		{{// -- le  noeud 5 -> extrapole en 1 2 3 (on aurait pu faire 1 2 4 -> choix arbitraire)
                  int ne = 5; indirect(1)=1;indirect(2)=2;indirect(3)=3; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- le noeud 6
                  int ne = 6; indirect(1)=3;indirect(2)=1;indirect(3)=4; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);   
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		  break;
         		}
         	  case 8: // quadratique en x et y
         		{{// -- le  noeud 5 et 8 on extrapole en 1 2 3 (on aurait pu faire 1 2 4 -> choix arbitraire)
                  int ne = 5; indirect(1)=1;indirect(2)=2;indirect(3)=3; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		  ne = 8;  
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- noeud 6 et 7 on extrapole en 4 3 2 
                  int ne = 6; indirect(1)=4;indirect(2)=3;indirect(3)=2; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		  ne = 7;  
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
       		     break;
         		}
         	  case 9: // quadratique en x et y
         		{{// -- le  noeud 5 et 8 on extrapole en 1 2 3 (on aurait pu faire 1 2 4 -> choix arbitraire)
                  int ne = 5; indirect(1)=1;indirect(2)=2;indirect(3)=3; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		  ne = 8;  
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- noeud 6 et 7 on extrapole en 4 3 2 
                  int ne = 6; indirect(1)=4;indirect(2)=3;indirect(3)=2; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		  ne = 7;  
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- le noeud  9, on fait la moyenne des 4 valeurs aux pt d'integ
                  int ne = 9; 
                  tab(ne)(1) = 0.25;tab(ne)(2) = 0.25;tab(ne)(3) = 0.25; tab(ne)(4) = 0.25;  
                  indir(ne).Change_taille(4); 
                  indir(ne)(1)=1;indir(ne)(2)=2;indir(ne)(3)=3;indir(ne)(4)=4;
         		 }
       		     break;
         		}
         	  case 16: // cubique en x et y
         		{{// -- le  noeud 5, 12 et 13 on extrapole en 1 2 3 (on aurait pu faire 1 2 4 -> choix arbitraire)
                  int ne = 5; indirect(1)=1;indirect(2)=2;indirect(3)=3; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
                  ne = 12;  
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		  ne = 13;  
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- noeud 6, 7 et 14 on extrapole en 2 4 1 
                  int ne = 6; indirect(1)=2;indirect(2)=4;indirect(3)=1; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3); 
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		  ne = 7;  
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		  ne = 14;  
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- noeud 8, 9 et 15 on extrapole en 4 3 2 
                  int ne = 8; indirect(1)=4;indirect(2)=3;indirect(3)=2; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3); 
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		  ne = 9;  
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		  ne = 15;  
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- noeud 10, 11 et 16 on extrapole en 3 1 4 
                  int ne = 10; indirect(1)=3;indirect(2)=1;indirect(3)=4; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3); 
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		  ne = 11;  
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		  ne = 16;  
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
       		     break;
         		}
         	  default:
         	    { cout << "\n erreur le nombre de noeud demande :" << NBNE <<"n\'est pas implante "
                       << "\nGeomTriangle::Calcul_extrapol(..";
                  Sortie(1);
                };
         	};
          break;  
   	 	}  // fin du cas avec 4 pt d'intégration
   	 case 9:
   	   { // cas avec 9 points d'intégration  
         // on extrapole linéairement vers les  noeuds en considérant à chaque fois les 3 pt d'intégration
         // les plus près
         // --- pour les 4 premiers noeuds c'est identique quelque soit le nombre total de noeud
         {// -- le premier noeud
          int ne = 1; indirect(1)=1;indirect(2)=2;indirect(3)=4; 
          Bases_naturel_duales(indirect,gi_B,gi_H);
          Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
          ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
          tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
          indir(ne).Change_taille(3); 
          indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         }
         {// -- le deuxième noeud
          int ne = 2; indirect(1)=3;indirect(2)=6;indirect(3)=2; 
          Bases_naturel_duales(indirect,gi_B,gi_H);
          Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
          ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
          tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);
          indir(ne).Change_taille(3); 
          indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         }
         {// -- le troisième noeud
          int ne = 3; indirect(1)=9;indirect(2)=8;indirect(3)=6; 
          Bases_naturel_duales(indirect,gi_B,gi_H);
          Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
          ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
          tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3); 
          indir(ne).Change_taille(3); 
          indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         }
         {// -- le quatrième noeud
          int ne = 4; indirect(1)=7;indirect(2)=4;indirect(3)=8; 
          Bases_naturel_duales(indirect,gi_B,gi_H);
          Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
          ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
          tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);   
          indir(ne).Change_taille(3); 
          indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         }
         switch (NBNE)  // on différencie en fonction du nombre de noeud
         	{ case 4: // quatre noeuds, déjà ok 
         		  break; 
         	  case 6:// quadratique en x et linéaire en y
         		{{// -- le  noeud 5 -> extrapole en 2 3 5 
                  int ne = 5; indirect(1)=2;indirect(2)=3;indirect(3)=5; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- le noeud 6
                  int ne = 6; indirect(1)=8;indirect(2)=7;indirect(3)=5; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);   
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		  break;
         		}
         	  case 8: // quadratique en x et y
         		{{// -- le  noeud 5 -> extrapole en 2 3 5 
                  int ne = 5; indirect(1)=2;indirect(2)=3;indirect(3)=5; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- le noeud 6
                  int ne = 6; indirect(1)=6;indirect(2)=9;indirect(3)=5; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- le noeud 7
                  int ne = 7; indirect(1)=8;indirect(2)=7;indirect(3)=5; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);   
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- le noeud 8
                  int ne = 8; indirect(1)=4;indirect(2)=1;indirect(3)=5; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);   
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
       		     break;
         		}
         	  case 9: // quadratique en x et y
         		{{// -- le  noeud 5 -> extrapole en 2 3 5 
                  int ne = 5; indirect(1)=2;indirect(2)=3;indirect(3)=5; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- le noeud 6
                  int ne = 6; indirect(1)=6;indirect(2)=9;indirect(3)=5; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- le noeud 7
                  int ne = 7; indirect(1)=8;indirect(2)=7;indirect(3)=5; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- le noeud 8
                  int ne = 8; indirect(1)=4;indirect(2)=1;indirect(3)=5; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);   
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- le noeud  9, idem le pt d'integ 5
                  int ne = 9; 
                  tab(ne)(5) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=5;
         		 }
       		     break;
         		}
         	  case 16: // cubique en x et y
         		{{// -- le  noeud 5 et 13 on extrapole en 1 2 5
                  int ne = 5; indirect(1)=1;indirect(2)=2;indirect(3)=5; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		  ne = 13;  
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- noeud 6 et 14 on extrapole en 2 3 5
                  int ne = 6; indirect(1)=2;indirect(2)=3;indirect(3)=5; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3); 
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		  ne = 14;  
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- noeud 7 
                  int ne = 7; indirect(1)=6;indirect(2)=5;indirect(3)=3; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3); 
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- noeud 8 et 15 on extrapole en 6 9 5 
                  int ne = 8; indirect(1)=6;indirect(2)=9;indirect(3)=5; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3); 
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		  ne = 15;  
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- noeud 9 
                  int ne = 9; indirect(1)=8;indirect(2)=5;indirect(3)=9; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3); 
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- noeud 10 et 16 
                  int ne = 10; indirect(1)=8;indirect(2)=7;indirect(3)=5; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3); 
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		  ne = 16;  
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
         		 {// -- noeud 11 
                  int ne = 11; indirect(1)=4;indirect(2)=5;indirect(3)=7; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3); 
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
        		 }
         		 {// -- noeud 12 
                  int ne = 12; indirect(1)=1;indirect(2)=2;indirect(3)=4; 
                  Bases_naturel_duales(indirect,gi_B,gi_H);
                  Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
                  ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
                  tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3); 
                  indir(ne).Change_taille(3); 
                  indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         		 }
       		     break;
         		}
         	  default:
         	    { cout << "\n erreur le nombre de noeud demande :" << NBNE <<"n\'est pas implante "
                       << "\nGeomTriangle::Calcul_extrapol(..";
                  Sortie(1);
                };
         	};
          break;  
   	 	}  // fin du cas avec 9 pt d'intégration
   	 case 16:
   	   { // cas avec 16 points d'intégration  
         // on extrapole linéairement vers les  noeuds en considérant à chaque fois les 3 pt d'intégration
         // les plus près
         // --- pour les 4 premiers noeuds c'est identique quelque soit le nombre total de noeud
         {// -- le premier noeud
          int ne = 1; indirect(1)=1;indirect(2)=2;indirect(3)=5; 
          Bases_naturel_duales(indirect,gi_B,gi_H);
          Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
          ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
          tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);  
          indir(ne).Change_taille(3); 
          indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         }
         {// -- le deuxième noeud
          int ne = 2; indirect(1)=4;indirect(2)=8;indirect(3)=3; 
          Bases_naturel_duales(indirect,gi_B,gi_H);
          Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
          ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
          tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);
          indir(ne).Change_taille(3); 
          indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         }
         {// -- le troisième noeud
          int ne = 3; indirect(1)=16;indirect(2)=15;indirect(3)=12; 
          Bases_naturel_duales(indirect,gi_B,gi_H);
          Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
          ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
          tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3); 
          indir(ne).Change_taille(3); 
          indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         }
         {// -- le quatrième noeud
          int ne = 4; indirect(1)=13;indirect(2)=9;indirect(3)=14; 
          Bases_naturel_duales(indirect,gi_B,gi_H);
          Coordonnee O(ptInteg(indirect(1))); // def de l'origine 
          ElemGeomC0::Coor_phi(O,gi_H,ptelem(ne),phi_,theta);
          tab(ne)(indirect(1)) = phi_(1);tab(ne)(indirect(2)) = phi_(2);tab(ne)(indirect(3)) = phi_(3);   
          indir(ne).Change_taille(3); 
          indir(ne)(1)=indirect(1);indir(ne)(2)=indirect(2);indir(ne)(3)=indirect(3);
         }
         switch (NBNE)  // on différencie en fonction du nombre de noeud
         	{ case 4: // quatre noeuds, déjà ok 
         		  break; 
         	  case 6:// quadratique en x et linéaire en y
         		{{// -- le  noeud 5 -> moyenne de 2 3
                  int ne = 5; 
                  tab(ne)(2) = 0.5;tab(ne)(3) = 0.5;  
                  indir(ne).Change_taille(2); 
                  indir(ne)(1)=2;indir(ne)(2)=3;
         		 }
         		 {// -- le noeud 6 -> moyenne de 14 15
                  int ne = 6;  
                  tab(ne)(14) = 0.5;tab(ne)(15) = 0.5;
                  indir(ne).Change_taille(2); 
                  indir(ne)(1)=14;indir(ne)(2)=15;
        		 }
         		  break;
         		}
         	  case 8: // quadratique en x et y : vu la proximité des pt d'integ on moyenne
         		{{// -- le  noeud 5 -> moyenne de 2 3
                  int ne = 5; 
                  tab(ne)(2) = 0.5;tab(ne)(3) = 0.5;  
                  indir(ne).Change_taille(2); 
                  indir(ne)(1)=2;indir(ne)(2)=3;
         		 }
         		 {// -- le noeud 6 -> moyenne de 8 12
                  int ne = 6;  
                  tab(ne)(8) = 0.5;tab(ne)(12) = 0.5;
                  indir(ne).Change_taille(2); 
                  indir(ne)(1)=8;indir(ne)(2)=12;
         		 }
         		 {// -- le noeud 7 -> moyenne de 14 15
                  int ne = 7;  
                  tab(ne)(14) = 0.5;tab(ne)(15) = 0.5;
                  indir(ne).Change_taille(2); 
                  indir(ne)(1)=14;indir(ne)(2)=15;
         		 }
         		 {// -- le noeud 8 -> moyenne de 5 9
                  int ne = 8;  
                  tab(ne)(5) = 0.5;tab(ne)(9) = 0.5;
                  indir(ne).Change_taille(2); 
                  indir(ne)(1)=5;indir(ne)(2)=9;
         		 }
       		     break;
         		}
         	  case 9: // quadratique en x et y
         		{{// -- le  noeud 5 -> moyenne de 2 3
                  int ne = 5; 
                  tab(ne)(2) = 0.5;tab(ne)(3) = 0.5;  
                  indir(ne).Change_taille(2); 
                  indir(ne)(1)=2;indir(ne)(2)=3;
         		 }
         		 {// -- le noeud 6 -> moyenne de 8 12
                  int ne = 6;  
                  tab(ne)(8) = 0.5;tab(ne)(12) = 0.5;
                  indir(ne).Change_taille(2); 
                  indir(ne)(1)=8;indir(ne)(2)=12;
         		 }
         		 {// -- le noeud 7 -> moyenne de 14 15
                  int ne = 7;  
                  tab(ne)(14) = 0.5;tab(ne)(15) = 0.5;
                  indir(ne).Change_taille(2); 
                  indir(ne)(1)=14;indir(ne)(2)=15;
         		 }
         		 {// -- le noeud 8 -> moyenne de 5 9
                  int ne = 8;  
                  tab(ne)(5) = 0.5;tab(ne)(9) = 0.5;
                  indir(ne).Change_taille(2); 
                  indir(ne)(1)=5;indir(ne)(2)=9;
         		 }
         		 {// -- le noeud  9, moyenne de 6 7 10 11
                  int ne = 9; 
                  tab(ne)(6) = 0.25;tab(ne)(7) = 0.25;tab(ne)(10) = 0.25;tab(ne)(11) = 0.25;
                  indir(ne).Change_taille(4); 
                  indir(ne)(1)=6;indir(ne)(2)=7;indir(ne)(3)=10;indir(ne)(4)=11;
        		 }
       		     break;
         		}
         	  case 16: // cubique en x et y -->> on exporte systématiquement au noeud le plus près pour simplifier
         		{{// -- le  noeud 5 
                  int ne = 5; tab(ne)(2) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=2;
         		 }
         		 {// -- le  noeud 6 
                  int ne = 6; tab(ne)(3) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=3;
         		 }
         		 {// -- le  noeud 7 
                  int ne = 7; tab(ne)(8) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=8;
         		 }
         		 {// -- le  noeud 8 
                  int ne = 8; tab(ne)(12) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=12;
         		 }
         		 {// -- le  noeud 9 
                  int ne = 9; tab(ne)(15) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=15;
         		 }
         		 {// -- le  noeud 10 
                  int ne = 10; tab(ne)(14) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=14;
         		 }
         		 {// -- le  noeud 11 
                  int ne = 11; tab(ne)(9) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=9;
         		 }
         		 {// -- le  noeud 12 
                  int ne = 12; tab(ne)(5) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=5;
         		 }
         		 {// -- le  noeud 13 
                  int ne = 13; tab(ne)(6) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=6;
         		 }
         		 {// -- le  noeud 14 
                  int ne = 14; tab(ne)(7) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=7;
         		 }
         		 {// -- le  noeud 15 
                  int ne = 15; tab(ne)(11) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=11;
         		 }
         		 {// -- le  noeud 16 
                  int ne = 16; tab(ne)(10) = 1.;indir(ne).Change_taille(1); indir(ne)(1)=10;
         		 }
       		     break;
         		}
         	  default:
         	    { cout << "\n erreur le nombre de noeud demande :" << NBNE <<"n\'est pas implante "
                       << "\nGeomTriangle::Calcul_extrapol(..";
                  Sortie(1);
                };
         	};
          break;  
   	 	}  // fin du cas avec 16 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);
       };
   };

}; 
        
  
  
  
  
    
  
  
  
  


