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/>.
# include "LesContacts.h"
# include <vector>
# include "ReferenceNE.h"
# include "ReferenceAF.h"
# include "CharUtil.h"
// --------------- variables statiques ---------
MotCle LesContacts : : motCle ; // liste des mots clés
2024-01-30 20:55:48 +01:00
Tableau < const TypeQuelconque * > LesContacts : : tqi_const_fct_nD_niveau_commentaire ;
Tableau < TypeQuelconque * > LesContacts : : tqi_fct_nD_niveau_commentaire ;
Tableau < int > LesContacts : : t_num_ordre_fct_nD_niveau_commentaire ;
2021-09-24 08:24:03 +02:00
//------------------------- la classe ReactCont -------------
// surcharge de l'operator de lecture
//istream & operator >> (istream & ent, LesContacts::ReactCont & a)
istream & operator > > ( istream & ent , LesContacts : : ReactCont & )
{ // lecture du type et vérification
string nom_type ; ent > > nom_type ;
if ( nom_type ! = " LesContacts::ReactCont " )
Sortie ( 1 ) ;
// les infos **** pb de la reconnaissance du noeud ***
/* EN CHANTIER
ent > > a . noe - > Num_Mail ( ) > > a . noe - > Num_noeud ( ) < < " " ;
// la force
sort < < a . force ;
// les noeuds de la frontière maitre
int taille = tabNoeud . Taille ( ) ;
for ( int i = 1 ; i < = taille ; i + + )
sort < < a . tabNoeud ( i ) - > Num_Mail ( )
< < " " < < a . tabNoeud ( i ) - > Num_noeud ( ) < < " " ;
// les réactions de la frontière maître
int taille2 = tabForce . Taille ( ) ;
for ( int i = 1 ; i < = taille2 ; i + + )
sort < < a . tabForce ( i ) ; */
return ent ;
} ;
// surcharge de l'operator d'ecriture
ostream & operator < < ( ostream & sort , const LesContacts : : ReactCont & a )
{ // écriture du type
sort < < " LesContacts::ReactCont " ;
// les infos
sort < < a . noe - > Num_Mail ( ) < < " " < < a . noe - > Num_noeud ( ) < < " " ;
// la force
sort < < a . force ;
// les noeuds de la frontière maitre
int taille = a . tabNoeud . Taille ( ) ;
for ( int i = 1 ; i < = taille ; i + + )
sort < < a . tabNoeud ( i ) - > Num_Mail ( )
< < " " < < a . tabNoeud ( i ) - > Num_noeud ( ) < < " " ;
// les réactions de la frontière maître
int taille2 = a . tabForce . Taille ( ) ;
for ( int i = 1 ; i < = taille2 ; i + + )
sort < < a . tabForce ( i ) ;
return sort ;
} ;
// constructeur par defaut
LesContacts : : ReactCont : : ReactCont ( ) : force ( ) , tabNoeud ( ) , tabForce ( ) { noe = NULL ; } ;
// constructeur en fonction des datas du noeud esclave seul
LesContacts : : ReactCont : : ReactCont ( Noeud * no , const Coordonnee & forc ) :
force ( forc ) , tabNoeud ( ) , tabForce ( ) { noe = no ; } ;
// constructeur en fonction des datas de tous les noeuds
LesContacts : : ReactCont : : ReactCont
( Noeud * no , const Coordonnee & forc , Tableau < Noeud * > tN , const Tableau < Coordonnee > & tFor )
: force ( forc ) , tabNoeud ( tN ) , tabForce ( tFor ) { noe = no ; } ;
// constructeur de copie
LesContacts : : ReactCont : : ReactCont ( const ReactCont & a ) : force ( a . force ) , tabNoeud ( a . tabNoeud ) , tabForce ( a . tabForce )
{ noe = a . noe ; } ;
// affectation
LesContacts : : ReactCont & LesContacts : : ReactCont : : operator = ( const LesContacts : : ReactCont & a )
{ force = a . force ; noe = a . noe ; tabNoeud = a . tabNoeud ; tabForce = a . tabForce ;
return * this ; } ;
// test
bool LesContacts : : ReactCont : : operator = = ( const LesContacts : : ReactCont & a )
{ if ( ( force = = a . force ) & & ( noe = = a . noe ) & &
( tabNoeud = = a . tabNoeud ) & & ( tabForce = = a . tabForce ) )
return true ; else return false ; } ;
bool LesContacts : : ReactCont : : operator ! = ( const LesContacts : : ReactCont & a )
{ if ( * this = = a ) return false ; else return true ; } ;
//------------------------- fin la classe ReactCont -------------
// CONSTRUCTEURS :
// constructeur par defaut
LesContacts : : LesContacts ( ) :
2023-12-15 19:17:23 +01:00
listCoLin ( ) , tabReacCont ( ) , listContact ( ) //,numtesN()
2021-09-24 08:24:03 +02:00
, sauve_lesFonctionsnD ( NULL ) , fct_nD_contact ( )
2024-03-24 11:43:58 +01:00
, fct_niveau_commentaire ( NULL ) , li_pour_noeuds_element ( ) , gr_pour_noeud ( NULL ) , gr_pour_elem ( NULL )
2021-09-24 08:24:03 +02:00
, listContact_nouveau_tatdt ( ) , listContact_efface_tatdt ( )
2023-05-03 17:23:49 +02:00
, nom_ref_zone_contact ( ) , lissage_de_la_normale ( )
2021-09-24 08:24:03 +02:00
, t_listFront ( ) , nb_mail_Esclave ( ) , nbmailautocontact ( 0 ) , nbmailMaitre ( )
2024-03-24 11:43:58 +01:00
# ifdef UTILISATION_MPI
, pointe_t_listFront ( ) , v_interProc_contact_actif ( )
# endif
2021-09-24 08:24:03 +02:00
, tesctotal ( ) , tesN_encontact ( )
, tesN_collant ( )
, nb_contact_actif ( 0 ) , indice ( ) , cont_solide_defor ( ) , liQ_en_sortie ( )
, t_connectionCLL ( )
, liste_elemens_front ( ) , tempsContact ( )
2023-09-03 10:10:17 +02:00
# ifdef UTILISATION_MPI
, temps_transfert_court ( ) , temps_transfert_long ( ) , temps_attente ( )
2023-12-15 19:17:23 +01:00
, inter_transfer ( ) , inter_transfer2 ( ) , lesMaille ( NULL )
2023-09-03 10:10:17 +02:00
# endif
2024-03-24 11:43:58 +01:00
{ // pour une sortie spécifique noeud et ou element
Grandeur_scalaire_entier grand_courant_entier ( 0 ) ; // par défaut pour la création des conteneurs quelconques
li_pour_noeuds_element . push_front ( TypeQuelconque ( NUM_NOEUD , X1 , grand_courant_entier ) ) ;
gr_pour_noeud = ( ( Grandeur_scalaire_entier * ) ( * li_pour_noeuds_element . begin ( ) ) . Grandeur_pointee ( ) ) ;
li_pour_noeuds_element . push_front ( TypeQuelconque ( NUM_ELEMENT , EPS11 , grand_courant_entier ) ) ;
gr_pour_elem = ( ( Grandeur_scalaire_entier * ) ( * li_pour_noeuds_element . begin ( ) ) . Grandeur_pointee ( ) ) ;
} ;
2021-09-24 08:24:03 +02:00
// constructeur de copie
LesContacts : : LesContacts ( const LesContacts & a ) :
2023-12-15 19:17:23 +01:00
listCoLin ( a . listCoLin ) , tabReacCont ( a . tabReacCont )
2021-09-24 08:24:03 +02:00
, sauve_lesFonctionsnD ( a . sauve_lesFonctionsnD ) , fct_nD_contact ( a . fct_nD_contact )
2024-03-24 11:43:58 +01:00
, fct_niveau_commentaire ( a . fct_niveau_commentaire ) , li_pour_noeuds_element ( a . li_pour_noeuds_element )
, gr_pour_noeud ( a . gr_pour_noeud ) , gr_pour_elem ( a . gr_pour_elem )
2021-09-24 08:24:03 +02:00
, listContact ( a . listContact ) //,numtesN(a.numtesN)
, listContact_nouveau_tatdt ( a . listContact_nouveau_tatdt ) , listContact_efface_tatdt ( a . listContact_efface_tatdt )
2023-05-03 17:23:49 +02:00
, nom_ref_zone_contact ( a . nom_ref_zone_contact ) , lissage_de_la_normale ( a . lissage_de_la_normale )
2021-09-24 08:24:03 +02:00
, t_listFront ( a . t_listFront ) , nb_mail_Esclave ( a . nb_mail_Esclave ) , nbmailautocontact ( a . nbmailautocontact )
2024-03-24 11:43:58 +01:00
# ifdef UTILISATION_MPI
, pointe_t_listFront ( ) , v_interProc_contact_actif ( )
# endif
2021-09-24 08:24:03 +02:00
, nbmailMaitre ( a . nbmailMaitre ) , tesctotal ( a . tesctotal ) , tesN_encontact ( a . tesN_encontact )
, tesN_collant ( a . tesN_collant )
, nb_contact_actif ( a . nb_contact_actif ) , indice ( a . indice ) , cont_solide_defor ( a . cont_solide_defor )
, liste_elemens_front ( a . liste_elemens_front ) , liQ_en_sortie ( ) , tempsContact ( a . tempsContact )
, t_connectionCLL ( a . t_connectionCLL )
2023-09-03 10:10:17 +02:00
# ifdef UTILISATION_MPI
, temps_transfert_court ( a . temps_transfert_court )
, temps_transfert_long ( a . temps_transfert_long ) , temps_attente ( a . temps_attente )
2023-12-15 19:17:23 +01:00
, inter_transfer ( ) , inter_transfer2 ( ) , lesMaille ( NULL )
2023-09-03 10:10:17 +02:00
# endif
2024-03-24 11:43:58 +01:00
{ // on réaffecte les pointeurs pour la sortie spécifique noeud et ou element
list < TypeQuelconque > : : iterator ili = li_pour_noeuds_element . begin ( ) ;
gr_pour_elem = ( ( Grandeur_scalaire_entier * ) ( * ili ) . Grandeur_pointee ( ) ) ;
ili + + ;
gr_pour_noeud = ( ( Grandeur_scalaire_entier * ) ( * ili ) . Grandeur_pointee ( ) ) ;
# ifdef UTILISATION_MPI
// on redéfini le tableau pointe_t_listFront() et la numérotation unique dans les fronts stockés
pointe_t_listFront . Change_taille ( a . pointe_t_listFront . Taille ( ) ) ;
int nb_zone = MaX ( 1 , nom_ref_zone_contact . size ( ) ) ;
int inum = 1 ;
for ( int i = 1 ; i < = nbmailMaitre ; i + + )
{ for ( int j = 1 ; j < = nb_zone ; j + + )
{ LaLIST_io < Front > & list_fronta = ( t_listFront ( i ) ( j ) ) ; // pour simplifier
LaLIST_io < Front > : : iterator il , ilfin = list_fronta . end ( ) ;
for ( il = list_fronta . begin ( ) ; il ! = ilfin ; il + + , inum + + )
{ pointe_t_listFront ( inum ) = & ( * il ) ;
( * il ) . ChangeNumUnique ( inum ) ;
} ;
} ;
} ;
# endif
} ;
2021-09-24 08:24:03 +02:00
// DESTRUCTEUR :
LesContacts : : ~ LesContacts ( )
{ } ;
// METHODES PUBLIQUES :
// 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 LesContacts : : Init_contact ( LesMaillages & lesMail
, const LesReferences & lesRef
, LesFonctions_nD * lesFonctionsnD )
{
tempsContact . Mise_en_route_du_comptage ( ) ; // temps cpu
2024-01-30 20:55:48 +01:00
// sauvegarde de la liste des fonctions nD
sauve_lesFonctionsnD = lesFonctionsnD ;
// init éventuel du pilotage par fct nD du niveau de commentaire
LesContacts : : Init_fct_niveau_commentaire ( ) ;
2023-05-03 17:23:49 +02:00
int niveau_commentaire_lescontacts = Permet_affichage ( ) ;
2021-09-24 08:24:03 +02:00
// on met à jour le niveau de commentaire dans les éléments de contact
2023-05-03 17:23:49 +02:00
ElContact : : Mise_a_jour_niveau_commentaire ( ) ;
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
// on sauvegarde un pointeur sur les maillages
lesMaille = & lesMail ;
if ( ParaGlob : : Monde ( ) - > rank ( ) = = 0 )
# endif
2024-03-24 11:43:58 +01:00
if ( niveau_commentaire_lescontacts > 4 )
2021-09-24 08:24:03 +02:00
cout < < " \n -- LesContacts::Init_contact: " ;
Creation_Fct_nD_contact ( ) ; // récupération des fonctions de pilotage éventuelles
// --- récup info maillage
// tescin : a la dimension du nombre de maillage esclave
// comme les maillages esclaves sont les premiers dans le .info,
// tescin(i) correspond aux noeuds des frontières du maillage i
2023-05-03 17:23:49 +02:00
// listFrontiere (i) : toutes les frontières des maillages, (peut-être vide pour certains maillages sans frontières)
2021-09-24 08:24:03 +02:00
// correspond aux frontières du maillage i: dabord pour les esclaves puis les maîtres
// nbEscla : nb de maillage esclave
// ind : pour tous les maillages, la liste des éléments qui contiennent chaque noeud
// (mis à jour lors de la création des frontières)
Tableau < Tableau < Noeud * > * > tescin = lesMail . Tab_noeud_frontiere_esclave ( ) ;
Tableau < LaLIST < Front > * > & listFrontiere = lesMail . ListFrontiere ( ) ;
const Tableau < const Tableau < List_io < Element * > > * > & ind = lesMail . Indice ( ) ;
// dans le cas d'un contact de type 4 on renseigne éventuellement une fonction de pilotage
string nom_fct4 = ParaGlob : : param - > ParaAlgoControleActifs ( ) . Fct_nD_bascul_contact_type_4 ( ) ;
if ( ( ParaGlob : : param - > ParaAlgoControleActifs ( ) . ContactType ( ) = = 4 )
& & ( nom_fct4 ! = " _ " )
)
{ // on va récupérer la fonction
if ( lesFonctionsnD - > Existe ( nom_fct4 ) )
{ Fonction_nD * pt_fonct = lesFonctionsnD - > Trouve ( nom_fct4 ) ;
// on vérifie pour l'instant que c'est bien une fonction de grandeurs globales
if ( pt_fonct - > NbVariable_locale ( ) ! = 0 ) // cas où il n'y a pas que des variables globales
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
{ if ( ParaGlob : : Monde ( ) - > rank ( ) = = 0 )
# endif
2021-09-24 08:24:03 +02:00
{ cout < < " \n *** erreur dans la definition de la fonction nD de pilotage "
< < " du type de contact 4 : " < < nom_fct4
< < " n'utilise pas que des variables globales !! " ;
2023-05-03 17:23:49 +02:00
tempsContact . Arret_du_comptage ( ) ; // fin cpu
2021-09-24 08:24:03 +02:00
Sortie ( 1 ) ;
}
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
}
# endif
2021-09-24 08:24:03 +02:00
else if ( pt_fonct - > NbComposante ( ) > 2 )
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
{ if ( ParaGlob : : Monde ( ) - > rank ( ) = = 0 )
# endif
2021-09-24 08:24:03 +02:00
{ cout < < " \n *** erreur dans la definition de la fonction nD de pilotage "
< < " du type de contact 4 : " < < nom_fct4
< < " ramene plus de 2 composantes !! " ;
2023-05-03 17:23:49 +02:00
tempsContact . Arret_du_comptage ( ) ; // fin cpu
2021-09-24 08:24:03 +02:00
Sortie ( 1 ) ;
}
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
}
# endif
2021-09-24 08:24:03 +02:00
else // sinon ok
{ ElContact : : Init_fct_pilotage_contact4 ( pt_fonct ) ; }
}
else
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
{ if ( ParaGlob : : Monde ( ) - > rank ( ) = = 0 )
# endif
2021-09-24 08:24:03 +02:00
{ cout < < " \n *** erreur dans la definition de la fonction nD de pilotage "
< < " du type de contact 4 , le nom : " < < nom_fct4
< < " ne correspond pas a une fonction nD existante !! " ;
2023-05-03 17:23:49 +02:00
tempsContact . Arret_du_comptage ( ) ; // fin cpu
2021-09-24 08:24:03 +02:00
Sortie ( 1 ) ;
} ;
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
} ;
# endif
2021-09-24 08:24:03 +02:00
} ;
/* // ----pour le débug
//{int nbMaillageTotal = listFrontiere.Taille();
//for (int nbmail=1;nbmail<=nbMaillageTotal;nbmail++)
// {int nbfront = listFrontiere(nbmail)->size();
// cout << "\n maillage " << nbmail << " -------- ";
// LaLIST <Front>::iterator iff,iffin = listFrontiere(nbmail)->end();
// iff=listFrontiere(nbmail)->begin();
//// for (iff=listFrontiere(nbmail)->begin();iff !=iffin;iff++)
// Front& titi = (*iff);
// titi.Affiche(); cout << "\n";
//
// };
//
// Sortie(1);
//};
//// fin débug */
// dans le tableau de listes de frontière on a d'abord les elements frontieres
// esclaves puis les elements maitres
int ntmail = listFrontiere . Taille ( ) ; // nb maxi de maillages
nb_mail_Esclave = lesMail . NbEsclave ( ) ; // def du nombre de maillages esclaves
// les maillages mixtes (ou en autocontact) font partie de la liste des nbEscla
// d'où si par exemple tous les éléments peuvent entrer en auto-contact
// -> nbEscla == ntmail == nbmailautocontact == nbmailMaitre
nbmailMaitre = ntmail - ( nb_mail_Esclave - nbmailautocontact ) ; // def du nombre de maillage maitres
// dans le cas d'auto-contact, on vérifie la cohérence
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
if ( ParaGlob : : Monde ( ) - > rank ( ) = = 0 )
# endif
2021-09-24 08:24:03 +02:00
if ( nbmailautocontact ! = 0 )
{ if ( ( nbmailautocontact < 1 ) | | ( nbmailautocontact > nb_mail_Esclave ) )
// nbmailautocontact doit etre >= 0 et < nb_mail_Esclave
{ cout < < " \n ** incoherence dans le nombre de maillage en auto contact !! "
< < " , le nombre de maillage en auto contact lu : " < < nbmailautocontact
< < " , n \' est pas acceptable, il est soit negatif soit superieur au nombre de maillage esclave ( "
< < nb_mail_Esclave < < " ) "
< < endl ;
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > = 0 )
2021-09-24 08:24:03 +02:00
cout < < " \n LesContacts::Init_contact(... " < < endl ;
tempsContact . Arret_du_comptage ( ) ; // fin cpu
Sortie ( 1 ) ;
} ;
} ;
// on récupère le tableau indice
indice = ind ;
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
if ( ParaGlob : : Monde ( ) - > rank ( ) = = 0 )
# endif
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > 2 )
2021-09-24 08:24:03 +02:00
cout < < " \n >>>> Information : Initialisation du contact: " ;
// dimensionnement du premier niveau des tableaux
tesctotal . Change_taille ( nb_mail_Esclave ) ;
tesN_collant . Change_taille ( nb_mail_Esclave ) ;
t_listFront . Change_taille ( nbmailMaitre ) ;
// --- on s'occupe du deuxième niveau de tesN_encontact
// une map vide par défaut
std : : map < Noeud * , LaLIST < LaLIST < ElContact > : : iterator > > map_vide ;
tesN_encontact . Change_taille ( nb_mail_Esclave , map_vide ) ;
// --- on s'occupe maintenant des niveaux 2 et 3 des tableaux tesctotal et tesN_collant
// on regarde si la zone de contact est restreinte
if ( nom_ref_zone_contact . size ( ) = = 0 )
{ // cas d'un contact non restreint
// cela correspond finalement à une seule zone de contact
// 1-- cas des noeuds esclaves
for ( int ii = 1 ; ii < = nb_mail_Esclave ; ii + + )
{ int taille = tescin ( ii ) - > Taille ( ) ; // nombre de noeuds esclave
// tescin -> tous les noeuds possiblement en esclave donc en contact
tesctotal ( ii ) . Change_taille ( 1 ) ; tesctotal ( ii ) ( 1 ) . Change_taille ( taille ) ;
tesN_collant ( ii ) . Change_taille ( 1 ) ; tesN_collant ( ii ) ( 1 ) . Change_taille ( taille ) ;
for ( int itai = 1 ; itai < = taille ; itai + + )
{ // ici, la seule zone c'est "tout" les noeuds esclaves, du coup le numéro d'ordre
// de stockage c'est le numéro dans tescin(ii), c-a-d le numéro de classement des noeuds esclaves
// pour le maillage ii
tesctotal ( ii ) ( 1 ) ( itai ) = ( * tescin ( ii ) ) ( itai ) ;
tesN_collant ( ii ) ( 1 ) ( itai ) = 0 ; // pas de contact collant car le contact est non restreint
} ;
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
if ( ParaGlob : : Monde ( ) - > rank ( ) = = 0 )
# endif
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > 2 )
2021-09-24 08:24:03 +02:00
cout < < " \n mail. esclave " < < ii < < " : " < < taille < < " noeuds esclaves pour contact " ;
} ;
// 2-- pour les éléments
int ilistfront = 1 ; // compteur pour le tableau t_listFront
// on parcours les elements maitres: à cause d'un auto contact
// éventuelle on peut avoir des maillages esclaves qui jouent le rôle également de
// maillages maitres
for ( int jf = ntmail - nbmailMaitre + 1 ; jf < = ntmail ; jf + + , ilistfront + + )
{ t_listFront ( ilistfront ) . Change_taille ( 1 ) ; // une seule zone de contact
LaLIST_io < Front > & lis_fronta = ( t_listFront ( ilistfront ) ( 1 ) ) ;
LaLIST < Front > : : iterator iMi , iMifin = ( * listFrontiere ( jf ) ) . end ( ) ;
for ( iMi = ( * listFrontiere ( jf ) ) . begin ( ) ; iMi ! = iMifin ; iMi + + )
lis_fronta . push_back ( ( * iMi ) ) ;
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
if ( ParaGlob : : Monde ( ) - > rank ( ) = = 0 )
# endif
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > 2 )
2023-12-15 19:17:23 +01:00
cout < < " \n mail. maitre " < < ilistfront < < " : " < < lis_fronta . size ( )
< < " frontieres pour contact " ;
2021-09-24 08:24:03 +02:00
} ;
}
else
{ // cas d'une zone restreinte de contact
// on va iterer sur les noeuds esclaves pour savoir s'ils appartiennent à la zone de contact potentiel
2023-09-03 10:10:17 +02:00
list < Quatre_string_un_entier > : : iterator il , ilfin = nom_ref_zone_contact . end ( ) ;
2021-09-24 08:24:03 +02:00
int nb_zone = nom_ref_zone_contact . size ( ) ;
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
if ( ParaGlob : : Monde ( ) - > rank ( ) = = 0 )
# endif
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > 2 )
2021-09-24 08:24:03 +02:00
cout < < " \n --> nombre de zone de contact: " < < nb_zone ;
// --- tout d'abord on s'occupe des noeuds esclaves
// on va boucler sur les zones pour être sûr de définir complètement toutes les zones
int izone = 1 ;
for ( il = nom_ref_zone_contact . begin ( ) ; il ! = ilfin ; il + + , izone + + ) // boucle sur les références de zone_contact
{ // recup de la reference correspondant au mot cle
string * nom_mail_noe = NULL ;
string nom_inter ;
if ( ( * il ) . nom1 . length ( ) )
{ nom_inter = ( ( * il ) . nom1 ) ;
nom_mail_noe = & nom_inter ;
}
const Reference & ref = lesRef . Trouve ( ( * il ) . nom2 , nom_mail_noe ) ;
// on continue que si c'est une référence de noeud
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
if ( ParaGlob : : Monde ( ) - > rank ( ) = = 0 )
# endif
2021-09-24 08:24:03 +02:00
if ( ref . Indic ( ) ! = 1 )
{ // ce n'est pas normal -> message d'erreur
cout < < " \n *** erreur la reference de zone de contact n'est pas "
< < " une reference de noeud ! " ;
ref . Affiche ( ) ;
cout < < " \n LesContacts::Init_contact(... " < < endl ;
2023-05-03 17:23:49 +02:00
tempsContact . Arret_du_comptage ( ) ; // fin cpu
2021-09-24 08:24:03 +02:00
Sortie ( 1 ) ;
} ;
// on peut maintenant utiliser de manière sûre une ref NE
const ReferenceNE & refNE = ( ( ReferenceNE & ) ref ) ;
// maintenant on va boucler sur les noeuds esclaves pour trouver
// les noeuds de la ref
bool zone_definie = false ;
for ( int intot = 1 ; intot < = nb_mail_Esclave ; intot + + )
{ // on dimensionne le niveaux 2 des tableaux
tesctotal ( intot ) . Change_taille ( nb_zone ) ;
tesN_collant ( intot ) . Change_taille ( nb_zone ) ;
// et maintenant le niveau 3 c-a-d le troisième niveau
//Les zones définies sont prises telles qu'elle, elles peuvent donc
// définir des noeuds potentiels au contact en dehors de ceux définis
// par la construction automatique des frontières dans lesMaillages
// -> donc ici on ne considère pas tescin (modif: 16 mai 2020)
int nb_noe = refNE . Taille ( ) ; // init
tesctotal ( intot ) ( izone ) . Change_taille ( nb_noe ) ;
tesN_collant ( intot ) ( izone ) . Change_taille ( nb_noe ) ;
// maintenant on va remplir
for ( int no_dans_ref = 1 ; no_dans_ref < = nb_noe ; no_dans_ref + + )
{ int num_noe_ref = refNE . Numero ( no_dans_ref ) ;
tesctotal ( intot ) ( izone ) ( no_dans_ref ) = & ( lesMail . Noeud_LesMaille ( ref . Nbmaille ( ) , num_noe_ref ) ) ;
tesN_collant ( intot ) ( izone ) ( no_dans_ref ) = ( * il ) . n ;
} ; // -- fin de la boucle sur les noeuds de la référence
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
if ( ParaGlob : : Monde ( ) - > rank ( ) = = 0 )
# endif
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > 2 )
2023-12-15 19:17:23 +01:00
cout < < " \n maillage esclave " < < intot < < " : zone de contact: " < < izone
< < " => " < < nb_noe < < " noeuds esclaves pour contact " ;
// arrivée ici, c'est que la zone a été définie
zone_definie = true ;
2021-09-24 08:24:03 +02:00
} ; // -- fin de la boucle sur intot c-a-d les maillages esclave
// message d'erreur si la zone n'a pas été définie
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
if ( ParaGlob : : Monde ( ) - > rank ( ) = = 0 )
# endif
2021-09-24 08:24:03 +02:00
if ( ! zone_definie )
{ cout < < " \n *** erreur dans la construction de la zone de contact " < < izone
< < " on ne trouve pas le maillage esclave correspondant ! " ;
refNE . Affiche ( ) ;
cout < < " \n LesContacts::Init_contact(... " < < endl ;
2023-05-03 17:23:49 +02:00
tempsContact . Arret_du_comptage ( ) ; // fin cpu
2021-09-24 08:24:03 +02:00
Sortie ( 1 ) ;
} ;
} ; //-- fin de la boucle sur les zones de contact
// --- maintenant on s'occupe des frontières des maillages maîtres
//Les zones définies sont prises telles qu'elle, elles peuvent donc
// définir des frontières potentielles au contact en dehors de ceux définis
// par la construction automatique des frontières dans lesMaillages
// -> donc ici on ne considère pas "listFrontiere" (modif: 16 mai 2020)
Tableau < int > zone_frontiere ( nb_zone , 0 ) ; // le nb d'elem dans chaque zone
// on initialise la liste
// on parcours les elements maitres
int ilistfront = 1 ; // compteur pour le tableau t_listFront
//à cause d'un auto contact éventuelle on peut avoir des maillages esclaves qui jouent le rôle également de
// maillages maitres
for ( int jlf = ntmail - nbmailMaitre + 1 ; jlf < = ntmail ; jlf + + , ilistfront + + ) // boucle sur les maillages maitres
{ // on dimensionne le niveaux 2 des tableaux
t_listFront ( ilistfront ) . Change_taille ( nb_zone ) ;
int izone = 1 ; // init compteur de zone
for ( il = nom_ref_zone_contact . begin ( ) ; il ! = ilfin ; il + + , izone + + ) // boucle sur les références de zone_contact
{ // recup de la reference correspondant au mot cle
string * nom_mail_face = NULL ;
if ( ( ( * il ) . nom3 . length ( ) ) )
nom_mail_face = & ( * il ) . nom3 ;
// on regarde si la référence existe
string nom_ref = ( * il ) . nom4 ;
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
if ( ParaGlob : : Monde ( ) - > rank ( ) = = 0 )
# endif
2021-09-24 08:24:03 +02:00
if ( ! lesRef . Existe ( nom_ref , nom_mail_face ) )
{ cout < < " \n *** erreur la reference " < < nom_ref ;
if ( nom_mail_face ! = NULL )
cout < < " du maillage " < < * nom_mail_face ;
cout < < " n'existe pas !! " ;
cout < < " \n LesContacts::Init_contact(... " < < endl ;
2023-05-03 17:23:49 +02:00
tempsContact . Arret_du_comptage ( ) ; // fin cpu
2021-09-24 08:24:03 +02:00
Sortie ( 1 ) ;
} ;
const Reference & ref = lesRef . Trouve ( ( * il ) . nom4 , nom_mail_face ) ;
// on continue si le maillage de la ref est bien celui du maître que l'on consulte actuellement
if ( ref . Nbmaille ( ) = = jlf )
{ // --- on balaie les frontières potentielles
LaLIST_io < Front > & list_fronta = ( t_listFront ( ilistfront ) ( izone ) ) ; // pour simplifier
switch ( ref . Indic ( ) )
{ case 3 : // cas d'une frontière de type surface,
{ const ReferenceAF & refAF = ( ( ReferenceAF & ) ref ) ;
int nb_fr = refAF . Taille ( ) ;
for ( int i_fr = 1 ; i_fr < = nb_fr ; i_fr + + )
{ int num_fr = refAF . NumeroFA ( i_fr ) ; // le numéro de la frontière
int num_ele = refAF . NumeroElem ( i_fr ) ; // le numéro de l'élément associé
int num_mail = refAF . Nbmaille ( ) ;
Element & ele = lesMail . Element_LesMaille ( num_mail , num_ele ) ;
// récupération ou création de la frontière
ElFrontiere * fro = ele . Frontiere_surfacique ( num_fr ) ;
// création et ajout de la frontière
list_fronta . push_back ( Front ( * fro , & ele , num_fr ) ) ;
zone_frontiere ( izone ) + + ;
} ;
break ;
}
case 4 : // cas d'une frontière de type arête
{ const ReferenceAF & refAF = ( ( ReferenceAF & ) ref ) ;
int nb_fr = refAF . Taille ( ) ;
for ( int i_fr = 1 ; i_fr < = nb_fr ; i_fr + + )
{ int num_fr = refAF . NumeroFA ( i_fr ) ; // le numéro de la frontière
int num_ele = refAF . NumeroElem ( i_fr ) ; // le numéro de l'élément associé
int num_mail = refAF . Nbmaille ( ) ;
Element & ele = lesMail . Element_LesMaille ( num_mail , num_ele ) ;
// récupération ou création de la frontière
ElFrontiere * fro = ele . Frontiere_lineique ( num_fr ) ;
// création et ajout de la frontière
list_fronta . push_back ( Front ( * fro , & ele , num_fr ) ) ;
zone_frontiere ( izone ) + + ;
} ;
break ;
}
default :
// ici la frontière peut-être n'importe quoi: point, arête, surface
// on vérifie que ce ne sont pas des ref Indic 5 ou 6 ou plus ou 1 ou 2
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
if ( ParaGlob : : Monde ( ) - > rank ( ) = = 0 )
# endif
2021-09-24 08:24:03 +02:00
{ cout < < " \n *** erreur la reference de zone de frontiere de contact n'est pas "
< < " une reference acceptable ! "
< < " seules les ref d'aretes ou de surface sont possibles " ;
ref . Affiche ( ) ;
cout < < " \n LesContacts::Init_contact(... " < < endl ;
2023-05-03 17:23:49 +02:00
tempsContact . Arret_du_comptage ( ) ; // fin cpu
2021-09-24 08:24:03 +02:00
Sortie ( 1 ) ;
} ;
2023-12-15 19:17:23 +01:00
break ;
2021-09-24 08:24:03 +02:00
} ; // fin du switch sur le type de frontière
} ;
} ; //-- fin de la boucle sur zone de contact
} ; //-- fin de la boucle sur les maillages maîtres
// petit message si nécessaire
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
if ( ParaGlob : : Monde ( ) - > rank ( ) = = 0 )
# endif
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > 2 ) //&& (list_fronta.size() > 0))
2021-09-24 08:24:03 +02:00
{ for ( int i = 1 ; i < = nb_zone ; i + + ) // boucle sur les références de zone_contact
{ cout < < " \n zone de contact: " < < i < < " => "
< < zone_frontiere ( i )
< < " frontieres prises en compte pour le contact " ;
if ( zone_frontiere ( i ) = = 0 )
cout < < " \n *** warning c'est un peu etrange qu'il y ait 0 frontiere, cela veut dire "
< < " que cette zone ne sera pas utilisable !! " ;
} ;
} ;
} ; //-- fin du else : cas d'une zone restreinte de contact
2023-05-03 17:23:49 +02:00
// on définit et on ajoute les fronts des angles morts
ElementAngleMort ( lesMail ) ;
2024-03-24 11:43:58 +01:00
// il faut mettre à jour les mitoyens des Front: c-a-d il faut que les mitoyens
// soient eux-même des fronts de t_listFront
int nb_zone = MaX ( 1 , nom_ref_zone_contact . size ( ) ) ;
for ( int i = 1 ; i < = nbmailMaitre ; i + + )
{ for ( int j = 1 ; j < = nb_zone ; j + + )
{ LaLIST_io < Front > & list_fronta = ( t_listFront ( i ) ( j ) ) ; // pour simplifier
LaLIST < Front > : : iterator iM , iMfin = list_fronta . end ( ) ;
for ( iM = list_fronta . begin ( ) ; iM ! = iMfin ; iM + + ) // boucle sur les frontières enregistrées
{ Front & fronta = ( * iM ) ; // pour simplifier
const Tableau < Front * > * ta = fronta . TabMitoyen ( ) ; // récup des mitoyens
if ( ta ! = NULL ) // cas où il y a des éléments voisins !
{ const Tableau < Front * > & taa = * ta ; // pour simplifier
int ta_taille = ta - > Taille ( ) ;
Tableau < Front * > inter ( ta_taille ) ; // un tableau inter de travail
for ( int i = 1 ; i < = ta_taille ; i + + )
// on récupère l'élément ad hoc
{ Front * froon = Front_de_meme_origine ( taa ( i ) , j ) ;
if ( froon ! = NULL )
{ inter ( i ) = froon ; }
else // sinon c'est un pb pour la suite
{ cout < < " \n *** erreur dans la definition des mitoyens pour l'initialisation des frontieres de contact "
< < " on n'a pas trouve dans la zone de contact une frontiere adequate : arret " ;
Sortie ( 1 ) ;
} ;
} ;
// on peut maintenant remplacer le tableau de mitoyen
fronta . DefMitoyen ( inter ) ;
} ;
} ;
} ;
} ;
2021-09-24 08:24:03 +02:00
// Pour diminuer le temps de recherche, et aussi les messages on va constituer une liste des éléments
// qui contiennent les frontières
liste_elemens_front . clear ( ) ; // init de la liste
2024-03-24 11:43:58 +01:00
# ifdef UTILISATION_MPI
int nb_total_front = 0 ; // permet ensuite de dimensionner le tableau pointe_t_listFront
# endif
2021-09-24 08:24:03 +02:00
for ( int i = 1 ; i < = nbmailMaitre ; i + + )
{ for ( int j = 1 ; j < = nb_zone ; j + + )
{ LaLIST_io < Front > & list_fronta = ( t_listFront ( i ) ( j ) ) ; // pour simplifier
LaLIST < Front > : : iterator iM , iMfin = list_fronta . end ( ) ;
for ( iM = list_fronta . begin ( ) ; iM ! = iMfin ; iM + + ) // boucle sur les frontières enregistrées
2024-03-24 11:43:58 +01:00
{ liste_elemens_front . push_back ( ( * iM ) . PtEI ( ) ) ;
# ifdef UTILISATION_MPI
nb_total_front + + ;
# endif
} ;
2021-09-24 08:24:03 +02:00
} ;
} ;
// on ordonne la liste puis on supprime les doublons
liste_elemens_front . sort ( ) ; // ordonne
liste_elemens_front . unique ( ) ; // supprime les doublons
// --- cas des contacts collants avec suppression des gaps ----
// suppression du gap de contact pour les noeuds "collant avec suppression de gap"
Suppression_gap_pour_noeud_collant ( ) ;
////--- debug
//{ for (int jf=ntmail-nbmailMaitre+1;jf<=ntmail;jf++)
// { LaLIST <Front>::iterator iM,iMfin=(*listFrontiere(jf)).end();
// for (iM = (*listFrontiere(jf)).begin();iM != iMfin; iM++) // boucle sur les fronts maitres
// { ElFrontiere* elemf = (*iM).Eleme(); // pour simplifier
// if (((*iM).Num_frontiere() == 1) && ((*iM).PtEI()->Num_elt()== 3130)
// && ((*iM).PtEI()->Num_maillage() == 4))
// { cout << "\n debug : frontiere 1 de l'element 3130";
// }
// }
// }
//}
////-- fin debug
2024-03-24 11:43:58 +01:00
# ifdef UTILISATION_MPI
// on défini le tableau pointe_t_listFront et on définit le numéro associé unique dans les fronts
pointe_t_listFront . Change_taille ( nb_total_front ) ;
int inum = 1 ;
for ( int i = 1 ; i < = nbmailMaitre ; i + + )
{ for ( int j = 1 ; j < = nb_zone ; j + + )
{ LaLIST_io < Front > & list_fronta = ( t_listFront ( i ) ( j ) ) ; // pour simplifier
LaLIST_io < Front > : : iterator il , ilfin = list_fronta . end ( ) ;
for ( il = list_fronta . begin ( ) ; il ! = ilfin ; il + + , inum + + )
{ pointe_t_listFront ( inum ) = & ( * il ) ;
( * il ) . ChangeNumUnique ( inum ) ;
} ;
} ;
} ;
// //--- debug
// {cout << "\n debug : LesContacts::Init_contact ";
// for (int i=1;i<=nbmailMaitre;i++)
// { for (int j=1;j<=nb_zone;j++)
// { LaLIST_io <Front> & list_fronta = (t_listFront(i)(j)); // pour simplifier
// LaLIST_io <Front>::iterator il,ilfin = list_fronta.end();
// for (il = list_fronta.begin();il != ilfin; il++)
// {if ((*il).NumUnique() == 0)
// cout << "\n debug : LesContacts::Init_contact "
// << " ***** erreur numunique == 0 !!" ;
// // maintenant on s'occupe des mitoyens
// {Front & fronta = (*il); // pour simplifier
// const Tableau <Front*>* ta = fronta.TabMitoyen(); // récup des mitoyens
// if (ta != NULL) // cas où il y a des éléments voisins !
// { const Tableau <Front*>& taa = *ta; // pour simplifier
// int ta_taille = ta->Taille();
// for (int i=1; i <= ta_taille; i++)
// {if (taa(i)->NumUnique() == 0)
// cout << "\n debug : LesContacts::Init_contact "
// << " ***** erreur dans les mitoyens : numunique == 0 !!" ;
// };
// };
// };
//
// };
// };
// };
// }
// //-- fin debug
# endif
2021-09-24 08:24:03 +02:00
tempsContact . Arret_du_comptage ( ) ; // fin cpu
} ;
// verification qu'il n'y a pas de contact avant le premier increment de charge
void LesContacts : : Verification ( )
2023-05-03 17:23:49 +02:00
{
# ifdef UTILISATION_MPI
// cas d'un calcul //, seule le CPU 0 est concernée
if ( ParaGlob : : Monde ( ) - > rank ( ) ! = 0 )
return ;
# endif
// on va iterer sur les noeuds esclaves pour savoir s'ils sont internes
2021-09-24 08:24:03 +02:00
// a un element c-a-d a l'interieur d'un element qui contiend un element
// frontiere
int nb_zone = MaX ( 1 , nom_ref_zone_contact . size ( ) ) ;
2023-05-03 17:23:49 +02:00
int niveau_commentaire_lescontacts = Permet_affichage ( ) ;
if ( niveau_commentaire_lescontacts > 4 )
2021-09-24 08:24:03 +02:00
cout < < " \n -- LesContacts::Verification: " ;
// mise à jour les boites d'encombrement des éléments frontière
{ LaLIST_io < Front > : : iterator iM , iMfin ;
for ( int i = 1 ; i < = nbmailMaitre ; i + + )
for ( int j = 1 ; j < = nb_zone ; j + + )
{ iMfin = ( t_listFront ( i ) ( j ) ) . end ( ) ;
//debug
//cout << "\n les elements frontières: " << t_listFront(jjf) << " ";
// fin debug
for ( iM = ( t_listFront ( i ) ( j ) ) . begin ( ) ; iM ! = iMfin ; iM + + )
( * iM ) . Boite_encombrement_frontiere ( TEMPS_t , 0. ) ; // au début pas de déplacement -> 0.
} ;
} ;
list < Element * > : : iterator ilfele , ilfelefin = liste_elemens_front . end ( ) ;
for ( int intot = 1 ; intot < = nb_mail_Esclave ; intot + + )
for ( int j = 1 ; j < = nb_zone ; j + + )
{ const Tableau < Noeud * > & tesc = tesctotal ( intot ) ( j ) ; // pour simplifier la notation
const Tableau < int > tesN_col = tesN_collant ( intot ) ( j ) ; // pour simplifier
int tesc_taille = tesc . Taille ( ) ;
for ( int inesc = 1 ; inesc < = tesc_taille ; inesc + + )
{ Noeud * noee = tesc ( inesc ) ; // pour simplifier
const Coordonnee & pt_esc = noee - > Coord1 ( ) ; // position du noeud esclave à l'instant t
//debug
//cout << "\n pt_esc= " << pt_esc << " "<< endl ;
// fin debug
int num_mail_noe_esclave = noee - > Num_Mail ( ) ;
// on parcours les elements maitres
for ( ilfele = liste_elemens_front . begin ( ) ; ilfele ! = ilfelefin ; ilfele + + )
{ Element & elem = * ( * ilfele ) ; // l'element qui contiend la frontiere
// dans le cas où l'élément et le noeud appartienne au même maillage, on est
// dans le cas d'un auto-contact. Dans ce cas on ne considère que les éléments
// qui ne contiennent pas le noeud esclave
if ( elem . Num_maillage ( ) = = num_mail_noe_esclave )
{ List_io < Element * > indice_m = ( * indice ( num_mail_noe_esclave ) ) ( noee - > Num_noeud ( ) ) ; // pour simplifier
if ( find ( indice_m . begin ( ) , indice_m . end ( ) , & elem ) ! = indice_m . end ( ) )
break ; // on arrête la boucle si on trouve l'élément parmi ceux contenant le noeud
} ;
// on regarde si le noeud esclave est dans la boite d'encombrement de l'élément
if ( elem . In_boite_emcombrement_elem ( pt_esc ) )
// on teste alors plus précisemment
{ //compteur++;
2023-05-03 17:23:49 +02:00
if ( ( elem . Interne_t ( pt_esc ) = = 1 ) & & ( niveau_commentaire_lescontacts > = 3 ) )
2021-09-24 08:24:03 +02:00
{ cout < < " \n attention, noeud esclave dans elem. "
< < " avant incre. 1 charge " ;
2024-03-24 11:43:58 +01:00
if ( niveau_commentaire_lescontacts > 3 )
2021-09-24 08:24:03 +02:00
cout < < " \n LesContacts::Verification(..) " ;
int num_mail_elem = ( elem . Tab_noeud ( ) ) ( 1 ) - > Num_Mail ( ) ;
cout < < " \n -> noeud " < < tesc ( inesc ) - > Num_noeud ( ) < < " du maillage " < < tesc ( inesc ) - > Num_Mail ( )
< < " dans l'element " < < elem . Num_elt ( ) < < " du maillage " < < num_mail_elem ;
if ( tesN_col ( inesc ) ) cout < < " (contact collant) " ;
//elem.Interne_t(pt_esc); // debug
//cout << endl;
// elem.Affiche();tesc(inesc)->Affiche();
//--- on laisse pour voir continuer Sortie(1);
} ;
} ;
} ; // -- fin de la boucle sur ifele
} ; // -- fin de la boucle sur inesc
} ; //-- fin de la boucle sur les zones
// cout << "\n compteur = " << compteur << endl;
// Sortie(1);
} ;
// definition des elements de contact eventuels
// dep_max : déplacement maxi des noeuds du maillage
// cette méthode est utilisée au début du calcul, ensuite c'est Nouveau()
// qui prend le relais
// ramène true s'il y a effectivement création d'élément de contact
2024-03-24 11:43:58 +01:00
// en parallèle seules les proc i>0 définissent des éléments de contact
// le proc 0 ne fait rien, il récupère le retour et fait le bilan
2021-09-24 08:24:03 +02:00
bool LesContacts : : DefElemCont ( double dep_max )
{
tempsContact . Mise_en_route_du_comptage ( ) ; // def deb compt
bool retour = false ; // init par défaut
2023-05-03 17:23:49 +02:00
int niveau_commentaire_lescontacts = Permet_affichage ( ) ;
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
int proc_en_cours = ParaGlob : : Monde ( ) - > rank ( ) ;
# endif
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > 4 )
2023-12-15 19:17:23 +01:00
{
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
2024-01-30 20:55:48 +01:00
< < " -- LesContacts::Def Elem Cont, initialement " < < listContact . size ( ) < < " elem contact " ;
2023-12-15 19:17:23 +01:00
# else
2024-01-30 20:55:48 +01:00
cout < < " \n -- LesContacts::Def Elem Cont, initialement " < < listContact . size ( ) < < " elem contact " ;
2023-12-15 19:17:23 +01:00
# endif
} ;
2021-09-24 08:24:03 +02:00
// on initialise les listes transitoires
listContact_nouveau_tatdt . clear ( ) ;
listContact_efface_tatdt . clear ( ) ;
// on met à jour le déplacement maxi toléré pour la classe ElContact
double coef_mult_dep_max = 2. ; // comme un noeud peut se déplacer de dep_max et que l'on
double dep_max_pratique = coef_mult_dep_max * dep_max ;
// peut avoir la cible "et" le noeud qui se déplace de dep_max, on doit considérer 2*dep_max
// on met à jour le déplacement maxi pour la class
ElContact : : Change_dep_max ( dep_max_pratique ) ;
int nb_zone = MaX ( 1 , nom_ref_zone_contact . size ( ) ) ;
double dist_max = Dabs ( ParaGlob : : param - > ParaAlgoControleActifs ( ) . DistanceMaxiAuPtProjete ( ) ) ;
2024-03-24 11:43:58 +01:00
# ifdef UTILISATION_MPI
if ( proc_en_cours ! = 0 ) // seules les proc i>0 définissent des éléments de contact
{
# endif
2021-09-24 08:24:03 +02:00
// on va iterer sur les noeuds esclaves pour savoir s'ils ont une trajectoire
// qui cree un contact avec les elements maitres, ou l'inverse, c-a-d s'ils sont
// dans de la matiere
LaLIST_io < Front > : : iterator iM , iMfin ; // des itérator de travail
// la mise à jour des boites d'encombrement n'est pas nécessaire car elle est faite dans l'algo avant le contact
// *** si car ici on tient compte du déplacement et pas dans le prog principale
// *** à voir si on ne peut pas le faire dans le prog princ, mais il faut faire un cas mini
// car pour les points on se retrouve avec une boite de dim nulle !!
// mise à jour les boites d'encombrement des éléments frontière
2023-05-03 17:23:49 +02:00
2021-09-24 08:24:03 +02:00
{ LaLIST_io < Front > : : iterator iM , iMfin ;
for ( int i = 1 ; i < = nbmailMaitre ; i + + )
for ( int j = 1 ; j < = nb_zone ; j + + )
{ iMfin = ( t_listFront ( i ) ( j ) ) . end ( ) ;
for ( iM = ( t_listFront ( i ) ( j ) ) . begin ( ) ; iM ! = iMfin ; iM + + )
( * iM ) . Boite_encombrement_frontiere ( TEMPS_t , dep_max_pratique ) ; // au début pas de déplacement -> 0.
} ;
} ;
LaLIST < ElContact > : : iterator icont_inter ; // sert pour la recherche de doublon
// list <TroisEntiers>::iterator inumtesN; // " " "
for ( int intot = 1 ; intot < = nb_mail_Esclave ; intot + + ) // boucle sur les maillages esclaves
2023-05-03 17:23:49 +02:00
for ( int j_zone = 1 ; j_zone < = nb_zone ; j_zone + + )
{ const Tableau < Noeud * > & tesc = tesctotal ( intot ) ( j_zone ) ; // pour simplifier la notation:
const Tableau < int > tesN_col = tesN_collant ( intot ) ( j_zone ) ; // pour simplifier
2021-09-24 08:24:03 +02:00
int tesc_taille = tesc . Taille ( ) ; // tab des noeuds esclaves à considérer
for ( int inesc = 1 ; inesc < = tesc_taille ; inesc + + ) // boucle sur les noeuds esclaves
{ Noeud * noee = tesc ( inesc ) ; // pour simplifier
int num_mail_noe_esclave = noee - > Num_Mail ( ) ;
int n_noee = noee - > Num_noeud ( ) ;
{ int nb_contact = 0 ; //au début pas de contact pour le noeud (pour gérer les doublons en contact)
const Coordonnee pt_esc = noee - > Coord2 ( ) ; // position du noeud esclave
for ( int jlf = 1 ; jlf < = nbmailMaitre ; jlf + + ) // boucle sur les maillages maitres
2023-05-03 17:23:49 +02:00
{ LaLIST_io < Front > & t_listFront_jlf_j = t_listFront ( jlf ) ( j_zone ) ;
2021-09-24 08:24:03 +02:00
iMfin = t_listFront_jlf_j . end ( ) ;
for ( iM = t_listFront_jlf_j . begin ( ) ; iM ! = iMfin ; iM + + ) // boucle sur les front
{
2023-12-15 19:17:23 +01:00
bool a_considerer = true ; // init par défaut
# ifdef UTILISATION_MPI
// dans le cas // on ne continue que si la frontière est relative à un élément associé au cpu
{ Element & elem = * ( ( * iM ) . PtEI ( ) ) ; // l'element qui contiend la frontiere
// on ne continue que si l'élément est concerné
if ( ! ( ParaGlob : : param - > Element_concerner ( elem . Num_maillage ( ) , elem . Num_elt_const ( ) ) ) )
a_considerer = false ;
} ;
# endif
2021-09-24 08:24:03 +02:00
std : : map < Noeud * , LaLIST < LaLIST < ElContact > : : iterator > > & tesN_encontact_ii = tesN_encontact ( num_mail_noe_esclave ) ;
// on regarde si la liste existe, si oui on peut tester les membres sinon, on ne fait rien
// car autrement on crée automatiquement une liste avec un élément vide
std : : map < Noeud * , LaLIST < LaLIST < ElContact > : : iterator > > : : iterator it_liste ;
if ( tesN_encontact_ii . find ( noee ) ! = tesN_encontact_ii . end ( ) )
{ LaLIST < LaLIST < ElContact > : : iterator > & list_tesN = tesN_encontact_ii [ noee ] ;
LaLIST < LaLIST < ElContact > : : iterator > : : iterator pl , plfin = list_tesN . end ( ) ;
nb_contact = list_tesN . size ( ) ;
for ( pl = list_tesN . begin ( ) ; pl ! = plfin ; pl + + )
{ ElContact & elc = ( * ( * pl ) ) ;
if ( elc . Elfront ( ) - > MemeOrigine ( * iM ) )
{ a_considerer = false ; break ; }
} ;
} ;
// donc on ne continue que si la face n'est pas déjà en contact avec le noeud
if ( a_considerer )
{ // on regarde si le noeud esclave est dans la boite d'encombrement de l'élément frontière
Element & elem = * ( ( * iM ) . PtEI ( ) ) ; // l'element qui contiend la frontiere
// dans le cas où l'élément et le noeud appartienne au même maillage, on est
// dans le cas d'un auto-contact. Dans ce cas on ne considère que les éléments
// qui ne contiennent pas le noeud esclave
if ( elem . Num_maillage ( ) = = num_mail_noe_esclave )
{ List_io < Element * > indice_m = ( * indice ( num_mail_noe_esclave ) ) ( n_noee ) ; // pour simplifier
if ( find ( indice_m . begin ( ) , indice_m . end ( ) , & elem ) ! = indice_m . end ( ) )
break ; // on arrête la boucle si on trouve l'élément parmi ceux contenant le noeud
} ;
// ---- finalement on ne va pas considérer le point frontière comme particulier ---
// du coup, il ne sera jamais pris en compte et on
// bool dans_la_boite=false; // init
// // on prend en compte le cas particulier de frontière point
// if ((*iM)->Eleme()->Type_geom_front() == POINT_G)
// // on utilise la boite d'encombrement de l'élément car pour l'instant
// // je ne vois pas de solution plus pertinente
// // bool In_boite_emcombrement_elem(const Coordonnee& M,double depass = 0.)
// { dans_la_boite = elem.In_boite_emcombrement_elem(pt_esc);}
// else // sinon c'est le cas normal, on test la boite de la frontière
// { dans_la_boite = (*iM)->In_boite_emcombrement_front(pt_esc);};
// if (dans_la_boite)
bool plus_en_avant = false ; // init
if ( tesN_col ( inesc ) ) // si collant: on projete systématiquement avec de grandes bornes
{ if ( ( * iM ) . In_boite_emcombrement_front ( pt_esc , dist_max ) )
plus_en_avant = true ;
}
else if ( ( * iM ) . In_boite_emcombrement_front ( pt_esc ) ) // cas non collant
{ plus_en_avant = true ; } ;
if ( plus_en_avant )
// on teste alors plus précisemment
{ // constitution d'un element de contact intermediaire
ElContact elcont ( & ( * iM ) , tesc ( inesc ) , fct_nD_contact , tesN_col ( inesc ) ) ;
2023-05-03 17:23:49 +02:00
elcont . Num_zone_contact ( ) = j_zone ; // affectation du numéro de zone
elcont . Change_lissage_normale ( lissage_de_la_normale ( j_zone ) ) ; // affectation du lissage
2024-03-24 11:43:58 +01:00
# ifdef UTILISATION_MPI
// on attribue au front de l'élément de contact, le numéro unique utilisable pour le tableau pointe_t_listFront
elcont . Elfront ( ) - > ChangeNumUnique ( ( * iM ) . NumUnique ( ) ) ;
# endif
2021-09-24 08:24:03 +02:00
// calcul du contact, et translation (éventuelle) du noeud sur la surface si le contact existe
bool init_inter = true ; // on est en phase d'initialisation
2023-05-03 17:23:49 +02:00
// //--- debug
// cout << "\n LesContacts::DefElemCont *3* "<< flush;
// elcont.Affiche(1);
// //--- fin debug
2021-09-24 08:24:03 +02:00
bool ret = elcont . Contact ( init_inter ) ;
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > 5 )
2021-09-24 08:24:03 +02:00
{ int num_mail_elem = ( elem . Tab_noeud ( ) ) ( 1 ) - > Num_Mail ( ) ;
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
# endif
2024-03-24 11:43:58 +01:00
< < " recherche du contact entre noeud " < < elcont . Esclave ( ) - > Num_noeud ( )
2021-09-24 08:24:03 +02:00
< < " du maillage " < < elcont . Esclave ( ) - > Num_Mail ( )
< < " et frontiere " < < ( * iM ) . Num_frontiere ( )
< < " de l'element " < < elem . Num_elt ( ) < < " du maillage "
< < num_mail_elem ;
if ( ret ) cout < < " \n --> contact trouve " ;
else cout < < " \n --> pas de contact " ;
2023-05-03 17:23:49 +02:00
if ( ( niveau_commentaire_lescontacts > 6 )
2021-09-24 08:24:03 +02:00
& & ( ( * iM ) . In_boite_emcombrement_front ( pt_esc ) )
)
{ Noeud * noeud = tesc ( inesc ) ;
// --- sortie d'info pour vérifier l'appartenance à la boite ou non
cout < < " , coordonnee noeud esclave : " ; noeud - > Coord2 ( ) . Affiche ( ) ;
cout < < " \n boite d'encombrement de l'element qui contient la frontiere: \n mini -> " ;
elem . RecupBoite_encombre_element ( ) . Premier ( ) . Affiche ( ) ;
cout < < " maxi -> " ;
elem . RecupBoite_encombre_element ( ) . Second ( ) . Affiche ( ) ;
cout < < " \n boite d'encombrement de la frontiere: \n mini -> " ;
( * iM ) . Encom_mini_FR ( ) . Affiche ( ) ;
cout < < " maxi -> " ;
( * iM ) . Encom_maxi_FR ( ) . Affiche ( ) ;
} ;
cout < < endl ;
} ;
if ( ret )
//sauvegarde éventuelle de l'element contact
{ // on regarde s'il n'y a pas un autre élément de contact avec le même noeud
if ( nb_contact = = 0 )
2023-05-03 17:23:49 +02:00
{ // s'il existe déjà ce n'est pas normal
# ifdef MISE_AU_POINT
{ if ( Element_contact_deja_present ( elcont ) ! = NULL )
2023-12-15 19:17:23 +01:00
{
# ifdef UTILISATION_MPI
cout < < " \n *** erreur: proc " < < proc_en_cours ;
# endif
cout < < " \n *** Erreur : l'element de contact existe déjà, ce n'est pas normal "
2023-05-03 17:23:49 +02:00
< < ( elcont ) . Esclave ( ) - > Num_noeud ( )
< < " du maillage " < < ( elcont ) . Esclave ( ) - > Num_Mail ( )
< < " la suite n'est pas possible "
< < " LesContacts::DefElemCont(.. \n " ;
tempsContact . Arret_du_comptage ( ) ; // fin cpu
Sortie ( 1 ) ;
} ;
}
# endif
// c'est le premier élément en contact, on l'enregistre
2021-09-24 08:24:03 +02:00
listContact . push_front ( elcont ) ;
retour = true ;
listContact_nouveau_tatdt . push_front ( listContact . begin ( ) ) ; // mémorisation
// et ajout dans la liste associé au noeud esclave
tesN_encontact_ii [ noee ] . push_front ( listContact . begin ( ) ) ;
nb_contact + + ;
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > 3 )
2021-09-24 08:24:03 +02:00
{ int num_mail_elem = ( elem . Tab_noeud ( ) ) ( 1 ) - > Num_Mail ( ) ;
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
# endif
2024-03-24 11:43:58 +01:00
< < " contact entre noeud " ;
2021-09-24 08:24:03 +02:00
if ( tesN_col ( inesc ) ) cout < < " collant " ;
cout < < elcont . Esclave ( ) - > Num_noeud ( )
< < " du maillage " < < elcont . Esclave ( ) - > Num_Mail ( )
< < " et frontiere " < < ( * iM ) . Num_frontiere ( )
< < " de l'element " < < elem . Num_elt ( ) < < " du maillage "
2023-05-03 17:23:49 +02:00
< < num_mail_elem < < " (zone " < < j_zone < < " ) " < < flush ;
if ( niveau_commentaire_lescontacts > 6 )
2021-09-24 08:24:03 +02:00
{ cout < < " \n pt intersection: " < < elcont . Point_intersection ( ) ;
elcont . Elfront ( ) - > Affiche ( ) ;
cout < < flush ;
} ;
} ;
}
else
{ // on a déjà un élément en contact
// on peut alors utiliser une ref sur l'élément de la map, sans craindre d'en créer
// un nouveau
LaLIST < LaLIST < ElContact > : : iterator > : : iterator pl =
tesN_encontact_ii [ noee ] . begin ( ) ; // le pointeur du premier de la liste
ElContact & elc = ( * ( * pl ) ) ;
// on va retenir l'élément dont le point de contact est le plus proche du point à t
//***: on retient ici le plus proche, mais dans nouveau on gardera tous les contacts
// ici il s'agit essentiellement de l'initialisation (à voir ensuite si c'est tenable !)
// --> permet aussi de coller sur un élément bien déterminé, s'il s'agit d'un collage
if ( ( elcont . Point_intersection ( ) - pt_esc ) . Norme ( )
< ( elc . Point_intersection ( ) - pt_esc ) . Norme ( ) )
{ // cas où le nouvel élément en contact est plus proche que celui enregistré
listContact_efface_tatdt . push_front ( elc ) ; // mémorise
// il faut utiliser erase et non remove car il n'y a pas d'opérateur =
// pour les éléments de contact
listContact . erase ( * pl ) ; // on efface l'ancien
listContact_nouveau_tatdt . remove ( * pl ) ;
// il faut supprimer dans tesN_encontact
tesN_encontact_ii [ noee ] . erase ( pl ) ;
2023-05-03 17:23:49 +02:00
// puis on met le nouveau s'il n'existe pas déjà
ElContact * test_existance = Element_contact_deja_present ( elcont ) ;
if ( test_existance = = NULL )
// s'il n'existe pas, on le rajoute
{ listContact . push_front ( elcont ) ;
retour = true ;
listContact_nouveau_tatdt . push_front ( listContact . begin ( ) ) ;
tesN_encontact_ii [ noee ] . push_front ( listContact . begin ( ) ) ;
// on n'intervient pas sur tesN_encontact, car ça ne change pas
2024-03-24 11:43:58 +01:00
if ( niveau_commentaire_lescontacts > 3 )
2023-05-03 17:23:49 +02:00
{ int num_mail_elem = ( elem . Tab_noeud ( ) ) ( 1 ) - > Num_Mail ( ) ;
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
# endif
< < " --- changement d'element en contact --- " ;
2024-03-24 11:43:58 +01:00
cout < < " contact entre noeud " ;
2023-05-03 17:23:49 +02:00
if ( tesN_col ( inesc ) ) cout < < " collant " ;
cout < < elcont . Esclave ( ) - > Num_noeud ( )
< < " du maillage " < < elcont . Esclave ( ) - > Num_Mail ( )
< < " et frontiere " < < ( * iM ) . Num_frontiere ( )
< < " de l'element " < < elem . Num_elt ( ) < < " du maillage "
< < num_mail_elem < < " (zone " < < j_zone < < " ) " < < flush ;
} ;
}
else if ( ! test_existance - > Actif ( ) )
// s'il existe et est inactif on le rend actif (pour remplacer celui qui devrait être créé)
{ test_existance - > Met_actif ( ) ;
} ;
2021-09-24 08:24:03 +02:00
} ;
// sinon le nouvel élément est plus loin que l'ancien, on en tient pas compte
} ;
} ;
// sinon il n'y a pas de contact
} ; //-- fin du test sur la boite_encombrement
} ; // -- fin du test : if (a_considerer)
} ; // -- fin de la boucle sur iM
} ; //-- fin de la boucle sur jlf
} ; //-- fin du test if (!tesN_encontact(intot)(n_noee))
} ; //-- fin de la boucle sur inesc
} ; //-- fin de la boucle sur les zones
2024-03-24 11:43:58 +01:00
# ifdef UTILISATION_MPI
} ; // fin du cas des proc i > 0
# endif
2021-09-24 08:24:03 +02:00
// retour
2024-03-24 11:43:58 +01:00
# ifdef UTILISATION_MPI
if ( proc_en_cours ! = 0 )
{
if ( niveau_commentaire_lescontacts > 4 ) // ==> LesContacts::
# else
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > 2 ) // ==> LesContacts::
2024-03-24 11:43:58 +01:00
# endif
2023-12-15 19:17:23 +01:00
{
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
# endif
< < " apres Def Elem Cont: " < < listContact . size ( ) < < " elem contact " ;
2021-09-24 08:24:03 +02:00
if ( listContact_nouveau_tatdt . size ( ) )
cout < < " , " < < listContact_nouveau_tatdt . size ( ) < < " nouveau(x) " ;
if ( listContact_efface_tatdt . size ( ) )
cout < < " , " < < listContact_efface_tatdt . size ( ) < < " effacement(s) " ;
cout < < flush ;
} ;
2024-03-24 11:43:58 +01:00
# ifdef UTILISATION_MPI
} ;
if ( proc_en_cours ! = 0 ) // on transmet à proc 0
{ temps_transfert_court . Mise_en_route_du_comptage ( ) ; // comptage cpu
// pour cela on va utiliser un conteneur intermédiaire
QuatreEntiers inter_entiers ( retour , listContact . size ( ) , listContact_nouveau_tatdt . size ( ) , listContact_efface_tatdt . size ( ) ) ;
// on transmet les infos au proc 0
mpi : : request reqs1 = ParaGlob : : Monde ( ) - > isend ( 0 , 61 , inter_entiers ) ;
// on attend pas
temps_transfert_court . Arret_du_comptage ( ) ; // fin comptage cpu
}
else // cas du cpu 0
{ // l'objectif ici est de récupérer les infos
tempsContact . Arret_du_comptage ( ) ; // fin cpu
int nb_contact = 0 ; int nb_new_contact = 0 ; int nb_efface_contact = 0 ; // que l'on va cumuler
int nb_proc_terminer = 0 ; // permettra de terminer
while ( nb_proc_terminer < ( ParaGlob : : Monde ( ) - > size ( ) - 1 ) )
{ // on récupère un résultat de cpu i
temps_transfert_court . Mise_en_route_du_comptage ( ) ; // comptage cpu
QuatreEntiers inter_entiers ;
mpi : : request reqs1 = ParaGlob : : Monde ( ) - > irecv ( mpi : : any_source , 61 , inter_entiers ) ;
reqs1 . wait ( ) ; // on attend que le conteneur soit rempli
// on cumule
nb_contact + = inter_entiers . deux ;
nb_new_contact + = inter_entiers . trois ;
nb_efface_contact + = inter_entiers . quatre ;
if ( inter_entiers . un ) // si un seul des retour s est bon on passe à true
retour = true ;
nb_proc_terminer + + ; // on prend en compte que l'on a récupéré un conteneur
} ;
if ( niveau_commentaire_lescontacts > 2 ) // ==> LesContacts::
{ cout < < " \n apres Def Elem Cont: " < < nb_contact < < " elem contact " ;
if ( nb_new_contact )
cout < < " , " < < nb_new_contact < < " nouveau(x) " ;
if ( nb_efface_contact )
cout < < " , " < < nb_efface_contact < < " effacement(s) " ;
cout < < flush ;
} ;
} ;
// il faut que tous les proc aient le retour global, car le retour sert dans l'algo général
broadcast ( * ParaGlob : : Monde ( ) , retour , 0 ) ;
# endif
2021-09-24 08:24:03 +02:00
tempsContact . Arret_du_comptage ( ) ; // fin cpu
return retour ;
} ;
// 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
bool LesContacts : : Nouveau ( double dep_max )
{
tempsContact . Mise_en_route_du_comptage ( ) ; // def deb compt
2023-05-03 17:23:49 +02:00
int niveau_commentaire_lescontacts = Permet_affichage ( ) ;
2024-03-24 11:43:58 +01:00
////--- debug
//cout << "\n debug LesContacts::Nouveau "<< " niveau_commentaire_lescontacts = "<< niveau_commentaire_lescontacts<< flush;
////--- fin debug
// list <TypeQuelconque> li_pour_noeuds; // pour une sortie spécifique noeud
// Grandeur_scalaire_entier grand_courant_entier(0); // par défaut pour la création des conteneurs quelconques
// li_pour_noeuds.push_front(TypeQuelconque(NUM_NOEUD,X1,grand_courant_entier));
// Grandeur_scalaire_entier& gr_pour_noeud
// = *((Grandeur_scalaire_entier*) (*li_pour_noeuds.begin()).Grandeur_pointee());
// list <TypeQuelconque> li_pour_elcont; // pour une sortie spécifique élément finis
// li_pour_elcont.push_front(TypeQuelconque(NUM_ELEMENT,EPS11,grand_courant_entier));
2024-01-30 20:55:48 +01:00
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
int proc_en_cours = ParaGlob : : Monde ( ) - > rank ( ) ;
# endif
2021-09-24 08:24:03 +02:00
int nb_zone = MaX ( 1 , nom_ref_zone_contact . size ( ) ) ;
2024-03-24 11:43:58 +01:00
bool retour = false ; // init du retour
2021-09-24 08:24:03 +02:00
// on sauvegarde la liste au départ
int taille_list_contact_nouveau_au_debut = listContact_nouveau_tatdt . size ( ) ;
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > 3 )
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
# endif
2024-01-30 20:55:48 +01:00
< < " -- LesContacts::Nouveau: temps= " < < ParaGlob : : Variables_de_temps ( ) . TempsCourant ( ) ;
2024-03-24 11:43:58 +01:00
# ifdef UTILISATION_MPI
if ( proc_en_cours ! = 0 ) // seules les proc i>0 définissent des éléments de contact
{
# endif
2021-09-24 08:24:03 +02:00
// on montre les noeuds actuellement en contact
2024-01-30 20:55:48 +01:00
if ( Permet_affichage ( ) > 4 )
2023-12-15 19:17:23 +01:00
{
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
# endif
2024-01-30 20:55:48 +01:00
< < " >> bilan des noeud(s) actuellement en contact: " ;
int nb_noe_en_contact = 0 ;
2021-09-24 08:24:03 +02:00
for ( int intot = 1 ; intot < = nb_mail_Esclave ; intot + + ) // boucle sur les maillages esclaves
for ( int j = 1 ; j < = nb_zone ; j + + )
{ const Tableau < Noeud * > & tesc = tesctotal ( intot ) ( j ) ; // pout simplifier la notation
const Tableau < int > tesN_col = tesN_collant ( intot ) ( j ) ; // pour simplifier
int tesc_taille = tesc . Taille ( ) ;
for ( int inesc = 1 ; inesc < = tesc_taille ; inesc + + ) // boucle sur les noeuds esclaves
2024-01-30 20:55:48 +01:00
{ Noeud * no = tesc ( inesc ) ;
int n_noee = no - > Num_noeud ( ) ;
2024-03-24 11:43:58 +01:00
* ( gr_pour_noeud - > ConteneurEntier ( ) ) = n_noee ; // pour l'affichage
* ( gr_pour_elem - > ConteneurEntier ( ) ) = 0 ; //pas d'élément ici
if ( Permet_affichage ( & li_pour_noeuds_element ) > 5 )
2024-01-30 20:55:48 +01:00
{
2021-09-24 08:24:03 +02:00
int num_mail_noe_esclave = no - > Num_Mail ( ) ;
// if (no->Num_noeud()==495)
2024-01-30 20:55:48 +01:00
cout < < " \n noeud " < < no - > Num_noeud ( ) < < " du maillage " < < no - > Num_Mail ( ) ;
2021-09-24 08:24:03 +02:00
cout < < " coord2= " ; no - > Coord2 ( ) . Affiche_1 ( cout ) ;
// #ifdef MISE_AU_POINT
// if (tesN_encontact(num_mail_noe_esclave).find(no)
// == tesN_encontact(num_mail_noe_esclave).end() )
// { cout << "\n*** Erreur : on ne trouve pas la liste d'element en contact avec le noeud esclave "
// << n_noee << " du maillage " << num_mail_noe_esclave
// << " la suite n'est pas possible "
// << " LesContacts::Nouveau(.. \n";
// tempsContact.Arret_du_comptage(); // fin cpu
// Sortie(1);
// };
// #endif
std : : map < Noeud * , LaLIST < LaLIST < ElContact > : : iterator > > & tesN_encontact_ii = tesN_encontact ( num_mail_noe_esclave ) ;
// on regarde si la liste existe, si oui on peut tester les membres sinon, on ne fait rien
// car autrement on crée automatiquement une liste avec un élément vide
std : : map < Noeud * , LaLIST < LaLIST < ElContact > : : iterator > > : : iterator it_liste ;
if ( tesN_encontact_ii . find ( no ) ! = tesN_encontact_ii . end ( ) )
2023-12-15 19:17:23 +01:00
{ //LaLIST < LaLIST<ElContact>::iterator > & list_tesN = tesN_encontact_ii[no];
2023-05-03 17:23:49 +02:00
// LaLIST < LaLIST<ElContact>::iterator >::iterator pl,plfin=list_tesN.end();
2024-01-30 20:55:48 +01:00
cout < < " \n --> noeud actuellement en contact " ;
nb_noe_en_contact + + ;
2021-09-24 08:24:03 +02:00
if ( tesN_collant ( num_mail_noe_esclave ) ( j ) ( inesc ) ) cout < < " collant " ;
}
2024-01-30 20:55:48 +01:00
else { cout < < " \n --> noeud actuellement pas en contact " ; } ;
2021-09-24 08:24:03 +02:00
cout < < flush ;
} ;
} ;
} ;
2024-01-30 20:55:48 +01:00
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
# endif
< < " ->> bilan : " < < nb_noe_en_contact < < " noeud(s) actuellement en contact: " ;
2021-09-24 08:24:03 +02:00
} ;
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > 4 )
// on va lister les éléments de contact
2023-12-15 19:17:23 +01:00
{
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
# endif
2024-01-30 20:55:48 +01:00
< < " >> liste des Elcontact au debut de LesContacts::Nouveau: (fct du niveau de commentaire des elcontact): " ;
2023-05-03 17:23:49 +02:00
LaLIST < ElContact > : : iterator ipp , ippfin = listContact . end ( ) ;
for ( ipp = listContact . begin ( ) ; ipp ! = ippfin ; ipp + + )
{ ( * ipp ) . Affiche ( 2 ) ; } ;
2024-01-30 20:55:48 +01:00
cout < < " fin liste " ;
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
# endif
< < " ->> bilan : " < < listContact . size ( ) < < " element(s) de contact: " ;
2023-12-15 19:17:23 +01:00
} ;
2023-05-03 17:23:49 +02:00
2021-09-24 08:24:03 +02:00
// on met à jour les boites des éléments qui contiennent les frontières
2023-12-15 19:17:23 +01:00
// ?? on pourrait peut-être restreindre aux seuls éléments de frontières du cpu i , à voir où est utilisée la méthode ??
2021-09-24 08:24:03 +02:00
Mise_a_jour_boite_encombrement_element_contenant_front ( ) ;
// on met à jour le déplacement maxi toléré pour la classe ElContact
double coef_mult_dep_max = 3. ; // comme un noeud peut se déplacer de dep_max et que l'on
double dep_max_pratique = coef_mult_dep_max * dep_max ;
// peut avoir la cible "et" le noeud qui se déplace de dep_max, on doit considérer 2*dep_max
// pour être sûr, on considère 3 fois
ElContact : : Change_dep_max ( dep_max_pratique ) ;
// --- 1) on va tout d'abord parcourir les éléments inactifs et regarder s'ils sont en contact
// si oui on les valide, sinon on les supprimes. Il faut le faire avant de prospecter car
// ces éléments inactifs ne vont pas être pris en compte car tesN_encontact(num_mail_noe_esclave)(inesc) = 0
2023-12-15 19:17:23 +01:00
// mais ils pourraient redevenir actifs, dans ce cas on aurait un noeud avec deux contacts
// dans le cas //, on considère que les contacts déjà calculés sont a considérer avec le cpu en cours
// car les tests d'appartenance on déjà été effectué au moment de la création
2021-09-24 08:24:03 +02:00
{ // ++ encapsulage
LaLIST < ElContact > : : iterator iE ;
// on met .end(), car cette borne peut changer au gré des suppression
for ( iE = listContact . begin ( ) ; iE ! = listContact . end ( ) ; iE + + )
if ( ! ( ( * iE ) . Actif ( ) ) // on intervient si le contact est déclaré inactif
& & ! ( ( * iE ) . Collant ( ) ) // et si ce n'est pas collant: si collant, on ne change rien
)
{ LaLIST < ElContact > : : iterator iiE = iE ;
if ( ( * iE ) . Contact ( ) )
{ // on valide si le contact est ok
( * iE ) . Met_actif ( ) ;
2024-03-24 11:43:58 +01:00
* ( gr_pour_noeud - > ConteneurEntier ( ) ) = ( * iE ) . Esclave ( ) - > Num_noeud ( ) ;
* ( gr_pour_elem - > ConteneurEntier ( ) ) = ( * iE ) . Elfront ( ) - > PtEI ( ) - > Num_elt ( ) ;
if ( Permet_affichage ( & li_pour_noeuds_element ) > 3 )
2024-01-30 20:55:48 +01:00
{ cout < < " \n reactivation (dans LesContacts::Nouveau) contact: " ;
2023-05-03 17:23:49 +02:00
( * iiE ) . Affiche ( 1 ) ; cout < < endl ;
2021-09-24 08:24:03 +02:00
} ;
}
else
{ // sinon on supprime car il n'y a pas de contact
iE - - ; // pointe sur le precedent element
2023-12-15 19:17:23 +01:00
Noeud * noe_esclave = ( * iiE ) . Esclave ( ) ;
int num_mail_esclave = noe_esclave - > Num_Mail ( ) ;
int num_noeud = noe_esclave - > Num_noeud ( ) ;
2024-03-24 11:43:58 +01:00
* ( gr_pour_noeud - > ConteneurEntier ( ) ) = num_noeud ;
* ( gr_pour_elem - > ConteneurEntier ( ) ) = ( * iE ) . Elfront ( ) - > PtEI ( ) - > Num_elt ( ) ;
if ( Permet_affichage ( & li_pour_noeuds_element ) > 3 )
2024-01-30 20:55:48 +01:00
{ cout < < " \n effacement contact (dans LesContacts::Nouveau): " ;
2023-05-03 17:23:49 +02:00
( * iiE ) . Affiche ( 1 ) ; cout < < endl ;
2021-09-24 08:24:03 +02:00
} ;
listContact_efface_tatdt . push_front ( * iiE ) ; // mémorise
# ifdef MISE_AU_POINT
2023-12-15 19:17:23 +01:00
if ( tesN_encontact ( num_mail_esclave ) . find ( noe_esclave )
= = tesN_encontact ( num_mail_esclave ) . end ( ) )
2021-09-24 08:24:03 +02:00
{ cout < < " \n *** Erreur : on ne trouve pas la liste d'element en contact avec le noeud esclave "
2023-12-15 19:17:23 +01:00
< < num_noeud < < " du maillage " < < num_mail_esclave
< < " la suite n'est pas possible " < < " LesContacts::Nouveau(.. \n " ;
2021-09-24 08:24:03 +02:00
tempsContact . Arret_du_comptage ( ) ; // fin cpu
Sortie ( 1 ) ;
} ;
# endif
LaLIST < LaLIST < ElContact > : : iterator > & list_tesN
2023-12-15 19:17:23 +01:00
= tesN_encontact ( num_mail_esclave ) [ noe_esclave ] ;
2021-09-24 08:24:03 +02:00
list_tesN . remove ( iiE ) ;
listContact . erase ( iiE ) ; // efface l'element
} ;
} ;
} ; // ++ fin encapsulage
// --fin 1)
// on va iterer sur les noeuds esclaves pour savoir s'ils ont une trajectoire
// qui cree un contact avec les elements maitres, ou l'inverse, c-a-d s'ils sont
// dans de la matiere
2024-03-24 11:43:58 +01:00
retour = false ; // init du retour
2021-09-24 08:24:03 +02:00
LaLIST_io < Front > : : iterator iM , iMfin ;
LaLIST < ElContact > : : iterator icont_inter ; // sert pour la recherche de doublon
list < TroisEntiers > : : iterator inumtesN ; // " " "
2024-01-30 20:55:48 +01:00
// tout d'abord on met à jour les boites d'encombrement des éléments frontière
2021-09-24 08:24:03 +02:00
for ( int jjf = 1 ; jjf < = nbmailMaitre ; jjf + + )
for ( int j = 1 ; j < = nb_zone ; j + + )
{ iMfin = ( t_listFront ( jjf ) ( j ) ) . end ( ) ;
for ( iM = ( t_listFront ( jjf ) ( j ) ) . begin ( ) ; iM ! = iMfin ; iM + + )
( * iM ) . Boite_encombrement_frontiere ( TEMPS_tdt , dep_max ) ;
2024-01-30 20:55:48 +01:00
} ;
// parcours des noeuds esclaves
2021-09-24 08:24:03 +02:00
for ( int intot = 1 ; intot < = nb_mail_Esclave ; intot + + ) // boucle sur les maillages esclaves
2023-05-03 17:23:49 +02:00
{ for ( int j_zone = 1 ; j_zone < = nb_zone ; j_zone + + )
{ const Tableau < Noeud * > & tesc = tesctotal ( intot ) ( j_zone ) ; // pout simplifier la notation
const Tableau < int > tesN_col = tesN_collant ( intot ) ( j_zone ) ; // pour simplifier
2021-09-24 08:24:03 +02:00
int tesc_taille = tesc . Taille ( ) ;
for ( int inesc = 1 ; inesc < = tesc_taille ; inesc + + ) // boucle sur les noeuds esclaves
// si le noeud est collant on ne fait rien
{ if ( ! tesN_col ( inesc ) )
{ Noeud * no = tesc ( inesc ) ;
int n_noee = no - > Num_noeud ( ) ;
int num_mail_noe_esclave = no - > Num_Mail ( ) ;
/* / #ifdef MISE_AU_POINT
// if (tesN_encontact(num_mail_noe_esclave).find(no)
// == tesN_encontact(num_mail_noe_esclave).end() )
// { cout << "\n*** Erreur : on ne trouve pas la liste d'element en contact avec le noeud esclave "
// << n_noee << " du maillage " << num_mail_noe_esclave
// << " la suite n'est pas possible "
// << " LesContacts::Nouveau(.. \n";
// tempsContact.Arret_du_comptage(); // fin cpu
// Sortie(1);
// };
// #endif */
std : : map < Noeud * , LaLIST < LaLIST < ElContact > : : iterator > > & tesN_encontact_ii
= tesN_encontact ( num_mail_noe_esclave ) ;
// on regarde si la liste existe, si oui on peut tester les membres sinon, on ne fait rien
// car autrement on crée automatiquement une liste avec un élément vide
std : : map < Noeud * , LaLIST < LaLIST < ElContact > : : iterator > > : : iterator it_liste ;
int nb_contact = 0 ;
if ( tesN_encontact_ii . find ( no ) ! = tesN_encontact_ii . end ( ) )
{ LaLIST < LaLIST < ElContact > : : iterator > & list_tesN = tesN_encontact_ii [ no ] ;
nb_contact = list_tesN . size ( ) ;
} ;
2024-01-30 20:55:48 +01:00
2024-03-24 11:43:58 +01:00
* ( gr_pour_noeud - > ConteneurEntier ( ) ) = n_noee ;
* ( gr_pour_elem - > ConteneurEntier ( ) ) = 0 ; // pas de numéro d'élément à prendre en compte pour la visu
if ( Permet_affichage ( & li_pour_noeuds_element ) > 6 )
2023-12-15 19:17:23 +01:00
{
# ifdef UTILISATION_MPI
2024-01-30 20:55:48 +01:00
cout < < " \n proc " < < proc_en_cours
2023-12-15 19:17:23 +01:00
# else
2024-01-30 20:55:48 +01:00
cout < < " \n "
2023-12-15 19:17:23 +01:00
# endif
< < " (re) examen eventuel : contact du noeud " < < n_noee < < " du maillage " < < num_mail_noe_esclave ;
2021-09-24 08:24:03 +02:00
cout < < " coord2= " ; no - > Coord2 ( ) . Affiche_1 ( cout ) ;
2024-03-24 11:43:58 +01:00
if ( Permet_affichage ( & li_pour_noeuds_element ) > 7 )
2021-09-24 08:24:03 +02:00
{ cout < < " num_mail_dans_contact = " < < num_mail_noe_esclave < < " inesc(num N local)= " < < inesc
2024-01-30 20:55:48 +01:00
< < " \n tesN_encontact= " < < nb_contact
2021-09-24 08:24:03 +02:00
< < " contacts enregistres " ;
} ;
// on dit si un des contacts est actif
int actif = 0 ;
if ( nb_contact )
{ LaLIST < LaLIST < ElContact > : : iterator > & list_tesN = tesN_encontact_ii [ no ] ;
LaLIST < LaLIST < ElContact > : : iterator > : : iterator il , ilfin = list_tesN . end ( ) ;
for ( il = list_tesN . begin ( ) ; il ! = ilfin ; il + + )
if ( ( * ( * il ) ) . Actif ( ) )
actif + + ;
if ( actif )
2024-01-30 20:55:48 +01:00
{ cout < < " \n noeud actuellement en contact dans " < < actif < < " element(s) " ;
2023-05-03 17:23:49 +02:00
if ( tesN_collant ( num_mail_noe_esclave ) ( j_zone ) ( inesc ) ) cout < < " collant " ;
2021-09-24 08:24:03 +02:00
}
2024-01-30 20:55:48 +01:00
else cout < < " \n noeud actuellement pas en contact " ;
2021-09-24 08:24:03 +02:00
int icont = 1 ;
for ( il = list_tesN . begin ( ) ; il ! = ilfin ; il + + , icont + + )
{ Front * elfront = ( * ( * il ) ) . Elfront ( ) ;
Element * elem = elfront - > PtEI ( ) ; // l'element qui contiend la frontiere
2024-01-30 20:55:48 +01:00
cout < < " \n elem_contact: " < < icont < < " avec frontiere: " < < elfront - > Num_frontiere ( )
2021-09-24 08:24:03 +02:00
< < " de l'element " < < elem - > Geometrie ( ) < < " : " < < elfront - > PtEI ( ) - > Num_elt ( )
< < " , type: " < < Nom_type_geom ( elfront - > Eleme_const ( ) - > Type_geom_front ( ) )
< < " du maillage : " < < elfront - > PtEI ( ) - > Num_maillage ( ) ;
} ;
} ;
// il y a un pb, car un noeud pourrait-être collant pour une zone et non collant pour une autre
// ce n'est peut-être pas un pb, mais il faudra peut-être avoir le niveau de zone en plus dans tesN_encontact ??
// cout << endl;
} ;
2024-03-24 11:43:58 +01:00
// on ne continue que si le noeud n'est pas entièrement bloqué
// si c'est le cas .... à finir !
2021-09-24 08:24:03 +02:00
{
Coordonnee pt_esc = no - > Coord2 ( ) ; // position du noeud esclave
// maintenant on regarde les frontieres maitres
int num_frontiere = 1 ; // pour le debug
for ( int jlf = 1 ; jlf < = nbmailMaitre ; jlf + + ) // boucle sur les maillages maîtres
2023-05-03 17:23:49 +02:00
{ LaLIST_io < Front > & t_listFront_jlf_j = t_listFront ( jlf ) ( j_zone ) ;
2021-09-24 08:24:03 +02:00
iMfin = t_listFront_jlf_j . end ( ) ;
for ( iM = t_listFront_jlf_j . begin ( ) ; iM ! = iMfin ; iM + + , num_frontiere + + ) // boucle sur les front maitres
// on parcours les elements maitres de la zone
// si le noeud esclave est déjà en contact avec la frontière ce n'est pas la peine de tester
{ // donc on passe en revue les éléments en contact
2023-12-15 19:17:23 +01:00
// si calcul // et élément déjà en contact c'est aussi vrai
2021-09-24 08:24:03 +02:00
bool a_considerer = true ; // init par défaut
if ( tesN_encontact_ii . find ( no ) ! = tesN_encontact_ii . end ( ) )
{ LaLIST < LaLIST < ElContact > : : iterator > & list_tesN = tesN_encontact_ii [ no ] ;
LaLIST < LaLIST < ElContact > : : iterator > : : iterator pl , plfin = list_tesN . end ( ) ;
for ( pl = list_tesN . begin ( ) ; pl ! = plfin ; pl + + )
{ ElContact & elc = ( * ( * pl ) ) ;
Front & elfront = ( * iM ) ;
Front * eltest = elc . Elfront ( ) ;
if ( eltest - > MemeOrigine ( elfront ) )
2023-05-03 17:23:49 +02:00
{ a_considerer = false ;
2024-01-30 20:55:48 +01:00
if ( elc . Permet_affichage ( ) > 6 )
{ cout < < " \n noeud esclave deja en contact " ; elc . Affiche ( 1 ) ;
2023-05-03 17:23:49 +02:00
} ;
break ; }
2021-09-24 08:24:03 +02:00
} ;
} ;
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
// dans le cas // on ne continue que si la frontière est relative à un élément associé au cpu
{ Element & elem = * ( ( * iM ) . PtEI ( ) ) ; // l'element qui contiend la frontiere
// on ne continue que si l'élément est concerné
if ( ! ( ParaGlob : : param - > Element_concerner ( elem . Num_maillage ( ) , elem . Num_elt_const ( ) ) ) )
a_considerer = false ;
} ;
# endif
2021-09-24 08:24:03 +02:00
// donc on ne continue que si la face n'est pas déjà en contact avec le noeud
2023-12-15 19:17:23 +01:00
// et dans le cas // que c'est ok
2021-09-24 08:24:03 +02:00
if ( a_considerer )
{ // on regarde si le noeud esclave est dans la boite d'encombrement de l'élément
// qui contient l'élément frontière (car l'élément frontière à une épaisseur nulle!)
Element & elem = * ( ( * iM ) . PtEI ( ) ) ; // l'element qui contiend la frontiere
Front & elfront = ( * iM ) ;
2024-01-30 20:55:48 +01:00
2024-03-24 11:43:58 +01:00
* ( gr_pour_noeud - > ConteneurEntier ( ) ) = no - > Num_noeud ( ) ;
* ( gr_pour_elem - > ConteneurEntier ( ) ) = elem . Num_elt ( ) ;
if ( Permet_affichage ( & li_pour_noeuds_element ) > 7 )
2021-09-24 08:24:03 +02:00
{ // --- sortie d'info pour vérifier l'appartenance à la boite ou non
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
# endif
< < " rappel: coordonnee noeud esclave : " ; no - > Coord2 ( ) . Affiche_1 ( cout ) ;
2021-09-24 08:24:03 +02:00
cout < < " \n boite d'encombrement de l'element maitre qui contient la frontiere: \n mini -> " ;
elem . RecupBoite_encombre_element ( ) . Premier ( ) . Affiche ( ) ;
cout < < " maxi -> " ;
elem . RecupBoite_encombre_element ( ) . Second ( ) . Affiche ( ) ;
} ;
// dans le cas où l'élément et le noeud appartienne au même maillage, on est
// dans le cas d'un auto-contact. Dans ce cas on ne considère que les éléments
// qui ne contiennent pas le noeud esclave
if ( elem . Num_maillage ( ) = = num_mail_noe_esclave )
{ List_io < Element * > indice_m = ( * indice ( num_mail_noe_esclave ) ) ( n_noee ) ; // pour simplifier
if ( find ( indice_m . begin ( ) , indice_m . end ( ) , & elem ) ! = indice_m . end ( ) )
break ; // on arrête la boucle si on trouve l'élément parmi ceux contenant le noeud
} ;
2024-03-24 11:43:58 +01:00
if ( Permet_affichage ( & li_pour_noeuds_element ) > 6 )
2023-12-15 19:17:23 +01:00
{
# ifdef UTILISATION_MPI
2024-01-30 20:55:48 +01:00
cout < < " \n proc " < < proc_en_cours
2023-12-15 19:17:23 +01:00
# else
2024-01-30 20:55:48 +01:00
cout < < " \n "
2023-12-15 19:17:23 +01:00
# endif
2024-01-30 20:55:48 +01:00
< < " frontiere: " < < elfront . Num_frontiere ( ) < < " (nb loc: " < < num_frontiere < < " ) "
2021-09-24 08:24:03 +02:00
< < " , type: " < < Nom_type_geom ( elfront . Eleme_const ( ) - > Type_geom_front ( ) )
< < " de l'element " < < elem . Geometrie ( ) < < " : "
< < elfront . PtEI ( ) - > Num_elt ( )
< < " du maillage : "
< < elfront . PtEI ( ) - > Num_maillage ( ) ;
} ;
if ( elem . In_boite_emcombrement_elem ( pt_esc , dep_max_pratique ) )
// on teste alors plus précisemment
// on regarde si cela pourrait conduire à un élément de contact identique
// à un élément que l'on vient juste d'effacer, si oui, on ne crée pas d'élément et
// on attend un prochain incrément, si effectivement l'élément doit se créer, il sera alors créé
2023-05-03 17:23:49 +02:00
// *** non, ça pose pb, on commente pour l'instant
2023-12-15 19:17:23 +01:00
{ //LaLIST <ElContact>::iterator ila,ilafin=listContact_efface_tatdt.end();
2021-09-24 08:24:03 +02:00
bool vraiment_nouveau_element = true ; // par défaut
2023-12-15 19:17:23 +01:00
/* // for (ila = listContact_efface_tatdt.begin();ila != ilafin;ila++)
2023-05-03 17:23:49 +02:00
// { if (((*ila).Esclave()->Num_noeud() == n_noee)
// && ((*((*ila).Elfront()->Eleme())) == (*((*iM).Eleme())))
// && ((*ila).Esclave()->Num_Mail() == num_mail_noe_esclave))
// { vraiment_nouveau_element = false;
// if ((*ila).Permet_affichage() > 5)
// {cout << "\n element de contact venant juste d'etre supprime, on arrete la creation ";
// (*ila).Affiche(1);
// };
// break;};
// };
2023-12-15 19:17:23 +01:00
*/
2024-03-24 11:43:58 +01:00
* ( gr_pour_noeud - > ConteneurEntier ( ) ) = n_noee ;
* ( gr_pour_elem - > ConteneurEntier ( ) ) = 0 ; // pas de filtre sur les nb elem
if ( Permet_affichage ( & li_pour_noeuds_element ) > 7 )
2024-01-30 20:55:48 +01:00
{ cout < < " \n liste des contacts sur le noeud " < < n_noee
< < " qui est prevu en effacement sur l'increment " ;
2021-09-24 08:24:03 +02:00
LaLIST < ElContact > : : iterator ila , ilafin = listContact_efface_tatdt . end ( ) ;
for ( ila = listContact_efface_tatdt . begin ( ) ; ila ! = ilafin ; ila + + )
2024-01-30 20:55:48 +01:00
{ cout < < " \n " < < n_noee < < " " < < ( * ila ) . Esclave ( ) - > Num_noeud ( )
2021-09-24 08:24:03 +02:00
< < " " ;
( * ila ) . Elfront ( ) - > Affiche ( ) ;
( * iM ) . Affiche ( ) ;
2024-01-30 20:55:48 +01:00
cout < < " \n ((*ila).Esclave()->Num_noeud() == noee->Num_noeud()) "
2021-09-24 08:24:03 +02:00
< < ( ( * ila ) . Esclave ( ) - > Num_noeud ( ) = = n_noee ) ;
2024-01-30 20:55:48 +01:00
cout < < " \n ((*((*ila).Elfront()->Eleme())) == (*((*iM)->Eleme()))) "
2021-09-24 08:24:03 +02:00
< < ( ( * ( ( * ila ) . Elfront ( ) - > Eleme ( ) ) ) = = ( * ( ( * iM ) . Eleme ( ) ) ) ) ;
2024-01-30 20:55:48 +01:00
cout < < " \n ((*ila).Esclave()->Num_Mail() == noee->Num_Mail()) "
2021-09-24 08:24:03 +02:00
< < ( ( * ila ) . Esclave ( ) - > Num_Mail ( ) = = n_noee ) ;
2024-01-30 20:55:48 +01:00
cout < < " \n vraiment_nouveau_element= " < < vraiment_nouveau_element < < endl ;
2021-09-24 08:24:03 +02:00
} ;
} ;
// on ne continue que si c'est un vrai nouvel élément
if ( vraiment_nouveau_element )
2023-05-03 17:23:49 +02:00
{ // on passe en revue les frontières de contact déjà existantes associées
2021-09-24 08:24:03 +02:00
// et s'il y a déjà un élément qui correspond, on arête la création
bool creation = true ; // init
if ( nb_contact )
{ LaLIST < LaLIST < ElContact > : : iterator > & list_tesN = tesN_encontact_ii [ no ] ;
LaLIST < LaLIST < ElContact > : : iterator > : : iterator il , ilfin = list_tesN . end ( ) ;
for ( il = list_tesN . begin ( ) ; il ! = ilfin ; il + + )
{ ElContact & con = ( * ( * il ) ) ;
if ( con . Elfront ( ) - > MemeOrigine ( elfront ) )
2023-05-03 17:23:49 +02:00
{ creation = false ;
if ( con . Permet_affichage ( ) > 5 )
2023-12-15 19:17:23 +01:00
{
# ifdef UTILISATION_MPI
2024-01-30 20:55:48 +01:00
cout < < " \n proc " < < proc_en_cours
2023-12-15 19:17:23 +01:00
# else
2024-01-30 20:55:48 +01:00
cout < < " \n "
2023-12-15 19:17:23 +01:00
# endif
< < " frontiere en contact deja existante , on arrete la creation " ;
2023-05-03 17:23:49 +02:00
elfront . Affiche ( 1 ) ;
} ;
}
2021-09-24 08:24:03 +02:00
} ;
} ;
// on ne continue que s'il n'existe pas d'élément de contact du même type
if ( creation )
{ ElContact elcont ( & ( * iM ) , tesc ( inesc ) , fct_nD_contact ) ;
2023-05-03 17:23:49 +02:00
elcont . Num_zone_contact ( ) = j_zone ; // affectation du numéro de zone
elcont . Change_lissage_normale ( lissage_de_la_normale ( j_zone ) ) ; // affectation du lissage
2024-03-24 11:43:58 +01:00
# ifdef UTILISATION_MPI
// on attribue au front de l'élément de contact, le numéro unique utilisable pour le tableau pointe_t_listFront
elcont . Elfront ( ) - > ChangeNumUnique ( ( * iM ) . NumUnique ( ) ) ;
# endif
2023-05-03 17:23:49 +02:00
2021-09-24 08:24:03 +02:00
// vérification que l'on a bien les frontières bien connectées
2023-05-03 17:23:49 +02:00
if ( ( niveau_commentaire_lescontacts > 5 )
| | ( elcont . Permet_affichage ( ) > 5 ) )
2021-09-24 08:24:03 +02:00
{ Front * elfront = elcont . Elfront ( ) ;
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
2024-01-30 20:55:48 +01:00
cout < < " \n proc " < < proc_en_cours
2023-12-15 19:17:23 +01:00
# else
2024-01-30 20:55:48 +01:00
cout < < " \n "
2023-12-15 19:17:23 +01:00
# endif
2024-01-30 20:55:48 +01:00
< < " test nouveau contact: examen plus precis: frontiere: " < < elfront - > Num_frontiere ( )
2023-12-15 19:17:23 +01:00
< < " , type: " < < Nom_type_geom ( elfront - > Eleme_const ( ) - > Type_geom_front ( ) )
< < " de l'element " < < elfront - > PtEI ( ) - > Num_elt ( ) < < " du maillage "
< < elfront - > PtEI ( ) - > Num_maillage ( ) ;
2024-03-24 11:43:58 +01:00
* ( gr_pour_elem - > ConteneurEntier ( ) ) = elfront - > PtEI ( ) - > Num_elt ( ) ;
if ( Permet_affichage ( & li_pour_noeuds_element ) > 7 )
2021-09-24 08:24:03 +02:00
elcont . Affiche ( ) ;
} ;
// calcul du contact, et translation éventuelle du noeud sur la surface
// si le contact existe, ceci en fonction de la méthode de contact
bool ret = elcont . Contact ( ) ;
2023-05-03 17:23:49 +02:00
if ( elcont . Permet_affichage ( ) > 5 )
2024-01-30 20:55:48 +01:00
{ cout < < " \n retour de Contact: ret= " < < ret ;
2023-05-03 17:23:49 +02:00
}
2021-09-24 08:24:03 +02:00
if ( ret )
2023-05-03 17:23:49 +02:00
{ //sauvegarde éventuelle de l'element contact
ElContact * test_existance = Element_contact_deja_present ( elcont ) ;
if ( test_existance = = NULL )
{ listContact . push_front ( elcont ) ;
//numtesN.push_front(TroisEntiers(num_mail_noe_esclave,j,n_noee));
tesN_encontact_ii [ no ] . push_front ( listContact . begin ( ) ) ;
listContact_nouveau_tatdt . push_front ( listContact . begin ( ) ) ;
// à ce stade le nouveau contact est actif
retour = true ; // on valide le retour
if ( ( niveau_commentaire_lescontacts > 3 )
| | ( elcont . Permet_affichage ( ) > 3 ) )
2023-12-15 19:17:23 +01:00
{
# ifdef UTILISATION_MPI
2024-01-30 20:55:48 +01:00
cout < < " \n proc " < < proc_en_cours
2023-12-15 19:17:23 +01:00
# else
2024-01-30 20:55:48 +01:00
cout < < " \n "
2023-12-15 19:17:23 +01:00
# endif
2024-01-30 20:55:48 +01:00
< < " newcontact: " ;
2023-05-03 17:23:49 +02:00
if ( tesN_col ( inesc ) ) cout < < " collant " ;
elcont . Affiche ( 1 ) ;
2024-01-30 20:55:48 +01:00
} ;
2023-05-03 17:23:49 +02:00
}
else if ( ! test_existance - > Actif ( ) )
// s'il existe et est inactif on le rend actif (pour remplacer celui qui devrait être créé)
{ test_existance - > Met_actif ( ) ;
if ( ( niveau_commentaire_lescontacts > 5 )
| | ( elcont . Permet_affichage ( ) > 5 ) )
{ cout < < " remis en actif: " ;
elcont . Affiche ( 2 ) ;
} ;
}
else
{ if ( ( niveau_commentaire_lescontacts > 5 )
| | ( elcont . Permet_affichage ( ) > 5 ) )
2024-01-30 20:55:48 +01:00
cout < < " --> contact deja enregistre " ;
2023-05-03 17:23:49 +02:00
} ;
2021-09-24 08:24:03 +02:00
}
else
2023-05-03 17:23:49 +02:00
{ if ( ( niveau_commentaire_lescontacts > 5 )
| | ( elcont . Permet_affichage ( ) > 5 ) )
2024-01-30 20:55:48 +01:00
cout < < " --> pas de contact " ;
2021-09-24 08:24:03 +02:00
} ;
2023-05-03 17:23:49 +02:00
// listContact.push_back(elcont);numtesN.push_back(DeuxEntiers(intot,inesc));
// if (niveau_commentaire_lescontacts >= 6)
2021-09-24 08:24:03 +02:00
// { Enum_type_geom type_front; Element & elem = *elcont.Elfront()->PtEI();
// int num_mail_elem = (elem.Tab_noeud())(1)->Num_Mail();
// cout << "\nnewcontact entre noeud " << elcont.Esclave()->Num_noeud()
// << " du maillage " << elcont.Esclave()->Num_Mail()
// << " et frontiere " << (*iM)->Num_frontiere()
// << " de l'element " << elem.Num_elt() << " du maillage "
// << num_mail_elem << flush;
// }
// retour = true;
// break; // on arrête la boucle sur les fronts car on a trouvé un contact
} ; // fin du test if creation
// sinon il n'y a pas de contact
} // -- fin du test sur examen if (vraiment_nouveau_element)
} ; //-- fin du test sur la boite_encombrement
} ; // -- fin du test : if (a_considerer)
} ; // -- boucle sur iM
} ; // -- boucle sur jlf
} ; // -- fin du test tesN_encontact(intot)(inesc)
} //-- fin du test non collant: if (!tesN_col(inesc))
} ; // -- boucle sur inesc
2023-05-03 17:23:49 +02:00
} // -- fin de la boucle sur les zones for (int j=1;j<= nb_zone;j++)
} ; // -- boucle sur intot
2024-03-24 11:43:58 +01:00
# ifdef UTILISATION_MPI
// affichage pour les proc != 0
if ( niveau_commentaire_lescontacts > 4 )
# else
if ( niveau_commentaire_lescontacts > 3 ) // ==> LesContacts::
# endif
2023-12-15 19:17:23 +01:00
{
# ifdef UTILISATION_MPI
2024-01-30 20:55:48 +01:00
cout < < " \n proc " < < proc_en_cours
2023-12-15 19:17:23 +01:00
# else
2024-01-30 20:55:48 +01:00
cout < < " \n "
2023-12-15 19:17:23 +01:00
# endif
2024-03-24 11:43:58 +01:00
< < " en fin de LesContacts::Nouveau: bilan: " < < listContact . size ( ) < < " elem(s) contact " ;
2021-09-24 08:24:03 +02:00
if ( listContact_nouveau_tatdt . size ( ) )
cout < < " , " < < ( listContact_nouveau_tatdt . size ( ) - taille_list_contact_nouveau_au_debut )
< < " nouveau(x) " ;
if ( listContact_efface_tatdt . size ( ) )
cout < < " , " < < listContact_efface_tatdt . size ( ) < < " effactement(s) " ;
2024-01-30 20:55:48 +01:00
} ;
if ( niveau_commentaire_lescontacts > 4 )
// on va lister les éléments de contact
{
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
2024-01-30 20:55:48 +01:00
# endif
< < " liste des Elcontact a la fin de LesContacts::Nouveau: (fct du niveau de commentaire des elcontact): " ;
LaLIST < ElContact > : : iterator ipp , ippfin = listContact . end ( ) ;
for ( ipp = listContact . begin ( ) ; ipp ! = ippfin ; ipp + + )
{ ( * ipp ) . Affiche ( 2 ) ; } ;
cout < < " fin liste " ;
} ;
if ( niveau_commentaire_lescontacts > 3 )
{
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
2023-12-15 19:17:23 +01:00
# endif
< < " <== fin LesContacts::Nouveau " ;
2021-09-24 08:24:03 +02:00
} ;
2024-03-24 11:43:58 +01:00
# ifdef UTILISATION_MPI
} ; // fin de la recherche de nouveaux contact pour proc != 0
# endif
# ifdef UTILISATION_MPI
if ( proc_en_cours ! = 0 ) // on transmet à proc 0
{ temps_transfert_court . Mise_en_route_du_comptage ( ) ; // comptage cpu
// pour cela on va utiliser un conteneur intermédiaire
QuatreEntiers inter_entiers ( retour , listContact . size ( ) , listContact_nouveau_tatdt . size ( ) , listContact_efface_tatdt . size ( ) ) ;
// on transmet les infos au proc 0
mpi : : request reqs1 = ParaGlob : : Monde ( ) - > isend ( 0 , 62 , inter_entiers ) ;
// on attend pas
temps_transfert_court . Arret_du_comptage ( ) ; // fin comptage cpu
}
else // cas du cpu 0
{ // l'objectif ici est de récupérer les infos
tempsContact . Arret_du_comptage ( ) ; // fin cpu
int nb_contact = 0 ; int nb_new_contact = 0 ; int nb_efface_contact = 0 ; // que l'on va cumuler
int nb_proc_terminer = 0 ; // permettra de terminer
while ( nb_proc_terminer < ( ParaGlob : : Monde ( ) - > size ( ) - 1 ) )
{ // on récupère un résultat de cpu i
temps_transfert_court . Mise_en_route_du_comptage ( ) ; // comptage cpu
QuatreEntiers inter_entiers ;
mpi : : request reqs1 = ParaGlob : : Monde ( ) - > irecv ( mpi : : any_source , 62 , inter_entiers ) ;
reqs1 . wait ( ) ; // on attend que le conteneur soit rempli
// on cumule
nb_contact + = inter_entiers . deux ;
nb_new_contact + = inter_entiers . trois ;
nb_efface_contact + = inter_entiers . quatre ;
if ( inter_entiers . un ) // si un seul des retour s est bon on passe à true
retour = true ;
nb_proc_terminer + + ; // on prend en compte que l'on a récupéré un conteneur
} ;
if ( retour )
if ( niveau_commentaire_lescontacts > 3 ) // ==> LesContacts::
{ cout < < " \n en fin de LesContacts::Nouveau: bilan: " < < nb_contact < < " elem(s) contact " ;
if ( nb_new_contact )
cout < < " , " < < nb_new_contact < < " nouveau(x) " ;
if ( nb_efface_contact )
cout < < " , " < < nb_efface_contact < < " effacement(s) " ;
cout < < flush ;
} ;
} ;
// il faut que tous les proc aient le retour global, car le retour sert dans l'algo général
broadcast ( * ParaGlob : : Monde ( ) , retour , 0 ) ;
# endif
2024-01-30 20:55:48 +01:00
2021-09-24 08:24:03 +02:00
tempsContact . Arret_du_comptage ( ) ; // fin cpu
//cout << "\n tempsContact.Temps_CPU_User = " << tempsContact.Temps_CPU_User() << flush;
return retour ;
} ;
// suppression définitive, si le contact à disparu, des éléments inactifs
// ramène false si aucun élément n'est finalement supprimé
bool LesContacts : : SuppressionDefinitiveElemInactif ( )
{
tempsContact . Mise_en_route_du_comptage ( ) ; // def deb compt
2023-05-03 17:23:49 +02:00
int niveau_commentaire_lescontacts = Permet_affichage ( ) ;
2024-03-24 11:43:58 +01:00
bool change = false ;
int nb_effacement = 0 ;
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
int proc_en_cours = ParaGlob : : Monde ( ) - > rank ( ) ;
2024-03-24 11:43:58 +01:00
if ( proc_en_cours ! = 0 ) // seules les proc i>0 définissent des éléments de contact
{
2023-12-15 19:17:23 +01:00
# endif
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > 4 )
2023-12-15 19:17:23 +01:00
{
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
# endif
< < " -- LesContacts::SuppressionDefinitiveElemInactif: " ;
} ;
2021-09-24 08:24:03 +02:00
LaLIST < ElContact > : : iterator iE ;
for ( iE = listContact . begin ( ) ; iE ! = listContact . end ( ) ; iE + + ) //,iden++)
{ if ( ! ( ( * iE ) . Actif ( ) ) // on intervient si le contact est déclaré inactif
& & ( ( * iE ) . Collant ( ) ) // et si c'est collant: ce n'est pas normal, on le remet actif
)
{ ( * iE ) . Met_actif ( ) ; // on valide l'activation
}
else if ( ! ( ( * iE ) . Actif ( ) ) // on intervient si le contact est déclaré inactif
& & ! ( ( * iE ) . Collant ( ) ) // et si ce n'est pas collant: si collant, on ne change rien
)
{ LaLIST < ElContact > : : iterator iiE = iE ;
// list <TroisEntiers>::iterator iiden = iden;
int num_mail_esclave = ( * iiE ) . Esclave ( ) - > Num_Mail ( ) ;
int num_noeud = ( * iiE ) . Esclave ( ) - > Num_noeud ( ) ;
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > 3 )
2021-09-24 08:24:03 +02:00
{ Element & elem = * ( * iiE ) . Elfront ( ) - > PtEI ( ) ;
int num_mail_elem = ( elem . Tab_noeud ( ) ) ( 1 ) - > Num_Mail ( ) ;
2023-05-03 17:23:49 +02:00
cout < < " \n effacement contact: " ; ( * iiE ) . Affiche ( 1 ) ;
2021-09-24 08:24:03 +02:00
} ;
iE - - ; // pointe sur le precedent element
listContact_efface_tatdt . push_front ( * iiE ) ;
# ifdef MISE_AU_POINT
if ( tesN_encontact ( num_mail_esclave ) . find ( ( * iiE ) . Esclave ( ) )
= = tesN_encontact ( num_mail_esclave ) . end ( ) )
{ cout < < " \n *** Erreur : on ne trouve pas la liste d'element en contact avec le noeud esclave "
< < ( * iiE ) . Esclave ( ) - > Num_noeud ( ) < < " du maillage " < < num_mail_esclave
< < " la suite n'est pas possible "
< < " LesContacts::SuppressionDefinitiveElemInactif(.. \n " ;
tempsContact . Arret_du_comptage ( ) ; // fin cpu
Sortie ( 1 ) ;
} ;
# endif
LaLIST < LaLIST < ElContact > : : iterator > & list_tesN
= tesN_encontact ( num_mail_esclave ) [ ( * iiE ) . Esclave ( ) ] ;
2023-05-03 17:23:49 +02:00
////--- debug
//{cout << "\n debug LesContacts::SuppressionDefinitiveElemInactif: ";
// (*iiE).Affiche(1);
// }
// //--- fin debug
2021-09-24 08:24:03 +02:00
list_tesN . remove ( iiE ) ;
// tesN_encontact(num_mail_esclave)(num_noeud).remove(iiE); // mise à jour de l'indicateur
listContact . erase ( iiE ) ; // efface l'element
2023-05-03 17:23:49 +02:00
////--- debug
//{cout << "\n liste restante des elements de contact ";
// LaLIST <ElContact>::iterator iE ;
// for (iE = listContact.begin(); iE != listContact.end(); iE++)
// {cout << "\n";(*iE).Affiche(1);}
//}
////--- fin debug
2021-09-24 08:24:03 +02:00
nb_effacement + + ;
change = true ;
// iden--;
// numtesN.erase(iiden);
}
//**** j'ai l'impression que la ligne qui suit ne sert à rien, car le if précédent était uniquement pour les inactifs, donc si on va à la ligne qui suit
// c'est que l'élément est actif, donc cela ne sert à rien de le réactiver ???? ceci dit cela ne génère pas une erreur a priori
2024-01-30 20:55:48 +01:00
else { /*(*iE).Met_actif();*/ } ; // on valide l'activation
2021-09-24 08:24:03 +02:00
} ;
2024-03-24 11:43:58 +01:00
// info
if ( niveau_commentaire_lescontacts > 2 )
{ if ( nb_effacement )
{
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
# endif
< < " sup: " < < nb_effacement < < " effacement(s) definitif(s) de contact " ;
} ;
} ;
if ( ( niveau_commentaire_lescontacts > 6 ) & & ( nb_effacement = = 0 ) )
cout < < " aucun effacement " ;
# ifdef UTILISATION_MPI
temps_transfert_court . Mise_en_route_du_comptage ( ) ; // comptage cpu
mpi : : request reqs1 = ParaGlob : : Monde ( ) - > isend ( 0 , 610 , change ) ;
// on attend pas
temps_transfert_court . Arret_du_comptage ( ) ; // fin comptage cpu
}
else // cas du cpu 0
{ // l'objectif ici est de récupérer les infos
tempsContact . Arret_du_comptage ( ) ; // fin cpu
int nb_proc_terminer = 0 ; // permettra de terminer
while ( nb_proc_terminer < ( ParaGlob : : Monde ( ) - > size ( ) - 1 ) )
{ // on récupère un résultat de cpu i
temps_transfert_court . Mise_en_route_du_comptage ( ) ; // comptage cpu
bool change_i ;
mpi : : request reqs1 = ParaGlob : : Monde ( ) - > irecv ( mpi : : any_source , 610 , change_i ) ;
reqs1 . wait ( ) ; // on attend que le conteneur soit rempli
if ( change_i ) // si un seul des retour s est bon on passe à true
change = true ;
nb_proc_terminer + + ; // on prend en compte que l'on a récupéré un conteneur
2023-12-15 19:17:23 +01:00
} ;
2024-03-24 11:43:58 +01:00
} ;
// il faut que tous les proc aient le retour global, car le retour sert dans l'algo général
broadcast ( * ParaGlob : : Monde ( ) , change , 0 ) ;
# endif
2021-09-24 08:24:03 +02:00
tempsContact . Arret_du_comptage ( ) ; // fin cpu
// retour du tableau
return change ;
} ;
// relachement des noeuds collés
// ramène true s'il y a des noeuds qui ont été relachés
bool LesContacts : : RelachementNoeudcolle ( )
{
tempsContact . Mise_en_route_du_comptage ( ) ; // def deb compt
2023-05-03 17:23:49 +02:00
int niveau_commentaire_lescontacts = Permet_affichage ( ) ;
2024-03-24 11:43:58 +01:00
bool change = false ;
# ifdef UTILISATION_MPI
int proc_en_cours = ParaGlob : : Monde ( ) - > rank ( ) ;
if ( proc_en_cours ! = 0 ) // seules les proc i>0 définissent des éléments de contact
{
# endif
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > 4 )
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
# endif
< < " -- LesContacts::RelachementNoeudcolle(): " ;
2024-03-24 11:43:58 +01:00
// return change; //------- pour le débug
2021-09-24 08:24:03 +02:00
LaLIST < ElContact > : : iterator iE ;
// list <TroisEntiers>::iterator iden = numtesN.begin();
// on met .end(), car cette borne peut changer au gré des suppression
for ( iE = listContact . begin ( ) ; iE ! = listContact . end ( ) ; iE + + ) //,iden++)
// on ne test que les éléments actifs, pour lesquels les calculs sont à jour
if ( ( ( * iE ) . Actif ( ) ) // on intervient si le contact est déclaré actif
& & ! ( ( * iE ) . Collant ( ) ) // et si ce n'est pas collant: si collant, on ne fait rien
)
if ( ( * iE ) . Decol ( ) )
// le décolement est testé soit sur la réaction, qui a été calculée
// au pas précédent, ou soit sur une position géométrique en dehors d'une zone d'accostage.
//S'il y a décolement on ne doit plus tenir compte du contact et donc on inactive l'élément de contact
{ LaLIST < ElContact > : : iterator iiE = iE ;
// list <TroisEntiers>::iterator iiden = iden;
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > 2 )
2023-12-15 19:17:23 +01:00
{
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
# endif
< < " inactivation (relachement) pour cause de decollement du contact " ;
2023-05-03 17:23:49 +02:00
( * iiE ) . Affiche ( 1 ) ; cout < < endl ;
2021-09-24 08:24:03 +02:00
////------ debug
//{cout << "\n debug: LesContacts::RelachementNoeudcolle() ";
// (*iE).Decol();
//}
//// ------- fin debug
} ;
change = true ;
( * iE ) . Met_Inactif ( ) ;
} ;
2023-05-03 17:23:49 +02:00
if ( ( ! change ) & & ( niveau_commentaire_lescontacts > 6 ) )
2021-09-24 08:24:03 +02:00
cout < < " aucun noeud relache " ;
2024-03-24 11:43:58 +01:00
# ifdef UTILISATION_MPI
temps_transfert_court . Mise_en_route_du_comptage ( ) ; // comptage cpu
mpi : : request reqs1 = ParaGlob : : Monde ( ) - > isend ( 0 , 6100 , change ) ;
// on attend pas
temps_transfert_court . Arret_du_comptage ( ) ; // fin comptage cpu
}
else // cas du cpu 0
{ // l'objectif ici est de récupérer les infos
tempsContact . Arret_du_comptage ( ) ; // fin cpu
int nb_proc_terminer = 0 ; // permettra de terminer
while ( nb_proc_terminer < ( ParaGlob : : Monde ( ) - > size ( ) - 1 ) )
{ // on récupère un résultat de cpu i
temps_transfert_court . Mise_en_route_du_comptage ( ) ; // comptage cpu
bool change_i ;
mpi : : request reqs1 = ParaGlob : : Monde ( ) - > irecv ( mpi : : any_source , 6100 , change_i ) ;
reqs1 . wait ( ) ; // on attend que le conteneur soit rempli
if ( change_i ) // si un seul des retour s est bon on passe à true
change = true ;
nb_proc_terminer + + ; // on prend en compte que l'on a récupéré un conteneur
} ;
} ;
// il faut que tous les proc aient le retour global, car le retour sert dans l'algo général
broadcast ( * ParaGlob : : Monde ( ) , change , 0 ) ;
# endif
2021-09-24 08:24:03 +02:00
tempsContact . Arret_du_comptage ( ) ; // fin cpu
// retour
return change ;
} ;
// definition des conditions lineaires de contact
// casAssemb : donne le cas d'assemblage a prendre en compte
// et marquage des ddl imposé par le contact
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 > & LesContacts : : ConditionLin ( const Nb_assemb & casAssemb )
2021-09-24 08:24:03 +02:00
{
tempsContact . Mise_en_route_du_comptage ( ) ; // def deb compt
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
int proc_en_cours = ParaGlob : : Monde ( ) - > rank ( ) ;
if ( proc_en_cours ! = 0 )
{
# endif
2021-09-24 08:24:03 +02:00
// on crée des conditions linéaires dans le cas du type 1: contact cinématique
// mais aussi dans les autres cas pour l'optimisation de largeur de bande par exemple
2023-05-03 17:23:49 +02:00
{ Calcul_Nb_contact_actif ( ) ;
2023-12-15 19:17:23 +01:00
listCoLin . clear ( ) ; // Change_taille(nb_contact_actif);
2021-09-24 08:24:03 +02:00
//cout << "\n nb actif pour condlin = " << nb_contact_actif;
// on boucle sur les elements de contact
LaLIST < ElContact > : : iterator iE , iEfin = listContact . end ( ) ;
for ( iE = listContact . begin ( ) ; iE ! = iEfin ; iE + + )
if ( ( * iE ) . Actif ( ) ) // on n'intervient que si le contact est actif
// appel de la fonction de construction de condition lineaire dans l'element de contact
2023-12-15 19:17:23 +01:00
{ listCoLin . push_front ( ( * iE ) . ConditionLi ( casAssemb . n ) ) ;
2021-09-24 08:24:03 +02:00
} ;
2023-12-15 19:17:23 +01:00
tempsContact . Arret_du_comptage ( ) ; // fin cpu
2021-09-24 08:24:03 +02:00
}
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
temps_transfert_long . Mise_en_route_du_comptage ( ) ; // comptage cpu
// maintenant on va les transmettres au cpu 0
// pour cela on va utiliser un conteneur intermédiaire
// on calcul la taille nécessaire pour le conteneur (a découper éventuellement ??)
int taille_conteneur = 0 ;
list < Condilineaire > : : iterator il , ilfin = listCoLin . end ( ) ;
for ( il = listCoLin . begin ( ) ; il ! = ilfin ; il + + )
taille_conteneur + = ( * il ) . Taille_Pack ( ) ;
inter_transfer . Change_taille ( taille_conteneur ) ; // le conteneur
// on rempli le conteneur
int rang = 1 ; // init
for ( il = listCoLin . begin ( ) ; il ! = ilfin ; il + + )
rang = ( * il ) . Pack_vecteur ( inter_transfer , rang ) ;
temps_attente . Arret_du_comptage ( ) ;
// on transfert
mpi : : request reqs1 = ParaGlob : : Monde ( ) - > isend ( 0 , 40 , taille_conteneur ) ;
2021-09-24 08:24:03 +02:00
2023-12-15 19:17:23 +01:00
mpi : : request reqs2 = inter_transfer . Ienvoi_MPI ( 0 , 41 ) ;
// on attend pas
temps_transfert_long . Arret_du_comptage ( ) ; // fin comptage cpu
}
else // cas du cpu 0
{ // l'objectif ici est de récupérer les conditions linéaires
tempsContact . Arret_du_comptage ( ) ; // fin cpu
temps_transfert_long . Mise_en_route_du_comptage ( ) ; // comptage cpu
int nb_proc_terminer = 0 ; // permettra de terminer
listCoLin . clear ( ) ; // Change_taille(nb_contact_actif);
while ( nb_proc_terminer < ( ParaGlob : : Monde ( ) - > size ( ) - 1 ) ) // gérer par les valeurs de tyfront
{ // on récupère un résultat de cpu i
int taille_transfert ;
mpi : : request reqs1 = ParaGlob : : Monde ( ) - > irecv ( mpi : : any_source , 40 , taille_transfert ) ;
mpi : : status stat = reqs1 . wait ( ) ; // on attend que le conteneur soit rempli
inter_transfer . Change_taille ( taille_transfert ) ; // le conteneur
int source = stat . source ( ) ; // récupération du numéro de la source
// on récupère
mpi : : request reqs2 = inter_transfer . Irecup_MPI ( source , 41 ) ;
reqs2 . wait ( ) ; // on attend que le conteneur soit rempli
nb_proc_terminer + + ; // on prend en compte que l'on a récupéré un conteneur
// on va remplir la liste des conditions limites
int rang = 1 ; // init
while ( rang ! = 0 )
{ Condilineaire condi ; // une condition intermédiaire
rang = condi . UnPack_vecteur ( * lesMaille , inter_transfer , rang ,
& LesMaillages : : Noeud_LesMaille ) ;
listCoLin . push_back ( condi ) ;
} ;
} ;
temps_transfert_long . Arret_du_comptage ( ) ;
} ;
# endif
// tempsContact.Arret_du_comptage(); // fin cpu
2021-09-24 08:24:03 +02:00
// retour du tableau
2023-12-15 19:17:23 +01:00
return listCoLin ;
2021-09-24 08:24:03 +02:00
} ;
// effacement du marquage de ddl bloque du au conditions lineaire de contact
void LesContacts : : EffMarque ( )
{
tempsContact . Mise_en_route_du_comptage ( ) ; // def deb compt
2023-12-15 19:17:23 +01:00
// on parcours la liste des conditions lineaires
list < Condilineaire > : : iterator il , ilfin = listCoLin . end ( ) ;
for ( il = listCoLin . begin ( ) ; il ! = ilfin ; il + + )
2021-09-24 08:24:03 +02:00
{ // on libere la condition
2023-12-15 19:17:23 +01:00
Condilineaire & C = ( * il ) ;
2021-09-24 08:24:03 +02:00
C . Noe ( ) - > Change_fixe ( C . Tab_Enum ( ) ( 1 ) , false ) ;
} ;
tempsContact . Arret_du_comptage ( ) ; // fin cpu
} ;
// 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 LesContacts : : Maitres_avec_deplacement_imposer ( ) const
{ bool retour = true ; // init par défaut
int dim = ParaGlob : : Dimension ( ) ;
int nb_zone = MaX ( 1 , nom_ref_zone_contact . size ( ) ) ;
// seule sont disponibles les zones de contact (restreintes éventuellement)
// on passe en revue tous les noeuds des frontières
for ( int i = 1 ; i < = nbmailMaitre ; i + + )
for ( int j = 1 ; j < = nb_zone ; j + + )
{ LaLIST_io < Front > : : const_iterator il , ilfin = t_listFront ( i ) ( j ) . end ( ) ;
for ( il = t_listFront ( i ) ( j ) . begin ( ) ; il ! = ilfin ; il + + )
{ const Tableau < Noeud * > & tn = ( * il ) . Eleme_const ( ) - > TabNoeud_const ( ) ;
int nb_noe = tn . Taille ( ) ;
for ( int n = 1 ; n < = nb_noe ; n + + )
{ const Noeud & noe = * tn ( n ) ; // pour simplifier
switch ( dim )
{ case 3 : if ( ! ( noe . Ddl_fixe ( X3 ) ) ) { retour = false ; break ; } ;
case 2 : if ( ! ( noe . Ddl_fixe ( X2 ) ) ) { retour = false ; break ; } ;
case 1 : if ( ! ( noe . Ddl_fixe ( X1 ) ) ) { retour = false ; break ; } ;
} ;
if ( ! retour ) break ;
} ;
if ( ! retour ) break ;
} ;
if ( ! retour ) break ;
} ;
// retour
return retour ;
} ;
// 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)
// = 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 LesContacts : : Largeur_Bande ( int & demi , int & total , const Nb_assemb & casAssemb , int & cumule )
{
tempsContact . Mise_en_route_du_comptage ( ) ; // def deb compt
2023-12-15 19:17:23 +01:00
bool retour = false ; // par défaut on se met dans le cas le plus simple : contact avec surface rigide
2021-09-24 08:24:03 +02:00
// dans le cas d'un contact avec surface déformable, le contact modifie la largeur de bande
demi = 0 ;
2023-12-15 19:17:23 +01:00
total = 0 ; // c'est le plus important, car la bande sup réelle est en général différente
// de la bande inf, mais ce qui sera utilisé pour le dimensionnement de la bande de la matrice
// c'est le total: inf + sup + 1 (le 1 est pour la diagonale, il ne sert à rien)
cumule = 0 ;
# ifdef UTILISATION_MPI
int proc_en_cours = ParaGlob : : Monde ( ) - > rank ( ) ;
if ( proc_en_cours ! = 0 )
{
# endif
// encapsulage de la partie hors calcul parallèle
{
LaLIST < ElContact > : : iterator iE , iEfin = listContact . end ( ) ;
int nb_Assemb = casAssemb . n ; // récup du numéro d'assemblage
//------ debug
// cout << "\n LesContacts::Largeur_Bande ";
// ------ fin debug
// on boucle sur les elements de contact
for ( iE = listContact . begin ( ) ; iE ! = iEfin ; iE + + )
{
//------ debug
// (*iE).Affiche();
// ------ fin debug
// on n'intervient que si le contact est actif et que ce n'est pas un contact solide déformable
if ( ( ( * iE ) . Actif ( ) ) & & ( ( * iE ) . Cas_solide ( ) = = 0 ) )
{ //on boucle sur les noeuds de l'element de contact
const Tableau < Noeud * > & tabnoeud = ( * iE ) . TabNoeud ( ) ;
int maxiPourLeContact = 0 ; // stocke le maxi pour chaque condition linéaire
retour = true ; // ici la largeur de bande en noeud est augmenté, car le noeud en contact
// est en relation avec des noeuds d'une surface déformable
for ( int noe = 1 ; noe < = tabnoeud . Taille ( ) ; noe + + )
for ( int no = noe + 1 ; no < = tabnoeud . Taille ( ) ; no + + )
{ Noeud & nne = * tabnoeud ( noe ) ;
Noeud & nno = * tabnoeud ( no ) ;
int di ;
if ( nne . PosiAssemb ( nb_Assemb ) > = nno . PosiAssemb ( nb_Assemb ) )
di = nne . PosiAssemb ( nb_Assemb ) - nno . PosiAssemb ( nb_Assemb )
+ nne . NB_ddl_actif_casAssemb ( nb_Assemb ) ;
else
di = nno . PosiAssemb ( nb_Assemb ) - nne . PosiAssemb ( nb_Assemb )
+ nno . NB_ddl_actif_casAssemb ( nb_Assemb ) ;
if ( di > demi ) demi = di ;
if ( di > maxiPourLeContact ) maxiPourLeContact = di ;
if ( 2 * di > total ) total = 2 * di ;
} ;
cumule + = maxiPourLeContact ;
} ;
} ;
total + = 1 ;
demi + = 1 ;
tempsContact . Arret_du_comptage ( ) ; // fin cpu
}
# ifdef UTILISATION_MPI
temps_transfert_court . Mise_en_route_du_comptage ( ) ; // comptage cpu
// maintenant on va transmettre au cpu 0
// pour cela on va utiliser un conteneur intermédiaire
QuatreEntiers inter_entiers ( demi , total , cumule , retour ) ;
// on transmet les infos au proc 0
mpi : : request reqs1 = ParaGlob : : Monde ( ) - > isend ( 0 , 44 , inter_entiers ) ;
// on attend pas
temps_transfert_court . Arret_du_comptage ( ) ; // fin comptage cpu
}
else // cas du cpu 0
{ // l'objectif ici est de récupérer les infos
tempsContact . Arret_du_comptage ( ) ; // fin cpu
int nb_proc_terminer = 0 ; // permettra de terminer
while ( nb_proc_terminer < ( ParaGlob : : Monde ( ) - > size ( ) - 1 ) ) // gérer par les valeurs de tyfront
{ // on récupère un résultat de cpu i
temps_transfert_court . Mise_en_route_du_comptage ( ) ; // comptage cpu
QuatreEntiers inter_entiers ;
mpi : : request reqs1 = ParaGlob : : Monde ( ) - > irecv ( mpi : : any_source , 44 , inter_entiers ) ;
reqs1 . wait ( ) ; // on attend que le conteneur soit rempli
temps_transfert_court . Arret_du_comptage ( ) ; // fin comptage cpu
tempsContact . Mise_en_route_du_comptage ( ) ; // def deb compt
if ( inter_entiers . un > demi ) demi = inter_entiers . un ;
if ( inter_entiers . deux > total ) total = inter_entiers . deux ;
cumule + = inter_entiers . trois ;
retour = ( retour | | ( ( bool ) inter_entiers . quatre ) ) ;
nb_proc_terminer + + ; // on prend en compte que l'on a récupéré un conteneur
tempsContact . Arret_du_comptage ( ) ;
} ;
} ;
2024-03-24 11:43:58 +01:00
// il faut que tous les proc aient le retour global, car le retour sert dans l'algo général
broadcast ( * ParaGlob : : Monde ( ) , retour , 0 ) ;
2023-12-15 19:17:23 +01:00
# endif
// retour de l'indicateur
2021-09-24 08:24:03 +02:00
return retour ;
} ;
// 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 LesContacts : : Actualisation ( int choix )
2021-09-24 08:24:03 +02:00
{
tempsContact . Mise_en_route_du_comptage ( ) ; // def deb compt
bool retour = false ; // init par défaut
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
int proc_en_cours = ParaGlob : : Monde ( ) - > rank ( ) ;
if ( proc_en_cours ! = 0 )
{
# endif
{
// on boucle sur les elements de contact
int i ;
LaLIST < ElContact > : : iterator iE , iEfin = listContact . end ( ) ;
int niveau_commentaire_lescontacts = Permet_affichage ( ) ;
2023-05-03 17:23:49 +02:00
2023-12-15 19:17:23 +01:00
if ( niveau_commentaire_lescontacts > 4 )
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours < < " : -- LesContacts::Actualisation: choix: " < < choix ;
# else
cout < < " \n -- LesContacts::Actualisation: choix: " < < choix ;
# endif
if ( niveau_commentaire_lescontacts > 4 )
// on va lister les éléments de contact
{
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
< < " : liste des Elcontact avant actualisation (fct du niveau de commentaire des elcontact): " ;
# else
cout < < " \n liste des Elcontact avant actualisation (fct du niveau de commentaire des elcontact): " ;
# endif
LaLIST < ElContact > : : iterator ipp , ippfin = listContact . end ( ) ;
for ( ipp = listContact . begin ( ) ; ipp ! = ippfin ; ipp + + )
{ ( * ipp ) . Affiche ( 2 ) ; } ;
2024-01-30 20:55:48 +01:00
cout < < " fin liste " ;
2023-12-15 19:17:23 +01:00
} ;
2021-09-24 08:24:03 +02:00
2023-12-15 19:17:23 +01:00
for ( i = 1 , iE = listContact . begin ( ) ; iE ! = iEfin ; iE + + , i + + ) //,iden++)
// appel de la fonction d'actualisation de chaque element de contact
if ( ( * iE ) . Actif ( ) ) // on intervient si le contact est déclaré actif
// on intervient également si c'est collant, car il faut quand même actualiser
// le contact,
{ int test = 0 ; // init
{
/* // Si le retour est négatif et que l'élément est actif, cela signifie que l'on ne peut pas calculer le contact
// là on on se contente d'inactiver l'élément
// si le retour == 0: on peut calculer mais on sort de l'élément et même des mitoyens
// là aussi on se contente d'inactiver l'élément
// durant l'actualisation, on peut changer d'élément frontière, du coup l'élément de contact résultant
// peut être égale à un élément déjà existant, et cela va faire double emploi
// dans ce cas précis on ne va pas valider l'actualisation, mais on se contente d'inactiver l'élément
// 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
// retourne:
// 0 : dans le cas ou on ne trouve pas d'intersection, cas d'une intersection qui n'est pas calculable
// 1 : contact ok, sur l'élément
// -1 : contact ok, mais hors de l'élément (là, on a parcouru tous les mitoyens et aucun ne convient
// du coup on utilise l'élément initial pour la projection
// 2 : changement de frontière, et contact ok sur la nouvelle frontière
// NB: sauf pour le cas 0, dans tous les autres cas, les grandeurs locales sont correctement calculées
// c-a-d : la projection, la normale
// en fonction de la méthode de contact, le noeud est ramené éventuellement sur la frontière
*/
test = ( * iE ) . Actualisation ( ) ;
ElContact * test_existance = NULL ;
if ( test = = 2 )
{ // on a changé de frontière, on regarde si l'élément de contact avec la nouvelle frontière n'est pas
//identique à un élément existant
test_existance = Element_contact_deja_present ( iE ) ;
} ;
if ( ( ( test < 0 ) & & ( choix = = 0 ) & & ! ( ( * iE ) . Collant ( ) ) ) // si c'est collant, on maintient le contact arbitrairement sauf si on
// est arrivé sur un élément existant
| | ( test = = 0 ) // ou que l'on ne peut pas calculer une intersection ... ce qui fait que le
// calcul des second membre et raideur ne sera pas possible
)
// on inactive l'element de contact
{ LaLIST < ElContact > : : iterator iiE = iE ;
if ( niveau_commentaire_lescontacts > = 3 )
{
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours < < " : "
# else
cout < < " \n "
# endif
< < " inactivation contact (les_contacts) pour cause de perte de contact: " ;
# ifdef MISE_AU_POINT
if ( niveau_commentaire_lescontacts > 4 )
cout < < " test= " < < test ;
# endif
2023-05-03 17:23:49 +02:00
2023-12-15 19:17:23 +01:00
( * iiE ) . Affiche ( 1 ) ;
} ;
( * iiE ) . Met_Inactif ( ) ; // inactive l'élément
retour = true ; // on signale le changement
}
else if ( test_existance ! = NULL )
2024-01-30 20:55:48 +01:00
// cas où test est forcément == 2 (car on a calculé test_existance) et on est arrivé sur un élément existant qui est actif
2023-12-15 19:17:23 +01:00
// on inactive l'element de contact
{ if ( test_existance - > Actif ( ) )
{ LaLIST < ElContact > : : iterator iiE = iE ;
if ( niveau_commentaire_lescontacts > = 3 )
{
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours < < " : "
# else
cout < < " \n "
# endif
< < " inactivation contact apres chgt de frontiere (les_contacts) pour cause de duplication: " ;
( * iiE ) . Affiche ( 1 ) ;
2023-05-03 17:23:49 +02:00
} ;
2023-12-15 19:17:23 +01:00
( * iiE ) . Met_Inactif ( ) ; // inactive l'élément
retour = true ; // on signale le changement
} ;
}
else // arrivée ici cela veut dire que test > 0 ou que c'est collant et test n'est pas négatif
// ou alors que test < 0 mais on a choix == 1, c-a-d que l'on veut maintenir le contact même en dehors de l'élément actuel
// (c'est par exemple une situation transitoire pendant les itérations en implicite)
{ if ( niveau_commentaire_lescontacts > = 7 )
2024-01-30 20:55:48 +01:00
{
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours < < " : "
# else
cout < < " \n "
# endif
< < " contact maintenu: " ; ( * iE ) . Affiche ( 1 ) ;
2024-01-30 20:55:48 +01:00
} ;
2023-12-15 19:17:23 +01:00
} ;
// si on a inactivé l'élément, on regarde s'il n'y a pas un autre contact, utilisant le même noeud
// que l'on pourrait activer
if ( ! ( * iE ) . Actif ( ) )
{ Noeud * noe = ( * iE ) . Esclave ( ) ;
int num_mail_noe_esclave = noe - > Num_Mail ( ) ;
std : : map < Noeud * , LaLIST < LaLIST < ElContact > : : iterator > > & tesN_encontact_ii
= tesN_encontact ( num_mail_noe_esclave ) ; // pour simplifier
// la liste doit exister ! car au moins (*iE) y appartient
// Tableau < std::map<Noeud*,LaLIST < LaLIST<ElContact>::iterator > > > tesN_encontact;
// tesN_encontact(numMail_esclave)[*pt_noeud] -> la liste des iterators d'élément en contact
// avec le noeud
// on regarde si la liste existe, si oui on peut tester les membres sinon, on ne fait rien
// car autrement on crée automatiquement une liste avec un élément vide
std : : map < Noeud * , LaLIST < LaLIST < ElContact > : : iterator > > : : iterator it_liste ;
if ( tesN_encontact_ii . find ( noe ) ! = tesN_encontact_ii . end ( ) )
{ LaLIST < LaLIST < ElContact > : : iterator > & list_tesN = tesN_encontact_ii [ noe ] ;
LaLIST < LaLIST < ElContact > : : iterator > : : iterator pl , plfin = list_tesN . end ( ) ;
for ( pl = list_tesN . begin ( ) ; pl ! = plfin ; pl + + )
2024-01-30 20:55:48 +01:00
if ( ( * pl ) ! = iE ) // on évite celui qu'on vient d'inactiver !!
2023-12-15 19:17:23 +01:00
{ ElContact & elc = ( * ( * pl ) ) ;
2024-01-30 20:55:48 +01:00
// on ne continue que si l'élément est inactif, sinon il est étudié dans la boucle globale
if ( ! ( elc . Actif ( ) ) )
{ // là on va faire une actualisation simplifiée: le cas collant n'est pas à prendre en compte
// car on n'arrive jamais ici en collant
elc . Met_actif ( ) ; // on doit activer l'élément pour utiliser Actualisation
// cela veut dire que systématiquement on calcule comme si le noeud esclave se déplace en contact
// (ce n'est pas une initialisation )
test = elc . Actualisation ( ) ;
test_existance = NULL ; // init
if ( test = = 2 )
{ // on a changé de frontière, on regarde si l'élément de contact avec la nouvelle frontière n'est pas
//identique à un élément existant
test_existance = Element_contact_deja_present ( iE ) ;
} ;
if ( ( test_existance = = NULL ) & & ( test > 0 ) )
// arrivée ici cela veut dire que le contact est valide
// on conserve l'élément actif
{ if ( niveau_commentaire_lescontacts > 2 )
{
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours < < " : "
# else
cout < < " \n "
# endif
< < " reactivation contact : " ; elc . Affiche ( 1 ) ;
} ;
}
else // sinon on inactive l'élément pour le ramener à l'état initial
{ elc . Met_Inactif ( ) ;
if ( elc . Permet_affichage ( ) > 2 )
cout < < " ===>> inactivation car element doublon " ;
} ;
2023-12-15 19:17:23 +01:00
} ;
} ;
} ;
}
2023-05-03 17:23:49 +02:00
} ;
2023-12-15 19:17:23 +01:00
}
// else
// {nb_contact_actif++; }; // on sauvegarde l'activité
if ( niveau_commentaire_lescontacts > 4 )
// on va lister les éléments de contact
{
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours < < " : "
# else
cout < < " \n "
# endif
< < " liste des Elcontact apres actualisation (fct du niveau de commentaire des elcontact): " ;
LaLIST < ElContact > : : iterator ipp , ippfin = listContact . end ( ) ;
for ( ipp = listContact . begin ( ) ; ipp ! = ippfin ; ipp + + )
{ ( * ipp ) . Affiche ( 2 ) ; } ;
2024-01-30 20:55:48 +01:00
cout < < " fin liste " ;
2023-12-15 19:17:23 +01:00
// on calcule et affiche le nombre de contact actif
Calcul_Nb_contact_actif ( ) ;
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours < < " : "
# else
cout < < " \n "
# endif
< < " nb_contact_actif= " < < nb_contact_actif < < endl ;
} ;
}
# ifdef UTILISATION_MPI
temps_transfert_court . Mise_en_route_du_comptage ( ) ; // comptage cpu
// maintenant on va transmettre au cpu 0
mpi : : request reqs1 = ParaGlob : : Monde ( ) - > isend ( 0 , 45 , retour ) ;
// on attend pas
temps_transfert_court . Arret_du_comptage ( ) ; // fin comptage cpu
}
else // cas du cpu 0
{ // l'objectif ici est de récupérer les infos
tempsContact . Arret_du_comptage ( ) ; // fin cpu
int nb_proc_terminer = 0 ; // permettra de terminer
while ( nb_proc_terminer < ( ParaGlob : : Monde ( ) - > size ( ) - 1 ) ) // gérer par les valeurs de tyfront
{ // on récupère un résultat de cpu i
temps_transfert_court . Mise_en_route_du_comptage ( ) ; // comptage cpu
bool inter_retour ;
mpi : : request reqs1 = ParaGlob : : Monde ( ) - > irecv ( mpi : : any_source , 45 , inter_retour ) ;
reqs1 . wait ( ) ; // on attend que le conteneur soit rempli
temps_transfert_court . Arret_du_comptage ( ) ; // fin comptage cpu
tempsContact . Mise_en_route_du_comptage ( ) ; // def deb compt
retour = ( retour | | ( inter_retour ) ) ;
nb_proc_terminer + + ; // on prend en compte que l'on a récupéré un conteneur
tempsContact . Arret_du_comptage ( ) ;
} ;
} ;
# endif
2024-03-24 11:43:58 +01:00
# ifdef UTILISATION_MPI
// il faut que tous les proc aient le retour global, car le retour sert dans l'algo général
broadcast ( * ParaGlob : : Monde ( ) , retour , 0 ) ;
# endif
2023-05-03 17:23:49 +02:00
2021-09-24 08:24:03 +02:00
// retour
tempsContact . Arret_du_comptage ( ) ; // fin cpu
2023-05-03 17:23:49 +02:00
return retour ;
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
2023-12-15 19:17:23 +01:00
// dans le cas d'un calcul // chaque proc i calcule une liste et la transmet au proc 0
// Le proc 0 globalise toutes les liste
2021-09-24 08:24:03 +02:00
void LesContacts : : Liste_noeuds_position_changer ( list < Noeud * > & li_noe )
{ tempsContact . Mise_en_route_du_comptage ( ) ; // def deb compt
// récup du type de contact
int contact_type = ElContact : : Recup_et_mise_a_jour_type_contact ( ) ;
li_noe . clear ( ) ; // on vide la liste
2023-12-15 19:17:23 +01:00
int niveau_commentaire_lescontacts = Permet_affichage ( ) ;
# ifdef UTILISATION_MPI
int proc_en_cours = ParaGlob : : Monde ( ) - > rank ( ) ;
if ( proc_en_cours ! = 0 )
{
# endif
{
if ( contact_type = = 4 ) // pour l'instant c'est le seul type de contact qui est concerné
{ // on boucle sur les elements de contact
int i ;
LaLIST < ElContact > : : iterator iE , iEfin = listContact . end ( ) ;
# ifndef UTILISATION_MPI
if ( niveau_commentaire_lescontacts > = 7 )
cout < < " \n -- LesContacts::Liste_noeuds_position_changer: " ;
# endif
for ( i = 1 , iE = listContact . begin ( ) ; iE ! = iEfin ; iE + + , i + + ) //,iden++)
if ( ( * iE ) . Actif ( ) ) // on intervient si le contact est déclaré actif
{ // récup du noeud esclave
Noeud * noe = ( * iE ) . Esclave ( ) ;
li_noe . push_back ( noe ) ;
} ;
} ;
2024-01-30 20:55:48 +01:00
tempsContact . Arret_du_comptage ( ) ; // fin cpu
2023-12-15 19:17:23 +01:00
}
# ifdef UTILISATION_MPI
temps_transfert_court . Mise_en_route_du_comptage ( ) ; // comptage cpu
// maintenant on va transmettre au cpu 0
int taille_list = li_noe . size ( ) ;
mpi : : request reqs1 = ParaGlob : : Monde ( ) - > isend ( 0 , 46 , taille_list ) ;
// on attend pas
temps_transfert_court . Arret_du_comptage ( ) ; // fin comptage cpu
temps_transfert_long . Mise_en_route_du_comptage ( ) ; // comptage cpu
// maintenant on va transmettre au cpu 0
// on va se servir d'un conteneur intermédiaire
union double_int
{ double x ;
int n [ 2 ] ;
} ;
double_int xinter ;
Vecteur v_inter ( taille_list ) ;
list < Noeud * > : : iterator il , ilfin = li_noe . end ( ) ;
int i = 1 ;
for ( il = li_noe . begin ( ) ; il ! = ilfin ; il + + , i + + )
{ xinter . n [ 0 ] = ( * il ) - > Num_Mail ( ) ; xinter . n [ 1 ] = ( * il ) - > Num_noeud ( ) ;
v_inter ( i ) = xinter . x ;
} ;
// envoi
v_inter . Ienvoi_MPI ( 0 , 47 ) ;
// on attend pas
temps_transfert_long . Arret_du_comptage ( ) ; // fin comptage cpu
}
else // cas du cpu 0
{ // l'objectif ici est de récupérer les infos
union double_int
{ double x ;
int n [ 2 ] ;
} ;
double_int xinter ;
int nb_proc_terminer = 0 ; // permettra de terminer
while ( nb_proc_terminer < ( ParaGlob : : Monde ( ) - > size ( ) - 1 ) ) // gérer par les valeurs de tyfront
{ // on récupère un résultat de cpu i
temps_transfert_court . Mise_en_route_du_comptage ( ) ; // comptage cpu
int taille_list ;
mpi : : request reqs1 = ParaGlob : : Monde ( ) - > irecv ( mpi : : any_source , 46 , taille_list ) ;
mpi : : status stat = reqs1 . wait ( ) ; // on attend que le conteneur soit rempli
int source = stat . source ( ) ; // récupération du numéro de la source
temps_transfert_court . Arret_du_comptage ( ) ; // fin comptage cpu
temps_transfert_long . Mise_en_route_du_comptage ( ) ; // comptage cpu
Vecteur v_inter ( taille_list ) ;
mpi : : request reqs2 = v_inter . Irecup_MPI ( source , 47 ) ;
reqs2 . wait ( ) ; // on attend que le conteneur soit rempli
temps_transfert_long . Arret_du_comptage ( ) ; // fin comptage cpu
tempsContact . Mise_en_route_du_comptage ( ) ; // def deb compt
// maintenant on abonde la liste
for ( int i = 1 ; i < = taille_list ; i + + )
{ xinter . x = v_inter ( i ) ;
li_noe . push_back ( & ( lesMaille - > Noeud_LesMaille ( xinter . n [ 0 ] , xinter . n [ 1 ] ) ) ) ;
} ;
nb_proc_terminer + + ; // on prend en compte que l'on a récupéré un conteneur
tempsContact . Arret_du_comptage ( ) ;
} ;
if ( niveau_commentaire_lescontacts > = 7 )
cout < < " \n proc 0: -- LesContacts::Liste_noeuds_position_changer: " ;
} ;
# endif
2021-09-24 08:24:03 +02:00
tempsContact . Arret_du_comptage ( ) ; // fin cpu
} ;
// calcul des reactions de contact et stockage des valeurs
// solution : le vecteur residu
// test d'un decollement eventuelle, pour un noeud en contact
2024-01-30 20:55:48 +01:00
// Dans le cas d'un calcul parallèle, tous les cpu calculent, mais seule le cpu 0
// affiche les messages normaux, mais tous les cpu affichent les messages d'erreur éventuels
// et les messages pour les niveaux de commentaires > 4
2021-09-24 08:24:03 +02:00
void LesContacts : : CalculReaction ( Vecteur & residu , bool & decol , const Nb_assemb & casAssemb
, bool affiche )
{
tempsContact . Mise_en_route_du_comptage ( ) ; // def deb compt
2024-01-30 20:55:48 +01:00
# ifdef UTILISATION_MPI
int proc_en_cours = ParaGlob : : Monde ( ) - > rank ( ) ;
# endif
2023-05-03 17:23:49 +02:00
int niveau_commentaire_lescontacts = Permet_affichage ( ) ;
2024-01-30 20:55:48 +01:00
# ifdef UTILISATION_MPI
if ( proc_en_cours = = 0 )
# endif
if ( niveau_commentaire_lescontacts > 4 )
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
# endif
< < " -- LesContacts::CalculReaction: \n " ;
2021-09-24 08:24:03 +02:00
int nb_Assemb = casAssemb . n ; // récup du numéro d'assemblage
// récup du type de contact
int contact_type = ElContact : : Recup_et_mise_a_jour_type_contact ( ) ;
// mise a dimension du tableau de stockage
// tabReacCont.Change_taille((int)listContact.size());
// on recalcule le nombre de contact actif car c'est mal géré, je ne sais pas pourquoi et ou
2023-05-03 17:23:49 +02:00
Calcul_Nb_contact_actif ( ) ;
2021-09-24 08:24:03 +02:00
tabReacCont . Change_taille ( nb_contact_actif ) ;
int itab ; // indice du tableau
decol = false ;
bool axi = false ; // cas particulier de l'axi
if ( ParaGlob : : AxiSymetrie ( ) )
axi = true ;
LaLIST < ElContact > : : iterator iE , iEfin = listContact . end ( ) ;
// on boucle sur les elements de contact
for ( itab = 1 , iE = listContact . begin ( ) ; iE ! = iEfin ; iE + + )
{ if ( ( * iE ) . Actif ( ) )
{ Noeud * noe = ( * iE ) . Esclave ( ) ; // le noeud esclave
int posi = noe - > Pointeur_assemblage ( X1 , nb_Assemb ) ; // position du ddl X1
# ifdef MISE_AU_POINT
if ( posi = = - 1 )
2024-01-30 20:55:48 +01:00
{
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
# endif
< < " Erreur : ddl X1 "
2021-09-24 08:24:03 +02:00
< < " inexistant pour le cas de charge " < < nb_Assemb < < ' \n '
< < " LesContacts::CalculReaction( (1) \n " ;
tempsContact . Arret_du_comptage ( ) ; // fin cpu
Sortie ( 1 ) ;
} ;
# endif
int dim = noe - > Dimension ( ) ; // dimension
// dans le cas où on est en axi-symétrie, le vecteur réaction est en 2D car le calcul au niveau de l'équilibre
// global n'est fait qu'en x et y
// donc on ne peut récupérer que du x et du y
int nb_ddl_en_var = dim ; // init
if ( axi )
nb_ddl_en_var - = 1 ;
Coordonnee force ( dim ) ; // on dimensionne à dim au cas où
for ( int i = 1 ; i < = nb_ddl_en_var ; i + + )
// je crois qu'il faut un - pour la force (??) 20 avril 2018
force ( i ) = - residu ( posi + i - 1 ) ; // si le type de contact est de type 1 -> c'est la réaction
if ( ( contact_type = = 1 ) | | ( contact_type = = 3 ) )
( * iE ) . Change_force ( force ) ; // mise à jour de la force dans l'élément de contact
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > 5 )
2021-09-24 08:24:03 +02:00
{ if ( ( contact_type = = 1 ) | | ( contact_type = = 3 ) )
{ cout < < " \n LesContacts::CalculReaction >> Details: residu totale = contact + CL + F_int (noeud: " < < noe - > Num_noeud ( )
< < " maillage: " < < noe - > Num_Mail ( ) < < " ) \n R= " < < force < < " gapTDT= " < < ( * iE ) . Gaptdt ( )
< < " \n dont F_contact= " < < ( * iE ) . Force_contact ( ) ;
cout < < " \n noeud: coor_tdt: " < < noe - > Coord2 ( ) < < " \n delta: " < < ( noe - > Coord2 ( ) - noe - > Coord1 ( ) ) ;
}
else if ( ( contact_type = = 2 ) | | ( contact_type = = 4 ) | | ( contact_type = = 41 ) | | ( contact_type = = 42 ) )
{ cout < < " \n LesContacts::CalculReaction >> Details: F_contact (noeud: " < < noe - > Num_noeud ( )
// 19 juin 2018 << " maillage:"<< noe->Num_Mail() << ")\nF=" << force << " gapTDT= " << (*iE).Gaptdt() ;
< < " maillage: " < < noe - > Num_Mail ( ) < < " ) \n Force= " < < ( * iE ) . Force_contact ( )
< < " gapTDT= " < < ( * iE ) . Gaptdt ( ) ;
cout < < " \n noeud: coor_tdt: " < < noe - > Coord2 ( ) < < " \n delta: " < < ( noe - > Coord2 ( ) - noe - > Coord1 ( ) ) ;
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > 7 )
2021-09-24 08:24:03 +02:00
( * iE ) . Affiche ( ) ;
}
else { cout < < " \n *** erreur, cas de type de contact= " < < contact_type < < " pas encore pris en compte " ;
tempsContact . Arret_du_comptage ( ) ; // fin cpu
Sortie ( 1 ) ;
} ;
} ;
// on regarde si le noeud decolle
if ( ( * iE ) . Decol ( ) ) decol = true ;
// puis les noeuds de l'element maitre
//!!!!! il faudra prevoir un cas ou on ne sauvegarde pas les maitres
Tableau < Noeud * > & tabNoeud = ( * iE ) . Elfront ( ) - > Eleme ( ) - > TabNoeud ( ) ; // le tableau
// on cree un tableau de sauvegarde des forces
int tail = tabNoeud . Taille ( ) ;
// Dans le cas du type 1 de contact, c'est le retour du résidu qui permet de construire des
// réaction, alors que dans le cas du type 2 c'est au contraire dans l'élément de contact
// que les grandeurs ont déjà été calculées
if ( ( contact_type = = 1 ) | | ( contact_type = = 3 ) )
{ Coordonnee ex ( dim ) ; // une position à la bonne dimmension
Tableau < Coordonnee > tabForce ( tail , ex ) ; // dimmensionnement du tableau avec alocation
for ( int it = 1 ; it < = tail ; it + + )
{ posi = tabNoeud ( it ) - > Pointeur_assemblage ( X1 , nb_Assemb ) ; // position du ddl X1
# ifdef MISE_AU_POINT
if ( posi = = - 1 )
2024-01-30 20:55:48 +01:00
{
# ifdef UTILISATION_MPI
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
# endif
< < " Erreur : ddl X1 "
2021-09-24 08:24:03 +02:00
< < " inexistant pour le cas de charge " < < nb_Assemb < < ' \n '
< < " LesContacts::CalculReaction( (2) \n " ;
tempsContact . Arret_du_comptage ( ) ; // fin cpu
Sortie ( 1 ) ;
} ;
# endif
for ( int i = 1 ; i < = nb_ddl_en_var ; i + + )
tabForce ( it ) ( i ) = residu ( posi + i - 1 ) ; // la reaction
} ;
tabReacCont ( itab ) = ReactCont ( noe , force , tabNoeud , tabForce ) ;
}
else
{ tabReacCont ( itab ) = ReactCont ( noe , ( * iE ) . Force_contact ( ) , tabNoeud , ( * iE ) . TabForce_cont ( ) ) ;
} ;
itab + + ;
} ;
} ;
// affichage éventuelle de la force maxi de contact
2024-03-24 11:43:58 +01:00
Forces_contact_maxi ( affiche ) ;
// idem pour les gap N et T
Gap_contact_maxi ( affiche ) ;
2021-09-24 08:24:03 +02:00
tempsContact . Arret_du_comptage ( ) ; // fin cpu
} ;
// affichage des reactions de contact sur la sortie
2024-01-30 20:55:48 +01:00
// il s'agit ici d'une sortie sur fichier : seule le cpu 0 l'effectue
2021-09-24 08:24:03 +02:00
void LesContacts : : Affiche ( ofstream & sort ) const
2024-01-30 20:55:48 +01:00
{
# ifdef UTILISATION_MPI
int proc_en_cours = ParaGlob : : Monde ( ) - > rank ( ) ;
if ( proc_en_cours = = 0 )
# endif
// on balaie le tableau de reaction
2021-09-24 08:24:03 +02:00
for ( int i = 1 ; i < = tabReacCont . Taille ( ) ; i + + )
{ ReactCont & R = tabReacCont ( i ) ;
sort < < " \n ================= noeud esclave ================== " ;
sort < < " \n maillage " < < ( R . noe ) - > Num_Mail ( )
< < " , noeud " < < ( R . noe ) - > Num_noeud ( )
< < " , force = " < < R . force ;
sort < < " \n ---------------- noeuds de la frontiere maitre ------------- " ;
int tail = R . tabNoeud . Taille ( ) ;
for ( int it = 1 ; it < = tail ; it + + )
{ Noeud & no = * ( R . tabNoeud ( it ) ) ;
Coordonnee & coor = R . tabForce ( it ) ;
sort < < " \n maillage " < < no . Num_Mail ( )
< < " , noeud " < < no . Num_noeud ( )
< < " , force = " < < coor < < " , de norme = " < < coor . Vect ( ) . Norme ( ) ;
} ;
} ;
} ;
// affichage à l'écran des informations liées au contact
2024-01-30 20:55:48 +01:00
// cas d'un calcul parallèle, on considère qu'il s'agit d'un affichage volontaire
// donc tous les cpu peuvent l'utiliser: on affiche en + le num du cpu
2021-09-24 08:24:03 +02:00
void LesContacts : : Affiche ( ) const
2023-12-15 19:17:23 +01:00
{
# ifdef UTILISATION_MPI
int proc_en_cours = ParaGlob : : Monde ( ) - > rank ( ) ;
2024-01-30 20:55:48 +01:00
cout < < " \n proc " < < proc_en_cours
# else
cout < < " \n "
2023-12-15 19:17:23 +01:00
# endif
< < " \n ---- affichage des informations liees au contact -------- " ;
2021-09-24 08:24:03 +02:00
cout < < " \n 1) liste des elements en contact " ;
LaLIST < ElContact > : : const_iterator il , ilfin = listContact . end ( ) ;
for ( il = listContact . begin ( ) ; il ! = ilfin ; il + + )
( * il ) . Affiche ( ) ;
cout < < " \n 2) reactions aux contact " ;
// on balaie le tableau de reaction
for ( int i = 1 ; i < = tabReacCont . Taille ( ) ; i + + )
{ ReactCont & R = tabReacCont ( i ) ;
cout < < " \n ================= noeud esclave ================== " ;
cout < < " \n maillage " < < ( R . noe ) - > Num_Mail ( )
< < " , noeud " < < ( R . noe ) - > Num_noeud ( )
< < " , force = " < < R . force ;
cout < < " \n ---------------- noeuds de la frontiere maitre ------------- " ;
int tail = R . tabNoeud . Taille ( ) ;
for ( int it = 1 ; it < = tail ; it + + )
{ Noeud & no = * ( R . tabNoeud ( it ) ) ;
Coordonnee & coor = R . tabForce ( i ) ;
cout < < " \n maillage " < < no . Num_Mail ( )
< < " , noeud " < < no . Num_noeud ( )
< < " , force = " < < coor < < " , de norme = " < < coor . Vect ( ) . Norme ( ) ;
} ;
} ;
cout < < " \n 3) liste des references de zones succeptibles d'entrer en contact " ;
2023-09-03 10:10:17 +02:00
list < Quatre_string_un_entier > : : const_iterator ill , illfin = nom_ref_zone_contact . end ( ) ;
2021-09-24 08:24:03 +02:00
cout < < " \n " ;
for ( ill = nom_ref_zone_contact . begin ( ) ; ill ! = illfin ; ill + + )
{ if ( ( * ill ) . nom1 . length ( ) ) cout < < " mail= " < < ( * ill ) . nom1 < < " " ;
cout < < " ref de noeud esclave: " < < ( * ill ) . nom2 ;
if ( ( * ill ) . n = = 1 )
cout < < " (contact collant) " ;
cout < < " , " ;
if ( ( * ill ) . nom3 . length ( ) ) cout < < " mail= " < < ( * ill ) . nom3 < < " " ;
cout < < " ref des frontieres maitres : " < < ( * ill ) . nom4 ;
} ;
} ;
// affichage et definition interactive des commandes
void LesContacts : : Info_commande_LesContacts ( UtilLecture & entreePrinc )
2023-12-15 19:17:23 +01:00
{
# ifdef UTILISATION_MPI
cout < < " \n *** erreur , la methode LesContacts::Info_commande_LesContacts "
< < " n'est pas utilisable en exécution MPI !!! " ;
Sortie ( 1 ) ;
# endif
ofstream & sort = * ( entreePrinc . Commande_pointInfo ( ) ) ; // pour simplifier
2021-09-24 08:24:03 +02:00
//On va proposer un menu
string rep = " " ;
sort < < " \n # --- les contact ------- " ;
while ( ( Minuscules ( rep ) ! = " f " ) & & ( Minuscules ( rep ) ! = " 0 " ) )
{
try
{
cout < < " \n -- definition de : --- "
< < " \n (0 ou f) (fin) "
< < " \n (1) auto_contact "
< < " \n (2) zone particuliere de contact "
< < " \n (3) contact solide-deformable "
< < " \n (4) contact collant "
< < " \n (5) contact collant avec suppression du gap "
< < " \n (6 ou ? ) informations "
< < " \n " ;
// procédure de lecture avec prise en charge d'un retour chariot
rep = lect_return_defaut ( false , " f " ) ;
if ( ( Minuscules ( rep ) = = " f " ) | | ( Minuscules ( rep ) = = " 0 " ) ) // sortie directe
break ;
int num = ChangeEntier ( rep ) ;
if ( Minuscules ( rep ) = = " ? " )
num = 6 ;
bool choix_valide = false ;
if ( ( num > = 0 ) & & ( num < = 6 ) )
{ choix_valide = true ; }
else { cout < < " \n Erreur on attendait un entier entre 0 et 6 !!, "
< < " \n redonnez une bonne valeur "
< < " \n ou taper f ou 0 pour arreter le programme " ;
choix_valide = false ;
}
string grandeur = " " ; // init
switch ( num )
{ case 0 : // sortie
{ break ; } // normalement cela a déjà été filtré avant
case 1 : // auto_contact
{ sort < < " \n auto_contact \n " ;
sort < < " \n #-------------------------------------------------------------------------------- " ;
sort < < " \n # definition du nombre de domaine esclave en auto-contat | " ;
sort < < " \n #-------------------------------------------------------------------------------- " ;
cout < < " \n nombre de maillage en autocontact (un entier) ? " ;
string nb_str ;
//int nb =0;
nb_str = ( int ) lect_double ( ) ;
if ( ( Minuscules ( nb_str ) = = " f " ) | | ( Minuscules ( nb_str ) = = " 0 " ) ) // sortie directe
break ;
int nb = ChangeEntier ( nb_str ) ;
cout < < " nom lu = " < < nb_str < < " c-a-d le nombre " < < nb ;
sort < < " \n " < < nb < < endl ;
break ;
}
case 2 : // zone particuliere de contact
{ cout < < " \n def d'une ref de noeuds esclave " ;
string nom_mail1 = " " ;
cout < < " \n nom du maillage ? " ;
nom_mail1 = lect_chaine ( ) ; cout < < " nom lu = " < < nom_mail1 ;
cout < < " \n nom de la reference de noeud ? " ;
string nom_ref = " " ;
nom_ref = lect_chaine ( ) ; cout < < " nom lu = " < < nom_ref ;
if ( nom_ref . at ( 0 ) ! = ' N ' )
{ cout < < " \n *** erreur, la premiere lettre de la ref de noeud "
< < " doit etre N et non " < < nom_ref . at ( 0 ) < < " !! " ;
break ;
} ;
cout < < " \n def d'une ref de faces maitres " ;
string nom_mail_face = " " ;
cout < < " \n nom du maillage ? " ;
nom_mail_face = lect_chaine ( ) ; cout < < " nom lu = " < < nom_mail_face ;
cout < < " \n nom de la reference de face ? " ;
string nom_ref_face = " " ;
nom_ref_face = lect_chaine ( ) ; cout < < " nom lu = " < < nom_ref_face ;
if ( nom_ref_face . at ( 0 ) ! = ' F ' )
{ cout < < " \n *** erreur, la premiere lettre de la ref de face "
< < " doit etre F et non " < < nom_ref_face . at ( 0 ) < < " !! " ;
break ;
} ;
sort < < " \n \n zone_contact #------------- " ;
sort < < " \n #---------------------------------------------------- "
< < " \n # ref noeuds | ref face | "
< < " \n #---------------------------------------------------- " ;
sort < < " \n nom_mail= " < < nom_mail1 < < " " < < nom_ref < < " "
< < " nom_mail= " < < nom_mail_face < < " " < < nom_ref_face < < endl ;
break ;
}
case 3 : // contact solide-deformable
{ cout < < " \n def de contact de type solide-deformable " ;
sort < < " \n \n contact_solide_deformable #------------- " ;
sort < < " \n #---------------------------------------------------- "
< < " \n # maillage solide | maillage deformable | "
< < " \n #---------------------------------------------------- " ;
sort < < " \n debut_liste_des_couples_de_noms_solide_deformable " ;
string nom_mailsolide = " " ;
do {
cout < < " \n nom du maillage considere solide ? (ou f pour finir) " ;
nom_mailsolide = lect_chaine ( ) ; cout < < " nom lu = " < < nom_mailsolide ;
if ( Minuscules ( nom_mailsolide ) = = " f " )
break ;
cout < < " \n nom du maillage considere deformable " ;
string nom_maildeformable = " " ;
cout < < " \n nom du maillage ? " ;
nom_maildeformable = lect_chaine ( ) ; cout < < " nom lu = " < < nom_maildeformable ;
sort < < " \n solide= " < < nom_mailsolide < < " "
< < " deformable= " < < nom_maildeformable < < " " < < endl ;
} while ( Minuscules ( nom_mailsolide ) ! = " f " ) ;
sort < < " \n fin_liste_des_couples_de_noms_solide_deformable " ;
break ;
}
case 4 : case 5 : // zone contact collant
{ cout < < " \n def d'une ref de noeuds esclave " ;
string nom_mail1 = " " ;
cout < < " \n nom du maillage ? " ;
nom_mail1 = lect_chaine ( ) ; cout < < " nom lu = " < < nom_mail1 ;
cout < < " \n nom de la reference de noeud ? " ;
string nom_ref = " " ;
nom_ref = lect_chaine ( ) ; cout < < " nom lu = " < < nom_ref ;
if ( nom_ref . at ( 0 ) ! = ' N ' )
{ cout < < " \n *** erreur, la premiere lettre de la ref de noeud "
< < " doit etre N et non " < < nom_ref . at ( 0 ) < < " !! " ;
break ;
} ;
cout < < " \n def d'une ref de faces maitres " ;
string nom_mail_face = " " ;
cout < < " \n nom du maillage ? " ;
nom_mail_face = lect_chaine ( ) ; cout < < " nom lu = " < < nom_mail_face ;
cout < < " \n nom de la reference de face ? " ;
string nom_ref_face = " " ;
nom_ref_face = lect_chaine ( ) ; cout < < " nom lu = " < < nom_ref_face ;
if ( nom_ref_face . at ( 0 ) ! = ' F ' )
{ cout < < " \n *** erreur, la premiere lettre de la ref de face "
< < " doit etre F et non " < < nom_ref_face . at ( 0 ) < < " !! " ;
break ;
} ;
if ( num = = 4 )
{ sort < < " \n \n glue_contact #------------- " ; }
else { sort < < " \n \n glue_contact_init_gap_zero #------------- " ; } ;
sort < < " \n #---------------------------------------------------- "
< < " \n # ref noeuds | ref face | "
< < " \n #---------------------------------------------------- " ;
sort < < " \n nom_mail= " < < nom_mail1 < < " " < < nom_ref < < " "
< < " nom_mail= " < < nom_mail_face < < " " < < nom_ref_face < < endl ;
break ;
}
case 6 : // information
{ cout < < " \n -- Concernant l'auto-contact, le nombre demande indique "
< < " \n le nombre de maillages en auto-contact, compte parmi les maillages "
< < " \n esclaves, donc doit etre <= au nombre de maillages esclaves ! "
< < " \n -- Concernant les zones de contact, indique les ref de noeuds esclaves "
< < " \n qui doivent etre consideres potentiellement en contact avec les ref "
< < " \n de faces. Si un (ou les deux) des deux mots cles zone_contact et/ou glue_contact "
< < " \n existe, seules les zones definies sont prises en compte. "
< < " \n -- Concernant le contact solide deformable "
< < " \n le maillage indique comme solide doit etre un maillage maitre "
< < " \n ou un maillage en auto-contact "
< < " \n le maillage deformable doit-etre un maillage esclave ou en auto-contact "
< < " \n le noeud en contact du solide deformable est systematiquement deplace "
< < " \n sur la surface du solide deformable, cette condition se substitue donc "
< < " \n a une condition de penalisation si celle-ci est en oeuvre "
< < " \n -- Concernant les zones de contact collant, indique les ref de noeuds esclaves "
< < " \n qui seront imposes en contact avec les ref "
< < " \n de faces. Si un (ou les deux) des deux mots cles zone_contact et/ou glue_contact "
< < " \n existe, seules les zones definies sont prises en compte. "
< < " \n " < < endl ;
}
default :
cout < < " \n le cas " < < rep < < " n'est pas traite !!, bizarre, il faut se plaindre !! " ;
} ;
}
catch ( ErrSortieFinale )
// cas d'une direction voulue vers la sortie
// on relance l'interuption pour le niveau supérieur
{ ErrSortieFinale toto ;
throw ( toto ) ;
}
catch ( . . . ) //(UtilLecture::ErrNouvelleDonnee erreur)
{ cout < < " \n Erreur on attendait un des mots cles proposes !!, "
< < " \n redonnez une bonne valeur "
< < " \n ou taper f ou 0 pour sortir " ;
} ;
} ; //-- fin du while
sort < < flush ;
} ;
// 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 LesContacts : : Lecture_zone_contact ( UtilLecture & entreePrinc , const LesReferences & lesRef )
2023-12-15 19:17:23 +01:00
{
# ifdef UTILISATION_MPI
int proc_en_cours = ParaGlob : : Monde ( ) - > rank ( ) ;
# endif
list < int > li_lissage_de_la_normale ; // stockage intermédiaire pour créer le tableau lissage_de_la_normale
2023-05-03 17:23:49 +02:00
int niveau_commentaire_lescontacts = Permet_affichage ( ) ;
2021-09-24 08:24:03 +02:00
while ( ( strstr ( entreePrinc . tablcar , " auto_contact " ) ! = NULL )
| | ( strstr ( entreePrinc . tablcar , " zone_contact " ) ! = NULL )
| | ( strstr ( entreePrinc . tablcar , " contact_solide_deformable " ) ! = NULL )
| | ( strstr ( entreePrinc . tablcar , " glue_contact " ) ! = NULL )
| | ( strstr ( entreePrinc . tablcar , " glue_contact_init_gap_zero " ) ! = NULL )
)
2023-05-03 17:23:49 +02:00
{ // on regarde si la zone de contact est avec lissage de la normale
int avec_lissage_de_la_normale = 0 ;
if ( strstr ( entreePrinc . tablcar , " avec_lissage_de_la_normale " ) ! = NULL )
avec_lissage_de_la_normale = 1 ;
2021-09-24 08:24:03 +02:00
// --- on examine le cas où il y a un marquage d'auto-contact
if ( strstr ( entreePrinc . tablcar , " auto_contact " ) ! = NULL )
// cas ou l'on a des domaines esclaves en auto-contact, lecture du nombre
{ entreePrinc . NouvelleDonnee ( ) ;
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > = 4 )
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
if ( proc_en_cours = = 0 )
# endif
2021-09-24 08:24:03 +02:00
cout < < " lecture du nombre de domaines esclaves en auto-contact " < < endl ;
* ( entreePrinc . entree ) > > nbmailautocontact ; // lecture du nombre
2023-05-03 17:23:49 +02:00
if ( niveau_commentaire_lescontacts > = 5 ) cout < < nbmailautocontact < < endl ;
if ( niveau_commentaire_lescontacts > = 4 )
2023-12-15 19:17:23 +01:00
# ifdef UTILISATION_MPI
if ( proc_en_cours = = 0 )
# endif
2024-01-30 20:55:48 +01:00
cout < < " fin de la lecture du nombre de domaines esclaves en auto-contact " < < endl ;
2021-09-24 08:24:03 +02:00
entreePrinc . NouvelleDonnee ( ) ; // positionnement sur une nouvelle info
} ;
// --- cas des zones particulières de contact
if ( ( strstr ( entreePrinc . tablcar , " zone_contact " ) ! = NULL )
| | ( strstr ( entreePrinc . tablcar , " glue_contact " ) ! = NULL )
| | ( strstr ( entreePrinc . tablcar , " glue_contact_init_gap_zero " ) ! = NULL )
)
{
int indic_glue = 0 ; // init de non glue a priori
if ( strstr ( entreePrinc . tablcar , " glue_contact_init_gap_zero " ) ! = NULL )
{ indic_glue = 2 ; } // cas particulier d'un contact collant avec suppression du gap
else if ( strstr ( entreePrinc . tablcar , " glue_contact " ) ! = NULL )
{ indic_glue = 1 ; } // cas particulier d'un contact collant
// lecture tant qu'il n'y a pas de nouveau mot clé
entreePrinc . NouvelleDonnee ( ) ;
2023-12-15 19:17:23 +01:00
if ( niveau_commentaire_lescontacts > = 4 )
# ifdef UTILISATION_MPI
if ( proc_en_cours = = 0 )
# endif
cout < < " debut de la lecture des zones de contact possibles " < < endl ;
2021-09-24 08:24:03 +02:00
while ( ! motCle . SimotCle ( entreePrinc . tablcar ) )
{ // on lit 2 par deux: une ref de noeud + une ref de frontière
2023-09-03 10:10:17 +02:00
Quatre_string_un_entier quatre_inter ; // une grandeur de travail
2021-09-24 08:24:03 +02:00
quatre_inter . n = indic_glue ; // on stocke la glue éventuelle
for ( int nr = 1 ; nr < = 2 ; nr + + )
{ // on commence par regarder si le nom du maillage est définit pour la référence
string nom_ref ; // variables de travail
string * nom_mail = NULL ; string nom ( " " ) ;
if ( strstr ( entreePrinc . tablcar , " nom_mail= " ) ! = NULL )
{ * ( entreePrinc . entree ) > > nom > > nom ; nom_mail = & nom ; }
// lecture du nom d'une référence
* ( entreePrinc . entree ) > > nom_ref ;
# ifdef ENLINUX
if ( ( entreePrinc . entree ) - > rdstate ( ) = = 0 )
# else
if ( ( ( entreePrinc . entree ) - > rdstate ( ) = = 0 ) | | ( ( entreePrinc . entree ) - > eof ( ) ) )
# endif
// pour mémoire ici on a
/* enum io_state
{ badbit = 1 < < 0 , // -> 1 dans rdstate()
eofbit = 1 < < 1 , // -> 2
failbit = 1 < < 2 , // -> 4
goodbit = 0 // -> O
} ; */
// lecture normale, vérification que la référence existe bien
2023-12-15 19:17:23 +01:00
{
if ( ! ( lesRef . Existe ( nom_ref , nom_mail ) ) )
2024-01-30 20:55:48 +01:00
{
# ifdef UTILISATION_MPI
if ( proc_en_cours = = 0 )
# endif
cout < < " \n erreur le nom de reference de zone de contact : " < < nom_ref
2021-09-24 08:24:03 +02:00
< < " , n'existe pas !! "
< < " \n LesContacts::Lecture_zone_contact(.. " ;
throw ( UtilLecture : : ErrNouvelleDonnee ( - 1 ) ) ;
Sortie ( 1 ) ;
}
else // enregistrement du nom de référence
{ if ( nr = = 1 )
// premier passage on stocke
{ quatre_inter . nom1 = nom ; quatre_inter . nom2 = nom_ref ; }
else // cas du deuxième passage on enregistre
{ quatre_inter . nom3 = nom ; quatre_inter . nom4 = nom_ref ;
nom_ref_zone_contact . push_back ( quatre_inter ) ;
2023-05-03 17:23:49 +02:00
li_lissage_de_la_normale . push_back ( avec_lissage_de_la_normale ) ;
2021-09-24 08:24:03 +02:00
} ;
}
# ifndef ENLINUX
if ( ( entreePrinc . entree ) - > eof ( ) ) // on arrive à la fin de la ligne
entreePrinc . NouvelleDonnee ( ) ; // lecture d'un nouvelle enregistrement
# endif
}
//sinon il y a un pb ou, l'on est à la fin de la ligne et on passe à l'enregistrement suivant
# ifdef ENLINUX
else if ( ( entreePrinc . entree ) - > fail ( ) )
// on a atteind la fin de la ligne et on appelle un nouvel enregistrement
{ entreePrinc . NouvelleDonnee ( ) ; } // lecture d'un nouvelle enregistrement
# endif
else // cas d'une erreur de lecture
2023-12-15 19:17:23 +01:00
{
# ifdef UTILISATION_MPI
if ( proc_en_cours = = 0 )
# endif
{ cout < < " \n erreur de lecture inconnue au niveau des references de zone de contact " ;
entreePrinc . MessageBuffer ( " ** LesContacts::Lecture_zone_contact(.. ** " ) ;
Affiche ( ) ;
throw ( UtilLecture : : ErrNouvelleDonnee ( - 1 ) ) ;
Sortie ( 1 ) ;
} ;
2021-09-24 08:24:03 +02:00
} ;
} ; // -- fin for (int nr=1;nr<=2;nr++)
} ; //-- fin du while (!motCle.SimotCle(entreePrinc.tablcar))
2023-12-15 19:17:23 +01:00
if ( niveau_commentaire_lescontacts > = 4 )
# ifdef UTILISATION_MPI
if ( proc_en_cours = = 0 )
# endif
2024-01-30 20:55:48 +01:00
cout < < " fin de la lecture des zones de contact " < < endl ;
2021-09-24 08:24:03 +02:00
} ;
// --- cas des contacts solide-deformable
if ( strstr ( entreePrinc . tablcar , " contact_solide_deformable " ) ! = NULL )
2023-12-15 19:17:23 +01:00
{ if ( niveau_commentaire_lescontacts > = 4 )
# ifdef UTILISATION_MPI
if ( proc_en_cours = = 0 )
# endif
2024-01-30 20:55:48 +01:00
cout < < " debut de la lecture des contacts solide-deformable " < < endl ;
2021-09-24 08:24:03 +02:00
string toto ; // variables de travail
while ( strstr ( entreePrinc . tablcar , " fin_liste_des_couples_de_noms_solide_deformable " ) = = NULL )
// && (!motCle.SimotCle(entreePrinc.tablcar)))
{ Deux_String ie ; // une variable de travail
* ( entreePrinc . entree ) > > toto > > ie . nom1 > > toto > > ie . nom2 ;
cont_solide_defor . push_back ( ie ) ;
entreePrinc . NouvelleDonnee ( ) ;
} ;
// on passe le mot clé de fin
entreePrinc . NouvelleDonnee ( ) ;
2023-12-15 19:17:23 +01:00
if ( niveau_commentaire_lescontacts > = 4 )
# ifdef UTILISATION_MPI
if ( proc_en_cours = = 0 )
# endif
cout < < " fin de la lecture des contacts solide-deformable " < < endl ;
2021-09-24 08:24:03 +02:00
} ;
} ;
2023-05-03 17:23:49 +02:00
// création du tableau lissage_de_la_normale
int nb_zone_lue = li_lissage_de_la_normale . size ( ) ;
if ( nb_zone_lue ! = 0 )
{ lissage_de_la_normale . Change_taille ( nb_zone_lue ) ; // init
list < int > : : iterator il , ilfin = li_lissage_de_la_normale . end ( ) ;
int iii = 1 ;
for ( il = li_lissage_de_la_normale . begin ( ) ; il ! = ilfin ; il + + , iii + + )
lissage_de_la_normale ( iii ) = ( * il ) ;
}
else // sinon on définie une seule zone et sans lissage
{ lissage_de_la_normale . Change_taille ( 1 ) ; lissage_de_la_normale ( 1 ) = 0 ; } ;
2021-09-24 08:24:03 +02:00
} ;