// 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-2021 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//
// 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);
// -------------------- 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 du nom éventuel d'une fonction
StabMembBiel(double v,string * s);
// 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;};
//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;};
// 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();
// 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
//--- gestion éventuelle des maxi mini -----
// 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 -----
Tableau F_StabMembBiel; // la force généralisé de stabilisation actuelle à chaque noeud
Tableau F_StabMembBiel_t; // la force généralisé de stabilisation à t
Tableau E_StabMembBiel; // l'énergie développée par la stabilisation à chaque noeud
Tableau E_StabMembBiel_t; // l'énergie développée par la stabilisation à t à chaque noeud
string * nom_fctnD; // sert uniquement lors de la lecture base info, en attendant de définir
//pt_fct_gamma
};
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