// This file is part of the Herezh++ application. // // The finite element software Herezh++ is dedicated to the field // of mechanics for large transformations of solid structures. // It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600) // INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) . // // Herezh++ is distributed under GPL 3 license ou ultérieure. // // Copyright (C) 1997-2022 Université Bretagne Sud (France) // AUTHOR : Gérard Rio // E-MAIL : gerardrio56@free.fr // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, // or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // For more information, please consult: . /************************************************************************ * DATE: 23/01/97 * * $ * * AUTEUR: G RIO (mailto:gerardrio56@free.fr) * * $ * * PROJET: Herezh++ * * $ * ************************************************************************ * BUT: Defini l'element generique de mecanique. * * $ * * '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * * * VERIFICATION: * * * * ! date ! auteur ! but ! * * ------------------------------------------------------------ * * ! ! ! ! * * $ * * '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * * MODIFICATIONS: * * ! date ! auteur ! but ! * * ------------------------------------------------------------ * * $ * ************************************************************************/ #ifndef ELEMMECA_H #define ELEMMECA_H #include "Element.h" #include "Tenseur.h" #include "NevezTenseur.h" #include "Deformation.h" #include "Loi_comp_abstraite.h" #include "Enum_calcul_masse.h" #include "Basiques.h" #include "Enum_dure.h" #include "CompThermoPhysiqueAbstraite.h" #include "CompFrotAbstraite.h" #include "LesPtIntegMecaInterne.h" #include "Enum_StabHourglass.h" #include "LesChargeExtSurElement.h" #include "Temps_CPU_HZpp.h" #include "Enum_StabMembrane.h" /// @addtogroup groupe_des_elements_finis /// @{ /// class ElemMeca : public Element { public : // VARIABLES PUBLIQUES : // CONSTRUCTEURS : ElemMeca (); // Constructeur utile quand le numero de maillage et d'identification de l'element est connu ElemMeca (int num_maill,int num_id) ; // Constructeur utile quand le numero de maillage et d'identification et le tableau des noeuds // de l'element sont connu ElemMeca (int num_maill,int num_id,const Tableau& tab); // Constructeur utile quand le numero de maillage et d'identification est connu, // ainsi que la geometrie et le type d'interpolation de l'element ElemMeca (int num_maill,int num_id,Enum_interpol id_interp_elt,Enum_geom id_geom_elt,string info=""); // Constructeur utile quand le numero de maillage et d'identification est connu, // ainsi que la geometrie et le type d'interpolation de l'element ElemMeca (int num_maill,int num_id,char* nom_interpol,char* nom_geom,string info=""); // Constructeur utile quand toutes les donnees de la classe Element sont connues ElemMeca (int num_maill,int num_id,const Tableau& tab,Enum_interpol id_interp_elt, Enum_geom id_geom_elt,string info=""); // Constructeur utile quand toutes les donnees de la classe Element sont connues ElemMeca (int num_maill,int num_id,const Tableau& tab,char* nom_interpol, char* nom_geom,string info=""); // Constructeur de copie ElemMeca (const ElemMeca& elt); // DESTRUCTEUR : ~ElemMeca (); // METHODES PUBLIQUES : // test si l'element est complet // = 1 tout est ok, =0 element incomplet int TestComplet(); // 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 int Interne_0(const Coordonnee& M,Coordonnee* coor_locales=NULL); int Interne_t(const Coordonnee& M,Coordonnee* coor_locales=NULL); int Interne_tdt(const Coordonnee& M,Coordonnee* coor_locales=NULL); // récupération des énergies intégrées sur l'éléments, résultants d'un précédent calcul // explicite, ou implicite const EnergieMeca& EnergieTotaleElement() const {return energie_totale;}; // test pour savoir si le calcul de contrainte en absolu est possible bool ContrainteAbsoluePossible(); // METHODES VIRTUELLES: // 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 !) // par contre sont inclus les ddl venant de l'élément, qui sont représenté directement aux noeuds // 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 ; // idem pour les grandeurs évoluées c'est-à-dire directement sous forme de vecteur, tenseurs .... // absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière virtual List_io Les_type_evolues_internes(bool absolue) const ; // idem pour les données particulières virtual List_io Les_types_particuliers_internes(bool absolue) const; // 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; // 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; // --------- calculs utils dans le cadre de la recherche du flambement linéaire // dans un premier temps uniquement virtuelles, ensuite se sera virtuelle pure pour éviter // les oubli de définition ----> AMODIFIER !!!!!!!! // Calcul de la matrice géométrique et initiale class MatGeomInit // pour le retour des pointeurs sur des matrices stockées // une paire par classe d'éléments { public : MatGeomInit(Mat_pleine * matG,Mat_pleine * matI) : matGeom(matG),matInit(matI) {}; Mat_pleine * matGeom ;Mat_pleine * matInit ; }; virtual MatGeomInit MatricesGeometrique_Et_Initiale (const ParaAlgoControle & pa) ; // --------- calcul d'erreur, calculs du champs de contrainte continu --------- // ajout des ddl de contraintes pour les noeuds de l'élément virtual void Plus_ddl_Sigma() = 0; // inactive les ddl du problème de recherche d'erreur : les contraintes virtual void Inactive_ddl_Sigma() = 0; // active les ddl du problème de recherche d'erreur : les contraintes virtual void Active_ddl_Sigma() = 0 ; // active le premier ddl du problème de recherche d'erreur : SIGMA11 virtual void Active_premier_ddl_Sigma() = 0 ; // retourne un tableau de ddl element, correspondant à la // composante de sigma -> SIG11, pour chaque noeud qui contiend // des ddl de contrainte // -> utilisé pour l'assemblage de la raideur d'erreur //!!!!!!!!!!!!! pour l'instant en virtuelle il faudra après en // virtuelle pure !!!!!!!!!!!!!!!!!!!!!!!!!!! virtual DdlElement& Tableau_de_Sig1() const ; // retourne un tableau de ddl element, correspondant à la // composante d'erreur -> ERREUR, pour chaque noeud // -> utilisé pour l'assemblage de la raideur d'erreur //dans cette version tous les noeuds sont supposés avoi un ddl erreur // dans le cas contraire il faut redéfinir la fonction dans l'élément terminal virtual DdlElement Tableau_de_ERREUR() const ; // calcul de l'erreur sur l'élément. Ce calcul n'est disponible // qu'une fois la remontée aux contraintes effectuées sinon aucune // action. En retour la valeur de l'erreur sur l'élément // type indique le type de calcul d'erreur : // = 1 : erreur = (int (delta sigma):(delta sigma) dv)/(int sigma:sigma dv) // le numerateur et le denominateur sont tel que : // errElemRelative = numerateur / denominateur , si denominateur different de 0 // sinon denominateur = numerateur si numerateur est different de 0, sinon // tous sont nuls mais on n'effectue pas la division //!!!!!!!!!!!!! pour l'instant en virtuelle il faudra après en // virtuelle pure !!!!!!!!!!!!!!!!!!!!!!!!!!! virtual void ErreurElement(int type,double& errElemRelative ,double& numerateur, double& denominateur); // les 3 routines qui suivent sont virtuelles, car la définition //qui est faite dans ElemMeca.cp considère qu'il y a un ddl erreur // par noeud de l'élément de manière systématique, // avec le status virtuel on peut définir dans la classe dérivée // un cas particulier // ajout des ddl d'erreur pour les noeuds de l'élément virtual void Plus_ddl_Erreur() ; // inactive les ddl d'erreur virtual void Inactive_ddl_Erreur() ; // active les ddl d'erreur virtual void Active_ddl_Erreur() ; // test pour savoir si l'erreur a été calculée bool ErreurDejaCalculee() { if (sigErreur == NULL) return false; else return true;}; // sortie de l'erreur à l'élément double Erreur( ) { return (*sigErreur);}; // lecture de données diverses sur le flot d'entrée // l'implantation est faite dans les classe dérivées virtual void LectureContraintes(UtilLecture * entreePrinc) =0 ; // retour des contraintes en absolu retour true si elle existe sinon false virtual bool ContraintesAbsolues(Tableau & tabSig) = 0; // --------- calcul dynamique --------- // calcul de la longueur d'arrête de l'élément minimal // divisé par la célérité dans le matériau virtual double Long_arrete_mini_sur_c(Enum_dure temps) = 0; // cas du bulk viscosity double E_elem_bulk_t,E_elem_bulk_tdt,P_elem_bulk; static void ActiveBulkViscosity(int choix) {bulk_viscosity=choix;}; static void InactiveBulkViscosity() {bulk_viscosity=false;}; static void ChangeCoefsBulkViscosity(const DeuxDoubles & coef) { c_traceBulk=coef.un;c_carreBulk=coef.deux;}; // initialisation pour le calcul de la matrice masse dans le cas de l'algorithme // de relaxation dynamique avec optimisation en continu de la matrice masse // casMass_relax: permet de choisir entre différentes méthodes de calcul de la masse void InitCalculMatriceMassePourRelaxationDynamique(int casMass_relax); // phase de calcul de la matrice masse dans le cas de l'algo de relaxation dynamique // mi=fonction de (alpha*K+beta*mu+gamma*Isig/3+theta/2*Sig_mises // ep: epaisseur, K module de compressibilite, mu: module de cisaillement, Isig trace de sigma, // Sig_mises la contrainte de mises // casMass_relax: permet de choisir entre différentes méthodes de calcul de la masse void CalculMatriceMassePourRelaxationDynamique (const double& alph, const double& beta, const double & lambda ,const double & gamma,const double & theta, int casMass_relax); // ---------- informations annexes ---------------- // récupération de la base locales au noeud noe, pour le temps: temps const BaseB & Gib_elemeca(Enum_dure temps, const Noeud * noe); // 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 void Grandeur_particuliere (bool absolue,List_io& liTQ,int iteg); // 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 void Grandeur_particuliere_face (bool absolue,List_io& liTQ,int face, int iteg); // 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 void Grandeur_particuliere_arete (bool absolue,List_io& liTQ,int arete, int iteg); // récupération de la loi de frottement, dans le cas où elle n'existe pas // retour d'un pointeur nul CompFrotAbstraite* LoiDeFrottement() const {return loiFrot;}; // récupération de la loi de comportement pour information, dans le cas où elle n'existe pas // retour d'un pointeur nul const Loi_comp_abstraite* LoiDeComportement() const {return loiComp;}; // récup du module de compressibilité moyen de l'élément double CompressibiliteMoyenne() const {return lesPtIntegMecaInterne->CompressibiliteMoyenne();}; // --- transfert des grandeurs des points d'intégration aux noeuds // transfert de ddl des points d'intégrations (de tous) 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 void TransfertAjoutAuNoeuds(const List_io < Ddl_enum_etendu >& lietendu ,const Tableau > & tab_val,int cas); // 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 void TransfertAjoutAuNoeuds(const Tableau >& tab_liQ ,List_io < TypeQuelconque > & liQ_travail,int cas); // accumulation aux noeuds de grandeurs venant de l'éléments vers ses 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 void Accumul_aux_noeuds(const List_io < Ddl_enum_etendu >& lietendu ,List_io < TypeQuelconque > & liQ,int cas); // activation du calcul des invariants de contraintes, qui seront calculé à chaque // fois que l'on calcul les contraintes au travers de la loi de comportement void ActivCalculInvariantsContraintes(); // idem pour la déformation void ActivCalculInvariantsDeformation(); // idem pour la vitesse de déformation void ActivCalculInvariantsVitesseDeformation(); // 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 bool Modif_orient_elem(int cas_orientation); // 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 // pour des éléments particulier (ex: SFE) la méthode est surchargée virtual int CalculNormale_noeud(Enum_dure temps, const Noeud& noe,Coordonnee& coor); // calcul si un point est a l'interieur de l'element ou non // il faut que M est la dimension globale // 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 int Interne(Enum_dure temps,const Coordonnee& M,Coordonnee* coor_locales=NULL); // -- connaissances particulières sur l'élément // ramène l'épaisseur de l'élément // =0. si la notion d'épaisseurs ne veut rien dire pour l'élément virtual double Epaisseurs(Enum_dure , const Coordonnee& ) {return 0.;}; // ramène l'épaisseur moyenne de l'élément (indépendante du point) // =0. si la notion d'épaisseurs ne veut rien dire pour l'élément virtual double EpaisseurMoyenne(Enum_dure ) {return 0.;}; // ramène la section de l'élément // =0. si la notion de section ne veut rien dire pour l'élément virtual double Section(Enum_dure , const Coordonnee& ) {return 0.;}; // ramène la section moyenne de l'élément (indépendante du point) // =0. si la notion de section ne veut rien dire pour l'élément virtual double SectionMoyenne(Enum_dure ) {return 0.;}; // // modifie l'épaisseur Moyenne à tdt // virtual void Modifie_epaisseur_moyenne_tdt(const double& h_t) // {cout << "\n erreur** la methode Modifie_epaisseur_moyenne(.. n'existe pas "; Sortie(1);}; // 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(); // idem pour une frontière (avant qu'elle soit supprimée) virtual void Prise_en_compte_des_consequences_suppression_une_frontiere(ElFrontiere* elemFront); // -------------------- calcul de frontières ------------------- // 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); // 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); // 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); // 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) // {return Frontiere_elemeca(cas,force);}; // -------------------- init éventuelle avant le chargement ------------------- // initialisation éventuelle, nécessaire avant d'appliquer l'ensemble des charges // par exemple des stockages intermédiaires virtual void Initialisation_avant_chargement(); // mise à jour éventuel de repère d'anisotropie virtual void Mise_a_jour_repere_anisotropie (BlocGen & bloc,LesFonctions_nD* lesFonctionsnD); //===================================================================================== protected : //===================================================================================== // METHODES PROTEGEES utilisables par les classes derivees : // Calcul des frontieres de l'element // creation des elements frontieres et retour du tableau de ces elements // 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 Tableau const & Frontiere_elemeca(int cas, bool force = false); // --------------------------------------------------------------------- // cas où l'on intègre que selon une liste (un axe, un plan, un volume) // --------------------------------------------------------------------- // Calcul du residu local et de la raideur locale, // pour le schema implicite d'ou a l'instant t + dt // ddl represente les degres de liberte specifiques a l'element // tabDepsBB = vitesse de déformation, tabDeltaEpsBB = incrément de def entre t et t+dt // cald_Dvirtuelle = indique si l'on doit calculer la dérivée de la vitesse de déformation virtuelle void Cal_implicit (DdlElement & tab_ddl,Tableau & d_epsBB ,Tableau < Tableau2 > d2_epsBB,Tableau & d_sigHH,int nbint ,const Vecteur& poids,const ParaAlgoControle & pa,bool cald_Dvirtuelle); // Calcul du residu local a l'instant t ou tdt // atdt = true : calcul à tdt, valeur par défaut // = false: calcul à t // ddl represente les degres de liberte specifiques a l'element // nbint = nb de pt d'integration , poids = poids d'integration void Cal_explicit (DdlElement & ddl,Tableau & d_epsBB,int nbint ,const Vecteur& poids,const ParaAlgoControle & pa,bool atdt=true); // Calcul de la matrice géométrique et de la matrice initiale // cette fonction est éventuellement appelée par les classes dérivées // ddl represente les degres de liberte specifiques a l'element // nbint = nb de pt d'integration , poids = poids d'integration // cald_Dvirtuelle = indique si l'on doit calculer la dérivée de la vitesse de déformation virtuelle void Cal_matGeom_Init (Mat_pleine & matGeom, Mat_pleine & matInit ,DdlElement & ddl,Tableau & d_epsBB,Tableau < Tableau2 > d2_epsBB ,Tableau & d_sigHH,int nbint,const Vecteur& poids ,const ParaAlgoControle & pa,bool cald_Dvirtuelle); // Calcul de la matrice masse selon différent choix donné par type_matrice_masse, // a l'instant initial. void Cal_Mat_masse (DdlElement & tab_ddl,Enum_calcul_masse type_matrice_masse, int nbint,const Tableau & taphi,int nbne ,const Vecteur& poids); // --------------------------------------------------------------------- // cas où l'on intègre selon deux listes (ex un axe et un plan, etc.) // --------------------------------------------------------------------- // Calcul du residu local et de la raideur locale, // pour le schema implicite d'ou a l'instant t + dt // ddl represente les degres de liberte specifiques a l'element void Cal_implicitap (DdlElement & tab_ddl,Tableau & d_epsBB ,Tableau < Tableau2 > d2_epsBB,Tableau & d_sigHH ,int nbint1,Vecteur& poids1,int nbint2,const Vecteur& poids2 ,const ParaAlgoControle & pa); // Calcul du residu local a l'instant t ou tdt // atdt = true : calcul à tdt, valeur par défaut // = false: calcul à t // ddl represente les degres de liberte specifiques a l'element // d_epsbb = variation des def // nbint = nb de pt d'integration , poids = poids d'integration void Cal_explicitap (DdlElement & ddl,Tableau & d_epsBB ,int nbint,const Vecteur& poids,bool atdt=true); // Calcul de la matrice géométrique et de la matrice initiale // cette fonction est éventuellement appelée par les classes dérivées // ddl represente les degres de liberte specifiques a l'element // d_epsbb = variation des def // nbint = nb de pt d'integration , poids = poids d'integration void Cal_matGeom_Initap (Mat_pleine & matGeom, Mat_pleine & matInit ,DdlElement & ddl,Tableau & d_epsBB,Tableau < Tableau2 > d2_epsBB ,Tableau & d_sigHH,int nbint,const Vecteur& poids); // -------------------------- calcul de second membre --------------------------- // calcul des seconds membres suivant les chargements // cas d'un chargement surfacique, sur les frontières des éléments // force indique la force surfacique appliquée // retourne le second membre résultant // nSurf : le numéro de la surface externe // calcul à l'instant tdt ou t en fonction de la variable atdt Vecteur& SM_charge_surf_E (DdlElement & ddls,int nSurf ,const Tableau & taphi,int nbne ,const Vecteur& poids,const Coordonnee& force,Fonction_nD* pt_fonct ,const ParaAlgoControle & pa,bool atdt=true); // idem SM_charge_surf_E mais -> implicite, // pa : permet de déterminer si l'on fait ou non le calcul de la contribution à la raideur // retourne le second membre et la matrice de raideur correspondant Element::ResRaid SMR_charge_surf_I (DdlElement & ddls,int nSurf ,const Tableau & taphi,int nbne ,const Vecteur& poids,const Coordonnee& force,Fonction_nD* pt_fonct ,const ParaAlgoControle & pa); // calcul des seconds membres suivant les chargements // cas d'un chargement pression, sur les frontières des éléments // pression indique la pression appliquée // la fonction nD est utilisée que si elle ne dépend pas strictement de grandeurs globales // retourne le second membre résultant // nSurf : le numéro de la surface externe // calcul à l'instant tdt ou t en fonction de la variable atdt Vecteur& SM_charge_pres_E (DdlElement & ddls,int nSurf ,const Tableau & taphi,int nbne ,const Vecteur& poids,double pression,Fonction_nD* pt_fonct ,const ParaAlgoControle & pa,bool atdt=true); // idem SM_charge_pres_E mais -> 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 // la fonction nD est utilisée que si elle ne dépend pas strictement de grandeurs globales Element::ResRaid SMR_charge_pres_I (DdlElement & ddls,int nSurf ,const Tableau & taphi,int nbne ,const Vecteur& poids,double pression,Fonction_nD* pt_fonct ,const ParaAlgoControle & pa); // cas d'un chargement lineique, sur les arêtes frontières des éléments // force indique la force lineique appliquée // retourne le second membre résultant // nArete : le numéro de l'arête externe // calcul à l'instant tdt ou t en fonction de la variable atdt Vecteur& SM_charge_line_E (DdlElement & ddls,int nArete ,const Tableau & taphi,int nbne ,const Vecteur& poids,const Coordonnee& force,Fonction_nD* pt_fonct ,const ParaAlgoControle & pa,bool atdt=true); // idem SM_charge_line_E mais -> 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 Element::ResRaid SMR_charge_line_I (DdlElement & ddlA,int nArete ,const Tableau & taphi,int nbne ,const Vecteur& poids,const Coordonnee& force,Fonction_nD* pt_fonct ,const ParaAlgoControle & pa); // cas d'un chargement lineique suiveur, sur les arêtes frontières des éléments // pas valable pour des éléments 3D ! // force indique la force lineique appliquée // retourne le second membre résultant // nArete : le numéro de l'arête externe // calcul à l'instant tdt ou t en fonction de la variable atdt Vecteur& SM_charge_line_Suiv_E (DdlElement & ddls,int nArete ,const Tableau & taphi,int nbne ,const Vecteur& poids,const Coordonnee& force,Fonction_nD* pt_fonct ,const ParaAlgoControle & pa,bool atdt=true); // idem SM_charge_line_E mais -> 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 Element::ResRaid SMR_charge_line_Suiv_I (DdlElement & ddlA,int nArete ,const Tableau & taphi,int nbne ,const Vecteur& poids,const Coordonnee& force,Fonction_nD* pt_fonct ,const ParaAlgoControle & pa); // cas d'un chargement surfacique suiveur, sur les surfaces de l'élément // la direction varie selon le système suivant: on définit les coordonnées matérielles // de la direction, ce qui sert ensuite à calculer les nouvelles directions. L'intensité // elle est constante. // force indique la force surfacique appliquée // retourne le second membre résultant // nSurf : le numéro de la surface externe // calcul à l'instant tdt ou t en fonction de la variable atdt Vecteur& SM_charge_surf_Suiv_E (DdlElement & ddls,int nSurf ,const Tableau & taphi,int nbne ,const Vecteur& poids,const Coordonnee& force,Fonction_nD* pt_fonct ,const ParaAlgoControle & pa,bool atdt=true); // idem SM_charge_surf_Suiv_E mais -> 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 Element::ResRaid SMR_charge_surf_Suiv_I (DdlElement & ddlA,int nSurf ,const Tableau & taphi,int nbne ,const Vecteur& poids,const Coordonnee& force,Fonction_nD* pt_fonct ,const ParaAlgoControle & pa); // cas d'un chargement volumique, sur l'élément // force indique la force volumique appliquée // retourne le second membre résultant // calcul à l'instant tdt ou t en fonction de la variable atdt Vecteur& SM_charge_vol_E (DdlElement & ddls ,const Tableau & taphi,int nbne ,const Vecteur& poids,const Coordonnee& force,Fonction_nD* pt_fonct ,const ParaAlgoControle & pa,bool sur_volume_finale_,bool atdt=true); // idem SM_charge_vol_E mais -> 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 void SMR_charge_vol_I (DdlElement & ddls ,const Tableau & taphi,int nbne ,const Vecteur& poids,const Coordonnee& force,Fonction_nD* pt_fonct ,const ParaAlgoControle & pa,bool sur_volume_finale_); // cas d'un chargement hydrostatique, sur les surfaces de l'élément // la charge dépend de la hauteur à la surface libre du liquide déterminée par un point // et une direction normale à la surface libre: // nSurf : le numéro de la surface externe // 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 si l'on doit limiter aux positions négatives // retourne le second membre résultant // calcul à l'instant tdt ou t en fonction de la variable atdt Vecteur& SM_charge_hydro_E (DdlElement & ddls,int nSurf ,const Tableau & taphi,int nbne ,const Vecteur& poids ,const Coordonnee& dir_normal_liquide,const double& poidvol ,const Coordonnee& M_liquide,bool sans_limitation ,const ParaAlgoControle & pa,bool atdt=true); // idem SM_charge_hydro_E mais -> 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 Element::ResRaid SMR_charge_hydro_I (DdlElement & ddlA,int nSurf ,const Tableau & taphi,int nbne ,const Vecteur& poids ,const Coordonnee& dir_normal_liquide,const double& poidvol ,const Coordonnee& M_liquide,bool sans_limitation ,const ParaAlgoControle & pa); // cas d'un chargement aero-hydrodynamique, sur les frontières de l'élément // 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 // retourne le second membre résultant // calcul à l'instant tdt ou t en fonction de la variable atdt // coef_mul: est un coefficient multiplicateur global (de tout) Vecteur& SM_charge_hydrodyn_E (const double& poidvol,const Tableau & taphi,int nbne ,Courbe1D* frot_fluid,const Vecteur& poids ,Courbe1D* coef_aero_n,int numfront,const double& coef_mul ,Courbe1D* coef_aero_t,const ParaAlgoControle & ,bool atdt=true); // idem SM_charge_hydrodyn_E mais -> 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 Element::ResRaid SM_charge_hydrodyn_I (const double& poidvol,const Tableau & taphi,int nbne ,Courbe1D* frot_fluid,const Vecteur& poids,DdlElement & ddls ,Courbe1D* coef_aero_n,int numfront,const double& coef_mul ,Courbe1D* coef_aero_t,const ParaAlgoControle & pa); // -------------------- calcul de frontières en protected ------------------- // --- fonction nécessaire pour la construction des Frontières linéiques ou surfaciques particulière à l'élément // adressage des frontières linéiques et surfacique // définit dans les classes dérivées, et utilisées pour la construction des frontières virtual ElFrontiere* new_frontiere_lin(int num,Tableau & tab, DdlElement& ddelem) = 0; virtual ElFrontiere* new_frontiere_surf(int num,Tableau & tab, DdlElement& ddelem) = 0; // -------------------- stabilisation d'hourglass ------------------- // calcul d'élément de contrôle d'hourglass associée à un comportement void Init_hourglass_comp(const ElemGeomC0& elgeHour, const string & str_precision ,LoiAbstraiteGeneral * loiHourglass,const BlocGen & bloc); // stabilisation pour un calcul implicit void Cal_implicit_hourglass(); // stabilisation pour un calcul explicit void Cal_explicit_hourglass(bool atdt); // -------------------- stabilisation transversale éventuelle de membrane ou de biel ------------------- // utilisée et alimentées par les classes dérivées: ElemMeca sert de conteneur ce qui permet // d'éviter de redéfinir des conteneurs locaux aux éléments membranes et biel class StabMembBiel // conteneur local pour un stockage globale de toutes les grandeurs concernées { public : // par défaut StabMembBiel(); // fonction du nombre de noeud ou pti StabMembBiel(int nbnoe); // fonction d'une valeur numérique et des noms éventuels de fonction StabMembBiel(double v,string * sgamma,string* sponder); // de copie StabMembBiel(const StabMembBiel& a); ~StabMembBiel(); StabMembBiel& operator= (const StabMembBiel& a); // --- acces aux données en inline Enum_StabMembraneBiel& Type_stabMembrane() {return type_stabMembrane;} bool& Aa_calculer() {return a_calculer;}; double& Valgamma() {return gamma;}; Fonction_nD* Pt_fct_gamma() {return pt_fct_gamma;} void Change_pt_fct_gamma(Fonction_nD* fct) {pt_fct_gamma=fct;}; // affichage const int& Affichage_stabilisation() const {return affichage_stabilisation;}; void Change_affichage_stabilisation(int niveau) {affichage_stabilisation = niveau;}; // gestion éventuelle des mini maxi const bool& Gestion_maxi_mini() const {return gestion_maxi_mini;}; void Change_gestion_maxi_mini(bool gestion) {gestion_maxi_mini = gestion;}; //beta const double& Beta() const {return beta;}; void Change_beta(double bet) {beta = bet;}; //f_mini const double& F_mini() const {return f_mini;}; void Change_f_mini(double f) {f_mini = f;}; // d_maxi const double& D_maxi() const {return d_maxi;}; void Change_d_maxi(double d) {d_maxi = d;}; // inactif_en_explicite const bool Activite_en_explicite() const {return activite_en_explicite;}; void change_activite_en_explicite(bool change) {activite_en_explicite=change;}; // pondération de F_t, utilisé dans le calcul de F(t+dt) Fonction_nD* Pt_fct_ponder_Ft() {return pt_fct_ponder_Ft;} void Change_pt_fct_ponder_Ft(Fonction_nD* fct) {pt_fct_ponder_Ft=fct;}; // l'intensité de la force de stabilisation au noeud i ou au pti i double& FF_StabMembBiel(int i) {return F_StabMembBiel(i);}; double& FF_StabMembBiel_t(int i) {return F_StabMembBiel_t(i);}; // l'énergie développée par la stabilisation au noeud i ou au pti i double& EE_StabMembBiel(int i) {return E_StabMembBiel(i);}; // l'énergie développée par la stabilisation au noeud i ou au pti i double& EE_StabMembBiel_t(int i) {return E_StabMembBiel_t(i);}; // énergie totale développée sur l'élément pour la stabilisation double EE_total_StabMembBiel() const ; double EE_total_StabMembBiel_t() const ; // valeur de référence pour calculer l'intensité de stabilisation // (identique pour tous les pti), typiquement == le max de la raideur par exemple double& Stab_ref() {return stab_ref;}; string * Nom_fctnD() {return nom_fctnD;}; // actualisation de la force de stabilisation de t+dt vers t void TdtversT(); // actualisation de la force de stabilisation de t vers tdt void TversTdt(); // 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 Lecture_bas_inf(ifstream& ent,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 Ecriture_bas_inf(ofstream& sort,const int cas) ; // complète en attribuant les fct nD si besoin, ceci après une lecture // initiale base_info void Complete_StabMembBiel(LesFonctions_nD* lesFonctionsnD); // changement du nombre de pti ou de noeuds, suivant le type de stabilisation void Change_nb_pti(int nbnoe); // le nb de pti ou de noeud du conteneur int Taille() const {return F_StabMembBiel.Taille();}; // --- données protected: Enum_StabMembraneBiel type_stabMembrane; // indique le type de stabilisation bool a_calculer; // indique si oui ou non il faut calculer la force de stabilisation double gamma; // si pt_fct_gamma == NULL -> valeur numérique lue // si pt_fct_gamma != NULL -> contient la dernière valeur d'alpha calculée via pt_fct_gamma Fonction_nD* pt_fct_gamma; // si non null, c'est cette fonction que l'on utilise sinon // c'est la valeur numérique gamma double stab_ref; // valeur de référence pour calculer l'intensité de stabilisation // (identique pour tous les pti ou noeuds), typiquement == le max de la raideur par exemple // peut changer ensuite pendant le calcul, suivant le type de stabilisation bool activite_en_explicite; // par défaut false, indique si oui ou non actif en explicite Fonction_nD* pt_fct_ponder_Ft; // si non nulle, la fonction est utilisée pour pondérer // la force de stabilisation à t, utilisée dans le calcul // à t+dt int affichage_stabilisation; // niveau d'affichage spécifique //--- gestion éventuelle des maxi mini ----- bool gestion_maxi_mini; // indique la gestion éventuelle (false par défaut) // si l'intensité de la stabilisation est supérieure à beta * intensite_Fext // on limite (cas où intensite_Fext >= F_mini) double beta; double f_mini; // force mini pour détection de force externe double d_maxi; // limitation éventuelle sur un déplacement maxi // --- stockage des infos ----- // stockage aux noeuds "ou" aux pti: dépend du type de stabilisation Tableau F_StabMembBiel; // la force généralisé de stabilisation actuelle Tableau F_StabMembBiel_t; // la force généralisé de stabilisation à t Tableau E_StabMembBiel; // l'énergie développée par la stabilisation Tableau E_StabMembBiel_t; // l'énergie développée par la stabilisation à t string * nom_fctnD; // sert uniquement lors de la lecture base info, en attendant de définir //pt_fct_gamma string * nom_fctnD_2; // idem pour pt_fct_ponder_Ft }; public : // retour de l'énergie totale de stabilisation éventuelle de membrane et ou de biel double Energie_stab_membBiel() {if (pt_StabMembBiel == NULL) {return 0.;} else {return pt_StabMembBiel->EE_total_StabMembBiel();}; }; protected : StabMembBiel* pt_StabMembBiel; // pointeur éventuellement non nul double maxi_F_t; // grandeur de travail utiliser par Cal_implicit_StabMembBiel Mat_pleine* matD; // raideur éventuelle, définie et supprimée dans la classe dérivée relative à un EF particulier Vecteur* resD; // résidu éventuelle, défini et supprimé dans la classe dérivée relative à un EF particulier // mise à jour de "a_calculer" en fonction du contexte void Mise_a_jour_A_calculer_force_stab(); // stabilisation pour un calcul implicit, // iteg -> donne le numéro du dernier pti sur lequel on a travaillé, auquel met est associé // iteg == 0 : un seul calcul global, et on est à la suite d'une boucle // correspond au calcul d'alpha: == stab_ref // iteg == -1 : fin d'un calcul avec boucle sur tous les pti, et on est à la suite de la boucle // iteg entre 1 et nbint: on est dans une boucle de pti // nbint : le nombre maxi de pti // poid_volume : si iteg > 0 : le poids d'intégration // si iteg <= 0 : l'intégrale de l'élément (ici la surface totale) // noeud_a_prendre_en_compte: si diff de null indique les noeuds à prendre en compte // : noeud_a_prendre_en_compte(i) = 0 --> le noeud i n'est pas à prendre en compte // doit avoir la taille du nombre total de noeud de l'élément void Cal_implicit_StabMembBiel(int iteg,const Met_abstraite::Impli& met, const int& nbint ,const double& poid_volume,Tableau * noeud_a_prendre_en_compte); // stabilisation pour un calcul explicit // iteg -> donne le numéro de pti sur lequel on travaille void Cal_explicit_StabMembBiel(int iteg,const Met_abstraite::Expli_t_tdt met, const int& nbint ,const double& poids_volume,Tableau * noeud_a_prendre_en_compte); private : // static Tableau< Vecteur> vec_StabMembBiel; // tableau de vecteurs de travail, éventuellement défini // -------------------- fin stabilisation transversale éventuelle de membrane ou de biel ------------------- public : // récupération de l'energie d'hourglass éventuelle // uniquement pour un pas de temps double Energie_Hourglass()const {return E_Hourglass;}; // idem pour l'énergie et la puissance de bulk viscosity double Energie_Bulk() const {return E_elem_bulk_tdt;}; double Puissance_Bulk() const {return P_elem_bulk;}; // idem éventuellement pour l'intensité de la force de stabilisation transversale au pti i double Force_StabMembBiel(int i) const {if (pt_StabMembBiel != NULL) return pt_StabMembBiel->FF_StabMembBiel(i); else return 0.;}; // idem éventuellement pour l'énergie de stabilisation transversale double Energie_StabMembBiel(int i) const {if (pt_StabMembBiel != NULL) return pt_StabMembBiel->EE_StabMembBiel(i); else return 0.;}; // récupération des temps cpu Temps_CPU_HZpp Temps_lois_comportement() const { Temps_CPU_HZpp inter; int taill = lesPtIntegMecaInterne->NbPti()+1; for (int i=1;iNbPti()+1; for (int i=1;i& taphi ,const Vecteur& poids,Tableau & resErr,Mat_pleine& raidErr ,const Tableau & taphiEr,const Vecteur& poidsEr ); // calcul de l'erreur sur l'élément. Ce calcul n'est disponible // qu'une fois la remontée aux contraintes effectuées sinon aucune // action. pour les autres arguments de retour, idem ErreurElement // qui est la fonction generique, les autres variables sont spécifiques // a l'element. void Cal_ErrElem(int type,double& errElemRelative ,double& numerateur, double& denominateur,const int nbne,const Tableau & taphi ,const Vecteur& poids,const Tableau & taphiEr,const Vecteur& poidsEr); // calcul de l'erreur aux noeuds. Contrairement au cas des contraintes // seul le résidu est calculé. Cas d'une intégration suivant une liste void Cal_ErrAuxNoeuds(const int nbne, const Tableau & taphi, const Vecteur& poids,Tableau & resErr ); // --------------------------------------------------------------------- // 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 // cas =1 -> premier passage pour de l'implicit // cas = 2 -> premier passage pour de l'explicit // cas = 11 -> passage autre que le premier pour de l'implicit // cas = 12 -> passage autre que le premier pour de l'explicit void VarDualSort(ofstream& sort, Tableau& nom,int nbint,int cas); // utilitaires de VarDualSort // affiche en fonction d'indic les differentes variables et appel // AffDefContiD en fonction de la dimension i // void AffDefCont( ofstream& sort,Loi_comp_abstraite::SaveResul * saveDon, TenseurBB& eps0BB,TenseurBB& epsBB,TenseurBB& DepsBB,TenseurBB& DeltaEpsBB, TenseurHH& sigHH, TenseurHB& epsHB,TenseurHB& sigHB, Coordonnee& valPropreEps,Coordonnee& valPropreDeps,Coordonnee& valPropreSig, double Mises,TenseurBB& epsAlmBB,TenseurBB& epslogBB, int indic); // cas 1D void AffDefCont1D( ofstream& sort,Loi_comp_abstraite::SaveResul * saveDon, TenseurBB& eps0BB,TenseurBB& epsBB,TenseurBB& DepsBB,TenseurBB& DeltaEpsBB, TenseurHH& sigHH, TenseurHB& epsHB,TenseurHB& sigHB, Coordonnee& valPropreEps,Coordonnee& valPropreDeps,Coordonnee& valPropreSig, double Mises,TenseurBB& epsAlmBB,TenseurBB& epslogBB,int indic); // cas 2D void AffDefCont2D( ofstream& sort,Loi_comp_abstraite::SaveResul * saveDon, TenseurBB& eps0BB,TenseurBB& epsBB,TenseurBB& DepsBB,TenseurBB& DeltaEpsBB, TenseurHH& sigHH, TenseurHB& epsHB,TenseurHB& sigHB, Coordonnee& valPropreEps,Coordonnee& valPropreDeps,Coordonnee& valPropreSig, double Mises,TenseurBB& epsAlmBB,TenseurBB& epslogBB,int indic); // cas 3D void AffDefCont3D( ofstream& sort,Loi_comp_abstraite::SaveResul * saveDon, TenseurBB& eps0BB,TenseurBB& epsBB,TenseurBB& DepsBB,TenseurBB& DeltaEpsBB, TenseurHH& sigHH, TenseurHB& epsHB,TenseurHB& sigHB, Coordonnee& valPropreEps,Coordonnee& valPropreDeps,Coordonnee& valPropreSig, double Mises,TenseurBB& epsAlmBB,TenseurBB& epslogBB,int indic); // --------------------------------------------------------------------- // --- méthodes relatives aux calculs d'erreurs ----------- // ---- utilisées par les classes dérivées --------- // ajout des ddl relatif aux contraintes pour les noeuds de l'élément void Ad_ddl_Sigma(const DdlElement& tab_ddlErr); // inactive les ddl du problème primaire de mécanique void Inact_ddl_primaire(DdlElement& tab_ddl); // active les ddl du problème primaire de mécanique void Act_ddl_primaire(DdlElement& tab_ddl); // inactive les ddl du problème de recherche d'erreur : les contraintes void Inact_ddl_Sigma(DdlElement& tab_ddlErr); // active les ddl du problème de recherche d'erreur : les contraintes void Act_ddl_Sigma(DdlElement& tab_ddlErr); // active le premier ddl du problème de recherche d'erreur : SIGMA11 void Act_premier_ddl_Sigma(); // --------------------------------------------------------------------- // lecture des contraintes sur le flot d'entrée void LectureDesContraintes (bool cas,UtilLecture * entreePrinc,Tableau & tabSigHH); // retour des contraintes en absolu retour true si elle existe sinon false void ContraintesEnAbsolues (bool cas,Tableau & tabSigHH,Tableau & tabSig); // ---------------- lecture écriture dans base info ---------------- // programmes utilisés par les classes dérivées // 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 Lecture_bas_inf (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 Ecriture_bas_inf(ofstream& sort,const int cas) ; // --------- utilitaires pour la dynamique // calcul de la longueur d'arrête de l'élément minimal // divisé par la célérité la plus rapide dans le matériau // appelé par les classes dérivées // nb_noeud : =0 indique que l'on utilise tous les noeuds du tableau de noeuds // = un nombre > 0, indique le nombre de noeuds à utiliser au début du tableau double Interne_Long_arrete_mini_sur_c(Enum_dure temps,int nb_noeud=0); // recuperation des coordonnées du point d'intégration numéro = iteg pour // la grandeur enu // temps: dit si c'est à 0 ou t ou tdt // si erreur retourne erreur à true Coordonnee CoordPtInt(Enum_dure temps,Enum_ddl enu,int iteg,bool& erreur); // 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 Coordonnee CoordPtIntFace(int face, Enum_dure temps,int iteg,bool& erreur); // 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 Coordonnee CoordPtIntArete(int arete, Enum_dure temps,int iteg,bool& erreur); // procesure permettant de completer l'element, en ce qui concerne les variables gérés // par ElemMeca, apres sa creation avec les donnees du bloc transmis // peut etre appeler plusieurs fois Element* Complete_ElemMeca(BlocGen & bloc,LesFonctions_nD* lesFonctionsnD); // retourne le numero du pt d'ing le plus près ou est exprimé la grandeur enum // temps: dit si c'est à 0 ou t ou tdt int PtLePlusPres(Enum_dure temps,Enum_ddl enu, const Coordonnee& M); // récupération des valeurs au numéro d'ordre = iteg pour // les grandeur enu // absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière // NB Importante: il faut faire attention à ce que ces métriques soient identiques à celles qui ont servit // pour le calcul des tenseurs: en particulier si c'est utilisé pour calculer les grandeurs pour le chargement // il faut s'assurer que ce sont les "mêmes pti" qui servent pour la charge et pour la raideur !! Tableau Valeur_multi(bool absolue,Enum_dure enu_t,const List_io& enu ,int iteg,int cas ) ; // récupération des valeurs Tensorielles (et non scalaire comme avec Valeur_multi) // au numéro d'ordre = iteg pour les grandeur enu // enu contient les grandeurs de retour // absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière // NB Importante: il faut faire attention à ce que ces métriques soient identiques à celles qui ont servit // pour le calcul des tenseurs: en particulier si c'est utilisé pour calculer les grandeurs pour le chargement // il faut s'assurer que ce sont les "mêmes pti" qui servent pour la charge et pour la raideur !! void Valeurs_Tensorielles(bool absolue, Enum_dure enu_t,List_io& enu ,int iteg,int cas ) ; // récupération de valeurs interpolées pour les grandeur enu ou directement calculées // absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière // une seule des 3 métriques doit-être renseigné, les autres doivent être un pointeur nul Tableau Valeur_multi_interpoler_ou_calculer (bool absolue, Enum_dure temps,const List_io& enu ,Deformation & defor ,const Met_abstraite::Impli* ex_impli ,const Met_abstraite::Expli_t_tdt* ex_expli_tdt ,const Met_abstraite::Expli* ex_expli ); // récupération de valeurs interpolées pour les grandeur enu // absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière // une seule des 3 métriques doit-être renseigné, les autres doivent être un pointeur nul void Valeurs_Tensorielles_interpoler_ou_calculer (bool absolue, Enum_dure temps,List_io& enu ,Deformation & defor ,const Met_abstraite::Impli* ex_impli ,const Met_abstraite::Expli_t_tdt* ex_expli_tdt ,const Met_abstraite::Expli* ex_expli ); // ==== >>>> methodes virtuelles definis dans les classes mères ============ // ramene l'element geometrique correspondant au ddl passé en paramètre virtual ElemGeomC0& ElementGeometrie(Enum_ddl ddl) const ; // 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; // ==== >>>> methodes virtuelles definis dans les classes dérivées ============ // ramene la dimension des tenseurs contraintes et déformations de l'élément virtual int Dim_sig_eps() const = 0; // VARIABLES PROTEGEES : //---- variables: contrainte, déformations etc.. aux points d'intégrations ------- // lesPtIntegMecaInterne pointe vers une entitée entièrement gérés par les classes dérivées // contenant les grandeurs mécaniques (contraintes, déformations etc.) stockées aux points d'intégration LesPtIntegMecaInterne * lesPtIntegMecaInterne; //----------- les charges externes éventuelles ---------- LesChargeExtSurElement * lesChargeExtSurEle; Loi_comp_abstraite * loiComp; // loi de comportement mécanique defini dans les classes derivees CompThermoPhysiqueAbstraite * loiTP; // éventuellement une loi de comportement thermo physique // defini dans les classes derivees CompFrotAbstraite * loiFrot; // éventuellement une loi de comportement au frottement pour ses frontières int dilatation; // indique si oui ou non on tiend compte de la dilatation thermique Met_abstraite * met; // definition specifique dans les classes derivees Deformation * def; // definition specifique dans les classes derivees // mais relative à la déformation mécanique Deformation * defEr; // idem que def mais pour la remonte aux contraintes Tableau defSurf; // idem mais pour les déformations des surfaces // externes (frontières) si cela est nécessaire Tableau defArete; // idem mais pour les déformations des arretes // externes (frontières) si cela est nécessaire Deformation * defMas; // idem que def mais pour le calcul de la matrice masse double* sigErreur; // erreur sur l'élément dans le calcul des contraintes; double* sigErreur_relative; // idem en valeur relative Tableau tabSaveDon; // donnée particulière à la loi mécanique Tableau tabSaveTP; // donnée parti à la loi thermo physique Tableau tabSaveDefDon; // donnée particulière pour la déf Tableau tab_energ,tab_energ_t; //les différentes énergies mécaniques mises en jeux // dimensionné dans les classes dérivées, a t+dt, et a t EnergieMeca energie_totale_t,energie_totale; // le bilan sur l'élément de l'énergie bool premier_calcul_meca_impli_expli; // au premier calcul soit en implicite, explicite, mat geom // toutes les grandeurs à t=0 de la métrique sont calculées et stockées dans la déformation // ensuite elles ne sont plus calculées -> premier_calcul_meca_impli_expli sert pour l'indiquer double masse_volumique; // masse volumique de l'élément //--- stabilisation d'hourglass éventuelle Enum_StabHourglass type_stabHourglass; // méthode de stabilisation double E_Hourglass; private: //--- stabilisation d'hourglass éventuelle Tableau tab_elHourglass; // tableau de pointeurs éventuels sur des éléments servant à la stabilisation // les éléments sont définies au travers de l'appel à la méthode Cal_hourglass_comp, par une classe dérivée, double coefStabHourglass ; // coef de stabilisation Mat_pleine* raid_hourglass_transitoire; // raideur transitoire d'hourglass, éventuellement définie static Tableau< Vecteur> vec_hourglass; // tableau de vecteurs de travail, éventuellement défini // -------- pour faciliter les routines Interne_t _0 et _tdt + paramètres de contrôle ---- static const Coordonnee & (Met_abstraite::*PointM) (const Tableau& tab_noeud,const Vecteur& phi); static void (Met_abstraite::*BaseND) (const Tableau& tab_noeud, const Mat_pleine& dphi,const Vecteur& phi,BaseB& bB,BaseH& bH); // ---------- cas du bulk viscosity ------------- private: // pour éviter les modifications par les classes dérivées static int bulk_viscosity; // indique si oui ou non on utilise le bulk viscosity // en plus = 1: fonctionnement normal, =2 fonctionnement quelque soit // le signe de IDeps static double c_traceBulk; // coeff de la trace de D pour le bulk static double c_carreBulk; // coeff du carré de la trace de D pour le bulk static TenseurHH * sig_bulkHH; // variable de travail pour le bulk // ---------- pour le calcul de la masse pour la méthode de relaxation dynamique static Ddl_enum_etendu masse_relax_dyn; // simplement pour le définir une fois pour toute protected: // pour une utilisation par les classes dérivées inline bool Bulk_visco_actif() {return bulk_viscosity;}; inline double& C_traceBulk() {return c_traceBulk;}; inline double& C_carreBulk() {return c_carreBulk;}; // calcul de la contrainte modifiée en fonction du bulk viscosity // ramène l'énergie et la puissance par unité de volume, dépensée par le bulk DeuxDoubles ModifContrainteBulk(Enum_dure temps,const TenseurHH& gijHH_tdt,TenseurHH & sigHH,const TenseurBB & DepsBB_tdt ,TenseurHH & sigbulkHH); // actualisation des ddl et des grandeurs actives de t+dt vers t void TdtversT_(); // actualisation des ddl et des grandeurs actives de t vers tdt void TversTdt_(); // calcul des intégrales de volume et de volume + temps // cas = 1 : pour un appel après un calcul implicit // cas = 2 : pour un appel après un calcul explicit void Calcul_Integ_vol_et_temps(int cas,const double& poid_jacobien,int iteg); // au premier pti init éventuel des intégrales de volume et temps void Init_Integ_vol_et_temps(); // ---- utilitaires interne private: // calcul du mini du module d'young équivalent pour tous les points d'intégrations double Calcul_mini_E_qui(Enum_dure temps); // calcul du maxi du module d'young équivalent pour tous les points d'intégrations double Calcul_maxi_E_qui(Enum_dure temps); // définition d'un repère d'anisotropie à un point d'intégration BaseH DefRepereAnisotropie(int nb_pti,LesFonctions_nD* lesFonctionsnD,const BlocGen & bloc); }; /// @} // end of group #endif