// 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-2021 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" /// @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 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 // const Tableau & ConditionLin(const Nb_assemb& casAssemb); // création d'un tableau 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, const Tableau & 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) 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.) // dans le cas où la réaction est négative, en fonction de l'algorithme l'élément de contact est // inactivé, cependant tous les éléments de contact sont passés en revue (actif ou pas) // ramène true si quelque chose à changé, false sinon bool Actualisation(); // 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) const; // récupération via les éléments de contact des gaps maxis // un : le maxi en gap normal, deux: le maxi en gap tangentiel DeuxDoubles Gap_contact_maxi(bool affiche) const; // 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()const; // 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 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(); //------- temps cpu ----- // retourne temps cumulé pour imposer les CL imposées const Temps_CPU_HZpp& Temps_cpu_Contact() const {return tempsContact;}; //----- 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); // ne sert plus (à virer car problématique !! ) // mise à jour du stockage inter, pour prendre en // compte une nouvelle numérotation des noeuds // void Prise_en_compte_nouvelle_numerotation_noeud(); // 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 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 Tableau tabCoLin; // 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) // 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) // 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 en 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()--- Tableau t_connectionCLL; //------- temps cpu ----- // retourne temps cumulé pour imposer les CL imposées Temps_CPU_HZpp tempsContact; // 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 // normalement devrait toujours être correct mais ?? il y a quelque chose d'incorrecte quelque part int Recalcul_Nb_contact_actif(); // création du conteneur Fct_nD_contact void Creation_Fct_nD_contact(); }; /// @} // 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