Herezh_dev/herezh_pp/contact/LesContacts_3.cc

1248 lines
57 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/>.
#include "LesContacts.h"
#include <vector>
#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 <ElContact>::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 <LaLIST <ElContact>::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<ElContact>::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 <ElContact>::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 <ElContact>::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 <ElContact>::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 <ElContact>::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: "<<tempsContact;
};
// 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
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
//--> 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<ElContact>::iterator ili_deb= listContact.begin();
LaLIST<ElContact>::iterator ilifin= listContact.end();
LaLIST<ElContact>::iterator ili;
// on passe en revue la liste de quelconque
{List_io<TypeQuelconque>::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 <Noeud*>& 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<TypeQuelconque> LesContacts::ListeGrandeurs_particulieres(bool absolue) const
{
// def de la liste de retour
List_io <TypeQuelconque> 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<TypeQuelconque> passé en paramètre
// idem pour une List_io < Ddl _enum_etendu >
void LesContacts::List_reduite_aux_contact(const List_io<TypeQuelconque>& liTQ
,List_io < TypeQuelconque >& li_restreinte_TQ
)
{
// initialisation des listes de retour
li_restreinte_TQ.clear();
// on passe en revue la liste
List_io<TypeQuelconque>::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<TypeQuelconque>& liTQ)
{liQ_en_sortie = liTQ; // on récupère la liste --> sans doute que cela ne sert à rien
LaLIST<ElContact>::iterator ili_deb= listContact.begin();
LaLIST<ElContact>::iterator ilifin= listContact.end();
LaLIST<ElContact>::iterator ili;
// on passe en revue la liste
List_io<TypeQuelconque>::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 <Element *>::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 <quatre_string_un_entier> nom_ref_zone_contact; // liste des noms de références des zones de contact
list <quatre_string_un_entier>::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 <Front>::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 : "<<boucle << flush;
for (int intot = 1;intot<= nb_mail_Esclave;intot++) // boucle sur les maillages esclaves
for (int j=1;j<=nb_zone;j++) // boucle sur les zones de contact
{const Tableau <Noeud*>& tesc= tesctotal(intot)(j); // pour simplifier la notation:
const Tableau <int> 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 <Coordonnee > list_P; // la liste des projetés
list <LaLIST_io <Front>::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 <Front> > > t_listFront;
LaLIST_io <Front>& 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 <Coordonnee >::iterator il,ilfin=list_P.end();
if (niveau_commentaire_contact >5 )
{cout << "\n " << list_P.size() << " proj trouvees "
<< " Noe: "<<noee->Num_noeud()
<< " mail: " << noee->Num_Mail() << " (zone"<<j<<")";
};
Coordonnee M = pt_esc; // init
Coordonnee P(M); // la projection
double distance = dist_max;
LaLIST_io <LaLIST_io <Front>::iterator>::iterator iface = li_pt_front_P.begin();
LaLIST_io <LaLIST_io <Front>::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=("<<distance<<") du noeud "<<noee->Num_noeud()
<< " du maillage " << noee->Num_Mail() << " (zone "<<j<<")";
if (niveau_commentaire_contact >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 "<<noee->Num_noeud()
<< " du maillage" << noee->Num_Mail() << " (zone "<<j<<")";
} ;
}; //-- fin de la boucle sur inesc
if (niveau_commentaire_contact >2 )
{if (compteur_noeuds_projecte)
cout << "\n zone: " << j <<", " << compteur_noeuds_projecte << " suppression(s) de gap, maxi_distance= "
<< le_maxi_des_distances_trouve << "( passage"<<boucle<<")" ;
int non_gap = tesc_taille-compteur_noeuds_projecte;
if ((non_gap)&& (boucle==1)) // au premier passage
cout << "\n zone: " << j <<", *** attention pour "<<non_gap
<< " noeud(s) pas de projection trouvee !! ";
};
}; //-- fin de la boucle sur intot
boucle++;
}
while ((!tout_projeter) && (boucle < boucle_maxi));
// Sortie(1);
};
// 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 LesContacts::Recup_ref( ElContact& al)
{ int nb_zone = MaX(1,nom_ref_zone_contact.size());
const Tableau <Noeud*>& 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 <Front> & list_fronta = t_listFront(i)(j); // pour simplifier
LaLIST_io <Front>::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 <Noeud*>& 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 <Condilineaire>& 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 <Enum_ddl > t_enu(1); t_enu(1)=X1 ;
LaLIST <ElContact>::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 <ElContact>::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 <int> > > ta_inverse_old(ta_inverse);
// on recherche les maxi des numéros de noeuds esclave, pour dimensionner ta_inverse !!
Tableau < Tableau <int> > 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 <Noeud*>& 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 <Noeud*>& 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 <int> > nouveau_Noe(nb_mail_Esclave);
// on cherche la taille maxi
Tableau <int> 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 <int>& nouveau_Noe_i = nouveau_Noe(i);
for (int j=1;j<=nb_zone;j++)
{ Tableau <int> & ta_inverse_old_ij = ta_inverse_old(i)(j);
Tableau <int> & 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<ElContact>::iterator > > > tesN_encontact;
// // on sauvegarde l'ancien
// Tableau < Tableau < LaLIST < LaLIST<ElContact>::iterator > > > tesN_encontact_old(tesN_encontact);
// // et on fait la passation
// for (int i=1;i<=nb_mail_Esclave;i++)
// {Tableau <int>& 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 <List_io < Element* > > *> 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 <List_io < Element* > > & 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 <ElContact>::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 <ElContact>::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;
};