- contient les éléments finis, métriques associées, déformations ... intégration du réperoire Géométrie: - contient les géométries 1D 2D et 3D, les frontières des éléments géométriques
1110 lines
60 KiB
C++
1110 lines
60 KiB
C++
// 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) <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/>.
|
|
|
|
|
|
// 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
|
|
|
|
|
|
#include <iostream>
|
|
#include <stdlib.h>
|
|
#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 <list>
|
|
#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<Noeud *>& 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<Noeud *>& 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<Noeud *>& 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<Noeud *>& 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<Noeud *>& 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<Noeud *> * ) = 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;
|
|
|
|
// 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;
|
|
|
|
// 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
|
|
// cas = 2: dans le cas 1D -> distance mini 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
|
|
// cas = 3: 1D idem cas 2, 2D: distance mini noeud arrête opposée, 3D: distance mini noeud face opposé
|
|
double LongueurGeometrique(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 <TypeQuelconque>* Integ_vol_typeQuel() const {return integ_vol_typeQuel;};
|
|
// cas des valeurs à l'incrément précédent
|
|
const Tableau <TypeQuelconque>* 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 <int> * 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 <TypeQuelconque>* Integ_vol_t_typeQuel() const {return integ_vol_t_typeQuel;};
|
|
// cas des valeurs à l'incrément précédent
|
|
const Tableau <TypeQuelconque>* 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 <int> * 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 <Vecteur*>* resEr, Mat_pleine* raidEr) :
|
|
resErr(resEr),raidErr(raidEr) {};
|
|
Tableau <Vecteur *>* 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 <Ddl_enum_etendu> 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 <TypeQuelconque> Les_type_evolues_internes(bool absolue) const = 0;
|
|
// idem pour les données particulières
|
|
virtual List_io <TypeQuelconque> 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 <TypeQuelconque> 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 <TypeQuelconque> 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 <Coordonnee> & 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 <Element*> 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<Noeud *> * 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<string>& 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 <double> Valeur_a_diff_temps
|
|
(bool absolue,Enum_dure enu_t,const List_io<Ddl_enum_etendu>& 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<TypeQuelconque>& 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<TypeQuelconque>& 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<TypeQuelconque>& 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<TypeQuelconque>& 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 <Tableau <double> > & 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 <List_io < TypeQuelconque > >& 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 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 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 <ElFrontiere*> 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);
|
|
|
|
// 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<Noeud *> * 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 <Noeud *> Construct_from_imcomplet(const Element & elem,list <DeuxEntiers> & 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 <Noeud *> Construct_from_lineaire(const Element & elem,list <DeuxEntiers> & 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<Noeud *> 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 <Vecteur *> * res_extA; // pour les résidus et second membres
|
|
Tableau <Mat_pleine *> * raid_extA; // pour les raideurs
|
|
// --- cas des efforts externes concernant les faces ------
|
|
Tableau <Vecteur *> * res_extS; // pour les résidus et second membres
|
|
Tableau <Mat_pleine *> * raid_extS; // pour les raideurs
|
|
// --- cas des efforts externes concernant les noeuds frontières ------
|
|
Tableau <Vecteur *> * res_extN; // pour les résidus et second membres
|
|
Tableau <Mat_pleine *> * 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 <TypeQuelconque>* integ_vol_typeQuel, * integ_vol_typeQuel_t;
|
|
Tableau <int> * index_Integ_vol_typeQuel;
|
|
Tableau <TypeQuelconque_enum_etendu > * enu_integ_vol_TQ;
|
|
// 2) intégration de volume et en temps: donc on commule le delta
|
|
Tableau <TypeQuelconque>* integ_vol_t_typeQuel, * integ_vol_t_typeQuel_t;
|
|
Tableau <int> * index_Integ_vol_t_typeQuel;
|
|
Tableau <TypeQuelconque_enum_etendu > * enu_integ_vol_t_TQ;
|
|
|
|
|
|
Tableau <ElFrontiere*> 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 <NouvelleTypeElement> 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<Noeud *> * 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<Noeud *> * 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
|