Herezh_dev/Elements/Geometrie/ElemGeom/volume/GeomHexaCom.cc
2023-05-03 17:23:49 +02:00

147 lines
4.9 KiB
C++

// 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 "GeomHexaCom.h"
#include <math.h>
#include "GeomSeg.h"
#include "GeomQuadrangle.h"
#include "MathUtil.h"
// constructeur
// le constructeur par défaut ne doit pas être utilisé
GeomHexaCom::GeomHexaCom()
{ cout << "\n erreur le constructeur par défaut ne doit pas être utilisé " ;
cout << "\nGeomHexaCom::GeomHexaCom() " << endl;
Sortie(1);
};
// la dimension est 3, on a nbi pt d'integration et nbe noeuds 6 faces, 12 aretes
GeomHexaCom::GeomHexaCom(int nbi, int nbe, Enum_interpol interpol) :
ElemGeomC0(3,nbi,nbe,6,12,HEXAEDRE,interpol)
{ // coordonnees des points d'integration
if (nbi == 8) // cas classique
{ double a = 1./sqrt(3.);
ptInteg(1) = Coordonnee(a,a,a);
ptInteg(2) = Coordonnee(a,a,-a);
ptInteg(3) = Coordonnee(a,-a,a);
ptInteg(4) = Coordonnee(a,-a,-a);
ptInteg(5) = Coordonnee(-a,a,a);
ptInteg(6) = Coordonnee(-a,a,-a);
ptInteg(7) = Coordonnee(-a,-a,a);
ptInteg(8) = Coordonnee(-a,-a,-a);
// poids d'integration
for (int i =1;i<=Nbi();i++)
WI(i)= 1.;
}
else if ((nbi==1) || (nbi==27) || (nbi == 64))
// on définit les points et poids d'intégration à partir
// d'un produit de ceux du segment
{ // definition des cotes
int nbil = 0;
switch (nbi)
{ case 1 :
nbil = 1;
break;
case 27 :
nbil = 3;
break;
case 64 :
nbil = 4;
break;
};
// on choisit 2 noeuds par défaut au lieu de la racine cubique de
// nbne mais cela n'a pas d'importance pour la détermination des
// points et poids d'intégration
GeomSeg b(nbil,2);
// definition des points et des poids
int ni = 1;
for (int niz = 1; niz<= nbil; niz++)
for (int niy = 1; niy<= nbil; niy++)
for (int nix = 1; nix<= nbil; nix++)
{ WI(ni) = b.Wi(nix) * b.Wi(niy) * b.Wi(niz);
ptInteg(ni) =
Coordonnee(b.CoorPtInteg(nix)(1),b.CoorPtInteg(niy)(1)
,b.CoorPtInteg(niz)(1));
ni++;
}
}
else
{cout << "\n erreur l'hexaèdre de nombre de point d\'integration " << Nbi()
<< " n\'est pas implante !! ";
cout << "\nGeomHexaCom::GeomHexaCom(int nbi) " << endl;
Sortie(1);
}
};
// destructeur
GeomHexaCom::~GeomHexaCom()
{
};
// constructeur de copie
GeomHexaCom::GeomHexaCom(const GeomHexaCom& a) :
ElemGeomC0(a)
{
};
// en fonction de coordonnees locales, retourne true si le point est a l'interieur
// de l'element, false sinon
bool GeomHexaCom::Interieur(const Coordonnee& M)
{ if ((Dabs(M(1)) <= 1.) &&
(Dabs(M(2)) <= 1.) &&
(Dabs(M(3)) <= 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 GeomHexaCom::Maxi_Coor_dans_directionGM(const Coordonnee& M)
{ // on recherche du maxi des 3 composantes en valeur absolu
double xmax = MaX(MaX(Dabs(M(1)),Dabs(M(2))),Dabs(M(3)));
if (xmax <= ConstMath::petit) return M;
// sinon on fait la règle de 3
Coordonnee P= M/xmax;
return P;
};