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