581 lines
30 KiB
C++
581 lines
30 KiB
C++
|
|
// This file is part of the Herezh++ application.
|
|
//
|
|
// The finite element software Herezh++ is dedicated to the field
|
|
// of mechanics for large transformations of solid structures.
|
|
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
|
|
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
|
|
//
|
|
// Herezh++ is distributed under GPL 3 license ou ultérieure.
|
|
//
|
|
// Copyright (C) 1997-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. *
|
|
* - 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. *
|
|
* $ *
|
|
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
|
|
* *
|
|
* 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);
|
|
|
|
|
|
// 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
|
|
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 :
|
|
|
|
// 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
|
|
{ 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;};
|
|
|
|
//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
|
|
// 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;};
|
|
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;};
|
|
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
|
|
// 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
|
|
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);};
|
|
#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);};
|
|
#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;};
|
|
|
|
// 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
|
|
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
|
|
// ----- pour l'instant ne sert pas !!! on commente ------
|
|
// // 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
|
|
|
|
// ... 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
|
|
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
|
|
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
|
|
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;
|
|
|
|
// 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
|
|
// 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();
|
|
|
|
// 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
|
|
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
|