// 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