Herezh_dev/Elements/Geometrie/ElemGeom/volume/GeomPentaQComp.cc

1289 lines
63 KiB
C++
Raw Normal View History

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