2021-09-18 09:47:14 +02:00
// FICHIER : Maillage.cp
// 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.
//
2023-05-03 17:23:49 +02:00
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
2021-09-18 09:47:14 +02:00
// 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 "Maillage.h"
# include <iostream>
using namespace std ; //introduces namespace std
# include <stdlib.h>
# include "Sortie.h"
# include <stdio.h>
# include <vector>
# include "List_io.h"
# include "CharUtil.h"
2024-06-20 15:42:40 +02:00
// au cas où pour la bufferisation des io
# include <string> // std::string
# include <iostream> // std::cout
# include <sstream> // std::stringstream
2023-06-12 17:30:26 +02:00
//#ifndef SYSTEM_MAC_OS_X_unix
// #include "Frontier.h"
//#endif
2021-09-18 09:47:14 +02:00
# include "ConstMath.h"
# include "ReferenceNE.h"
# include "ReferenceAF.h"
# include "MvtSolide.h"
# include "TypeQuelconqueParticulier.h"
2024-08-29 09:31:24 +02:00
# ifdef UTILISATION_MPI
# include <boost/mpi/environment.hpp>
# include <boost/mpi/communicator.hpp>
# include <boost/serialization/string.hpp>
# include <boost/serialization/vector.hpp>
# include <boost/mpi.hpp>
namespace mpi = boost : : mpi ;
# endif
2021-09-18 09:47:14 +02:00
// 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_maill : est facultatif, s'il est différent de ".", il est pris en compte comme nom de maillage
// Constructeur par defaut
Maillage : : Maillage ( map < string , int , std : : less < string > > & lisNomMail , int nmail , int dim
, const string & nom_maill ) :
listeNomMail ( lisNomMail ) , nomDuMaillage ( ) , idmail ( nmail ) , dimension ( dim )
2023-05-03 17:23:49 +02:00
, tab_noeud ( ) , tab_element ( ) , listFrontiere ( ) , tab_noeud_front ( ) , indice ( ) , indice_NFr ( )
2021-09-18 09:47:14 +02:00
, list_refIn ( ) , list_refOut ( ) , lesRefin ( NULL ) , mitoyen_de_chaque_element ( )
, ddl_representatifs_des_physiques ( ) , types_de_problemes ( )
, ind_elem ( ) , tab_sens_element ( ) // tableaux internes utilisés par Orientation_elements_mitoyens_recursif
, detruire_les_noeuds_et_elements ( true )
2024-06-20 15:42:40 +02:00
# ifdef UTILISATION_MPI
2024-08-29 09:31:24 +02:00
, buffer_ioBI_MPI ( ) , offset_maillage ( ) , les_taille_buffer_ioBI_MPI ( )
, les_taille_buffer_ioBI_MPI_inter ( )
2024-06-20 15:42:40 +02:00
# endif
2021-09-18 09:47:14 +02:00
{ if ( nom_maill = = " . " )
{ // tout d'abord on donne un nom par défaut au maillage
nomDuMaillage = " pas_de_nom " ;
while ( listeNomMail . find ( nomDuMaillage ) ! = listeNomMail . end ( ) )
{ // on cherche un nom quelconque qui n'est pas déjà utilisé
nomDuMaillage + = ' _ ' ;
} ;
}
else // le paramètre de nom de maillage est valide
{ nomDuMaillage = nom_maill ;
} ;
// maintenant on associe le nom au numéro dans la map
listeNomMail [ nomDuMaillage ] = idmail ;
2024-06-20 15:42:40 +02:00
// #ifdef UTILISATION_MPI
// tablcarI_O_gros = new char [taille_tablcarI_O_gros] ; // def du tableau de travail
// #endif
2021-09-18 09:47:14 +02:00
} ;
// Constructeur fonction d'une dimension, du nombre de noeuds
// du nombre d'elements, et d'un numero d'identification (le nb de maillage)
Maillage : : Maillage ( map < string , int , std : : less < string > > & lisNomMail
, int dim , int n_noeud , int n_elt , int nmail , const string & nom_maill ) :
// Constructeur utile quand la dimension, le nombre de noeuds
// et le nombre d'elements du maillage sont connus
listeNomMail ( lisNomMail ) , tab_noeud ( n_noeud ) , tab_element ( n_elt ) , listFrontiere ( ) , tab_noeud_front ( )
2023-05-03 17:23:49 +02:00
, indice ( ) , indice_NFr ( ) , list_refIn ( ) , list_refOut ( ) , lesRefin ( NULL ) , mitoyen_de_chaque_element ( )
2021-09-18 09:47:14 +02:00
, ddl_representatifs_des_physiques ( ) , types_de_problemes ( )
, ind_elem ( ) , tab_sens_element ( ) // tableaux internes utilisés par Orientation_elements_mitoyens_recursif
, detruire_les_noeuds_et_elements ( true )
2024-06-20 15:42:40 +02:00
# ifdef UTILISATION_MPI
2024-08-29 09:31:24 +02:00
, buffer_ioBI_MPI ( ) , offset_maillage ( ) , les_taille_buffer_ioBI_MPI ( )
, les_taille_buffer_ioBI_MPI_inter ( )
2024-06-20 15:42:40 +02:00
# endif
2021-09-18 09:47:14 +02:00
{ if ( nmail < = 0 )
{ cout < < " \n Erreur : numero de maillage invalide ! \n " ;
cout < < " MAILLAGE::MAILLAGE(int ,int ,int,int ) \n " ;
Sortie ( 1 ) ;
} ;
idmail = nmail ;
// traitement du nom de maillage
if ( nom_maill = = " . " )
{ // on donne un nom par défaut au maillage
nomDuMaillage = " pas_de_nom " ;
while ( listeNomMail . find ( nomDuMaillage ) ! = listeNomMail . end ( ) )
{ // on cherche un nom quelconque qui n'est pas déjà utilisé
nomDuMaillage + = ' _ ' ;
} ;
}
else // le paramètre de nom de maillage est valide
{ nomDuMaillage = nom_maill ;
} ;
// maintenant on associe le nom au numéro dans la map
listeNomMail [ nomDuMaillage ] = idmail ;
if ( ( dim < 1 ) | | ( dim > 3 ) )
{ cout < < " \n Erreur : dimension invalide ! \n " ;
cout < < " MAILLAGE::MAILLAGE(int ,int ,int ,int) \n " ;
Sortie ( 1 ) ;
} ;
if ( n_noeud < = 0 )
{ cout < < " \n Erreur : nombre de noeuds non valide ! \n " ;
cout < < " MAILLAGE::MAILLAGE(int ,int ,int ,int) \n " ;
Sortie ( 1 ) ;
} ;
if ( n_elt < = 0 )
{ cout < < " \n Erreur : nombre d'elements invalide ! \n " ;
cout < < " MAILLAGE::MAILLAGE(int ,int ,int,int ) \n " ;
Sortie ( 1 ) ;
} ;
dimension = dim ;
} ;
// 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 : : Maillage ( map < string , int , std : : less < string > > & lisNomMail
, int dim , list < Noeud * > & li_noeud , list < Element * > li_element
, int nmail , const string & nom_maill ) :
listeNomMail ( lisNomMail ) , tab_noeud ( ) , tab_element ( ) , listFrontiere ( ) , tab_noeud_front ( )
2023-05-03 17:23:49 +02:00
, indice ( ) , indice_NFr ( ) , list_refIn ( ) , list_refOut ( ) , lesRefin ( NULL ) , mitoyen_de_chaque_element ( )
2021-09-18 09:47:14 +02:00
, ddl_representatifs_des_physiques ( ) , types_de_problemes ( )
, ind_elem ( ) , tab_sens_element ( ) // tableaux internes utilisés par Orientation_elements_mitoyens_recursif
, detruire_les_noeuds_et_elements ( true )
2024-06-20 15:42:40 +02:00
# ifdef UTILISATION_MPI
2024-08-29 09:31:24 +02:00
, buffer_ioBI_MPI ( ) , offset_maillage ( ) , les_taille_buffer_ioBI_MPI ( )
, les_taille_buffer_ioBI_MPI_inter ( )
2024-06-20 15:42:40 +02:00
# endif
2021-09-18 09:47:14 +02:00
{ if ( ParaGlob : : NiveauImpression ( ) > = 5 )
cout < < " \n creation du maillage: " < < nom_maill < < endl ;
if ( nmail < = 0 )
{ cout < < " \n Erreur2 : numero de maillage invalide ! \n " ;
cout < < " MAILLAGE::MAILLAGE( ) \n " ;
Sortie ( 1 ) ;
} ;
// si le numéro de maillage est déjà utilisé, on signale que la place est prise
for ( std : : map < string , int , std : : less < string > > : : iterator it = listeNomMail . begin ( ) ;
it ! = listeNomMail . end ( ) ; + + it )
{ if ( ( it - > second ) = = nmail )
{ cout < < " \n *** erreur: le numero de maillage " < < nmail
< < " est deja utilise pour le maillage " < < ( it - > first )
< < " \n constructeur: Maillage::Maillage (... " < < flush ;
Sortie ( 1 ) ;
} ;
} ;
// sinon c'est ok
idmail = nmail ;
// traitement du nom de maillage
if ( nom_maill = = " . " )
{ // on donne un nom par défaut au maillage
nomDuMaillage = " pas_de_nom " ;
while ( listeNomMail . find ( nomDuMaillage ) ! = listeNomMail . end ( ) )
{ // on cherche un nom quelconque qui n'est pas déjà utilisé
nomDuMaillage + = ' _ ' ;
} ;
}
else // le paramètre de nom de maillage est valide
{ nomDuMaillage = nom_maill ;
} ;
// maintenant on associe le nom au numéro dans la map
listeNomMail [ nomDuMaillage ] = idmail ;
if ( ( dim < 1 ) | | ( dim > 3 ) )
{ cout < < " \n Erreur2 : dimension invalide ! \n " ;
cout < < " MAILLAGE::MAILLAGE(... \n " ;
Sortie ( 1 ) ;
} ;
dimension = dim ;
// récupération des noeuds
int nbN = li_noeud . size ( ) ;
list < Noeud * > : : iterator il , ilfin = li_noeud . end ( ) ;
Change_nb_noeud ( nbN ) ;
// tab_noeud.Change_taille(nbN,NULL);
// on vérifie que la numérotation est correcte pour les noeuds
// c'est-à-dire que tous les numéros peuvent être rangés à suivre
bool numerotation_correcte = true ;
for ( il = li_noeud . begin ( ) ; il ! = ilfin ; il + + )
{ int nb = ( * il ) - > Num_noeud ( ) ;
if ( nb < 1 | | nb > nbN )
{ numerotation_correcte = false ;
break ;
} ;
} ;
if ( numerotation_correcte )
{ // on peut y aller sans vérif
for ( il = li_noeud . begin ( ) ; il ! = ilfin ; il + + )
tab_noeud ( ( * il ) - > Num_noeud ( ) ) = * il ;
}
else
// on est obligé de changer la numérotation des noeuds
{ int nb = 1 ;
for ( il = li_noeud . begin ( ) ; il ! = ilfin ; il + + , nb + + )
{ tab_noeud ( nb ) = * il ; int nbinit = ( * il ) - > Num_noeud ( ) ;
( * il ) - > Change_num_noeud ( nb ) ;
if ( ParaGlob : : NiveauImpression ( ) > 0 )
{ cout < < " \n warning : le numero initial du noeud " < < nbinit < < " est remplace par "
< < " le numero d'ordre attribue automatiquement par herezh " < < nb
< < " \n seul ce dernier sera utilise par la suite ! " < < endl ;
if ( ParaGlob : : NiveauImpression ( ) > 5 )
cout < < " \n Maillage::Maillage (map < string, int ,.... " < < endl ;
} ;
} ;
} ;
// récupération des éléments
int nbE = li_element . size ( ) ;
list < Element * > : : iterator ile , ilefin = li_element . end ( ) ;
Change_nb_element ( nbE ) ;
// on vérifie que la numérotation est correcte pour les éléments (comme pour les noeuds)
// c'est-à-dire que tous les numéros peuvent être rangés à suivre
numerotation_correcte = true ;
for ( ile = li_element . begin ( ) ; ile ! = ilefin ; ile + + )
{ int nb = ( * ile ) - > Num_elt ( ) ;
if ( nb < 1 | | nb > nbE )
{ numerotation_correcte = false ;
break ;
} ;
} ;
if ( numerotation_correcte )
{ // on peut y aller sans vérif
for ( ile = li_element . begin ( ) ; ile ! = ilefin ; ile + + )
tab_element ( ( * ile ) - > Num_elt ( ) ) = * ile ;
}
else
// on est obligé de changer la numérotation des éléments
{ int nb = 1 ;
for ( ile = li_element . begin ( ) ; ile ! = ilefin ; ile + + , nb + + )
{ tab_element ( nb ) = * ile ; int nbinit = ( * ile ) - > Num_elt ( ) ;
( * ile ) - > Change_num_elt ( nb ) ;
if ( ParaGlob : : NiveauImpression ( ) > 0 )
{ cout < < " \n warning : le numero initial de l'element " < < nbinit < < " est remplace par "
< < " le numero d'ordre attribue automatiquement par herezh " < < nb
< < " \n seul ce dernier sera utilise par la suite ! " < < endl ;
if ( ParaGlob : : NiveauImpression ( ) > 5 )
cout < < " \n Maillage::Maillage (map < string, int ,.... " < < endl ;
} ;
} ;
} ;
// on modifie le numéro de maillage pour les noeuds et éléments
int NBN_P1 = tab_noeud . Taille ( ) + 1 ;
for ( int nn = 1 ; nn < NBN_P1 ; nn + + )
tab_noeud ( nn ) - > Change_num_Mail ( idmail ) ;
int NBE_P1 = tab_element . Taille ( ) + 1 ;
for ( int ne = 1 ; ne < NBE_P1 ; ne + + )
tab_element ( ne ) - > Change_num_maillage ( idmail ) ;
if ( ParaGlob : : NiveauImpression ( ) > = 5 )
cout < < " \n fin creation du maillage: " < < nom_maill < < endl ;
} ;
// 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
// d'autre part le numéro de maillage et le nom de maillage n'est pas valide, il faut
// ensuite les définir
Maillage : : Maillage ( const Maillage & mail ) :
listeNomMail ( mail . listeNomMail ) , idmail ( mail . idmail ) , nomDuMaillage ( mail . nomDuMaillage ) , dimension ( mail . dimension )
, tab_noeud ( mail . tab_noeud ) , tab_element ( mail . tab_element )
, listFrontiere ( mail . listFrontiere ) , tab_noeud_front ( mail . tab_noeud_front )
2023-05-03 17:23:49 +02:00
, indice ( ) , indice_NFr ( ) , list_refIn ( ) , list_refOut ( ) , lesRefin ( NULL )
2021-09-18 09:47:14 +02:00
, mitoyen_de_chaque_element ( mail . mitoyen_de_chaque_element )
, ddl_representatifs_des_physiques ( mail . ddl_representatifs_des_physiques )
, types_de_problemes ( mail . types_de_problemes )
, ind_elem ( ) , tab_sens_element ( ) // tableaux internes utilisés par Orientation_elements_mitoyens_recursif
, detruire_les_noeuds_et_elements ( true )
2024-06-20 15:42:40 +02:00
# ifdef UTILISATION_MPI
2024-08-29 09:31:24 +02:00
, buffer_ioBI_MPI ( ) , offset_maillage ( ) , les_taille_buffer_ioBI_MPI ( )
, les_taille_buffer_ioBI_MPI_inter ( )
2024-06-20 15:42:40 +02:00
# endif
2021-09-18 09:47:14 +02:00
{ // tout d'abord on donne un nom par défaut au maillage
nomDuMaillage = " pas_de_nom " ;
while ( listeNomMail . find ( nomDuMaillage ) ! = listeNomMail . end ( ) )
{ // on cherche un nom quelconque qui n'est pas déjà utilisé
nomDuMaillage + = ' _ ' ;
} ;
// maintenant on associe le nom au numéro dans la map
listeNomMail [ nomDuMaillage ] = idmail ;
} ;
// 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 ! ni les normales,
// ni les infos concernant les intégrales (qui sont propres aux maillages existants)
Maillage : : Maillage ( map < string , int , std : : less < string > > & lisNomMail
, int nmail , const string & nomDu , const Maillage & mail ) :
listeNomMail ( lisNomMail ) , idmail ( nmail ) , nomDuMaillage ( nomDu ) , dimension ( mail . dimension )
, tab_noeud ( ) , tab_element ( ) , listFrontiere ( ) , tab_noeud_front ( )
2023-05-03 17:23:49 +02:00
, indice ( ) , indice_NFr ( ) , list_refIn ( ) , list_refOut ( ) , lesRefin ( NULL )
2021-09-18 09:47:14 +02:00
, mitoyen_de_chaque_element ( )
, ddl_representatifs_des_physiques ( mail . ddl_representatifs_des_physiques )
, types_de_problemes ( mail . types_de_problemes )
, ind_elem ( ) , tab_sens_element ( ) // tableaux internes utilisés par Orientation_elements_mitoyens_recursif
, detruire_les_noeuds_et_elements ( true )
2024-06-20 15:42:40 +02:00
# ifdef UTILISATION_MPI
2024-08-29 09:31:24 +02:00
, buffer_ioBI_MPI ( ) , offset_maillage ( ) , les_taille_buffer_ioBI_MPI ( )
, les_taille_buffer_ioBI_MPI_inter ( )
2024-06-20 15:42:40 +02:00
# endif
2021-09-18 09:47:14 +02:00
{ // on vérifie que le nom de maillage fourni n'existe pas
if ( listeNomMail . find ( nomDuMaillage ) ! = listeNomMail . end ( ) )
{ cout < < " \n erreur, le nom de maillage demande existe deja : " < < nomDuMaillage
< < " \n Maillage::Maillage (..... " ;
Sortie ( 1 ) ;
} ;
// on vérifie que le numéro de maillage proposé est valide
if ( idmail < = 0 )
{ cout < < " \n Erreur : numero de maillage invalide ! = " < < idmail < < " \n " ;
cout < < " MAILLAGE::MAILLAGE(.... \n " ;
Sortie ( 1 ) ;
} ;
// maintenant on associe le nom au numéro dans la map
listeNomMail [ nomDuMaillage ] = idmail ;
// on s'occupe tout d'abord des noeuds
int nbn = mail . tab_noeud . Taille ( ) ;
Change_nb_noeud ( nbn ) ;
for ( int ino = 1 ; ino < = nbn ; ino + + )
{ tab_noeud ( ino ) = new Noeud ( * ( mail . tab_noeud ( ino ) ) ) ;
tab_noeud ( ino ) - > Change_num_Mail ( nmail ) ;
} ;
// maintenant les éléments
int nbe = mail . tab_element . Taille ( ) ;
Change_nb_element ( nbe ) ;
for ( int ie = 1 ; ie < = nbe ; ie + + )
{ tab_element ( ie ) = mail . tab_element ( ie ) - > Nevez_copie ( ) ;
//debug
//tab_element(ie)->Affiche(1); cout << endl;
//fin debug
// on réaffecte les noeuds du maillage
Tableau < Noeud * > & ttab = tab_element ( ie ) - > Tab_noeud ( ) ;
int ttabtaille = ttab . Taille ( ) ;
for ( int ine = 1 ; ine < = ttabtaille ; ine + + )
ttab ( ine ) = tab_noeud ( ttab ( ine ) - > Num_noeud ( ) ) ;
// on change le numéro de maillage
tab_element ( ie ) - > Change_num_maillage ( idmail ) ;
} ;
// dans le cas où mail.mitoyen_de_chaque_element n'est pas vide,
// on construit le nouveau
if ( mail . mitoyen_de_chaque_element . Taille ( ) ! = 0 )
Calcul_tous_les_front_et_leurs_mitoyens ( ) ;
} ;
Maillage : : ~ Maillage ( )
// Destructeur
{ if ( detruire_les_noeuds_et_elements ) // cas normal
{ for ( int i = 1 ; i < = tab_noeud . Taille ( ) ; i + + )
delete tab_noeud ( i ) ;
for ( int i = 1 ; i < = tab_element . Taille ( ) ; i + + )
2024-06-20 15:42:40 +02:00
{ delete tab_element ( i ) ;
} ;
2021-09-18 09:47:14 +02:00
} ;
// pas de destruction de tab_noeud_front car ce sont des noeuds de tab_noeud, ils sont déjà détruit
} ;
void // lecture d'un maillage et def des references s'y rapportant
Maillage : : LectureMaillage ( UtilLecture * entreePrinc , LesReferences & lesRef )
{ if ( ParaGlob : : NiveauImpression ( ) > = 5 ) cout < < " debut de lecture de maillage " < < endl ;
if ( ParaGlob : : NiveauImpression ( ) > = 6 ) cout < < " lecture du nom de maillage " < < endl ;
// cas où il y a un nom de maillage
if ( strstr ( entreePrinc - > tablcar , " nom_maillage " ) ! = NULL )
{
// // on commence par mettre à jour listeNomMail en supprimant le doublet nom <=> numéro existant
// listeNomMail.erase(listeNomMail.find(nomDuMaillage));
// modif le 14 avril 2015
// non c'est une mauvaise idée, il faut au contraire arrêter le programme et dire qu'il y a
// deux fois le même nom, par contre si le nom de maillage c'est "pas_de_nom" il faut le supprimer
if ( ( nomDuMaillage = = " pas_de_nom " ) & & ( listeNomMail . find ( nomDuMaillage ) ! = listeNomMail . end ( ) ) )
listeNomMail . erase ( listeNomMail . find ( nomDuMaillage ) ) ;
string toto ;
* ( entreePrinc - > entree ) > > toto > > nomDuMaillage ;
if ( listeNomMail . find ( nomDuMaillage ) ! = listeNomMail . end ( ) )
{ cout < < " \n erreur *** plusieurs maillages ont le meme nom : " < < nomDuMaillage
< < " \n revoir les noms de maillage !! " < < endl ;
Sortie ( 1 ) ;
} ;
// maintenant on associe le nom au numéro dans la map
listeNomMail [ nomDuMaillage ] = idmail ;
// ensuite lecture de l'entête des noeuds
entreePrinc - > NouvelleDonnee ( ) ;
if ( strstr ( entreePrinc - > tablcar , " noeuds " ) = = NULL )
{ cout < < " *** erreur dans la lecture des noeuds "
< < " \n LectureMaillage(... " < < endl ;
entreePrinc - > MessageBuffer ( " ** lecture de l'entete des noeuds ** " ) ;
throw ( UtilLecture : : ErrNouvelleDonnee ( - 1 ) ) ;
Sortie ( 1 ) ;
} ;
}
else
// on définit un nom apriori uniquement dans le cas d'un seul maillage
// sinon c'est une erreur
{ if ( idmail = = 1 )
{ // on commence par mettre à jour listeNomMail en supprimant le doublet nom <=> numéro existant
listeNomMail . erase ( listeNomMail . find ( nomDuMaillage ) ) ;
nomDuMaillage = " premier_maillage " ;
// maintenant on associe le nom au numéro dans la map
listeNomMail [ nomDuMaillage ] = idmail ;
}
else
{ cout < < " \n Erreur dans la lecture du maillage " < < idmail < < " ****** " ;
cout < < " \n il n'y a pas de nom de maillage alors que c'est obligatoire !! "
< < " \n LectureMaillage(... " < < endl ;
entreePrinc - > MessageBuffer ( " ** lecture de l'entete des noeuds ** " ) ;
throw ( UtilLecture : : ErrNouvelleDonnee ( - 1 ) ) ;
Sortie ( 1 ) ;
} ;
} ;
//------------- lecture des noeuds -------------
// lecture du nombre de noeud
if ( ParaGlob : : NiveauImpression ( ) > = 6 ) cout < < " lecture des noeuds " < < endl ;
entreePrinc - > NouvelleDonnee ( ) ;
if ( ParaGlob : : NiveauImpression ( ) > = 8 ) cout < < " lecture du nombre de noeud " < < endl ;
int nbNoeud ; // nombre de noeud
* ( entreePrinc - > entree ) > > nbNoeud ; // lecture dans le flot memoire
if ( ParaGlob : : NiveauImpression ( ) > = 8 ) cout < < nbNoeud < < endl ;
Change_nb_noeud ( nbNoeud ) ; // dimensionnement dynamique du tableau de noeud
# ifdef ETUDIANT_LIMITATION
if ( nbNoeud > nb_maxi_noeud )
{ cout < < " \n nombre maxi de noeud autorisé atteind " < < nb_maxi_noeud ;
Sortie ( 1 ) ;
} ;
# endif
// lecture des noeuds
Noeud * ptr ;
for ( int i = 1 ; i < = nbNoeud ; i + + )
{ entreePrinc - > NouvelleDonnee ( ) ;
ptr = new Noeud ( i , dimension , idmail ) ; // et attribution du numero de maillage
if ( ParaGlob : : NiveauImpression ( ) = = 10 ) cout < < " n: " < < i < < " " < < flush ;
// lecture du noeud
ptr - > Lecture ( entreePrinc ) ;
Affectation_noeud ( * ptr ) ;
} ;
// -------------- lecture des references se rapportant aux noeuds ---------
entreePrinc - > NouvelleDonnee ( ) ;
if ( strstr ( entreePrinc - > tablcar , " elements " ) = = NULL )
// cas où les références sont mises aprés les noeuds, dans ce cas c'est
// des références de noeud
{ if ( ParaGlob : : NiveauImpression ( ) > = 6 ) cout < < " lecture des references de noeuds " < < endl ;
lesRef . Indic ( " noeud " ) ; // indic que les prochaines references seront pour les noeuds
lesRef . NbMaille ( idmail ) ; // indic le numéro de maillage aux références
lesRef . Lecture ( * entreePrinc ) ;
} ;
// ------------ lecture des elements -----------
// lecture du nombre d'element
int nbElement = 0 ; // nombre d'element null par défaut
if ( strstr ( entreePrinc - > tablcar , " elements " ) ! = NULL ) // cas avec element
{ if ( ParaGlob : : NiveauImpression ( ) > = 6 ) cout < < " lecture des elements du maillage " < < endl ;
entreePrinc - > NouvelleDonnee ( ) ;
if ( ParaGlob : : NiveauImpression ( ) > = 8 ) cout < < " lecture du nombre d'element " < < endl ;
* ( entreePrinc - > entree ) > > nbElement ;
if ( ParaGlob : : NiveauImpression ( ) > = 8 ) cout < < nbElement < < endl ;
# ifdef ETUDIANT_LIMITATION
if ( nbElement > nb_maxi_element )
{ cout < < " \n nombre maxi d'element autorise atteind " < < nb_maxi_element ;
Sortie ( 1 ) ;
} ;
# endif
// dimensionnement dynamique du tableau d'elements
Change_nb_element ( nbElement ) ;
// Lecture des elements
Element * ptr ;
for ( int i = 1 ; i < = nbElement ; i + + )
{ // lecture geometrie et interpolation
entreePrinc - > NouvelleDonnee ( ) ;
if ( ParaGlob : : NiveauImpression ( ) = = 10 ) cout < < " e: " < < i < < " " < < flush ;
// def des énumérations de travail
int num_elt = i ; // numéro interne de l'élément
int num_elt_lue ; // numéro lue
Enum_geom id_geom ; Enum_interpol id_interpol ; EnumElemTypeProblem id_typeProb ;
// cas d'info annexe
string str_precision ( " " ) ; // stockage info annexe de choix, initié à rien par défaut
// lectures des infos pour le choix d'un élément
Lecture_info_1element ( entreePrinc , num_elt_lue , id_geom , id_interpol , id_typeProb , str_precision ) ;
if ( num_elt_lue ! = num_elt )
{ if ( ParaGlob : : NiveauImpression ( ) > 0 )
{ cout < < " \n warning : le numero de l'element lue " < < num_elt_lue < < " est different du numero "
< < " d'ordre attribue automatiquement par herezh " < < num_elt
< < " \n seul ce dernier sera utilise pour les resultats ! " < < endl ;
} ;
} ;
// ======== choix de l'element =====================================
// et affectation du pointeur d'element en fonction de id_geom et id_interpol
// le numero d'element : num_elt, est affecte a l'element pointe par ptr
ptr = Element : : Choix_element ( idmail , num_elt , id_geom , id_interpol , id_typeProb , str_precision ) ;
if ( ptr = = NULL )
{ // l'operation a echouee
cout < < " \n Erreur dans le choix d'element ****** " ;
cout < < " \n l \' element : " < < Nom_interpol ( id_interpol )
< < " " < < Nom_geom ( id_geom )
< < " n \' est pas present dans le programme ! " < < endl ;
entreePrinc - > MessageBuffer ( " ** lecture d'un element ** " ) ;
throw ( UtilLecture : : ErrNouvelleDonnee ( - 1 ) ) ;
Sortie ( 1 ) ;
} ;
// lecture des infos particulieres a l'element
Tableau < Noeud * > * pt = & tab_noeud ;
ptr - > LectureDonneesParticulieres ( entreePrinc , pt ) ;
Affectation_element ( * ptr ) ;
// si c'est le premier élément du premier maillage on regarde s'il s'agit
// d'un élément axisymétrique et on adapte l'espace de travail en conséquence
if ( ( i = = 1 ) & & ( idmail = = 1 ) )
{ if ( TestEnum_geom_axisymetrique ( id_geom ) )
ParaGlob : : Change_en_AxiSymetrie ( ) ;
}
else
{ // dans le cas des autres éléments on vérifie qu'ils ne sont pas incohérent
if ( TestEnum_geom_axisymetrique ( id_geom ) ! = ( ParaGlob : : AxiSymetrie ( ) ) )
{ cout < < " \n **** erreur en definition de l'element " < < num_elt < < " du maillage " < < idmail
< < " nom= " < < nomDuMaillage ;
if ( ParaGlob : : AxiSymetrie ( ) )
cout < < " \n incoherence : l'espace de travail n'est pas axisymetrique (definit par les precedents elements) "
< < " et l'element lu est axisymetrique !! " ;
else
cout < < " \n incoherence : l'espace de travail est axisymetrique (definit par les precedents elements) "
< < " et l'element lu n'est pas axisymetrique !! " ;
cout < < endl ;
Sortie ( 1 ) ;
} ;
} ;
}
}
else
{ if ( ParaGlob : : NiveauImpression ( ) > = 6 )
cout < < " cas de la lecture d'un maillage SANS elements " < < endl ; // cas sans element
} ;
// -------------- lecture des references se rapportant aux elements ---------
// ou aux arête ou aux faces et meme eventuellement à des noeuds
if ( ParaGlob : : NiveauImpression ( ) > = 6 ) cout < < " lecture des references apres les elements " < < endl ;
entreePrinc - > NouvelleDonnee ( ) ;
lesRef . NbMaille ( idmail ) ; // indic le numéro de maillage aux références
lesRef . Indic ( " rien_actuellement " ) ; // indic que les prochaines references seront
// a déterminer en fonction du nom de la référence
lesRef . Lecture ( * entreePrinc ) ;
// -------------- ajout de références globales ---------------------
// ---- création de la référence de tous les éléments si elle n'existe pas déjà
string etout ( " E_tout " ) ;
if ( ! lesRef . Existe ( etout , idmail ) & & ( nbElement ! = 0 ) )
{ // on construit le tableau des numéros des éléments
Tableau < int > tabE ( nbElement ) ; for ( int i = 1 ; i < = nbElement ; i + + ) tabE ( i ) = i ;
ReferenceNE * retout = new ReferenceNE ( tabE , idmail , 2 , etout ) ; // construction de la référence
lesRef . Ajout_reference ( retout ) ; // ajout de la ref, qui est maintenant géré par lesRef
} ;
// ---- dans tous les cas on ajoute la référence de tous les noeuds dans le cas où elle n'existe pas
string ntout ( " N_tout " ) ;
if ( ! lesRef . Existe ( ntout , idmail ) )
{ // on construit le tableau des numéros de noeuds
Tableau < int > tabN ( nbNoeud ) ; for ( int i = 1 ; i < = nbNoeud ; i + + ) tabN ( i ) = i ;
ReferenceNE * rtout = new ReferenceNE ( tabN , idmail , 1 , ntout ) ; // construction de la référence
lesRef . Ajout_reference ( rtout ) ; // ajout de la ref, qui est maintenant géré par lesRef
} ;
if ( ParaGlob : : NiveauImpression ( ) > = 5 ) cout < < " fin lecture de maillage " < < endl ;
// ----- on s'occupe maintenant de définir les types de pb gérés ------
Mise_a_jour_type_pb_type_associe_ddl ( ) ;
2024-06-20 15:42:40 +02:00
2021-09-18 09:47:14 +02:00
} ;
// lecture et application des opérations d'affinages sur le maillage: ex:déplacement solide
void Maillage : : LectureEtApplicationAffinage ( UtilLecture * entreePrinc , LesReferences & lesRef )
{
if ( ParaGlob : : NiveauImpression ( ) > = 5 ) cout < < " lecture affinage maillage " < < endl ;
while ( ( strstr ( entreePrinc - > tablcar , " def_mouvement_solide_initiaux_ " ) ! = NULL )
| | ( strstr ( entreePrinc - > tablcar , " suppression_noeud_non_references_ " ) ! = NULL )
| | ( strstr ( entreePrinc - > tablcar , " creation_ref_noeud_non_references_ " ) ! = NULL )
| | ( strstr ( entreePrinc - > tablcar , " fusion_noeuds_proches_ " ) ! = NULL )
| | ( strstr ( entreePrinc - > tablcar , " fusion_elements_superposes_ " ) ! = NULL )
| | ( strstr ( entreePrinc - > tablcar , " suppression_elements_2noeuds_tres_proches_ " ) ! = NULL )
| | ( strstr ( entreePrinc - > tablcar , " def_auto_ref_frontiere_ " ) ! = NULL )
| | ( strstr ( entreePrinc - > tablcar , " renumerotation_des_noeuds_ " ) ! = NULL )
)
{
// -------------- lecture éventuelle et application de mouvements rigides ------------------
Lecture_des_mouvements_solides ( entreePrinc ) ;
// --------------- suppression éventuelle des noeuds, non référencés par les éléments ------
LectureEtSuppressionNoeudNonReferencer ( entreePrinc , lesRef ) ;
// --------------- création éventuelle d'une référence sur les noeuds, non référencés par les éléments ------
LectureEtCreationRefNoeudNonReferencer ( entreePrinc , lesRef ) ;
// --------------- éventuellement collapse de noeuds proches ------------------------
LectureEtCollapse_noeuds_proches ( entreePrinc , & lesRef ) ;
// --------------- éventuellement collapse d'éléments supperposés -------------------
LectureEtCollapse_element_superpose ( entreePrinc , & lesRef ) ;
// -------------- éventuellement suppression d'elements à 2 noeuds, de distances très proches
LectureEtSup_Elem_noeudsConfondu ( entreePrinc , & lesRef ) ;
//---------------- création automatique des références globales de frontière si demandé ----------
CreationRefFrontiere ( entreePrinc , lesRef ) ;
//----- debug
//{ // on écrit la connection de l'élément 55
// Element* el = tab_element(55);
// const Tableau<Noeud *>& tabi = el->Tab_noeud_const();
// cout << "\n *** connection de l'element 55: avant renumerotation ";
// for (int i=1;i<=tabi.Taille();i++) cout << " "<<tabi(i)->Num_noeud();
// cout << " Maillage::LectureMaillage () " << endl;
//}
//---fin debug
// --------------- renumérotation éventuelle des noeuds ------------------------------------
LectureEtRenumerotation ( entreePrinc , lesRef ) ;
////----- debug
//{ // on écrit la connection de l'élément 55
// Element* el = tab_element(55);
// const Tableau<Noeud *>& tabi = el->Tab_noeud_const();
// cout << "\n *** connection de l'element 55: après renumerotation ";
// for (int i=1;i<=tabi.Taille();i++) cout << " "<<tabi(i)->Num_noeud();
// cout << " Maillage::LectureMaillage () " << endl;
// Sortie(1);
//}
////---fin debug
} ;
// ----------------- 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
VerifReference ( lesRef ) ;
if ( ParaGlob : : NiveauImpression ( ) > = 5 ) cout < < " fin lecture affinage maillage " < < endl ;
} ;
// affichage et definition interactive des commandes
// cas = 1: interactif complet
// cas = 2: entrée uniquement de noms de fichier
// cas = 3: entrée uniquement de l'affinage
void Maillage : : Info_commande_Maillages ( UtilLecture * entreePrinc , LesReferences & lesRef , int cas )
{ ofstream & sort = * ( entreePrinc - > Commande_pointInfo ( ) ) ; // pour simplifier
string rep = " o " ;
if ( cas = = 2 )
{ cout < < " \n # voulez-vous inclure un fichier ou continuer sur un exemple (rep o ou ? ou f) ? " ;
rep = lect_return_defaut ( false , " f " ) ;
} ;
if ( ( ( rep = = " o " ) | | ( rep = = " O " ) | | ( rep = = " 0 " ) ) & & ( cas ! = 3 ) )
{ cout < < " \n non du fichier .her (sans l'extension .her) a inclure ? " ;
rep = lect_chaine ( ) ;
sort < < " \n \n # -- def maillage " ;
sort < < " \n < " < < ( rep + " .her " ) ;
cout < < " \n un fichier .lis a inclure ? (o ou n (defaut)) " ;
rep = lect_return_defaut ( false , " n " ) ;
if ( rep = = " o " )
{ cout < < " \n non du fichier .lis (sans l'extension .lis) a inclure ? " ;
rep = lect_chaine ( ) ;
sort < < " \n < " < < ( rep + " .lis " ) ;
} ;
}
else if ( ( rep = = " ? " ) & & ( cas ! = 3 ) )
{ // sinon on continue sur un exemple de maillage
sort < < " \n # -- defintion du nom du maillage (facultatif pour le premier maillage "
< < " \n # -- qui s'appel par defaut : premier_maillage) "
< < " \n "
< < " \n nom_maillage plaque_troue # exemple de nom de maillage "
< < " \n noeuds ------------ # definition des noeuds " ;
//------------- definition des noeuds -------------
int dimen = ParaGlob : : Dimension ( ) ;
# ifdef SYSTEM_MAC_OS_CARBON
int nbNoeud = pow ( 3 , dimen ) ; // nombre de noeud de l'exemple
# else
int nbNoeud = ( ( int ) pow ( ( float ) 3 , ( int ) dimen ) ) ; // nombre de noeud de l'exemple
# endif
sort < < " \n " < < nbNoeud < < " NOEUDS # definition du nombre de noeud "
< < " \n \n "
< < " \n #--------------------------------------------------------------- "
< < " \n #|NO DU| X | Y | Z | "
< < " \n #|NOEUD| | | | "
< < " \n #--------------------------------------------------------------- " ;
Change_nb_noeud ( nbNoeud ) ; // dimensionnement dynamique du tableau de noeud
// définition d'une grille générique de noeuds qui permettra de définir les éléments générique
Tableau < Coordonnee * > tab_coo ( nbNoeud ) ;
switch ( dimen )
{ case 1 :
{ for ( int i = 1 ; i < = 3 ; i + + ) tab_coo ( i ) = new Coordonnee ( ( double ) i ) ; break ; }
case 2 :
{ int l = 1 ; for ( int i = 1 ; i < = 3 ; i + + ) for ( int j = 1 ; j < = 3 ; j + + , l + + )
tab_coo ( l ) = new Coordonnee ( ( double ) i , ( double ) j ) ; break ; }
case 3 :
{ int l = 1 ; for ( int i = 1 ; i < = 3 ; i + + ) for ( int j = 1 ; j < = 3 ; j + + ) for ( int k = 1 ; k < = 3 ; k + + , l + + )
tab_coo ( l ) = new Coordonnee ( ( double ) i , ( double ) j , ( double ) k ) ; break ; }
} ;
// def des noeuds
Noeud * ptr ;
for ( int i = 1 ; i < = nbNoeud ; i + + )
{ ptr = new Noeud ( i , dimension , 1 ) ; // et attribution du numero de maillage
// def du noeud
ptr - > Info_commande_Noeud ( entreePrinc , * tab_coo ( i ) , i ) ;
Affectation_noeud ( * ptr ) ;
} ;
// -------------- def d'exemples de references se rapportant aux noeuds ---------
sort < < " \n # --- reference de noeuds ce trouvant apres la definition des noeuds --- "
< < " \n # ( il est possible aussi de definir des references de noeud apres "
< < " \n # la definition des elements) "
< < " \n # NB: !! une reference de noeud doit commencer par N suivi d'une chaine de caracteres \n " ;
lesRef . Indic ( " noeud " ) ; // indic que les prochaines references seront pour les noeuds
lesRef . NbMaille ( idmail ) ; // indic le numéro de maillage aux références
lesRef . Info_commande_lesRef ( nbNoeud , 0 , entreePrinc , 1 ) ; // def d'exemple des divers refs de noeuds
// ------------ def d'exemple d'elements -----------
2024-08-29 09:31:24 +02:00
int nbElement = 0 ; // nombre d'element
2021-09-18 09:47:14 +02:00
bool choix_valide = false ;
// affichage des types d'élément actuellement disponible selon la dimension
// creation d'un tableau d'éléments
Tableau < Element * > tab_el = Element : : Info_commande_Element ( entreePrinc ) ;
int nbele = tab_el . Taille ( ) ;
Tableau < bool > chooi ( nbele , false ) ; // tableau de travail
cout < < " \n Donner le type d'element que vous souhaitez utiliser: ? " ;
string rep ; int num ;
while ( ! choix_valide )
{
try
{ // affichage des éléments possibles
// on balaie le tableau des elements enregistre
int undeux = 0 ;
cout < < " \n (0) fin \n " ;
for ( int i = 1 ; i < = nbele ; i + + )
{ cout < < " ( " < < i < < " ) " < < tab_el ( i ) - > Geometrie ( ) < < " " < < tab_el ( i ) - > Interpolation ( )
< < " " ;
undeux + + ;
if ( undeux = = 2 ) { cout < < " \n " ; undeux = 0 ; }
} ;
rep = lect_return_defaut ( false , " 0 " ) ;
if ( rep = = " fin_prog " ) Sortie ( 1 ) ;
num = ChangeEntier ( rep ) ;
choix_valide = false ;
if ( num = = 0 )
{ choix_valide = true ; }
else // sinon
{ if ( ( num > 0 ) & & ( num < = nbele ) )
{ if ( chooi ( num ) )
cout < < " \n type d'element deja choisit, recommencer " ;
else
chooi ( num ) = true ;
}
else { cout < < " \n Erreur on attendait un entier entre 0 et " < < nbele < < " !!, "
< < " \n redonnez une bonne valeur "
< < " \n ou taper fin_prog pour arreter le programme " ;
}
}
}
catch ( ErrSortieFinale )
// cas d'une direction voulue vers la sortie
// on relance l'interuption pour le niveau supérieur
{ ErrSortieFinale toto ;
throw ( toto ) ;
}
catch ( . . . ) //(UtilLecture::ErrNouvelleDonnee erreur)
{ cout < < " \n Erreur on attendait un entier entre 0 et " < < nbele < < " !!, "
< < " \n redonnez une bonne valeur "
< < " \n ou taper fin_prog pour arreter le programme " ;
choix_valide = false ;
}
} //-- fin du while
// on definit le maillage d'essai
// 1- def du nombre d'élément
int ielmax = 0 ;
for ( int ie = 1 ; ie < = nbele ; ie + + )
if ( chooi ( ie ) ) ielmax + + ;
Change_nb_element ( ielmax ) ;
// 2- remplissage du tableau d'élément
int iel = 1 ;
for ( int ie = 1 ; ie < = nbele ; ie + + )
if ( chooi ( ie ) )
{ tab_element ( iel ) = tab_el ( ie ) ;
tab_element ( iel ) - > Change_num_elt ( iel ) ;
tab_el ( ie ) = NULL ;
iel + + ;
}
// on affiche les éléments
sort < < " \n # les elements \n "
< < " \n elements ---------- " ;
sort < < " \n " < < ielmax < < " ELEMENTS " ;
sort < < " \n #---------------------------------------------------------------------- " ;
sort < < " \n #| NO | | | " ;
sort < < " \n #|ELTS | type element | Noeuds | " ;
sort < < " \n #---------------------------------------------------------------------- " ;
string ord = " commande " ;
Tableau < Noeud * > * pt = & tab_noeud ;
for ( int i = 1 ; i < = ielmax ; i + + )
tab_element ( i ) - > Info_com_Element ( entreePrinc , ord , pt ) ;
sort < < " \n \n " ;
// -------------- def des references se rapportant aux elements ---------
// ou aux arête ou aux faces et meme eventuellement à des noeuds
sort < < " \n # --- reference ce trouvant apres la definition des elements --- "
< < " \n # NB: !! une reference de noeud doit commencer par N suivi d'une chaine de caracteres "
< < " \n # une reference d'element commence par E suivi d'une chaine de caracteres "
< < " \n # une reference de face commence par F et une reference d'arrete commence par A \n " ;
lesRef . NbMaille ( idmail ) ; // indic le numéro de maillage aux références
lesRef . Info_commande_lesRef ( nbNoeud , ielmax , entreePrinc , 2 ) ; // def d'exemple des divers refs de noeuds
// effacement des éléments qui ne servent plus
for ( int i = 1 ; i < = ielmax ; i + + )
if ( tab_el ( i ) ! = NULL ) delete tab_el ( i ) ;
} ; // fin de l'exemple de maillage
// ---------- définition des affinages éventuelles ----------
// while ( (strstr(entreePrinc->tablcar,"def_mouvement_solide_initiaux_")!=NULL)
// || (strstr(entreePrinc->tablcar,"suppression_noeud_non_references_")!=NULL)
// || (strstr(entreePrinc->tablcar,"creation_ref_noeud_non_references_")!=NULL)
// || (strstr(entreePrinc->tablcar,"fusion_noeuds_proches_")!=NULL)
// || (strstr(entreePrinc->tablcar,"fusion_elements_superposes_")!=NULL)
// || (strstr(entreePrinc->tablcar,"suppression_elements_2noeuds_tres_proches_")!=NULL)
// || (strstr(entreePrinc->tablcar,"def_auto_ref_frontiere_")!=NULL)
// || (strstr(entreePrinc->tablcar,"renumerotation_des_noeuds_")!=NULL)
//On va proposer un menu
while ( ( Minuscules ( rep ) ! = " f " ) & & ( Minuscules ( rep ) ! = " 0 " ) )
{
try
{
cout
< < " \n (0 ou f defaut) (fin) "
< < " \n (1) mouvement solide "
< < " \n (2) suppression des noeuds non reference "
< < " \n (3) collapse de noeuds proches "
< < " \n (4) collapse d'elements superposes "
< < " \n (5) creation de references frontieres "
< < " \n (6) renumerotation "
< < " \n (7) creation d'une ref sur les noeuds non references "
< < " \n (8) suppression des petits elements a 2 ou 3 noeuds 2D "
< < " \n (9 ou ? ) informations "
< < " \n " ;
rep = lect_return_defaut ( false , " f " ) ;
if ( ( Minuscules ( rep ) = = " f " ) | | ( Minuscules ( rep ) = = " 0 " ) ) // sortie directe
break ;
int num = ChangeEntier ( rep ) ;
if ( Minuscules ( rep ) = = " ? " )
num = 9 ;
bool choix_valide = false ;
if ( ( num > = 0 ) & & ( num < = 9 ) )
{ choix_valide = true ; }
else { cout < < " \n Erreur on attendait un entier entre 0 et 9 !!, "
< < " \n redonnez une bonne valeur "
< < " \n ou taper f ou 0 pour arreter le programme " ;
choix_valide = false ;
}
switch ( num )
{ case 0 : // sortie
{ break ; } // normalement cela a déjà été filtré avant
case 1 : // mouvement solide
{ MvtSolide mvt ; // un mouvement par défaut
sort < < " \n \n def_mouvement_solide_initiaux_ \n " ;
mvt . Info_commande_MvtSolide ( sort ) ;
break ; }
case 2 : // suppression des noeuds non reference
{ sort < < " \n suppression_noeud_non_references_ " ;
break ; }
case 3 : // collapse de noeuds proches
{ sort < < " \n fusion_noeuds_proches_ " ;
cout < < " \n donner la distance en dessous de laquelle on fusionne (un reel) ? " ;
double rayon = 0. ;
rayon = lect_double ( ) ; cout < < " valeur lue " < < rayon ;
sort < < rayon < < " " ;
break ; }
case 4 : // collapse d'elements superposes
{ sort < < " \n fusion_elements_superposes_ " ;
break ; }
case 5 : // creation de references frontieres
{ sort < < " \n def_auto_ref_frontiere_ " ;
break ; }
case 6 : // creation de references frontieres
{ sort < < " \n renumerotation_des_noeuds_ " ;
break ; }
case 7 : // creation d'une ref sur les noeuds non reference
{ sort < < " \n creation_ref_noeud_non_references_ " ;
break ; }
case 8 : // suppression des petits elements a 2 ou 3 noeuds 2D
{ sort < < " \n suppression_elements_2noeuds_tres_proches_ " ;
cout < < " \n donner la distance entre deux noeuds de l'element en dessous de laquelle on supprime (un reel) ? " ;
double rayon = 0. ;
rayon = lect_double ( ) ; cout < < " valeur lue " < < rayon ;
sort < < rayon < < " " ;
break ; }
case 9 : // informations
{ cout < < " \n en dehors de la signification intuitive des differents ordres "
< < " pour des informations plus precise il est preferable de se rapporter a la documentation "
< < " d'Herezh++, car c'est differents ordres recouvrent des procedures difficiles a "
< < " decrire en quelques lignes. " ;
break ; }
default :
cout < < " \n le cas " < < rep < < " n'est pas encore traite !!, mais cela devrait ce faire sans tarder " ;
} ;
}
catch ( ErrSortieFinale )
// cas d'une direction voulue vers la sortie
// on relance l'interuption pour le niveau supérieur
{ ErrSortieFinale toto ;
throw ( toto ) ;
}
catch ( . . . ) //(UtilLecture::ErrNouvelleDonnee erreur)
{ cout < < " \n Erreur on attendait un des mots clés proposés !!, "
< < " \n redonnez une bonne valeur "
< < " \n ou taper f ou 0 pour sortir " ;
} ;
} ; //-- fin du while
} ;
// Affiche l'ensemble des donnees du maillage
void Maillage : : Affiche ( ) const
{ cout < < " \n \t \t *** DONNEES DU MAILLAGE *** \n \n " ;
cout < < " \n nom du maillage : " < < nomDuMaillage < < " , " ;
cout < < " Dimension : " < < dimension < < " \n " ;
// les types de problèmes associés
// {list <EnumElemTypeProblem>::const_iterator il,ilfin=types_de_problemes.end();
// cout <<"\n types_de_problemes: " << types_de_problemes.size() ;
// for (il=types_de_problemes.begin();il != ilfin;il++)
// NomElemTypeProblem(*il);
// };
{ int tail = types_de_problemes . Taille ( ) ;
cout < < " \n types_de_problemes: " < < tail ;
for ( int i = 1 ; i < = tail ; i + + )
cout < < " " < < NomElemTypeProblem ( types_de_problemes ( i ) ) ;
} ;
// // les ddl associés
// {list <Enum_ddl>::const_iterator il,ilfin=ddl_representatifs_des_physiques.end();
// cout <<"\n type_de_ddl_associes: " << ddl_representatifs_des_physiques.size();
// for (il=ddl_representatifs_des_physiques.begin();il != ilfin;il++)
// Nom_ddl(*il);
// };
{ int tail = ddl_representatifs_des_physiques . Taille ( ) ;
cout < < " \n type_de_ddl_associes: " < < tail ;
for ( int i = 1 ; i < = tail ; i + + )
cout < < " " < < Nom_ddl ( ddl_representatifs_des_physiques ( i ) ) ;
} ;
// cout << "Nombre de degres de liberte : " << Nombre_ddl() << "\n";
cout < < " Nombre de noeuds : " < < Nombre_noeud ( ) < < " \n " ;
cout < < " Nombre d'elements : " < < Nombre_element ( ) < < " \n \n " ;
for ( int i = 1 ; i < = Nombre_noeud ( ) ; i + + )
// boucle sur les noeuds
{
cout < < " \n Noeud " < < i < < " : \n " ;
tab_noeud ( i ) - > Affiche ( ) ;
} ;
cout < < " \n " ;
for ( int i = 1 ; i < = Nombre_element ( ) ; i + + )
// boucle sur les elements
{
cout < < " \n Element " < < i < < " : \n " ;
tab_element ( i ) - > Affiche ( ParaGlob : : NiveauImpression ( ) ) ;
} ;
cout < < " \n " ;
// renseignement concernant les frontières
int nbmaxiElement = ( int ) listFrontiere . size ( ) ;
cout < < " nombre d'element frontiere : " < < nbmaxiElement ;
cout < < " liste : \n " ;
LaLIST < Front > : : const_iterator ip ; int ne ;
for ( ne = 1 , ip = listFrontiere . begin ( ) ; ip ! = listFrontiere . end ( ) ; ip + + , ne + + )
{ // écriture de l'élément courant
cout < < ne < < " " ; // le numéro
const ElemGeomC0 & geom = ( * ip ) . Eleme ( ) - > ElementGeometrique ( ) ;
cout < < Nom_geom ( geom . TypeGeometrie ( ) ) < < " " ; // la géométrie
cout < < Nom_interpol ( geom . TypeInterpolation ( ) ) < < " " ; // l'interpolation
// les noeuds
Tableau < Noeud * > tabnoeud = ( * ip ) . Eleme ( ) - > TabNoeud ( ) ;
int taille = tabnoeud . Taille ( ) ;
for ( int ine = 1 ; ine < = taille ; ine + + )
cout < < tabnoeud ( ine ) - > Num_noeud ( ) < < " " ;
cout < < " \n " ;
} ;
// la liste des noeuds de la frontières, on ne sort que les numéros
cout < < " \n liste des numeros de noeud de la frontiere " ;
int taal = tab_noeud_front . Taille ( ) ;
for ( int i = 1 ; i < = taal ; i + + )
cout < < tab_noeud_front ( i ) - > Num_noeud ( ) < < " " ;
cout < < " \n " ;
} ;
/*void
Maillage : : Affiche ( char * nom_fichier )
// Affiche les donnees du maillage dans le fichier nom_fichier
// au format du fichier d'entree ".her"
{
FILE * fichier ;
// ouverture du fichier nom_fichier
if ( ( fichier = fopen ( nom_fichier , " w " ) ) = = NULL )
{
cout < < " ERREUR D'OUVERTURE DU FICHIER : " ;
cout < < nom_fichier < < " \n " ;
Sortie ( 1 ) ;
} ;
fprintf ( fichier , " \n nom_maillage " , nomDuMaillage . c_str ( ) ) ;
fprintf ( fichier , " \n \n noeuds -------- \n \n " ) ;
fprintf ( fichier , " \t \t %d NOEUDS \n \n " , Nombre_noeud ( ) ) ;
// affichage des noeuds :
switch ( dimension )
{
case 1 : // cas unidimensionnel
for ( int i = 1 ; i < = Nombre_noeud ( ) ; i + + )
{
fprintf ( fichier , " \t %d \t %lf \n " , Noeud_mail ( i ) . Num_noeud ( ) ,
Noeud_mail ( i ) . Coord0 ( ) ( 1 ) ) ;
} ;
break ;
case 2 : // cas bidimensionnel
for ( int i = 1 ; i < = Nombre_noeud ( ) ; i + + )
{
fprintf ( fichier , " \t %d \t \t " , Noeud_mail ( i ) . Num_noeud ( ) ) ;
fprintf ( fichier , " %lf \t %lf \n " , Noeud_mail ( i ) . Coord0 ( ) ( 1 ) ,
Noeud_mail ( i ) . Coord0 ( ) ( 2 ) ) ;
} ;
break ;
case 3 : // cas tridimensionnel
for ( int i = 1 ; i < = Nombre_noeud ( ) ; i + + )
{
fprintf ( fichier , " \t %d \t \t " , Noeud_mail ( i ) . Num_noeud ( ) ) ;
fprintf ( fichier , " %lf \t %lf \t %lf \n " , Noeud_mail ( i ) . Coord0 ( ) ( 1 ) ,
Noeud_mail ( i ) . Coord0 ( ) ( 2 ) , Noeud_mail ( i ) . Coord0 ( ) ( 3 ) ) ;
} ;
break ;
default :
cout < < " Erreur de dimension \n " ;
cout < < " MAILLAGE::AFFICHE(char* ) \n " ;
Sortie ( 1 ) ;
} ;
fprintf ( fichier , " \n \n elements -------- \n \n " ) ;
fprintf ( fichier , " \t \t %d ELEMENTS \n \n " , Nombre_element ( ) ) ;
// affichage des elements
for ( int i = 1 ; i < = Nombre_element ( ) ; i + + )
{
fprintf ( fichier , " \t %d \t " , Element_mail ( i ) . Num_elt ( ) ) ;
fprintf ( fichier , " %s \t %s \t \t " , Element_mail ( i ) . Geometrie ( ) ,
Element_mail ( i ) . Interpolation ( ) ) ;
for ( int j = 1 ; j < = Element_mail ( i ) . Nombre_noeud ( ) ; j + + )
fprintf ( fichier , " %d \t " , Element_mail ( i ) . Num_noeud ( j ) ) ;
fprintf ( fichier , " \n " ) ;
} ;
fprintf ( fichier , " \n \n " ) ;
} ;
*/
Maillage &
Maillage : : operator = ( Maillage & mail )
// Surcharge de l'operateur = : realise l'egalite entre deux maillages
// cependant le numéro de maillage et le nom de maillage n'est pas valide, il faut
// ensuite les définir
{ dimension = mail . dimension ;
//nomDuMaillage = mail.nomDuMaillage;
tab_noeud = mail . tab_noeud ;
tab_element = mail . tab_element ;
listFrontiere = mail . listFrontiere ;
tab_noeud_front = mail . tab_noeud_front ;
ddl_representatifs_des_physiques = mail . ddl_representatifs_des_physiques ;
types_de_problemes = mail . types_de_problemes ;
return ( * this ) ;
} ;
// test si toutes les informations des maillages sont completes
// = true -> complet
// = false -> incomplet
bool Maillage : : Complet ( )
{ bool res = true ;
int tab_noeudTaille = tab_noeud . Taille ( ) ;
for ( int i = 1 ; i < = tab_noeudTaille ; i + + )
{ // res = res && tab_noeud(i)->TestComplet();
if ( ! ( tab_noeud ( i ) - > TestComplet ( ) ) )
{ cout < < " \n pb au niveau du test du noeud " < < tab_noeud ( i ) - > Num_noeud ( ) ;
res = false ;
} ;
} ;
int tab_elemTaille = tab_element . Taille ( ) ;
for ( int i = 1 ; i < = tab_elemTaille ; i + + )
{ //res = res && tab_element(i)->TestComplet();
if ( ! ( tab_element ( i ) - > TestComplet ( ) ) )
{ cout < < " \n pb au niveau du test de l'element " < < tab_element ( i ) - > Num_elt ( ) ;
res = false ;
} ;
} ;
// les parties frontières ne sont pas obligatoires
return res ;
} ;
// ramene la demi largeur de bande en ddl et la largeur de bande
void Maillage : : Largeur_Bande ( int & demi , int & total , const Nb_assemb & casAss )
{ demi = 0 ;
int nb_ass = casAss . n ;
int tab_elemTaille = tab_element . Taille ( ) ;
for ( int ne = 1 ; ne < = tab_elemTaille ; ne + + )
{ int tab_eleNbNoeud = tab_element ( ne ) - > Nombre_noeud ( ) ;
for ( int noe = 1 ; noe < = tab_eleNbNoeud ; noe + + )
// bug, voic remarque qui suit for ( int no=noe+1; no<=tab_eleNbNoeud;no++)
// l'idée est bonne de commencer à noe+1, mais en fait lorsque l'on a un seul noeud, cela conduit
// a avoir une largeur de bande nulle, donc il faut commencer à noe, et dans ce cas c'est ok
// mais pour les éléments avec plus d'un noeud, on a une boucle supp
for ( int no = noe ; no < = tab_eleNbNoeud ; no + + )
{ Noeud & nne = tab_element ( ne ) - > Noeud_elt ( noe ) ;
Noeud & nno = tab_element ( ne ) - > Noeud_elt ( no ) ;
int di ;
if ( nne . PosiAssemb ( nb_ass ) > = nno . PosiAssemb ( nb_ass ) )
di = nne . PosiAssemb ( nb_ass ) - nno . PosiAssemb ( nb_ass )
+ nne . NB_ddl_actif_casAssemb ( nb_ass ) ;
else
di = nno . PosiAssemb ( nb_ass ) - nne . PosiAssemb ( nb_ass )
+ nno . NB_ddl_actif_casAssemb ( nb_ass ) ;
if ( di > demi ) demi = di ;
} ;
} ;
total = demi * 2 - 1 ;
demi = demi ;
} ;
// 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 Maillage : : Tous_Xi_fixes ( const Nb_assemb & casAss ) const
{ int retour = 1 ;
int nb_ass = casAss . n ;
// on va parcourir les noeuds
int tab_noeud_taille = tab_noeud . Taille ( ) ;
int dim = ParaGlob : : Dimension ( ) ;
switch ( dim )
{ case 3 :
{ for ( int i = 1 ; i < = tab_noeud_taille ; i + + )
{ Noeud & noe = * tab_noeud ( i ) ; // pour simplifier
if ( ! ( noe . Ddl_fixe ( X3 ) & & noe . Ddl_fixe ( X2 ) & & noe . Ddl_fixe ( X1 ) ) )
{ retour = 0 ; break ; } ;
} ;
break ;
}
case 2 :
{ for ( int i = 1 ; i < = tab_noeud_taille ; i + + )
{ Noeud & noe = * tab_noeud ( i ) ; // pour simplifier
if ( ! ( noe . Ddl_fixe ( X2 ) & & noe . Ddl_fixe ( X1 ) ) )
{ retour = 0 ; break ; } ;
} ;
break ;
}
case 1 :
{ for ( int i = 1 ; i < = tab_noeud_taille ; i + + )
{ Noeud & noe = * tab_noeud ( i ) ; // pour simplifier
if ( ! ( noe . Ddl_fixe ( X1 ) ) )
{ retour = 0 ; break ; } ;
} ;
break ;
}
} ;
// --- idem mais plus long a priori car contient un switch
// for (int i=1;i<=tab_noeud_taille;i++)
// { Noeud& noe = *tab_noeud(i); // pour simplifier
// switch(dim)
// {case 3: if (!(noe.Ddl_fixe(X3))) {retour=0; break;};
// case 2: if (!(noe.Ddl_fixe(X2))) {retour=0; break;};
// case 1: if (!(noe.Ddl_fixe(X1))) {retour=0; break;};
// };
// if (!retour) break;
// };
return retour ;
} ;
// création pour chaque noeud de la liste des éléments qui contiennent le noeud
void Maillage : : Calcul_indice ( )
{ // création du tableau indice : pour chaque noeud on regarde quel élément contiend ce noeud
/// les 3/ sont pour la version vector qui marche bien aussi
/// vector <vector <Element*> > indice(tab_noeud.Taille());
int tab_noeud_taille = tab_noeud . Taille ( ) ;
indice . Change_taille ( tab_noeud_taille ) ;
// au cas où le tableau existait auparavant on initialise les éléments du tableau
for ( int i = 1 ; i < = tab_noeud_taille ; i + + )
indice ( i ) . clear ( ) ;
// maintenant on passe en revue les éléments
int tabelTaille = tab_element . Taille ( ) ;
// indice(i) contiend les numéros d'élément contenant le noeud i
for ( int i22 = 1 ; i22 < = tabelTaille ; i22 + + )
{ Element * elem1 = tab_element ( i22 ) ; // recup de l'element
// récup de son tableau de noeud
Tableau < Noeud * > & tabn = elem1 - > Tab_noeud ( ) ;
int tabntaille = tabn . Taille ( ) ;
for ( int ij = 1 ; ij < = tabntaille ; ij + + )
{ // on balaie ses noeuds
/// indice[(tabn(ij)->Num_noeud())-1].push_back(elem1);
indice ( ( tabn ( ij ) - > Num_noeud ( ) ) ) . push_back ( elem1 ) ;
} ;
} ;
// on supprime les doublons
for ( int i = 1 ; i < = tab_noeud_taille ; i + + )
{ list < Element * > & intertab = indice ( i ) ; // pour allèger l'écriture
intertab . sort ( ) ; // on ordonne
intertab . unique ( ) ; // on supprime les doublons
/*//-- debug
//{cout << "\n noeud " << i << " taille indice(i) " << intertab.size() ;
// list<Element*>::iterator ina,infin;
// infin = intertab.end();
// for (ina = intertab.begin();ina!=infin;ina++)
// {Element * elem2 = *ina; // recup de l'element
// cout << " element " << elem2->Num_elt() << " ";
// };
// cout << "\n";
// };
//-- debug
//{cout << "\n debug ** Maillage::Calcul_indice() ";
// int numnoeud = 104;
// list<Element*>& intertab = indice(numnoeud);
// list<Element*>::iterator ina,infin;
// infin = intertab.end();
// for (ina = intertab.begin();ina!=infin;ina++)
// {Element * elem2 = *ina; // recup de l'element
// cout << " element-- " << elem2->Num_elt() << " ";
// };
// cout << "\n"<<endl ;
//};
//--fin debug*/
} ;
} ;
2023-05-03 17:23:49 +02:00
// création pour chaque noeud de la liste des éléments frontières qui contiennent le noeud
void Maillage : : Calcul_indice_NFr ( )
{ // le tableau indice_NFr (indice des noeuds frontières) va permettre une recherche plus rapide
// on le construit:
int tab_noeud_taille = tab_noeud . Taille ( ) ;
indice_NFr . Change_taille ( tab_noeud_taille ) ;
// au cas où le tableau existait auparavant on initialise les éléments du tableau
for ( int i = 1 ; i < = tab_noeud_taille ; i + + )
indice_NFr ( i ) . clear ( ) ;
// indice_NFr contiend les front succeptible d'avoir des frontières géométriques communes
LaLIST < Front > : : iterator iF ;
LaLIST < Front > : : iterator iFfin = listFrontiere . end ( ) ;
for ( iF = listFrontiere . begin ( ) ; iF ! = iFfin ; iF + + )
{ Front * fro = & ( * iF ) ;
ElFrontiere * efem1 = fro - > Eleme ( ) ; // recup de l'element géométrique qui a créé la frontière
// récup de son tableau de noeud
Tableau < Noeud * > & tabn = efem1 - > TabNoeud ( ) ;
int tabntaille = tabn . Taille ( ) ;
for ( int ij = 1 ; ij < = tabntaille ; ij + + )
// on balaie ses noeuds
indice_NFr ( ( tabn ( ij ) - > Num_noeud ( ) ) ) . push_back ( fro ) ;
} ;
// on supprime les doublons
for ( int i = 1 ; i < = tab_noeud_taille ; i + + )
{ List_io < Front * > & intertab = indice_NFr ( i ) ; // pour allèger l'écriture
intertab . sort ( ) ; // on ordonne
intertab . unique ( ) ; // on supprime les doublons
} ;
} ;
2024-08-29 09:31:24 +02:00
// calcule des normales aux noeuds: dans le cas d'éléments finis 1D ou 2D
// et aussi pour les frontières (qui sont normalement de type 1D ou 2D)
2021-09-18 09:47:14 +02:00
// 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
2023-05-03 17:23:49 +02:00
// init par défaut des valeurs à t == celle à t=0
2021-09-18 09:47:14 +02:00
void Maillage : : InitNormaleAuxNoeuds ( )
{ // on va parcourir les noeuds et on n'intervient que si le noeud
// appartient à un élément 1D et/ou 2D
int nbNoeud = tab_noeud . Taille ( ) ;
2024-11-25 10:36:00 +01:00
int dima = ParaGlob : : Dimension ( ) ;
2021-09-18 09:47:14 +02:00
int borne_max_nbNoeud = nbNoeud + 1 ;
Coordonnee coor_inter ; // coordonnée de travail
Coordonnee premiere_normale ; // idem
2024-04-24 10:34:35 +02:00
{
Grandeur_coordonnee grandCoordonnee_0 ( ParaGlob : : Dimension ( ) ) ; // un type courant
TypeQuelconque typQ4_0 ( NN_SURF_t0 , EPS11 , grandCoordonnee_0 ) ;
Grandeur_coordonnee grandCoordonnee_t ( ParaGlob : : Dimension ( ) ) ; // un type courant
TypeQuelconque typQ4_t ( NN_SURF_t , EPS11 , grandCoordonnee_t ) ;
2021-09-18 09:47:14 +02:00
2024-04-24 10:34:35 +02:00
// on commence par ajouter les conteneurs
// on fait un conteneur particulier pour tous les noeuds, donc 2 boucles
// car cela permet d'optimiser l'utilisation de la méthode AjoutUnTypeQuelconque de Noeud
for ( int ine = 1 ; ine < borne_max_nbNoeud ; ine + + )
{ // on regarde si le conteneur de la normale existe au noeud et création éventuelle
Noeud & noe = * tab_noeud ( ine ) ; // pour simplifier
if ( ! noe . Existe_ici ( NN_SURF_t0 ) )
noe . AjoutUnTypeQuelconque ( typQ4_0 ) ;
} ;
for ( int ine = 1 ; ine < borne_max_nbNoeud ; ine + + )
{ // on regarde si le conteneur de la normale existe au noeud et création éventuelle
Noeud & noe = * tab_noeud ( ine ) ; // pour simplifier
if ( ! noe . Existe_ici ( NN_SURF_t ) )
noe . AjoutUnTypeQuelconque ( typQ4_t ) ;
} ;
// maintenant on s'occupe du contenu
for ( int ine = 1 ; ine < borne_max_nbNoeud ; ine + + )
{ Noeud & noe = * tab_noeud ( ine ) ; // pour simplifier
// on récupère le conteneur de la normale
TypeQuelconque & tiq = noe . ModifGrandeur_quelconque ( NN_SURF_t0 ) ;
Grandeur_coordonnee & gr = * ( ( Grandeur_coordonnee * ) ( tiq . Grandeur_pointee ( ) ) ) ;
Coordonnee & normale = * gr . ConteneurCoordonnee ( ) ;
normale . Zero ( ) ; // init
// calcul éventuel du tableau Indice
this - > Indice ( ) ;
List_io < Element * > & li_elem = indice ( ine ) ; // la liste des éléments qui contiennent le noeud
List_io < Element * > : : iterator il , ilfin = li_elem . end ( ) ;
// on balaie les éléments
int nb_normale = 0 ; // le nombre de normales trouvées
for ( il = li_elem . begin ( ) ; il ! = ilfin ; il + + )
{ Element & elem = * ( * il ) ;
Enum_type_geom enutygeom = Type_geom_generique ( elem . Id_geometrie ( ) ) ;
// if ((enutygeom == LIGNE) || (enutygeom == SURFACE))
2024-11-25 10:36:00 +01:00
if ( ( enutygeom = = SURFACE ) // dans une première étape on ne s'occupe que des surfaces en 3D
& & ( dima = = 3 ) // si surface en 2D, ce sera les éléments frontières qui détermineront les normales
)
2024-04-24 10:34:35 +02:00
{ int cas = elem . CalculNormale_noeud ( TEMPS_0 , * tab_noeud ( ine ) , coor_inter ) ;
if ( cas = = 0 )
{ cout < < " \n *** erreur, le calcul de la normale n'est pas possible "
< < " pour le noeud " < < tab_noeud ( ine ) - > Num_noeud ( )
< < " du maillage " < < tab_noeud ( ine ) - > Num_Mail ( )
< < " par rapport a l'element " < < elem . Num_elt ( )
< < " du maillage " < < elem . Num_maillage ( )
< < " \n Maillage::MiseAjourNormaleAuxNoeuds() " ;
Sortie ( 1 ) ;
}
else if ( cas = = 2 )
{ // le calcul n'est pas licite, mais ce n'est pas une erreur
// simplement, l'élément n'est pas rusé pour ce noeud, on ne fait rien
}
else // sinon c'est ok
{ // on peut avoir des directions très proches mais de sens inverse ... ce qui va
// conduire à une somme nulle, pour éviter cela, on regarde le produit scalaire
// s'il est négatif on utilise l'inverse de la normale
// donc en définitif on gardera globalement la direction précédente
if ( ( normale * coor_inter ) > 0. )
{ normale + = coor_inter ; }
else
{ normale - = coor_inter ; } ;
nb_normale + + ;
} ;
} ;
2021-09-18 09:47:14 +02:00
} ;
2024-04-24 10:34:35 +02:00
if ( nb_normale ! = 0 )
{ normale / = nb_normale ;
// enfin on normalise la normale
////------ debug
//if (normale.Norme() == 0.)
// {
// for (il = li_elem.begin(); il != ilfin; il++)
// {Element& elem = *(*il);
// Enum_type_geom enutygeom = Type_geom_generique(elem.Id_geometrie());
// // if ((enutygeom == LIGNE) || (enutygeom == SURFACE))
// if (enutygeom == SURFACE) // pour l'intant on ne traite que les surfaces
// {elem.CalculNormale_noeud(TEMPS_0,*tab_noeud(ine),coor_inter);
// if (coor_inter.Dimension() == 0)
// {cout << "\n *** erreur, le calcul de la normale n'est pas possible "
// << " pour le noeud "<<tab_noeud(ine)->Num_noeud()
// << " du maillage " << tab_noeud(ine)->Num_Mail()
// << " par rapport a l'element "<< elem.Num_elt()
// << " du maillage " << elem.Num_maillage()
// << "\n Maillage::MiseAjourNormaleAuxNoeuds() ";
// Sortie(1);
// }
// else // sinon c'est ok
// {normale += coor_inter;
// nb_normale++;
// };
// };
// };
//
// }
//
//// end debug
normale . Normer ( ) ;
// ce qui fini la mise à jour de la normale au noeud
} ;
} ;
}
2023-05-03 17:23:49 +02:00
// on fait de même pour les éléments frontières minimals
// calcul éventuel du tableau indice_NFr
this - > Indice_NFr ( ) ;
2024-04-24 10:34:35 +02:00
{ Grandeur_coordonnee grandCoordonnee_0 ( ParaGlob : : Dimension ( ) ) ; // un type courant
TypeQuelconque typQ4_0 ( N_FRONT_t0 , EPS11 , grandCoordonnee_0 ) ;
Grandeur_coordonnee grandCoordonnee_t ( ParaGlob : : Dimension ( ) ) ; // un type courant
TypeQuelconque typQ4_t ( N_FRONT_t , EPS11 , grandCoordonnee_t ) ;
// à t=0
for ( int ine = 1 ; ine < borne_max_nbNoeud ; ine + + )
2023-05-03 17:23:49 +02:00
{ Noeud & noe = * tab_noeud ( ine ) ; // pour simplifier
2024-04-24 10:34:35 +02:00
// on regarde si le conteneur de la normale à un noeud frontière existe au noeud et création éventuelle
2023-05-03 17:23:49 +02:00
if ( ! noe . Existe_ici ( N_FRONT_t0 ) )
2024-04-24 10:34:35 +02:00
noe . AjoutUnTypeQuelconque ( typQ4_0 ) ;
} ;
// on fait la même chose à t ce qui évitera de tester à la mise à jour
for ( int ine = 1 ; ine < borne_max_nbNoeud ; ine + + )
{ Noeud & noe = * tab_noeud ( ine ) ; // pour simplifier
// on regarde si le conteneur de la normale à un noeud frontière existe au noeud et création éventuelle
2023-05-03 17:23:49 +02:00
if ( ! noe . Existe_ici ( N_FRONT_t ) )
2024-04-24 10:34:35 +02:00
noe . AjoutUnTypeQuelconque ( typQ4_t ) ;
} ;
// on s'occupe du contenu
for ( int ine = 1 ; ine < borne_max_nbNoeud ; ine + + )
{ Noeud & noe = * tab_noeud ( ine ) ; // pour simplifier
2023-05-03 17:23:49 +02:00
2024-04-24 10:34:35 +02:00
// on récupère le conteneur au noeud
2023-05-03 17:23:49 +02:00
TypeQuelconque & tiq = noe . ModifGrandeur_quelconque ( N_FRONT_t0 ) ;
Grandeur_coordonnee & gr = * ( ( Grandeur_coordonnee * ) ( tiq . Grandeur_pointee ( ) ) ) ;
Coordonnee & normale = * gr . ConteneurCoordonnee ( ) ;
normale . Zero ( ) ; // init
2023-05-27 10:50:10 +02:00
// si on est en dimension 1, la normale est directement déterminé
if ( dima = = 1 )
{ normale ( 1 ) = 1. ;
}
else
{ // ici dima > 1, les éléments ont une métrique car ils sont différents des éléments points
List_io < Front * > & li_elem = indice_NFr ( ine ) ; // la liste des Front qui contiennent le noeud
List_io < Front * > : : iterator il , ilfin = li_elem . end ( ) ;
// on balaie les éléments
int nb_normale = 0 ; // le nombre de normales trouvées
for ( il = li_elem . begin ( ) ; il ! = ilfin ; il + + )
{ Front & elem = * ( * il ) ;
Enum_type_geom enutygeom = elem . Eleme_const ( ) - > Type_geom_front ( ) ;
int cas = elem . Eleme ( ) - > CalculNormale_noeud ( TEMPS_0 , * tab_noeud ( ine ) , coor_inter ) ;
// //------ debug
// if ((noe.Num_noeud() == 6) && (noe.Num_Mail()==2))
// { cout << "\n debug Maillage::InitNormaleAuxNoeuds():"
// << " noe "<< noe.Num_noeud() << " N= "; coor_inter.Affiche();
// };
// // ----- end debug
2023-05-03 17:23:49 +02:00
2023-05-27 10:50:10 +02:00
if ( cas = = 0 )
{ cout < < " \n *** erreur, le calcul de la normale n'est pas possible "
< < " pour le noeud " < < tab_noeud ( ine ) - > Num_noeud ( )
< < " du maillage " < < tab_noeud ( ine ) - > Num_Mail ( )
< < " par rapport a l'element de frontiere " ;
elem . Affiche ( 1 ) ;
cout < < " \n Maillage::InitNormaleAuxNoeuds() " ;
Sortie ( 1 ) ;
}
else if ( cas = = 2 )
{ // le calcul n'est pas licite, mais ce n'est pas une erreur
// simplement, l'élément n'est pas rusé pour ce noeud, on ne fait rien
}
else // sinon c'est ok
{ // on peut avoir des directions très proches mais de sens inverse ... ce qui va
// conduire à une somme nulle,
2024-04-24 10:34:35 +02:00
double intens_normale = normale . Norme ( ) ; // l'intensité actuelle
Coordonnee inter_co = normale + coor_inter ;
2023-05-27 10:50:10 +02:00
// if ((intens_normale > ConstMath::unpeupetit) && (inter_co.Norme() < ConstMath::petit))
// // normalement ne devrait pas arriver
// {
//
// }
2024-04-24 10:34:35 +02:00
//pour éviter cela, on pourrait regarder le produit scalaire
// s'il est négatif on utilise l'inverse de la normale
// donc en définitif on gardera globalement la direction précédente
if ( ( intens_normale > ConstMath : : unpeupetit ) & & ( inter_co . Norme ( ) < ConstMath : : petit ) )
{ normale - = coor_inter ; } // cas où la somme s'annulle
else // sinon cas normale
// if ((normale * coor_inter) > 0.)
{ normale + = coor_inter ; }
// {normale += coor_inter; }// ici cela me semble plus juste: on ne doit pas avoir de pb d'inversion de normale
2023-05-27 10:50:10 +02:00
nb_normale + + ;
} ;
} ;
if ( nb_normale ! = 0 )
{ normale / = nb_normale ;
// enfin on normalise la normale
normale . Normer ( ) ;
// ce qui fini la mise à jour de la normale au noeud
// //------ debug
// if ((noe.Num_noeud() == 6) && (noe.Num_Mail()==2))
// { cout << "\n debug Maillage::InitNormaleAuxNoeuds():"
// << " noe "<< noe.Num_noeud() << " N= "; normale.Affiche();
// };
// // ----- end debug
2023-05-03 17:23:49 +02:00
} ;
} ;
} ;
2024-04-24 10:34:35 +02:00
}
2024-12-11 21:30:13 +01:00
# ifndef UTILISATION_MPI // la vérif est intractable en MPI, pour des grands maillage
// on neutralise pour l'instant (le pb c'est les noeuds qui appartiennent qu'à
// des poutres en 3D et donc qui n'ont pas d'orientation, donc pas de normale)
// ça posera pb pour le contact
2023-05-03 17:23:49 +02:00
# ifdef MISE_AU_POINT
// on vérifie que tous les noeuds des frontières possèdent une normales
{ LaLIST < Front > : : iterator il , ilfin = listFrontiere . end ( ) ;
for ( il = listFrontiere . begin ( ) ; il ! = ilfin ; il + + )
{ Front & elem = ( * il ) ; // pour simplifier
ElFrontiere * elfro = elem . Eleme ( ) ;
Tableau < Noeud * > & tabNFront = elfro - > TabNoeud ( ) ;
int nbnoefront_et1 = 1 + tabNFront . Taille ( ) ;
for ( int inoe = 1 ; inoe < nbnoefront_et1 ; inoe + + )
{ Noeud & noe = * tabNFront ( inoe ) ; // pour simplifier
// on récupère le conteneur au noeud après création éventuelle
TypeQuelconque & tiq = noe . ModifGrandeur_quelconque ( N_FRONT_t0 ) ;
Grandeur_coordonnee & gr = * ( ( Grandeur_coordonnee * ) ( tiq . Grandeur_pointee ( ) ) ) ;
Coordonnee & normale = * gr . ConteneurCoordonnee ( ) ;
if ( Dabs ( normale . Norme ( ) ) = = 0. )
// cela veut qu'aucune normale n'est disponible, c'est bizarre
{ cout < < " \n *** attention le noeud " < < noe . Num_noeud ( )
< < " du maillage " < < noe . Num_Mail ( )
< < " n'a pas de normale moyenne definie a t0 " ;
} ;
////------ debug
2024-08-29 09:31:24 +02:00
//if ((noe.Num_noeud() == 1708) && (noe.Num_Mail()==2))
2023-05-03 17:23:49 +02:00
// { cout << "\n debug Maillage::InitNormaleAuxNoeuds():"
2024-08-29 09:31:24 +02:00
// << " noe "<< noe.Num_noeud() << " N à t = "; normale.Affiche();
2023-05-03 17:23:49 +02:00
// };
//// ----- end debug
} ;
} ;
} ;
# endif
2024-12-11 21:30:13 +01:00
# endif
2023-05-03 17:23:49 +02:00
// on initialise à t par défaut
{ LaLIST < Front > : : iterator il , ilfin = listFrontiere . end ( ) ;
for ( il = listFrontiere . begin ( ) ; il ! = ilfin ; il + + )
{ Front & elem = ( * il ) ; // pour simplifier
ElFrontiere * elfro = elem . Eleme ( ) ;
Tableau < Noeud * > & tabNFront = elfro - > TabNoeud ( ) ;
int nbnoefront_et1 = 1 + tabNFront . Taille ( ) ;
for ( int inoe = 1 ; inoe < nbnoefront_et1 ; inoe + + )
{ Noeud & noe = * tabNFront ( inoe ) ; // pour simplifier
// on récupère le conteneur au noeud après création éventuelle
TypeQuelconque & tiq = noe . ModifGrandeur_quelconque ( N_FRONT_t0 ) ;
Grandeur_coordonnee & gr = * ( ( Grandeur_coordonnee * ) ( tiq . Grandeur_pointee ( ) ) ) ;
Coordonnee & normale = * gr . ConteneurCoordonnee ( ) ;
// on récupère le conteneur au noeud après création éventuelle
TypeQuelconque & tiq_t = noe . ModifGrandeur_quelconque ( N_FRONT_t ) ;
Grandeur_coordonnee & gr_t = * ( ( Grandeur_coordonnee * ) ( tiq_t . Grandeur_pointee ( ) ) ) ;
Coordonnee & normale_t = * gr_t . ConteneurCoordonnee ( ) ;
normale_t = normale ;
} ;
} ;
} ;
2021-09-18 09:47:14 +02:00
} ;
2024-08-29 09:31:24 +02:00
// calcule des normales aux noeuds: dans le cas d'éléments 1D ou 2D
// et aussi pour les frontières (qui sont normalement de type 1D ou 2D)
2021-09-18 09:47:14 +02:00
// a priori le calcul s'effectue par une moyenne des normales des éléments qui
// entourent le noeud.
// mise à jour -> mise à jour des normales à t
void Maillage : : MiseAjourNormaleAuxNoeuds ( )
{ // on va parcourir les noeuds et on n'intervient que si le noeud
// appartient à un élément 1D et/ou 2D
int nbNoeud = tab_noeud . Taille ( ) ;
2024-11-25 10:36:00 +01:00
int dima = ParaGlob : : Dimension ( ) ;
2021-09-18 09:47:14 +02:00
int borne_max_nbNoeud = nbNoeud + 1 ;
Coordonnee coor_inter ; // coordonnée de travail
for ( int ine = 1 ; ine < borne_max_nbNoeud ; ine + + )
{ Noeud & noe = * tab_noeud ( ine ) ; // pour simplifier
// on récupère la normale au noeud
TypeQuelconque & tiq = noe . ModifGrandeur_quelconque ( NN_SURF_t ) ;
Grandeur_coordonnee & gr = * ( ( Grandeur_coordonnee * ) ( tiq . Grandeur_pointee ( ) ) ) ;
Coordonnee & normale = * gr . ConteneurCoordonnee ( ) ;
normale . Zero ( ) ; // init
// calcul éventuel du tableau Indice
this - > Indice ( ) ;
2023-05-27 10:50:10 +02:00
int dima = ParaGlob : : Dimension ( ) ;
2021-09-18 09:47:14 +02:00
2023-05-27 10:50:10 +02:00
// si on est en dimension 1, la normale est directement déterminé
if ( dima = = 1 )
{ normale ( 1 ) = 1. ;
}
else
{ // ici dima > 1, les éléments ont une métrique car ils sont différents des éléments points
List_io < Element * > & li_elem = indice ( ine ) ; // la liste des éléments qui contiennent le noeud
List_io < Element * > : : iterator il , ilfin = li_elem . end ( ) ;
// on balaie les éléments
int nb_normale = 0 ; // le nombre de normales trouvées
for ( il = li_elem . begin ( ) ; il ! = ilfin ; il + + )
{ Element & elem = * ( * il ) ;
Enum_type_geom enutygeom = Type_geom_generique ( elem . Id_geometrie ( ) ) ;
// if ((enutygeom == LIGNE) || (enutygeom == SURFACE))
2024-11-25 10:36:00 +01:00
if ( ( enutygeom = = SURFACE ) // dans une première étape on ne s'occupe que des surfaces en 3D
& & ( dima = = 3 ) // si surface en 2D, ce sera les éléments frontières qui détermineront les normales
)
2023-05-27 10:50:10 +02:00
{ int cas = elem . CalculNormale_noeud ( TEMPS_t , * tab_noeud ( ine ) , coor_inter ) ;
if ( cas = = 0 )
{ cout < < " \n *** erreur, le calcul de la normale n'est pas possible "
< < " pour le noeud " < < tab_noeud ( ine ) - > Num_noeud ( )
< < " du maillage " < < tab_noeud ( ine ) - > Num_Mail ( )
< < " par rapport a l'element " < < elem . Num_elt ( )
< < " du maillage " < < elem . Num_maillage ( )
< < " \n Maillage::MiseAjourNormaleAuxNoeuds() " ;
Sortie ( 1 ) ;
}
else if ( cas = = 2 )
{ // le calcul n'est pas licite, mais ce n'est pas une erreur
// simplement, l'élément n'est pas rusé pour ce noeud, on ne fait rien
}
else // sinon c'est ok
2024-04-24 10:34:35 +02:00
{ // on peut avoir des directions très proches mais de sens inverse ... ce qui va
// conduire à une somme nulle, pour éviter cela, on regarde le produit scalaire
// s'il est négatif on utilise l'inverse de la normale
// donc en définitif on gardera globalement la direction précédente
if ( ( normale * coor_inter ) > 0. )
{ normale + = coor_inter ; }
else
{ normale - = coor_inter ; } ;
// {normale += coor_inter;
2023-05-27 10:50:10 +02:00
nb_normale + + ;
} ;
2021-09-18 09:47:14 +02:00
} ;
} ;
2023-05-27 10:50:10 +02:00
if ( nb_normale ! = 0 )
{ normale / = nb_normale ;
// enfin on normalise la normale
normale . Normer ( ) ;
} ;
2021-09-18 09:47:14 +02:00
} ;
// ce qui fini la mise à jour de la normale au noeud
} ;
2023-05-03 17:23:49 +02:00
// on fait de même pour les éléments frontières minimals
// calcul éventuel du tableau indice_NFr
this - > Indice_NFr ( ) ;
for ( int ine = 1 ; ine < borne_max_nbNoeud ; ine + + )
{ Noeud & noe = * tab_noeud ( ine ) ; // pour simplifier
// on récupère la normale au noeud
TypeQuelconque & tiq = noe . ModifGrandeur_quelconque ( N_FRONT_t ) ;
Grandeur_coordonnee & gr = * ( ( Grandeur_coordonnee * ) ( tiq . Grandeur_pointee ( ) ) ) ;
Coordonnee & normale = * gr . ConteneurCoordonnee ( ) ;
normale . Zero ( ) ; // init
2023-05-27 10:50:10 +02:00
// si on est en dimension 1, la normale est directement déterminé
if ( dima = = 1 )
{ normale ( 1 ) = 1. ;
}
else
{ // ici dima > 1, les éléments ont une métrique car ils sont différents des éléments points
List_io < Front * > & li_elem = indice_NFr ( ine ) ; // la liste des Front qui contiennent le noeud
List_io < Front * > : : iterator il , ilfin = li_elem . end ( ) ;
// on balaie les éléments
int nb_normale = 0 ; // le nombre de normales trouvées
for ( il = li_elem . begin ( ) ; il ! = ilfin ; il + + )
{ Front & elem = * ( * il ) ;
Enum_type_geom enutygeom = elem . Eleme_const ( ) - > Type_geom_front ( ) ;
int cas = elem . Eleme ( ) - > CalculNormale_noeud ( TEMPS_t , * tab_noeud ( ine ) , coor_inter ) ;
if ( cas = = 0 )
{ cout < < " \n *** erreur, le calcul de la normale n'est pas possible "
< < " pour le noeud " < < tab_noeud ( ine ) - > Num_noeud ( )
< < " du maillage " < < tab_noeud ( ine ) - > Num_Mail ( )
< < " par rapport a l'element de frontiere " ;
elem . Affiche ( 1 ) ;
cout < < " \n Maillage::InitNormaleAuxNoeuds() " ;
Sortie ( 1 ) ;
}
else if ( cas = = 2 )
{ // le calcul n'est pas licite, mais ce n'est pas une erreur
// simplement, l'élément n'est pas rusé pour ce noeud, on ne fait rien
}
else // sinon c'est ok
{ // on peut avoir des directions très proches mais de sens inverse ... ce qui va
// conduire à une somme nulle, pour éviter cela, on regarde le produit scalaire
// s'il est négatif on utilise l'inverse de la normale
// donc en définitif on gardera globalement la direction précédente
2024-04-24 10:34:35 +02:00
if ( ( normale * coor_inter ) > 0. )
2023-05-27 10:50:10 +02:00
{ normale + = coor_inter ; }
2024-04-24 10:34:35 +02:00
else
{ normale - = coor_inter ; } ;
2023-05-27 10:50:10 +02:00
nb_normale + + ;
} ;
} ;
if ( nb_normale ! = 0 )
{ normale / = nb_normale ;
// enfin on normalise la normale
normale . Normer ( ) ;
2023-05-03 17:23:49 +02:00
} ;
} ;
// ce qui fini la mise à jour de la normale au noeud
} ;
2024-12-11 21:30:13 +01:00
# ifndef UTILISATION_MPI // la vérif est intractable en MPI, pour des grands maillage
// on neutralise pour l'instant (le pb c'est les noeuds qui appartiennent qu'à
// des poutres en 3D et donc qui n'ont pas d'orientation, donc pas de normale)
// ça posera pb pour le contact
2023-05-03 17:23:49 +02:00
# ifdef MISE_AU_POINT
// on vérifie que tous les noeuds des frontières possèdent une normales
{ LaLIST < Front > : : iterator il , ilfin = listFrontiere . end ( ) ;
for ( il = listFrontiere . begin ( ) ; il ! = ilfin ; il + + )
{ Front & elem = ( * il ) ; // pour simplifier
ElFrontiere * elfro = elem . Eleme ( ) ;
Tableau < Noeud * > & tabNFront = elfro - > TabNoeud ( ) ;
int nbnoefront_et1 = 1 + tabNFront . Taille ( ) ;
for ( int inoe = 1 ; inoe < nbnoefront_et1 ; inoe + + )
{ Noeud & noe = * tabNFront ( inoe ) ; // pour simplifier
// on récupère le conteneur au noeud après création éventuelle
TypeQuelconque & tiq = noe . ModifGrandeur_quelconque ( N_FRONT_t ) ;
Grandeur_coordonnee & gr = * ( ( Grandeur_coordonnee * ) ( tiq . Grandeur_pointee ( ) ) ) ;
Coordonnee & normale = * gr . ConteneurCoordonnee ( ) ;
if ( Dabs ( normale . Norme ( ) ) = = 0. )
// cela veut qu'aucune normale n'est disponible, c'est bizarre
{ cout < < " \n *** attention le noeud " < < noe . Num_noeud ( )
< < " du maillage " < < noe . Num_Mail ( )
< < " n'a pas de normale moyenne definie a t " ;
} ;
} ;
} ;
} ;
# endif
2024-12-11 21:30:13 +01:00
# endif
2023-05-03 17:23:49 +02:00
2021-09-18 09:47:14 +02:00
} ;
// 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 Maillage : : MiseAjourNormaleAuxNoeuds_de_tdt_vers_T ( )
{ // on va parcourir les noeuds et on n'intervient que si le noeud
// appartient à un élément 1D et/ou 2D
int nbNoeud = tab_noeud . Taille ( ) ;
2024-11-25 10:36:00 +01:00
int dima = ParaGlob : : Dimension ( ) ;
2021-09-18 09:47:14 +02:00
int borne_max_nbNoeud = nbNoeud + 1 ;
Coordonnee coor_inter ; // coordonnée de travail
for ( int ine = 1 ; ine < borne_max_nbNoeud ; ine + + )
{ Noeud & noe = * tab_noeud ( ine ) ; // pour simplifier
// on récupère la normale au noeud
TypeQuelconque & tiq = noe . ModifGrandeur_quelconque ( NN_SURF_t ) ;
Grandeur_coordonnee & gr = * ( ( Grandeur_coordonnee * ) ( tiq . Grandeur_pointee ( ) ) ) ;
Coordonnee & normale = * gr . ConteneurCoordonnee ( ) ;
normale . Zero ( ) ; // init
// calcul éventuel du tableau Indice
this - > Indice ( ) ;
List_io < Element * > & li_elem = indice ( ine ) ; // la liste des éléments qui contiennent le noeud
List_io < Element * > : : iterator il , ilfin = li_elem . end ( ) ;
// on balaie les éléments
int nb_normale = 0 ; // le nombre de normales trouvées
for ( il = li_elem . begin ( ) ; il ! = ilfin ; il + + )
{ Element & elem = * ( * il ) ;
Enum_type_geom enutygeom = Type_geom_generique ( elem . Id_geometrie ( ) ) ;
// if ((enutygeom == LIGNE) || (enutygeom == SURFACE))
2024-11-25 10:36:00 +01:00
if ( ( enutygeom = = SURFACE ) // dans une première étape on ne s'occupe que des surfaces en 3D
& & ( dima = = 3 ) // si surface en 2D, ce sera les éléments frontières qui détermineront les normales
)
2021-09-18 09:47:14 +02:00
{ // ici contrairement à la méthode: MiseAjourNormaleAuxNoeuds
// on demande à l'élément de calculer la normale avec la géométrie à tdt
int cas = elem . CalculNormale_noeud ( TEMPS_tdt , * tab_noeud ( ine ) , coor_inter ) ;
if ( cas = = 0 )
{ cout < < " \n *** erreur, le calcul de la normale n'est pas possible "
< < " pour le noeud " < < tab_noeud ( ine ) - > Num_noeud ( )
< < " du maillage " < < tab_noeud ( ine ) - > Num_Mail ( )
< < " par rapport a l'element " < < elem . Num_elt ( )
< < " du maillage " < < elem . Num_maillage ( )
< < " \n Maillage::MiseAjourNormaleAuxNoeuds_de_tdt_vers_T() " ;
Sortie ( 1 ) ;
}
else if ( cas = = 2 )
{ // le calcul n'est pas licite, mais ce n'est pas une erreur
// simplement, l'élément n'est pas rusé pour ce noeud, on ne fait rien
}
else // sinon c'est ok
2024-04-24 10:34:35 +02:00
{ // on peut avoir des directions très proches mais de sens inverse ... ce qui va
// conduire à une somme nulle, pour éviter cela, on regarde le produit scalaire
// s'il est négatif on utilise l'inverse de la normale
// donc en définitif on gardera globalement la direction précédente
if ( ( normale * coor_inter ) > 0. )
{ normale + = coor_inter ; }
else
{ normale - = coor_inter ; } ;
// {normale += coor_inter;
2021-09-18 09:47:14 +02:00
nb_normale + + ;
} ;
} ;
} ;
if ( nb_normale ! = 0 )
{ normale / = nb_normale ;
// enfin on normalise la normale
normale . Normer ( ) ;
} ;
// ce qui fini la mise à jour de la normale au noeud
} ;
2023-05-03 17:23:49 +02:00
// on fait de même pour les éléments frontières minimals
// calcul éventuel du tableau indice_NFr
this - > Indice_NFr ( ) ;
for ( int ine = 1 ; ine < borne_max_nbNoeud ; ine + + )
{ Noeud & noe = * tab_noeud ( ine ) ; // pour simplifier
// on récupère la normale au noeud
TypeQuelconque & tiq = noe . ModifGrandeur_quelconque ( N_FRONT_t ) ;
Grandeur_coordonnee & gr = * ( ( Grandeur_coordonnee * ) ( tiq . Grandeur_pointee ( ) ) ) ;
Coordonnee & normale = * gr . ConteneurCoordonnee ( ) ;
normale . Zero ( ) ; // init
2023-05-27 10:50:10 +02:00
// si on est en dimension 1, la normale est directement déterminé
if ( dima = = 1 )
{ normale ( 1 ) = 1. ;
}
else
{ // ici dima > 1, les éléments ont une métrique car ils sont différents des éléments points
// la norme est nulle, on continue
List_io < Front * > & li_elem = indice_NFr ( ine ) ; // la liste des Front qui contiennent le noeud
List_io < Front * > : : iterator il , ilfin = li_elem . end ( ) ;
// on balaie les éléments
int nb_normale = 0 ; // le nombre de normales trouvées
for ( il = li_elem . begin ( ) ; il ! = ilfin ; il + + )
{ Front & elem = * ( * il ) ;
Enum_type_geom enutygeom = elem . Eleme_const ( ) - > Type_geom_front ( ) ;
// ici contrairement à la méthode: MiseAjourNormaleAuxNoeuds
// on demande à l'élément de calculer la normale avec la géométrie à tdt
int cas = elem . Eleme ( ) - > CalculNormale_noeud ( TEMPS_tdt , * tab_noeud ( ine ) , coor_inter ) ;
if ( cas = = 0 )
{ cout < < " \n *** erreur, le calcul de la normale n'est pas possible "
< < " pour le noeud " < < tab_noeud ( ine ) - > Num_noeud ( )
< < " du maillage " < < tab_noeud ( ine ) - > Num_Mail ( )
< < " par rapport a l'element de frontiere " ;
elem . Affiche ( 1 ) ;
cout < < " \n Maillage::InitNormaleAuxNoeuds() " ;
Sortie ( 1 ) ;
}
else if ( cas = = 2 )
{ // le calcul n'est pas licite, mais ce n'est pas une erreur
// simplement, l'élément n'est pas rusé pour ce noeud, on ne fait rien
}
else // sinon c'est ok
{ // on peut avoir des directions très proches mais de sens inverse ... ce qui va
// conduire à une somme nulle, pour éviter cela, on regarde le produit scalaire
// s'il est négatif on utilise l'inverse de la normale
// donc en définitif on gardera globalement la direction précédente
2024-04-24 10:34:35 +02:00
if ( ( normale * coor_inter ) > 0. )
2023-05-27 10:50:10 +02:00
{ normale + = coor_inter ; }
2024-04-24 10:34:35 +02:00
else
{ normale - = coor_inter ; } ;
2023-05-27 10:50:10 +02:00
nb_normale + + ;
} ;
} ;
if ( nb_normale ! = 0 )
{ normale / = nb_normale ;
// enfin on normalise la normale
normale . Normer ( ) ;
2023-05-03 17:23:49 +02:00
} ;
} ;
// ce qui fini la mise à jour de la normale au noeud
} ;
2024-12-11 21:30:13 +01:00
# ifndef UTILISATION_MPI // la vérif est intractable en MPI, pour des grands maillage
// on neutralise pour l'instant (le pb c'est les noeuds qui appartiennent qu'à
// des poutres en 3D et donc qui n'ont pas d'orientation, donc pas de normale)
// ça posera pb pour le contact
2023-05-03 17:23:49 +02:00
# ifdef MISE_AU_POINT
// on vérifie que tous les noeuds des frontières possèdent une normales
{ LaLIST < Front > : : iterator il , ilfin = listFrontiere . end ( ) ;
for ( il = listFrontiere . begin ( ) ; il ! = ilfin ; il + + )
{ Front & elem = ( * il ) ; // pour simplifier
ElFrontiere * elfro = elem . Eleme ( ) ;
Tableau < Noeud * > & tabNFront = elfro - > TabNoeud ( ) ;
int nbnoefront_et1 = 1 + tabNFront . Taille ( ) ;
for ( int inoe = 1 ; inoe < nbnoefront_et1 ; inoe + + )
{ Noeud & noe = * tabNFront ( inoe ) ; // pour simplifier
// on récupère le conteneur au noeud après création éventuelle
TypeQuelconque & tiq = noe . ModifGrandeur_quelconque ( N_FRONT_t ) ;
Grandeur_coordonnee & gr = * ( ( Grandeur_coordonnee * ) ( tiq . Grandeur_pointee ( ) ) ) ;
Coordonnee & normale = * gr . ConteneurCoordonnee ( ) ;
if ( Dabs ( normale . Norme ( ) ) = = 0. )
// cela veut qu'aucune normale n'est disponible, c'est bizarre
{ cout < < " \n *** attention le noeud " < < noe . Num_noeud ( )
< < " du maillage " < < noe . Num_Mail ( )
< < " n'a pas de normale moyenne definie a t " ;
} ;
} ;
} ;
} ;
# endif
2024-12-11 21:30:13 +01:00
# endif
2023-05-03 17:23:49 +02:00
2021-09-18 09:47:14 +02:00
} ;
// creation des elements frontiere
2023-05-03 17:23:49 +02:00
// il s'agit ici des frontière minimales permettant de représenter toute la frontière
// Ainsi:
// en 1D on retrouve:
// - des points uniquement
// en 2D on retrouve :
// - des segments dans le cas d'une surface (les noeuds sont exclus car intégrés aux lignes)
// - points et segment pour les lignes
// en 2D axi, on retrouve :
// - des segments dans le cas d'une surface (les noeuds sont exclus car intégrés aux lignes)
// - points et segment pour les lignes
// en 3D, on retrouve
// - des faces pour les éléments volumique (noeuds et lignes sont exclus)
// - une face et des lignes pour les éléments 2D (pas de noeuds)
2021-09-18 09:47:14 +02:00
void Maillage : : CreeElemFront ( )
{
// 0- on supprime la liste existante
listFrontiere . erase ( listFrontiere . begin ( ) , listFrontiere . end ( ) ) ;
// 1- tout d'abord on crée les éléments frontière dans chaque élément
int tabelTaille = tab_element . Taille ( ) ;
// on boucle sur les elements
for ( int i2 = 1 ; i2 < = tabelTaille ; i2 + + )
2025-01-22 18:18:03 +01:00
// création des éléments frontières (on force)
tab_element ( i2 ) - > Frontiere ( true ) ;
int nb_init_frontiere = 0 ;
# ifdef MISE_AU_POINT
{ for ( int i1 = 1 ; i1 < = tabelTaille ; i1 + + )
{ const Tableau < ElFrontiere * > & tab1 = tab_element ( i1 ) - > Frontieres_Actuelles ( ) ;
int tab1Taille = tab1 . Taille ( ) ;
for ( int i = 1 ; i < = tab1Taille ; i + + )
if ( tab1 ( i ) ! = NULL )
nb_init_frontiere + + ;
}
// cout << "\n au début : après création des frontières dans les elements ->"<<nb_front_enreg<<" frontières " << flush;
} ;
# endif
// -- fin debug
2021-09-18 09:47:14 +02:00
// 2- maintenant on va créé des tableaux permettant d'accélérer l'algorithme final
// pour chaque noeud on regarde quel élément contiend ce noeud
Calcul_indice ( ) ;
int tab_noeud_taille = tab_noeud . Taille ( ) ;
// indice contiend les numéros d'élément succeptible d'avoir des frontières
// communes
// 3- maintenant on va de nouveau boucler sur les éléments en regardant
// pour chaque frontière si elle est effectivement recevable c-a-d si
// il n'y a pas deux frontières identiques
Front lili ; // un element de référence de frontière courant
2025-01-22 18:18:03 +01:00
// des indicateurs pour la sortie de message
int nb_cas_I = 0 ; int nb_cas_II = 0 ; int nb_cas_courant = 0 ;
2021-09-18 09:47:14 +02:00
// for (int i1 = 1; i1 <= tabelTaille-1; ++i1)
for ( int i1 = 1 ; i1 < = tabelTaille ; i1 + + )
{ Element * elem1 = tab_element ( i1 ) ; // recup de l'element
2025-01-22 18:18:03 +01:00
// récup du type des éléments finis :-> POINT_G , LIGNE , SURFACE, VOLUME
Enum_type_geom typ1_element = Type_geom_generique ( elem1 - > Id_geometrie ( ) ) ;
const Tableau < ElFrontiere * > & tab1 = elem1 - > Frontieres_Actuelles ( ) ; // et de ses frontières
2021-09-18 09:47:14 +02:00
int tab1Taille = tab1 . Taille ( ) ; // frontières
2025-01-22 18:18:03 +01:00
/* //------- debug
{ int nb_front_enreg = 0 ;
cout < < " \n === début === on regarde les frontieres ( " < < tabelTaille < < " ) de l'element " < < elem1 - > Num_elt ( ) < < " type " < < Nom_type_geom ( typ1_element ) ;
for ( int i1 = 1 ; i1 < = tabelTaille ; i1 + + )
{ const Tableau < ElFrontiere * > & tab1 = tab_element ( i1 ) - > Frontieres_Actuelles ( ) ;
int tab1Taille = tab1 . Taille ( ) ;
for ( int i = 1 ; i < = tab1Taille ; i + + )
if ( tab1 ( i ) ! = NULL )
nb_front_enreg + + ;
}
cout < < " \n actuellement: dans les elements -> " < < nb_front_enreg < < " frontières, dans la liste -> " < < listFrontiere . size ( ) < < flush ;
}
//---- fin debug */
2021-09-18 09:47:14 +02:00
// on boucle sur les frontière, qui doivent être repérée par un pointeur non nulle
for ( int j1 = 1 ; j1 < = tab1Taille ; j1 + + )
// on essaie de voir si l'élément j1 est recevable, c-a-d pointeur non nulle
// sinon cela veut dire que la frontière a été supprimer car en double
{ ElFrontiere * elfr = tab1 ( j1 ) ; // pour simplifier
2025-01-22 18:18:03 +01:00
// on ne continue que si le pointeur est non nul
2021-09-18 09:47:14 +02:00
if ( elfr ! = NULL )
2025-01-22 18:18:03 +01:00
{ Enum_type_geom typ1_frontiere = elfr - > Type_geom_front ( ) ;
2021-09-18 09:47:14 +02:00
bool res = false ;
// si deux éléments frontières sont identiques alors tous leurs noeuds
// sont identiques. En particulier le premier noeud de *elfr est commum
// avec tous les éléments succeptibles de contenir un élément frontière
// identique. On va donc utiliser la liste indice qui contiend cette liste
int numnoeud = ( elfr - > TabNoeud ( ) ) ( 1 ) - > Num_noeud ( ) ;
list < Element * > : : iterator ina , infin ;
list < Element * > & intertab = indice ( numnoeud ) ; // pour allèger l'écriture
infin = intertab . end ( ) ;
2025-01-22 18:18:03 +01:00
/* //-- debug
cout < < " \n element1 " < < elem1 - > Num_elt ( ) < < " cas de la frontière " < < j1 < < " type " < < Nom_type_geom ( typ1_frontiere )
< < " : nb candidat -> " < < intertab . size ( ) < < " on parcours les candidats: " ;
{ if ( ( ( elem1 - > Num_elt ( ) = = 10 ) & & ( j1 = = 3 ) )
| | ( ( elem1 - > Num_elt ( ) = = 12 ) & & ( j1 = = 4 ) )
)
{ cout < < " \n elem1 " < < elem1 - > Num_elt ( ) < < " , frontière " < < j1 ;
Tableau < Noeud * > & taa = elfr - > TabNoeud ( ) ;
cout < < " \n les num des noeuds de la frontière : " ;
for ( int i = 1 ; i < = taa . Taille ( ) ; i + + )
cout < < taa ( i ) - > Num_noeud ( ) < < " " ;
cout < < " \n la liste des elem contenant le premier noeud " ;
list < Element * > : : iterator ina , infin = intertab . end ( ) ;
for ( ina = intertab . begin ( ) ; ina ! = infin ; ina + + )
cout < < ( * ina ) - > Num_elt ( ) < < " " ;
}
}
//--fin debug */
int type_ajout = 0 ; // pour le debug
2021-09-18 09:47:14 +02:00
// on balaie les élément succeptibles d'avoir des frontières communes
for ( ina = intertab . begin ( ) ; ina ! = infin ; ina + + )
{ Element * elem2 = * ina ; // recup de l'element
2025-01-22 18:18:03 +01:00
// récup du type des éléments finis :-> POINT_G , LIGNE , SURFACE, VOLUME
Enum_type_geom typ2_element = Type_geom_generique ( elem2 - > Id_geometrie ( ) ) ;
2021-09-18 09:47:14 +02:00
2025-01-22 18:18:03 +01:00
/* //-- debug
cout < < " \n candidat element: " < < elem2 - > Num_elt ( ) < < " type " < < Nom_type_geom ( typ2_element ) ;
//--fin debug */
2021-09-18 09:47:14 +02:00
// on ne fait la recherche que pour les éléments différents de elem1
bool res_ina = false ; // init d'un indicateur interne à la boucle j2 qui suit,
if ( elem2 ! = elem1 )
{
2025-01-22 18:18:03 +01:00
const Tableau < ElFrontiere * > & tab2 = elem2 - > Frontieres_Actuelles ( ) ; // et des éléments
2021-09-18 09:47:14 +02:00
int tab2Taille = tab2 . Taille ( ) ; // frontières
for ( int j2 = 1 ; j2 < = tab2Taille ; + + j2 )
{ // dans le cas où l'élément frontière existe, c'est-à-dire
// qu'il n'a pas été supprimé par un précédent passage
// on le compare
ElFrontiere * tab2j2 = tab2 ( j2 ) ; // pour simplifier
2025-01-22 18:18:03 +01:00
2021-09-18 09:47:14 +02:00
if ( tab2j2 ! = NULL )
2025-01-22 18:18:03 +01:00
{ Enum_type_geom typ2_frontiere = tab2j2 - > Type_geom_front ( ) ;
/* //-- debug
cout < < " \n element 2 " < < elem2 - > Num_elt ( ) < < " cas de la frontière " < < j2 < < " type " < < Nom_type_geom ( typ2_frontiere ) ;
//--fin debug */
// // pb dans le calcul de l'opposé ou due à l'utilisation de p ?? ElFrontiere* p = tab2j2->Oppose(); // variable transitoire
// if ((*elfr) == (*p))
if ( ( * elfr ) = = ( * tab2j2 ) )
2021-09-18 09:47:14 +02:00
// on a trouve un element qui annule
2025-01-22 18:18:03 +01:00
// cependant il y a un cas particulier:
// I - on a la supperposition de 2 mêmes frontières mais pour des éléments finis de tailles différentes
// 1) on a la supperposition d'une surface d'un élément fini 2D avec une facette d'un élément 3D
// 2) ou la supperposition d'une ligne d'un élément fini 1D avec une arête d'un élément 3D ou 2D
// dans ces là, ces ElFrontiere peuvent quand même représenter une vrai frontière mais
// elles font double emploi, du coup on fait le choix de garder l'élément frontière de dim inférieur
{
// modif
// on ne continue que s'il s'agit du même type d'élément
if ( typ1_element = = typ2_element )
{ res = res_ina = true ; // on met les indicateurs
// pour sortie de la boucle sur j2
// suppression de l'élément dans la liste
if ( elem2 - > SupprimeFront ( tab2j2 ) )
nb_cas_courant + + ;
} ;
// if (typ1_element != typ2_element) // là il faut regarder de plus près:
// // pour les types, il s'agit d'un enuméré avec: POINT_G = 1 , LIGNE , SURFACE, VOLUME, RIEN_TYPE_GEOM
// {
// if (typ1_element > typ2_element) // on va supprimer le 1 et garder le 2
// {res = res_ina = true;// on met l'indicateur
// }
// else // c'est forcément l'inverse: on va supprimer le 2 et garder le 1
// // suppression de l'élément dans la liste
// // mais on ne met pas l'indicateur, donc la frontière d'elem1 ne sera pas supprimé, d'une part
// // et on continue les boucles sur j2 et au dessus sur ina
// {
/* //------- debug
// on passe en revue la liste des frontières enregistrées, normalement on ne devrait pas supprimer une frontière déjà enregistrée
{ LaLIST < Front > : : iterator iF , iFfin = listFrontiere . end ( ) ;
for ( iF = listFrontiere . begin ( ) ; iF ! = iFfin ; iF + + )
{ Front * fro = & ( * iF ) ;
ElFrontiere * elfli = fro - > Eleme ( ) ;
if ( ( ( * elfli ) = = ( * tab2j2 ) ) & & ( elem2 - > Num_elt ( ) = = fro - > PtEI ( ) - > Num_elt ( ) ) )
{ cout < < " \n erreur1 la frontière est déjà enregistrée, on ne devrait pas avoir à la supprimer ?? " < < flush ;
}
}
}
//---- fin debug */
// if (elem2->SupprimeFront(tab2j2))
// {nb_cas_I++;
/* //------- debug
{ int nb_front_enreg = 0 ;
for ( int i1 = 1 ; i1 < = tabelTaille ; i1 + + )
{ const Tableau < ElFrontiere * > & tab1 = tab_element ( i1 ) - > Frontieres_Actuelles ( ) ;
int tab1Taille = tab1 . Taille ( ) ;
for ( int i = 1 ; i < = tab1Taille ; i + + )
if ( tab1 ( i ) ! = NULL )
nb_front_enreg + + ;
}
cout < < " \n suppression frontière elem2 (cas_I): actuellement dans les elements -> " < < nb_front_enreg < < " frontières, dans la liste -> " < < listFrontiere . size ( ) < < flush ;
}
// on passe en revue la liste des frontières enregistrées, et on vérifie que toutes les frontières correspondent à des frontières d'éléments toujours licites
{ LaLIST < Front > : : iterator iF , iFfin = listFrontiere . end ( ) ;
for ( iF = listFrontiere . begin ( ) ; iF ! = iFfin ; iF + + )
{ Front * fro = & ( * iF ) ;
Element * elem = fro - > PtEI ( ) ;
if ( elem - > Frontieres_Actuelles ( ) ( elem - > Num_global_frontiere ( fro - > Num_frontiere ( ) , fro - > Eleme ( ) - > Type_geom_front ( ) ) ) = = NULL )
{ cout < < " \n *** erreur de cohérence liste<=>éléments finis, la frontière " ; fro - > Affiche ( 1 ) ;
cout < < " n'existe plus dans l'élément finis " < < flush ;
Sortie ( 1 ) ;
}
}
}
//---- fin debug */
// };
// }
// }
// else
//
//
// // II - on a la supperposition de 2 mêmes frontière pour des éléments de même taille
// // 1) mais si on est en 3D et qu'il s'agit d'une frontière 2D d'un élément 2D, il s'agit d'élément 2D qui peuvent
// // définir une frontière, on fait le choix de garder une des deux frontières et de supprimer l'autre
// { if ((ParaGlob::Dimension() == 3) && (typ2_frontiere ==3))
// // on va supprimer le 2 et garder le 1
// // mais on ne met pas l'indicateur, donc la frontière d'elem1 ne sera pas supprimé
// // et on continue les boucles sur j2 et au dessus sur ina
// {
/* //------- debug
// on passe en revue la liste des frontières enregistrées, normalement on ne devrait pas supprimer une frontière déjà enregistrée
{ LaLIST < Front > : : iterator iF , iFfin = listFrontiere . end ( ) ;
for ( iF = listFrontiere . begin ( ) ; iF ! = iFfin ; iF + + )
{ Front * fro = & ( * iF ) ;
ElFrontiere * elfli = fro - > Eleme ( ) ;
if ( ( ( * elfli ) = = ( * tab2j2 ) ) & & ( elem2 - > Num_elt ( ) = = fro - > PtEI ( ) - > Num_elt ( ) ) )
{ cout < < " \n erreur2 la frontière est déjà enregistrée, on ne devrait pas avoir à la supprimer ?? " < < flush ;
}
}
}
cout < < " \n avant suppression frontière elem2 " ;
// on passe en revue la liste des frontières enregistrées, et on vérifie que toutes les frontières correspondent à des frontières d'éléments toujours licites
{ LaLIST < Front > : : iterator iF , iFfin = listFrontiere . end ( ) ;
for ( iF = listFrontiere . begin ( ) ; iF ! = iFfin ; iF + + )
{ Front * fro = & ( * iF ) ;
Element * elem = fro - > PtEI ( ) ;
if ( elem - > Frontieres_Actuelles ( ) ( elem - > Num_global_frontiere ( fro - > Num_frontiere ( ) , fro - > Eleme ( ) - > Type_geom_front ( ) ) ) = = NULL )
{ cout < < " \n *** erreur de cohérence liste<=>éléments finis, la frontière " ; fro - > Affiche ( 1 ) ;
cout < < " n'existe plus dans l'élément finis " < < flush ;
Sortie ( 1 ) ;
}
}
}
//---- fin debug */
// if (elem2->SupprimeFront(tab2j2))
// {nb_cas_II++;
/* //------- debug
{ int nb_front_enreg = 0 ;
for ( int i1 = 1 ; i1 < = tabelTaille ; i1 + + )
{ const Tableau < ElFrontiere * > & tab1 = tab_element ( i1 ) - > Frontieres_Actuelles ( ) ;
int tab1Taille = tab1 . Taille ( ) ;
for ( int i = 1 ; i < = tab1Taille ; i + + )
if ( tab1 ( i ) ! = NULL )
nb_front_enreg + + ;
}
cout < < " \n suppression frontière elem2 (cas_II): actuellement dans les elements -> " < < nb_front_enreg < < " frontières, dans la liste -> " < < listFrontiere . size ( ) < < flush ;
// on passe en revue la liste des frontières enregistrées, et on vérifie que toutes les frontières correspondent à des frontières d'éléments toujours licites
{ LaLIST < Front > : : iterator iF , iFfin = listFrontiere . end ( ) ;
for ( iF = listFrontiere . begin ( ) ; iF ! = iFfin ; iF + + )
{ Front * fro = & ( * iF ) ;
Element * elem = fro - > PtEI ( ) ;
if ( elem - > Frontieres_Actuelles ( ) ( elem - > Num_global_frontiere ( fro - > Num_frontiere ( ) , fro - > Eleme ( ) - > Type_geom_front ( ) ) ) = = NULL )
{ cout < < " \n *** erreur de cohérence liste<=>éléments finis, la frontière " ; fro - > Affiche ( 1 ) ;
cout < < " n'existe plus dans l'élément finis " < < flush ;
Sortie ( 1 ) ;
}
}
}
}
//---- fin debug */
// };
// }
// else // autre cas -> c-a-d hors cas particulier
// // cas où on a le même type, on va supprimer les deux frontières
// {res = res_ina = true;// on met les indicateurs
// // pour sortie de la boucle sur j2
// // suppression de l'élément dans la liste
/* //------- debug
{ cout < < " \n on va supprimer : la frontiere " < < tab2j2 - > Type_geom_front ( ) < < " de num dans le type " < < elem2 - > Num_de_frontiere_dans_le_type ( j2 )
< < " de l'element fini " < < elem2 - > Num_elt ( ) < < " type " < < Nom_type_geom ( typ2_element ) < < flush ;
// on passe en revue la liste des frontières enregistrées, normalement on ne devrait pas supprimer une frontière déjà enregistrée
LaLIST < Front > : : iterator iF , iFfin = listFrontiere . end ( ) ;
for ( iF = listFrontiere . begin ( ) ; iF ! = iFfin ; iF + + )
{ Front * fro = & ( * iF ) ;
ElFrontiere * elfli = fro - > Eleme ( ) ;
if ( ( ( * elfli ) = = ( * tab2j2 ) ) & & ( elem2 - > Num_elt ( ) = = fro - > PtEI ( ) - > Num_elt ( ) ) )
{ cout < < " \n erreur3 la frontière est déjà enregistrée, on ne devrait pas avoir à la supprimer ?? " < < flush ;
}
}
}
cout < < " \n avant (2) suppression frontière elem2 " ;
// on passe en revue la liste des frontières enregistrées, et on vérifie que toutes les frontières correspondent à des frontières d'éléments toujours licites
{ LaLIST < Front > : : iterator iF , iFfin = listFrontiere . end ( ) ;
for ( iF = listFrontiere . begin ( ) ; iF ! = iFfin ; iF + + )
{ Front * fro = & ( * iF ) ;
Element * elem = fro - > PtEI ( ) ;
if ( elem - > Frontieres_Actuelles ( ) ( elem - > Num_global_frontiere ( fro - > Num_frontiere ( ) , fro - > Eleme ( ) - > Type_geom_front ( ) ) ) = = NULL )
{ cout < < " \n *** erreur de cohérence liste<=>éléments finis, la frontière " ; fro - > Affiche ( 1 ) ;
cout < < " n'existe plus dans l'élément finis " < < flush ;
Sortie ( 1 ) ;
}
}
}
//---- fin debug */
// if (elem2->SupprimeFront(tab2j2))
// {nb_cas_courant++;
/* //------- debug
{ int nb_front_enreg = 0 ;
for ( int i1 = 1 ; i1 < = tabelTaille ; i1 + + )
{ const Tableau < ElFrontiere * > & tab1 = tab_element ( i1 ) - > Frontieres_Actuelles ( ) ;
int tab1Taille = tab1 . Taille ( ) ;
for ( int i = 1 ; i < = tab1Taille ; i + + )
if ( tab1 ( i ) ! = NULL )
nb_front_enreg + + ;
}
cout < < " \n suppression frontière elem2 (cas_courant): actuellement dans les elements -> " < < nb_front_enreg < < " frontières, dans la liste -> " < < listFrontiere . size ( ) < < flush ;
// on passe en revue la liste des frontières enregistrées, et on vérifie que toutes les frontières correspondent à des frontières d'éléments toujours licites
{ LaLIST < Front > : : iterator iF , iFfin = listFrontiere . end ( ) ;
for ( iF = listFrontiere . begin ( ) ; iF ! = iFfin ; iF + + )
{ Front * fro = & ( * iF ) ;
Element * elem = fro - > PtEI ( ) ;
if ( elem - > Frontieres_Actuelles ( ) ( elem - > Num_global_frontiere ( fro - > Num_frontiere ( ) , fro - > Eleme ( ) - > Type_geom_front ( ) ) ) = = NULL )
{ cout < < " \n *** erreur de cohérence liste<=>éléments finis, la frontière " ; fro - > Affiche ( 1 ) ;
cout < < " n'existe plus dans l'élément finis " < < flush ;
Sortie ( 1 ) ;
}
}
}
}
//---- fin debug */
// }
// };
// };
2021-09-18 09:47:14 +02:00
} ;
2025-01-22 18:18:03 +01:00
// delete p; // suppression de l'element p transitoire
2021-09-18 09:47:14 +02:00
}
2025-01-22 18:18:03 +01:00
// si il y a eu suppression de l'élément frontière on sort de la boucle sur j2
2021-09-18 09:47:14 +02:00
if ( res_ina ) break ; // on sort de la boucle si pas élément de frontière
} ;
2023-05-03 17:23:49 +02:00
// si l'on a détecté une égalité on arête également cette boucle
2021-09-18 09:47:14 +02:00
// après avoir supprimé l'élément frontière
// non, car on pourrait avoir une frontière qui soit commune à plus de 2 éléments
// pour l'instant ce n'est pas le cas, mais par exemple des arrêtes pour les volumes ??
// if (res)
// { elem1->SupprimeFront(elfr);
// elfr=NULL;
// break;
// }
} ;
} ;
// en sortie on sauvegarde uniquement si c'est un élément frontière
if ( ! res )
2025-01-22 18:18:03 +01:00
{ // on doit ajouter,
2021-09-18 09:47:14 +02:00
int num_dans_le_type = elem1 - > Num_de_frontiere_dans_le_type ( j1 ) ;
2025-01-22 18:18:03 +01:00
/* //------- debug
// on vérifie que la frontière existe toujours dans l'élément
if ( tab1 ( j1 ) = = NULL )
{ cout < < " \n erreur: on devrait toujours avoir la frontière non détruite ??? " < < flush ;
}
//--fin debug */
2021-09-18 09:47:14 +02:00
listFrontiere . push_back ( Front ( * elfr , elem1 , num_dans_le_type ) ) ;
2025-01-22 18:18:03 +01:00
# ifdef MISE_AU_POINT
if ( ParaGlob : : NiveauImpression ( ) > 6 )
{ cout < < " \n ajout frontiere " < < num_dans_le_type < < " (dans le type) c-a-d de num global " < < j1 < < " \n " ;
LaLIST < Front > : : iterator iFfin = listFrontiere . end ( ) ;
iFfin - - ;
( * iFfin ) . Affiche ( 1 ) ;
} ;
# endif
/* //------- debug
{ cout < < " \n ajout d'une frontière d'elem1 dans la liste " ;
int nb_front_enreg = 0 ;
for ( int i1 = 1 ; i1 < = tabelTaille ; i1 + + )
{ const Tableau < ElFrontiere * > & tab1 = tab_element ( i1 ) - > Frontieres_Actuelles ( ) ;
int tab1Taille = tab1 . Taille ( ) ;
for ( int i = 1 ; i < = tab1Taille ; i + + )
if ( tab1 ( i ) ! = NULL )
nb_front_enreg + + ;
}
cout < < " \n actuellement: dans les elements -> " < < nb_front_enreg < < " frontières, dans la liste -> " < < listFrontiere . size ( ) < < flush ;
// on passe en revue la liste des frontières enregistrées, et on vérifie que toutes les frontières correspondent à des frontières d'éléments toujours licites
{ LaLIST < Front > : : iterator iF , iFfin = listFrontiere . end ( ) ;
for ( iF = listFrontiere . begin ( ) ; iF ! = iFfin ; iF + + )
{ Front * fro = & ( * iF ) ;
Element * elem = fro - > PtEI ( ) ;
if ( elem - > Frontieres_Actuelles ( ) ( elem - > Num_global_frontiere ( fro - > Num_frontiere ( ) , fro - > Eleme ( ) - > Type_geom_front ( ) ) ) = = NULL )
{ cout < < " \n *** erreur de cohérence liste<=>éléments finis, la frontière " ; fro - > Affiche ( 1 ) ;
cout < < " n'existe plus dans l'élément finis " < < flush ;
Sortie ( 1 ) ;
}
}
}
}
//---- fin debug */
2021-09-18 09:47:14 +02:00
}
else // sinon la frontière est commune avec au moins une autre, on l'a supprime
2025-01-22 18:18:03 +01:00
{
/* //------- debug
// on passe en revue la liste des frontières enregistrées, normalement on ne devrait pas supprimer une frontière déjà enregistrée
{ LaLIST < Front > : : iterator iF , iFfin = listFrontiere . end ( ) ;
for ( iF = listFrontiere . begin ( ) ; iF ! = iFfin ; iF + + )
{ Front * fro = & ( * iF ) ;
ElFrontiere * elfli = fro - > Eleme ( ) ;
if ( ( ( * elfli ) = = ( * elfr ) ) & & ( elem1 - > Num_elt ( ) = = fro - > PtEI ( ) - > Num_elt ( ) ) )
{ cout < < " \n erreur4 la frontière est déjà enregistrée, on ne devrait pas avoir à la supprimer ?? " < < flush ;
}
}
}
//---- fin debug */
if ( elem1 - > SupprimeFront ( elfr ) )
{ nb_cas_courant + + ;
/* //------- debug
{ int nb_front_enreg = 0 ;
for ( int i1 = 1 ; i1 < = tabelTaille ; i1 + + )
{ const Tableau < ElFrontiere * > & tab1 = tab_element ( i1 ) - > Frontieres_Actuelles ( ) ;
int tab1Taille = tab1 . Taille ( ) ;
for ( int i = 1 ; i < = tab1Taille ; i + + )
if ( tab1 ( i ) ! = NULL )
nb_front_enreg + + ;
}
cout < < " \n suppression frontière d'elem1 (cas_courant): actuellement dans les elements -> " < < nb_front_enreg < < " frontières, dans la liste -> " < < listFrontiere . size ( ) < < flush ;
// on passe en revue la liste des frontières enregistrées, et on vérifie que toutes les frontières correspondent à des frontières d'éléments toujours licites
{ LaLIST < Front > : : iterator iF , iFfin = listFrontiere . end ( ) ;
for ( iF = listFrontiere . begin ( ) ; iF ! = iFfin ; iF + + )
{ Front * fro = & ( * iF ) ;
Element * elem = fro - > PtEI ( ) ;
if ( elem - > Frontieres_Actuelles ( ) ( elem - > Num_global_frontiere ( fro - > Num_frontiere ( ) , fro - > Eleme ( ) - > Type_geom_front ( ) ) ) = = NULL )
{ cout < < " \n *** erreur de cohérence liste<=>éléments finis, la frontière " ; fro - > Affiche ( 1 ) ;
cout < < " n'existe plus dans l'élément finis " < < flush ;
Sortie ( 1 ) ;
}
}
}
}
//---- fin debug */
} ;
} ;
/* //-- debug
cout < < " \n element1 " < < elem1 - > Num_elt ( ) < < " fin du cas de la frontière " < < j1 < < " type " < < Nom_type_geom ( typ1_frontiere ) < < endl ;
//--fin debug */
2021-09-18 09:47:14 +02:00
} ; // fin du test if (elfr != NULL)
} ; // fin de la boucle sur les frontières de elem1
} // fin de la boucle externe des éléments
2025-01-22 18:18:03 +01:00
2021-09-18 09:47:14 +02:00
/* // cas du dernier élément, ses éléments frontières non nuls sont forcément bons
non finalement , cela semble poser des pb sur le dernier é lément vu que l ' on a mis une procédure d ' accélération
pour le calcul des frontières donc on met en stand by pour l ' instant , si pas de pb qui apparaissent on supprime
{ Element * elem1 = tab_element ( tabelTaille ) ; // recup de l'element
const Tableau < ElFrontiere * > & tab1 = elem1 - > Frontiere ( ) ; // et des éléments
int tab1Taille = tab1 . Taille ( ) ; // frontières
for ( int j1 = 1 ; j1 < = tab1Taille ; + + j1 )
// on essaie de voir si l'élément j1 est recevable
{ ElFrontiere * elfr = tab1 ( j1 ) ; // pour simplifier
if ( elfr ! = NULL )
{ //lili.Eleme() =elfr; lili.numMail = idmail; lili.ptEl = elem1;
listFrontiere . push_back ( Front ( elfr , elem1 ) ) ;
}
}
}
*/
2024-11-25 10:36:00 +01:00
//Sortie(1);
2025-01-22 18:18:03 +01:00
////------- debug
//cout << "\n debug ** Maillage::CreeElemFront() ";
//cout << " nb frontière avant sort = " << listFrontiere.size() << endl;
////---- fin debug
2024-11-25 10:36:00 +01:00
// on classe les front de manière ensuite à faire des recherches rapide et supprime les doublons
listFrontiere . sort ( ) ;
// normalement arrivée ici les frontières sont uniques, mais en non rapide on vérifie
# ifdef MISE_AU_POINT
{ int nb_front_initial = listFrontiere . size ( ) ;
listFrontiere . unique ( egal_font ) ;
if ( nb_front_initial ! = listFrontiere . size ( ) )
{ cout < < " \n *** sans doute un pb: la liste de frontiere initialement cree avait pour taille "
< < nb_front_initial < < " front , apres passage dans listFrontiere.unique(egal_font) sa nouvelle "
< < " taille est " < < listFrontiere . size ( ) < < " !!! "
< < " \n Maillage::CreeElemFront() " < < endl ;
} ;
2025-01-22 18:18:03 +01:00
// vérif de cohérence entre les frontières enregistrées dans les éléments et celles stockées dans la liste
int nb_front_enreg = 0 ;
for ( int i1 = 1 ; i1 < = tabelTaille ; i1 + + )
{ const Tableau < ElFrontiere * > & tab1 = tab_element ( i1 ) - > Frontieres_Actuelles ( ) ;
int tab1Taille = tab1 . Taille ( ) ;
for ( int i = 1 ; i < = tab1Taille ; i + + )
if ( tab1 ( i ) ! = NULL )
nb_front_enreg + + ;
}
if ( nb_front_enreg ! = listFrontiere . size ( ) )
{ cout < < " \n *** erreur on a dans les elements -> " < < nb_front_enreg < < " frontieres, et dans la liste -> " < < listFrontiere . size ( )
< < " on devrait avoir le meme nombre !! "
< < " \n Maillage::CreeElemFront() " < < flush ;
Sortie ( 1 ) ;
}
if ( ParaGlob : : NiveauImpression ( ) > 4 )
{ cout < < " \n creation d'elements frontieres: " ;
if ( nb_cas_I ) cout < < " \n suppression d'au moins " < < nb_cas_I < < " frontieres qui font double emploi " ;
if ( nb_cas_II ) cout < < " \n suppression de " < < nb_cas_II < < " frontieres 2D d'éléments finis 3D, et on garde une frontiere 2D d'un element 2D equivalent " ;
if ( nb_cas_courant ) cout < < " \n suppression de " < < nb_cas_courant < < " frontieres internes (donc en double) " ;
cout < < " \n il reste " < < nb_front_initial < < " frontieres finales pour " < < tabelTaille < < " elements finis c-a-d "
< < nb_init_frontiere < < " frontieres internes initiales " ;
} ;
2024-11-25 10:36:00 +01:00
}
# endif
2021-09-18 09:47:14 +02:00
// effacement du contenu du tableau indice
indice . Libere ( ) ;
//// ---- debug -----
// vérification que l'on a bien les frontières bien connectées
// cout << " \n debug: Maillage::CreeElemFront()";
//{ LaLIST <Front>::iterator iF;
// LaLIST <Front>::iterator iFfin = listFrontiere.end();
// cout << "\n liste des frontières: \n ";
// for (iF = listFrontiere.begin();iF!=iFfin; iF++)
// { Front* elfront = &(*iF);
// Enum_type_geom type_front; // va être modifier par Num_frontiere
// cout << " frontière: " << elfront->Num_frontiere() << " " << elfront->Eleme()->Type_geom_front()
// << " de l'element " << elfront->PtEI()->Num_elt() << " du maillage "
// << elfront->PtEI()->Num_maillage() << " \n ";
// };
//};
// // vérif particulière (a commenter !)
//{ LaLIST <Front>::iterator iF;
// LaLIST <Front>::iterator iFfin = listFrontiere.end();
// int nbf = 1;
// for (iF = listFrontiere.begin();iF!=iFfin; iF++)
// { Front* fro = &(*iF);
// ElFrontiere * efem1 = fro->Eleme(); // recup de l'element géométrique qui a créé la frontière
// // récup de son tableau de noeud
// Tableau<Noeud *>& tabn = efem1->TabNoeud();
// int tabntaille = tabn.Taille();
// if (fro->PtEI()->Id_geometrie() == HEXAEDRE)
// {cout << "nbf= " << nbf << ", ele= " << fro->PtEI()->Num_elt() << " : ";
// for (int ij=1;ij<= tabntaille;ij++)
// // on balaie ses noeuds
// cout << tabn(ij)->Num_noeud() << " ";
// cout << endl ;
// nbf++;
// };
// };
//
//}
//
//// ---- fin debug -----
2024-03-24 11:43:58 +01:00
// definition des elements frontières mitoyens aux elements de frontiere
2021-09-18 09:47:14 +02:00
MitoyenFront ( ) ;
2025-01-22 18:18:03 +01:00
# ifdef MISE_AU_POINT
{ // on vérifie que tous les éléments frontières ont au moins un voisin, sinon c'est pas courant d'avoir un seul élément
// donc on met un warning
LaLIST < Front > : : iterator iF , iFfin = listFrontiere . end ( ) ;
for ( iF = listFrontiere . begin ( ) ; iF ! = iFfin ; iF + + )
{ Front * fro = & ( * iF ) ;
const Tableau < Front * > * tabmitoyen = fro - > TabMitoyen ( ) ;
if ( tabmitoyen = = NULL )
{ cout < < " \n *** warning: " ;
fro - > Affiche ( 1 ) ;
cout < < " pas d'element mitoyen " ;
if ( ParaGlob : : NiveauImpression ( ) > 5 )
cout < < " \n Maillage::CreeElemFront() " < < endl ;
} ;
} ;
}
# endif
2021-09-18 09:47:14 +02:00
// ==== définition du tableau des noeuds frontières =====
// 1) on définit un tableau de numéro de noeuds qui sont utilisés
Tableau < int > t_noe ( tab_noeud_taille , 0 ) ; // tous les éléments sont nul
// 2) on balaie les éléments frontières
LaLIST < Front > : : iterator li , li_end = listFrontiere . end ( ) ;
for ( li = listFrontiere . begin ( ) ; li ! = li_end ; li + + )
{ Tableau < Noeud * > & tt = ( * li ) . Eleme ( ) - > TabNoeud ( ) ;
int tt_taille = tt . Taille ( ) ;
for ( int i = 1 ; i < = tt_taille ; i + + )
( t_noe ( tt ( i ) - > Num_noeud ( ) ) ) + + ;
} ;
// 3) on récupère le nombre de noeud frontière
int nb_n_f = 0 ;
for ( int ii = 1 ; ii < = tab_noeud_taille ; ii + + )
if ( t_noe ( ii ) ! = 0 ) nb_n_f + + ;
// 4) def du tableau final
tab_noeud_front . Change_taille ( nb_n_f ) ;
nb_n_f = 0 ; // on se ressert du numéro
for ( int ii = 1 ; ii < = tab_noeud_taille ; ii + + )
{ if ( t_noe ( ii ) ! = 0 ) { nb_n_f + + ; tab_noeud_front ( nb_n_f ) = tab_noeud ( ii ) ; } ; } ;
// dans le cas où les éléments frontières sont des lignes, on les ordonnes
// de manière à former une ligne continue
// OrdonancementDesLigne();
} ;
2023-05-03 17:23:49 +02:00
// création forcée en 3D de toutes les frontières lignes (non traités par CreeElemFront())
// qui appartiennent à la frontière globales, ceci uniquement pour les éléments volumiques
// - Ces frontières ne sont pas intégrées dans la liste de frontière minimale
// - une même ligne peut appartenir à plusieurs éléments finis, elle n'est donc pas ici
// définit de manière unique (contrairement aux frontières minimales)
void Maillage : : CreeListFrontiere_ligne_3D ( )
{ // on n'intervient qu'en 3D
if ( ( ParaGlob : : Dimension ( ) = = 3 ) & & ! ( ParaGlob : : AxiSymetrie ( ) ) )
{ // au cas où ... si la liste des frontières est vide on crée les frontières
if ( listFrontiere . size ( ) = = 0 )
CreeElemFront ( ) ;
// maintenant on efface la liste existante de front segment au cas où
listFrontiere_ligne_3D . erase ( listFrontiere_ligne_3D . begin ( ) , listFrontiere_ligne_3D . end ( ) ) ;
// on crée les éléments frontière segment pour chaque élément de la frontière minimale
LaLIST < Front > : : iterator il , ilfin = listFrontiere . end ( ) ;
for ( il = listFrontiere . begin ( ) ; il ! = ilfin ; il + + )
{ // on vérifie que c'est un élément volumique
Enum_type_geom enutygeom = Type_geom_generique ( ( * il ) . PtEI ( ) - > Id_geometrie ( ) ) ;
if ( enutygeom = = VOLUME )
{ // on construit et on récupère les frontières segments,
// récup de l'élément géométrique
ElemGeomC0 & el = ( * il ) . PtEI ( ) - > ElementGeometrique ( ) ;
int tail_ar = el . NbSe ( ) ; // nombre potentiel d'arêtes
for ( int ifront = 1 ; ifront < = tail_ar ; ifront + + )
{ ElFrontiere * const elfr = ( * il ) . PtEI ( ) - > Frontiere_lineique ( ifront , true ) ;
// ajout après création, de la frontière front
// dans front il y a une création d'un ElFrontiere qui est == à *elfr
// mais c'est un élément frontière autonome (indépendant de celui de l'élément)
listFrontiere_ligne_3D . push_back ( Front ( * elfr , ( * il ) . PtEI ( ) , ifront ) ) ;
} ;
} ;
} ;
2024-08-29 09:31:24 +02:00
// on classe et supprime les doublons
listFrontiere_ligne_3D . sort ( ) ;
listFrontiere_ligne_3D . unique ( egal_font ) ;
2023-05-03 17:23:49 +02:00
} ;
} ;
2021-09-18 09:47:14 +02:00
// change le nom et le numéro du maillage
void Maillage : : ChangeNomNumeroMaillage ( const string & nom , int num )
{ // on vérifie que le nom de maillage fourni n'existe pas
if ( listeNomMail . find ( nom ) ! = listeNomMail . end ( ) )
{ cout < < " \n erreur, le nom de maillage demande existe deja : " < < nom
< < " \n Maillage::ChangeNomNumeroMaillage(..... " ;
Sortie ( 1 ) ;
} ;
// on met à jour listeNomMail en supprimant le doublet nom <=> numéro existant
listeNomMail . erase ( listeNomMail . find ( nomDuMaillage ) ) ;
nomDuMaillage = nom ; // on enregistre le nouveau nom
// on vérifie que le numéro de maillage proposé est valide
if ( num < = 0 )
{ cout < < " \n Erreur : numero de maillage invalide ! = " < < num < < " \n " ;
cout < < " Maillage::ChangeNomNumeroMaillage(.... \n " ;
Sortie ( 1 ) ;
} ;
idmail = num ; // on enregistre le nouveau numéro
// maintenant on peut associer le nom au numéro dans la map
listeNomMail [ nomDuMaillage ] = idmail ;
} ;
// ramène le numéro du noeud le plus proche du point donné à t=0
int Maillage : : Noeud_le_plus_proche_0 ( const Coordonnee & M )
{ // tout d'abord si le maillage n'a pas de noeud on ramène 0
int tail_mail = tab_noeud . Taille ( ) ;
if ( tail_mail = = 0 ) return 0 ;
// sinon initialisation de la recherche
int num_rech = 1 ; // choix du premier noeud
// distance avec le noeud
double dist = ( tab_noeud ( 1 ) - > Coord0 ( ) - M ) . Norme ( ) ;
// on boucle sur les noeuds
for ( int i = 2 ; i < = tail_mail ; i + + )
{ double dista = ( tab_noeud ( i ) - > Coord0 ( ) - M ) . Norme ( ) ;
if ( dista < = dist )
{ dist = dista ; num_rech = i ; } ;
} ;
// retour
return num_rech ;
} ;
// ramène le numéro du noeud le plus proche du point donné à t=t
int Maillage : : Noeud_le_plus_proche_t ( const Coordonnee & M )
{ // tout d'abord si le maillage n'a pas de noeud on ramène 0
int tail_mail = tab_noeud . Taille ( ) ;
if ( tail_mail = = 0 ) return 0 ;
// sinon initialisation de la recherche
int num_rech = 1 ; // choix du premier noeud
// distance avec le noeud
double dist = ( tab_noeud ( 1 ) - > Coord1 ( ) - M ) . Norme ( ) ;
// on boucle sur les noeuds
for ( int i = 2 ; i < = tail_mail ; i + + )
{ double dista = ( tab_noeud ( i ) - > Coord1 ( ) - M ) . Norme ( ) ;
if ( dista < = dist )
{ dist = dista ; num_rech = i ; } ;
} ;
// retour
return num_rech ;
} ;
// ramène le numéro du noeud le plus proche du point donné à t=tdt
int Maillage : : Noeud_le_plus_proche_tdt ( const Coordonnee & M )
{ // tout d'abord si le maillage n'a pas de noeud on ramène 0
int tail_mail = tab_noeud . Taille ( ) ;
if ( tail_mail = = 0 ) return 0 ;
// sinon initialisation de la recherche
int num_rech = 1 ; // choix du premier noeud
// distance avec le noeud
double dist = ( tab_noeud ( 1 ) - > Coord2 ( ) - M ) . Norme ( ) ;
// on boucle sur les noeuds
for ( int i = 2 ; i < = tail_mail ; i + + )
{ double dista = ( tab_noeud ( i ) - > Coord2 ( ) - M ) . Norme ( ) ;
if ( dista < = dist )
{ dist = dista ; num_rech = i ; } ;
} ;
// retour
return num_rech ;
} ;
// 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
Maillage : : NBelemEtptInteg Maillage : : Element_le_plus_proche
( Enum_dure enu_temps , const List_io < Ddl_enum_etendu > & list_enu
, const Coordonnee & M )
{ Maillage : : NBelemEtptInteg ret ;
// tout d'abord si le maillage n'a pas d'élément on ramène 0
int tail_mail = tab_element . Taille ( ) ; ret . nbElem = 0 ; ret . nbPtInteg = 0 ;
if ( tail_mail = = 0 ) { return ret ; }
// sinon initialisation de la recherche
// on boucle sur les éléments pour trouver celui qui contiend M
// M peut également être sur la surface de l'élément ce qui est ok également
for ( int i = 1 ; i < = tail_mail ; i + + )
{ bool trouve = false ;
switch ( enu_temps )
{ case TEMPS_0 : if ( tab_element ( i ) - > Interne_0 ( M ) ) trouve = true ; break ;
case TEMPS_t : if ( tab_element ( i ) - > Interne_t ( M ) ) trouve = true ; break ;
case TEMPS_tdt : if ( tab_element ( i ) - > Interne_tdt ( M ) ) trouve = true ; break ;
} ;
if ( trouve )
{ // on a trouvé un élément on recherche le point le plus près ou est exprimé la grandeur
ret . nbElem = i ;
List_io < Ddl_enum_etendu > : : const_iterator ii , iide = list_enu . begin ( ) ;
List_io < Ddl_enum_etendu > : : const_iterator iifin = list_enu . end ( ) ;
ret . nbPtInteg = tab_element ( i ) - > PointLePlusPres ( enu_temps , ( * iide ) . Enum ( ) , M ) ;
// on vérifie que tous les ddl sont disponibles au pt d'integ
for ( ii = iide ; ii ! = iifin ; ii + + )
if ( ! ( tab_element ( i ) - > Existe_pt_integ ( ret . nbPtInteg , ( * ii ) . Enum ( ) ) ) )
{ ret . nbPtInteg = - 1 ; return ret ; }
// retour normal
return ret ;
/* ancienne vérif, pas bonne
// on vérifie que tous les ddl sont de la même famille sinon erreur
for ( ii = iide ; ii ! = iifin ; ii + + )
if ( ! Meme_famille ( ( * ii ) . Enum ( ) , ( * iide ) . Enum ( ) ) )
{ ret . nbPtInteg = - 1 ; return ret ; }
// retour normal
return ret ;
*/
} ;
} ;
// retour dans le cas où l'on n'a pas trouvé d'élément
ret . nbElem = 0 ;
ret . nbPtInteg = 0 ;
return ret ;
} ;
// 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 * Maillage : : Centre_de_Gravite_Element_le_plus_proche ( Enum_dure enu_temps , const Coordonnee & M )
{ Element * el_retour = NULL ;
double distance = ConstMath : : tresgrand ;
int nbelem = tab_element . Taille ( ) ;
Coordonnee G ( ParaGlob : : Dimension ( ) ) ;
// on balaie les éléments
for ( int ine = 1 ; ine < = nbelem ; ine + + )
{ // on commence par calculer le centre de gravité
G . Zero ( ) ;
Tableau < Noeud * > taN = tab_element ( ine ) - > Tab_noeud ( ) ;
int nbn = taN . Taille ( ) ;
switch ( enu_temps )
{ case TEMPS_0 :
for ( int inn = 1 ; inn < = nbn ; inn + + )
{ Noeud * noe = taN ( inn ) ;
G + = noe - > Coord0 ( ) ;
} ;
break ;
case TEMPS_t :
for ( int inn = 1 ; inn < = nbn ; inn + + )
{ Noeud * noe = taN ( inn ) ;
G + = noe - > Coord1 ( ) ;
} ;
break ;
case TEMPS_tdt :
for ( int inn = 1 ; inn < = nbn ; inn + + )
{ Noeud * noe = taN ( inn ) ;
G + = noe - > Coord2 ( ) ;
} ;
break ;
} ;
G / = nbn ;
double new_distance = ( M - G ) . Norme ( ) ;
if ( new_distance < distance )
{ el_retour = tab_element ( ine ) ;
distance = new_distance ;
} ;
} ;
// retour de l'élément
return el_retour ;
} ;
// ramène le maximum de variation de coordonnée entre t et tdt de tous les noeuds du maillage
double Maillage : : Max_var_dep_t_a_tdt ( ) const
{ int nbn = tab_noeud . Taille ( ) ; double ret = 0. ;
for ( int i = 1 ; i < = nbn ; i + + ) ret = MaX ( tab_noeud ( i ) - > Max_var_coor_t_a_tdt ( ) , ret ) ;
return ret ;
} ;
// ramène le minimum de la distance entre deux noeuds de l'ensemble des éléments
double Maillage : : Min_dist2Noeud_des_elements ( Enum_dure temps ) const
{ double retour = ConstMath : : tresgrand ; // init
// on balaie les éléments
int taille_elem = tab_element . Taille ( ) ;
for ( int i = 1 ; i < = taille_elem ; i + + )
{ const Tableau < Noeud * > & tab_N_el = tab_element ( i ) - > Tab_noeud ( ) ;
int nbn_loc = tab_N_el . Taille ( ) ;
switch ( temps )
{ case TEMPS_0 :
{ for ( int in = 1 ; in < = nbn_loc ; in + + )
{ const Coordonnee & Ci = tab_N_el ( in ) - > Coord0 ( ) ;
for ( int jn = in + 1 ; jn < = nbn_loc ; jn + + )
{ const Coordonnee & Cj = tab_N_el ( jn ) - > Coord0 ( ) ;
retour = MiN ( retour , ( Ci - Cj ) . Max_val_abs ( ) ) ;
} ;
} ;
break ;
}
case TEMPS_t :
{ for ( int in = 1 ; in < = nbn_loc ; in + + )
{ const Coordonnee & Ci = tab_N_el ( in ) - > Coord1 ( ) ;
for ( int jn = in + 1 ; jn < = nbn_loc ; jn + + )
{ const Coordonnee & Cj = tab_N_el ( jn ) - > Coord1 ( ) ;
retour = MiN ( retour , ( Ci - Cj ) . Max_val_abs ( ) ) ;
} ;
} ;
break ;
}
case TEMPS_tdt :
{ for ( int in = 1 ; in < = nbn_loc ; in + + )
{ const Coordonnee & Ci = tab_N_el ( in ) - > Coord2 ( ) ;
for ( int jn = in + 1 ; jn < = nbn_loc ; jn + + )
{ const Coordonnee & Cj = tab_N_el ( jn ) - > Coord2 ( ) ;
retour = MiN ( retour , ( Ci - Cj ) . Max_val_abs ( ) ) ;
} ;
} ;
break ;
}
default :
cout < < " \n Erreur : valeur incorrecte du type Enum_dure ! \n " ;
cout < < " Maillage::Min_dist2Noeud_des_elements(... \n " ;
Sortie ( 1 ) ;
} ;
} ;
return retour ;
} ;
//----- lecture écriture de base info -----
// lecture base info
// = 1 : on récupère tout
// = 2 : on récupère uniquement les données variables (supposées comme telles)
2024-06-20 15:42:40 +02:00
void Maillage : : Lecture_base_info ( istream & entr , int cas )
2024-08-29 09:31:24 +02:00
{
# ifdef UTILISATION_MPI
int proc_en_cours = ParaGlob : : Monde ( ) - > rank ( ) ;
// === première partie commune à tous les proc
// normalement tous les buffers ont été rempli, on se contente de rediriger les flux
# endif
int nbElement = tab_element . Taille ( ) ;
int dime ; string toto ; int idmail_n ; string nomDuMaillage_n ;
bool mono_proc_on_lit_un_BI_multiProc = false ;
Element * pte ;
switch ( cas )
{ case 1 : // ------- on récupère tout -------------------------
{
# ifdef UTILISATION_MPI
{ // on crée le flux sur le premier buffer:
istrstream * entrons = new istrstream ( buffer_ioBI_MPI ( 1 ) . c_str ( ) , buffer_ioBI_MPI ( 1 ) . size ( ) ) ;
istream & entr = * entrons ; // on redéfinit entr
# endif
entr > > toto ; // entête
// dans le cas où on lit un fichier créé avec MPI io, et que l'on n'est pas
// en MPI, on passe les offsets et tailles
# ifndef UTILISATION_MPI
if ( toto = = " buf0_Maillages " )
{ for ( int i = 0 ; i < 3 ; i + + ) //
{ toto . clear ( ) ;
std : : getline ( entr , toto ) ;
2021-09-18 09:47:14 +02:00
} ;
2024-08-29 09:31:24 +02:00
mono_proc_on_lit_un_BI_multiProc = true ;
} ;
# endif
if ( mono_proc_on_lit_un_BI_multiProc ) // cas de la lecture en mono
{ entr > > toto > > idmail_n > > nomDuMaillage_n > > toto > > dime ; } // d'un fichier créé en multi proc
else // cas d'une lecture en mono d'un fichier mono
// ou cas d'une lecture multi d'un fichier créé en multi proc
{ entr > > idmail_n > > nomDuMaillage_n > > toto > > dime ; } ; // on a déjà lue toto
// // l'id et le nom du maillage et la dimension
// entr >> toto >> idmail_n >> nomDuMaillage_n >> toto >> dime ;
// les types de problèmes associés
// { types_de_problemes.clear(); int nb=0; // init
// entr >> toto >> nb ; string type;
// for (int i=1;i<=nb;i++)
// {entr >> type;types_de_problemes.push_back(Id_nom_ElemTypeProblem(type));};
// };
{ int nb = 0 ; // init
entr > > toto > > nb ; string type ;
types_de_problemes . Change_taille ( nb ) ;
for ( int i = 1 ; i < = nb ; i + + )
{ entr > > type ; types_de_problemes ( i ) = ( Id_nom_ElemTypeProblem ( type ) ) ; } ;
} ;
// les ddl associés
// { ddl_representatifs_des_physiques.clear(); int nb=0; // init
// entr >> toto >> nb ; string ddl;
// for (int i=1;i<=nb;i++)
// {entr >> ddl;ddl_representatifs_des_physiques.push_back(Id_nom_ddl(ddl));};
// };
{ int nb = 0 ; // init
entr > > toto > > nb ; string type ;
ddl_representatifs_des_physiques . Change_taille ( nb ) ;
for ( int i = 1 ; i < = nb ; i + + )
{ entr > > type ; ddl_representatifs_des_physiques ( i ) = ( Id_nom_ddl ( type ) ) ; } ;
} ;
// si le nom de maillage lu est différent de celui existant,
// on supprime le doublet dans la map de gestion et on met à jour
if ( nomDuMaillage ! = nomDuMaillage_n )
{ listeNomMail . erase ( listeNomMail . find ( nomDuMaillage ) ) ;
nomDuMaillage = nomDuMaillage_n ;
listeNomMail [ nomDuMaillage ] = idmail_n ;
idmail = idmail_n ;
}
else
{ // sinon on vérifie quand même que le numéro n'a pas changé
if ( idmail ! = idmail_n )
{ listeNomMail [ nomDuMaillage ] = idmail_n ;
idmail = idmail_n ;
} ;
} ;
if ( dime ! = dimension )
cout < < " \n Erreur : valeur de la dimension non coherente avec "
< < " l'espace de travail! \n "
< < " Maillage::Lecture_base_info(istream& sort,int cas) "
2023-05-03 17:23:49 +02:00
< < endl ;
2024-08-29 09:31:24 +02:00
cout < < " === lecture du maillage " < < nomDuMaillage < < " nb " < < idmail < < " \n " ;
//------------- lecture des noeuds -------------
cout < < " lecture des noeuds " ;
// le nombre de noeud
int nbNoeud = tab_noeud . Taille ( ) ;
entr > > nbNoeud > > toto ;
// normalement ici on ne doit pas avoir déjà de noeud
Change_nb_noeud ( nbNoeud ) ; // dimensionnement dynamique du tableau de noeud
// lecture des noeuds
Noeud * ptr ;
for ( int i = 1 ; i < = nbNoeud ; i + + )
{ ptr = new Noeud ( i , dimension , idmail ) ; // et attribution du numero de maillage
ptr - > Lecture_base_info ( entr , cas ) ;
Affectation_noeud ( * ptr ) ;
} ;
// ------------ les elements finis -----------
cout < < " , lecture des elements \n " ;
entr > > toto ;
// lecture du nombre d'element
int nbElement ;
entr > > toto > > nbElement ;
// dimensionnement dynamique du tableau d'elements
Change_nb_element ( nbElement ) ;
# ifdef UTILISATION_MPI
} ; // fin lecture premier buffer
# endif
// Lecture des elements
# ifndef UTILISATION_MPI
// cas d'un calcul uni-CPU
for ( int i = 1 ; i < = nbElement ; i + + )
# else
// cas d'un calcul //
if ( proc_en_cours ! = 0 ) // seules les proc i gèrent les éléments
{ // on récupère la distribution d'éléments concernant le cpu en cours
const list < int > list_elem_cpu = ParaGlob : : param - > const_List_element_CPU_en_cours ( idmail ) ;
// le nombre d'élément spécifiquement pour le CPU
// int nbElement_cpu = list_elem_cpu.size();
// int inter; // le nombre stocké sur le .BI
// entr >> toto >> inter;
// // on vérifie que c'est le bon
// if (inter != nbElement_cpu)
// { cout << "\nErreur : le nombre d'element a lire: " << nbElement_cpu
// << " est different de celui stocke sur le .BI: " << inter
// << "\n cas d'un calcul parallele avec lecture initiale du .BI, cpu nb:"
// << ParaGlob::Monde()->rank() << " !! "
// << "\n Maillage::Lecture_base_info(istream& sort,int cas)"
// << endl;
// Sortie (1);
// };
// lecture des éléments
// on balaie les éléments nécessaires
list < int > : : const_iterator il , ilfin = list_elem_cpu . end ( ) ;
for ( il = list_elem_cpu . begin ( ) ; il ! = ilfin ; il + + )
{ int i = ( * il ) ;
// pour chaque élément il y a un buffer particulier, d'où un flux particulier
istrstream * entrons = new istrstream ( buffer_ioBI_MPI ( 1 + i ) . c_str ( ) , les_taille_buffer_ioBI_MPI [ i - 1 ] ) ;
istream & entr = * entrons ; // redéfinition
# endif
{ // lecture geometrie et interpolation
Enum_geom id_geom ; Enum_interpol id_interpol ;
EnumElemTypeProblem id_typeProb ; string str_precision ;
int num_elt ; // donnee dont on ne se sert pas
entr > > toto > > num_elt > > id_geom > > id_interpol > > id_typeProb ;
// on regarde le prochain caractère sans changer le flot
/////int cr=entr.peek();
//--- début du remplacement du peek
char car = Picococar ( entr ) ; // = flot.peek();
// on recupère l'entier correspondant au caractère
int cr = int ( car ) ;
//--- fin du remplacement du peek
// on regarde s'il y a une chaine discriminante
if ( cr = = int ( ' _ ' ) ) entr > > str_precision ;
// ======== choix de l'element =====================================
// et affectation du pointeur d'element en fonction de id_geom et id_interpol
// le numero d'element : num_elt, est affecte a l'element pointe par ptr
pte = Element : : Choix_element ( idmail , num_elt , id_geom , id_interpol , id_typeProb , str_precision ) ;
if ( pte = = NULL )
{ // l'operation a echouee
cout < < " \n Erreur dans le choix d'element ****** " ;
cout < < " \n l \' element : " < < Nom_interpol ( id_interpol )
< < " " < < Nom_geom ( id_geom )
< < " n \' est pas present dans le programme ! "
< < " \n Maillage::Lecture_base_info(... " < < endl ;
Sortie ( 1 ) ;
} ;
// lecture des infos particulieres a l'element
Tableau < Noeud * > * pt = & tab_noeud ;
pte - > Lecture_base_info ( entr , pt , cas ) ;
Affectation_element ( * pte ) ;
// si c'est le premier élément du premier maillage on regarde s'il s'agit
// d'un élément axisymétrique et on adapte l'espace de travail en conséquence
if ( ( i = = 1 ) & & ( idmail = = 1 ) )
{ if ( TestEnum_geom_axisymetrique ( id_geom ) )
ParaGlob : : Change_en_AxiSymetrie ( ) ;
}
else
{ // dans le cas des autres éléments on vérifie qu'ils ne sont pas incohérent
if ( TestEnum_geom_axisymetrique ( id_geom ) ! = ( ParaGlob : : AxiSymetrie ( ) ) )
{ cout < < " \n **** erreur en definition de l'element " < < num_elt < < " du maillage " < < idmail
< < " nom= " < < nomDuMaillage ;
if ( ParaGlob : : AxiSymetrie ( ) )
cout < < " \n incoherence : l'espace de travail n'est pas axisymetrique (definit par les precedents elements) "
< < " et l'element lu est axisymetrique !! " ;
else
cout < < " \n incoherence : l'espace de travail est axisymetrique (definit par les precedents elements) "
< < " et l'element lu n'est pas axisymetrique !! " ;
cout < < endl ;
Sortie ( 1 ) ;
} ;
} ;
}
# ifdef UTILISATION_MPI
} ;
} ; // fin cas d'un calcul //
{ // on crée le flux sur le dernier buffer:
istrstream * entrons = new istrstream ( buffer_ioBI_MPI ( 2 + nbElement ) . c_str ( ) , buffer_ioBI_MPI ( 2 + nbElement ) . size ( ) ) ;
istream & entr = * entrons ; // redéfinition
# endif
entr > > toto ; // lecture de "---fin_maillage---"
# ifdef MISE_AU_POINT
if ( toto ! = " ---fin_maillage--- " )
{ cout < < " \n Erreur : on a lue: " < < toto < < " , alors que l'on attendait ---fin_maillage--- ! \n " ;
cout < < " Maillage::Lecture_base_info(istream& sort,int cas) "
< < " cas= " < < cas < < endl ;
Sortie ( 1 ) ;
} ;
# endif
# ifdef UTILISATION_MPI
} ; // fin dernier buffer
# endif
2023-05-03 17:23:49 +02:00
2024-08-29 09:31:24 +02:00
// ------------ les elements frontières -----------
// il sont créé par ailleurs si il y en a besoin
break ;
}
case 2 : // ----------- lecture uniquement de se qui varie --------------------
{ // le nom du maillage pour vérification
// cout << "\n debug **** Maillage::Lecture_base_info\n"
// << "\n entr.rdstate() " << entr.rdstate() << flush;
//entr.clear();
# ifdef UTILISATION_MPI
{ // on crée le flux sur le premier buffer:
istrstream * entrons = new istrstream ( buffer_ioBI_MPI ( 1 ) . c_str ( ) , buffer_ioBI_MPI ( 1 ) . size ( ) ) ;
istream & entr = * entrons ; // redéfinition
# endif
string inter , nomDuMail ;
// entr >> inter >> nomDuMail ;
entr > > inter ; // entête
// dans le cas où on lit un fichier créé avec MPI io, et que l'on n'est pas
// en MPI, on passe les offsets et tailles
# ifndef UTILISATION_MPI
if ( inter = = " buf0_Maillages " )
{ for ( int i = 0 ; i < 3 ; i + + ) //
{ inter . clear ( ) ;
std : : getline ( entr , inter ) ;
} ;
mono_proc_on_lit_un_BI_multiProc = true ;
} ;
# endif
if ( mono_proc_on_lit_un_BI_multiProc ) // cas de la lecture en mono
{ entr > > inter > > nomDuMail ; } // d'un fichier créé en multi proc
else // cas d'une lecture en mono d'un fichier mono
// ou cas d'une lecture multi d'un fichier créé en multi proc
{ entr > > nomDuMail ; } ; // on a déjà lue toto
if ( nomDuMail ! = nomDuMaillage )
{ cout < < " \n Erreur : le nom du maillage lu ( " < < nomDuMail < < " ) n'est pas identique avec celui en cours ( "
< < nomDuMaillage < < " ) !! "
< < " \n Maillage::Lecture_base_info(istream& sort,int cas) "
< < endl ;
Sortie ( 1 ) ;
} ;
//------------- les noeuds -------------
// le tableau doit être déjà dimensionné
int nbNoeud = tab_noeud . Taille ( ) ;
for ( int i = 1 ; i < = nbNoeud ; i + + )
tab_noeud ( i ) - > Lecture_base_info ( entr , cas ) ;
# ifdef UTILISATION_MPI
} ; // fin lecture premier buffer
# endif
// ------------ les elements finis -----------
Tableau < Noeud * > * pt = & tab_noeud ;
int nb ; string toto ;
# ifndef UTILISATION_MPI
// cas d'un calcul uni-CPU
for ( int j = 1 ; j < = nbElement ; j + + )
# else
// cas d'un calcul //
if ( proc_en_cours ! = 0 ) // seules les proc i gèrent les éléments
{ // on récupère la distribution d'éléments concernant le cpu en cours
const list < int > list_elem_cpu = ParaGlob : : param - > const_List_element_CPU_en_cours ( idmail ) ;
// le nombre d'élément spécifiquement pour le CPU
int nbElement_cpu = list_elem_cpu . size ( ) ;
// int intera; // le nombre stocké sur le .BI
// entr >> toto >> intera;
// // on vérifie que c'est le bon
// if (intera != nbElement_cpu)
// { cout << "\nErreur : le nombre d'element a lire: " << nbElement_cpu
// << " est different de celui stocke sur le .BI: " << inter
// << "\n cas d'un calcul parallele avec lecture courante du .BI, cpu nb:"
// << ParaGlob::Monde()->rank() << " !! "
// << "\n Maillage::Lecture_base_info(istream& sort,int cas)"
// << endl;
// Sortie (1);
// };
// lecture des éléments
// on balaie les éléments nécessaires
list < int > : : const_iterator il , ilfin = list_elem_cpu . end ( ) ;
for ( il = list_elem_cpu . begin ( ) ; il ! = ilfin ; il + + )
{ int j = ( * il ) ;
// pour chaque élément il y a un buffer particulier, d'où un flux particulier
istrstream * entrons = new istrstream ( buffer_ioBI_MPI ( 1 + j ) . c_str ( ) , les_taille_buffer_ioBI_MPI [ j - 1 ] ) ;
istream & entr = * entrons ;
# endif
{ entr > > toto > > nb ; // le numéro de l'élément
tab_element ( j ) - > Lecture_base_info ( entr , pt , cas ) ;
} ;
# ifdef UTILISATION_MPI
// fin cas d'un calcul //
} ;
} ; // fin cas d'un calcul //
{ // on crée le flux sur le dernier buffer:
istrstream * entrons = new istrstream ( buffer_ioBI_MPI ( 2 + nbElement ) . c_str ( ) , buffer_ioBI_MPI ( 2 + nbElement ) . size ( ) ) ;
istream & entr = * entrons ; // redéfinition
# endif
entr > > toto ; // lecture de "---fin_maillage---"
# ifdef MISE_AU_POINT
if ( toto ! = " ---fin_maillage--- " )
{ cout < < " \n Erreur : on a lue: " < < toto < < " , alors que l'on attendait ---fin_maillage--- ! \n " ;
cout < < " Maillage::Lecture_base_info(istream& sort,int cas) "
< < " cas= " < < cas < < endl ;
Sortie ( 1 ) ;
} ;
# endif
# ifdef UTILISATION_MPI
} ; // fin dernier buffer
# endif
// ------------ les elements frontières -----------
// il sont créé par ailleurs si il y en a besoin
break ;
}
default :
{ cout < < " \n Erreur : valeur incorrecte du type de lecture ! \n " ;
cout < < " Maillage::Lecture_base_info(istream& sort,int cas) "
< < " cas= " < < cas < < endl ;
Sortie ( 1 ) ;
} ;
} ;
2021-09-18 09:47:14 +02:00
} ;
// écriture base info
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
2024-06-20 15:42:40 +02:00
void Maillage : : Ecriture_base_info ( ostream & sort , int cas )
{
2024-08-29 09:31:24 +02:00
// le nombre d'élément total
int nbElement = tab_element . Taille ( ) ;
2024-06-20 15:42:40 +02:00
# ifdef UTILISATION_MPI
int proc_en_cours = ParaGlob : : Monde ( ) - > rank ( ) ;
// 1) dans le cas d'un proc 0 ou i, on redéfinit le flux de sortie, pour bufferiser les infos en sortie
// qui sont ensuite sortie via MPI i-o à l'aide de la méthode Ecriture_base_info_MPI_IO
// les récupérations et les sorties sont effectuées de manière asynchrone par rapport aux autres proc
// 2) seul le proc 0 sort l'entête et les noeuds
// 3) seules les proc i sortent les éléments
2024-08-29 09:31:24 +02:00
// dimensionnement, si les tailles sont inchangées, aucune action
les_taille_buffer_ioBI_MPI . resize ( nbElement ) ;
les_taille_buffer_ioBI_MPI . assign ( nbElement , 0 ) ; // init
int taille_buffer_ioBI_MPI = nbElement + 2 ; // cf. le .h
buffer_ioBI_MPI . Change_taille ( taille_buffer_ioBI_MPI ) ; // si c'est la bonne taille aucune action
2024-06-20 15:42:40 +02:00
# endif
switch ( cas )
2021-09-18 09:47:14 +02:00
{ case 1 : // ------- on sauvegarde tout -------------------------
2024-06-20 15:42:40 +02:00
{
# ifdef UTILISATION_MPI
if ( proc_en_cours = = 0 ) // première partie dédié proc 0
2024-08-29 09:31:24 +02:00
{ std : : ostringstream sort ; // redéfinition de sort
2024-06-20 15:42:40 +02:00
# endif
// l'id et le nom du maillage et la dimension
sort < < " \n num= " < < idmail < < " " < < nomDuMaillage < < " "
< < " dim= " < < dimension ;
2024-08-29 09:31:24 +02:00
// les types de problèmes associés
2024-06-20 15:42:40 +02:00
{ int tail = types_de_problemes . Taille ( ) ;
sort < < " \n types_de_problemes: " < < tail ;
for ( int i = 1 ; i < = tail ; i + + )
sort < < " " < < NomElemTypeProblem ( types_de_problemes ( i ) ) ;
} ;
2021-09-18 09:47:14 +02:00
2024-08-29 09:31:24 +02:00
// les ddl associés
2024-06-20 15:42:40 +02:00
{ int tail = ddl_representatifs_des_physiques . Taille ( ) ;
sort < < " \n type_de_ddl_associes: " < < tail ;
for ( int i = 1 ; i < = tail ; i + + )
sort < < " " < < Nom_ddl ( ddl_representatifs_des_physiques ( i ) ) ;
} ;
sort < < " \n " ;
//------------- les noeuds -------------
// le nombre de noeud
int nbNoeud = tab_noeud . Taille ( ) ;
sort < < nbNoeud < < " noeuds \n " ;
// sorti des noeuds
for ( int i = 1 ; i < = nbNoeud ; i + + )
tab_noeud ( i ) - > Ecriture_base_info ( sort , cas ) ;
// ------------ les elements finis -----------
sort < < " \n --les_elements-- " ;
sort < < " \n nombre_total_element " < < nbElement ;
# ifdef UTILISATION_MPI
sort < < " \n " ;
2024-08-29 09:31:24 +02:00
buffer_ioBI_MPI ( 1 ) = sort . str ( ) ; // on sauvegarde
2024-06-20 15:42:40 +02:00
}
# endif
2021-09-18 09:47:14 +02:00
// écriture des éléments
2024-06-20 15:42:40 +02:00
# ifndef UTILISATION_MPI
2023-05-03 17:23:49 +02:00
// cas d'un calcul uni-CPU
2021-09-18 09:47:14 +02:00
for ( int j = 1 ; j < = nbElement ; j + + )
2024-08-29 09:31:24 +02:00
{
2024-06-20 15:42:40 +02:00
# else
if ( proc_en_cours ! = 0 ) // seules les proc i gèrent les éléments
2024-08-29 09:31:24 +02:00
{ // on récupère la distribution d'éléments concernant le cpu en cours
const list < int > list_elem_cpu = ParaGlob : : param - > const_List_element_CPU_en_cours ( idmail ) ;
// écriture des éléments
// on balaie les éléments nécessaires
list < int > : : const_iterator il , ilfin = list_elem_cpu . end ( ) ;
for ( il = list_elem_cpu . begin ( ) ; il ! = ilfin ; il + + )
{ int j = ( * il ) ;
std : : stringstream sort ; // redéfinition de sort
# endif
{ // tout d'abord les données de différentiation
// numéro geometrie et interpolation
sort < < " \n \n element: " < < tab_element ( j ) - > Num_elt ( ) < < " "
< < tab_element ( j ) - > Id_geometrie ( ) < < " "
< < tab_element ( j ) - > Interpolation ( ) < < " "
< < tab_element ( j ) - > TypeProblem ( ) < < " "
< < tab_element ( j ) - > Infos_annexe ( ) < < " \n " ;
// puis les données de l'élément
tab_element ( j ) - > Ecriture_base_info ( sort , cas ) ;
} ;
# ifdef UTILISATION_MPI
buffer_ioBI_MPI ( j + 1 ) = sort . str ( ) ; // on sauvegarde
//les_taille_buffer_ioBI_MPI[0] -> donne la première partie donc [i] donne l'élément i
les_taille_buffer_ioBI_MPI [ j - 1 ] = buffer_ioBI_MPI ( j + 1 ) . size ( ) ;
} ;
2024-06-20 15:42:40 +02:00
}
2024-08-29 09:31:24 +02:00
else // cas du proc 0
{ // sortie du retour à la ligne
std : : stringstream sort ; // redéfinition de sort
sort < < " \n ---fin_maillage--- \n " ;
buffer_ioBI_MPI ( 2 + nbElement ) = sort . str ( ) ; // on sauvegarde
} ;
2024-06-20 15:42:40 +02:00
# endif
# ifndef UTILISATION_MPI
2024-08-29 09:31:24 +02:00
} ;
sort < < " \n ---fin_maillage--- \n " ;
// sort << "\n ";
2024-06-20 15:42:40 +02:00
# endif
2021-09-18 09:47:14 +02:00
// ------------ les elements frontières -----------
// ne sont pas sauvegardé car reconstruit à la demande
break ;
2024-06-20 15:42:40 +02:00
}
2021-09-18 09:47:14 +02:00
case 2 : // ----------- sauvegarde uniquement de se qui varie --------------------
2024-06-20 15:42:40 +02:00
{
# ifdef UTILISATION_MPI
if ( proc_en_cours = = 0 ) // première partie dédié proc 0
2024-08-29 09:31:24 +02:00
{ std : : ostringstream sort ; // redéfinition de sort
2024-06-20 15:42:40 +02:00
# endif
// le nom du maillage pour vérification en lecture
sort < < " \n nomDuMail= " < < nomDuMaillage < < " \n " ;
//------------- les noeuds -------------
int nbNoeud = tab_noeud . Taille ( ) ;
// sorti des noeuds
for ( int i = 1 ; i < = nbNoeud ; i + + )
tab_noeud ( i ) - > Ecriture_base_info ( sort , cas ) ;
# ifdef UTILISATION_MPI
sort < < " \n " ;
2024-08-29 09:31:24 +02:00
buffer_ioBI_MPI ( 1 ) = sort . str ( ) ; // on sauvegarde
2024-06-20 15:42:40 +02:00
} ;
# endif
2021-09-18 09:47:14 +02:00
// ------------ les elements finis -----------
int nbElement = tab_element . Taille ( ) ;
2024-06-20 15:42:40 +02:00
# ifndef UTILISATION_MPI
// cas d'un calcul uni-CPU
2021-09-18 09:47:14 +02:00
for ( int j = 1 ; j < = nbElement ; j + + )
2024-06-20 15:42:40 +02:00
# else
if ( proc_en_cours ! = 0 ) // seules les proc i gèrent les éléments
{ // on récupère la distribution d'éléments concernant le cpu en cours
const list < int > list_elem_cpu = ParaGlob : : param - > const_List_element_CPU_en_cours ( idmail ) ;
// écriture des éléments
// on balaie les éléments nécessaires
list < int > : : const_iterator il , ilfin = list_elem_cpu . end ( ) ;
2024-08-29 09:31:24 +02:00
int indice_buffer_ioBI_MPI = 2 ;
for ( il = list_elem_cpu . begin ( ) ; il ! = ilfin ; il + + , indice_buffer_ioBI_MPI + + )
2024-06-20 15:42:40 +02:00
{ int j = ( * il ) ;
2024-08-29 09:31:24 +02:00
std : : stringstream sort ; // redéfinition de sort pour chaque élément
2024-06-20 15:42:40 +02:00
# endif
{ sort < < " \n \n element_nb: " < < tab_element ( j ) - > Num_elt ( ) < < " " ;
tab_element ( j ) - > Ecriture_base_info ( sort , cas ) ;
} ;
# ifdef UTILISATION_MPI
2024-08-29 09:31:24 +02:00
buffer_ioBI_MPI ( j + 1 ) = sort . str ( ) ; // sauvegarde particulière pour l'élément
les_taille_buffer_ioBI_MPI [ j - 1 ] = buffer_ioBI_MPI ( j + 1 ) . size ( ) ;
} ; // fin boucle éléments
}
else // cas du proc 0
{ // sortie du retour à la ligne
std : : stringstream sort ; // redéfinition de sort
sort < < " \n ---fin_maillage--- \n " ;
buffer_ioBI_MPI ( 2 + nbElement ) = sort . str ( ) ; // on sauvegarde
} ;
2024-06-20 15:42:40 +02:00
# endif
2023-05-03 17:23:49 +02:00
2024-06-20 15:42:40 +02:00
# ifndef UTILISATION_MPI
2024-08-29 09:31:24 +02:00
sort < < " \n ---fin_maillage--- \n " ;
// sort << "\n ";
2024-06-20 15:42:40 +02:00
# endif
// ------------ les elements frontières -----------
// ne sont pas sauvegardé car reconstruit à la demande
2021-09-18 09:47:14 +02:00
break ;
2024-06-20 15:42:40 +02:00
}
2021-09-18 09:47:14 +02:00
default :
{ cout < < " \n Erreur : valeur incorrecte du type de sauvegarde ! \n " ;
2024-06-20 15:42:40 +02:00
cout < < " Maillage::Ecriture_base_info(ostream& sort,int cas) "
2021-09-18 09:47:14 +02:00
< < " cas= " < < cas < < endl ;
Sortie ( 1 ) ;
} ;
} ;
2024-08-29 09:31:24 +02:00
# ifdef UTILISATION_MPI
// on transmet à proc 0 les tailles de buffer (concerne uniquement les éléments),
// il faut de toute manière que proc 0 centralise toutes les tailles
// avant de pouvoir calculer les offsets qu'il transmet ensuite à proc i, il faut faire une transmission avec accusé de réception
if ( proc_en_cours ! = 0 )
{ mpi : : request reqs2 = ParaGlob : : Monde ( ) - > isend ( 0 , 9867 , les_taille_buffer_ioBI_MPI ) ;
reqs2 . wait ( ) ;
}
else // récup des buffers par le proc 0
{ int nb_proc_terminer = 0 ; // permettra de terminer
les_taille_buffer_ioBI_MPI_inter . resize ( nbElement ) ;
// on initialise les_taille_buffer_ioBI_MPI
les_taille_buffer_ioBI_MPI . assign ( nbElement , 0 ) ;
while ( nb_proc_terminer < ( ParaGlob : : Monde ( ) - > size ( ) - 1 ) ) // gérer par les valeurs de tyfront
{ // on récupère un résultat de cpu i
mpi : : request reqs2 = ParaGlob : : Monde ( ) - > irecv ( mpi : : any_source , 9867 , les_taille_buffer_ioBI_MPI_inter ) ;
reqs2 . wait ( ) ; // on attend que le conteneur soit rempli
// mpi::status stat = reqs2.wait(); // on attend que le conteneur soit rempli
// int source = stat.source(); // récupération du numéro de la source
// // on récupère la distribution d'éléments concernant le cpu en cours
// const list <int > list_elem_cpu = ParaGlob::param->const_List_element_CPU_en_cours(idmail);
// // écriture des éléments
// // on balaie les éléments nécessaires
// list <int >::const_iterator il,ilfin=list_elem_cpu.end();
// int indice_buffer_ioBI_MPI=2;
// for (il = list_elem_cpu.begin();il != ilfin;il++,indice_buffer_ioBI_MPI++)
// {int j = (*il);
// les_taille_buffer_ioBI_MPI[j-1] = les_taille_buffer_ioBI_MPI_inter[j-1];
// };
//
nb_proc_terminer + + ; // on prend en compte que l'on a récupéré un conteneur
// on met à jour
for ( int i = 0 ; i < nbElement ; i + + )
les_taille_buffer_ioBI_MPI [ i ] + = les_taille_buffer_ioBI_MPI_inter [ i ] ;
} ;
} ;
// on synchronise les proc pour éviter qu'un proc travaille sur un maillage différent d'un autre
// au niveau du passage d'info
ParaGlob : : Monde ( ) - > barrier ( ) ; // synchronisation ici de tous les process
# endif
2021-09-18 09:47:14 +02:00
} ;
2024-06-20 15:42:40 +02:00
# ifdef UTILISATION_MPI
2024-08-29 09:31:24 +02:00
// retour de la taille globale des sorties retardées gérées par par LesMaillages
// concernant les sorties sur .BI
// seul le retour de proc 0 est licite
2024-12-15 15:18:59 +01:00
MPI_Offset Maillage : : Taille_buffer_sortie_BI ( )
{ MPI_Offset taille = 0 ; // init
2024-08-29 09:31:24 +02:00
int proc_en_cours = ParaGlob : : Monde ( ) - > rank ( ) ;
int nb_element = tab_element . Taille ( ) ;
if ( proc_en_cours = = 0 )
2024-12-15 15:18:59 +01:00
{ MPI_Offset taille_entete = 38 + ( nb_element + 3 ) * 21 + 27 ; // cf. Maillage::Ecriture_base_info_MPI_IO
2024-08-29 09:31:24 +02:00
taille + = buffer_ioBI_MPI ( 1 ) . size ( ) + taille_entete ;
taille + = buffer_ioBI_MPI ( 2 + nb_element ) . size ( ) ;
}
else // cas des proc i != 0
{ for ( int i = 1 ; i < = nb_element ; i + + )
taille + = buffer_ioBI_MPI ( i + 1 ) . size ( ) ;
} ;
// il faut sommer sur tous les proc
2024-12-15 15:18:59 +01:00
MPI_Offset taille_totale = 0 ; // init
2024-08-29 09:31:24 +02:00
// la somme s'effectue vers le proc 0
2024-12-15 15:18:59 +01:00
reduce ( * ParaGlob : : Monde ( ) , taille , taille_totale , std : : plus < MPI_Offset > ( ) , 0 ) ;
2024-08-29 09:31:24 +02:00
// if (proc_en_cours == 0)
// { cout << "\n Maillage::Taille_buffer_sortie_BI() taille_totale = "<<taille_totale << endl;
// };
// retour
return taille_totale ; // seul le retour de proc 0 est licite
} ;
// récupération de l'offset global sur .BI pour la classe
// et mise à jour des offsets de classes dérivées si besoin
2024-12-15 15:18:59 +01:00
void Maillage : : Mise_a_jour_Offset_BI_ecriture ( MPI_Offset offset , const int cas )
2024-08-29 09:31:24 +02:00
{
int proc_en_cours = ParaGlob : : Monde ( ) - > rank ( ) ;
int nb_element = tab_element . Taille ( ) ;
offset_maillage . resize ( 3 + nb_element ) ; // d'où de [0] à [2+nb_element]
if ( proc_en_cours = = 0 )
{ // on commence par prendre en compte l'offset général
offset_maillage [ 0 ] = offset ;
// puis on intègre la taille de l'ensemble des offsets:
2024-12-15 15:18:59 +01:00
MPI_Offset taille_entete = 38 + ( nb_element + 3 ) * 21 + 27 ; // cf. Maillage::Ecriture_base_info_MPI_IO
2024-08-29 09:31:24 +02:00
offset_maillage [ 1 ] = offset + taille_entete + buffer_ioBI_MPI ( 1 ) . size ( ) ; // position pour le premier élément
// on calcule l'offset spécifique pour chaque élément
// NB: les_taille_buffer_ioBI_MPI_inter de chaque proc, ont été transmises des proc i vers
// proc 0 à la fin de la méthode: Ecriture_base_info
2024-12-15 15:18:59 +01:00
MPI_Offset offset_courant = offset_maillage [ 1 ] ; // init
2024-08-29 09:31:24 +02:00
for ( int ne = 1 ; ne < = nb_element ; ne + + )
{ // les_taille_buffer_ioBI_MPI[k-1] -> donne la taille du buffer pour l'élément k
offset_courant + = les_taille_buffer_ioBI_MPI [ ne - 1 ] ; // taille du buffer de ne
offset_maillage [ ne + 1 ] = offset_courant ; // position pour l'élément ne+1 sauf pour le dernier
// on a pour le dernier offset_maillage[nb_element+1] correspond au début du second buffer
// propre
} ;
// puis les 2 dernier offsets qui servent en fait que pour le proc 0
// offset_maillage[nb_element+1] viens d'être calculé
// buffer_ioBI_MPI(k+1) : élément k (k== numéro d'ordre de l'élément dans le tableau tab_element)
offset_maillage [ nb_element + 2 ] = offset_maillage [ nb_element + 1 ] + buffer_ioBI_MPI ( 2 + nb_element ) . size ( ) ;
// offset_maillage[nb_element+2] correspond à la fin
} ;
// le proc 0 transmet les tailles et les offsets des éléments à tous les proc
broadcast ( * ParaGlob : : Monde ( ) , les_taille_buffer_ioBI_MPI , 0 ) ; // peut-être pas nécessaire ??
broadcast ( * ParaGlob : : Monde ( ) , offset_maillage , 0 ) ;
} ;
// idem en lecture, mais là il s'agit uniquement de la mise à jour
// de l'offset seul puis c'est la classe qui s'en débrouille
2024-12-15 15:18:59 +01:00
void Maillage : : Mise_a_jour_Offset_BI_lecture ( MPI_Offset offset , const int cas )
{ MPI_Offset taille_offset = tab_element . Taille ( ) + 3 ;
2024-08-29 09:31:24 +02:00
offset_maillage . resize ( taille_offset ) ;
offset_maillage [ 0 ] = offset ;
} ;
// Lecture des offsets MPI des infos bufferisées
void Maillage : : Lecture_offset_base_info_MPI_IO
( //MPI_Offset offset_gene,
MPI_File * ent_MPI , const int cas )
{
int proc_en_cours = ParaGlob : : Monde ( ) - > rank ( ) ;
// tous les proc lisent
int nb_element = tab_element . Taille ( ) ;
// // on initialise tous les offsets
// int ierr = MPI_File_seek_shared(*ent_MPI,offset_gene,MPI_SEEK_SET);
// 1) ==== la taille de l'ensemble des offsets
2024-12-15 15:18:59 +01:00
MPI_Offset taille_buf = 0 ; // init
2024-08-29 09:31:24 +02:00
// on encapsule pour ré-utiliser la même trame
{ char * buffer_car = new char [ 38 ] ; // def du tableau de travail
MPI_Status status ;
int ierr = MPI_File_read_all ( * ent_MPI , buffer_car , 38 , MPI_CHAR , & status ) ;
if ( ierr )
{ cout < < " \n *** erreur d'acces a MPI_File_read_all: code " < < ierr < < " , stop Herezh "
< < " \n proc " < < proc_en_cours < < " , lecture de la taille de l'ensemble des offsets "
< < " \n Maillage::Lecture_base_info_MPI_IO(... " < < endl ;
Sortie ( 1 ) ;
} ;
// on crée un flux sur le tableau de caractères:
istrstream * ent_inter = new istrstream ( buffer_car , 38 ) ;
// lecture de l'entête
string toto ;
( * ent_inter ) > > toto ;
if ( toto ! = " buf0_Maillages " )
{ cout < < " \n **** erreur on devait lire : 'buf0_Maillages' "
< < " et on lue " < < toto < < " la suite n'est pas possible -> arret !! "
< < " \n Maillage::Lecture_offset_base_info_MPI_IO(... " < < endl ;
Sortie ( 1 ) ;
} ;
// on lit la taille de buf2
( * ent_inter ) > > taille_buf ;
} ;
// 2) ==== lecture des offsets
{ char * buffer_car = new char [ taille_buf ] ; // def du tableau de travail
MPI_Status status ;
int ierr = MPI_File_read_all ( * ent_MPI , buffer_car , taille_buf , MPI_CHAR , & status ) ;
if ( ierr )
{ cout < < " \n *** erreur d'acces a MPI_File_read_all: code " < < ierr < < " , stop Herezh "
< < " \n proc " < < proc_en_cours < < " , lecture des offsets "
< < " \n Maillage::Lecture_base_info_MPI_IO(... " < < endl ;
Sortie ( 1 ) ;
} ;
// on crée un flux sur le tableau de caractères:
istrstream * ent_inter = new istrstream ( buffer_car , taille_buf ) ;
// lecture de l'entête
string toto ;
( * ent_inter ) > > toto ;
if ( toto ! = " offset_base_info_MPI_IO " )
{ cout < < " \n **** erreur on devait lire : 'offset_base_info_MPI_IO' "
< < " et on lue " < < toto < < " la suite n'est pas possible -> arret !! "
< < " \n Maillage::Lecture_offset_base_info_MPI_IO(... " < < endl ;
Sortie ( 1 ) ;
} ;
// on lit les offsets
2024-12-15 15:18:59 +01:00
MPI_Offset taille_offset = nb_element + 3 ;
2024-08-29 09:31:24 +02:00
offset_maillage . resize ( taille_offset ) ;
2024-12-15 15:18:59 +01:00
for ( MPI_Offset i = 0 ; i < taille_offset ; i + + )
2024-08-29 09:31:24 +02:00
( * ent_inter ) > > offset_maillage [ i ] ;
} ;
// 3) ==== on dimensionne les_taille_buffer_ioBI_MPI
// on initialise les_taille_buffer_ioBI_MPI
les_taille_buffer_ioBI_MPI . resize ( nb_element ) ;
for ( int ne = 1 ; ne < = nb_element ; ne + + )
les_taille_buffer_ioBI_MPI [ ne - 1 ] = offset_maillage [ ne + 1 ] - offset_maillage [ ne ] ;
} ;
// lecture MPI des infos bufferisées
void Maillage : : Lecture_base_info_MPI_IO ( MPI_File * ent_MPI , const int cas )
{
int proc_en_cours = ParaGlob : : Monde ( ) - > rank ( ) ;
// on lit tout d'abord les offsets
Maillage : : Lecture_offset_base_info_MPI_IO ( ent_MPI , cas ) ;
int nb_element = tab_element . Taille ( ) ;
buffer_ioBI_MPI . Change_taille ( nb_element + 2 ) ;
// tous les proc lisent l'entête et les noeuds ce qui correspond au premier buffer de proc 0
{ //premier buffer
2024-12-15 15:18:59 +01:00
MPI_Offset taille_entete = 38 + ( nb_element + 3 ) * 21 + 27 ; // cf. Maillage::Ecriture_base_info_MPI_IO
MPI_Offset taille_buf = offset_maillage [ 1 ] - ( offset_maillage [ 0 ] + taille_entete ) ;
2024-08-29 09:31:24 +02:00
char * buffer_car = new char [ taille_buf ] ; // def du tableau de travail
MPI_Status status ;
int ierr = MPI_File_read_all ( * ent_MPI , buffer_car , taille_buf , MPI_CHAR , & status ) ;
if ( ierr )
{ cout < < " \n *** erreur d'acces a MPI_File_read_all: code " < < ierr < < " , stop Herezh "
< < " \n proc " < < proc_en_cours < < " , lecture buffer1 "
< < " \n Maillage::Lecture_base_info_MPI_IO(... " < < endl ;
Sortie ( 1 ) ;
} ;
buffer_ioBI_MPI ( 1 ) . resize ( taille_buf ) ;
buffer_ioBI_MPI ( 1 ) . replace ( 0 , taille_buf , buffer_car ) ;
// buffer_ioBI_MPI(1).copy(buffer_car,taille_buf);
} ; // fin premier buffer
// chaque proc i lit ses propres buffers
if ( proc_en_cours ! = 0 )
{ // pour chaque éléments:
// 1) on se positionne sur l'offset associé
// 2) on lit le buffer
// on récupère la distribution d'éléments concernant le cpu en cours
const list < int > list_elem_cpu = ParaGlob : : param - > const_List_element_CPU_en_cours ( idmail ) ;
// le nombre d'élément spécifiquement pour le CPU
int nbElement_cpu = list_elem_cpu . size ( ) ;
// on balaie les éléments nécessaires
list < int > : : const_iterator il , ilfin = list_elem_cpu . end ( ) ;
2024-12-15 15:18:59 +01:00
MPI_Offset indice_buffer_ioBI_MPI = 2 ;
2024-08-29 09:31:24 +02:00
for ( il = list_elem_cpu . begin ( ) ; il ! = ilfin ; il + + , indice_buffer_ioBI_MPI + + )
{ int j = ( * il ) ;
2024-12-15 15:18:59 +01:00
MPI_Offset offset = offset_maillage [ j ] ; // récup de l'offset
2024-08-29 09:31:24 +02:00
int ierr = MPI_File_seek ( * ent_MPI , offset , MPI_SEEK_SET ) ; // positionnement
if ( ierr ) // traitement erreur éventuelle
{ cout < < " \n *** erreur de positionnement MPI_File_seek: code " < < ierr < < " , stop Herezh "
< < " \n proc: " < < proc_en_cours
< < " , pour l'element " < < j < < " "
< < " \n Maillage::Lecture_base_info_MPI_IO(... " < < endl ;
Sortie ( 1 ) ;
} ;
2024-12-15 15:18:59 +01:00
MPI_Offset taille_buf = les_taille_buffer_ioBI_MPI [ j - 1 ] ;
2024-08-29 09:31:24 +02:00
char * buffer_car = new char [ taille_buf ] ; // def du tableau de travail
MPI_Status status ;
ierr = MPI_File_read ( * ent_MPI , buffer_car , taille_buf , MPI_CHAR , & status ) ;
if ( ierr ) // traitement erreur éventuelle
{ cout < < " \n *** erreur de lecture MPI_File_read: code " < < ierr < < " , stop Herezh "
< < " \n proc: " < < proc_en_cours
< < " , lecture buffer de l'element " < < j < < " "
< < " \n Maillage::Lecture_base_info_MPI_IO(... " < < endl ;
Sortie ( 1 ) ;
} ;
buffer_ioBI_MPI ( 1 + j ) . resize ( taille_buf ) ;
buffer_ioBI_MPI ( 1 + j ) . replace ( 0 , taille_buf , buffer_car ) ;
// buffer_ioBI_MPI(1+j).copy(buffer_car,taille_buf);
} ;
} ;
// tous les proc lisent le dernier buffer
{ // on initialise tous les offsets au cas où
int ierr = MPI_File_seek ( * ent_MPI , offset_maillage [ nb_element + 1 ] , MPI_SEEK_SET ) ;
2024-12-15 15:18:59 +01:00
MPI_Offset taille_buf = offset_maillage [ nb_element + 2 ] - offset_maillage [ nb_element + 1 ] ;
2024-08-29 09:31:24 +02:00
char * buffer_car = new char [ taille_buf ] ; // def du tableau de travail
MPI_Status status ;
ierr = MPI_File_read_all ( * ent_MPI , buffer_car , taille_buf , MPI_CHAR , & status ) ;
if ( ierr )
{ cout < < " \n *** erreur d'acces a MPI_File_read_all: code " < < ierr < < " , stop Herezh "
< < " \n proc " < < proc_en_cours < < " , lecture "
< < " \n Maillage::Lecture_base_info_MPI_IO(... " < < endl ;
Sortie ( 1 ) ;
} ;
buffer_ioBI_MPI ( 2 + nb_element ) . resize ( taille_buf ) ;
buffer_ioBI_MPI ( 2 + nb_element ) . replace ( 0 , taille_buf , buffer_car ) ;
// buffer_ioBI_MPI(2+nb_element).copy(buffer_car,taille_buf);
} ; // fin du deuxième buffer
} ;
2024-06-20 15:42:40 +02:00
// écriture MPI des infos bufferisées
2024-08-29 09:31:24 +02:00
void Maillage : : Ecriture_base_info_MPI_IO ( MPI_File * sort_MPI , const int cas )
2024-06-20 15:42:40 +02:00
{
int proc_en_cours = ParaGlob : : Monde ( ) - > rank ( ) ;
if ( proc_en_cours = = 0 )
2024-08-29 09:31:24 +02:00
{ // === écriture dans flot string de la taille des buffers propres
// ici c'est le premier et le dernier élément des buffers
// pour avoir une sortie lisible, on crée tout d'abord un buffer string avec les infos
std : : ostringstream buf2 ( std : : ios_base : : out ) ;
buf2 < < " \n offset_base_info_MPI_IO \n " ; // 27 char
2024-12-15 15:18:59 +01:00
MPI_Offset taille_offset = offset_maillage . size ( ) ; // 3+nb_element
2024-08-29 09:31:24 +02:00
int nb_element = tab_element . Taille ( ) ;
# ifdef MISE_AU_POINT
if ( taille_offset ! = ( nb_element + 3 ) )
{ cout < < " \n *** sans doute erreur, taille_offset " < < taille_offset
< < " est different de nb_element+3 = " < < nb_element + 3
< < " \n Maillage::Ecriture_base_info_MPI_IO(... " < < endl ;
Sortie ( 1 ) ;
} ;
# endif
2024-12-15 15:18:59 +01:00
for ( MPI_Offset i = 0 ; i < taille_offset ; i + + )
2024-08-29 09:31:24 +02:00
// on sort donc (3+nb_element)*21 char
{ buf2 < < std : : right < < setw ( 20 ) < < offset_maillage [ i ] ;
buf2 < < " " ;
} ;
// le buffer du stream n'est pas pérenne il faut le récupérer
string buf_inter = buf2 . str ( ) ; // on récupère le buffer
2024-12-15 15:18:59 +01:00
MPI_Offset taille_buf = buf_inter . size ( ) ; // doit faire 27+(3+nb_element)*20 char
2024-08-29 09:31:24 +02:00
# ifdef MISE_AU_POINT
if ( taille_buf ! = ( nb_element + 3 ) * 21 + 27 )
{ cout < < " \n *** sans doute erreur, taille_buf " < < taille_buf
< < " est different de (nb_element+3)*21+27 = " < < ( nb_element + 3 ) * 21 + 27
< < " \n Maillage::Ecriture_base_info_MPI_IO(... " < < endl ;
Sortie ( 1 ) ;
} ;
# endif
2024-06-20 15:42:40 +02:00
2024-08-29 09:31:24 +02:00
// 1) ==== écriture de la taille de l'ensemble des offsets
// on encapsule pour ré-utiliser la même trame
2024-06-20 15:42:40 +02:00
{
2024-08-29 09:31:24 +02:00
std : : ostringstream bufdeb ( std : : ios_base : : out ) ;
bufdeb < < " \n buf0_Maillages " ; // 17 char
bufdeb < < std : : right < < setw ( 20 ) < < taille_buf ; // on justifie à droite et on utilise 20 char
bufdeb < < " " ; // 1 char
string buf_inter = bufdeb . str ( ) ; // normalement 38 char
// sortie sur fichier de la taille de buf2
2024-12-15 15:18:59 +01:00
MPI_Offset offset = offset_maillage [ 0 ] ; // récup de l'offset
2024-08-29 09:31:24 +02:00
int ierr = MPI_File_seek ( * sort_MPI , offset , MPI_SEEK_SET ) ; // positionnement
if ( ierr ) // traitement erreur éventuelle
{ cout < < " \n *** erreur de positionnement MPI_File_seek: code " < < ierr < < " , stop Herezh "
< < " \n proc 0, ecriture buf0_Maillages "
< < " \n Maillage::Ecriture_base_info_MPI_IO(... " < < endl ;
Sortie ( 1 ) ;
} ;
MPI_Status status ; // pour le retour
ierr = MPI_File_write ( * sort_MPI , buf_inter . c_str ( ) , 38 , MPI_CHAR , & status ) ;
if ( ierr )
{ cout < < " \n *** erreur d'acces a MPI_File_write: code " < < ierr < < " , stop Herezh "
< < " \n proc 0, ecriture entete buffer "
< < " \n Maillage::Ecriture_base_info_MPI_IO(... " < < endl ;
Sortie ( 1 ) ;
} ;
} ;
2024-06-20 15:42:40 +02:00
2024-08-29 09:31:24 +02:00
// 2) ==== écriture des offsets c-a-d sortie sur fichier de buf2
{ MPI_Status status ; // pour le retour
int ierr = MPI_File_write ( * sort_MPI , buf_inter . c_str ( ) , taille_buf , MPI_CHAR , & status ) ;
if ( ierr )
{ cout < < " \n *** erreur d'acces a MPI_File_write: code " < < ierr < < " , stop Herezh "
< < " \n proc 0, ecriture des offsets "
< < " \n Maillage::Ecriture_base_info_MPI_IO(... " < < endl ;
Sortie ( 1 ) ;
2024-06-20 15:42:40 +02:00
} ;
2024-08-29 09:31:24 +02:00
} ;
// 3) ==== écriture du premier buffer propre
{ MPI_Status status ; // pour le retour
int ierr = MPI_File_write ( * sort_MPI , buffer_ioBI_MPI ( 1 ) . c_str ( )
, buffer_ioBI_MPI ( 1 ) . size ( ) , MPI_CHAR , & status ) ;
if ( ierr )
{ cout < < " \n *** erreur d'acces a MPI_File_write: code " < < ierr < < " , stop Herezh "
< < " \n proc 0, ecriture premier buffer propre "
< < " \n Maillage::Ecriture_base_info_MPI_IO(... " < < endl ;
Sortie ( 1 ) ;
} ;
} ;
// 4) ==== écriture du dernier buffer propre
{ int nb_element = tab_element . Taille ( ) ;
2024-12-15 15:18:59 +01:00
MPI_Offset offset = offset_maillage [ nb_element + 1 ] ; // récup de l'offset
2024-08-29 09:31:24 +02:00
int ierr = MPI_File_seek ( * sort_MPI , offset , MPI_SEEK_SET ) ; // positionnement
if ( ierr ) // traitement erreur éventuelle
{ cout < < " \n *** erreur de positionnement MPI_File_seek: code " < < ierr < < " , stop Herezh "
< < " \n proc 0, ecriture dernier buffer propre "
< < " \n Maillage::Ecriture_base_info_MPI_IO(... " < < endl ;
Sortie ( 1 ) ;
} ;
MPI_Status status ; // pour le retour
ierr = MPI_File_write ( * sort_MPI , buffer_ioBI_MPI ( 2 + nb_element ) . c_str ( )
, buffer_ioBI_MPI ( 2 + nb_element ) . size ( ) , MPI_CHAR , & status ) ;
if ( ierr )
{ cout < < " \n *** erreur d'acces a MPI_File_write: code " < < ierr < < " , stop Herezh "
< < " \n proc 0, ecriture dernier buffer propre "
< < " \n Maillage::Ecriture_base_info_MPI_IO(... " < < endl ;
Sortie ( 1 ) ;
} ;
} ;
2024-06-20 15:42:40 +02:00
} ;
2024-08-29 09:31:24 +02:00
// écriture des éléments
if ( proc_en_cours ! = 0 )
{ // pour chaque éléments:
// 1) on se positionne sur l'offset associé
// 2) on écrit le buffer
// on récupère la distribution d'éléments concernant le cpu en cours
const list < int > list_elem_cpu = ParaGlob : : param - > const_List_element_CPU_en_cours ( idmail ) ;
// le nombre d'élément spécifiquement pour le CPU
int nbElement_cpu = list_elem_cpu . size ( ) ;
// écriture des éléments
// on balaie les éléments nécessaires
list < int > : : const_iterator il , ilfin = list_elem_cpu . end ( ) ;
int indice_buffer_ioBI_MPI = 2 ;
for ( il = list_elem_cpu . begin ( ) ; il ! = ilfin ; il + + , indice_buffer_ioBI_MPI + + )
{ int j = ( * il ) ;
2024-12-15 15:18:59 +01:00
MPI_Offset offset = offset_maillage [ j ] ; // récup de l'offset
2024-08-29 09:31:24 +02:00
int ierr = MPI_File_seek ( * sort_MPI , offset , MPI_SEEK_SET ) ; // positionnement
if ( ierr ) // traitement erreur éventuelle
{ cout < < " \n *** erreur de positionnement MPI_File_write: code " < < ierr < < " , stop Herezh "
< < " \n proc: " < < proc_en_cours
< < " , pour l'element " < < j < < " "
< < " \n Maillage::Ecriture_base_info_MPI_IO(... " < < endl ;
Sortie ( 1 ) ;
} ;
MPI_Status status ; // pour le retour
ierr = MPI_File_write ( * sort_MPI , buffer_ioBI_MPI ( 1 + j ) . c_str ( )
, buffer_ioBI_MPI ( 1 + j ) . size ( ) , MPI_CHAR , & status ) ;
if ( ierr ) // traitement erreur éventuelle
{ cout < < " \n *** erreur d'ecriture MPI_File_write: code " < < ierr < < " , stop Herezh "
< < " \n proc: " < < proc_en_cours
< < " , ecriture l'element " < < j < < " "
< < " \n Maillage::Ecriture_base_info_MPI_IO(... " < < endl ;
Sortie ( 1 ) ;
} ;
} ;
} ;
2024-06-20 15:42:40 +02:00
} ;
# endif
2021-09-18 09:47:14 +02:00
// ------ 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 > Maillage : : Taille_boiteMail ( )
{ // définition du tableau de retour
Tableau < Vecteur > tabret ( 2 ) ;
// cas particulier de maillage vide
int nbNoeud = tab_noeud . Taille ( ) ;
if ( nbNoeud = = 0 )
return tabret ;
// sinon le cas normal
tabret ( 1 ) . Change_taille ( dimension ) ;
tabret ( 2 ) . Change_taille ( dimension ) ;
// on balaie tous les coordonnées des noeuds pour déterminer les tailles
// maxi et mini
// dans une première étape on regarde s'il existe les coordonnées à t=0
// t et t+dt, ceci à partir du premier noeud qui sert de test
// on cherche les extrémas
for ( int i = 1 ; i < = nbNoeud ; i + + )
{ Coordonnee a0 = tab_noeud ( i ) - > Coord0 ( ) ;
for ( int k = 1 ; k < = dimension ; k + + )
{ if ( tabret ( 1 ) ( k ) > a0 ( k ) )
tabret ( 1 ) ( k ) = a0 ( k ) ;
if ( tabret ( 2 ) ( k ) < a0 ( k ) )
tabret ( 2 ) ( k ) = a0 ( k ) ;
}
// dans le cas de coordonnées à t idem
if ( tab_noeud ( i ) - > ExisteCoord1 ( ) )
{ Coordonnee aat = tab_noeud ( i ) - > Coord1 ( ) ;
for ( int k = 1 ; k < = dimension ; k + + )
{ if ( tabret ( 1 ) ( k ) > aat ( k ) )
tabret ( 1 ) ( k ) = aat ( k ) ;
if ( tabret ( 2 ) ( k ) < aat ( k ) )
tabret ( 2 ) ( k ) = aat ( k ) ;
}
} ;
// dans le cas de coordonnées à t+dt idem
if ( tab_noeud ( i ) - > ExisteCoord2 ( ) )
{ Coordonnee aatdt = tab_noeud ( i ) - > Coord2 ( ) ;
for ( int k = 1 ; k < = dimension ; k + + )
{ if ( tabret ( 1 ) ( k ) > aatdt ( k ) )
tabret ( 1 ) ( k ) = aatdt ( k ) ;
if ( tabret ( 2 ) ( k ) < aatdt ( k ) )
tabret ( 2 ) ( k ) = aatdt ( k ) ;
}
} ;
}
return tabret ;
} ;
//========================== fonction protegee =============================
2024-03-24 11:43:58 +01:00
// definition des elements frontières mitoyens aux elements de frontiere
2021-09-18 09:47:14 +02:00
// à la fin du programme tous les éléments mitoyens sont stocké dant les éléments front
// la manip est de créer des éléments frontières aux éléments frontières existant
// ensuite deux éléments sont mitoyens s'il ont la même frontière
// à la fin du programme tous les frontières des éléments frontières sont supprimé
void Maillage : : MitoyenFront ( )
{ // le tableau indice_NFr (indice des noeuds frontières) va permettre une recherche plus rapide
2023-05-03 17:23:49 +02:00
Calcul_indice_NFr ( ) ;
// // on le construit:
// int tab_noeud_taille= tab_noeud.Taille();
// Tableau <List_io <Front*> > indice_NFr(tab_noeud_taille);
// // indice_NFr contiend les front succeptible d'avoir des frontières géométriques communes
// LaLIST <Front>::iterator iF;
// LaLIST <Front>::iterator iFfin = listFrontiere.end();
// for (iF = listFrontiere.begin();iF!=iFfin; iF++)
// { Front* fro = &(*iF);
// ElFrontiere * efem1 = fro->Eleme(); // recup de l'element géométrique qui a créé la frontière
// // récup de son tableau de noeud
// Tableau<Noeud *>& tabn = efem1->TabNoeud();
// int tabntaille = tabn.Taille();
// for (int ij=1;ij<= tabntaille;ij++)
// // on balaie ses noeuds
// indice_NFr((tabn(ij)->Num_noeud())).push_back(fro);
// };
// // on supprime les doublons
// for (int i=1;i<=tab_noeud_taille;i++)
// { List_io <Front*>& intertab = indice_NFr(i); // pour allèger l'écriture
// intertab.sort(); // on ordonne
// intertab.unique(); // on supprime les doublons
// };
2021-09-18 09:47:14 +02:00
//-- debug
// cout << "\n maillage " << idmail << "\n";
// for (int ii=1;ii<= tab_noeud.Taille();ii++)
// {cout << "\n noeud " << ii << "\n";
// list<Front*>::iterator ina,infin;
// list<Front*>& intertab = indice_NFr(ii); // pour allèger l'écriture
// infin = intertab.end();
// for (ina = intertab.begin();ina!=infin;ina++)
// {Front* elem2 = (*ina); // recup de l'element
// elem2->Affiche();
// };
// };
// cout << endl;
// // Sortie(1);
//--fin debug
// on determine les elements front mitoyens a chaque element frontiere, s'ils existent
LaLIST < Front > : : iterator iE , jE , iiE ;
LaLIST < Front * > inters ; // stockage intermediaire
LaLIST < Front > : : iterator iEfin = listFrontiere . end ( ) ;
for ( iE = listFrontiere . begin ( ) ; iE ! = iEfin ; iE + + )
// pour chaque element on recherche d'autre element ayant des frontieres communes
{ // création d'élément frontières secondaires des frontières primaires
Tableau < ElFrontiere * > tabi = ( * iE ) . Eleme ( ) - > Frontiere ( ) ; // frontieres géométriques de iE
2025-01-22 18:18:03 +01:00
//// --- pour le débug
//cout << "\n on cherche un mitoyen a "; (*iE).Affiche(1);
//{cout << "\n noeuds: ";const Tableau <Noeud *> tabno = (*iE).Eleme()->TabNoeud();
// int nb = tabno.Taille();
// for (int ijk=1;ijk<=nb; ijk++)
// cout << tabno(ijk)->Num_noeud() << " ";
//}
////-----
2021-09-18 09:47:14 +02:00
int tabitaille = tabi . Taille ( ) ;
for ( int i = 1 ; i < = tabitaille ; i + + )
{ ElFrontiere * elfr = tabi ( i ) ;
2025-01-22 18:18:03 +01:00
//// --- pour le débug
//cout << " frontiere : " << i ;
////---
2021-09-18 09:47:14 +02:00
// si deux éléments frontières sont identiques alors tous leurs noeuds
// sont identiques. En particulier le premier noeud de *elfr est commum
// avec tous les éléments succeptibles de contenir un élément frontière
// identique. On va donc utiliser le vector indice_NFr qui contiend cette liste
int numnoeud = ( elfr - > TabNoeud ( ) ) ( 1 ) - > Num_noeud ( ) ;
list < Front * > : : iterator ina , infin ;
list < Front * > & intertab = indice_NFr ( numnoeud ) ; // pour allèger l'écriture
infin = intertab . end ( ) ;
2025-01-22 18:18:03 +01:00
//// pour le debug
//cout << "\n nb de candidat mitoyen (via indice_NFr) : "<< intertab.size();
////--
2021-09-18 09:47:14 +02:00
// on balaie les élément succeptibles d'avoir des frontières communes
for ( ina = intertab . begin ( ) ; ina ! = infin ; ina + + )
{ Front * elem2 = ( * ina ) ; // recup de l'element frontière
2025-01-22 18:18:03 +01:00
//// ---pour le debug
//cout << "\n on test "; elem2->Affiche(1);
//{cout << "\n noeuds: ";const Tableau <Noeud *> tabno = elem2->Eleme()->TabNoeud();
// int nb = tabno.Taille();
// for (int ijk=1;ijk<=nb; ijk++)
// cout << tabno(ijk)->Num_noeud() << " ";
//}
////--
2021-09-18 09:47:14 +02:00
// on ne fait la recherche que pour les éléments différent de *iE
if ( * elem2 ! = * iE )
{ Tableau < ElFrontiere * > tabj = elem2 - > Eleme ( ) - > Frontiere ( ) ; // frontieres de ina
int tabjtaille = tabj . Taille ( ) ;
for ( int j = 1 ; j < = tabjtaille ; j + + )
{ // ElFrontiere * tabjjOppose=(tabj(j)->Oppose()); // element transitoire
if ( ( * elfr ) = = * ( tabj ( j ) ) ) // ||
// (*(tabi(i)) == *tabjjOppose) )
// iE et ina ont une frontiere commune, sont donc mitoyen
{ //Front pj = &(*(*ina));
inters . push_back ( & ( * elem2 ) ) ;
//-- debug
//{Tableau <Noeud *>& toto = elfr->TabNoeud(); cout << "\n premiere frontiere NB: "<< i << ": ";
//for (int ii=1;ii<=toto.Taille();ii++) cout <<toto(ii)->Num_noeud() << " ";}
//{Tableau <Noeud *>& toto = (tabj(j))->TabNoeud(); cout << "\n frontiere mitoyenne NB: "<< j << ": ";
//for (int ii=1;ii<=toto.Taille();ii++) cout <<toto(ii)->Num_noeud() << " "; }
//cout << "\n ";
//if ((j1==3)&&(j2==6))
// cout << "on y est ";
//--fin debug
2025-01-22 18:18:03 +01:00
//// pour le débug
2021-09-18 09:47:14 +02:00
// cout << "\n on a trouve une frontiere commune ";
2025-01-22 18:18:03 +01:00
// elem2->Affiche(1);
2021-09-18 09:47:14 +02:00
// cout << " frontiere commune: noeuds: ";
// Tableau <Noeud *> tabno = (tabj(j))->TabNoeud();
// int nb = tabno.Taille();
2025-01-22 18:18:03 +01:00
// for (int ijk=1;ijk<=nb; ijk++)
2021-09-18 09:47:14 +02:00
// cout << tabno(ijk)->Num_noeud() << " ";
2025-01-22 18:18:03 +01:00
//// fin pour le débug
}
//// pour le debug
// else
// cout << "\n pas d'égalité ";
////--
2021-09-18 09:47:14 +02:00
// delete tabjjOppose; // suppression de l'element transitoire
} ;
} ;
} ;
} ;
// fin de la recherche concernant elfr
2023-05-03 17:23:49 +02:00
// on supprime les doublons
inters . sort ( ) ; // on ordonne
inters . unique ( ) ; // on supprime les doublons
2021-09-18 09:47:14 +02:00
// creation d'un tableau a la place de la liste
Tableau < Front * > tabb ( ( int ) inters . size ( ) ) ;
LaLIST < Front * > : : iterator ip ; int i2 ;
LaLIST < Front * > : : iterator ipfin = inters . end ( ) ;
LaLIST < Front * > : : iterator ipdebut = inters . begin ( ) ;
for ( i2 = 1 , ip = ipdebut ; ip ! = ipfin ; ip + + , i2 + + )
tabb ( i2 ) = & ( * ( * ip ) ) ;
// def des elements mitoyen
( * iE ) . DefMitoyen ( tabb ) ;
2025-01-22 18:18:03 +01:00
//// -- débug --- affichage
//cout << "\n au final on a:";
//if (tabb.Taille() > 0)
// cout << tabb.Taille() <<" frontiere mitoyenne ";
//if (inters.size() == 0)
// {cout << " nb frontière == 0 ";
2021-09-18 09:47:14 +02:00
// (*iE).Affiche();
// cout << endl;
// };
2025-01-22 18:18:03 +01:00
//// -- fin débug --- affichage
2021-09-18 09:47:14 +02:00
// on vide la liste
inters . erase ( ipdebut , ipfin ) ;
2023-05-03 17:23:49 +02:00
} ;
2021-09-18 09:47:14 +02:00
// -- débug --- affichage
// for ( iE = listFrontiere.begin(); iE !=iEfin; iE++)
// (*iE).Affiche();
// -- fin débug --- affichage
//effacement de tous les éléments frontières secondaires des éléments frontières
// primaires
LaLIST < Front > : : iterator iEE ;
for ( iEE = listFrontiere . begin ( ) ; iEE ! = iEfin ; iEE + + )
( * iEE ) . Eleme ( ) - > EffaceFrontiere ( ) ;
// -- débug --- affichage
// for ( iE = listFrontiere.begin(); iE !=iEfin; iE++)
// { Tableau <Front*>& tabi = (*iE).TabMitoyen();
// int tabitaille = tabi.Taille();
// for (int i=1;i<= tabitaille;i++)
// { Front* elfr = tabi(i);
// cout << "\n";
// elfr->Affiche();
// }
// };
//// -- fin débug --- affichage
//
} ;
// dans le cas où les éléments frontières sont des lignes, on les ordonnes
// de manière à former une ligne continue
void Maillage : : OrdonancementDesLigne ( )
{ // on définit une liste intermédiaire
LaLIST < Front > interlist ;
// on commence par le premier élément de la liste et de proche en proche on
// rempli la liste
// on passe en revue les éléments frontières
// LaLIST <Front>::iterator iEE;
// for ( iEE = listFrontiere.begin(); iEE !=iEfin; iEE++)
// (*iEE).elem->EffaceFrontiere();
} ;
// 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 Maillage : : Calcul_tous_les_front_et_leurs_mitoyens ( )
{ // on crée les éléments frontières dans chaque élément
int tabelTaille = tab_element . Taille ( ) ;
mitoyen_de_chaque_element . Change_taille ( tabelTaille ) ; // dimensionnement
// on boucle sur les elements
for ( int i2 = 1 ; i2 < = tabelTaille ; i2 + + )
{ // création des éléments frontières
Element * elem1 = tab_element ( i2 ) ;
elem1 - > Frontiere ( true ) ;
// puis on crée tous les éléments Front, qui sont alors stockés dans mitoyen_de_chaque_element(i2)
// par contre pour l'instant on n'a pas les mitoyens de calculés
const Tableau < ElFrontiere * > & tab1 = elem1 - > Frontiere ( ) ; // et de ses frontières
Tableau < Front > & tab_front = mitoyen_de_chaque_element ( i2 ) ; // pour simplifier
int tab1Taille = tab1 . Taille ( ) ; // nb de frontières
tab_front . Change_taille ( tab1Taille ) ; // dimensionne mitoyen_de_chaque_element(i2)
for ( int j = 1 ; j < = tab1Taille ; j + + )
tab_front ( j ) = Front ( * tab1 ( j ) , elem1 , j ) ;
//cout << "\n les front";
//for (int j=1;j<=tab1Taille;j++)
// tab_front(j).Affiche();
} ;
// on crée des tableaux permettant d'accélérer l'algorithme final
// pour chaque noeud on note quel élément contiend ce noeud
// "indice" contiend les numéros d'élément succeptible d'avoir des frontières communes
Calcul_indice ( ) ;
// on va boucler sur les éléments en regardant
// pour chaque frontière si il y a d'autres frontières mitoyennes c-a-d si
// il y a d'autres frontières identiques
for ( int i1 = 1 ; i1 < = tabelTaille ; i1 + + )
{ Tableau < Front > & tab_front = mitoyen_de_chaque_element ( i1 ) ; // pour simplifier
int tab1Taille = tab_front . Taille ( ) ; // nb de frontières (qui sont déjà stockées)
for ( int j1 = 1 ; j1 < = tab1Taille ; j1 + + ) // on boucle sur les frontière de l'élément principale (nb=i1)
// on essaie de voir si l'élément j1 est recevable
{ const ElFrontiere * elfr = tab_front ( j1 ) . Eleme_const ( ) ; // récup de la frontière
// si deux éléments frontières sont identiques alors tous leurs noeuds
// sont identiques. En particulier le premier noeud de *elfr est commum
// avec tous les éléments succeptibles de contenir un élément frontière
// identique. On va donc utiliser la liste indice qui contiend cette liste
int numnoeud = ( elfr - > TabNoeud_const ( ) ) ( 1 ) - > Num_noeud ( ) ;
list < Element * > : : iterator ina , infin ;
list < Element * > & intertab = indice ( numnoeud ) ; // pour allèger l'écriture
infin = intertab . end ( ) ;
LaLIST < Front * > inters ; // stockage intermediaire
// on balaie les élément succeptibles d'avoir des frontières communes
for ( ina = intertab . begin ( ) ; ina ! = infin ; ina + + )
{ Element * elem2 = * ina ; // recup de l'element
// on ne fait la recherche que pour les éléments différents de elem1
int num_elem2 = elem2 - > Num_elt ( ) ;
if ( num_elem2 ! = i1 )
{ // récup des éléments front correspondant à elem2
Tableau < Front > & tab_fro = mitoyen_de_chaque_element ( num_elem2 ) ;
int tab_fro_taille = tab_fro . Taille ( ) ;
for ( int j2 = 1 ; j2 < = tab_fro_taille ; j2 + + )
{ // on compare
if ( ( * tab_fro ( j2 ) . Eleme_const ( ) ) = = ( * elfr ) )
{ // on récupère le Front de l'élément elem2, pour la frontière j2
Front * front_j2 = & tab_fro ( j2 ) ;
inters . push_back ( front_j2 ) ;
//--debug
//tab_front(j1).Affiche();
//front_j2->Affiche();
//--fin_debug
} ;
} ;
} ;
} ;
// on supprime les doublons
inters . sort ( ) ; // on ordonne
inters . unique ( ) ; // on supprime les doublons
// creation d'un tableau a la place de la liste
Tableau < Front * > tabb ( ( int ) inters . size ( ) ) ;
LaLIST < Front * > : : iterator ip ; int i2 ;
LaLIST < Front * > : : iterator ipfin = inters . end ( ) ;
LaLIST < Front * > : : iterator ipdebut = inters . begin ( ) ;
for ( i2 = 1 , ip = ipdebut ; ip ! = ipfin ; ip + + , i2 + + )
tabb ( i2 ) = & ( * ( * ip ) ) ;
// def des elements mitoyen, stocké dans mitoyen_de_chaque_element(i1)
tab_front ( j1 ) . DefMitoyen ( tabb ) ;
} ; // fin de la boucle sur les frontières de elem1
} ; // fin de la boucle externe des éléments
//--debug
//for (int i=1;i<=mitoyen_de_chaque_element.Taille();i++)
// {cout <<"\n\n **** element: "<<i<<" frontiere: ";
// Tableau <Front>& tab_f = mitoyen_de_chaque_element(i);
// for (int j=1;j<=tab_f.Taille();j++)
// tab_f(j).Affiche();
// }
//--fin debug
// effacement du contenu du tableau indice
indice . Libere ( ) ;
} ;
// lectures des infos pour le choix d'un élément
void Maillage : : Lecture_info_1element ( UtilLecture * entreePrinc , int & num_elt , Enum_geom & id_geom
, Enum_interpol & id_interpol , EnumElemTypeProblem & id_typeProb
, string & str_precision )
{ // mise en place des valeurs par défaut
str_precision = " " ;
id_typeProb = MECA_SOLIDE_DEFORMABLE ; // type par défaut
// lecture des champs qui doivent être toujours présents
* ( entreePrinc - > entree ) > > num_elt > > id_geom > > id_interpol ;
// cas d'info annexe ou du type de problème
// on regarde le prochain caractère sans changer le flot
/// int cr=(entreePrinc->entree)->peek(); ne marche pas !!!
//--- début du remplacement du peek
char car = Picococar ( * ( entreePrinc - > entree ) ) ; // = flot.peek();
// on recupère l'entier correspondant au caractère
int cr = int ( car ) ;
//--- fin du remplacement du peek
// si c'est un chiffre c'est fini pour le choix de l'élément
int zero = int ( ' 0 ' ) ; int neuf = int ( ' 9 ' ) ;
// if ((cr >= int('0'))&&(cr <= int('9'))) return;
if ( ( cr > = zero ) & & ( cr < = neuf ) ) return ;
// maintenant on a deux cas, soit des infos annexes ou soit
// la définition du type de pb suivi ou non d'infos annexes
if ( cr = = int ( ' _ ' ) )
// cas où on a des infos annexes de choix
{ * ( entreePrinc - > entree ) > > str_precision ;
// ensuite il ne doit y avoir que des numéros donc fin
return ;
}
// ou on regarde s'il y a définition du type de problème
// qui doit commencer par une lettre
else if ( ( ( cr > = int ( ' a ' ) ) & & ( cr < = int ( ' z ' ) ) ) | |
( ( cr > = int ( ' A ' ) ) & & ( cr < = int ( ' Z ' ) ) ) )
{ * ( entreePrinc - > entree ) > > id_typeProb ;
// on regarde s'il y a des infos annexes après le type de problem
if ( cr = = int ( ' _ ' ) )
// cas où on a des infos annexes de choix
{ * ( entreePrinc - > entree ) > > str_precision ;
// ensuite il ne doit y avoir que des numéros donc fin
return ;
}
} ;
// sinon c'est le cas qui ne doit pas arriver mais pour éviter des warnings
return ;
} ;
// 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 Maillage : : Affectation_noeud ( Noeud & noeud )
{ int nbn = noeud . Num_noeud ( ) ;
if ( tab_noeud ( nbn ) = = NULL )
{ tab_noeud ( nbn ) = & noeud ; }
else
// on augmente la place
{ int tail_tab_noeud = tab_noeud . Taille ( ) + 1 ;
tab_noeud . Change_taille ( tail_tab_noeud ) ;
noeud . Change_num_noeud ( tail_tab_noeud ) ;
tab_noeud ( tail_tab_noeud ) = & noeud ;
if ( ParaGlob : : NiveauImpression ( ) > 0 )
{ cout < < " \n warning : le numero initial du noeud " < < nbn < < " est remplace par "
< < " le numero d'ordre attribue automatiquement par herezh " < < tail_tab_noeud
< < " \n seul ce dernier sera utilise par la suite ! " < < endl ;
if ( ParaGlob : : NiveauImpression ( ) > 5 )
cout < < " \n Maillage::Affectation_noeud (Noeud& noeud) " < < endl ;
} ;
} ;
} ;
// 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 Maillage : : Affectation_element ( Element & element )
{ int nbe = element . Num_elt ( ) ;
if ( tab_element ( nbe ) = = NULL )
{ tab_element ( nbe ) = & element ; }
else
// on augmente la place
{ int tail_tab_element = tab_element . Taille ( ) + 1 ;
tab_element . Change_taille ( tail_tab_element ) ;
element . Change_num_elt ( tail_tab_element ) ;
tab_element ( tail_tab_element ) = & element ;
if ( ParaGlob : : NiveauImpression ( ) > 0 )
{ cout < < " \n warning : le numero initial de l'element " < < nbe < < " est remplace par "
< < " le numero d'ordre attribue automatiquement par herezh " < < tail_tab_element
< < " \n seul ce dernier sera utilise par la suite ! " < < endl ;
if ( ParaGlob : : NiveauImpression ( ) > 5 )
cout < < " \n Maillage::Affectation_element (Element& element) " < < endl ;
} ;
} ;
// on met à jour éventuellement les types de problèmes gérés
EnumElemTypeProblem enu = element . Id_TypeProblem ( ) ;
if ( ! types_de_problemes . Contient ( enu ) )
{ int tail = types_de_problemes . Taille ( ) ;
types_de_problemes . Change_taille ( tail + 1 ) ;
types_de_problemes ( tail + 1 ) = enu ;
ddl_representatifs_des_physiques . Change_taille ( tail + 1 ) ;
switch ( enu )
{ case MECA_SOLIDE_DEFORMABLE :
ddl_representatifs_des_physiques ( tail + 1 ) = X1 ; break ;
case THERMIQUE :
ddl_representatifs_des_physiques ( tail + 1 ) = TEMP ; break ;
default :
cout < < " \n ***Erreur : pour l'instant le type de probleme: " < < NomElemTypeProblem ( enu )
< < " n'est pas pris en compte ! \n " ;
cout < < " \n Maillage::Affectation_element(... \n " ;
Sortie ( 1 ) ;
} ;
} ;
//
//
//
// if (find(types_de_problemes.begin(),types_de_problemes.end(),enu) == types_de_problemes.end())
// {
// types_de_problemes.push_back(enu);
// types_de_problemes.sort(); types_de_problemes.unique();
// switch (enu)
// {case MECA_SOLIDE_DEFORMABLE :
// ddl_representatifs_des_physiques.push_back(X1);break;
// case THERMIQUE :
// ddl_representatifs_des_physiques.push_back(TEMP);break;
// default :
// cout << "\n***Erreur : pour l'instant le type de probleme: "<<NomElemTypeProblem(enu)
// << "n'est pas pris en compte !\n";
// cout << "\n Maillage::Affectation_element(... \n";
// Sortie(1);
// };
// };
} ;
// 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 Maillage : : Change_nb_noeud ( int nouveau_nb )
{ int vieille_taille = tab_noeud . Taille ( ) ;
tab_noeud . Change_taille ( nouveau_nb ) ;
for ( int i = vieille_taille + 1 ; i < = nouveau_nb ; i + + )
tab_noeud ( i ) = NULL ;
} ;
// 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 Maillage : : Change_nb_element ( int nouveau_nb )
{ int vieille_taille = tab_element . Taille ( ) ;
tab_element . Change_taille ( nouveau_nb ) ;
for ( int i = vieille_taille + 1 ; i < = nouveau_nb ; i + + )
tab_element ( i ) = NULL ;
} ;