// 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: . #include "LesContacts.h" #include #include "ReferenceNE.h" #include "ReferenceAF.h" #include "CharUtil.h" #include "Enum_TypeQuelconque.h" #include "TypeQuelconqueParticulier.h" // récupération des ddl ou des grandeurs actives de tdt vers t void LesContacts::TdtversT() { LaLIST ::iterator il,ilfin=listContact.end(); for (il=listContact.begin();il != ilfin; il++) (*il).TdtversT(); // on nettoie les indicateurs transitoires listContact_nouveau_tatdt.clear(); listContact_efface_tatdt.clear(); }; // actualisation des ddl et des grandeurs actives de t vers tdt void LesContacts::TversTdt() { // on essaie de mettre la situation de contact comme elle était à t // a) on supprime les nouveaux contacts {LaLIST ::iterator>::iterator al,alfin=listContact_nouveau_tatdt.end(); for (al=listContact_nouveau_tatdt.begin();al != alfin; al++) { ElContact& elc = (*(*al)); Noeud* no = elc.Esclave(); 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::TversTdt(.. \n"; Sortie(1); }; #endif LaLIST < LaLIST::iterator > & list_tesN = tesN_encontact(num_mail_noe_esclave)[no]; list_tesN.remove(*al); // tesN_encontact(num_mail_noe_esclave)(n_noee).remove(*al); if (elc.Actif()) //a priori les nouveaux contacts étaient actif nb_contact_actif--; // mais on ne sait jamais listContact.erase(*al); // cout << "\n debug toto "; }; }; // b) on rajoute les contacts supprimés {LaLIST ::iterator al,alfin=listContact_efface_tatdt.end(); for (al=listContact_efface_tatdt.begin();al != alfin; al++) { ElContact& elc = (*al); Noeud* no = elc.Esclave(); int n_noee = no->Num_noeud(); int num_mail_noe_esclave = no->Num_Mail(); listContact.push_front(*al); // on met à jour le tableau tesN_encontact #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::TversTdt(.. \n"; Sortie(1); }; #endif tesN_encontact(num_mail_noe_esclave)[no].push_front(listContact.begin()); if ((*al).Actif()) // si l'élément supprimé était actif on remet à jour nb_contact_actif++; }; }; // c) on nettoie les indicateurs transitoires listContact_nouveau_tatdt.clear(); listContact_efface_tatdt.clear(); // d) on revient à t pour les éléments en contact {LaLIST ::iterator il,ilfin=listContact.end(); for (il=listContact.begin();il != ilfin; il++) (*il).TversTdt(); }; }; // 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 et de la pénétration // donc nécessite que le contact ait déjà été étudié double LesContacts::Pas_de_temps_ideal()const { double delta_optimal=ConstMath::tresgrand; // on passe en revue tous les contacts LaLIST ::const_iterator il,ilfin=listContact.end(); for (il=listContact.begin();il != ilfin; il++) { double dtelem_optimal = (*il).Pas_de_temps_ideal(); if (dtelem_optimal != 0.) delta_optimal = MiN(delta_optimal, dtelem_optimal); }; // retour du temps proposé if (delta_optimal==ConstMath::tresgrand) // cela veut dire qu'il n'a pas été modifié, on le met à 0 pour indiquer que l'on a rien // n'a proposer delta_optimal = 0.; return delta_optimal; }; // écriture base info // cas donne le niveau de sauvegarde void LesContacts::Ecri_base_info_LesContacts(ofstream& sort) { // globalement on sauvegarde toujours tout, car les éléments de contact peuvent apparaître à tout moment // tout d'abord on indique le type sort << "\n LesContacts: taille " << listContact.size() << " " ; // NB: le nombre de maillages esclave et en auto-contact, peut-être redéfinit lors d'un restart // donc n'est pas sauvegardé // ensuite on sauvegarde la liste des éléments de contact: en fait tout d'abord les infos // qui permettent de construire un élément ad hoc, et ensuite les infos spécifiques internes à l'élément for (LaLIST ::iterator ic = listContact.begin();ic != listContact.end(); ic++) {// les infos permettants de contruire l'élément de contact: on considère que les numéros des noeuds, maillages, éléments // restent identiques, par contre on peut avoir d'un échange des zones de restriction de contact d'une sauvegarde à un restart sort << "\nN_es " << (*ic).Esclave()->Num_Mail() <<" " << (*ic).Esclave()->Num_noeud(); // le noeud esclave Front * elfront = (*ic).Elfront(); sort << " El " << elfront->NumMail() << " " << elfront->PtEI()->Num_elt_const() << " " << elfront->Eleme()->Type_geom_front() << " "<< elfront->Num_frontiere() ; // la frontière // les infos spécifiques éventuelles (*ic).Ecri_base_info_ElContact(sort); }; sort << "\n tps_rech_contact: "< important : les conteneurs sont supposés initialisés avec l'appel void LesContacts::Mise_a_jour_Pour_Grandeur_particuliere( List_io < TypeQuelconque >& li_restreinte_TQ ) { LaLIST::iterator ili_deb= listContact.begin(); LaLIST::iterator ilifin= listContact.end(); LaLIST::iterator ili; // on passe en revue la liste de quelconque {List_io::iterator itq,itqfin=li_restreinte_TQ.end(); for (itq=li_restreinte_TQ.begin();itq!=itqfin;itq++) {const TypeQuelconque_enum_etendu& enuTypeQuelconque = (*itq).EnuTypeQuelconque(); if (enuTypeQuelconque.Nom_vide()) // veut dire que c'est un enum pur switch (enuTypeQuelconque.EnumTQ()) { case NOEUD_PROJECTILE_EN_CONTACT: {// ----- cas des noeuds projectiles en contact // on parcours la liste des élément en contact for (ili=ili_deb;ili!=ilifin;ili++) {ElContact & elcont = (*ili); // pour simplifier // on attribue une grandeur arbitraire de 100 aux noeuds pour un contact actif // pour les éléments de contact inactif -> -0.1 // un noeud peut être plusieurs fois en contact -> les nombres sont cumulées // on fait l'hypothèse qu'un ne sera jamais inactif plus de 99 fois, du coup // en regardant le nombre modulo 100 on peut en déduire le nombre d'inactivité // et en regardant le nombre de centaine on en déduit le nombre de contact TypeQuelconque& tyqN = elcont.Esclave()->ModifGrandeur_quelconque(enuTypeQuelconque); Grandeur_scalaire_double& tyTQ= *((Grandeur_scalaire_double*) tyqN.Grandeur_pointee()); if (elcont.Actif()) {*(tyTQ.ConteneurDouble()) += 100.; } else {*(tyTQ.ConteneurDouble()) -= 0.1; } }; break; } case NOEUD_FACETTE_EN_CONTACT: {// ----- cas des noeuds facettes en contact // on parcours la liste des éléments de contact for (ili=ili_deb;ili!=ilifin;ili++) {ElContact & elcont = (*ili); // pour simplifier // on attribue une grandeur arbitraire de 100 aux noeuds pour un contact actif // pour les éléments de contact inactif -> -0.1 // un noeud peut être plusieurs fois en contact -> les nombres sont cumulées // on fait l'hypothèse qu'un ne sera jamais inactif plus de 99 fois, du coup // en regardant le nombre modulo 100 on peut en déduire le nombre d'inactivité // et en regardant le nombre de centaine on en déduit le nombre de contact Tableau & tablN = elcont.TabNoeud(); int NBNF=tablN.Taille(); // on boucle sur les noeuds de la facette (le premier noeud = noeud esclave) if (elcont.Actif()) {for (int i=2;i<=NBNF;i++) {TypeQuelconque& tyqN = tablN(i)->ModifGrandeur_quelconque(enuTypeQuelconque); Grandeur_scalaire_double& tyTQ= *((Grandeur_scalaire_double*) tyqN.Grandeur_pointee()); *(tyTQ.ConteneurDouble()) += 100.; } } else {for (int i=2;i<=NBNF;i++) {TypeQuelconque& tyqN = tablN(i)->ModifGrandeur_quelconque(enuTypeQuelconque); Grandeur_scalaire_double& tyTQ= *((Grandeur_scalaire_double*) tyqN.Grandeur_pointee()); *(tyTQ.ConteneurDouble()) -= 0.1; } }; }; break; } case PENETRATION_CONTACT: {// ----- cas des noeuds projectiles en contact // on parcours la liste des élément en contact // on cumule s'il y a plusieurs contacts for (ili=ili_deb;ili!=ilifin;ili++) {ElContact & elcont = (*ili); // pour simplifier TypeQuelconque& tyqN = elcont.Esclave()->ModifGrandeur_quelconque(enuTypeQuelconque); Grandeur_coordonnee& tyTQ= *((Grandeur_coordonnee*) tyqN.Grandeur_pointee()); if (elcont.Actif()) {// on définit un vecteur au niveau du noeud en contact, qui part du noeud // projectile et va au point d'impact const Coordonnee& Mtdt = elcont.Point_intersection(); *(tyTQ.ConteneurCoordonnee()) += Mtdt - elcont.Esclave()->Coord2(); }; // sinon on ne fait rien }; break; } case GLISSEMENT_CONTACT: {// ----- cas des noeuds projectiles en contact // on parcours la liste des élément en contact // on cumule s'il y a plusieurs contacts for (ili=ili_deb;ili!=ilifin;ili++) {ElContact & elcont = (*ili); // pour simplifier TypeQuelconque& tyqN = elcont.Esclave()->ModifGrandeur_quelconque(enuTypeQuelconque); Grandeur_coordonnee& tyTQ= *((Grandeur_coordonnee*) tyqN.Grandeur_pointee()); if (elcont.Actif()) {// on définit un vecteur au niveau du noeud en contact, qui part du noeud // projectile et va au point d'impact *(tyTQ.ConteneurCoordonnee()) += elcont.Dep_tangentiel(); }; // sinon on ne fait rien }; break; } case NORMALE_CONTACT: {// ----- cas des noeuds projectiles en contact // on parcours la liste des élément en contact // on cumule s'il y a plusieurs contacts for (ili=ili_deb;ili!=ilifin;ili++) {ElContact & elcont = (*ili); // pour simplifier TypeQuelconque& tyqN = elcont.Esclave()->ModifGrandeur_quelconque(enuTypeQuelconque); Grandeur_coordonnee& tyTQ= *((Grandeur_coordonnee*) tyqN.Grandeur_pointee()); if (elcont.Actif()) {// on définit un vecteur au niveau du noeud en contact, qui part du noeud // projectile et va au point d'impact *(tyTQ.ConteneurCoordonnee()) += elcont.Normale_actuelle(); }; // sinon on ne fait rien }; break; } case FORCE_CONTACT: {// ----- cas des noeuds projectiles en contact // on parcours la liste des élément en contact for (ili=ili_deb;ili!=ilifin;ili++) {ElContact & elcont = (*ili); // pour simplifier TypeQuelconque& tyqN = elcont.Esclave()->ModifGrandeur_quelconque(enuTypeQuelconque); Grandeur_coordonnee& tyTQ= *((Grandeur_coordonnee*) tyqN.Grandeur_pointee()); if (elcont.Actif()) {// on récupère la force de contact *(tyTQ.ConteneurCoordonnee()) += elcont.Force_contact(); }; // sinon on ne fait rien }; break; } case CONTACT_PENALISATION_N: {// ----- on attribue la pénalisation au noeud projectile // on met la pénalisation totale s'il y a plusieurs contacts // on parcours la liste des élément en contact for (ili=ili_deb;ili!=ilifin;ili++) {ElContact & elcont = (*ili); // pour simplifier TypeQuelconque& tyqN = elcont.Esclave()->ModifGrandeur_quelconque(enuTypeQuelconque); Grandeur_scalaire_double& tyTQ= *((Grandeur_scalaire_double*) tyqN.Grandeur_pointee()); if (elcont.Actif()) {*(tyTQ.ConteneurDouble()) += elcont.Penalisation(); }; }; break; } case CONTACT_PENALISATION_T: {// ----- on attribue la pénalisation au noeud projectile // on met la pénalisation totale s'il y a plusieurs contacts // on parcours la liste des élément en contact for (ili=ili_deb;ili!=ilifin;ili++) {ElContact & elcont = (*ili); // pour simplifier TypeQuelconque& tyqN = elcont.Esclave()->ModifGrandeur_quelconque(enuTypeQuelconque); Grandeur_scalaire_double& tyTQ= *((Grandeur_scalaire_double*) tyqN.Grandeur_pointee()); if (elcont.Actif()) {*(tyTQ.ConteneurDouble()) += elcont.Penalisation_tangentielle(); }; }; break; } case CONTACT_ENERG_PENAL: {// ----- on attribue l'énergie de pénalisation au noeud projectile // on met l'énergie totale s'il y a plusieurs contacts // on parcours la liste des élément en contact for (ili=ili_deb;ili!=ilifin;ili++) {ElContact & elcont = (*ili); // pour simplifier TypeQuelconque& tyqN = elcont.Esclave()->ModifGrandeur_quelconque(enuTypeQuelconque); Grandeur_scalaire_double& tyTQ= *((Grandeur_scalaire_double*) tyqN.Grandeur_pointee()); if (elcont.Actif()) {*(tyTQ.ConteneurDouble()) += elcont.EnergiePenalisation(); }; }; break; } case CONTACT_ENERG_GLISSE_ELAS: {// ----- on attribue l'énergie de pénalisation au noeud projectile // on met l'énergie totale s'il y a plusieurs contacts // on parcours la liste des élément en contact for (ili=ili_deb;ili!=ilifin;ili++) {ElContact & elcont = (*ili); // pour simplifier TypeQuelconque& tyqN = elcont.Esclave()->ModifGrandeur_quelconque(enuTypeQuelconque); Grandeur_scalaire_double& tyTQ= *((Grandeur_scalaire_double*) tyqN.Grandeur_pointee()); if (elcont.Actif()) {*(tyTQ.ConteneurDouble()) += elcont.EnergieFrottement().EnergieElastique(); }; }; break; } case CONTACT_ENERG_GLISSE_PLAS: {// ----- on attribue l'énergie de pénalisation au noeud projectile // on met l'énergie totale s'il y a plusieurs contacts // on parcours la liste des élément en contact for (ili=ili_deb;ili!=ilifin;ili++) {ElContact & elcont = (*ili); // pour simplifier TypeQuelconque& tyqN = elcont.Esclave()->ModifGrandeur_quelconque(enuTypeQuelconque); Grandeur_scalaire_double& tyTQ= *((Grandeur_scalaire_double*) tyqN.Grandeur_pointee()); if (elcont.Actif()) {*(tyTQ.ConteneurDouble()) += elcont.EnergieFrottement().DissipationPlastique(); }; }; break; } case CONTACT_ENERG_GLISSE_VISQ: {// ----- on attribue l'énergie de pénalisation au noeud projectile // on met l'énergie totale s'il y a plusieurs contacts // on parcours la liste des élément en contact for (ili=ili_deb;ili!=ilifin;ili++) {ElContact & elcont = (*ili); // pour simplifier TypeQuelconque& tyqN = elcont.Esclave()->ModifGrandeur_quelconque(enuTypeQuelconque); Grandeur_scalaire_double& tyTQ= *((Grandeur_scalaire_double*) tyqN.Grandeur_pointee()); if (elcont.Actif()) {*(tyTQ.ConteneurDouble()) += elcont.EnergieFrottement().DissipationVisqueuse(); }; }; break; } case CONTACT_NB_DECOL: {// ----- on attribue le nombre de décolement au noeud projectile // on met le totale s'il y a plusieurs contacts // on parcours la liste des élément en contact for (ili=ili_deb;ili!=ilifin;ili++) {ElContact & elcont = (*ili); // pour simplifier TypeQuelconque& tyqN = elcont.Esclave()->ModifGrandeur_quelconque(enuTypeQuelconque); Grandeur_scalaire_double& tyTQ= *((Grandeur_scalaire_double*) tyqN.Grandeur_pointee()); if (elcont.Actif()) {*(tyTQ.ConteneurDouble()) += elcont.Nb_decol(); }; }; break; } case CONTACT_COLLANT: {// ----- on attribue le fait d'être collant ou pas au noeud projectile // on met le totale s'il y a plusieurs contacts // on parcours la liste des élément en contact for (ili=ili_deb;ili!=ilifin;ili++) {ElContact & elcont = (*ili); // pour simplifier TypeQuelconque& tyqN = elcont.Esclave()->ModifGrandeur_quelconque(enuTypeQuelconque); Grandeur_scalaire_double& tyTQ= *((Grandeur_scalaire_double*) tyqN.Grandeur_pointee()); if (elcont.Actif()) {*(tyTQ.ConteneurDouble()) += elcont.Collant(); }; }; break; } case NUM_ZONE_CONTACT: {// ----- on attribue le numéro de zone de contact au noeud projectile // on met le totale s'il y a plusieurs contacts // on parcours la liste des élément en contact for (ili=ili_deb;ili!=ilifin;ili++) {ElContact & elcont = (*ili); // pour simplifier TypeQuelconque& tyqN = elcont.Esclave()->ModifGrandeur_quelconque(enuTypeQuelconque); Grandeur_scalaire_double& tyTQ= *((Grandeur_scalaire_double*) tyqN.Grandeur_pointee()); if (elcont.Actif()) {*(tyTQ.ConteneurDouble()) += elcont.Num_zone_contact(); }; }; break; } case CONTACT_NB_PENET: {// ----- on attribue le nombre de décolement au noeud projectile // on met le totale s'il y a plusieurs contacts // on parcours la liste des élément en contact for (ili=ili_deb;ili!=ilifin;ili++) {ElContact & elcont = (*ili); // pour simplifier TypeQuelconque& tyqN = elcont.Esclave()->ModifGrandeur_quelconque(enuTypeQuelconque); Grandeur_scalaire_double& tyTQ= *((Grandeur_scalaire_double*) tyqN.Grandeur_pointee()); if (elcont.Actif()) {*(tyTQ.ConteneurDouble()) += elcont.Nb_pene(); }; }; break; } case CONTACT_CAS_SOLIDE: {// ----- on attribue le nombre au noeud projectile // =0 contact bi déformable, =1 le noeud est libre et la frontière est bloqué (solide) // = 2 le noeud est bloqué (solide) la frontière est libre // = 3 tout est solide // ici on ne met pas le totale s'il y a plusieurs contacts !! // c'est le dernier élément qui contient le noeud projectile, qui donne le résultat // on parcours la liste des élément en contact for (ili=ili_deb;ili!=ilifin;ili++) {ElContact & elcont = (*ili); // pour simplifier TypeQuelconque& tyqN = elcont.Esclave()->ModifGrandeur_quelconque(enuTypeQuelconque); Grandeur_scalaire_double& tyTQ= *((Grandeur_scalaire_double*) tyqN.Grandeur_pointee()); if (elcont.Actif()) {*(tyTQ.ConteneurDouble()) = elcont.Cas_solide(); }; }; break; } default: ;// on ne fait rien }; }; }; }; // 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 LesContacts::ListeGrandeurs_particulieres(bool absolue) const { // def de la liste de retour List_io liTQ; // on ne ramène les infos que si le contact est actif if (ParaGlob::param->ParaAlgoControleActifs().ContactType()!= 0) { // grandeurs de travail int dim = ParaGlob::Dimension(); // ici on est en 3D et les grandeurs sont par principe en absolue, donc la variable absolue ne sert pas Grandeur_scalaire_double grand_courant(0.); Coordonnee inter(dim); Grandeur_coordonnee grand_coor_courant(inter); // def d'un type quelconque représentatif à chaque grandeur // a priori ces grandeurs sont défini aux noeuds //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée // $$$ cas de la visualisation des noeuds projectiles en contact {TypeQuelconque typQ1(NOEUD_PROJECTILE_EN_CONTACT,X1,grand_courant); liTQ.push_back(typQ1); }; // $$$ cas de la visualisation des noeuds des facettes en contact {TypeQuelconque typQ1(NOEUD_FACETTE_EN_CONTACT,X1,grand_courant); liTQ.push_back(typQ1); }; // $$$ cas de la visualisation du glissement des noeuds projectiles actifs {TypeQuelconque typQ1(GLISSEMENT_CONTACT,X1,grand_coor_courant); liTQ.push_back(typQ1); }; // $$$ cas de la visualisation du glissement des noeuds projectiles actifs {TypeQuelconque typQ1(NORMALE_CONTACT,X1,grand_coor_courant); liTQ.push_back(typQ1); }; // $$$ cas de la visualisation de la pénétration en contact {TypeQuelconque typQ1(PENETRATION_CONTACT,X1,grand_coor_courant); liTQ.push_back(typQ1); }; // $$$ cas de la visualisation des forces de contact {TypeQuelconque typQ1(FORCE_CONTACT,X1,grand_coor_courant); liTQ.push_back(typQ1); }; // $$$ nombre de pénétration {TypeQuelconque typQ1(CONTACT_NB_PENET,X1,grand_courant); liTQ.push_back(typQ1); }; // $$$ nombre de décolement {TypeQuelconque typQ1(CONTACT_NB_DECOL,X1,grand_courant); liTQ.push_back(typQ1); }; // $$$ cas_solide {TypeQuelconque typQ1(CONTACT_CAS_SOLIDE,X1,grand_courant); liTQ.push_back(typQ1); }; {TypeQuelconque typQ1(CONTACT_ENERG_PENAL,X1,grand_courant); liTQ.push_back(typQ1); }; {TypeQuelconque typQ1(CONTACT_ENERG_GLISSE_ELAS,X1,grand_courant); liTQ.push_back(typQ1); }; {TypeQuelconque typQ1(CONTACT_ENERG_GLISSE_PLAS,X1,grand_courant); liTQ.push_back(typQ1); }; {TypeQuelconque typQ1(CONTACT_ENERG_GLISSE_VISQ,X1,grand_courant); liTQ.push_back(typQ1); }; {TypeQuelconque typQ1(CONTACT_PENALISATION_N,X1,grand_courant); liTQ.push_back(typQ1); }; {TypeQuelconque typQ1(CONTACT_PENALISATION_T,X1,grand_courant); liTQ.push_back(typQ1); }; {TypeQuelconque typQ1(CONTACT_COLLANT,X1,grand_courant); liTQ.push_back(typQ1); }; {TypeQuelconque typQ1(NUM_ZONE_CONTACT,X1,grand_courant); liTQ.push_back(typQ1); }; }; // retour return liTQ; }; // concernant les grandeurs gérées par le contact: // ramène une liste d'enuméré correspondant aux List_io passé en paramètre // idem pour une List_io < Ddl _enum_etendu > void LesContacts::List_reduite_aux_contact(const List_io& liTQ ,List_io < TypeQuelconque >& li_restreinte_TQ ) { // initialisation des listes de retour li_restreinte_TQ.clear(); // on passe en revue la liste List_io::const_iterator itq,itqfin=liTQ.end(); for (itq=liTQ.begin();itq!=itqfin;itq++) {const TypeQuelconque& tipParticu = (*itq); // pour simplifier const TypeQuelconque_enum_etendu& enuTypeQuelconque = tipParticu.EnuTypeQuelconque(); if (enuTypeQuelconque.Nom_vide()) // veut dire que c'est un enum pur switch (enuTypeQuelconque.EnumTQ()) { case NOEUD_PROJECTILE_EN_CONTACT: case NOEUD_FACETTE_EN_CONTACT: case PENETRATION_CONTACT: case FORCE_CONTACT: case CONTACT_PENALISATION_N: case CONTACT_PENALISATION_T: case CONTACT_ENERG_PENAL: case NORMALE_CONTACT: case GLISSEMENT_CONTACT: case CONTACT_ENERG_GLISSE_ELAS: case CONTACT_ENERG_GLISSE_VISQ: case CONTACT_ENERG_GLISSE_PLAS: case CONTACT_NB_DECOL: case CONTACT_NB_PENET: case CONTACT_CAS_SOLIDE: case CONTACT_COLLANT: case NUM_ZONE_CONTACT: {// ----- cas des noeuds projectiles en contact li_restreinte_TQ.push_front(TypeQuelconque(tipParticu)); break; } default: ;// on ne fait rien }; }; }; // 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 void LesContacts::Init_Grandeur_particuliere (bool absolue,List_io& liTQ) {liQ_en_sortie = liTQ; // on récupère la liste --> sans doute que cela ne sert à rien LaLIST::iterator ili_deb= listContact.begin(); LaLIST::iterator ilifin= listContact.end(); LaLIST::iterator ili; // on passe en revue la liste List_io::iterator itq,itqfin=liTQ.end(); // on part du principe qu'il y a plus de noeuds en contact que de grandeur donc on fait une // boucle externe sur les noeuds en contact: on parcours la liste des noeuds en contact for (ili=ili_deb;ili!=ilifin;ili++) {ElContact& elcont = (*ili); // pour simplifier for (itq=liTQ.begin();itq!=itqfin;itq++) {TypeQuelconque& tipParticu = (*itq); // pour simplifier EnumTypeQuelconque enuTQ = tipParticu.EnuTypeQuelconque().EnumTQ(); switch (enuTQ) { case NOEUD_PROJECTILE_EN_CONTACT: case NOEUD_FACETTE_EN_CONTACT: case GLISSEMENT_CONTACT: case PENETRATION_CONTACT: case FORCE_CONTACT: case CONTACT_NB_PENET: case CONTACT_PENALISATION_N: case CONTACT_PENALISATION_T: case CONTACT_NB_DECOL: case CONTACT_CAS_SOLIDE: case CONTACT_ENERG_PENAL: case CONTACT_COLLANT: case NUM_ZONE_CONTACT: case NORMALE_CONTACT: case CONTACT_ENERG_GLISSE_ELAS: case CONTACT_ENERG_GLISSE_VISQ: case CONTACT_ENERG_GLISSE_PLAS: {// ----- cas des noeuds projectiles en contact elcont.Esclave()->AjoutUnTypeQuelconque(*itq); // ajout du conteneur break; } default: ; // sinon rien }; }; }; } ; //========================== fonction protegee ============================= // mise à jour des boites d'encombrement pour les éléments qui contiennent une frontière void LesContacts::Mise_a_jour_boite_encombrement_element_contenant_front() { list ::iterator il,ilfin = liste_elemens_front.end(); for (il = liste_elemens_front.begin();il!=ilfin;il++) (*il)->Boite_encombre_element(TEMPS_tdt); }; // suppression du gap de contact pour les noeuds "collant avec suppression de gap" void LesContacts::Suppression_gap_pour_noeud_collant() { int niveau_commentaire_contact = ParaGlob::param->ParaAlgoControleActifs().Niveau_commentaire_contact(); if (niveau_commentaire_contact == 0) {niveau_commentaire_contact = ParaGlob::NiveauImpression();}; // on passe en revue les zones de contact et si nécessaire on supprime les gaps // sinon retour bool continuer = false; // init par défaut // list nom_ref_zone_contact; // liste des noms de références des zones de contact list ::iterator iu,iufin = nom_ref_zone_contact.end(); for (iu = nom_ref_zone_contact.begin();iu != iufin; iu++) if ((*iu).n == 2) {continuer = true; break;}; if (!continuer) return; // sinon il faut effectivement faire une suppression de gap if (niveau_commentaire_contact > 2) cout << "\n >>>> Suppression_gap_pour_noeud_collant : "; // on va iterer sur les noeuds esclaves collants dont on veut supprimer le gap LaLIST_io ::iterator iM,iMfin; // des itérator de travail int nb_zone = MaX(1,nom_ref_zone_contact.size()); double dist_max = Dabs(ParaGlob::param->ParaAlgoControleActifs().DistanceMaxiAuPtProjete()); int tout_projeter = true; // init int boucle_maxi = 10; // 10 boucle maxi int boucle = 1; do { if (niveau_commentaire_contact >2 ) cout << "\n boucle : "<& tesc= tesctotal(intot)(j); // pour simplifier la notation: const Tableau tesN_col = tesN_collant(intot)(j); // pour simplifier int tesc_taille=tesc.Taille(); // tab des noeuds esclaves à considérer int compteur_noeuds_projecte=0; // le nombre de noeuds qui sont projetés double le_maxi_des_distances_trouve = 0.; for (int inesc = 1;inesc<= tesc_taille;inesc++) // boucle sur les noeuds esclaves if (tesN_col(inesc) == 2 ) // cas noeud collant avec volonté de supprimer le gap { Noeud* noee = tesc(inesc); // pour simplifier //--- debug //if (noee->Num_noeud() == 5) // {cout << "\n arrivée au bon element "; // } const Coordonnee pt_esc = noee->Coord0(); // position du noeud esclave initial list list_P; // la liste des projetés list ::iterator> li_pt_front_P; // liste sur les faces pour le debug for (int jlf=1;jlf<=nbmailMaitre;jlf++) // boucle sur les maillages maitres {//Tableau < Tableau < LaLIST_io > > t_listFront; LaLIST_io & t_l_front = t_listFront(jlf)(j); iMfin=t_l_front.end(); for (iM = t_l_front.begin() ; iM != iMfin; iM++) // boucle sur les front maitres {// si c'est dans le volume de la frontière augmenté de la distance ad hoc on test // plus précisément if ((*iM).In_boite_emcombrement_front(pt_esc,dist_max)) {// on projete le noeud sur la frontière Coordonnee P; ////--- debug //if ((noee->Num_noeud() == 5) && ((*iM).PtEI()->Num_elt()==367)) // {cout << "\n arrivée au bon element "; // // } //{double Ndis = (P-pt_esc).Norme(); // if (Ndis > 20) // (*iM).Eleme()->Projection_normale(pt_esc,P); //} //-- fin debug // //----debug //{if ((noee->Num_noeud() == 12) // && ((*iM).Num_frontiere() == 1) && ((*iM).PtEI()->Num_elt() == 3130)) // { cout << "\n debug : frontiere 1 de l'element 3130";} //} ////----fin debug // si la projection est valide on enregistre if ((*iM).Eleme()->Projection_normale(pt_esc,P)) { list_P.push_back(P); li_pt_front_P.push_back(iM); }; //--- debug //{double Ndis = (P-pt_esc).Norme(); // if (Ndis > 20) // (*iM).Eleme()->Projection_normale(pt_esc,P); //} //-- fin debug }; }; }; // maintenant on va garder le plus proche bool projection_ok = false; // init if (list_P.size() != 0) {list ::iterator il,ilfin=list_P.end(); if (niveau_commentaire_contact >5 ) {cout << "\n " << list_P.size() << " proj trouvees " << " Noe: "<Num_noeud() << " mail: " << noee->Num_Mail() << " (zone"<::iterator>::iterator iface = li_pt_front_P.begin(); LaLIST_io ::iterator>::iterator iface_maxi ; for (il=list_P.begin(); il!= ilfin;il++,iface++) { double Ndis = (M-(*il)).Norme(); if (niveau_commentaire_contact >5 ) cout << " dist: " << Ndis ; if (Ndis < distance) {P = (*il); distance = Ndis; projection_ok = true; // au moins un nouveau point iface_maxi = iface; }; }; // si la distance == 0., il n'y a pas à changer les coordonnées // car le point projeté == le point initial if (distance > ConstMath::petit) {// on change les coordonnées du noeud noee->Change_coord0(P); noee->Change_coord1(P); noee->Change_coord2(P); compteur_noeuds_projecte++; tout_projeter=false; if (distance > le_maxi_des_distances_trouve) le_maxi_des_distances_trouve = distance; if (niveau_commentaire_contact >3 ) cout << "\n suppression gap=("<Num_noeud() << " du maillage " << noee->Num_Mail() << " (zone "<4 ) {cout << "\n ancienne coordonnee "<< pt_esc << " nouvelle " << P; // dans le cas où iface_maxi a été attribué if (projection_ok) (*(*iface_maxi)).Affiche(); ////--- debug //{ //const Coordonnee pt_esc = noee->Coord0(); //Coordonnee PP; //(*(*iface_maxi)).Eleme()->Projection_normale(pt_esc,PP); //cout << "\n $$$ nouvelle coordonnees projetee "<< PP; //} ////-- fin debug }; } else if (projection_ok) // si on n'a pas de projection avec changement de position // mais par contre on a quand même trouvé un projeté on enregistre {compteur_noeuds_projecte++;}; }; if ((!projection_ok) && (boucle==1)) // au premier passage { if (niveau_commentaire_contact >3 ) cout << "\n pas de projection trouvee donc de suppression gap du noeud "<Num_noeud() << " du maillage" << noee->Num_Mail() << " (zone "<2 ) {if (compteur_noeuds_projecte) cout << "\n zone: " << j <<", " << compteur_noeuds_projecte << " suppression(s) de gap, maxi_distance= " << le_maxi_des_distances_trouve << "( passage"<& tn = al.TabNoeud(); int num_mail_esclave = tn(1)->Num_Mail(); int num_mail_maitre = tn(2)->Num_Mail(); int num_noe = tn(1)->Num_noeud(); // on parcours la liste des frontières succeptibles d'entrer en contact // pour repérer la zone int num_zone = 0; // init int nb_maitre = t_listFront.Taille(); int nb_esclave = tesctotal.Taille(); for (int i=1;i<=nb_maitre;i++) {for (int j=1;j<=nb_zone;j++) {LaLIST_io & list_fronta = t_listFront(i)(j); // pour simplifier LaLIST_io ::iterator il,ilfin = list_fronta.end(); for (il = list_fronta.begin();il != ilfin; il++) {if ((*il)==(*al.Elfront())) // les deux pointeurs pointent sur la même frontière, donc // maintenant on regarde du coté des noeuds esclaves { for (int ie = 1; ie<=nb_esclave;ie++) {const Tableau & tesc= tesctotal(i)(j); // pour simplifier la notation: int tesc_taille=tesc.Taille(); // tab des noeuds esclaves à considérer for (int inesc = 1;inesc<= tesc_taille;inesc++) // boucle sur les noeuds esclaves {if (tesc(inesc) == al.Esclave()) // les deux pointeurs pointent sur le même noeud, c'est ok {num_zone = j; break;}; }; if (num_zone) break; }; }; if (num_zone) break; }; if (num_zone) break; }; if (num_zone) break; }; // retour des infos return num_zone; }; // 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 & LesContacts::ConnectionCLL() { // on boucle sur le tableau et pour chaque element on crée une condition lineaire int tabTaille = listContact.size(); t_connectionCLL.Change_taille(tabTaille); // un tableau servant à la def de la CLL Tableau t_enu(1); t_enu(1)=X1 ; LaLIST ::const_iterator il,ilfin=listContact.end(); int posi=1; // init pour le tableau for (il=listContact.begin();il != ilfin;il++,posi++) { const Tableau < Noeud *>& t_n = (*il).Const_TabNoeud(); // on est dans le cas ou l'on connait les infos relatives uniquements aux noeuds, aux enum ddl t_connectionCLL(posi) = Condilineaire(t_enu, t_n); }; // retour return t_connectionCLL; }; // 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 LesContacts::Recalcul_Nb_contact_actif() { LaLIST ::iterator il,ilfin = listContact.end(); int ancien_nb_contact_actif = nb_contact_actif; nb_contact_actif = 0; // init for (il = listContact.begin();il != ilfin; il++) if ((*il).Actif()) nb_contact_actif++; int niveau_commentaire_contact = ParaGlob::param->ParaAlgoControleActifs().Niveau_commentaire_contact(); if (niveau_commentaire_contact == 0) {niveau_commentaire_contact = ParaGlob::NiveauImpression();}; if (nb_contact_actif != ancien_nb_contact_actif) if (niveau_commentaire_contact > 4) cout << "\n mise a jour anormale du nombre de contact actif : " << " ancien_nb_contact_actif= " << ancien_nb_contact_actif << " nouveau_nombre= " << nb_contact_actif << endl; return nb_contact_actif; }; // création du conteneur Fct_nD_contact void LesContacts::Creation_Fct_nD_contact() { {// cas de la penalisation normale string nom_fct = ParaGlob::param->ParaAlgoControleActifs().Fct_nD_penalisationPenetration(); if (nom_fct != "_") {// on va récupérer la fonction if (sauve_lesFonctionsnD->Existe(nom_fct)) { Fonction_nD * pt_fonct = sauve_lesFonctionsnD->Trouve(nom_fct); // sauvegarde fct_nD_contact.fct_nD_penalisationPenetration = pt_fonct; } else { cout << "\n *** erreur dans la definition de la fonction nD de pilotage de la penalisation normale " << " le nom : " << nom_fct << " ne correspond pas a une fonction nD existante !! "; Sortie(1); }; } else {fct_nD_contact.fct_nD_penalisationPenetration=NULL;}; }; {// cas fct_nD_penetration_contact_maxi string nom_fct = ParaGlob::param->ParaAlgoControleActifs().Fct_nD_penetration_contact_maxi(); if (nom_fct != "_") {// on va récupérer la fonction if (sauve_lesFonctionsnD->Existe(nom_fct)) { Fonction_nD * pt_fonct = sauve_lesFonctionsnD->Trouve(nom_fct); // sauvegarde fct_nD_contact.fct_nD_penetration_contact_maxi = pt_fonct; } else { cout << "\n *** erreur dans la definition de la fonction nD de pilotage de la " << " penetration maxi, le nom : " << nom_fct << " ne correspond pas a une fonction nD existante !! "; Sortie(1); }; } else {fct_nD_contact.fct_nD_penetration_contact_maxi=NULL;}; }; {// cas Fct_nD_penetration_borne_regularisation string nom_fct = ParaGlob::param->ParaAlgoControleActifs().Fct_nD_penetration_borne_regularisation(); if (nom_fct != "_") {// on va récupérer la fonction if (sauve_lesFonctionsnD->Existe(nom_fct)) { Fonction_nD * pt_fonct = sauve_lesFonctionsnD->Trouve(nom_fct); // sauvegarde fct_nD_contact.fct_nD_penetration_borne_regularisation = pt_fonct; } else { cout << "\n *** erreur dans la definition de la fonction nD de pilotage de la " << " borne de regularisation, le nom : " << nom_fct << " ne correspond pas a une fonction nD existante !! "; Sortie(1); }; } else {fct_nD_contact.fct_nD_penetration_borne_regularisation=NULL;}; }; {// cas fct_nD_force_contact_noeud_maxi string nom_fct = ParaGlob::param->ParaAlgoControleActifs().Fct_nD_force_contact_noeud_maxi(); if (nom_fct != "_") {// on va récupérer la fonction if (sauve_lesFonctionsnD->Existe(nom_fct)) { Fonction_nD * pt_fonct = sauve_lesFonctionsnD->Trouve(nom_fct); // sauvegarde fct_nD_contact.fct_nD_force_contact_noeud_maxi = pt_fonct; } else { cout << "\n *** erreur dans la definition de la fonction nD de pilotage de la " << " force de contact normale, le nom : " << nom_fct << " ne correspond pas a une fonction nD existante !! "; Sortie(1); }; } else {fct_nD_contact.fct_nD_force_contact_noeud_maxi=NULL;}; }; {// cas fct_nD_penalisationTangentielle string nom_fct = ParaGlob::param->ParaAlgoControleActifs().Fct_nD_penalisationTangentielle(); if (nom_fct != "_") {// on va récupérer la fonction if (sauve_lesFonctionsnD->Existe(nom_fct)) { Fonction_nD * pt_fonct = sauve_lesFonctionsnD->Trouve(nom_fct); // sauvegarde fct_nD_contact.fct_nD_penalisationTangentielle = pt_fonct; } else { cout << "\n *** erreur dans la definition de la fonction nD de pilotage de la penalisation tangentielle " << " le nom : " << nom_fct << " ne correspond pas a une fonction nD existante !! "; Sortie(1); }; } else {fct_nD_contact.fct_nD_penalisationTangentielle=NULL;}; }; {// cas fct_nD_tangentielle_contact_maxi string nom_fct = ParaGlob::param->ParaAlgoControleActifs().Fct_nD_tangentielle_contact_maxi(); if (nom_fct != "_") {// on va récupérer la fonction if (sauve_lesFonctionsnD->Existe(nom_fct)) { Fonction_nD * pt_fonct = sauve_lesFonctionsnD->Trouve(nom_fct); // sauvegarde fct_nD_contact.fct_nD_tangentielle_contact_maxi = pt_fonct; } else { cout << "\n *** erreur dans la definition de la fonction nD de pilotage du " << " deplacement tangentiel maxi, le nom : " << nom_fct << " ne correspond pas a une fonction nD existante !! "; Sortie(1); }; } else {fct_nD_contact.fct_nD_tangentielle_contact_maxi=NULL;}; }; {// cas fct_nD_tangentielle_borne_regularisation string nom_fct = ParaGlob::param->ParaAlgoControleActifs().Fct_nD_tangentielle_borne_regularisation(); if (nom_fct != "_") {// on va récupérer la fonction if (sauve_lesFonctionsnD->Existe(nom_fct)) { Fonction_nD * pt_fonct = sauve_lesFonctionsnD->Trouve(nom_fct); // sauvegarde fct_nD_contact.fct_nD_tangentielle_borne_regularisation = pt_fonct; } else { cout << "\n *** erreur dans la definition de la fonction nD de pilotage de la " << " borne de regularisation tangentielle, le nom : " << nom_fct << " ne correspond pas a une fonction nD existante !! "; Sortie(1); }; } else {fct_nD_contact.fct_nD_tangentielle_borne_regularisation=NULL;}; }; {// cas fct_nD_force_tangentielle_noeud_maxi string nom_fct = ParaGlob::param->ParaAlgoControleActifs().Fct_nD_force_tangentielle_noeud_maxi(); if (nom_fct != "_") {// on va récupérer la fonction if (sauve_lesFonctionsnD->Existe(nom_fct)) { Fonction_nD * pt_fonct = sauve_lesFonctionsnD->Trouve(nom_fct); // sauvegarde fct_nD_contact.fct_nD_force_tangentielle_noeud_maxi = pt_fonct; } else { cout << "\n *** erreur dans la definition de la fonction nD de pilotage de la " << " force tangentielle maxi, le nom : " << nom_fct << " ne correspond pas a une fonction nD existante !! "; Sortie(1); }; } else {fct_nD_contact.fct_nD_force_tangentielle_noeud_maxi=NULL;}; }; }; /*// mise à jour du stockage inter, pour prendre en // compte une nouvelle numérotation des noeuds void LesContacts::Prise_en_compte_nouvelle_numerotation_noeud() { //on va reconstruire ta_inverse int nb_zone = MaX(1,nom_ref_zone_contact.size()); // on garde en mémoire les anciens numéros pour faire le pontage Tableau < Tableau < Tableau > > ta_inverse_old(ta_inverse); // on recherche les maxi des numéros de noeuds esclave, pour dimensionner ta_inverse !! Tableau < Tableau > maxi_num_noe_esclave(nb_mail_Esclave); // init à 0 for (int i=1;i<=nb_mail_Esclave;i++) {maxi_num_noe_esclave(i).Change_taille(nb_zone); for (int j=1;j<=nb_zone;j++) {const Tableau & tesc= tesctotal(i)(j); // pour simplifier la notation: int tesc_taille=tesc.Taille(); // tab des noeuds esclaves à considérer int& max_num_esclave = maxi_num_noe_esclave(i)(j); // pour simplifier for (int inesc = 1;inesc<= tesc_taille;inesc++) // boucle sur les noeuds esclaves { Noeud* noee = tesc(inesc); // pour simplifier int num_noeud = noee->Num_noeud(); if (num_noeud > max_num_esclave) max_num_esclave = num_noeud; }; }; }; // Maintenant on peut dimensionner ta_inverse for (int i=1;i<=nb_mail_Esclave;i++) {ta_inverse(i).Change_taille(nb_zone); for (int j=1;j<=nb_zone;j++) ta_inverse(i)(j).Change_taille(maxi_num_noe_esclave(i)(j),0); }; // ensuite on va remplir ta_inverse for (int intot=1;intot<=nb_mail_Esclave;intot++) {for (int j=1;j<=nb_zone;j++) {const Tableau & tesc= tesctotal(intot)(j); // pour simplifier la notation: 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 ta_inverse(intot)(j)(noee->Num_noeud()) = inesc; }; }; }; // on va créer un tableau de changement des numéros de noeuds Tableau < Tableau > nouveau_Noe(nb_mail_Esclave); // on cherche la taille maxi Tableau maxi_maxi_num_noe_esclave(nb_mail_Esclave); // les maxis pour chaque maillage for (int i=1;i<=nb_mail_Esclave;i++) {int& max_max_esclave = maxi_maxi_num_noe_esclave(i) = 0; // init for (int j=1;j<=nb_zone;j++) {int& max_num_esclave = maxi_num_noe_esclave(i)(j); // pour simplifier if (max_num_esclave > max_max_esclave) max_max_esclave = max_num_esclave; }; }; // on balaie les anciens noeuds for (int i=1;i<=nb_mail_Esclave;i++) {nouveau_Noe(i).Change_taille(maxi_maxi_num_noe_esclave(i)); Tableau & nouveau_Noe_i = nouveau_Noe(i); for (int j=1;j<=nb_zone;j++) { Tableau & ta_inverse_old_ij = ta_inverse_old(i)(j); Tableau & ta_inverse_ij = ta_inverse(i)(j); int nbN = ta_inverse_old_ij.Taille(); for (int k=1;k<= nbN;k++) // k c'est le numéro de l'ancien noeud {if (ta_inverse_old_ij(k) != 0) {for (int k2=1;k2<= nbN;k2++) { if (ta_inverse_old_ij(k) == ta_inverse_ij(k2)) {nouveau_Noe_i(k)=k2;break;}; }; }; }; }; }; // // maintenant on met à jour le tableau tesN_encontact // // Tableau < Tableau < LaLIST < LaLIST::iterator > > > tesN_encontact; // // on sauvegarde l'ancien // Tableau < Tableau < LaLIST < LaLIST::iterator > > > tesN_encontact_old(tesN_encontact); // // et on fait la passation // for (int i=1;i<=nb_mail_Esclave;i++) // {Tableau & nouveau_Noe_i = nouveau_Noe(i); // int nbn = tesN_encontact(i).Taille(); // for (int j=1;j<=nbn;j++) // { tesN_encontact(i)(nouveau_Noe_i(j)) = tesN_encontact_old(i)(j); // }; // }; // on continue avec le tableau: 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 Tableau < const Tableau > *> indice_old(indice); int nb_mail = indice_old.Taille(); for (int i=1;i<=nb_mail;i++) {if (indice_old(i) != NULL) { int nbn = indice_old(i)->Taille(); // const Tableau > & indice_i = indice(i); // for (int j=1;j<=nbn;j++) //indice } } cout << "\n LesContacts::Prise_en_compte_nouvelle_numerotation_noeud() pas terminé !!" << " il faut changer lesMaillages pour récupérer directement la nouvelle numérotation !!"; Sortie(1); }; */ // récupération via les éléments de contact des forces maxis // et affichage éventuel // un : le maxi en effort normal, deux: le maxi en effort tangentiel DeuxDoubles LesContacts::Forces_contact_maxi(bool affiche) const {DeuxDoubles retour; LaLIST ::const_iterator il,ilfin = listContact.end(); for (il = listContact.begin();il != ilfin; il++) { const ElContact& icont = (*il); // pour simplifier double fNmax = icont.F_N_MAX(); double fTmax = icont.F_T_MAX(); if (Dabs(fNmax) > Dabs(retour.un) ) retour.un = fNmax; if (Dabs(fTmax) > Dabs(retour.deux) ) retour.deux = fTmax; }; int niveau_commentaire_contact = ParaGlob::param->ParaAlgoControleActifs().Niveau_commentaire_contact(); if (niveau_commentaire_contact == 0) {niveau_commentaire_contact = ParaGlob::NiveauImpression();}; if ((affiche && (ParaGlob::NiveauImpression() > 2)) || (niveau_commentaire_contact > 5) // spécifiquement pour le contact ) cout << "\n contact: reaction ==> F_N max " << retour.un << " F_T max " << retour.deux; return retour; }; // 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 LesContacts::Gap_contact_maxi(bool affiche) const {DeuxDoubles retour; LaLIST ::const_iterator il,ilfin = listContact.end(); for (il = listContact.begin();il != ilfin; il++) { const ElContact& icont = (*il); // pour simplifier double fNmax = icont.Gaptdt(); double fTmax = icont.Dep_T_tdt(); if (Dabs(fNmax) > Dabs(retour.un) ) retour.un = fNmax; if (Dabs(fTmax) > Dabs(retour.deux) ) retour.deux = fTmax; }; int niveau_commentaire_contact = ParaGlob::param->ParaAlgoControleActifs().Niveau_commentaire_contact(); if (niveau_commentaire_contact == 0) {niveau_commentaire_contact = ParaGlob::NiveauImpression();}; if ((affiche && (ParaGlob::NiveauImpression() > 2)) || (niveau_commentaire_contact > 5) // spécifiquement pour le contact ) cout << ", maxi gap_N : " << retour.un << " gap_T : " << retour.deux; return retour; };