// 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: . #ifndef LesContacts_2_deja_inclus #include "LesContacts.h" #endif #ifndef LesContacts_2_deja_inclus #include #include "ReferenceNE.h" #include "ReferenceAF.h" //----- lecture écriture base info ----- // lecture base info // 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 LesContacts::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) { int niveau_commentaire_lescontacts = Permet_affichage(); // tout d'abord on lit le type string type_contact,no_taille; int taille=0; // taille par défaut ent >> type_contact >> no_taille >> taille; #ifdef MISE_AU_POINT if (type_contact != "LesContacts:") { cout << "\n erreur dans la lecture des contacts, on attendait la chaine: LesContacts:" << " alors que l'on a lue : " << type_contact << "\n LesContacts::Lec_base_info_LesContacts(i..."; Sortie(1); }; if (no_taille != "taille") { cout << "\n erreur dans la lecture des contacts, on attendait la chaine: taille" << " alors que l'on a lue : " << no_taille << "\n LesContacts::Lec_base_info_LesContacts(i..."; Sortie(1); }; #endif // on supprime tous les éléments de contact sauf... les collants qui restent collant {LaLIST ::iterator iE ; // on met .end(), car cette borne peut changer au gré des suppression for (iE = listContact.begin(); iE != listContact.end(); iE++) if (!((*iE).Collant()) // et si ce n'est pas collant: si collant, on ne change rien ) { // sinon on supprime LaLIST ::iterator iiE = iE; iE--; // pointe sur le precedent element LaLIST < LaLIST::iterator > & list_tesN = tesN_encontact((*iiE).Esclave()->Num_Mail())[(*iiE).Esclave()]; list_tesN.remove(iiE); listContact.erase(iiE); // efface l'element }; }; Tableau compteur_inesc(nb_mail_Esclave,1); // compteur de compteur de noeuds esclaves // on initialise la liste des éléments en contact // listContact.clear(); // comme on redémarre, on efface la situation actuelle // non, il faut garder les éléments collants // --- on s'occupe du deuxième niveau de tesN_encontact // une map vide par défaut std::map::iterator > > map_vide; tesN_encontact.Change_taille(nb_mail_Esclave,map_vide); for (int i=1;i<= taille;i++) {// on commence par créer un élément de contact de base en fonction des infos sauvegardées // --- le noeud esclave string toto; int numMail_esclave, numNoeud_esclave; string type; int numMail_element, num_element, num_front_element; Enum_type_geom enu ; string nom_enu; //N_es 1 72 El 2 2 SURFACE 1 ent >> toto >> numMail_esclave >> numNoeud_esclave // le noeud esclave >> type >> numMail_element >> num_element // partie relative à l'élément >> enu >> num_front_element; // et la frontière // on ne continue que si le noeud fait partie des maillages esclave ou en auto-contact // le nombre de maillages esclave et en auto-contact, peut-être redéfinit lors d'un restart // donc n'est pas sauvegardé if (numMail_esclave <= nb_mail_Esclave) { Noeud& no = (instance.*RecupNoeud)(numMail_esclave, numNoeud_esclave); // "" // --- création de la frontière Element& elem = (instance.*RecupElement_LesMaille)(numMail_element,num_element); ElFrontiere* elfr; switch (enu) { case POINT_G : elfr = elem.Frontiere_points(num_front_element,true) ; break; case LIGNE : elfr = elem.Frontiere_lineique(num_front_element,true) ; break; case SURFACE : elfr = elem.Frontiere_surfacique(num_front_element,true) ; break; default : cout << "\nErreur : valeur incorrecte du type de frontiere " << Nom_type_geom(enu) << " !\n"; cout << "LesContacts::Lec_base_info_LesContacts(... \n"; Sortie(1); }; // création d'un Front Front froont(*elfr,&elem,num_front_element); // froont ne contient pas forcément les éléments mitoyens, en particulier pour les élément d'angles morts // par contre il doit correspondre à un des éléments enregistrés dans t_listFront // on va donc le chercher dans t_listFront Front* froant=NULL; // le front que l'on cherche // ** 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) int ii = numMail_element - (nb_mail_Esclave-nbmailautocontact); Tableau < LaLIST_io >& t_listFront_i = t_listFront(ii); // pour simplifier int nbzoneEt1 = 1+t_listFront_i.Taille(); int num_zone = 0; // le numéro de zone éventuel bool trouver = false; for (int izone = 1; izone < nbzoneEt1;izone++) {LaLIST_io & t_listFront_i_izone = t_listFront_i(izone); // pour simplifier LaLIST_io ::iterator it,itfin=t_listFront_i_izone.end(); for (it = t_listFront_i_izone.begin();it != itfin; it++) {if ((*it).MemeOrigine(froont)) {froant = &(*it); trouver = true; break; }; }; if (trouver) {num_zone=izone; break;} }; // on vérifie que l'on a bien trouvé un front sinon, on signale if ((trouver == false) && (ParaGlob::NiveauImpression() > 0)) {cout << "\n *** attention la frontiere de contact "; froont.Affiche(1); cout << " n'existe plus, on n'en tient plus compte "; }; // même si l'élément n'existe plus // on continue la création pour ne pas corrompre la lecture // on créer un élément de contact ad hoc // création de l'élément de contact ElContact courant(&froont,&no,fct_nD_contact); // lecture des données particulières (qui ne contiennent pas les mitoyens) courant.Lec_base_info_ElContact(ent); if (trouver) {// on met à jour les mitoyens // definition des elements mitoyens à partir du front enregistré qui lui contient les mitoyens // qui ont été créé à l'initialisation if (froant->TabMitoyen() != NULL) courant.Elfront()->DefMitoyen(*(froant->TabMitoyen())); // mis à jour du numéro de zone courant.Num_zone_contact() = num_zone; courant.Change_lissage_normale(lissage_de_la_normale(num_zone)); // affectation du lissage // sauvegarde si l'élément de contact n'existe pas déjà ElContact* test_existance= Element_contact_deja_present(courant); if (test_existance == NULL) {listContact.push_front(courant); LaLIST::iterator ipp = listContact.begin(); // on met à jour le tableau tesN_encontact //*** la liste peut très bien ne pas exister ! // #ifdef MISE_AU_POINT // if (tesN_encontact(numMail_esclave).find((*ipp).Esclave()) // == tesN_encontact(numMail_esclave).end() ) // { cout << "\n*** Erreur : on ne trouve pas la liste d'element en contact avec le noeud esclave " // << (*ipp).Esclave()->Num_noeud() << " du maillage " << numMail_esclave // << " la suite n'est pas possible " // << " LesContacts::Lec_base_info_LesContacts(.. \n"; // Sortie(1); // }; // #endif // ajout dans la liste associé au noeud esclave tesN_encontact(numMail_esclave)[(*ipp).Esclave()].push_front(listContact.begin()); }; }; } // fin de l'ajout d'un élément de contact else {if (ParaGlob::NiveauImpression() > 0) cout << "\n *** attention, le maillage "<4) // on va lister les éléments de contact { cout << "\n liste des Elcontact (fct du niveau de commentaire des elcontact): "; LaLIST::iterator ipp,ippfin=listContact.end(); for (ipp=listContact.begin();ipp != ippfin; ipp++) {(*ipp).Affiche(2);}; }; Calcul_Nb_contact_actif(); if (((ParaGlob::NiveauImpression() > 2) && (nb_contact_actif != 0)) || (niveau_commentaire_lescontacts > 0 ) ) cout << "\n >> restart: lecture elements contact : "<< nb_contact_actif << " elements lus " << endl ; string mot; ent >> mot >> tempsContact; }; #endif // fin du test d'inclusion : ifndef LesContacts_2_deja_inclus