Gérard Rio
a317216f06
- modification des sorties post pour loi hypo 2D_C et 1D_C - corr bug lecture fct_nD avec toutes les lois hypo isotropes - corr bug sur le calcul de la compressibilité pour les loi hypo 2D_C - première mise en place du calcul parallèle sur le contact - ajout d'une fct nD pour gérer le niveau de commentaire sur LesContacts (indépendante de celle qui gère le niveau de commentaire concernant les éléments de contact) - amélioration de la méthode d'initialisation du contact, utilisée en début d'incrément
231 lines
11 KiB
C++
Executable file
231 lines
11 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-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 <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_lescontacts = Permet_affichage();
|
|
if (Permet_affichage()>4)
|
|
cout << "\n -- LesContacts::Lec_base_info_LesContacts ";
|
|
|
|
// 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
|
|
};
|
|
};
|
|
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);
|
|
// 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 <Front> >& 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 <Front>& t_listFront_i_izone = t_listFront_i(izone); // pour simplifier
|
|
LaLIST_io <Front>::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<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 (Permet_affichage()>4)
|
|
// on va lister les éléments de contact
|
|
{ cout << "\n liste des Elcontact (fct du niveau de commentaire des elcontact): ";
|
|
LaLIST<ElContact>::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
|
|
|
|
|
|
|