2021-09-24 08:24:03 +02:00
// 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)
2021-09-24 08:24:03 +02:00
// 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 : Creation et gestion des contacts . *
* $ *
* ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' * *
* VERIFICATION : *
* *
* ! date ! auteur ! but ! *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
* ! ! ! ! *
* $ *
* ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' *
* MODIFICATIONS : *
* ! date ! auteur ! but ! *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
* $ *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifndef LESCONTACTS_H
# define LESCONTACTS_H
# include "Front.h"
# include <list>
# include "List_io.h"
# include "ElContact.h"
# include "Condilineaire.h"
# include "Nb_assemb.h"
# include "LesMaillages.h"
# include "LesReferences.h"
# include "Basiques.h"
# include "TypeQuelconque.h"
# include "Temps_CPU_HZpp.h"
2024-03-24 11:43:58 +01:00
# include "Enum_TypeQuelconque.h"
# include "TypeQuelconqueParticulier.h"
2023-12-15 19:17:23 +01:00
# include <stdlib.h>
# ifdef UTILISATION_MPI
# include <boost/serialization/split_member.hpp>
# include <boost/serialization/string.hpp>
# include "mpi.h"
# include <boost/mpi/environment.hpp>
# include <boost/mpi/communicator.hpp>
# include <boost/serialization/string.hpp>
# include <boost/mpi.hpp>
namespace mpi = boost : : mpi ;
# endif
2021-09-24 08:24:03 +02:00
/// @addtogroup Groupe_sur_les_contacts
/// @{
///
class LesContacts
{
public :
// CONSTRUCTEURS :
// constructeur par defaut
LesContacts ( ) ;
// constructeur de copie
LesContacts ( const LesContacts & a ) ;
// DESTRUCTEUR :
~ LesContacts ( ) ;
// METHODES PUBLIQUES :
2024-03-24 11:43:58 +01:00
// ramène le nombre de maillages esclaves en auto contact, donc qui joue le rôle esclave et maître, ou maillages mixte: dépend de la manière dont les zones de contact ont été
// est définit en lecture des données
int NbmailAutoContact ( ) const { return nbmailautocontact ; } ;
2021-09-24 08:24:03 +02:00
// ramène la liste des éléments de contact
LaLIST < ElContact > & LesElementsDeContact ( ) { return listContact ; } ;
// initialisation des zones de contacts éventuelles à partir des éléments de frontières et des noeuds esclaves
// sauf les frontières qui sont les mêmes pendant tout le calcul
// --- en entrée:
// les maillages, les ref et les fonctions nD
// -- en sortie:
// cas du contact type 4 : on renseigne éventuellement une fonction de pilotage --> fct_pilotage_contact4
// récup de: nb_mail_Esclave, nbmailMaitre,
// récup du tableau "indice" : = la liste pour chaque noeud, des éléments qui contient ce noeud
// création des conteneurs internes : tesctotal, tesN_collant, t_listFront, tesN_encontact
void Init_contact ( LesMaillages & lesMail
, const LesReferences & lesRef
, LesFonctions_nD * lesFonctionsnD ) ;
// mise à jour du tableau "indice": là on utilise les numéros de noeuds qui peuvent changer
// via une renumérotation. Le tableau indice, est un tableau utilisé pour les recherches
// mais le numéro de noeud n'est pas utilisé pour les stockages divers (on utilise un pointeur de noeud)
// du coup le tableau indice peut évoluer ex: après un remaillage avec chg de num de noeud
// il doit donc être remis à jour avant l'étude de nouveau contact
// la liste pour chaque noeud, des éléments qui contient ce noeud
// indice(i)(j) : = la liste des éléments qui contiennent le noeud j, pour le maillage i
void Mise_a_jour_indice ( const Tableau < const Tableau < List_io < Element * > > * > ind )
{ indice = ind ; } ;
// indique si l'initialisation a déjà été effectuée ou pas, car celle-ci ne doit-être faite
// qu'une fois
bool Init_contact_pas_effectue ( ) const { return ( tesctotal . Taille ( ) = = 0 ) ; } ;
// verification qu'il n'y a pas de contact avant le premier increment de charge
void Verification ( ) ;
// definition des elements de contact eventuels
// - imposition des conditions de non penetration
// dep_max : déplacement maxi des noeuds du maillage
// , sert pour def des boites d'encombrement maxi des frontières
// ramène true s'il y a effectivement création d'élément de contact
bool DefElemCont ( double dep_max ) ;
// reexamen du contact pour voir s'il n'y a pas de nouveau element de
// contact
// ramene false s'il n'y a pas de nouveau element de contact
// true sinon
// dep_max : déplacement maxi des noeuds du maillage
// , sert pour def des boites d'encombrement maxi des frontières
bool Nouveau ( double dep_max ) ;
// suppression définitive, si le contact à disparu, des éléments inactifs
// ramène false si aucun élément n'est finalement supprimé
bool SuppressionDefinitiveElemInactif ( ) ;
// relachement des noeuds collés
// ramène true s'il y a des noeuds qui ont été relachés
bool RelachementNoeudcolle ( ) ;
// definition de conditions lineaires de contact
// marquage des ddl correspondant aux directions bloquees s'il s'agit d'un contact de type 1
// casAssemb : donne le cas d'assemblage en cours
2023-12-15 19:17:23 +01:00
// Dans le cas d'un calcul parallèle, il y a transfert des conditions au cpu 0
// seules les cpu i calculent les conditions linéaires
// NB: on ne met pas la liste en const car on a besoin de pouvoir modifier les infos à l'intérieur
// des CL pour les utiliser, mais l'idée est la liste elle, reste constante
list < Condilineaire > & ConditionLin ( const Nb_assemb & casAssemb ) ;
2021-09-24 08:24:03 +02:00
2023-12-15 19:17:23 +01:00
// création d'une liste de condition linéaire, correspondant à tous les éléments de contact en cours
2021-09-24 08:24:03 +02:00
// qu'ils soient actifs ou pas (a prior cette méthode est conçu pour donner des infos relativement à la largeur
// de bandes en noeuds due aux CLL)
// chacune des condition ne contient "d'exploitable" que le tableau de noeuds associés à la CLL,
2023-12-15 19:17:23 +01:00
// Dans le cas d'un calcul parallèle, il y a transfert des conditions au cpu 0
// seules les cpu i calculent les conditions linéaires
// NB: on ne met pas la liste en const car on a besoin de pouvoir modifier les infos à l'intérieur
// des CL pour les utiliser, mais l'idée est la liste elle, reste constante
list < Condilineaire > & ConnectionCLL ( ) ;
2021-09-24 08:24:03 +02:00
// effacement du marquage de ddl bloque du au conditions lineaire de contact
void EffMarque ( ) ;
// indique si les surfaces des maillages maîtres ont des déplacements fixés
// c-a-d sont de type solide imposé
// retourne true si les déplacements des maîtres sont imposés
bool Maitres_avec_deplacement_imposer ( ) const ;
// def de la largeur de bande des elements contacts
// casAssemb : donne le cas d'assemblage a prendre en compte
// les condi linéaires ne donnent pas des largeurs de bande sup et inf égales !!!
// demi = la demi largeur de bande maxi ,
// total = le maxi = la largeur sup + la largeur inf +1
// cumule = la somme des maxis, ce qui donnera la largeur finale, due à des multiples multiplications: une par conditions linéaires
// ceci dans le cas de la prise en compte par rotation (et uniquement dans ce cas)
// en retour, ramène un booleen qui :
// = true : si la largeur de bande en noeud est supérieure à 1 (cas d'un contact avec une surface déformable)
// = false : si non, ce qui signifie dans ce cas qu'il n'y a pas d'augmentation de la largeur
// en noeud (cas d'un contact avec une surface rigide)
2023-12-15 19:17:23 +01:00
// dans le cas d'un calcul // seule le cpu 0 effectue la résolution, par contre tous les cpu i contribuent
// ils vont donc transmettre les informations au cpu 0
2021-09-24 08:24:03 +02:00
bool Largeur_Bande ( int & demi , int & total , const Nb_assemb & casAssemb , int & cumule ) ;
// actualisation du contact, on examine que les elements de contact, dont on
// actualise la projection du noeud esclave en fonction de la position de l'element
// maitre frontiere (mais la position finale du noeud n'est pas forcément changée, cela dépend du
// modèle de contact (cinématique, pénalisation etc.)
// ramène true si quelque chose à changé, false sinon
2023-05-03 17:23:49 +02:00
// choix == 1 : les éléments actifs sont maintenu en contact même si l'intersection est hors frontière
// si l'intersection n'est pas calculable, l'élément de contact est laissè inchangé
// choix == 0 : les éléments actifs sont inactivés si l'intersection est hors frontière ou
// si l'intersection n'est pas calculable
// NB: pour les deux choix, s'il y a doublon d'élément de contact, due à un changement de frontière
// en cours d'actualisation, on inactive le(s) doublon(s)
2023-12-15 19:17:23 +01:00
// dans le cas d'un calcul // chaque proc i effectue son actualisation, s'il y a changement de surface avec sortie
// de la surface gérée par le proc i, cela sera vérifié au niveau de l'élément de contact
// Le proc 0 se contente de récupérer et globaliser les retours des proc i
2023-05-03 17:23:49 +02:00
bool Actualisation ( int choix ) ;
2021-09-24 08:24:03 +02:00
// ramène une liste de noeuds dont la position a été perturbé par le contact
// (dépend du type de contact : ex cas contact = 4)
// la liste passée en paramètre est supprimée et remplacée par la liste résultat
void Liste_noeuds_position_changer ( list < Noeud * > & li_noe ) ;
// calcul des reactions de contact et stockage des valeurs
// solution : le vecteur residu
// test d'un decollement eventuelle, pour un noeud en contact
// ramene true s'il y a decollement, sinon false
// casAssemb : donne le cas d'assemblage en cours
void CalculReaction ( Vecteur & residu , bool & decol , const Nb_assemb & casAssemb
, bool affiche ) ;
// récupération via les éléments de contact des forces maxis
// un : le maxi en effort normal, deux: le maxi en effort tangentiel
2024-01-30 20:55:48 +01:00
DeuxDoubles Forces_contact_maxi ( bool affiche ) ;
2021-09-24 08:24:03 +02:00
2024-01-30 20:55:48 +01:00
// récupération via les éléments de contact des gaps maxi en négatif, donc les mini
2021-09-24 08:24:03 +02:00
// un : le maxi en gap normal, deux: le maxi en gap tangentiel
2024-01-30 20:55:48 +01:00
DeuxDoubles Gap_contact_maxi ( bool affiche ) ;
2021-09-24 08:24:03 +02:00
// cas d'une méthode avec pénalisation: calcul éventuel d'un pas de temps idéal,
// 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, des forces de réaction et de la pénétration
// donc nécessite que le contact ait déjà été étudié et que les efforts de contact ait été calculé
2024-01-30 20:55:48 +01:00
double Pas_de_temps_ideal ( ) ;
2021-09-24 08:24:03 +02:00
// calcul d'une estimation du pas de temps critique du aux éléments de contact
// affichage des reactions de contact sur la sortie
void Affiche ( ofstream & sort ) const ;
// affichage à l'écran des informations liées au contact
void Affiche ( ) const ;
// affichage et definition interactive des commandes
void Info_commande_LesContacts ( UtilLecture & entreePrinc ) ;
// lecture éventuelle des zones où le contact doit être recherché, à l'exclusion de tout
// autre zone, ainsi que la définition de l'auto-contact éventuel
// ainsi que des contacts solide-deformables éventuel
2023-12-15 19:17:23 +01:00
// cas d'un calcul parallèle, tous les proc utilisent la méthode, seule le proc 0 affiche
2021-09-24 08:24:03 +02:00
void Lecture_zone_contact ( UtilLecture & entreePrinc , const LesReferences & lesRef ) ;
// 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 ( ) ;
2024-03-24 11:43:58 +01:00
// ramène le nombre de contacts actifs actuel
int Nb_actifs ( ) const { return nb_contact_actif ; } ;
2021-09-24 08:24:03 +02:00
//------- temps cpu -----
// retourne temps cumulé pour imposer les CL imposées
const Temps_CPU_HZpp & Temps_cpu_Contact ( ) const { return tempsContact ; } ;
2023-09-03 10:10:17 +02:00
# ifdef UTILISATION_MPI
// cas d'un calcul parallèle: // passage des infos entre process
const Temps_CPU_HZpp & Temps_transfert_court ( ) const { return temps_transfert_court ; } ;
const Temps_CPU_HZpp & Temps_transfert_long ( ) const { return temps_transfert_long ; } ;
const Temps_CPU_HZpp & Temps_attente ( ) const { return temps_attente ; } ;
2024-03-24 11:43:58 +01:00
// mise à jour list contact pour proc 0: il s'agit des infos minimales
void Mise_a_jour_liste_contacts_actif_interProc ( ) ;
// on définit une méthode qui permet de retrouver un élément à partir d'infos minimales
ElContact * RecupElContactActif ( int num_mailEsclave , int num_noeudEsclave , int numUnique )
{ LaLIST < ElContact > : : iterator ili , ilifin = listContact . end ( ) ;
for ( ili = listContact . begin ( ) ; ili ! = ilifin ; ili + + )
if ( ( ( * ili ) . Esclave ( ) - > Num_Mail ( ) = = num_mailEsclave )
& & ( ( * ili ) . Esclave ( ) - > Num_noeud ( ) = = num_noeudEsclave )
& & ( ( * ili ) . Elfront ( ) - > NumUnique ( ) = = numUnique )
)
return ( & ( * ili ) ) ;
return NULL ;
} ;
2023-09-03 10:10:17 +02:00
# endif
2021-09-24 08:24:03 +02:00
//----- lecture écriture de restart -----
// cas donne le niveau de sauvegarde
void Ecri_base_info_LesContacts ( ofstream & sort ) ;
// on utilise deux pointeurs de fonctions qui permettent de récupérer le pointeur de noeud esclave
// idem au niveau de l'élément
template < class T >
void Lec_base_info_LesContacts ( ifstream & ent
, T & instance // l'instance qui permet d'appeler les pointeurs de fonctions
, Noeud & ( T : : * RecupNoeud ) ( int i , int j ) const
, Element & ( T : : * RecupElement_LesMaille ) ( int i , int j ) const ) ;
// méthode générale: récupération des grandeurs particulière (hors ddl )
// correspondant à liTQ
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
// ===> n'est pas utilisée dans le cas du contact, c'est la méthode spécifique
// Mise_a_jour_Pour_Grandeur_particuliere qui la remplace (qui n'est pas en const car elle
// modifie les conteneurs des noeuds et éventuellement éléments)
void Grandeur_particuliere
( bool absolue , List_io < TypeQuelconque > & , Loi_comp_abstraite : : SaveResul * , list < int > & decal ) const
{ } ;
// Il s'agit ici de mettre à jour les conteneurs stockés aux noeuds et/ou aux éléments
// qui servent à récupérer les infos liés aux contact correspondant à liTQ
// actuellement les conteneurs passés en paramètre ne servent que pour
// les énumérés, et les informations résultantes sont stockées au niveau des noeuds
// constituant les éléments de contact
//--> important : les conteneurs sont supposés initialisés avec l'appel
void Mise_a_jour_Pour_Grandeur_particuliere (
List_io < TypeQuelconque > & li_restreinte_TQ
) ;
// récupération de la liste de tous les grandeurs particulières disponibles avec le contact
// cette liste est identique quelque soit le maillage: il n'y a donc pas de tableau indicé du num de maillage
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
List_io < TypeQuelconque > ListeGrandeurs_particulieres ( bool absolue ) const ;
// concernant les grandeurs gérées par le contact:
// ramène une liste d'iterator correspondant aux List_io<TypeQuelconque> passé en paramètre
// idem pour une List_io < Ddl _enum_etendu >
void List_reduite_aux_contact ( const List_io < TypeQuelconque > & liTQ
, List_io < TypeQuelconque > & li_restreinte_TQ
) ;
// initialisation des listes de grandeurs qu'ils faudra transférérer aux niveaux des noeuds des élements
// de contact, on définit si besoin, les conteneurs ad hoc au niveau des noeuds
// ok, mais à revoir sans doute cf. pense bete 14 oct
void Init_Grandeur_particuliere ( bool absolue , List_io < TypeQuelconque > & li1 ) ;
2023-05-03 17:23:49 +02:00
//retourne le niveau d'affichage
2024-01-30 20:55:48 +01:00
// li si non nulle permet d'indiquer spécifiquement quelle grandeur on veut
// sortir
int Permet_affichage ( list < TypeQuelconque > * li = NULL ) const
2024-03-24 11:43:58 +01:00
{ int niveau_commentaire_lescontacts = ParaGlob : : param - > ParaAlgoControleActifs ( ) . Niveau_commentaire_LesContact ( ) ;
2024-01-30 20:55:48 +01:00
return ( ( fct_niveau_commentaire = = NULL ) ?
( niveau_commentaire_lescontacts = = 0 ) ? ParaGlob : : NiveauImpression ( ) : niveau_commentaire_lescontacts
: Valeur_fct_nD_LesContacts ( fct_niveau_commentaire , li
, LesContacts : : tqi_fct_nD_niveau_commentaire
, LesContacts : : tqi_const_fct_nD_niveau_commentaire
, LesContacts : : t_num_ordre_fct_nD_niveau_commentaire )
) ;
2023-05-03 17:23:49 +02:00
} ;
2023-09-03 10:10:17 +02:00
2021-09-24 08:24:03 +02:00
// initialisation de la liste de grandeurs qui sont effectivement gérées par le contact
// ok, mais à revoir sans doute cf. pense bete 14 oct
// List_io<TypeQuelconque> Init_list_grandeur_contact_a_sortir(const Tableau <List_io < TypeQuelconque > >& li1);
class ReactCont
{ // surcharge de l'operator de lecture
friend istream & operator > > ( istream & , ReactCont & ) ;
// surcharge de l'operator d'ecriture
friend ostream & operator < < ( ostream & , const ReactCont & ) ;
public :
Noeud * noe ; // noeud esclave
Coordonnee force ; // force de reaction au noeud esclave
Tableau < Noeud * > tabNoeud ; // les noeuds de la frontiere maitre
Tableau < Coordonnee > tabForce ; // les reac "" ""
// constructeur par defaut
ReactCont ( ) ;
// constructeur en fonction des datas du noeud esclave seul
ReactCont ( Noeud * no , const Coordonnee & forc ) ;
// constructeur en fonction des datas de tous les noeuds
ReactCont ( Noeud * no , const Coordonnee & forc , Tableau < Noeud * > tN , const Tableau < Coordonnee > & tFor ) ;
// constructeur de copie
ReactCont ( const ReactCont & a ) ;
// affectation
ReactCont & operator = ( const ReactCont & a ) ;
// test
bool operator = = ( const ReactCont & a ) ;
bool operator ! = ( const ReactCont & a ) ;
} ;
//----------------------------------------------------------------------------------------------------
private :
// VARIABLES PROTEGEES de la classe LesContacts:
LesFonctions_nD * sauve_lesFonctionsnD ; // sauvegarde à l'initialisation (méthode Init_contact)
ElContact : : Fct_nD_contact fct_nD_contact ; // fonctions nD de pilotage: peuvent ne pas exister
2024-01-30 20:55:48 +01:00
// -- partie affichage éventuellement piloté
Fonction_nD * fct_niveau_commentaire ; // fct nD dans le cas d'une valeur pilotée
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 ;
2024-03-24 11:43:58 +01:00
list < TypeQuelconque > li_pour_noeuds_element ; // pour une sortie spécifique noeud et ou élément fini contenant la frontière
Grandeur_scalaire_entier * gr_pour_noeud ; // contient le numéro de noeud esclave éventuel
Grandeur_scalaire_entier * gr_pour_elem ; // contient le numéro éventuel de l'élément fini contenant la frontière
2024-01-30 20:55:48 +01:00
// -- fin partie affichage éventuellement piloté
2021-09-24 08:24:03 +02:00
LaLIST < ElContact > listContact ; // la liste des elements en contact
LaLIST < LaLIST < ElContact > : : iterator > listContact_nouveau_tatdt ; // la liste des nouveaux contacts qui sont apparus sur l'incrément
LaLIST < ElContact > listContact_efface_tatdt ; // la liste des contacts effacés sur l'incrément
int nb_contact_actif ; // nombre de contact actif courant
// list <TroisEntiers> numtesN; // .un : maillage, .deux: num zone de contact, .trois: num propre du noeud
// // la liste des numéros dans tesN des noeuds en contact
Tableau < ReactCont > tabReacCont ; // les reactions
2023-12-15 19:17:23 +01:00
list < Condilineaire > listCoLin ; // tableau des conditions lineaires
2021-09-24 08:24:03 +02:00
static MotCle motCle ; // liste des mots clés
// la liste des éléments qui contiennent des frontières, est reconstitué au démarrage avec Init_contact(..
list < Element * > liste_elemens_front ;
// la liste pour chaque noeud, des éléments qui contient ce noeud : construite avec Init_contact
// indice(i)(j) : = la liste des éléments qui contiennent le noeud j, pour le maillage i
Tableau < const Tableau < List_io < Element * > > * > indice ;
//--------- les tableaux de gestions pour la recherche de contact ----------------
2023-09-03 10:10:17 +02:00
list < Quatre_string_un_entier > nom_ref_zone_contact ; // liste des noms de références des zones de contact éventuelle
2021-09-24 08:24:03 +02:00
// cette liste peut être vide, dans ce cas cela signifie que toutes les frontières des pièces sont
// suceptible de rentrer en contact. Dans le cas où la liste n'est pas vide, seules les grandeurs
// référencées sont succeptibles de rentrer en contact
// nom1 -> nom_mail_ref_zone_contact pour les noeuds
// nom2 -> le nom de la référence de noeuds
// nom3 -> nom_mail_ref_zone_contact pour les frontières
// nom4 -> le nom de la référence de frontière
// n -> l'entier = 0 : pas d'utilisation
// = 1 : indique qu'il faut considérer un contact collant (glue)
2023-05-03 17:23:49 +02:00
Tableau < int > lissage_de_la_normale ; // même dimension que nom_ref_zone_contact
// lissage_de_la_normale(i) : indique si oui ou non, la normale sur la zone i doit être lissée
2021-09-24 08:24:03 +02:00
// la liste des éléments frontières succeptibles d'entrer en contact
// ces Front (qui contiennent que des pointeurs sauf une boite d'encombrement)
// sont différents de ceux des maillages, et sont donc stocké en interne
Tableau < Tableau < LaLIST_io < Front > > > t_listFront ;
// t_listFront(i)(j)(k) : maillage maître (i)
// zone de contact (j)
// (K) = kième frontière (dans l'ordre de la liste)
// ** pour le tableaux t_listFront, le numéros dit de maillage, n'est pas le numéro
// ** intrinsèque de maillage (telle que ceux associés aux noeuds et éléments)
// ** mais uniquement un numéro locale d'ordre
// ** mais on a: les éléments de frontière de t_listFront(i) font partie du maillage
// i + (nb_mail_Esclave-nbmailautocontact)
2024-03-24 11:43:58 +01:00
# ifdef UTILISATION_MPI
// cas d'un calcul parallèle: // passage des infos entre process
Tableau < Front * > pointe_t_listFront ; // pointe_t_listFront(i_num) permet de repérer un élément unique
// dans t_listFront
// à l'inverse, chaque Front stocke son numéro i_num
// pointe_t_listFront est défini dans LesContacts::Init_contact
Vecteur v_interProc_contact_actif ; // conteneur de travail utilisé pour le passage d'infos
// entre proc , par la méthode Mise_a_jour_liste_contacts_actif_interProc()
# endif
2021-09-24 08:24:03 +02:00
// les noeuds esclaves potentiels
Tableau < Tableau < Tableau < Noeud * > > > tesctotal ;
// tesctotal(i)(j)(k) : maillage esclave (i), zone de contact (j)
// noeud esclave (k) : k= le numéro d'ordre dans tesctotal(i)(j),
// ==>> ce n'est pas le numéro du noeud dans le maillage !
// indicateur de noeuds collants
Tableau < Tableau < Tableau < int > > > tesN_collant ;
// tesN_collant(i)(j)(k): maillage esclave (i), zone de contact (j)
// noeud esclave (k):k= le numéro d'ordre dans tesctotal(i)(j),
// ==>> ce n'est pas le numéro du noeud dans le maillage !
// indique pour si le noeud esclave doit être
// considéré en contact collant (=1) ou pas (=0)
// tesN_encontact: globalise tous les contacts sur un noeud (indépendamment des zones de contact)
// tesN_encontact(i)(num_noe) : nombre de contact avec le noeud
// ancien stockage: Tableau < Tableau < LaLIST < LaLIST<ElContact>::iterator > > > tesN_encontact;
// ancien stockage // tesN_encontact(i)(num_noe): maillage (i), noeud -> num_noe:
// indique pour le noeud esclave s'il est en contact ou non via la taille de la liste associée
// utilisation: pour chaque Noeud* = tesctotal(i)(k) -> la liste des éléments en contact
// contenant le noeud k
// on remplace par une map: l'avantage c'est que l'on utilise plus les numéros de noeuds pour
// retrouver la liste, mais on utilise à la place la valeur pointeur de noeud esclave qui
// doit être unique, du coup c'est indépendant de la numérotation des noeuds -> permet de la renumérotation
// sans changer la map
Tableau < std : : map < Noeud * , LaLIST < LaLIST < ElContact > : : iterator > > > tesN_encontact ;
2024-01-30 20:55:48 +01:00
// tesN_encontact(numMail_esclave)[*pt_noeud] -> la liste des iterators d'élément de contact
2021-09-24 08:24:03 +02:00
// avec le noeud
//--------- fin tableaux de gestions pour la recherche de contact ----------------
int nb_mail_Esclave ; // indique le nombre de maillages esclaves
int nbmailautocontact ; // indique le nombre de maillages esclaves en auto contact, donc qui joue le rôle esclave et maître, ou maillages mixte: dépend de la manière dont les zones de contact ont été définit
int nbmailMaitre ; // indique le nombre de maillages maitres
// = nombre total de maillage - (nb_mail_Esclave-nbmailautocontact)
// si l'on considère l'ensemble des maillages du calcul on a successivement:
// les nb_mail_Esclave-nbmailautocontact premier maillages: purement esclave
// puis les nbmailautocontact qui sont en auto contact: ils jouent le rôle d'esclaves et maîtres en même temps
// puis nbmailMaitre-nbmailautocontact : purement maître
list < Deux_String > cont_solide_defor ; // liste des noms de maillages définissants les contacts
// solide-déformable: (*ie).nom1 -> le maillage solide , (*ie).nom2 -> le maillage deformable
// ---- pour le post traitement ---
List_io < TypeQuelconque > liQ_en_sortie ; // liste de grandeurs quelconque qu'il faut sortir
// -------- une variable de travail pour la méthode LesContacts::ConnectionCLL()---
2023-12-15 19:17:23 +01:00
list < Condilineaire > t_connectionCLL ;
2021-09-24 08:24:03 +02:00
//------- temps cpu -----
// retourne temps cumulé pour imposer les CL imposées
Temps_CPU_HZpp tempsContact ;
2023-09-03 10:10:17 +02:00
# ifdef UTILISATION_MPI
// cas d'un calcul parallèle: // passage des infos entre process
Temps_CPU_HZpp temps_transfert_court ;
Temps_CPU_HZpp temps_transfert_long ;
Temps_CPU_HZpp temps_attente ;
2023-12-15 19:17:23 +01:00
Vecteur inter_transfer ; // un conteneur de transfert pour ConditionLin
Vecteur inter_transfer2 ; // un conteneur de transfert pour ConnectionCLL
// on sauvegarde un pointeur sur les maillages
LesMaillages * lesMaille ;
2023-09-03 10:10:17 +02:00
# endif
2021-09-24 08:24:03 +02:00
// METHODES PROTEGEES :
// mise à jour des boites d'encombrement pour les éléments qui contiennent une frontière
void Mise_a_jour_boite_encombrement_element_contenant_front ( ) ;
// suppression du gap de contact pour les noeuds "collant avec suppression de gap"
void Suppression_gap_pour_noeud_collant ( ) ;
// récupération de la zone de contact d'un élément de contact existant
// c'est un peu lourdinge, mais l'avantage c'est que cela s'adapte à une situation qui
// a par exemple changé
// si en retour le numéro de zone = 0, cela signifie que le contact ne peut plus exister
int Recup_ref ( ElContact & al ) ;
// récupère le nombre de contact actif et met à jour ce nombre
2023-05-03 17:23:49 +02:00
int Calcul_Nb_contact_actif ( ) ;
2021-09-24 08:24:03 +02:00
// création du conteneur Fct_nD_contact
void Creation_Fct_nD_contact ( ) ;
2023-05-03 17:23:49 +02:00
// création et ajout des éléments de frontière correspondant aux angles morts
// en 2D : noeud frontière + éléments interne
// en 3D : ligne frontière + éléments interne
void ElementAngleMort ( LesMaillages & lesMail ) ;
// test si un nouvel élément de contact possible appartient en fait déjà à la liste des contacts enregistrés
// NB: pas rusé mais il faudrait pour optimiser, ordonner la liste des éléments de contact en
// introduisant une nouvelle relation d'ordre et un nouvel operateur d'égalité ...
//il faut regarder s'il est actif aussi ???
//mais en création on pourrait regarder les intactifs, et au lieu de créer un nouveau, passer l'inactif en actif
//du coup, il faudrait peut-être ramener l'élément trouvé pour changer son activité ??
//donc ici il y a quelque chose à faire
ElContact * Element_contact_deja_present ( const ElContact & al )
{ LaLIST < ElContact > : : iterator ili , ilifin = listContact . end ( ) ;
for ( ili = listContact . begin ( ) ; ili ! = ilifin ; ili + + )
if ( ( * ili ) . MemeOrigine ( al ) )
return ( & ( * ili ) ) ;
return NULL ;
} ;
// idem mais avec un iterator
// permet de comparer un iterator de la liste avec les éléments de la liste
ElContact * Element_contact_deja_present ( LaLIST < ElContact > : : iterator & il )
{ LaLIST < ElContact > : : iterator ili , ilifin = listContact . end ( ) ;
for ( ili = listContact . begin ( ) ; ili ! = ilifin ; ili + + )
if ( ( ( * ili ) . MemeOrigine ( * il ) ) & & ( il ! = ili ) )
return ( & ( * ili ) ) ;
return NULL ;
} ;
2024-03-24 11:43:58 +01:00
// recherche dans les Front enregistrés de la zone , c-a-d dans t_listFront(i)(zone)
// un Front de même origine , c-a-d sans les mitoyens
// si aucun résultat retourne NULL
// sinon ramène l'élément de t_listFront de même origine
Front * Front_de_meme_origine ( Front * fro , int zone ) const ;
2024-01-30 20:55:48 +01:00
// init éventuel du pilotage par fct nD du niveau de commentaire
void Init_fct_niveau_commentaire ( ) ;
// définition des conteneurs des TypeQuelconque pour fct nD de LesContacts
void Definition_conteneurs_fctnD_TypeQuelconque
( Fonction_nD * pt_fonct , Tableau < TypeQuelconque * > & tqi , Tableau < const TypeQuelconque * > & tqii
, Tableau < int > & t_num_ordre ) ;
// calcul d'une fonction nD relative à aux données de LesContacts
double Valeur_fct_nD_LesContacts ( Fonction_nD * fct_nD , list < TypeQuelconque > * li
, Tableau < TypeQuelconque * > & tqi
, Tableau < const TypeQuelconque * > & tqii
, Tableau < int > & t_num_ordre ) const ;
2023-05-03 17:23:49 +02:00
2021-09-24 08:24:03 +02:00
} ;
/// @} // end of group
// pour faire de l'inline: nécessaire avec les templates
// on n'inclut que les méthodes templates
# include "LesContacts_2.cc"
# define LesContacts_2_deja_inclus
# endif