Herezh_dev/herezh_pp/contact/LesContacts_2.cc

177 lines
7.9 KiB
C++
Executable file

// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// 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 <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.
#ifndef LesContacts_2_deja_inclus
#include "LesContacts.h"
#endif
#ifndef LesContacts_2_deja_inclus
#include <vector>
#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 <class T>
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_contact = ParaGlob::param->ParaAlgoControleActifs().Niveau_commentaire_contact();
// 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 <ElContact>::iterator iE ;
// on met .end(), car cette borne peut changer au gré des suppression
for (iE = listContact.begin(); iE != listContact.end(); iE++)
if (!((*iE).Collant()) // et si ce n'est pas collant: si collant, on ne change rien
)
{ // sinon on supprime
LaLIST <ElContact>::iterator iiE = iE;
iE--; // pointe sur le precedent element
LaLIST < LaLIST<ElContact>::iterator > & list_tesN
= tesN_encontact((*iiE).Esclave()->Num_Mail())[(*iiE).Esclave()];
list_tesN.remove(iiE);
listContact.erase(iiE); // efface l'element
};
Recalcul_Nb_contact_actif();
};
// nb_contact_actif = 0 ; // init
Tableau <int> 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<Noeud*,LaLIST < LaLIST<ElContact>::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);
// création de l'élément de contact
ElContact courant(&froont,&no,fct_nD_contact);
// lecture des données particulières
courant.Lec_base_info_ElContact(ent);
// on regarde si c'était un contact actif ou pas, si oui on incrémente le nombre
if (courant.Actif())
nb_contact_actif++;
// sauvegarde
listContact.push_front(courant);
LaLIST<ElContact>::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 "<<numMail_esclave<<" n'est plus esclave !"
<< " l'element de contact non pris en compte: "
<< "\n N_es " <<numMail_esclave << " "<<numNoeud_esclave
<< type << " "<< numMail_element << " "<< num_element << " "
<< Nom_type_geom(enu) <<" "<<num_front_element;
};
};
if (((ParaGlob::NiveauImpression() > 2) && (nb_contact_actif != 0))
|| (niveau_commentaire_contact > 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