Herezh_dev/herezh_pp/Maillage/Maillage.h

960 lines
53 KiB
C
Raw Normal View History

// FICHIER : Maillage.h
// CLASSE : Maillage
// 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/>.
/************************************************************************
* DATE: 23/01/97 *
* $ *
* AUTEUR: G RIO (mailto:gerardrio56@free.fr) *
* $ *
* PROJET: Herezh++ *
* $ *
************************************************************************
* BUT: def de la classe Maillage, *
* Une instance de la classe Maillage est identifiee a partir *
* de la dimension, des tableaux des noeuds et des elements. *
* $ *
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * *
* VERIFICATION: *
* *
* ! date ! auteur ! but ! *
* ------------------------------------------------------------ *
* ! ! ! ! *
* $ *
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
* MODIFICATIONS: *
* ! date ! auteur ! but ! *
* ------------------------------------------------------------ *
* $ *
************************************************************************/
#ifndef MAILLAGE_H
#define MAILLAGE_H
#include <iostream>
#include <map>
#include "Noeud.h"
#include "Element.h"
#include "Tableau_T.h"
#include "UtilLecture.h"
#include "Enum_geom.h"
#include "Enum_interpol.h"
#include "LesReferences.h"
#include "Front.h"
#include "LaList.h"
#include "Nb_assemb.h"
#include "Ddl_enum_etendu.h"
#include "Droite.h"
#include "Plan.h"
#include "Sphere.h"
#include "Cylindre.h"
#include "Cercle.h"
#include "Condilineaire.h"
#include "DiversStockage.h"
/// @addtogroup Les_Maillages
/// @{
///
//------------------------------------------------------------------
//! Maillage: un maillage particulier
//------------------------------------------------------------------
/// \author Gérard Rio
/// \version 1.0
/// \date 23/01/97
class Maillage
{
public :
friend class LesMaillages;
// CONSTRUCTEURS :
// pour tous les constructeurs: map < string, int , std::less <string> >* lisNomMail,
// est un tableau associatif nom <=> numéro de maillage, qui est utilisé par
// les maillages, mais mis à jour par chaque maillage.
// nom_maillage : est facultatif, s'il est différent de ".", il est pris en compte
// Constructeur par defaut
Maillage (map < string, int , std::less <string> > & lisNomMail,int nmail=1,int dim=3
,const string& nom_maillage = ".");
// Constructeur fonction d'une dimension, du nombre de noeuds
// du nombre d'elements, et d'un numero d'identification (le nb de maillage)
Maillage (map < string, int , std::less <string> > & lisNomMail
,int dim,int n_noeud,int n_elt,int nmail
,const string& nom_maillage = ".");
// Constructeur fonction de la plupart des informations (qui peuvent être vide
// mais doivent être cohérentes)
// *** il n'y a pas de création de nouveaux noeuds et de nouveaux éléments,
// ce sont les éléments et noeuds passés en paramètres qui sont ceux du maillage créé
Maillage (map < string, int , std::less <string> > & lisNomMail
,int dim,list <Noeud* >& li_noeud, list <Element* > li_element
,int nmail
,const string& nom_maillage = ".");
// Constructeur de copie, cependant ici il n'y a pas de création de noeud ni d'élément
// c'est seulement une création de nouveaux conteneurs de pointeurs
// cependant le numéro de maillage et le nom de maillage n'est pas valide, il faut
// ensuite les définir
Maillage (const Maillage& mail);
// Constructeur de copie, avec création de nouveaux noeuds et éléments identiques à ceux passées
// en argument, nmail: donne le numéro du nouveau maillage créée, qui est donc a priori différent
// de celui de mail, idem pour le nom du maillage
// les frontières ne sont pas transmises ni calculées !
Maillage (map < string, int , std::less <string> > & lisNomMail
,int nmail, const string& nomDuMaillage, const Maillage& mail);
// DESTRUCTEUR :
~Maillage ();
// METHODES :
// lecture de maillages au travers des outils de la classe
// UtilLecture et def des references s'y rapportant
void LectureMaillage(UtilLecture * entreePrinc,LesReferences& lesRef);
// lecture et application des opérations d'affinages sur le maillage: ex:déplacement solide
void LectureEtApplicationAffinage(UtilLecture * entreePrinc,LesReferences& lesRef);
// ajout d'une liste de noeud à un maillage
// si le numéro de maillage associé au noeud est nul, il est remplacé par celui du maillage
// si le numéro de maillage est déjà existant et est différent ce celui de this, il y a
// création d'un nouveau noeud identique, avec le numéro this
// ajout éventuel d'une liste de référence de noeuds, si celle-ci est non-nulle
// il y a création de nouvelles ref correspondantes au numéro de maillage de this
// et ces références sont rajoutées à lesRef
void Ajout_de_Noeuds(const list <Noeud *> & taN,list <const Reference*>* lref=NULL,LesReferences* lesRef=NULL );
// ajout d'une liste d'éléments et de noeud à un maillage
// si le numéro de maillage associé à l'élément ou noeud est nul, il est remplacé par celui du maillage
// si le numéro de maillage est déjà existant et est différent ce celui de this, il y a
// création d'un nouvel item identique, avec le numéro this
// ajout éventuel d'une liste de références associées , si celle-ci est non-nulle
// il y a création de nouvelles ref correspondantes au numéro de maillage de this
// et ces références sont rajoutées à lesRef
// les noeuds qui sont associés aux éléments de taE, doivent faire partie : soit de taN, soit du maillage this
void Ajout_elements_et_noeuds(const list <Noeud *> & taN, const list <Element *> & taE,list <const Reference*>* lref,LesReferences* lesRef );
// affichage et definition interactive des commandes
// cas = 1: interactif complet
// cas = 2: entrée uniquement de noms de fichier
void Info_commande_Maillages(UtilLecture * entreePrinc,LesReferences& lesRef, int cas);
// Affiche les donnees du maillage
void Affiche () const ;
// Affiche les donnees du maillage dans un fichier
// dont le nom est construit à partir du nom du maillage
// au format ".her" et ".lis"
void Affiche_dans_her_lis(LesReferences &lesRef,Enum_dure temps);
//modification du maillage pour le restreindre aux seuls éléments de la référence passée en paramètre
// toutes les infos relatives à des éléments supprimés, sont également supprimés
void Restreint_sous_maillage(LesReferences* lesRef, string nom_ref);
// Surcharge de l'operateur = : realise l'egalite de deux maillages
// cependant le numéro de maillage et le nom de maillage n'est pas valide, il faut
// ensuite les définir
Maillage& operator= (Maillage& mail);
inline int Dimension () const
// Retourne la dimension
{ return dimension; };
// ramène la liste des problèmes physiques gérés par les éléments du maillage
inline const Tableau <Enum_ddl >& Ddl_representatifs_des_physiques()const
{return ddl_representatifs_des_physiques;};
// ramene la liste des degrés de liberté inconnus, associés aux pb
// physiques gérés par les éléments qui existent dans le maillage
// Si éléments mécaniques -> ddl Xi voir Vi et gamma_i
// Si éléments thermiques -> ddl de température
// Si éléments méca + éléments thermiques -> ddl Xi et température
// etc. en fonction des éléments qui existent dans le maillage
inline const Tableau <EnumElemTypeProblem >& Types_de_problemes() const
{return types_de_problemes;};
inline int Nombre_noeud_elt(int i) const
// Retourne le nombre de noeuds lies au ieme element
{ return tab_element(i)->Nombre_noeud(); };
inline int Nombre_noeud() const
// Retourne le nombre de noeuds du maillage
{ return tab_noeud.Taille(); };
inline int Nombre_element() const
// Retourne le nombre d'elements du maillage
{ return tab_element.Taille(); };
inline Tableau<Noeud *>& Tab_noeud()
// Retourne le tableau des noeuds
{ return tab_noeud; };
inline Tableau<Element *>& Tab_element()
// Retourne le tableau des elements
{ return tab_element; };
inline Noeud& Noeud_mail(int i)
// Retourne le ieme noeud Noeud du tableau tab_noeud
{ return *tab_noeud(i); };
inline Element& Element_mail(int i)
// Retourne le ieme element Element du tableau tab_element
{ return *tab_element(i); };
// idem mais en version constant
inline const Element& Element_mail_const(int i)
{ return *tab_element(i); };
// test si toutes les informations des maillages sont completes
// = true -> complet
// = false -> incomplet
bool Complet();
// ramene la demi largeur de bande en ddl et la largeur de bande
void Largeur_Bande(int& demi, int& total,const Nb_assemb& nb_casAssemb);
// test pour savoir si tous les coordonnées des noeuds d'un maillage sont imposé
// ramène 1 si tout est fixé, 0 sinon
int Tous_Xi_fixes(const Nb_assemb& casAss) const;
// calcule des normales aux noeuds: dans le cas d'éléments 1D ou 2D uniquement
// a priori le calcul s'effectue par une moyenne des normales des éléments qui
// entourent le noeud.
// init -> calcul des normales à t=0
// et ajout conteneur aux noeuds des normales à t = 0 et t
void InitNormaleAuxNoeuds();
// mise à jour -> mise à jour des normales à t
void MiseAjourNormaleAuxNoeuds();
// mise à jour -> mise à jour des normales à t
// mais ici, on calcule les normales à tdt, et on transfert à t
// cette méthode est utile si on veut utiliser des normales à t pour une valeur
// particulière (transitoire) de la géométrie à tdt
// cf: l'algo non dyna par exempel
void MiseAjourNormaleAuxNoeuds_de_tdt_vers_T();
// creation des elements frontiere
void CreeElemFront();
// ramene un pointeur sur la liste des elements frontieres
inline LaLIST <Front>* ListFront() { return &listFrontiere;};
// ramene le tableau des noeuds de la frontière
Tableau<Noeud *>& Tab_noeud_front() {return tab_noeud_front; };
// ramene le nom du maillage
string NomDuMaillage() {return nomDuMaillage;};
// change le nom et le numéro du maillage
void ChangeNomNumeroMaillage(const string & nom,int num);
// ramène le numéro du noeud le plus proche du point donné à t=0,
int Noeud_le_plus_proche_0(const Coordonnee& M);
// idem à t
int Noeud_le_plus_proche_t(const Coordonnee& M);
// idem à tdt
int Noeud_le_plus_proche_tdt(const Coordonnee& M);
// ramène le maximum de variation de coordonnée entre t et tdt de tous les noeuds du maillage
double Max_var_dep_t_a_tdt() const;
// ramène le minimum de la distance entre deux noeuds de l'ensemble des éléments
double Min_dist2Noeud_des_elements(Enum_dure temps) const;
// transfert de grandeurs des points d'intégration aux noeuds
// 1- en entrée les type de ddl internes que l'on veut transférer
// idem pour les type évoluées et les types particuliers
// 2- en entrée: cas qui indique la méthode de transfert à utiliser
// =1 : les valeurs aux noeuds sont obtenue par moyennage des valeurs des pts d'integ les plus près
// des éléments qui entourent le noeud
// on décompose le processus en trois étapes pour éviter d'initialiser plusieurs fois lorque l'on refait à chaque fois
// le même transfert
// A) première étape def des conteneurs et c'est tout, la méthode peut donc être utilisée
// pour autre chose. tabQ: permet d'avoir plusieurs listes de TypeQuelconque
// en entrée: tabQ doit-être de dimension 2, donc pointe sur 2 listes, si un des pointeur
// est nulle on n'en tient pas compte
void AjoutConteneurAuNoeud(const List_io < Ddl_enum_etendu >& lienu
,const Tableau <List_io < TypeQuelconque > * >& tabQ);
// B) initialisation des updates sur les noeuds
void InitUpdateAuNoeud(const List_io < Ddl_enum_etendu >& lienu
,const Tableau <List_io < TypeQuelconque > * >& tabQ,int cas);
// C) exécution du transfert
// transfert incrémental (pour un élément et tous les pt d'integ):
// transfert de ddl de tous les pt d'integ aux noeuds d'un éléments (on ajoute aux noeuds, on ne remplace pas)
// les ddl doivent déjà exister aux noeuds sinon erreur
// il doit s'agir du même type de répartition de pt d'integ pour toutes les grandeurs
void TransfertPtIntegAuNoeud(Element& ele,const List_io < Ddl_enum_etendu >& lietendu
,const Tableau <Tableau <double> > & tab_val,int cas)
{ele.TransfertAjoutAuNoeuds(lietendu,tab_val,cas);};
// idem pour des grandeurs quelconques, transfert de "tous" les points d'intégration en même temps
// ceci pour optimiser, les informations sont ici contenues dans les types quelconques
// liQ_travail: est une liste de travail qui sera utilisée dans le transfert
// - transfert de type quelconque des points d'intégrations (de tous) aux noeuds d'un éléments (on ajoute aux noeuds,
// - on ne remplace pas). Les types quelconques doivent déjà exister.
// - un tableau tab_liQ correspondent aux grandeurs quelconque pour tous les pt integ. tab_liQ(i) est associé au pt d'integ i
// - Toutes les listes sont identiques au niveau des descripteurs (types...) ce sont uniquement les valeurs numériques
// - c-a-dire les valeurs associées à TypeQuelconque::Grandeur qui sont différentes (elles sont associées à chaque pt d'integ)
// - liQ_travail: est une liste de travail qui sera utilisée dans le transfert
void TransfertPtIntegAuNoeud(Element& ele,const Tableau <List_io < TypeQuelconque > >& tab_liQ
,List_io < TypeQuelconque > & liQ_travail,int cas)
{ele.TransfertAjoutAuNoeuds(tab_liQ,liQ_travail,cas);};
// D) dernière étape: (par exemple calcul des moyennes en chaque noeuds)
// les résultats sont stockés aux noeuds
void FinTransfertPtIntegAuNoeud(const List_io < Ddl_enum_etendu >& lienu
,const Tableau <List_io < TypeQuelconque > * >& tabQ,int cas);
// ..... cumul et moyenne de grandeurs venant des éléments vers les noeuds (exemple la pression appliquée) .....
// on décompose le processus en 4 étapes pour éviter d'initialiser plusieurs fois lorque l'on refait à chaque fois
// la même opération (typiquement à chaque incrément)
// on peut utiliser:
// A) AjoutConteneurAuNoeud : pour ajouter des conteneurs ad hoc aux noeuds
// B) InitUpdateAuNoeud: avant le cumul, initialise les conteneurs
// C) Accumul_aux_noeuds : balaie les éléments avec cumul aux noeuds
// D) MoyenneCompteurAuNoeud : effectue les moyennes aux noeuds
// accumulation aux noeuds de grandeurs venant des éléments vers leurs noeuds (exemple la pression appliquée)
// autres que celles aux pti classiques, mais directements disponibles
// le contenu du conteneur stockées dans liQ est utilisé en variable intermédiaire
void Accumul_aux_noeuds(const List_io < Ddl_enum_etendu >& lietendu
,List_io < TypeQuelconque > & liQ,int cas)
{int NBE=tab_element.Taille();
for (int i=1;i<=NBE;i++)
tab_element(i)->Accumul_aux_noeuds(lietendu,liQ,cas);
};
// fonctions utilitaires du même genre
// ajout sur le maillage d'un conteneur particulier quelconque
void AjoutConteneurAuNoeud(TypeQuelconque& tQ);
// ajout sur le maillage d'un ou plusieur ddl_enum_etendu comme conteneur
void AjoutConteneurAuNoeud(const List_io < Ddl_enum_etendu >& lienu);
// initialisation des updates de ddl_étendu uniquement sur les noeuds: on met à 0 les ddl_etendu correspondant,
// les compteurs, comptant le nombre de fois où les noeuds sont modifiés, sont mis à 0
void InitUpdateAuNoeud(const List_io < Ddl_enum_etendu >& lienu);
// idem pour un seul ddl_etendu
void InitUpdateAuNoeud(const Ddl_enum_etendu & enu);
// moyenne des valeurs aux noeuds (en fonction du nombre ou le noeud a été modifié)
void MoyenneCompteurAuNoeud(const Ddl_enum_etendu & enu);
// initialisation des coordonnées à t et tdt aux mêmes valeurs qu'à 0
// utile quand on veut utiliser les métriques pour un pb non couplés
void Init_Xi_t_et_tdt_de_0();
// def d'un conteneur pour deux numéros: elem et pti
class NBelemEtptInteg
{public: int nbElem; int nbPtInteg;
// surcharge de l'operator de lecture
friend istream & operator >> (istream & ent, NBelemEtptInteg & de)
{ ent >> de.nbElem >> de.nbPtInteg; return ent;};
// surcharge de l'operator d'ecriture
friend ostream & operator << (ostream & sort , const NBelemEtptInteg & de)
{ sort << de.nbElem <<" " << de.nbPtInteg << " "; return sort;};
bool operator < (const NBelemEtptInteg& c) const; bool operator > (const NBelemEtptInteg& c) const;
bool operator == (const NBelemEtptInteg& c) const {return ((nbElem==c.nbElem)&&(nbPtInteg==c.nbPtInteg));};
bool operator != (const NBelemEtptInteg& c) const {return !((nbElem==c.nbElem)&&(nbPtInteg==c.nbPtInteg));};
};
// def d'un conteneur pour 3 numéros: elem, num face ou arete, et pti
class NBelemFAEtptInteg
{public: int nbElem; int nbFA; int nbPtInteg;
// surcharge de l'operator de lecture
friend istream & operator >> (istream & ent, NBelemFAEtptInteg & de)
{ ent >> de.nbElem >> de.nbFA >> de.nbPtInteg; return ent;};
// surcharge de l'operator d'ecriture
friend ostream & operator << (ostream & sort , const NBelemFAEtptInteg & de)
{ sort << de.nbElem <<" "<< de.nbFA <<" " << de.nbPtInteg << " "; return sort;};
bool operator < (const NBelemFAEtptInteg& c) const; bool operator > (const NBelemFAEtptInteg& c) const;
bool operator == (const NBelemFAEtptInteg& c) const {return ((nbElem==c.nbElem)&&(nbFA==c.nbFA)&&(nbPtInteg==c.nbPtInteg));};
bool operator != (const NBelemFAEtptInteg& c) const {return !((nbElem==c.nbElem)&&(nbFA==c.nbFA)&&(nbPtInteg==c.nbPtInteg));};
};
// ramène le numéro de l'élément qui contiend un point donné et le numéro du point
// d'intégration le plus proche pour les ddl de la liste, (ddl spécifique à l'élément c'est-a-dire
// hors des ddl des noeuds de l'éléments)
// si pas de numéro d'élément ramène un numéro d'élément nulle
// si les numéros de point d'intégration ne sont pas identique pour l'ensemble
// des ddl, pb !!, le numéro du pt integ de retour est alors négatif
// enu_temps: dit si les coordonnées du point M sont à 0 ou t ou tdt
NBelemEtptInteg Element_le_plus_proche
(Enum_dure enu_temps,const List_io <Ddl_enum_etendu>& list_enu,const Coordonnee& M);
// ramène le numéro de l'élément dont le centre de gravité à t = enu_temps est le plus proche d'un point donné
// Le point peut être n'importe où, en particulier à l'extérieur de la matière
// si pb retour de null
const Element* Centre_de_Gravite_Element_le_plus_proche(Enum_dure enu_temps,const Coordonnee& M);
// ramène pour chaque noeud, la liste des éléments qui contiennent le noeud
// si le tableau n'existe pas, il est construit, sinon uniquement un retour
// et la miss à jour est uniquement faite lors de la création des frontières
const Tableau <List_io < Element* > >& Indice()
{if (indice.Taille() == 0) Calcul_indice();
return indice; };
//----- lecture écriture dans base info -----
// cas donne le niveau de la récupération
// = 1 : on récupère tout
// = 2 : on récupère uniquement les données variables (supposées comme telles)
void Lecture_base_info(ifstream& ent,const int cas);
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void Ecriture_base_info(ofstream& sort,const int cas);
// sortie du schemaXML: en fonction de enu
static void SchemaXML_Maillages(ofstream& sort,const Enum_IO_XML enu) ;
// ------ informations utiles par exemples pour la visualisation
// retourne les dimensions minis et maxi suivant les axes du repère
// absolu du maillage (en faite le calcul est fondé
// uniquement sur la position des noeuds du maillage
// le premier vecteur contient les minimums
// le deuxième vecteur contient les maximums
Tableau <Vecteur> Taille_boiteMail();
// --------- utilitaires de manipulation de maillage
// test pour savoir si le maillage contiend des éléments à interpolation linéaire
bool Contient_lineaire();
// test pour savoir si le maillage contiend des éléments à interpolation quadratique incomplète
bool Contient_quadratique_incomplet();
// transformation des éléments linéaires du maillage en quadratiques.
// les éléments linéaires sont supprimés,
// Important: dans la procédure de renumérotation, la routine modifie la numérotation initiale des noeuds !!
// il y a également création de référence adaptée au nouveau maillage en cohérence avec l'ancien maillage
void Transfo_lin_quadraIncomp(LesReferences &lesRef);
// transformation des éléments quadratiques incomplet du maillage en quadratiques complets.
// les éléments incomplets sont supprimée,
// Important: dans la procédure de renumérotation, la routine modifie la numérotation initiale des noeuds !!
// il y a également création de référence adaptée au nouveau maillage en cohérence avec l'ancien maillage
void Transfo_quadraIncomp_quadraComp(LesReferences &lesRef);
// relocalisation des points milieux des arrêtes des éléments quadratiques
void RelocPtMilieuMailleQuadra();
// définition interactive de listes de références
void CreationInteractiveListesRef(LesReferences* lesRef);
// modification de l'orientation d'éléments
void Modif_orientation_element(int cas_orientation,LesReferences* lesRef);
// Lecture et Collapse des éléments supperposés, c-a-d identiques, dans le cas où il en existe
void LectureEtCollapse_element_superpose(UtilLecture * entreePrinc,LesReferences* lesRef);
// Collapse des éléments supperposés, c-a-d identiques, dans le cas où il en existe
void Collapse_element_superpose(LesReferences* lesRef);
// Lecture et collapse de noeuds très proche: appartenant à des éléments différents
void LectureEtCollapse_noeuds_proches(UtilLecture * entreePrinc, LesReferences* lesRef);
// collapse de noeuds très proche: appartenant à des éléments différents
// rayon : donne la distance maxi entre les noeuds qui doivent être collapsé
void Collapse_noeuds_proches(double rayon, LesReferences* lesRef);
// Lecture et suppression d'elements à 2 noeuds, de distances très proches
void LectureEtSup_Elem_noeudsConfondu(UtilLecture * entreePrinc, LesReferences* lesRef);
// suppression d'elements à 2 noeuds, de distances très proches
// rayon : donne la distance maxi entre les noeuds
void Sup_Elem_noeudsConfondu(double rayon, LesReferences* lesRef);
// création d'éléments SFE en fonction d'éléments classiques
void CreationMaillageSFE();
// test pour savoir si le maillage est ok pour être transformée en sfe
bool OKPourTransSfe();
// lecture et suppression éventuelle des noeuds, non référencés par les éléments et les références
void LectureEtSuppressionNoeudNonReferencer(UtilLecture * entreePrinc,LesReferences& lesRef);
// uniquement suppression éventuelle des noeuds, non référencés par les éléments et les références
void SuppressionNoeudNonReferencer(LesReferences& lesRef);
// Affichage des noeuds, non référencés par les éléments
void AffichageNoeudNonReferencer();
// lecture et création éventuelle d'une ref sur les noeuds, non référencés par les éléments
void LectureEtCreationRefNoeudNonReferencer(UtilLecture * entreePrinc,LesReferences& lesRef);
// création éventuelle d'une référence sur les noeuds, non référencés par les éléments
void CreationRefNoeudNonReferencer(LesReferences& lesRef);
// vérification que toutes les références de noeuds, d'éléments, d'arêtes et de faces sont valides
// c-a-d se réfèrent à des éléments existants
void VerifReference(LesReferences& lesRef);
// lecture et renumérotation éventuelle des noeuds
void LectureEtRenumerotation(UtilLecture * entreePrinc,LesReferences& lesRef);
// renumérotation des noeuds du maillage, en fonction de conditions linéaires éventuelles
// ramène false si rien n'a changé (à cause d'un pb ou parce que la renumérotation n'est pas meilleure), vrai sinon
bool Renumerotation(LesReferences& lesRef,const Tableau <Tableau <Condilineaire> >& condCLL);
// création automatique des références globales de frontière si demandé dans le .info
void CreationRefFrontiere(UtilLecture * entreePrinc,LesReferences& lesRef);
// demande de création automatique des références globales de frontière
void CreationRefFrontiere(LesReferences& lesRef);
// force la mise à une valeur d'un ddl (ou de la liste de ddl fonction de la dimention) particulier, quelques soit son activité
// si fonction_de_la_dimension = true : c'est toute les ddl fct de la dimension qui sont mis à la valeur
void Force_Ddl_aux_noeuds_a_une_valeur(Enum_ddl enu, const double& val,Enum_dure temps, bool fonction_de_la_dimension);
// mise à zéro de dd_enum_etendu aux noeuds : force la mise à une valeur à 0
void Force_Ddl_etendu_aux_noeuds_a_zero(const Tableau<Ddl_enum_etendu>& tab_enu);
protected :
int idmail ; // numero de maillage
string nomDuMaillage;
// liste communes de tous les noms de maillages associée à un numéro
// sous forme d'un arbre pour faciliter la recherche
// cette liste n'est modifiée que par chaque maillage
map < string, int , std::less <string> >& listeNomMail;
int dimension; // dimension du maillage
Tableau<Noeud *> tab_noeud; // tableau des noeuds du maillage
Tableau<Element *> tab_element; // tableau des elements du maillage
// list des elements frontieres du maillage, c-a-d des frontières uniques
LaLIST <Front> listFrontiere;
// tableau des noeuds des éléments frontières
Tableau <Noeud *> tab_noeud_front;
// tableau utilitaire:
// indice(i) contient la liste des éléments qui contiennent le noeud i
Tableau <List_io < Element*> > indice;
// pour chaque élément "i" , mitoyen_de_chaque_element(i)(j) contient l'élément Front
// qui décrit la frontière "j" de l'élément et dedans, les éléments mitoyens de cette frontière
// appartenant à d'autres éléments (ce tableau est construit par la méthode : Mitoyen())
Tableau < Tableau <Front> > mitoyen_de_chaque_element;
// définie la liste des types de degrés de liberté inconnus, qui vont être calculés par la résolution des problèmes
// physiques gérés par les éléments qui existent dans le maillages
// Si éléments mécaniques -> ddl Xi voir Vi et gamma_i
// Si éléments thermiques -> ddl de température
// Si éléments méca + éléments thermiques -> ddl Xi et température
// etc. en fonction des éléments qui existent dans les maillages
// (généré à la lecture du maillage, ce qui permet d'optimiser la consultation par la suite)
Tableau <Enum_ddl > ddl_representatifs_des_physiques;
// idem au niveau des types de problèmes gérés par les éléments
Tableau <EnumElemTypeProblem > types_de_problemes;
//indicateur uniquement utilisé pour la destruction, par défaut est toujours vrai
// via la méthode Preparation_destruction_avec_conservation_noeuds_elements(), on peut le modifier
bool detruire_les_noeuds_et_elements;
// -- variables internes utilisées par Orientation_elements_mitoyens_recursif
// tab_sens_element(i) : = 1 au début, puis vaut -1 si le sens de l'élément i à été changé
Tableau <double> tab_sens_element; // pendant les différents appels de Orientation_elements_mitoyens_recursif
// - on définit un tableau d'indicateur, permettant de savoir si un élément a été traité ou pas
// une fois qu'un élément a été traité: a) on ne permet plus son changement de sens
// b) de plus dans le cas d'une suite d'appels récursif, il n'est plus retenue pour les nouvelles listes
Tableau <bool> ind_elem; // def et init à 0, c-à-d non traité
// -- fin variables internes utilisées par Orientation_elements_mitoyens_recursif
// METHODES PROTEGEES :
// cas particulier de destruction, sans suppression des noeuds et éléments
// l'utilisation de la méthode suivante, permet ensuite de supprimer le maillage
// tout en évitant la destruction des noeuds internes et éléments internes
// à utiliser avec précaution, intéressant si l'on veut créer un nouveau maillage
// avec les noeuds et éléments de ce maillage
void Preparation_destruction_avec_conservation_noeuds_elements()
{ detruire_les_noeuds_et_elements = false; };
// change le numéro de maillage
void Change_numero_maillage(int new_num);
// definition des elements mitoyens aux elements de frontiere
// à la fin du programme tous les éléments mitoyens sont stocké dant les éléments
// Front et non les éléments frontières qui eux sont supprimés
void MitoyenFront();
// création pour chaque noeud de la liste des éléments qui contiennent le noeud
void Calcul_indice();
// definition d'un stockage contenant tous les Front associés à toutes les frontières de tous les éléments
// puis définition des elements mitoyens à ces Front : deux éléments Front sont mitoyens
// s'ils correspondent à des Element différents, et si les frontières associées possèdent les mêmes noeuds
// toutes ces informations sont stockées dans : mitoyen_de_chaque_element (cf. sa description)
void Calcul_tous_les_front_et_leurs_mitoyens();
// dans le cas où les éléments frontières sont des lignes, on les ordonnes
// de manière à former une ligne continue
void OrdonancementDesLigne();
// lectures des infos pour le choix d'un élément
void Lecture_info_1element(UtilLecture * entreePrinc,int& num_elt,Enum_geom& id_geom
,Enum_interpol& id_interpol,EnumElemTypeProblem& id_typeProb
,string& discriminant);
// lecture des mouvements solides si nécessaire
void Lecture_des_mouvements_solides(UtilLecture * entreePrinc);
// une classe de travail qui sert pour pouvoir classer les noeuds par leur position géométrique initiale
// deux élément sont identiques si leur position initiale sont identique
// a >= b si : soit a.x >= b.x, ou a.x==b.x et a.y >= b.y, ou a.x==b.x et a.y == b.y et a.z >= b.z
class PosiEtNoeud
{ public:
Noeud * noe; // le noeud
Element * el; // l'élément auquel il est rattaché
// -------- constructeur ------------
PosiEtNoeud() : noe(NULL),el(NULL) {}; // constructeur par défaut
PosiEtNoeud(Noeud * no,Element * e) : noe(no),el(e) {}; // constructeur normal
PosiEtNoeud(const PosiEtNoeud& po) : noe(po.noe),el(po.el) {}; // constructeur de copie
//------ surcharges qui ne travaillent que sur la position --------
PosiEtNoeud& operator= (const PosiEtNoeud& po); // affectation
bool operator == (const PosiEtNoeud& po) const ; // test d'égalité
bool operator != (const PosiEtNoeud& po) const ; // test d'inégalité
bool operator < (const PosiEtNoeud& po) const ; // relation d'ordre
bool operator <= (const PosiEtNoeud& po) const ; // relation d'ordre
bool operator > (const PosiEtNoeud& po) const ; // relation d'ordre
bool operator >= (const PosiEtNoeud& po) const ; // relation d'ordre
};
// fonctions simples ayant pour but de bien repérer des opérations dangereuses
// affectation d'un noeud au maillage c-a-d au tableau de pointeur de noeud,
// a condition que la place ne soit pas déjà occupée sinon on change le numéro
// de noeud et on augmente le tableau
void Affectation_noeud (Noeud& noeud);
// affectation d'un element au maillage c-a-d au tableau de pointeur d'element,
// a condition que la place ne soit pas déjà occupée sinon on change le numéro
// de l'élément et on augmente le tableau
void Affectation_element (Element& element);
// Modifie le nombre de noeuds du maillage (N.B.: Fait appel
// a la methode Change_taille de la classe Tableau<Noeud>)
// les éléments supplémentaires ont un pointeur mis à Null
void Change_nb_noeud (int nouveau_nb);
// Modifie le nombre d'elements du maillage (N.B.: Fait appel
// a la methode Change_taille de la classe Tableau<Element>)
// les éléments supplémentaires ont un pointeur mis à Null
void Change_nb_element (int nouveau_nb);
// ** pour l'instant ne fonctionne que pour les éléments surfaces
// orientation automatique des éléments mitoyens, à l'élément num_elem, et ensuite
// récursivement à tous les éléments mitoyens des mitoyens jusqu'à ce que la chaine s'arrête
// L'ensemble des éléments est alors groupé dans une référence qui est construit à partir du numéro num_elem
// et qui est ajouté aux refs déjà existantes
// ensuite, le programme passe en revue les éléments restants, et regarde s'ils font parti
// d'un ensemble homogène orienté, si non, ramène la liste des éléments hors ensemble orienté
// *** ne concerne que les éléments surfaces, les autres sont ignorés
// ind_elem(i) : (tableau interne) indique si l'élément i a été traité (=true) ou non (=false)
// ind_elem: est pris en compte puis mis à jour par le programme, c-a-d que les nouveaux éléments orienté
// passe de false à true, par contre tous les éléments déjà à true, ne sont pas pris en compte dans le traitement
// angle_maxi : angle maximum entre deux éléments, au dessus duquel on considère qu'il y a une rupture de la mitoyenneté
// nom_ref : s'il est différent de "_", donne le nom de base voulu à la série de référence qui va être construite
// inverse : indique si l'on souhaite partir d'une orientation inverse de celle existante avant application de l'algo
// ceci pour l'élément de départ: au premier appel, l'opération est toujours possible, ensuite cela dépend
// si l'élément trouvé a déjà été traité ou pas
// recursiv : indique si l'on se situe dans une suite récursive d'appel de la méthode
// si oui, seule les éléments non déjà pris en compte dans les appels précédents, sont examiné
// c'est ind_elem qui permet de s'en assurer
// si non: cas par exemple d'un angle_maxi qui change, on réexamine tous les éléments, cependant
// la ré_orientation éventuelle n'est faite qu'une seule fois (toujours via ind_elem)
list <int> Orientation_elements_mitoyens_recursif(bool recursif,string& nom_ref,int num_elem
, LesReferences& lesRef,double& angle_maxi,bool inverse);
// méthode pour initialiser les différents tableaux utilisés par Orientation_elements_mitoyens_recursif
void Init_Orientation_elements_mitoyens_recursif();
// méthode pour orienter des éléments en fonction d'un rayon: AG, A étant un point donné, G étant le centre de
// gravité d'une facette
// A : coordonnée d'un point, si indic_G(i) est true, alors A(i) est remplacé par la coordonnée G(i) du centre
// de gravité de la facette
// zone_a_traiter: le nom de la référence des éléments a traiter
// inverse : si true, l'orientation des normales des facettes est identique à celles de AG, sinon c'est l'inverse
void Orientation_via_rayon(const Tableau <bool> & indic_G,const Coordonnee & A
,const string& zone_a_traiter, LesReferences& lesRef, bool inverse);
// ------- pour la définition interactive de liste de ref -------------
// def d'un conteneur pour deux numéros: nb element nb face
class NBelemEtFace {public: int nbElem; int nbFace;
bool operator < (const NBelemEtFace& c) const; bool operator > (const NBelemEtFace& c) const;
bool operator == (const NBelemEtFace& c) const {return ((nbElem==c.nbElem)&&(nbFace==c.nbFace));};
bool operator != (const NBelemEtFace& c) const {return !((nbElem==c.nbElem)&&(nbFace==c.nbFace));};
};
// def d'un conteneur pour deux numéros: nb element nb arête
class NBelemEtArete {public: int nbElem; int nbArete;
bool operator < (const NBelemEtArete& c) const; bool operator > (const NBelemEtArete& c) const;
bool operator == (const NBelemEtArete& c) const {return ((nbElem==c.nbElem)&&(nbArete==c.nbArete));};
bool operator != (const NBelemEtArete& c) const {return !((nbElem==c.nbElem)&&(nbArete==c.nbArete));};
};
// calcul des listes de références en fonction de la demande:
// list_nomReference: contient les types de refs que l'on veut
// list_methode: contient la ou les méthodes que l'on veut utiliser
// cas 1D
void CalculListRef_1D(list<string>& list_nomReference,LesReferences* lesRef,list<string>& list_methode
,const Enum_ddl & enu_ddl);
// cas 2D
void CalculListRef_2D(list<string>& list_nomReference,LesReferences* lesRef,list<string>& list_methode
,const Enum_ddl & enu_ddl);
// cas 3D
void CalculListRef_3D(list<string>& list_nomReference,LesReferences* lesRef,list<string>& list_methode
,const Enum_ddl & enu_ddl);
// les méthodes de bases
// fonction générique pour des condition PresDe
void PresDe(const list<string>& list_nomReference, list <Noeud *>& list_noeud_restant
,list <Element *>& list_element_restant,const Enum_ddl& enu_ddl
,list <NBelemEtptInteg>& list_elemPtin_restant,bool& premLpti
,list <NBelemEtFace>& list_elemFace_restant,bool& premLface
,list <NBelemEtArete>& list_elemArrete_restant,bool& premLarrete);
// fonction générique pour des condition "tout dedans"
void ToutDedans(const list<string>& list_nomReference, list <Noeud *>& list_noeud_restant
,list <Element *>& list_element_restant,const Enum_ddl& enu_ddl
,list <NBelemEtptInteg>& list_elemPtin_restant,bool& premLpti
,list <NBelemEtFace>& list_elemFace_restant,bool& premLface
,list <NBelemEtArete>& list_elemArrete_restant,bool& premLarrete);
// constitution des références
void EnregRef(const list<string>& list_nomReference,list <Noeud *>& list_noeud_restant
,list <NBelemEtptInteg>& list_elemPtin_restant,list <Element *>& list_element_restant
,list <NBelemEtFace>& list_elemFace_restant,list <NBelemEtArete>& list_elemArrete_restant
,LesReferences* lesRef);
// définition des fonctions conditions
// def de data internes qui servent pour les fonctions init et exe: dimensionnées dans init, utilisé dans exe
// donc: init et exe doivent être utilisé absolument à suivre
Tableau <Coordonnee> t_poi;
Tableau <Droite> t_droit;
Tableau <double> t_para;
Tableau <Plan> t_plan;
Tableau <Sphere> t_sphere;
Tableau <Cylindre> t_cylindre;
Tableau <Cercle> t_cercle;
// cas de croisement avec des références existantes: def de variables de passage pour InRef et OutRef
// les pointeurs qui suivent ne servent pas à créer des refs, mais uniquement a récupérer les adresses
list <const Reference*> list_refIn;
list <const Reference*> list_refOut;
LesReferences* lesRefin; // variable utilisée uniquement pour le passage d'info à
// ,InitInRef(), ExeInRef (), InitOutRef(), ExeOutRef()
// tout d'abord les pointeurs de fonctions en cours
// - pour les conditions Presde
// acquisition interactive des paramètres de la condition
void (Maillage::*initConditionPresDe) (double& dist);
// exécution de la condition : ramène true si ok, false sinon
bool (Maillage::*ExeConditionPresDe) (const double& dist,const Coordonnee& M)const;
// - pour les condition ToutDedans
// acquisition interactive des paramètres de la condition
void (Maillage::*initConditionToutDedans) ();
// exécution de la condition : ramène true si ok, false sinon
bool (Maillage::*ExeConditionToutDedans) (const Tableau <Coordonnee> & tab_M)const;
// recherche près d'un point
// def interactive du point et de la distance
void InitPresPoint(double& dist);
// exécution de la condition
bool ExePresPoint(const double& dist,const Coordonnee& M) const;
// recherche d'un coté d'un point (en 1D)
void InitCotePoint();
// ramène true si tous les points sont du même coté que t_poi(1)
bool ExeCotePoint(const Tableau <Coordonnee> & t_M)const;
// recherche entre deux points (1D)
void InitEntrePoint();
// ramène true si tous les points sont entre t_poi(1) et t_poi(2)
bool ExeEntrePoint(const Tableau <Coordonnee> & t_M)const;
// recherche entre deux points (1D) _avec_distance
void InitEntrePoint_avec_distance();
// ramène true si tous les points sont entre t_poi(1) et t_poi(2)
bool ExeEntrePoint_avec_distance(const Tableau <Coordonnee> & t_M)const;
// recherche près d'une ligne
void InitPresLigne(double& dist);
bool ExePresLigne(const double& dist,const Coordonnee& M)const;
// dans le cas particulier d'une ligne, on peut ordonner certaines listes résultantes / à la lignes
// il s'agit des noeuds et des pt d'integ: on les ordonnes par rapport à leurs projections sur la lignes
void InitOrdonneLigne();
void OrdonneLigne(list <Noeud *>& list_noeud_restant,list <NBelemEtptInteg>& list_elemPtin_restant
,const Enum_ddl& enu_ddl);
// recherche près d'un cercle
void InitPresCercle(double& dist);
bool ExePresCercle(const double& dist,const Coordonnee& M)const;
// recherche près d'un plan
void InitPresPlan(double& dist);
bool ExePresPlan(const double& dist,const Coordonnee& M)const;
// recherche près d'un cylindre
void InitPresCylindre(double& dist);
bool ExePresCylindre(const double& dist,const Coordonnee& M)const;
// recherche près d'une sphere
void InitPresSphere(double& dist);
bool ExePresSphere(const double& dist,const Coordonnee& M)const;
// recherche d'un coté d'un plan
void InitCotePlan();
// ramène true si tous les points sont du même coté que t_poi(1) du plan
bool ExeCotePlan(const Tableau <Coordonnee> & t_M)const;
// condition entre plans //
void InitEntrePlan();
// ramène true si tous les points sont entre les deux plans
bool ExeEntrePlan(const Tableau <Coordonnee> & t_M)const;
// condition entre plans _avec_distance //
void InitEntrePlan_avec_distance();
// ramène true si tous les points sont entre les deux plans
bool ExeEntrePlan_avec_distance(const Tableau <Coordonnee> & t_M)const;
// condition dans ou dehors un cylindre
void InitDansCylindre();
// ramène true si tous les points sont dans le cylindre
bool ExeDansCylindre(const Tableau <Coordonnee> & t_M)const;
// ramène true si tous les points sont à l'extérieur du cylindre
bool ExeOutCylindre(const Tableau <Coordonnee> & t_M)const;
// condition entre deux cylindre
void InitEntreCylindre();
// ramène true si tous les points sont entre les deux cylindres
bool ExeEntreCylindre(const Tableau <Coordonnee> & t_M)const;
// condition dans ou dehors d'une sphére
void InitDansSphere();
// ramène true si tous les points sont dans la sphère
bool ExeDansSphere(const Tableau <Coordonnee> & t_M)const;
// ramène true si tous les points sont à l'extérieur de la sphère
bool ExeOutSpheres(const Tableau <Coordonnee> & t_M)const;
// condition entre deux spheres concentriques
void InitEntreSpheres();
// ramène true si tous les points sont entre les deux sphères
bool ExeEntreSpheres(const Tableau <Coordonnee> & t_M)const;
// condition du même coté d'une droite (en 2D seulement)
void InitCoteDroite();
// ramène true si tous les points sont du même coté que t_poi(1) de la droite (en 2D uniquement)
bool ExeCoteDroite(const Tableau <Coordonnee> & t_M)const;
// condition entre 2 droites (en 2D seulement)
void InitEntreDroite();
// ramène true si tous les points sont entre les 2 droites (en 2D uniquement)
bool ExeEntreDroite(const Tableau <Coordonnee> & t_M)const;
// condition entre 2 droites (en 2D seulement) _avec_distance
void InitEntreDroite_avec_distance();
// ramène true si tous les points sont entre les 2 droites (en 2D uniquement)
bool ExeEntreDroite_avec_distance(const Tableau <Coordonnee> & t_M)const;
// condition dans ou dehors un cercle (en 2D seulement)
void InitDansCercle();
// ramène true si tous les points sont dans le cercle
bool ExeDansCercle(const Tableau <Coordonnee> & t_M)const;
// ramène true si tous les points sont à l'extérieur du cercle
bool ExeOutCercle(const Tableau <Coordonnee> & t_M)const;
// condition entre cercles concentriques (en 2D seulement)
void InitEntreCercles();
// ramène true si tous les points sont entre les deux cercles concentriques
bool ExeEntreCercles (const Tableau <Coordonnee> & t_M)const;
// acquisition d'un plan
Plan Acquisition_interactive_plan();
// acquisition d'un point
Coordonnee Acquisition_interactive_point();
// acquisition d'une droite
Droite Acquisition_interactive_droite();
// acquisition d'un vecteur=direction
Coordonnee Acquisition_interactive_vecteur();
// condition d'appartenance à une référence existante
void InitInRef();
// condition d'exclusion à une référence existante
void InitOutRef();
// ---- mise en place de la condition d'appartenance ou d'exclusion à des références existantes
// contrairement aux autres conditions, cette condition est prise en compte au moment de la création finale
// de la référence dans la méthode : EnregRef, via les méthodes du 2)
// 1) une fonction qui ne fait rien, mais est là pour que le tout fonctionne normalement
bool Exe_In_out_avecRefExistantes(const Tableau <Coordonnee> & t_M)const; // ne fait rien
// 2) fonctions qui réellement font quelque chose: utilisées dans la méthode EnregRef
void Exe_In_out_avecRefExistantes_N(list <Noeud *>& list_noeud_restant);
void Exe_In_out_avecRefExistantes_E(list <Element *>& list_element_restant);
void Exe_In_out_avecRefExistantes_G(list <NBelemEtptInteg>& list_elemPtin_restant);
void Exe_In_out_avecRefExistantes_F(list <NBelemEtFace>& list_elemFace_restant);
void Exe_In_out_avecRefExistantes_A(list <NBelemEtArete>& list_elemArrete_restant);
// void InterOuDiff_avecRefExistantes(const Tableau <Coordonnee> & t_M)const;
//-------------------- méthodes particulières pour l'optimisation de largeur de bande ------------------------
// une classe intermédiaire pour pouvoir classer les noeuds en fonction du degré
class Noeud_degre
{ public: Noeud* noe; int degre;
Noeud_degre (): noe(NULL), degre(0) {};
Noeud_degre (Noeud* no,int deg): noe(no),degre(deg) {};
Noeud_degre (const Noeud_degre& no ): noe(no.noe), degre(no.degre) {};
~Noeud_degre() {};
bool operator > (const Noeud_degre& a) const { return (this->degre > a.degre);};
bool operator >= (const Noeud_degre& a) const { return (this->degre >= a.degre);};
bool operator < (const Noeud_degre& a) const { return (this->degre < a.degre);};
bool operator <= (const Noeud_degre& a) const { return (this->degre <= a.degre);};
Noeud_degre& operator= (const Noeud_degre& de) { degre = de.degre; noe = de.noe; return (*this);};
};
// méthode static: c-a-d indépendante des données du maillage (elle est générale)
// calcul du point de départ, en fonction de conditions linéaires éventuelles
// il y a également calcul des voisins et de la descendance du noeud de retour
// s'il y a un pb, calcul_ok en retour est false
static Noeud* Point_de_depart(const Tableau<Element *>& tab_elem
,const Tableau<Noeud *>& tab_noe
,const Tableau <Tableau <Noeud*> *> tt_noeud_front
,Tableau < LaLIST_io <Noeud* > >& t_voisin
, list < list < Noeud_degre > > & lis_descent
,const Tableau <Tableau <Condilineaire> >& condCLL,bool& calcul_ok);
// méthode static: c-a-d indépendante des données du maillage (elle est générale)
// calcul des voisins de tous les noeuds du maillage en fonction des éléments et de conditions
// linéaires éventuelles,
// en entrée/sortie t_voisin
// restriction: il faut que tab_noe contienne tous les noeuds référencés dans tab_elem et tt_t_condCLL
// s'il y a un pb, calcul_ok en retour est false
static Tableau < LaLIST_io <Noeud* > >& Voisins(const Tableau<Element *>& tab_elem
,const Tableau<Noeud *>& tab_noe
,Tableau < LaLIST_io <Noeud* > >& t_voisin
,const Tableau <Tableau <Condilineaire> >& t_t_condCLL,bool& calcul_ok);
// méthode static: c-a-d indépendante des données du maillage (elle est générale)
// calcul de la descendance d'un noeud noeu,
// on considère que les voisins sont dèjà correctement définis
// en entrée la liste qui est modifiée en interne et retournée en sortie
// le premier élément de la liste c'est la dernière descendance
// s'il y a un pb, calcul_ok en retour est false
static list < list < Noeud_degre > > & Descendance (const int& taille_tabnoeud
,Noeud * noeu, Tableau < LaLIST_io <Noeud* > >& t_voisin
, list < list < Noeud_degre > > & lient,bool& calcul_ok);
// méthode static: c-a-d indépendante des données du maillage (elle est générale)
// algorithme de Cuthill Mac Kee directe
// noeu : le noeud de départ
// lis_descent : les descendants de noeu, qui va être modifié dans le processus
// ramène une nouvelle numérotation (mais les numéros internes des noeuds ne sont pas changé
static Tableau <Noeud* > Cuthill_Mac_Kee(const int& taille_tabnoeud,Noeud * noeu
,Tableau < LaLIST_io <Noeud* > >& t_voisin
, list < list < Noeud_degre > >& lis_descent);
// méthode static: c-a-d indépendante des données du maillage (elle est générale)
// calcul de la largeur de bande en noeuds
static int LargeurBandeEnNoeuds(const Tableau<Element *>& tab_elem);
// on s'occupe de mettre à jour les types de pb et les ddl types associés
void Mise_a_jour_type_pb_type_associe_ddl();
};
/// @} // end of group
#endif