Herezh_dev/contact/ElContact.h

581 lines
30 KiB
C
Raw Normal View History

// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
2023-05-03 17:23:49 +02:00
// 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 <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.
/************************************************************************
* DATE: 23/01/97 *
* $ *
* AUTEUR: G RIO (mailto:gerardrio56@free.fr) *
* $ *
* PROJET: Herezh++ *
* $ *
************************************************************************
* BUT: Element de contact. *
2023-05-03 17:23:49 +02:00
* - l'élément utilise une frontiere Front qui contient ses *
* donnees geometriques : l'élément de contact crée une copie *
* d'un élément de frontière qui existe par ailleurs, en fait *
* l'originale existe dans LesContacts. *
* L'aspect spécifique est: *
* . le Front de l'élément de contact est une copie *
* . le tableau de ses mitoyens pointe sur les originaux *
* du coup on peut supprimer et créer de nouvelles copies *
* de Front sans invalider le tableau de pointeur de Front *
* qui définit les mitoyens ! (un peu tordu ) *
* - il gère les aspects spécifiques du contact: efforts, *
* résidu, raideur etc. *
* $ *
2023-05-03 17:23:49 +02:00
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
* *
* VERIFICATION: *
* *
* ! date ! auteur ! but ! *
* ------------------------------------------------------------ *
* ! ! ! ! *
* $ *
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
* MODIFICATIONS: *
* ! date ! auteur ! but ! *
* ------------------------------------------------------------ *
* $ *
************************************************************************/
#ifndef ELCONTACT_H
#define ELCONTACT_H
#include "Front.h"
#include "Noeud.h"
#include "Condilineaire.h"
#include "LesFonctions_nD.h"
/** @defgroup Groupe_sur_les_contacts
*
* BUT: groupe relatif aux contacts
*
*
* \author Gérard Rio
* \version 1.0
* \date 23/01/97
* \brief groupe relatif aux contacts
*
*/
/// @addtogroup Groupe_sur_les_contacts
/// @{
///
class ElContact
{
public :
// une classe structure de transfert pour simplifier le passage de paramètres
class Fct_nD_contact
{ public:
Fct_nD_contact();
Fct_nD_contact(const Fct_nD_contact& a);
~Fct_nD_contact();
Fct_nD_contact& operator= (const Fct_nD_contact& a);
2023-05-03 17:23:49 +02:00
// utilisation de fct nD
Fonction_nD * fct_nD_penalisationPenetration; // fct nD dans le cas d'une valeur pilotée
Fonction_nD * fct_nD_penetration_contact_maxi; // fct nD dans le cas d'une valeur pilotée
Fonction_nD * fct_nD_penetration_borne_regularisation; // fct nD dans le cas d'une valeur pilotée
Fonction_nD * fct_nD_force_contact_noeud_maxi; // fct nD dans le cas d'une valeur pilotée
Fonction_nD * fct_nD_penalisationTangentielle;
Fonction_nD * fct_nD_tangentielle_contact_maxi; // fct nD dans le cas d'une valeur pilotée
Fonction_nD * fct_nD_tangentielle_borne_regularisation; // fct nD dans le cas d'une valeur pilotée
Fonction_nD * fct_nD_force_tangentielle_noeud_maxi; // fct nD dans le cas d'une valeur pilotée
2023-05-03 17:23:49 +02:00
Fonction_nD * fct_niveau_commentaire; // fct nD dans le cas d'une valeur pilotée
// initialisation des conteneurs statique des fonction nD
void Init_conteneur_statique();
// stockage transitoire pour les quelconques vraiment quelconque
static Tableau <const TypeQuelconque * > tqi_const_fct_nD_penalisationPenetration;
static Tableau < TypeQuelconque * > tqi_fct_nD_penalisationPenetration;
static Tableau <int> t_num_ordre_fct_nD_penalisationPenetration;
static Tableau <const TypeQuelconque * > tqi_const_fct_nD_penetration_contact_maxi;
static Tableau < TypeQuelconque * > tqi_fct_nD_penetration_contact_maxi;
static Tableau <int> t_num_ordre_fct_nD_penetration_contact_maxi;
static Tableau <const TypeQuelconque * > tqi_const_fct_nD_penetration_borne_regularisation;
static Tableau < TypeQuelconque * > tqi_fct_nD_penetration_borne_regularisation;
static Tableau <int> t_num_ordre_fct_nD_penetration_borne_regularisation;
static Tableau <const TypeQuelconque * > tqi_const_fct_nD_force_contact_noeud_maxi;
static Tableau < TypeQuelconque * > tqi_fct_nD_force_contact_noeud_maxi;
static Tableau <int> t_num_ordre_fct_nD_force_contact_noeud_maxi;
static Tableau <const TypeQuelconque * > tqi_const_fct_nD_penalisationTangentielle;
static Tableau < TypeQuelconque * > tqi_fct_nD_penalisationTangentielle;
static Tableau <int> t_num_ordre_fct_nD_penalisationTangentielle;
static Tableau <const TypeQuelconque * > tqi_const_fct_nD_tangentielle_contact_maxi;
static Tableau < TypeQuelconque * > tqi_fct_nD_tangentielle_contact_maxi;
static Tableau <int> t_num_ordre_fct_nD_tangentielle_contact_maxi;
static Tableau <const TypeQuelconque * > tqi_const_fct_nD_tangentielle_borne_regularisation;
static Tableau < TypeQuelconque * > tqi_fct_nD_tangentielle_borne_regularisation;
static Tableau <int> t_num_ordre_fct_nD_tangentielle_borne_regularisation;
static Tableau <const TypeQuelconque * > tqi_const_fct_nD_force_tangentielle_noeud_maxi;
static Tableau < TypeQuelconque * > tqi_fct_nD_force_tangentielle_noeud_maxi;
static Tableau <int> t_num_ordre_fct_nD_force_tangentielle_noeud_maxi;
static Tableau <const TypeQuelconque * > tqi_const_fct_nD_niveau_commentaire;
static Tableau < TypeQuelconque * > tqi_fct_nD_niveau_commentaire;
static Tableau <int> t_num_ordre_fct_nD_niveau_commentaire;
protected :
// définition des conteneurs de transfert des TypeQuelconque
// pour une fonction nD particulière
void Definition_conteneurs_static_TypeQuelconque
(Fonction_nD * pt_fonct,Tableau < TypeQuelconque * >& tqi
,Tableau < const TypeQuelconque * >& tqii,Tableau <int>& t_num_ordre );
};
// CONSTRUCTEURS :
// par defaut
ElContact();
// la version avec fonction de pilotage nD
ElContact(Fct_nD_contact & fct_contact);
// fonction d'un pointeur d'element frontiere et d'un pointeur de noeud
// du fait éventuel qu'il peut-être collant ou pas
ElContact ( const Front * elfront, const Noeud * noeud, Fct_nD_contact & fct_contact_, int collant = 0);
// de copie
ElContact ( const ElContact & a);
// DESTRUCTEUR :
~ElContact ();
// METHODES PUBLIQUES :
2023-05-03 17:23:49 +02:00
// affectation de toute les donnees
ElContact& operator = ( const ElContact& a);
// test d'egalite sur les éléments originaux :
// l'élément de frontière front, le noeud esclave, même zone de contact
inline bool MemeOrigine( const ElContact& a) const
2023-05-03 17:23:49 +02:00
{ if ( (this->elfront->MemeOrigine(*a.Elfront()))
&& (this->noeud->Num_noeud() == a.Const_Esclave()->Num_noeud())
&& (this->noeud->Num_Mail() == a.Const_Esclave()->Num_Mail())
&& (num_zone_contact == a.Const_Num_zone_contact())
)
return true;
else
return false;
};
// init d'une fonction nD pour le pilotage du type de contact 4
static void Init_fct_pilotage_contact4(Fonction_nD * fct_pilo_contact4)
{fct_pilotage_contact4 = fct_pilo_contact4;};
2023-05-03 17:23:49 +02:00
//retourne le niveau d'affichage
int Permet_affichage() const
{ return( (fct_nD_contact.fct_niveau_commentaire == NULL) ?
(niveau_commentaire == 0) ? ParaGlob::NiveauImpression() : niveau_commentaire
: Valeur_fct_nD(fct_nD_contact.fct_niveau_commentaire
,ElContact::Fct_nD_contact::tqi_fct_nD_niveau_commentaire
,ElContact::Fct_nD_contact::tqi_const_fct_nD_niveau_commentaire
,ElContact::Fct_nD_contact::t_num_ordre_fct_nD_niveau_commentaire
)
);
};
// méthode statique de modification éventuelle du type de contact utilisé localement
// par exemple pour le type 4 en fonction des itérations
static int Recup_et_mise_a_jour_type_contact() ;
// affichage à l'écran des informations liées au contact
2023-05-03 17:23:49 +02:00
// cas = 0 : affichage en fonction du niveau de commentaire voulu
// cas = 1 : affichage minimal nécessaire pour repérer l'élément
// cas = 2 : affichage en fonction du niveau de commentaire pour les éléments de contact
void Affiche(int cas=0) const ;
// calcul d'un contact eventuel entre le noeud esclave et la frontiere
// ramene true s'il y a contact
// si init = false, on recherche le contact a partir du precedent point sauvegarde
// sinon on commence a l'aide d'element de reference,
// et on calcule et sauvegarde les coordonnées
// initiale locales theta^i du point de contact
// si le contact existe et si l'algo le demande (cf. ParaAlgoControle) :
// le noeud pourrait-être ramené sur la surface mais:
// on ne fait pas de projection, sinon on ne peut pas tester plusieurs contacts pour
// choisir le meilleur, puisque les choses changent entre avant et après le test de contact
// donc ici la position du noeud esclave n'est pas modifiée
bool Contact( bool init = true);
// juste après l'utilisation de la méthode Contact(), ramène le point en contact
const Coordonnee& Point_intersection() const { return Mtdt; };
// un stockage utilisé par les méthodes appelantes
int& Num_zone_contact() {return num_zone_contact;};
2023-05-03 17:23:49 +02:00
int Const_Num_zone_contact() const {return num_zone_contact;};
// calcul de la trajectoire a prendre en compte pour le contact
// ---- a) cas ou à t il n'y avait pas de contact, ou que l'on n'a pas fait de projection sur la surface (cas du contact cinématique)
// 4 cas : 1) le noeud bouge, dans ce cas la trajectoire est determinee
// par la variation de la position du noeud
// 2) le noeud est immobile, mais la frontiere bouge, la trajectoire est determine
// par une parallele a la variation moyenne de la frontiere (variation de G)
// 4) est une variante du 2), cas où l'on a une rotation autour de G, dans ce cas on prend comme trajectoire
// le maxi des déplacements de noeud
// 3) rien ne bouge, on utilise la normale au point de reference de l'element de frontiere
// pour calculer la trajectoire .
// dans le cas 3 la variable test = 0 , sinon elle vaut 1 pour le cas 1 et 2 pour le cas 2 , 4 pour le cas 4
// ---- b) cas ou à t on était déjà en contact avec projection sur la surface
// la trajectoire est alors systématiquement la direction de la dernière normale,
// retour : test=5
Coordonnee Trajectoire(int & test);
// calcul de l'Intersection de la trajectoire du noeud definit par le vecteur V
// avec l'element frontiere
// ramene les coordonnees du noeud projete
// dans le cas où il n'y a pas d'intersection, on ramène un point de dimension nulle
Coordonnee Intersection( const Coordonnee& V,bool init);
// construction de la condition lineaire de contact
// nb_assemb : indique le numéro d'assemblage correspondant
Condilineaire ConditionLi(int nb_assemb);
// ramene le tableau de tous les noeuds, le premier est celui esclave
Tableau <Noeud*>& TabNoeud() {return tabNoeud;};
const Tableau <Noeud*>& Const_TabNoeud() const {return tabNoeud;};
// ramene le tableau pour assemblage: dépend du Cas_solide()
// est cohérent avec TableauDdlCont
Tableau <Noeud*>& TabNoeud_pour_assemblage() {return tabNoeud_pour_assemblage;};
// retourne les tableaux de ddl associés aux noeuds, gere par l'element
// qui sont actifs au moment de la demande
// Tableau de DdlElement pour l'assemblage uniquement
const DdlElement & TableauDdlCont() const {return *ddlElement_assemblage;};
// ramene le noeud esclave
inline Noeud* Esclave() { return noeud;};
2023-05-03 17:23:49 +02:00
inline const Noeud* Const_Esclave() const { return noeud;};
// ramene la force de contact pour consultation
const Coordonnee& Force_contact() const {return force_contact;};
// ramène les maxis concernant le noeud esclave
double F_N_MAX() const {return F_N_max;};
double F_T_MAX() const {return F_T_max;};
// ramène la pénalisation actuelle éventuelle
const double& Penalisation() const {return penalisation;};
const double& Penalisation_tangentielle() const {return penalisation_tangentielle;};
// ramène le déplacement tangentiel actuel
const Coordonnee& Dep_tangentiel() const {return dep_tangentiel;};
// ramène la normale actuelle
const Coordonnee& Normale_actuelle() const {return N;};
// idem pour les réactions sur les noeuds de la facette
const Tableau <Coordonnee>& TabForce_cont() const {return tabForce_cont;};
// actualisation de la projection du noeud esclave en fonction de la position de l'element
// maitre frontiere. Lorsque le noeud change d'element fontiere, on change l'element
// frontiere de l'element de contact en consequence
// dans le cas ou on ne trouve pas d'intersection, cas d'un noeud qui sort d'une zone de
2023-05-03 17:23:49 +02:00
// contact, on retourne 0, sinon retourne 1 si on n'a pas changé de frontière
// retourne 2 si on a changé de frontière
// en fonction de la méthode de contact, le noeud est ramené éventuellement sur la frontière
int Actualisation();
// ramene un pointeur sur l'element frontiere
inline Front * Elfront() const { return elfront;};
// permet de changer le deplacement maxi de tous les noeuds, qui sert
// pour éviter de considérer des contact trop éloignés
static void Change_dep_max(const double & deplac_max)
{dep_max = deplac_max * ParaGlob::param->ParaAlgoControleActifs().FacPourRayonAccostage();};
// test et met à jour le compteur de décollage du noeud
// si le noeud decolle ou non en fonction de la force de reaction
// ramene 1: s'il decolle
// 0: s'il ne décolle pas
bool Decol();
// change force: permet de changer la valeur de la force
// utile quand la force est calculée en dehors de l'élément de contact
void Change_force(const Coordonnee& force);
// idem pour les forces réparties sur la facette
void Change_TabForce_cont(const Tableau <Coordonnee>& tab) {tabForce_cont=tab;};
// gestion de l'activité
int Actif() const {return actif;}; // ramène l'activité du contact
2023-05-03 17:23:49 +02:00
void Met_Inactif() { actif = 0;nb_decol_tdt=0;
#ifdef MISE_AU_POINT
if (Permet_affichage() > 2)
{cout << "\n -- ElContact::Met_Inactif() -> inactivation du contact: ";this->Affiche(1);};
2023-05-03 17:23:49 +02:00
#endif
}; // met en inactif
void Met_actif() { actif++;nb_decol_tdt=0;
#ifdef MISE_AU_POINT
if (Permet_affichage() > 2)
{cout << "\n -- ElContact::Met_actif() -> activation du contact: ";this->Affiche(1);};
2023-05-03 17:23:49 +02:00
#endif
}; // met en actif une fois de plus
// ramène le nombre actuel de décolement
int Nb_decol() const {return nb_decol_tdt;};
// ramène le nombre de pénétration actuel
int Nb_pene() const {return nb_pene_tdt;};
// --- calcul des puissances virtuelles développées par les efforts de contact ----------
// et eventuellement calcul de la raideur associé
// -> explicite à tdt
virtual Vecteur* SM_charge_contact();
// -> implicite,
virtual Element::ResRaid SM_K_charge_contact();
// récup uniquement des conteneurs raideurs et résidu (pas forcément remplis, mais de la bonne taille)
Element::ResRaid Conteneur_ResRaid();
// récup uniquement du conteneur résidu (pas forcément rempli, mais de la bonne taille)
Vecteur* Conteneur_Residu();
// récupération des énergies intégrées sur l'éléments, résultants d'un précédent calcul
// explicite, ou implicite:
// 1- il s'agit ici de l'énergie développée par le frottement glissant ou pas
const EnergieMeca& EnergieFrottement() const {return energie_frottement;};
// 2- énergie de pénalisation (élastique a priori)
const double& EnergiePenalisation() const {return energie_penalisation;};
// cas d'une méthode avec pénalisation: calcul éventuel d'un pas de temps idéal,
// permettant de limiter la pénétration
// si oui retour de la valeur delta_t proposé
// sinon dans tous les autres cas retour de 0.
// le calcul se fait en fonction du pas de temps courant et de la pénétration
// donc nécessite que le contact ait déjà été étudié
double Pas_de_temps_ideal()const;
// ramène l'info sur le fait que le contact est avec un solide ou pas
// retour = 0 : contact bi déformable,
// = 1 le noeud est libre et la frontière est bloqué (solide)
// = 2 le noeud est bloqué (solide) la frontière est libre
// = 3: tout est bloqué (solide)
int Cas_solide() const {return cas_solide;};
// permet de modifier le contact entre collant ou non suivant "change"
void Change_contact_collant(bool change);
// récup de l'information concernant le contact collant ou pas
int Collant() const {return cas_collant;};
2023-05-03 17:23:49 +02:00
// gestion du lissage du lissage de la normale
void Change_lissage_normale(int lissage)
{normale_lisser = lissage;};
// récup de l'information
// indique si la normale doit-être lissée sur l'élément frontière, ou non
int Lissage_normale() const {return normale_lisser;};
// récup des gaps calculés
const double & Gaptdt() const {return gap_tdt;};
const double & Dep_T_tdt() const {return dep_T_tdt;}
// mise à jour du niveau de commentaire
2023-05-03 17:23:49 +02:00
static void Mise_a_jour_niveau_commentaire()
{niveau_commentaire = ParaGlob::param->ParaAlgoControleActifs().Niveau_commentaire_contact();};
// récupération des ddl ou des grandeurs actives de tdt vers t
void TdtversT();
// actualisation des ddl et des grandeurs actives de t vers tdt
void TversTdt();
//----- lecture écriture de restart -----
void Lec_base_info_ElContact(ifstream& ent);
void Ecri_base_info_ElContact(ofstream& sort);
#ifdef UTILISATION_MPI // spécifique au calcul parallèle
// stockage dans un unique vecteur, des infos à partir de l'indice rang inclus
// correspond à une sérialisation des infos
// ramène le positionnement dans v pour un prochain enreg, sauf si > à la taille de v
// dans ce cas ramène 0
// niveau: == 1 -> niveau minimum de sauvegarde, concerne uniquement la structure de l'élément
int Pack_vecteur(int niveau, Vecteur& v,int rang) const;
// taille du conteneur actuel de la condition linéaire
// dépend du niveau de sauvegarde
int Taille_Pack(int niveau) const;
// modification des infos à partir de l'indice rang inclus en fonction du vecteur passé en paramètre
// correspond à une désérialisation
// ramène le positionnement dans v pour un prochain enreg, sauf si > à la taille de v
// dans ce cas ramène 0
// on passe un pointeur de fonctions qui ramène un noeud en fonction d'un numéro de maillage et d'un
// numéro de noeud, ceci pour éviter de passer toute l'instance de la classe Les_maillages
// niveau: == 1 -> niveau minimum de sauvegarde, concerne uniquement la structure de l'élément
template <class T> int UnPack_vecteur(T& instance,int niveau,const Vecteur& v,int rang,
Noeud & (T::*Ptfonc) (int num_mail,int num_noeud) const );
#endif
protected :
// VARIABLES PROTEGEES :
int actif; // un indicateur, disant si le contact est actif ou pas
// conteneur plutôt utilisé par les classes appelantes
// =1 -> premier contact, > 1 contact qui suit un contact
2023-05-03 17:23:49 +02:00
// ... elfront, noeud, tabNoeud : peuvent changer d'affectation sur le pas
// pour pouvoir revenir au temps t, on définit les valeurs à t
Front* elfront, * elfront_t; // un element frontiere , qui est créé par l'élément de contact
// et qui correspond à une copie d'un élément frontière qui existe par ailleurs
// en fait, qui existe dans LesContacts
Noeud * noeud, * noeud_t; // un pointeur de noeud
// pour éviter de le construire à chaque demande on définit un tableau de tous les noeuds
2023-05-03 17:23:49 +02:00
Tableau <Noeud*> tabNoeud, tabNoeud_t; // tableau de tous les noeud, le premier est noeud
int num_zone_contact; // un stockage uniquement utilisé par les méthodes appelantes
// le tableau des positions successives du noeud esclave, ceci pour effectuer une moyenne glissante
Tableau <Coordonnee> tab_posi_esclave;
// le nombre courant de positions de noeuds esclaves actuellement stockées
int nb_posi_esclave_stocker_t,nb_posi_esclave_stocker_tdt;
// indice dans tab_posi_esclave, du prochain stockage
int indice_stockage_glissant_t,indice_stockage_glissant_tdt;
Coordonnee Mtdt,Mt; // sauvegarde du point d'intercection s'il est recevable
Coordonnee M_noeud_tdt_avant_projection; // dans le cas d'une projection du noeud sur la surface maître
// sauvegarde des coordonnées du noeuds esclave: utilisation avec le type de contact 4
// les fonctions d'interpolation au premier point en contact: sert pour le contact collant
2023-05-03 17:23:49 +02:00
Vecteur phi_theta_0 ; // *** il faut sauvegarder également la frontière correspondante
EnergieMeca energie_frottement; // énergie développée par le frottement glissant ou pas
double energie_penalisation; // énergie due à la pénalisation (élastique a priori)
// cas_solide permet de simplifier le contact dans le cas ou le maître ou l'esclave est solide
// sert pour diminuer la taille de la raideur uniquement
int cas_solide; // =0 contact bi déformable, =1 le noeud est libre et la frontière est bloqué (solide)
// = 2 le noeud est bloqué (solide) la frontière est libre
// = 3 tout est solide
int cas_collant; // prise en compte éventuelle d'un contact collant, si 0: contact normal
// = 1 : contact collant
2023-05-03 17:23:49 +02:00
int normale_lisser; // indique si la normale doit-être lissée sur l'élément, ou non
int nb_change_frontiere; // totalise sur un incrément le nb de fois de changement de front
// sert à éviter les flip flop en implicite
Vecteur * residu; // residu local
Mat_pleine * raideur; // raideur locale
DdlElement * ddlElement_assemblage; // le ddlElement qui correspond
Tableau <Noeud*> tabNoeud_pour_assemblage; // tableau des noeuds qui servent pour l'assemblage
Coordonnee force_contact,force_contact_t; // force de contact sur le noeud principal
double F_N_max,F_T_max,F_N_max_t,F_T_max_t; // les maxis constatés
Tableau <Coordonnee> tabForce_cont,tabForce_cont_t; // le tableau des forces sur les noeuds de la facette
Coordonnee N; // la dernière normale calculée
Coordonnee dep_tangentiel; // le dernier déplacement tangentiel calculé
int nb_decol_t,nb_decol_tdt; // nombre de fois où le noeud décolle de manière consécutive
double gap_t,gap_tdt; // les pénétrations d'un pas à l'autre
double dep_T_t, dep_T_tdt; // les valeurs absolue des déplacements tangentiels d'un pas à l'autre
double nb_pene_t,nb_pene_tdt; // le nombre de penetration positives
// cas TypeCalculPenalisationPenetration() = 4 ou -4
// -> cas d'un facteur multiplicatif évolutif, on fait une moyenne glissante de 2
// on mémorise donc les facteurs multiplicatifs successifs
double mult_pene_t,mult_pene_tdt;
// cas TypeCalculPenalisationTangentielle() = 4 ou -4
// -> cas d'un facteur multiplicatif évolutif, on fait une moyenne glissante de 2
// on mémorise donc les facteurs multiplicatifs successifs
double mult_tang_t,mult_tang_tdt;
double penalisation,penalisation_tangentielle; // on sauvegarde la pénalisation
// l'intérêt est de pouvoir la visualiser
double penalisation_t,penalisation_tangentielle_t; // les grandeurs à t
// utilisation de fct nD
Fct_nD_contact fct_nD_contact;
// pour le contact 4, pour le calcul de la pénalisation avec une moyenne glissante
Tableau <double > val_penal; // tableau de stockage intermédiaire
int pt_dans_val_penal; // indice du prochain elem du tableau a remplir
// stocke le dernier type de trajectoire du noeud par rapport à la facette
// c-a-d la valeur de la variable test dans la fonction Trajectoire(int & test)
int type_trajectoire_t,type_trajectoire_tdt;
// concernant les enum de ddl associées aux éléments de contact, on définit un tableau global
// qui est utilisé par tous les éléments
static list <DdlElement> list_Ddl_global; // liste de tous les DdlElements des éléments de contact
static list <Vecteur> list_SM; // list de seconds membres locals: sert pour tous les éléments de contact
static list <Mat_pleine> list_raideur; // list de raideurs locales: " " " "
// stockage du maximum de distance tolérée entre noeud à tdt et le projeté, sert pour éliminer les contacts aberrants
static double dep_max;
static int niveau_commentaire;
2023-05-03 17:23:49 +02:00
// stockage d'une fonction nD pour le pilotage du type de contact 4
static Fonction_nD * fct_pilotage_contact4;
// METHODES PROTEGEES :
// calcul la normal en fonction de differente conditions
Coordonnee Calcul_Normale (int dim, Plan & pl, Droite & dr,int indic);
void Libere();
// construction du tableau de tous les noeuds, le premier est celui esclave
// et mise à jour de ddlElement et de list_Ddl_global éventuellement
2023-05-03 17:23:49 +02:00
// et mise à jour des grandeurs liées à elfront: concerne le dimensionnement
// si on change d'elfront -> peut changer le nombre de noeud maître d'où
// il faut redimensionner: tabForce_cont,tabForce_cont_t;
void Construction_TabNoeud();
2023-05-03 17:23:49 +02:00
// récupération d'informations des classes internes pour le calcul du résidu
// N: le vecteur normal
// M_impact: le point d'impact sur la surface (ou ligne)
// phii : les fonctions d'interpolation au point d'impact
// si avec_var est vrai: il y a retour du tableau de variation de la normale
Tableau <Coordonnee >* RecupInfo(Coordonnee& N,Coordonnee& M_impact,Vecteur& phii,bool avec_var );
// mise à jour de cas_solide et donc de ddlElement en fonction de l'activité des ddl
// mise à jour du tableau de noeud pour l'assemblage tabNoeud_pour_assemblage
void Mise_a_jour_ddlelement_cas_solide_assemblage();
// récup d'une place pour le résidu local et mise à jour de list_SM éventuellement
void RecupPlaceResidu(int nbddl);
// récup d'une place pour la raideur locale et mise à jour de list_raideur éventuellement
void RecupPlaceRaideur(int nbddl);
// calcul du facteur de pénalisation en pénétration, en fonction de la géométrie
// du module de compressibilité et des différents possibles
// éventuellement, calcul de la dérivée: d_beta_gapdu, du facteur par rapport au gap
// la sensibilité dépend du type de calcul du facteur de pénalisation
double CalFactPenal(const double& gap,double & d_beta_gap,int contact_type);
// calcul du facteur de pénalisation tangentielle, en fonction de la géométrie
// du module de compressibilité et des différents cas possibles
// éventuellement, calcul de la dérivée: d_beta_gapdu, du facteur par rapport au gap
// la sensibilité dépend du type de calcul du facteur de pénalisation
double CalFactPenalTangentiel(const double& gap,double & d_beta_gap);
// limitation éventuelle au niveau de la pénétration maxi
//void Limitation_penetration_maxi(
// calcul éventuel de la moyenne glissante des positions successive du noeud esclave
void ChangeEnMoyGlissante(Coordonnee& Noe_atdt);
// calcul de la moyenne glissante de la pénalisation
void Moyenne_glissante_penalisation(double& penalisation, double& essai_penalisation);
// calcul d'une fonction nD relative à des données de contact
2023-05-03 17:23:49 +02:00
double Valeur_fct_nD(Fonction_nD * fct_nD,Tableau < TypeQuelconque * >& tqi
,Tableau < const TypeQuelconque * >& tqii,Tableau <int>& t_num_ordre ) const;
};
/// @} // end of group
// pour faire de l'inline: nécessaire avec les templates
// on n'inclut que les méthodes templates
#include "ElContact_3.cc"
#define ElContact_deja_inclus
#endif