// FICHIER : Element.h
// CLASSE : Element
// 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: .
// La classe Element est une classe abstraite qui regroupe les caracteristiques communes
// a tout type d'element : un numero d'identification, deux identificateurs de type
// enumere (un pour la geometrie, un pour le type d'interpolation), un tableau de
// connexite des noeuds de l'element.
#ifndef ELEMENT_H
#define ELEMENT_H
using namespace std;
#include
#include
#include "Sortie.h"
#include "ElFrontiere.h"
#include "Enum_interpol.h"
#include "Enum_geom.h"
#include "EnumElemTypeProblem.h"
#include "Enum_dure.h"
#include "Mat_pleine.h"
#include "Noeud.h"
#include "Tableau_T.h"
#include "Vecteur.h"
#include "Tenseur.h"
#include "UtilLecture.h"
#include "DdlElement.h"
#include "LoiAbstraiteGeneral.h"
#include
#include "Bloc.h"
#include "ElemGeomC0.h"
#include "Enum_calcul_masse.h"
#include "ParaAlgoControle.h"
#include "Ddl_etendu.h"
#include "Basiques.h"
#include "Enum_type_geom.h"
#include "TypeQuelconque.h"
#include "PlusieursCoordonnees.h"
#include "Enum_PiPoCo.h"
#include "Enum_chargement.h"
/** @defgroup groupe_des_elements_finis
*
* La classe Element est une classe abstraite qui regroupe les caracteristiques communes
* a tout type d'element : un numero d'identification, deux identificateurs de type
* enumere (un pour la geometrie, un pour le type d'interpolation), un tableau de
* connexite des noeuds de l'element.
*
*
* \author Gérard Rio
* \version 1.0
* \date 23/01/97
* \brief groupe relatif aux éléments finis
*
*/
/// @addtogroup groupe_des_elements_finis
/// @{
///
class Element
{
public:
// CONSTRUCTEURS :
// Constructeur par defaut (ou fonction d'un numero d'identification)
Element (int num_maill=0,int num_id=-3);
// Constructeur fonction d'un numero de maillage et du tableau de connexite des noeuds
Element (int num_maill, int num_id,const Tableau& tab);
// Constructeur fonction d'un numéro de maillage, d'un numero d'élément, de trois identificateurs
// (geometrie, interpolation, type de probléme )
// éventuellement un string d'information annexe
Element (int num_maill,int num_id, Enum_interpol id_interp_elt,Enum_geom id_geom_elt,
EnumElemTypeProblem id_prob,string info="");
// Constructeur fonction d'un numéro de maillage, d'un numero d'élément et d'un numéro de maillage
// et de deux noms (geometrie, interpolation)
//et le type de problème traité par l'element
Element (int num_maill,int num_id,const string& nom_interpol,const string& nom_geom,
const string& nom_prob,string info="");
// Constructeur fonction d'un numéro de maillage, d'un numero, du tableau de connexite des noeuds et de
// trois identificateurs et un nom (geometrie, interpolation, type de probleme,
// particularité éventuelle),
// et du type de problème traité par l'element
Element (int num_maill,int num_id,const Tableau& tab,Enum_interpol id_interp_elt,
Enum_geom id_geom_elt,EnumElemTypeProblem id_prob,string info="");
// Constructeur fonction d'un numéro de maillage, d'un numero, du tableau de connexite des noeuds et de
// quatre noms (geometrie, interpolation, type de probleme, particularité éventuelle),
// et du type de problème traité par l'element
Element (int num_maill, int num_id,const Tableau& tab,const string& nom_interpol,const string& nom_geom,
const string& nom_prob,string info="");
// Constructeur de copie
Element (const Element& elt);
// DESTRUCTEUR :
// La variable loicomp doit etre instanciee a l'exterieur de cette classe
// aussi lors de la destruction d'un element il n'y a pas destruction de la
// loi de comportement associee
// on ne recopie pas les adresses pointees car celles-ci peuvent changer,
// donc il vaut mieux les reconstruire si besoin est.
virtual ~Element ();
// METHODES NON VIRTUELLES:
/* // lecture de l'entete de l'element, permet son identification parmi
// tous les elements derivants
void LectureEnTete(UtilLecture * entreePrinc); */
// Affiche les donnees liees a l'element
// n=1 : donnees d'en tete
// n=2 : + tableau de noeuds
// n=3 : + residu
// n=4 : + raideur et matrice de masse si elle existe
void Affiche (int n = 4) const;
// Surcharge de l'operateur = : realise l'egalite de deux elements
Element& operator= (Element& elt);
inline void Change_num_elt (int nouveau_num)
// Modifie le numero d'identification de l'element
// ATTENTION : Les modifications liees au changement de numero de l'element sont
// a la charge de l'utilisateur
{ num_elt=nouveau_num; };
inline void Change_interpol (string& nouveau_nom)
// Remplace le nom du type d'interpolation par nouveau_nom
// (par l'intermediaire du type enumere associe)
// ATTENTION : Les modifications liees au changement du type d'interpolation
// sont a la charge de l'utilisateur.
{ id_interpol=Id_nom_interpol(nouveau_nom); };
inline void Change_interpol (Enum_interpol nouveau_id)
// Remplace l'identificateur d'interpolation par nouveau_id
// ATTENTION : Les modifications liees au changement du type d'interpolation
// sont a la charge de l'utilisateur.
{ id_interpol=nouveau_id; };
inline void Change_geom (string& nouveau_nom)
// Remplace le nom de la geometrie par nouveau_nom
// (par l'intermediaire du type enumere associe)
// ATTENTION : Les modifications liees au changement de geometrie sont a la
// charge de l'utilisateur.
{ id_geom=Id_nom_geom(nouveau_nom); };
inline void Change_geom (Enum_geom nouveau_id)
// Remplace l'identificateur d'interpolation par nouveau_id
// ATTENTION : Les modifications liees au changement de geometrie sont a
// la charge de l'utilisateur.
{ id_geom=nouveau_id; };
inline string Geometrie ()
// Retourne le nom correspondant a la geometrie de l'element
{ return Nom_geom(id_geom); };
inline Enum_geom Id_geometrie () const
// Retourne l'identificateur correspondant a la geometrie de l'element
// (de type enumere)
{ return id_geom; };
inline string Interpolation ()
// Retourne le type d'interpolation de l'element
{ return Nom_interpol(id_interpol); };
inline Enum_interpol Id_interpolation () const
// Retourne l'identificateur associe a l'interpolation de l'element
// (de type enumere)
{ return id_interpol; };
inline string TypeProblem ()
// Retourne le type de problème traité par l'element
{ return NomElemTypeProblem (id_problem); };
// retourne les infos annexes éventuelles de l'éléments
// redéfini que pour les éléments particuliers
virtual string Infos_annexe() const {return infos_annexes;};
inline EnumElemTypeProblem Id_TypeProblem () const
// Retourne l'identificateur associe au problème traité par l'element
// (de type enumere)
{ return id_problem; };
inline int Num_noeud (int i) const
// Retourne le numero global du ieme noeud lie a l'element
{
#ifdef MISE_AU_POINT
if ( (i<1) || (i>tab_noeud.Taille()) )
{cout << "\nErreur : composante inexistante !\n";
cout << "ELEMENT::NUM_NOEUD (int ) \n";
Sortie(1);
};
#endif
return tab_noeud(i)->Num_noeud();
};
inline Noeud& Noeud_elt (int i)
// Retourne le ieme noeud de connexite de l'element
{
#ifdef MISE_AU_POINT
if ( (i<1) || (i>tab_noeud.Taille()) )
{cout << "\nErreur : composante inexistante !\n";
cout << "ELEMENT::NOEUD_ELT (int ) \n";
Sortie(1);
};
#endif
return *tab_noeud(i);
};
inline int Nombre_noeud() const
// Retourne le nombre de noeuds lies a l'element
{ return tab_noeud.Taille(); };
inline int& Num_elt()
// Retourne le numero d'identification de l'element
{ return num_elt; };
// idem en lecture
inline int Num_elt_const() const {return num_elt;};
// retourne le numéro de maillage de l'élément
int Num_maillage() const {return num_maillage;};
// change le numéro de maillage de l'élément
void Change_num_maillage(int newnum) {num_maillage = newnum;};
inline Tableau& Tab_noeud()
// Retourne le tableau des noeuds appartenant a l'element
{ return tab_noeud; };
// change le numéro du noeud: ***** a utiliser avec discernement !!
// car évidemment cela peut complètement changer l'intégrité de l'élément
inline void Change_noeud(int i, Noeud* noe)
{tab_noeud(i) = noe;};
// idem précédent, mais en const, Retourne le tableau des noeuds appartenant a l'element
inline const Tableau& Tab_noeud_const() const
{ return tab_noeud; };
// METHODES VIRTUELLES:
// test si l'element est complet
// = 1 tout est ok, =0 element incomplet
virtual int TestComplet();
// Libere la place occupee par le residu et eventuellement la raideur
virtual void Libere ();
// METHODES VIRTUELLES PURES :
// Lecture des donnees de la classe sur fichier
// attribution des ddl aux noeuds relies a l'element
// en fonction du type d'element
virtual void LectureDonneesParticulieres
(UtilLecture * ,Tableau * ) = 0;
// Calcul du residu local et de la raideur locale a t+dt
// pour le schema implicite
class ResRaid { public : Vecteur* res; Mat_pleine * raid ; };
virtual ResRaid Calcul_implicit (const ParaAlgoControle & pa ) = 0;
// récup uniquement du conteneur raideur (pas forcément rempli, mais de la bonne taille)
Mat_pleine * Conteneur_raideur () {return raideur; };
// Calcul du residu local a l'instant t
// pour le schema explicit, resultat dans le vecteur pointe
virtual Vecteur* CalculResidu_t (const ParaAlgoControle & pa) = 0;
// Calcul du residu local a l'instant tdt
// pour le schema explicit, resultat dans le vecteur pointe
virtual Vecteur* CalculResidu_tdt (const ParaAlgoControle & pa) = 0;
// récup uniquement du conteneur résidu (pas forcément rempli, mais de la bonne taille)
Vecteur* Conteneur_Residu () {return residu;};
// Calcul de la matrice masse pour l'élément
virtual Mat_pleine * CalculMatriceMasse (Enum_calcul_masse id_calcul_masse) = 0;
// procedure permettant de completer l'element apres
// sa creation avec les donnees du bloc transmis
// peut etre appeler plusieurs fois
virtual Element* Complete(BlocGen & bloc,LesFonctions_nD* lesFonctionsnD) = 0;
// mise à jour éventuel de repère d'anisotropie
virtual void Mise_a_jour_repere_anisotropie(BlocGen & bloc,LesFonctions_nD* lesFonctionsnD);
//------- gestion des ddl et grandeurs actives de l'élément --------------
//------- (et non les ddl des noeuds !!) --------------------------------
// actualisation des ddl et des grandeurs actives de t+dt vers t
virtual void TdtversT() = 0;
// actualisation des ddl et des grandeurs actives de t vers tdt
virtual void TversTdt() = 0;
// -------------- grandeurs géométriques relatives à l'élément ----------------
// ramene l'element geometrique
virtual ElemGeomC0& ElementGeometrique() const =0;
// ramene l'element geometrique en constant
virtual const ElemGeomC0& ElementGeometrique_const() const =0;
// calcul d'une longueur géométrique mini représentative de l'élément
// cas = 1: correspond à la distance mini entre deux noeuds coins de l'élément
double LongueurGeometrique_mini(int cas) const;
// ramène la coordonnée maxi dans la direction i de l'ensemble des noeuds de l'élément
// à l'instant tdt, ou t ou t=0 en fonction de temps
double Maxi_xi_noeud(int i, Enum_dure temps);
// calcul d'une longueur géométrique moyenne représentative de l'élément
// cas = 1: correspond à la distance moyenne entre deux noeuds coins de l'élément
// cas = 2: dans le cas 1D -> distance moyenne entre noeuds extrèmes
// en 2D: quadrangle: racine carré de la surface; triangle: racine carré de 2*surface
// en 3D: hexa: racine cubique de vol; penta: racine cub de 2*vol, tétra: racine cub 6*vol
double LongueurGeometrique_caracteristique(int cas) const;
// récupération du volume de l'élément (qui doit avoir été calculé dans une des classes dérivées
// par exemple en mécanique via un calcul explicite ou implicite d'équilibre mécanique
// pour un élément 3D: le volume au sens classique
// pour un élément 2D: il s'agit de la surface * l'épaisseur
// pour un élément 1D: il s'agit de la longueur * la section
double Volume() const {return volume;};
// calcul le volume entre l'élément (=surface2D) et les plans de ref: yz, xz, xy, dans cet ordre
// valable uniquement pour les éléments 2D dans un espace 3D, ramène une dim nulle sinon
// le calcul est approché, il est effectué à partir d'une triangulation de la surface de l'élément
const Coordonnee & VolumePlan();
// modification de l'orientation de l'élément en fonction de cas_orientation
// =0: inversion simple (sans condition) de l'orientation
// si cas_orientation est diff de 0: on calcul le jacobien aux différents points d'intégration
// 1. si tous les jacobiens sont négatifs on change d'orientation
// 2. si tous les jacobiens sont positifs on ne fait rien
// 3. si certains jacobiens sont positifs et d'autres négatifs message
// d'erreur et on ne fait rien
// ramène true: s'il y a eu changement effectif, sinon false
virtual bool Modif_orient_elem(int cas_orientation) = 0;
// calcul éventuel de la normale à un noeud
// ce calcul existe pour les éléments 2D, 1D axi, et aussi pour les éléments 1D
// qui possède un repère d'orientation
// en retour coor = la normale si coor.Dimension() est = à la dimension de l'espace
// si le calcul n'existe pas --> coor.Dimension() = 0
// ramène un entier :
// == 1 : calcul normal
// == 0 : problème de calcul -> coor.Dimension() = 0
// == 2 : indique que le calcul n'est pas licite pour le noeud passé en paramètre
// c'est le cas par exemple des noeuds exterieurs pour les éléments SFE
// mais il n'y a pas d'erreur, c'est seulement que l'élément n'est pas ad hoc pour
// calculer la normale à ce noeud là
// temps: indique à quel moment on veut le calcul
virtual int CalculNormale_noeud(Enum_dure temps, const Noeud& noe
,Coordonnee& coor) = 0;
//----------- intégration sur volume et temps ---------------
// --- cas des intégrales volumiques: définition du conteneur, il peut également s'agir d'une intégration temporelle en +
// d'où la grandeur courante et celle à t
// dans le cas où il n'y a pas d'intégrale, retour d'un pointeur NULL
// 1) retour des intégrations de volume uniquement
// cas des valeurs courantes
const Tableau * Integ_vol_typeQuel() const {return integ_vol_typeQuel;};
// cas des valeurs à l'incrément précédent
const Tableau * Integ_vol_typeQuel_t() const {return integ_vol_typeQuel_t;};
// une liste d'index qui est utilisable par les méthodes qui récupère les infos
// il y a un index par intégrale
// NB: si le numéro est négatif, cela veut dire que l'intégrale est figée, on n'intègre plus
// cela vient d'un restart par exemple, qui contenait l'ingégrale, mais l'utilisateur
// ne veut plus que l'intégration continue
const Tableau * Index_Integ_vol_typeQuel() const {return index_Integ_vol_typeQuel;};
// 2) intégration de volume et en temps: donc on commule le delta
// cas des valeurs courantes
const Tableau * Integ_vol_t_typeQuel() const {return integ_vol_t_typeQuel;};
// cas des valeurs à l'incrément précédent
const Tableau * Integ_vol_t_typeQuel_t() const {return integ_vol_t_typeQuel_t;};
// une liste d'index qui est utilisable par les méthodes qui récupère les infos
// il y a un index par intégrale
const Tableau * Index_Integ_vol_t_typeQuel() const {return index_Integ_vol_t_typeQuel;};
//------- calcul d'erreur, remontée des contraintes -------------------
// calcul du résidu et de la matrice de raideur pour la remontée des contraintes
// et le calcul d'erreur
class Er_ResRaid { public :
Er_ResRaid(){}; // par défaut
Er_ResRaid(Tableau * resEr, Mat_pleine* raidEr) :
resErr(resEr),raidErr(raidEr) {};
Tableau * resErr; Mat_pleine* raidErr;
};
// pour l'instant uniquement virtuel, par la suite devra être virtuelle pure
//1) remontée aux contraintes
virtual Er_ResRaid ContrainteAuNoeud_ResRaid();
// 2) remontée aux erreurs aux noeuds
virtual Er_ResRaid ErreurAuNoeud_ResRaid();
// retourne les tableaux de ddl associés aux noeuds, gere par l'element
// qui sont actifs au moment de la demande
// ce tableau et specifique a l'element
virtual const DdlElement & TableauDdl() const = 0;
// retourne la liste de tous les types de ddl interne actuellement utilisés
// par l'élément (actif ou non), sont exclu de cette liste les ddl des noeuds
// reliés à l'élément (ddl implique grandeur uniquement scalaire !)
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
virtual List_io Les_type_de_ddl_internes(bool absolue) const = 0;
// idem pour les grandeurs évoluées c'est-à-dire directement sous forme de vecteur, tenseurs, scalaire ....
virtual List_io Les_type_evolues_internes(bool absolue) const = 0;
// idem pour les données particulières
virtual List_io Les_types_particuliers_internes(bool absolue) const = 0;
// retourne la liste de toutes les grandeurs quelconques relatives aux faces de
// l'élément (actif ou non),
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
virtual List_io Les_type_quelconque_de_face(bool absolue) const = 0;
// retourne la liste de toutes les grandeurs quelconques relatives aux arêtes de
// l'élément (actif ou non),
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
virtual List_io Les_type_quelconque_de_arete(bool absolue) const = 0;
// ----- activation ou non des ddl primaires, ----
// ------ défini dans les classes dérivées ----
// inactive les ddl primaires
virtual void Inactive_ddl_primaire() {};
// active les ddl primaires
virtual void Active_ddl_primaire() {};
// sortie de l'erreur à l'élément
virtual double Erreur() = 0;
// acquisition d'une loi de comportement
virtual void DefLoi(LoiAbstraiteGeneral * NouvelleLoi) = 0;
// Compléter pour la mise en place de la gestion de l'hourglass via un comportement
// ramène un pointeur null si la complexion n'est pas adaptée à l'élément
virtual Element* Complet_Hourglass(LoiAbstraiteGeneral * NouvelleLoi, const BlocGen & bloc) = 0;
// méthode pour indiquer à l'élément de préparer ses paramètres internes pour un futur calcul suivant une précision donnée
// precision = 0 : aucune précision demandée, precision >=0 : précision maximale demandée
void Drapeau_preparation_calcul_precis(int precision) {prepa_niveau_precision = precision;};
// calcul d'un point dans l'élément réel en fonction des coordonnées dans l'élément de référence associé
// temps: indique si l'on veut les coordonnées à t = 0, ou t ou tdt
// 1) cas où l'on utilise la place passée en argument
virtual Coordonnee & Point_physique(const Coordonnee& c_int,Coordonnee & co,Enum_dure temps) = 0;
// 2) cas avec création
Coordonnee Point_physique(const Coordonnee& c_int,Enum_dure temps)
{ Coordonnee co(ParaGlob::Dimension());Point_physique(c_int,co,temps);return co;};
// 3) cas où l'on veut les coordonnées aux 1, 2 ou trois temps selon la taille du tableau t_co
virtual void Point_physique(const Coordonnee& c_int,Tableau & t_co) = 0;
// vérification de l'existence d'un point d'intégration correspondant à un ddl
virtual bool Existe_pt_integ (int nbptinteg, Enum_ddl) const;
// ramène le nombre total de points d'intégration correspondant à un type énuméré
// peut-être surchargé pour des éléments particuliers (type sfe par exemple)
virtual int NbPtInteg(Enum_ddl enu) const {return this->ElementGeometrie(enu).Nbi();};
// ramene l'element geometrique correspondant au ddl passé en paramètre
virtual ElemGeomC0& ElementGeometrie(Enum_ddl ddl) const =0;
// ramène le nombre de grandeurs génératrices pour un pt d'integ, correspondant à un type enuméré
// peut-être surchargé pour des éléments particuliers
virtual int NbGrandeurGene(Enum_ddl enu) const =0;
// <<<<<< Pour les plaques et coques: >>>>>>>
// indique si l'élément fait partie des plaques, poutres ou coques ou aucun de ce types
Enum_PiPoCo PoutrePlaqueCoque() const {return TypePiPoCo(id_interpol,id_geom);};
// ramène le nombre de points d'intégration de surface correspondant à un type énuméré
// ramène 0 si l'élément n'est pas une plaque ou coque
virtual int NbPtIntegSurface(Enum_ddl ) const {return 0;};
// ramène le nombre de points d'intégration en épaisseur correspondant à un type énuméré
// ramène 0 si l'élément n'est pas une plaque ou coque
virtual int NbPtIntegEpaiss(Enum_ddl ) const {return 0;};
// ramene l'element geometrique de surface correspondant au ddl passé en paramètre
// ou null si ce n'est pas définie, dans ce cas si l'élément géométrique de surface est 2D
// cela signifie qu'il faut se référer à l'élément générique: ElementGeometrie(...
virtual ElemGeomC0* ElementGeometrieSurface(Enum_ddl ) const {return NULL;};
// ramene l'element geometrique d'épaisseur correspondant au ddl passé en paramètre
// ou null si ce n'est pas définie, dans ce cas si l'élément géométrique de surface est 2D
// cela signifie que tout est constant (identique) dans l'épaisseur
virtual ElemGeomC0* ElementGeometrieEpaiss(Enum_ddl ) const {return NULL;};
// <<<<<< fin Pour les plaques et coques: >>>>>>>
// calcul si un point est a l'interieur de l'element ou non
// il faut que M est la dimension globale
// les trois fonctions sont pour l'etude a t=0, t et tdt
// retour : =0 le point est externe, =1 le point est interne ,
// = 2 le point est sur la frontière à la précision près
// coor_locales : s'il est différent de NULL, est affecté des coordonnées locales calculées,
// uniquement précises si le point est interne
virtual int Interne_0(const Coordonnee& M,Coordonnee* coor_locales=NULL) =0;
virtual int Interne_t(const Coordonnee& M,Coordonnee* coor_locales=NULL) =0;
virtual int Interne_tdt(const Coordonnee& M,Coordonnee* coor_locales=NULL) =0;
// ======== sortie fichier de commande ====================================
// ramène un tableau de pointeur d'élément qui sont concerné
// par la sortie des commandes
static Tableau Info_commande_Element(UtilLecture * entreePrinc);
// affichage d'info en fonction de ordre
// ordre = "commande" : affichage d'un exemple d'entree pour l'élément
virtual void Info_com_Element(UtilLecture * entreePrinc,string& ordre,Tableau * tabMaillageNoeud) = 0;
// ======== affichage ou récupération d'informations =============
// affichage dans la sortie transmise, des variables duales "nom"
// aux differents points d'integration
// dans le cas ou nom est vide, affichage de "toute" les variables
virtual void AfficheVarDual(ofstream& sort, Tableau& nom) = 0;
// retourne un numero d'ordre d'un point le plus près ou est exprimé la grandeur enum
// par exemple un point d'intégration, mais n'est utilisable qu'avec des méthodes particulières
// par exemple CoordPtInteg, ou Valeur_a_diff_temps
// car le numéro d'ordre peut-être différent du numéro d'intégration au sens classique
// temps: dit si c'est à 0 ou t ou tdt
virtual int PointLePlusPres(Enum_dure temps,Enum_ddl enu, const Coordonnee& M) = 0;
// recuperation des coordonnées du point de numéro d'ordre iteg pour
// la grandeur enu
// temps: dit si c'est à 0 ou t ou tdt
// si erreur retourne erreur à true
virtual Coordonnee CoordPtInteg(Enum_dure temps,Enum_ddl enu,int iteg,bool& erreur) = 0;
// recuperation des coordonnées du point d'intégration numéro = iteg pour
// la face : face
// temps: dit si c'est à 0 ou t ou tdt
// si erreur retourne erreur à true
virtual Coordonnee CoordPtIntFace(int face, Enum_dure temps,int iteg,bool& erreur) = 0;
// recuperation des coordonnées du point d'intégration numéro = iteg pour
// la face : face
// temps: dit si c'est à 0 ou t ou tdt
// si erreur retourne erreur à true
virtual Coordonnee CoordPtIntArete(int arete, Enum_dure temps,int iteg,bool& erreur) = 0;
// récupération des valeurs au numéro d'ordre = iteg pour
// les grandeur enu: ici il s'agit de grandeurs scalaires
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
virtual Tableau Valeur_a_diff_temps
(bool absolue,Enum_dure enu_t,const List_io& enu,int iteg) = 0;
// récupération des valeurs au numéro d'ordre = iteg pour les grandeurs enu
// ici il s'agit de grandeurs tensorielles, le retour s'effectue dans la liste
// de conteneurs quelconque associée
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
virtual void ValTensorielle_a_diff_temps(bool absolue,Enum_dure enu_t,List_io& enu,int iteg) = 0;
// récupération de grandeurs particulières au numéro d'ordre = iteg
// celles-ci peuvent être quelconques
// en retour liTQ est modifié et contiend les infos sur les grandeurs particulières
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
virtual void Grandeur_particuliere (bool absolue,List_io& liTQ,int iteg) = 0;
// récupération de grandeurs particulières pour une face au numéro d'ordre = iteg
// celles-ci peuvent être quelconques
// en retour liTQ est modifié et contiend les infos sur les grandeurs particulières
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
virtual void Grandeur_particuliere_face (bool absolue,List_io& liTQ,int face, int iteg) = 0;
// récupération de grandeurs particulières pour une arête au numéro d'ordre = iteg
// celles-ci peuvent être quelconques
// en retour liTQ est modifié et contiend les infos sur les grandeurs particulières
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
virtual void Grandeur_particuliere_arete (bool absolue,List_io& liTQ,int arete, int iteg) = 0;
// --- transfert des grandeurs des points d'intégration aux noeuds
// transfert de ddl des points d'intégrations (de tous) aux noeuds d'un éléments (on ajoute aux noeuds, on ne remplace pas)
// les ddl doivent déjà exister aux noeuds sinon erreur
// il doit s'agir du même type de répartition de pt d'integ pour toutes les grandeurs
// tab_val(i)(j) : valeur associée au i ième pt d'integ et au j ième ddl_enum_etendu
virtual void TransfertAjoutAuNoeuds(const List_io < Ddl_enum_etendu >& lietendu
,const Tableau > & tab_val,int cas) = 0;
// transfert de type quelconque des points d'intégrations (de tous) aux noeuds d'un éléments (on ajoute aux noeuds,
// on ne remplace pas). Les types quelconques doivent déjà exister
// un tableau dans tab_liQ correspondent aux grandeurs quelconque pour tous les pt integ,
// tab_liQ(i) pour le pt d'integ i
// liQ_travail: est une liste de travail qui sera utilisée dans le transfert
virtual void TransfertAjoutAuNoeuds(const Tableau >& tab_liQ
,List_io < TypeQuelconque > & liQ_travail,int cas) = 0;
// accumulation aux noeuds de grandeurs venant des éléments vers leurs noeuds (exemple la pression appliquée)
// autres que celles aux pti classiques, mais directements disponibles
// le contenu du conteneur stockées dans liQ est utilisé en variable intermédiaire
virtual void Accumul_aux_noeuds(const List_io < Ddl_enum_etendu >& lietendu
,List_io < TypeQuelconque > & liQ,int cas) = 0;
// ============ Calcul des frontieres de l'element================
// tout d'abord une explication sur la terminologie
// on appelle frontières minimales de l'éléments les frontières naturelles c'est-à-dire
// pour les éléments 1D : les noeuds aux l'extrémitées en monde 1D
// sinon également l'élément en monde 2D et 3D
// pour les éléments 2D : les arrêtes de l'élément en monde 2D
// sinon également la surface de l'élément en monde 2D et 3D
// pour les éléments 3D : les surfaces externes de l'élément
// Calcul des frontieres minimales de l'element et retour d'un tableau tabb des frontières
// creation des elements frontieres et stockage dans l'element
// si c'est la première fois sinon il y a seulement retour du tableau de ces elements
// a moins que le paramètre force est mis a true dans ce dernier cas seul les frontière effacées sont recréée
virtual Tableau const & Frontiere(bool force = false) = 0;
// avec la méthode Frontiere() on obtient un tableau de frontières tabb(i) , qui peut contenir des points, lignes ou surfaces
// la méthode qun peu redondante, mais pratique, qui ramène le numéro local "n" de frontière dans le type en fonction du numéro global "i"
// d'une manière générale supposons que tabb contient des lignes, points et surfaces, alors:
// si tabb(i) est une surface, Num_de_frontiere_dans_le_type(i) donnera le numéro de la surface
// si tabb(i) est une ligne, Num_de_frontiere_dans_le_type(i) donnera le numéro de la ligne
// si tabb(i) est un point, Num_de_frontiere_dans_le_type(i) donnera le numéro du point
// ramène 0 si i > tabb.Taille() ou < 1
int Num_de_frontiere_dans_le_type(int i) const;
// indique si oui ou non il existe des éléments frontières
bool Existe_frontiere()const {return tabb.Taille();};
// suppression d'un élément frontière
void SupprimeFront(ElFrontiere* elemFront);
// suppression de tous les éléments frontières
// y compris les linéiques et surfaciques spécifiques éventuellement défini par les
// fonctions Frontiere_lineique et par Frontiere_surfacique
void SupprimeFront();
// ------ cas particulier de frontières non spécifiquement défini -----
// pour les éléments 3D les éléments frontières sont des surfaces qui contiennent
// les arêtes. Les arêtes ne sont donc pas spécifiquement définies comme frontière
// lorsque l'on veut spécifiquement les définir il faut le demander
// idem pour les éléments 1D en monde 1D, et les surfaces pour les éléments 2D en monde
// 2D
// >>>> par contre pour les éléments 2D, la méthode Frontiere_lineique appel la <<<
// >>>> la méthode générale Frontiere, la création crée toutes les frontières de <<<
// >>>> l'élément, la suppression est également équivalente à SupprimeFront() <<<
// ramène la frontière point
// éventuellement création des frontieres points de l'element et stockage dans l'element
// si c'est la première fois sinon il y a seulement retour de l'elements
// a moins que le paramètre force est mis a true
// dans ce dernier cas la frontière effacéee est recréée
// num indique le numéro du point à créer (numérotation EF)
virtual ElFrontiere* const Frontiere_points(int num,bool force = false) = 0;
// ramène la frontière linéique
// éventuellement création des frontieres linéique de l'element et stockage dans l'element
// si c'est la première fois et en 3D sinon il y a seulement retour de l'elements
// a moins que le paramètre force est mis a true
// dans ce dernier cas la frontière effacéee est recréée
// num indique le numéro de l'arête à créer (numérotation EF)
virtual ElFrontiere* const Frontiere_lineique(int num,bool force = false) = 0;
// ramène la frontière surfacique
// éventuellement création des frontieres surfacique de l'element et stockage dans l'element
// si c'est la première fois sinon il y a seulement retour de l'elements
// a moins que le paramètre force est mis a true
// dans ce dernier cas la frontière effacéee est recréée
// num indique le numéro de la surface à créer (numérotation EF)
virtual ElFrontiere* const Frontiere_surfacique(int num,bool force = false) = 0;
// pas de fonction "suppression" car en fait c'est une fonction frontière déguisée
// il faut donc se servir de SupprimeFront()
// ramene vrai si la surface numéro ns existe pour l'élément
virtual bool SurfExiste(int ns) const =0;
// ramene vrai si l'arête numéro na existe pour l'élément
virtual bool AreteExiste(int na) const =0;
// ramene le numero de la frontière passée en argument si elle existe actuellement au niveau de l'élément
// sinon ramène 0
// ramene également type_front: qui indique le type de frontière: POINT_G, LIGNE ou SURFACE
// c'est une méthode très longue, a utiliser avec précaution
int Num_frontiere(const ElFrontiere& fronti, Enum_type_geom& type_front) const;
// Calcul spécifiques des frontieres de l'element et retour d'un tableau tabb des frontières
// creation des elements frontieres et stockage dans l'element
// la création n'a lieu qu'au premier appel
// ou lorsque l'on force le paramètre force a true
// dans ce dernier cas seul les frontière effacées sont recréée
// cas :
// = 0 -> on veut toutes les frontières
// = 1 -> on veut uniquement les surfaces
// = 2 -> on veut uniquement les lignes
// = 3 -> on veut uniquement les points
// = 4 -> on veut les surfaces + les lignes
// = 5 -> on veut les surfaces + les points
// = 6 -> on veut les lignes + les points
// virtual Tableau const & Frontiere_specifique(int cas, bool force = false) = 0;
// mise à jour de la boite d'encombrement de l'élément, suivant les axes I_a globales
// en retour coordonnées du point mini dans retour.Premier() et du point maxi dans .Second()
virtual const DeuxCoordonnees& Boite_encombre_element(Enum_dure temps);
// récupération de la boite d'encombrement de l'élément (la dernière calculée selon Boite_encombre_element)
const DeuxCoordonnees & RecupBoite_encombre_element() const {return boite_encombre;};
// test si le point passé en argument appartient à la boite d'encombrement de l'élément
// tous les points sont supposées avoir la même dimension
// si depass est différent de 0, les maxi et mini de la boite sont augmentés de "depass"
bool In_boite_emcombrement_elem(const Coordonnee& M,double depass = 0.) const;
// ========== calcul des seconds membres suivant les chargements =======
// initialisation éventuelle, nécessaire avant d'appliquer l'ensemble des charges
// par exemple des stockages intermédiaires
virtual void Initialisation_avant_chargement() = 0;
// cas d'un chargement surfacique, sur les frontières des éléments
// force indique la force surfacique appliquée
// numface indique le numéro de la face chargée
// retourne le second membre résultant
// NB: il y a une définition par défaut pour les éléments qui n'ont pas de
// surface externe -> message d'erreur d'où le virtuel et non virtuel pur
// -> explicite à t
virtual Vecteur SM_charge_surfacique_E_t
(const Coordonnee& force,Fonction_nD* pt_fonct,int numFace,const ParaAlgoControle & pa) ;
// -> explicite à tdt
virtual Vecteur SM_charge_surfacique_E_tdt
(const Coordonnee& force,Fonction_nD* pt_fonct,int numFace,const ParaAlgoControle & pa) ;
// -> implicite,
// pa: permet de déterminer si oui ou non on calcul la contribution à la raideur
// retourne le second membre et la matrice de raideur correspondant
virtual ResRaid SMR_charge_surfacique_I
(const Coordonnee& force,Fonction_nD* pt_fonct,int numFace,const ParaAlgoControle & pa) ;
// cas d'un chargement de type pression, sur les frontières des éléments
// pression indique la pression appliquée
// numface indique le numéro de la face chargée
// retourne le second membre résultant
// NB: il y a une définition par défaut pour les éléments qui n'ont pas de
// surface externe -> message d'erreur d'où le virtuel et non virtuel pur
// -> explicite à t
// la fonction nD est utilisée que si elle ne dépend pas strictement de grandeurs globales
virtual Vecteur SM_charge_pression_E_t
(double pression,Fonction_nD* pt_fonct, int numFace,const ParaAlgoControle & pa) ;
// -> explicite à tdt
virtual Vecteur SM_charge_pression_E_tdt
(double pression,Fonction_nD* pt_fonct,int numFace,const ParaAlgoControle & pa) ;
// -> implicite,
// pa: permet de déterminer si oui ou non on calcul la contribution à la raideur
// retourne le second membre et la matrice de raideur correspondant
virtual ResRaid SMR_charge_pression_I
(double pression,Fonction_nD* pt_fonct,int numFace,const ParaAlgoControle & pa) ;
// cas d'un chargement de type pression unidirectionnelle, sur les frontières des éléments
// presUniDir indique le vecteur appliquée
// numface indique le numéro de la face chargée
// retourne le second membre résultant
// NB: il y a une définition par défaut pour les éléments qui n'ont pas de
// surface externe -> message d'erreur d'où le virtuel et non virtuel pur
// -> explicite à t
virtual Vecteur SM_charge_presUniDir_E_t
(const Coordonnee& presUniDir,Fonction_nD* pt_fonct,int numFace,const ParaAlgoControle & pa) ;
// -> explicite à tdt
virtual Vecteur SM_charge_presUniDir_E_tdt
(const Coordonnee& presUniDir,Fonction_nD* pt_fonct,int numFace,const ParaAlgoControle & pa) ;
// -> implicite,
// pa: permet de déterminer si oui ou non on calcul la contribution à la raideur
// retourne le second membre et la matrice de raideur correspondant
virtual ResRaid SMR_charge_presUniDir_I
(const Coordonnee& presUniDir,Fonction_nD* pt_fonct,int numFace
,const ParaAlgoControle & pa) ;
// cas d'un chargement lineique, sur les aretes frontières des éléments
// force indique la force lineique appliquée
// numarete indique le numéro de l'arete chargée
// retourne le second membre résultant
// NB: il y a une définition par défaut pour les éléments qui n'ont pas
// d'arete externe -> message d'erreur d'où le virtuel et non virtuel pur
// -> explicite à t
virtual Vecteur SM_charge_lineique_E_t
(const Coordonnee& force,Fonction_nD* pt_fonct,int numArete,const ParaAlgoControle & pa) ;
// -> explicite à tdt
virtual Vecteur SM_charge_lineique_E_tdt
(const Coordonnee& force,Fonction_nD* pt_fonct,int numArete,const ParaAlgoControle & pa) ;
// -> implicite,
// pa: permet de déterminer si oui ou non on calcul la contribution à la raideur
// retourne le second membre et la matrice de raideur correspondant
virtual ResRaid SMR_charge_lineique_I
(const Coordonnee& force,Fonction_nD* pt_fonct,int numArete,const ParaAlgoControle & pa) ;
// cas d'un chargement lineique suiveuse, sur les aretes frontières des éléments 2D (uniquement)
// force indique la force lineique appliquée
// numarete indique le numéro de l'arete chargée
// retourne le second membre résultant
// NB: il y a une définition par défaut pour les éléments qui n'ont pas
// d'arete externe -> message d'erreur d'où le virtuel et non virtuel pur
// -> explicite à t
virtual Vecteur SM_charge_lineique_Suiv_E_t
(const Coordonnee& force,Fonction_nD* pt_fonct,int numArete,const ParaAlgoControle & pa) ;
// -> explicite à tdt
virtual Vecteur SM_charge_lineique_Suiv_E_tdt
(const Coordonnee& force,Fonction_nD* pt_fonct,int numArete,const ParaAlgoControle & pa) ;
// -> implicite,
// pa: permet de déterminer si oui ou non on calcul la contribution à la raideur
// retourne le second membre et la matrice de raideur correspondant
virtual ResRaid SMR_charge_lineique_Suiv_I
(const Coordonnee& force,Fonction_nD* pt_fonct,int numArete
,const ParaAlgoControle & pa) ;
// ---- cas d'un chargement en force volumique,
// force indique la force volumique appliquée
// retourne le second membre résultant
// -> explicite à t
virtual Vecteur SM_charge_volumique_E_t
(const Coordonnee& force,Fonction_nD* pt_fonct,const ParaAlgoControle & pa,bool sur_volume_finale_) ;
// -> explicite à tdt
virtual Vecteur SM_charge_volumique_E_tdt
(const Coordonnee& force,Fonction_nD* pt_fonct,const ParaAlgoControle & pa,bool sur_volume_finale_) ;
// -> implicite,
// pa: permet de déterminer si oui ou non on calcul la contribution à la raideur
// retourne le second membre et la matrice de raideur correspondant
virtual ResRaid SMR_charge_volumique_I
(const Coordonnee& force,Fonction_nD* pt_fonct,const ParaAlgoControle & pa,bool sur_volume_finale_) ;
// --- cas d'un chargement surfacique hydrostatique,
// poidvol: indique le poids volumique du liquide
// M_liquide : un point de la surface libre
// dir_normal_liquide : direction normale à la surface libre
// sans_limitation : indique s'il y a une limitation du calcul pour les seuls positions négatives
// retourne le second membre résultant
// -> explicite à t
virtual Vecteur SM_charge_hydrostatique_E_t(const Coordonnee& dir_normal_liquide,const double& poidvol
,int numFace,const Coordonnee& M_liquide,const ParaAlgoControle & pa,bool sans_limitation) ;
// -> explicite à tdt
virtual Vecteur SM_charge_hydrostatique_E_tdt(const Coordonnee& dir_normal_liquide,const double& poidvol
,int numFace,const Coordonnee& M_liquide,const ParaAlgoControle & pa,bool sans_limitation) ;
// -> implicite,
// pa: permet de déterminer si oui ou non on calcul la contribution à la raideur
// retourne le second membre et la matrice de raideur correspondant
virtual ResRaid SMR_charge_hydrostatique_I(const Coordonnee& dir_normal_liquide,const double& poidvol
,int numFace,const Coordonnee& M_liquide,const ParaAlgoControle & pa,bool sans_limitation) ;
// cas d'un chargement surfacique hydro-dynamique,
// Il y a trois forces: une suivant la direction de la vitesse: de type traînée aerodynamique
// Fn = poids_volu * fn(V) * S * (normale*u) * u, u étant le vecteur directeur de V (donc unitaire)
// une suivant la direction normale à la vitesse de type portance
// Ft = poids_volu * ft(V) * S * (normale*u) * w, w unitaire, normal à V, et dans le plan n et V
// une suivant la vitesse tangente de type frottement visqueux
// T = to(Vt) * S * ut, Vt étant la vitesse tangentielle et ut étant le vecteur directeur de Vt
// coef_mul: est un coefficient multiplicateur global (de tout)
// retourne le second membre résultant
// -> explicite à t
virtual Vecteur SM_charge_hydrodynamique_E_t( Courbe1D* frot_fluid,const double& poidvol
, Courbe1D* coef_aero_n,int numFace,const double& coef_mul
, Courbe1D* coef_aero_t,const ParaAlgoControle & pa);
// -> explicite à tdt
virtual Vecteur SM_charge_hydrodynamique_E_tdt( Courbe1D* frot_fluid,const double& poidvol
, Courbe1D* coef_aero_n,int numFace,const double& coef_mul
, Courbe1D* coef_aero_t,const ParaAlgoControle & pa);
// -> implicite,
// pa: permet de déterminer si oui ou non on calcul la contribution à la raideur
// retourne le second membre et la matrice de raideur correspondant
virtual ResRaid SMR_charge_hydrodynamique_I( Courbe1D* frot_fluid,const double& poidvol
, Courbe1D* coef_aero_n,int numFace,const double& coef_mul
, Courbe1D* coef_aero_t,const ParaAlgoControle & pa) ;
//============= lecture écriture dans base info ==========
// cas donne le niveau de la récupération
// = 1 : on récupère tout
// = 2 : on récupère uniquement les données variables (supposées comme telles)
// tabMaillageNoeud : contiend les noeuds du maillage de définition de l'élément
virtual void Lecture_base_info
(ifstream& ent,const Tableau * tabMaillageNoeud,const int cas) = 0;
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
virtual void Ecriture_base_info(ofstream& sort,const int cas) = 0;
//-------------- pour modification d'éléments ---------------------------
// définition d'un conteneur pour la définition d'un type d'élément
class Signature
{ public:
// surcharge de l'operator d'ecriture
friend ostream & operator << (ostream &, const Signature &) ;
// constructeur de création
Signature(Enum_interpol id_pol,Enum_geom om,EnumElemTypeProblem blem,string inf):
id_interpol(id_pol),id_geom(om),id_problem(blem),infos_annexes(inf) {};
Signature(const Signature& a): // constructeur de copie
id_interpol(a.id_interpol),id_geom(a.id_geom),id_problem(a.id_problem),infos_annexes(a.infos_annexes) {};
Signature& operator = ( const Signature& a); // surcharge de l'affectation
bool operator == ( const Signature& a); // surcharge de l'égalité
bool operator != ( const Signature& a); // surcharge de non égalité
// données publiques car conteneur de base pour l'échange typée
Enum_interpol id_interpol; // identificateur d'interpolation
Enum_geom id_geom; // identificateur de geometrie
EnumElemTypeProblem id_problem; // identificateur du type de problem
string infos_annexes; // infos annexes complémentaires permettant une distinction
// plus fine entre plusieurs éléments identiques pour
// les trois énumérations (par exemple n'ayant pas le même
// nombre de pt d'integ
};
// ramène la signature de l'élément
Signature Signature_element() const
{ Signature iter(id_interpol,id_geom,id_problem,infos_annexes); return iter;};
// test si this et l'élément passé en paramètre sont identiques uniquement concernant la signature et la géométrie
// par contre il peut y avoir des différences au niveau de la loi, de la matière etc.
// les éléments peuvent être de maillages différents
// ramène true s'il y a identité, false sinon
bool Meme_signature_et_geometrie(const Element& elem)const;
// ======== choix d'un element ====================================
// choix d'un element derive et affectation d'un pointeur d'element
// en fonction du num de maillage, de id_geom, id_interpol, id_typede problem, et éventuellement d'une
// chaine de caractère discriminante
// le numero d'element : num_elt, est affecte a l'element pointe par ptr
// fonctionnement : le choix est effectue grace a la liste static "listTypeElement"
// qui est rempli au moment du chargement du programme, par toutes
// classes derivees
// dans le cas ou l'operation echoue, renvoi du pointeur null
static Element* Choix_element(int num_mail,int num_elt,Enum_geom id_geom
,Enum_interpol id_interpol,EnumElemTypeProblem id_typeProb
,const string& discriminant);
// idem en fonction de la signature
static Element* Choix_element(int num_mail,int num_elt,Signature signa);
// renseignement d'un élément complet à partir d'un élément incomplet de même type
// retourne les nouveaux noeuds construit à partir de l'interpolation incomplète.
// dans le cas où l'élément n'est pas concerné, retourne une liste vide
// ramène également une liste de même dimension contenant les bornes en numéros de noeuds
// entre lesquelles il faut définir les nouveaux numéros de noeuds si l'on veut conserver
// une largeur de bande optimisée du même type
// nbnt+1: est le premier numéro de noeud utilisable pour les nouveaux noeuds
virtual list Construct_from_imcomplet(const Element & elem,list & li_bornes, int nbnt);
// renseignement d'un élément quadratique incomplet à partir d'un élément linéaire de même type
// retourne les nouveaux noeuds construit à partir de l'interpolation linéqire.
// dans le cas où l'élément n'est pas concerné, retourne une liste vide
// ramène également une liste de même dimension contenant les bornes en numéros de noeuds
// entre lesquelles il faut définir les nouveaux numéros de noeuds si l'on veut conserver
// une largeur de bande optimisée du même type
// nbnt+1: est le premier numéro de noeud utilisable pour les nouveaux noeuds
virtual list Construct_from_lineaire(const Element & elem,list & li_bornes, int nbnt);
// réaffectation d'un pointeur de noeud
// ramène faux si l'opération n'est pas possible
bool Reaffectation_pointeur_noeud(Noeud * ancien, Noeud * nouveau);
// création d'un élément de copie: utilisation de l'opérateur new et du constructeur de copie
virtual Element* Nevez_copie() const = 0;
// ========================= variables protégées ===========================
protected :
int num_elt; // numero d'identification de l'element
int num_maillage; // numéro de maillage
Tableau tab_noeud; // tableau de connexite des noeuds
Enum_interpol id_interpol; // identificateur d'interpolation
Enum_geom id_geom; // identificateur de geometrie
EnumElemTypeProblem id_problem; // identificateur du type de problem
// retourne les infos annexes éventuelles de l'éléments
string infos_annexes; // infos annexes complémentaires permettant une distinction
// plus fine entre plusieurs éléments identiques pour$
// les trois énumérations (par exemple n'ayant pas le même
// nombre de pt d'integ
int sens_numerotation; // par defaut = 1, mais si tous les jacobiens sont inverses => sens = -1
// --- cas de la puissance interne ---
Vecteur * residu; // residu local
Mat_pleine * raideur; // raideur locale
// --- cas des efforts externes concernant les aretes ------
Tableau * res_extA; // pour les résidus et second membres
Tableau * raid_extA; // pour les raideurs
// --- cas des efforts externes concernant les faces ------
Tableau * res_extS; // pour les résidus et second membres
Tableau * raid_extS; // pour les raideurs
// --- cas des efforts externes concernant les noeuds frontières ------
Tableau * res_extN; // pour les résidus et second membres
Tableau * raid_extN; // pour les raideurs
// --- cas de la dynamique ------
Mat_pleine * mat_masse; // matrice masse
// --- géométrie -------
double volume; // volume actuelle de l'élément: calculé dans les classes dérivées
Coordonnee volumePlan; // volume entre l'élément et les plans de ref: yz, xz, xy, uniquement pour les éléments
// 2D dans un espace 3D
// --- cas des intégrales volumiques: définition du conteneur, il peut également s'agir d'une intégration temporelle en +
// d'où la grandeur courante et celle à t
// ces grandeurs sont renseignées uniquement par les classes dérivées
// dans le cas où il n'y a pas d'intégrale -> les pointeurs sont NULL
// associé aux intégrale, il y a une liste d'index qui est utilisable par les méthodes
// qui récupère les infos
// il y a un index par intégrale et ce numéro est unique et défini au moment de la définition des conteneurs
// (*index_Integ_vol_typeQuel)(ii) contient alors le numéro de l'intégrale qui a été
// demandé par l'utilisateur = le numéro d'apparition dans le .info
// NB: si le numéro est négatif, cela veut dire que l'intégrale est figée, on n'intègre plus
// cela vient d'un restart par exemple, qui contenait l'ingégrale, mais l'utilisateur
// ne veut plus que l'intégration continue
// enu_integ_vol_TQ : indique l'enum du conteneur pour la récupération
// idem pour enu_integ_vol_t_TQ
// 1) intégration de volume uniquement
Tableau * integ_vol_typeQuel, * integ_vol_typeQuel_t;
Tableau * index_Integ_vol_typeQuel;
Tableau * enu_integ_vol_TQ;
// 2) intégration de volume et en temps: donc on commule le delta
Tableau * integ_vol_t_typeQuel, * integ_vol_t_typeQuel_t;
Tableau * index_Integ_vol_t_typeQuel;
Tableau * enu_integ_vol_t_TQ;
Tableau tabb; // le tableau des elements frontieres
int ind_front_lin; // entier qui permet de contrôler la création des frontières linéiques
int ind_front_surf; // idem pour les éléments frontières de surface
int ind_front_point; // idem pour les éléments frontières points
// pour ces trois entiers ind_... , =0 pas de frontières, =1 toutes les frontières existent,
// =2 seules certaines frontières existent
int posi_tab_front_lin; // indice du début -1 des éléments linéique dans tabb
int posi_tab_front_point; // indice du début -1 des points dans tabb
// au niveau du stockage dans tabb, il y a les surfaces puis les lignes puis les points
// boite d'encombrement: boite_encombre.Premier() -> les min de la boite, .Second() -> les maxi
DeuxCoordonnees boite_encombre; // ceci suivant les axes du repère global
// indicateur piloter par la méthode : Drapeau_preparation_calcul_precis(..
// qui vise à indiquer à l'élément de préparer ses paramètres internes pour un futur calcul suivant une précision donnée
int prepa_niveau_precision; // precision = 0 : aucune précision demandée, precision >=0 : précision maximale demandée
//-------------------------------------------------------------------------------------
// classes à usage interne ou par les éléments internes des classes dérivées
//-------------------------------------------------------------------------------------
// definition de la liste qui contiendra les donnees necessaires a la creation
// de nouveaux elements
public:
class ConstrucElement
{ public:
// les fonctions permettant de creer une nouvelle instance d'element
virtual Element * NouvelElement(int num_mail,int num) = 0; // un nouvel élément sans rien
// ramene true si la construction de l'element est possible en fonction
// des variables globales actuelles: ex en fonction de la dimension
virtual bool Element_possible() = 0;
};
class NouvelleTypeElement
{ public :
// constructeur par défaut
NouvelleTypeElement();
// constructeur normal
NouvelleTypeElement(const Enum_geom id_g,const Enum_interpol id_in
, const EnumElemTypeProblem id_type
, ConstrucElement * el =NULL,string discri="");
// constructeur de copie
NouvelleTypeElement(const NouvelleTypeElement& nvel);
// opérateur d'assigment
NouvelleTypeElement& operator= (const NouvelleTypeElement& elt);
// opérateur tests
bool operator == (const NouvelleTypeElement& elt);
bool operator != (const NouvelleTypeElement& elt);
bool MemeTypeElement(const NouvelleTypeElement& elt);
// données public
Enum_geom id_geom; // identificateur de geometrie
Enum_interpol id_interpol; // identificateur d'interpolation
EnumElemTypeProblem id_typeProblem; // identificateur du type de problème géré par l'élément
string infos_annexes; // chaine de caractère qui permet de spécialisé un élément parmi un ensemble
// d'une même famille : par exemple deux éléments avec un nombre de pt d'integ
// différents
ConstrucElement * el; // qui permet la def de l'element specifique
};
// list de tous les éléments (donnés interne) mais que l'on doit mettre en public pour que tous les
// éléments dérivés puissent l'utilisé sans que on l'ai déclare explicitement ici
static list listTypeElement;
//=====================================================================================
// METHODES PROTEGEES utilisables ou a renseigner par les classes derivees :
//=====================================================================================
protected :
// ajout du tableau specific de ddl des noeuds
// la procedure met a jour les ddl
// des noeuds constituants l'element
virtual void ConstTabDdl() = 0;
// affichage d'info en fonction de ordre
// ordre = "commande" : affichage d'un exemple d'entree pour l'élément
void Info_com_El
(int nbnoeu,UtilLecture * entreePrinc,string& ordre,Tableau * tabMaillageNoeud) ;
// changement du type de problème
inline void Change_TypeProblem(EnumElemTypeProblem new_id_problem)
{id_problem = new_id_problem; };
// ---------------- lecture écriture dans base info ----------------
// pour les données spécifiques à element
// cas donne le niveau de la récupération
// = 1 : on récupère tout
// = 2 : on récupère uniquement les données variables (supposées comme telles)
void Lect_bas_inf_element
(ifstream& ent,const Tableau * tabMaillageNoeud,const int cas) ;
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void Ecri_bas_inf_element(ofstream& sort,const int cas) ;
// ---------------- concernant les frontières ----------------
// suppression des frontières linéiques éventuelles
// num indique le numéro de l'arête à supprimer (numérotation EF)
// si num = 0, indique qu'il faut supprimer toutes les frontières
void SupprimeFront3D_lineique(int num = 0);
// fonction a renseigner par les classes dérivées, concernant les répercutions
// éventuelles due à la suppression de tous les frontières
// nums_i : donnent les listes de frontières supprimées
virtual void Prise_en_compte_des_consequences_suppression_tous_frontieres() = 0;
// idem pour une frontière (avant qu'elle soit supprimée)
virtual void Prise_en_compte_des_consequences_suppression_une_frontiere(ElFrontiere* elemFront) = 0;
public:
// constantes générales qui permettent d'éviter d'utiliser des chiffres dans les classes
// dérivées ceci pour plus de lisibilité et de sureté
static const double epaisseur_defaut; // épaisseur par défaut
static const double largeur_defaut; // largeur par défaut
static const double section_defaut; // section par défaut
static const double masse_volumique_defaut ; // masse_volumique par défaut
protected:
// variable de travail pour la fonction Choix_element
static bool premier_passage_Choix_element;
};
/// @} // end of group
#endif