// 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) . // // 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 . // // For more information, please consult: . /************************************************************************ * DATE: 23/01/97 * * $ * * AUTEUR: G RIO (mailto:gerardrio56@free.fr) * * $ * * PROJET: Herezh++ * * $ * ************************************************************************ * BUT: Element geometrique generique pour une discrétisation C0. * * $ * * '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * * * VERIFICATION: * * * * ! date ! auteur ! but ! * * ------------------------------------------------------------ * * ! ! ! ! * * $ * * '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * * MODIFICATIONS: * * ! date ! auteur ! but ! * * ------------------------------------------------------------ * * $ * ************************************************************************/ #ifndef ELEMGEOMC0_H #define ELEMGEOMC0_H // #include #include "Mat_pleine.h" #include "Tableau_T.h" #include "Vecteur.h" #include "Coordonnee.h" #include "Enum_interpol.h" #include "Enum_geom.h" #include "Enum_type_pt_integ.h" /** @defgroup Les_Elements_de_geometrie * * BUT: groupe concernant les éléments de géométrie 1D, 2D, 3D * * \author Gérard Rio * \version 1.0 * \date 23/01/97 * \brief groupe concernant les éléments de géométrie 1D, 2D, 3D * */ /// @addtogroup Les_Elements_de_geometrie /// @{ /// class ElemGeomC0 { public : // CONSTRUCTEURS : ElemGeomC0(); // pardefaut // cas ou l'on connait la dimension = dim, // le nombre de point d'integration nbi et le nombre // de noeud de l'element nbne // le nombre de face nbfe, le nombre de segment nbse // IMPORTANT : par defaut le nombre de pt d'integ pour les faces ou segents // s'il y en a, est calcule a partir du nombre total de point d'integ // se referer a la description des elements // par défaut le type de point d'intégration est de gauss ElemGeomC0(int dim,int nbi,int nbne,int nbfe,int nbse ,Enum_geom geom, Enum_interpol interpol ,Enum_type_pt_integ type_pti = PTI_GAUSS); // de copie ElemGeomC0(const ElemGeomC0& a); // DESTRUCTEUR : virtual ~ElemGeomC0(); // METHODES PUBLIQUES : // retourne la dimension de l'element inline int Dimension() const { return dimension;}; // retourne le nombre total de point d'integration inline int Nbi() const { return tabPhi.Taille();}; // retourne le nombre total de noeud inline int Nbne() const { return NBNE;}; // retourne le nombre de face inline int NbFe() const { return NBFE;}; // retourne le nombre de segment inline int NbSe() const { return NBSE;}; // retourne les coordonnees du point d'integration i inline Coordonnee const & CoorPtInteg(int i) const { return ptInteg(i);}; // retourne les fonctions d'interpolation au point d'integration i inline Vecteur const & Phi(int i) const { return tabPhi(i);}; // retourne les tableau de fonctions d'interpolation inline Tableau const & TaPhi() const { return tabPhi;}; // retourne les derivees des fonctions d'interpolation au point d'integration i inline Mat_pleine const& Dphi(int i) { return tabDPhi(i);}; // retourne le tableau des derivees des fonctions d'interpolation inline Tableau < Mat_pleine > const& TaDphi() const { return tabDPhi;}; // retourne les poids d'integration du point d'integration i inline double Wi(int i) const { return WI(i);}; // retourne le vecteur des poids d'integration inline Vecteur const & TaWi() const { return WI;}; // retourne l'"element face de référence" correspondant a la face i inline ElemGeomC0 const & ElemFace(int i) const { return *face(i);}; // retourne l'"element segment de référence" correspondant a l'arrète i inline ElemGeomC0 const & ElemSeg(int i) const { return *seg(i);}; // retourne true si l'element est complet sinon false bool Complet() const ; // retourne la connection des noeuds des faces par rapport a ceux de l'element inline Tableau > const & Nonf() const { return NONF;}; // retourne la connection des noeuds des arêtes par rapport a ceux de l'element inline Tableau > const & NonS() const { return NONS;}; // retourne les coordonnées des noeuds locaux inline Tableau const & PtelemRef() const {return ptelem;}; // retourne le type de géométrie inline Enum_geom TypeGeometrie() const {return id_geom;}; // retourne le type d'interpolation inline Enum_interpol TypeInterpolation() const {return id_interpol;}; // retourne le type de points d'intégration inline Enum_type_pt_integ TypePointIntegration() const {return id_type_pt_integ;}; // cas de l'extrapolation de grandeur des points d'intégrations aux noeuds // ramène un 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) class ConteneurExtrapolation { // surcharge de l'operator de lecture avec le type friend istream & operator >> (istream &, ConteneurExtrapolation &); // surcharge de l'operator d'ecriture friend ostream & operator << (ostream &, const ConteneurExtrapolation &); public: ConteneurExtrapolation() : tab(),indir() {}; ConteneurExtrapolation(const ConteneurExtrapolation &a) : tab(a.tab),indir(a.indir) {}; ConteneurExtrapolation& operator= ( const ConteneurExtrapolation& a) {tab=a.tab;indir=a.indir; return *this;}; // les tableaux publiques Tableau > tab; Tableau > indir; }; inline ConteneurExtrapolation const & ExtrapolationNoeud(int cas) const { return extrapol(cas);}; // 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 virtual ElemGeomC0 * newElemGeomC0(ElemGeomC0 * pt) = 0; // creation d'une numérotation correspondant à un élément d'orientation inverse // la numérotation est donnée par rapport à la numérotation normale de l'élément (de 1 à NBNE) inline Tableau const & InvConnec() const { return INVCONNEC;}; // ramène le tableau des tranches de numérotation // c-a-d: ex: un quadrangle quadratique à 9 noeuds à 3 tranches: 4, 4, 1 // - la première tranche correspond aux 4 noeuds sommets, la numérotation peut être cyclique (permutation circulaire) // parmi ses 4 noeuds // - la second tranche correspond aux 4 noeuds intermédiaires, là aussi, la numérotation peut être une // permutation circulaire parmi ses 4 noeuds // - la troisième tranche correspond au noeud central // NB: la somme de toutes les tranches = le nombre total de noeud de l'élément inline Tableau const & Ind() const { return IND;}; // ramène les tableaux de permutations permettant de calculer le tableau // de connection permuté, ceci par rapport à la numérotation normale // le second tableau correspond aux noeuds sommets (angle par exemple), les autres tableaux sont // les noeuds internes aux arrêtes ou à l'élément // chaque tableau contient le double du nombre de noeud associé, // Utilisation: soit un noeud de numéro local nl, soit nl <= permut(2).Taille()= t1, dans ce cas il s'agit du // premier tableau : la numérotation sera pour i=1 à t1: permut(2)(nl+i-1) // pour les numéros au-dessus de t1, on décale de permut(1)(1) = d1, c-a-d si permut(3).Taille()=t2 // la numérotation qui suit est : pour j=1 à t2 : permut(3)( // en chantier inline Tableau > const & Permutation() const { return permut;}; //--------- cas de coordonnees locales quelconques ---------------- // retourne les fonctions d'interpolation au point M (en coordonnees locales) virtual const Vecteur& Phi_point(const Coordonnee& M) = 0; // retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales) virtual const Mat_pleine& Dphi_point(const Coordonnee& M) = 0; // en fonction de coordonnees locales, retourne true si le point est a l'interieur // de l'element, false sinon virtual bool Interieur(const Coordonnee& M) = 0; // 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 GGM est nul, dans ce cas retour de M virtual Coordonnee Maxi_Coor_dans_directionGM(const Coordonnee& M) { cout << "\n Pas implante pour l'instant, Maxi_Coor_dans_direction(..."; Sortie(1); Coordonnee P=M; return P;}; // =0; pour l'instant essaie //--------- triangulation des faces lorsqu'elles existes ------- // le retour est la liste de la connection par rapport à la numérotation locale // de tous les facettes triangulaire linéaire qui composent les faces de l'élément // l'indice de premier niveau indique le numéro de la face // l'indice de deuxième niveau correspond à la numérotation du triangle // le troisième indice qui varie de 1 à 3 indique la connection // tab(i)(j)(k) : pour la face i, le triangle j , le numéro du noeud dans la // numérotation locale des noeuds de l'élément const Tableau > >& Trian_lin() const { return NONFt; }; //--------- segmentation des arêtes ------- // le retour est la liste de la connection par rapport à la numérotation locale // de tous les segments linéaire qui composent les arêtes de l'élément // l'indice de premier niveau indique le numéro de l'arête // l'indice de deuxième niveau correspond à la numérotation du segment // le troisième indice qui varie de 1 à 2 indique la connection // tab(i)(j)(k) : pour l'arête i, le segment j , le numéro du noeud dans la // numérotation locale des noeuds de l'élément const Tableau > >& Trian_seg() const { return NONSs; }; // fonctions utilitaires spécifiques à l'interpolation linéaire: // méthode utilisée pour extrapoler une grandeur à partir: // soit de 2 points -> ex: pour une extrapolation linéaire (métrique en 1D) // soit de 3 points -> ex: pour une extrapolation linéaire (métrique en 2D ) // soit de 4 points (non coplanaires) -> ex: pour une extrapolation linéaire (métrique en 3D ) // ces nipt points sont définit par le tableau tab_M, //et en sortie on récupère les dim vecteurs de la base naturelle et les dim vecteurs de la base duale // dans le cas où le calcul n'est pas possible (points trop près) on ramène false, sinon true static bool Bases_naturelles_duales(const Tableau & tab_M ,Tableau & giB,Tableau & giH ); // on donne les vecteurs de la base naturelle, et les vecteurs de la base duale // l'origine de la base O, // et un point A, // en sortie: les coordonnées locale de A dans la base naturelle, et les fonctions d'interpolation // linéaire (1,2 ou 3D ce qui correspond à ligne, triangle, tetraedre) au point A static void Coor_phi(const Coordonnee& O ,const Tableau & giH_, const Coordonnee& A ,Vecteur& phi, Coordonnee& theta) ; protected : // VARIABLES PROTEGEES : int dimension; // dimension de l'element int NBNE; // nombre de noeuds de l'element int NBFE; // nombre de face par element int NBSE; // nombre de segment par element Tableau > NONF; // connexion des noeuds des faces par rapport a ceux des elements // NONF(j)(i) noeud i de la face j = noeud de l'element Tableau > NONS; // connexion des noeuds des segments par rapport a ceux des elements // NONS(j)(i) noeud i du segment j = noeud de l'element Tableau INVCONNEC; // conection d'un élément d'orientation inverse du sens normal, // la numérotation est donnée par rapport à la numérotation normale (de 1 à NBNE) Tableau IND; //tableau donnant les tranches de numérotation qui ont une numérotation cyclique // c-a-d: ex: un quadrangle quadratique à 9 noeuds à 3 tranches: 4, 4, 1 // - la première tranche correspond aux 4 noeuds sommets, la numérotation peut être cyclique (permutation circulaire) // parmi ses 4 noeuds // - la second tranche correspond aux 4 noeuds intermédiaires, là aussi, la numérotation peut être une // permutation circulaire parmi ses 4 noeuds // - la troisième tranche correspond au noeud central // NB: la somme de toutes les tranches = le nombre total de noeud de l'élément // Tableau > permut; // définit les tableaux de permutations permettant de calculer le tableau // de connection permuté, ceci par rapport à la numérotation normale // le premier tableau correspond aux noeuds sommets (angle par exemple), les autres tableaux sont // les noeuds internes aux arrêtes ou à l'élément // en chantier !!!!! // ramène les tableaux de permutations permettant de calculer le tableau // de connection permuté, ceci par rapport à la numérotation normale // le second tableau correspond aux noeuds sommets (angle par exemple), les autres tableaux sont // les noeuds internes aux arrêtes ou à l'élément // chaque tableau contient le double du nombre de noeud associé, // Utilisation: soit un noeud de numéro local nl, soit nl <= permut(2).Taille()= t1, dans ce cas il s'agit du // premier tableau : la numérotation sera pour i=1 à t1: permut(2)(nl+i-1) // pour les numéros au-dessus de t1, on décale de permut(1)(1) = d1, c-a-d si permut(3).Taille()=t2 // la numérotation qui suit est : pour j=1 à t2 : permut(3)( // 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=borne_inf(i) à borne_sup(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) Tableau extrapol; // pour l'element Tableau ptelem ; // coordonnees des points de l'élément Tableau ptInteg ; // coordonnees des points d'integration Tableau tabPhi ; // tabPhi(ni) = phi = fonctions d'interpolation // au point d'interpolation ni, phi a la dimension de nbne Tableau < Mat_pleine > tabDPhi; // tabDPhi(ni) = Dphi tel que, Dphi(i,r) = // valeur de la derivee de la fonction phi(r) par rapport a la coordonnee` // locale i (= 1 ou 2 ou 3, ceci dependant de la dimension de l'element) Vecteur WI; // poids d'integration // pour les faces Tableau < ElemGeomC0 * > face ; // pointe sur les elements faces // pour les segments Tableau < ElemGeomC0 * > seg ; // pointe sur les elements segments // type de géométrie Enum_geom id_geom; // type d'interpolation Enum_interpol id_interpol; // type de point d'intégration Enum_type_pt_integ id_type_pt_integ; // pour la triangulation linéaires des faces lorsqu'elles existent // connexion des noeuds des faces par rapport a ceux des elements // l'indice de premier niveau indique le numéro de la face // l'indice de deuxième niveau correspond à la numérotation du triangle // le troisième indice qui varie de 1 à 3 indique la connection Tableau > > NONFt; // pour la segmentation linéaires des arêtes lorsqu'elles existent // connexion des noeuds des arêtes par rapport a ceux des elements // l'indice de premier niveau indique le numéro de l'arête // l'indice de deuxième niveau correspond à la numérotation du segment // le troisième indice qui varie de 1 à 2 indique la connection Tableau > > NONSs; // METHODES PROTEGEES : // -- méthode identique à Bases_naturelles_duales sauf que l'on utilise une numérotation // indirecte ce qui permet d'éviter de contruire le tableau de coordonnées lorsque celui-ci // existe globalement // méthode utilisée pour extrapoler une grandeur à partir: // soit de 2 points -> ex: pour une extrapolation linéaire (métrique en 1D) // soit de 3 points -> ex: pour une extrapolation linéaire (métrique en 2D ) // soit de 4 points cas = 2 : extrapolation bi-linéaire (métrique en 2D) // soit de 4 points (non coplanaires) cas = 1 -> ex: pour une extrapolation linéaire (métrique en 3D ) // soit de 8 points cas = 1 : pour une extrapolation bi-linéaire (métrique en 3D) // ces nipt points d'intégration, dont les numéros dans ptInteg sont défini par le tableau indirec(i), // i=1 à nipt, avec ptInteg(indirec(i)) le point à considérer, et en sortie on récupère les dim vecteurs // de la base naturelle et les dim vecteurs de la base duale // dans le cas où le calcul n'est pas possible (points trop près) on ramène false, sinon true bool Bases_naturel_duales(const Tableau & indirec ,Tableau & giB,Tableau & giH_ , int cas = 1) const; }; /// @} // end of group #endif