Projet

Général

Profil

Perl script : convert lists of nodes to the corresponding list of edges or faces » hz_refN_2_refAF.pl

version 1.00 - Julien Troufflard, 26/01/2026 19:04

 
#!/usr/bin/env perl
use strict;
use English;
use File::Basename;
my $NOM_PROG = basename $PROGRAM_NAME;

my $VERSION = '1.00';
######################################################################################################
# script pour creer la liste d aretes ou de faces correspondante a des listes de noeuds #
# version 1.00 : version initiale #
######################################################################################################

#
# remarque aux developpeurs : le choix fait dans ce script est de declencher une erreur fatale ("die")
# pour le moindre probleme plutot que de rester silencieux.
# Un probleme peut venir de : un numero de noeud incorrect, une liste de reference
# de noeuds inexistante dans le maillage, une liste a creer vide, etc...
#
# => l idee generale est que l utilisateur soit au courant du moindre probleme
# venant de ses choix d arguments
#


# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# VARIABLES QUE L UTILISATEUR PEUT ETRE AMENE A RENSEIGNER #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

#
# ... rien pour l instant
#

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# FIN VARIABLES UTILISATEUR #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# VARIABLES DEVELOPPEUR (NE PAS MODIFIER : RESERVEES AUX DEVELOPPEURS)#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

# table de hashage contenant la numerotation des aretes et faces par type d element
# (numerotation dans l element de reference)
my %NUMEROTATION_AF_ELT;

my @TYPE_ELT_SUPPORTES;#pour accumuler la liste des elements connus
# et ensuite on convertira cette liste en une unique chaine pour faire une verif
# rapide des elements du maillage

#-------------------------------------
#------------ elements 1D ------------
#-------------------------------------

#---- element : POUT BIE1 ----
$_ = "POUT BIE1";
push(@TYPE_ELT_SUPPORTES, $_);
#aretes
$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'NB'} = 1;
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{1}} = (1,2);
#faces
$NUMEROTATION_AF_ELT{'FACE'}{'NB'} = 0;

#---- element : POUT BIE2
$_ = "POUT BIE2";
push(@TYPE_ELT_SUPPORTES, $_);
#aretes
$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'NB'} = 1;
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{1}} = (1,2,3);
#faces
$NUMEROTATION_AF_ELT{'FACE'}{'NB'} = 0;


#-------------------------------------
#---------- elements 1D AXI ----------
#-------------------------------------

#
# les aretes des elements 1D AXI sont numerotees comme les elements 1D
# => on peut directement reutiliser les elements 1D en passant par une reference \%{ ... }
#

#---- element : SEG_AXI BIE1 ----
$_ = "SEG_AXI BIE1";
push(@TYPE_ELT_SUPPORTES, $_);
$NUMEROTATION_AF_ELT{$_} = \%{$NUMEROTATION_AF_ELT{"POUT BIE1"}}; # ref vers POUT BIE1

#---- element : SEG_AXI BIE2 ----
$_ = "SEG_AXI BIE2";
push(@TYPE_ELT_SUPPORTES, $_);
$NUMEROTATION_AF_ELT{$_} = \%{$NUMEROTATION_AF_ELT{"POUT BIE2"}}; # ref vers POUT BIE2


#-------------------------------------
#------------ elements 2D ------------
#-------------------------------------

#---- element : TRIANGLE LINEAIRE ----
$_ = "TRIANGLE LINEAIRE";
push(@TYPE_ELT_SUPPORTES, $_);
#aretes
$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'NB'} = 3;
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{1}} = (1,2);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{2}} = (2,3);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{3}} = (3,1);
#faces
$NUMEROTATION_AF_ELT{$_}{'FACE'}{'NB'} = 1;
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{1}} = (1,2,3);

#---- element : TRIANGLE QUADRACOMPL ----
$_ = "TRIANGLE QUADRACOMPL";
push(@TYPE_ELT_SUPPORTES, $_);
#aretes
$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'NB'} = 3;
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{1}} = (1,4,2);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{2}} = (2,5,3);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{3}} = (3,6,1);
#faces
$NUMEROTATION_AF_ELT{$_}{'FACE'}{'NB'} = 1;
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{1}} = (1,2,3,4,5,6);

#---- element : QUADRANGLE LINEAIRE ----
$_ = "QUADRANGLE LINEAIRE";
push(@TYPE_ELT_SUPPORTES, $_);
#aretes
$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'NB'} = 4;
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{1}} = (1,2);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{2}} = (2,3);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{3}} = (3,4);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{4}} = (4,1);
#faces
$NUMEROTATION_AF_ELT{$_}{'FACE'}{'NB'} = 1;
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{1}} = (1,2,3,4);

#---- element : QUADRANGLE QUADRACOMPL ----
$_ = "QUADRANGLE QUADRACOMPL";
push(@TYPE_ELT_SUPPORTES, $_);
#aretes
$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'NB'} = 4;
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{1}} = (1,5,2);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{2}} = (2,6,3);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{3}} = (3,7,4);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{4}} = (4,8,1);
#faces
$NUMEROTATION_AF_ELT{$_}{'FACE'}{'NB'} = 1;
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{1}} = (1,2,3,4,5,6,7,8,9);


#-------------------------------------
#---------- elements 2D AXI ----------
#-------------------------------------

#
# les aretes et face des elements 2D AXI sont numerotes comme les elements 2D
# => on peut directement reutiliser les elements 2D en passant par une reference \%{ ... }
#

#---- element : TRIA_AXI LINEAIRE ----
$_ = "TRIA_AXI LINEAIRE";
push(@TYPE_ELT_SUPPORTES, $_);
$NUMEROTATION_AF_ELT{$_} = \%{$NUMEROTATION_AF_ELT{"TRIANGLE LINEAIRE"}}; # ref vers TRIANGLE LINEAIRE

#---- element : TRIA_AXI QUADRACOMPL ----
$_ = "TRIA_AXI QUADRACOMPL";
push(@TYPE_ELT_SUPPORTES, $_);
$NUMEROTATION_AF_ELT{$_} = \%{$NUMEROTATION_AF_ELT{"TRIANGLE QUADRACOMPL"}}; # ref vers TRIANGLE QUADRACOMPL

#---- element : QUAD_AXI LINEAIRE ----
$_ = "QUAD_AXI LINEAIRE";
push(@TYPE_ELT_SUPPORTES, $_);
$NUMEROTATION_AF_ELT{$_} = \%{$NUMEROTATION_AF_ELT{"QUADRANGLE LINEAIRE"}}; # ref vers QUADRANGLE LINEAIRE

#---- element : QUAD_AXI QUADRACOMPL ----
$_ = "QUAD_AXI QUADRACOMPL";
push(@TYPE_ELT_SUPPORTES, $_);
$NUMEROTATION_AF_ELT{$_} = \%{$NUMEROTATION_AF_ELT{"QUADRANGLE QUADRACOMPL"}}; # ref vers QUADRANGLE QUADRACOMPL


#-------------------------------------
#------------ elements 3D ------------
#-------------------------------------

#---- element : TETRAEDRE LINEAIRE ----
$_ = "TETRAEDRE LINEAIRE";
push(@TYPE_ELT_SUPPORTES, $_);
#aretes
$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'NB'} = 6;
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{1}} = (1,2);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{2}} = (2,3);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{3}} = (3,1);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{4}} = (1,4);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{5}} = (2,4);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{6}} = (3,4);
#faces
$NUMEROTATION_AF_ELT{$_}{'FACE'}{'NB'} = 4;
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{1}} = (1,3,2);
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{2}} = (1,4,3);
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{3}} = (1,2,4);
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{4}} = (2,3,4);

#---- element : TETRAEDRE QUADRACOMPL ----
$_ = "TETRAEDRE QUADRACOMPL";
push(@TYPE_ELT_SUPPORTES, $_);
#aretes
$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'NB'} = 6;
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{1}} = (1,5,2);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{2}} = (2,6,3);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{3}} = (3,7,1);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{4}} = (1,8,4);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{5}} = (2,9,4);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{6}} = (3,10,4);
#faces
$NUMEROTATION_AF_ELT{$_}{'FACE'}{'NB'} = 4;
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{1}} = (7,3,6,2,5,1);
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{2}} = (7,1,8,4,10,3);
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{3}} = (5,2,9,4,8,1);
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{4}} = (6,3,10,4,9,2);

#---- element : HEXAEDRE LINEAIRE ----
$_ = "HEXAEDRE LINEAIRE";
push(@TYPE_ELT_SUPPORTES, $_);
#aretes
$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'NB'} = 12;
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{1}} = (1,2);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{2}} = (2,3);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{3}} = (3,4);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{4}} = (4,1);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{5}} = (1,5);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{6}} = (2,6);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{7}} = (3,7);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{8}} = (4,8);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{9}} = (5,6);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{10}} = (6,7);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{11}} = (7,8);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{12}} = (8,5);
#faces
$NUMEROTATION_AF_ELT{$_}{'FACE'}{'NB'} = 6;
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{1}} = (1,4,3,2);
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{2}} = (1,5,8,4);
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{3}} = (1,2,6,5);
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{4}} = (5,6,7,8);
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{5}} = (2,3,7,6);
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{6}} = (3,4,8,7);

#---- element : HEXAEDRE QUADRACOMPL ----
$_ = "HEXAEDRE QUADRACOMPL";
push(@TYPE_ELT_SUPPORTES, $_);
#aretes
$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'NB'} = 12;
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{1}} = (1,9,2);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{2}} = (2,10,3);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{3}} = (3,11,4);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{4}} = (4,12,1);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{5}} = (1,13,5);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{6}} = (2,14,6);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{7}} = (3,15,7);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{8}} = (4,16,8);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{9}} = (5,17,6);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{10}} = (6,18,7);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{11}} = (7,19,8);
@{$NUMEROTATION_AF_ELT{$_}{'ARETE'}{'CONNEX'}{12}} = (8,20,5);
#faces
$NUMEROTATION_AF_ELT{$_}{'FACE'}{'NB'} = 6;
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{1}} = (1,4,3,2,12,11,10,9,21);
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{2}} = (1,5,8,4,13,20,16,12,25);
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{3}} = (1,2,6,5,9,14,17,13,22);
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{4}} = (5,6,7,8,17,18,19,20,26);
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{5}} = (2,3,7,6,10,15,18,14,23);
@{$NUMEROTATION_AF_ELT{$_}{'FACE'}{'CONNEX'}{6}} = (3,4,8,7,11,16,19,15,24);


#conversion de la liste des types d element supportes en une chaine
# format de la chaine : "TRIANGLE LINEAIRE / QUADRANGLE LINEAIRE / etc..."
# => permettre de savoir si un element existe dans %NUMEROTATION_AF_ELT en faisant
# le test par exemple: ($TYPE_ELT_SUPPORTES =~ /TETRAEDRE LINEAIRE/)
my $TYPE_ELT_SUPPORTES = join(" / ", @TYPE_ELT_SUPPORTES);


# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# FIN VARIABLES DEVELOPPEUR #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #





sub affichage_aide {
use Text::Wrap;
#config du package Text::Wrap
$Text::Wrap::columns = 81;#le nombre de caracteres maximum par ligne sera egal a ($Text::Wrap::columns - 1) dans le cas ou utilise wrap

#indentation de longueur $NOM_PROG
my $indent_NOM_PROG = ""; $indent_NOM_PROG .= " " for(1 .. length($NOM_PROG));

print "--------------------------------------------\n";
print " script $NOM_PROG (version $VERSION)\n";
print "--------------------------------------------\n";
print "\n";
print wrap("", " ", "But : creer la liste d aretes ou de faces correspondante a des listes de noeuds\n");
print "\n";
print wrap(""," $indent_NOM_PROG ",
"Usage : $NOM_PROG [-h|help] fic_her listeAF_a_creer N_1 [N_2 ... N_n]\n",
"\n");
print "\n";
print "--------------------------------------------\n";
print "Arguments\n";
print "--------------------------------------------\n";
print " o fic_her : fichier .her\n";
print " o listeAF_a_creer : nom de la liste a creer\n";
print " > si le nom commence par A => creation d une liste d aretes\n";
print " > si le nom commence par F => creation d une liste de face\n";
print " o N_1 [N_2 ... N_n] : numeros ou listes de reference de noeuds du fichier fic_her\n";
print "\n";
print "--------------------------------------------\n";
print "Fonctionnement\n";
print "--------------------------------------------\n";
print wrap(" ", " ", "Ne seront retenus que les aretes ou faces dont tous les noeuds existent dans les ",
"noeuds ou listes N_i. La liste cree est affichee dans le terminal.\n");
print "\n";
print " Liste des elements supportes :\n";
foreach my $type_elt (@TYPE_ELT_SUPPORTES) {
print " > $type_elt\n";
}

print "\n";
print "--------------------------------------------\n";
print "Options\n";
print "--------------------------------------------\n";
my $_4espaces = " ";

#
# affichage des options (si possible en suivant le style d indentation et dans l ordre alphabetique, selon votre patience :) :) )
#

$_ = $_4espaces.chaine2espaces("-v : ");
print wrap($_4espaces, $_, "-v : affichage du numero de version\n");

print "\n";
print "--------------------------------------------\n";
print "Exemples\n";
print "--------------------------------------------\n";
print wrap(" ", " ", "> creer la liste de faces F_sup correspondante aux noeuds 2, 3, 10 et a la liste ",
"N_sup du maillage part_01.her :\n");
print "\n $NOM_PROG part_01.her F_sup 2 3 10 N_sup\n";
print "\n";
print wrap(" ", " ", "> creer la liste d aretes A_contact correspondante aux noeuds des listes ",
"N_bord_1 et N_bord_2 du maillage outil_ext.her :\n");
print "\n $NOM_PROG outil_ext.her A_contact N_bord_1 N_bord_2\n";
print "\n";
print "Auteur :\n";
print " TROUFFLARD Julien\n";
print " julien.troufflard\@free.fr\n";
print "----------------------------------------\n";
exit;
}


#------------------------------------
#premier balayage des arguments
# => si option du style -h ou -help => affichage aide
#------------------------------------
my $isOpt_help = 0;
foreach my $arg (@ARGV) {
if(($arg =~ /^-h$/i) or ($arg =~ /^-help$/i)) {
$isOpt_help = 1;
}
}
#si option -h|-help ou pas d arguments => affichage aide
if($isOpt_help or ($#ARGV == -1)) {
affichage_aide();
}

#option -v => affichage de la version et arret
foreach my $arg (@ARGV) {
if($arg eq '-v') {
print "\n $NOM_PROG : version $VERSION\n\n";
exit;
}
}


#------------------------------------
#recuperation des arguments et options
#------------------------------------
my $fic_her; #fichier .her
my $liste_AF_a_creer; #nom de la liste a creer (doit commencer par A ou F)
my @liste_Ni; #noeuds ou liste de noeuds donnes en argument pour determiner les aretes/faces

my $opt;
my @args;
while($#ARGV != -1) {
$opt = shift(@ARGV);

#option ...
if(0) {
}

#arguments obligatoires
else {
push(@args,$opt);
}
}#while($#ARGV != -1)

($#args >= 2) or die "\nErreur (prog:$NOM_PROG) : arguments manquants...\n\n";
$fic_her = shift(@args);
$liste_AF_a_creer = shift(@args);

#parcours du reste des arguments a la recherche de numero de noeud ou liste de reference de noeuds
# (ARRET DU PROGRAMME si on trouve autre chose qu un entier et une chaine commencant par N)
foreach my $entree (@args) {
($entree =~ /^\d+$/ or $entree =~ /^N/) or die "\nErreur (prog:$NOM_PROG) : noeud ou liste de reference incorrect en entree (argument lu : $entree)...\n\n";
push(@liste_Ni, $entree);
}


#verif existence du maillage
(-e $fic_her) or die "\nErreur (prog:$NOM_PROG) : fichier $fic_her introuvable...\n\n";


#verif que la liste a creer commence par A ou F
($liste_AF_a_creer =~ /^[AF]/) or die "\nErreur (prog:$NOM_PROG) : la liste a creer doit commencer par A ou F (argument lu : $liste_AF_a_creer)...\n\n";


#lecture du maillage
my ($nom_maillage, $nb_noeuds, $ref_noeuds, $nb_elts, $ref_elements, @listes_ref) = lecture_mail_her($fic_her);


#conversion du contenu de @liste_Ni en indicateur de noeud a trouver
# (ARRET DU PROGRAMME si on trouve un numero de noeuds invalide ou une liste de noeuds inexistante)
my %is_NOEUD_A_TROUVER;
foreach my $Ni (@liste_Ni) {
#cas d un numero de noeud
if($Ni =~ /^\d/) {
($Ni > 0) or die "\nErreur (prog:$NOM_PROG) : numero de noeud incorrect en entree (numero : $Ni => devrait etre superieur a 0)...\n\n";
($Ni <= $nb_noeuds) or die "\nErreur (prog:$NOM_PROG) : numero de noeud incorrect en entree (numero : $Ni => depasse le numero max $nb_noeuds dans le fichier $fic_her)\n";
$is_NOEUD_A_TROUVER{$Ni} = 1;
}
#cas d une liste de reference de noeuds
else {
defined($listes_ref[0]->{$Ni}[0]) or die "\nErreur (prog:$NOM_PROG) : liste de reference $Ni n existe pas dans le fichier $fic_her ...\n\n";
foreach my $noeud (@{$listes_ref[0]->{$Ni}}) {
$is_NOEUD_A_TROUVER{$noeud} = 1;
}
}
}


#-------------------------------------------------------------------------
#parcours des elements du maillage a la recherche des aretes/faces
# qui ont tous leurs noeuds presents dans la table %is_NOEUD_A_TROUVER
#-------------------------------------------------------------------------

#type de liste a creer => permettra de pointer vers la bonne cle dans %NUMEROTATION_AF_ELT ("ARETE" ou "FACE")
my $TYPE_LISTE = "ARETE";
$TYPE_LISTE = "FACE" if($liste_AF_a_creer =~ /^F/);

#NB : on applique le meme traitement que ce soit une liste d aretes ou de faces a creer
# inutile de differencier le traitement car :
# 1) le format d une liste d aretes ou de faces est le meme :
# NOM_LISTE no_elt no_AF no_elt no_AF etc... (avec no_AF = numero arete ou face)
#
# 2) on a la variable $TYPE_LISTE qui pointera automatiquement vers la cle "ARETE" ou "FACE"
# dans la table %NUMEROTATION_AF_ELT

#liste qui contiendra les paires (no element no arete/face)
my @contenu_liste_AF_a_creer;

for(my $no_elt=1; $no_elt<=$nb_elts; $no_elt++) {
my @connectivite_elt = @{$ref_elements->{$no_elt}{'CONNEX'}};

my $nb_noeuds_a_trouver = 0;#pour trier les elements inutiles (au moins 2 noeuds minimum pour regarder ses aretes/faces)
foreach my $n (@connectivite_elt) {
next if(not $is_NOEUD_A_TROUVER{$n});
$nb_noeuds_a_trouver++;
last if($nb_noeuds_a_trouver > 2);#on s arrete si on en a deja trouve 3 (on aura potentiellement au moins une arete ou une face)
}
#on ne continue $nb_noeuds_a_trouver au moins egal a 2 que si
next if($nb_noeuds_a_trouver < 2);

#recuperation du type d element (seulement les 2 premiers mots pour ne pas tenir compte d un eventuel _cmNpti)
$_ = $ref_elements->{$no_elt}{'TYPE'};
@_ = split;
my $type_elt = "$_[0] $_[1]";

#verif de l existence de cet element dans $TYPE_ELT_SUPPORTES
($TYPE_ELT_SUPPORTES =~ /$type_elt/) or die "\nErreur (prog:$NOM_PROG) : element $no_elt => type non reconnu ($type_elt)...\n\n";


#on parcourt chaque arete/face d un element de type $type_elt
MAIN:for(my $no_AF=1; $no_AF<=$NUMEROTATION_AF_ELT{$type_elt}{$TYPE_LISTE}{'NB'}; $no_AF++) {
# on parcourt la numerotation de reference de l arete/face $no_AF de ce type d element
foreach my $no_ref_noeud_AF (@{$NUMEROTATION_AF_ELT{$type_elt}{$TYPE_LISTE}{'CONNEX'}{$no_AF}}) {
# le numero $no_ref_noeud_AF est un numero dans l element de reference
# il faut le convertir en numero de noeud de l element reel $no_elt
# => le numero de noeud reel correspond au noeud $no_ref_noeud_AF de la liste de connectivite de
# l element $no_elt ( NB : on retranche 1 car les indices de liste commence a 0 => $no_ref_noeud_AF - 1 )
my $no_noeud_reel = $connectivite_elt[$no_ref_noeud_AF-1];
#test d existence de ce noeud reel dans la table %is_NOEUD_A_TROUVER
next MAIN if(not defined $is_NOEUD_A_TROUVER{$no_noeud_reel});
}

#si on arrive ici, c est que l arete/face $no_AF de l element $no_elt possede tous ses noeuds
# dans les noeuds a trouver => ajout dans la liste
push(@contenu_liste_AF_a_creer, $no_elt, $no_AF);
}

}#for(my $no_elt=1; $no_elt<=$nb_elts; $nb_elts++)

#ERREUR si la liste est vide
if($#contenu_liste_AF_a_creer == -1) {
$TYPE_LISTE =~ tr/A-Z/a-z/;
die "\nErreur (prog:$NOM_PROG) : aucune $TYPE_LISTE ne correspond aux noeuds donnes...\n\n";
}


#affichage de la liste obtenue dans le terminal
ecrire_liste_A_F(*STDOUT, $liste_AF_a_creer, @contenu_liste_AF_a_creer);




#prend en argument une chaine de caracteres et renvoie
#une chaine de caracteres de meme longueur constituee d espaces
sub chaine2espaces {
my $chaine = shift;
(my $chaine_espaces = $chaine) =~ s/./ /g;
return $chaine_espaces;
}


#ecrire une liste d aretes et faces
sub ecrire_liste_A_F {
my $handle = shift;
my $nom_liste = shift;
my @liste_no = @_;

my $cpt; my $cpt_max = 30; my $nb_blancs;

$nb_blancs = ""; $nb_blancs .= " " for(1 .. length($nom_liste));
$_ = shift(@liste_no);
print $handle "$nom_liste $_";
$cpt = 1;
foreach my $no (@liste_no) {
$cpt++;
if($cpt == 1) {print $handle "$nb_blancs $no";}
elsif($cpt == $cpt_max) {print $handle " $no\n"; $cpt = 0;}
else {print $handle " $no";}
}
print $handle "\n" if($cpt != $cpt_max);
}


#----------------
#sub qui lit un maillage herezh++ pour recuperer les noeuds, les elements et les listes de references
#et les renvoier sous forme de reference (lecture du .her et d un .lis si il existe)
#
# exemple d appel :
# my ($nom_maillage, $nb_noeuds, $ref_tab_noeuds, $nb_elts, $ref_tab_elements, @ref_listes) = lecture_mail_her("fic_her");
#
# avec - $nom_maillage : nom du maillage (si il y en a un. sinon $nom_maillage sera egal a undef
# - $nb_noeuds : nombre de noeuds (entier)
# - $ref_tab_noeuds : reference vers un tableau de noeuds => $ref_tab_noeuds->[no noeud][0] : coordonnee x
# $ref_tab_noeuds->[no noeud][1] : coordonnee y
# $ref_tab_noeuds->[no noeud][2] : coordonnee z)
# - $nb_elts : nombre d elements (entier)
# - $ref_tab_elements : reference vers une table de hashage => $ref_tab_elements->{no elt}{'TYPE'} : type d element
# @{$ref_tab_elements->{no elt}{'CONNEX'}} : (liste des noeuds)
# - @ref_listes : liste de references vers les tables de hashage contenant les listes de references de noeuds, aretes, faces et elements
# => $ref_listes[0] : reference vers la table de hashage des listes de noeuds => @{$ref_listes[0]->{'nom liste'}} : (liste des noeuds)
# $ref_listes[1] : reference vers la table de hashage des listes d aretes => @{$ref_listes[1]->{'nom liste'}} : (liste des aretes)
# $ref_listes[2] : reference vers la table de hashage des listes de faces => @{$ref_listes[2]->{'nom liste'}} : (liste des faces)
# $ref_listes[3] : reference vers la table de hashage des listes d elements => @{$ref_listes[3]->{'nom liste'}} : (liste des elements)
# $ref_listes[4] : reference vers la table de hashage des listes de points d integration => @{$ref_listes[4]->{'nom liste'}} : (liste des points d integration)
#
sub lecture_mail_her {
my $fher = shift;

my $nom_maillage;

#------------------------
# lecture du maillage .her
#------------------------
#-lecture de noeuds
my @tab_noeuds; my $nb_noeuds;
my $no_noeud = 0;
open(Fher, "<$fher");
while(<Fher>) {
if(/^\s*nom_maillage\s+(\S+)/o) {$nom_maillage = $1; next;}
next if(not /(\d+)\s+NOEUDS/o);
$nb_noeuds = $1;
last;
}
while(<Fher>) {
last if($no_noeud == $nb_noeuds);
next if(not /^\s*(\d+)\s+(\S+)\s+(\S+)\s+(\S+)\s*$/o);
$no_noeud = $1;
@{$tab_noeuds[$no_noeud]} = ($2,$3,$4);
}

#-lecture des elements
my %tab_elements; my $nb_elts;
my $no_elt = 0;
while(<Fher>) {
next if(not /(\d+)\s+ELEMENTS/o);
$nb_elts = $1;
last;
}
while(<Fher>) {
last if($no_elt == $nb_elts);
next if(not /^\s*\d+\s+\w+\s+\w+/o);
s/^\s+//;s/\s+$//;
$_ =~ /^(\d+)\s+/;
$no_elt = $1; s/^(\d+)\s+//;
$_ =~ /\s+(\d+(?:\s+\d+)*)$/;
@{$tab_elements{$no_elt}{'CONNEX'}} = split(/\s+/, $1); s/\s+(\d+(?:\s+\d+)*)$//;
$tab_elements{$no_elt}{'TYPE'} = $_; $tab_elements{$no_elt}{'TYPE'} =~ s/\s+/ /g;
}
close(Fher);


#------------------------
# lecture des references (dans le .her et dans un eventuel .lis)
#------------------------
my $flis = $fher; $flis =~ s/.her$/.lis/;
my $nom_liste;
my $is_liste_en_cours;
my %listes_NOEUDS;
my %listes_ARETES;
my %listes_FACES;
my %listes_ELEMENTS;
my %listes_PTI;

#-dans le .her
open(Fher, "<$fher");
$is_liste_en_cours = 0;
while(<Fher>) {
chomp;
if(/^\s*(N\S+)/o) {
$nom_liste = $1;
$is_liste_en_cours = 1;
s/^\s*N\S+\s+//; s/\s+$//;
push(@{$listes_NOEUDS{$nom_liste}},split(/\s+/,$_));
}
elsif(/^\s*noeuds/io or /^\s*elements/i or /^\s*[AFEG]/o) {
$is_liste_en_cours = 0;
}
elsif($is_liste_en_cours and /^\s*\d+(\s+\d+)*\s*$/io) {
s/^\s+//; s/\s+$//;
push(@{$listes_NOEUDS{$nom_liste}},split(/\s+/,$_));
}
}
close(Fher);

open(Fher, "<$fher");
$is_liste_en_cours = 0;
while(<Fher>) {
chomp;
if(/^\s*(A\S+)/o) {
$nom_liste = $1;
$is_liste_en_cours = 1;
s/^\s*A\S+\s+//; s/\s+$//;
push(@{$listes_ARETES{$nom_liste}},split(/\s+/,$_));
}
elsif(/^\s*noeuds/io or /^\s*elements/i or /^\s*[NFEG]/o) {
$is_liste_en_cours = 0;
}
elsif($is_liste_en_cours and /^\s*\d+(\s+\d+)*\s*$/io) {
s/^\s+//; s/\s+$//;
push(@{$listes_ARETES{$nom_liste}},split(/\s+/,$_));
}
}
close(Fher);

open(Fher, "<$fher");
$is_liste_en_cours = 0;
while(<Fher>) {
chomp;
if(/^\s*(F\S+)/) {
$nom_liste = $1;
$is_liste_en_cours = 1;
s/^\s*F\S+\s+//; s/\s+$//;
push(@{$listes_FACES{$nom_liste}},split(/\s+/,$_));
}
elsif(/^\s*noeuds/io or /^\s*elements/i or /^\s*[NAEG]/o) {
$is_liste_en_cours = 0;
}
elsif($is_liste_en_cours and /^\s*\d+(\s+\d+)*\s*$/io) {
s/^\s+//; s/\s+$//;
push(@{$listes_FACES{$nom_liste}},split(/\s+/,$_));
}
}
close(Fher);

open(Fher, "<$fher");
$is_liste_en_cours = 0;
while(<Fher>) {
chomp;
if(/^\s*(E\S+)/o) {
$nom_liste = $1;
$is_liste_en_cours = 1;
s/^\s*E\S+\s+//; s/\s+$//;
push(@{$listes_ELEMENTS{$nom_liste}},split(/\s+/,$_));
}
elsif(/^\s*noeuds/io or /^\s*elements/io or /^\s*[NAFG]/o) {
$is_liste_en_cours = 0;
}
elsif($is_liste_en_cours and /^\s*\d+(\s+\d+)*\s*$/io) {
s/^\s+//; s/\s+$//;
push(@{$listes_ELEMENTS{$nom_liste}},split(/\s+/,$_));
}
}
close(Fher);

open(Fher, "<$fher");
$is_liste_en_cours = 0;
while(<Fher>) {
chomp;
if(/^\s*(G\S+)/o) {
$nom_liste = $1;
$is_liste_en_cours = 1;
s/^\s*G\S+\s+//; s/\s+$//;
push(@{$listes_PTI{$nom_liste}},split(/\s+/,$_));
}
elsif(/^\s*noeuds/io or /^\s*elements/io or /^\s*[NAFE]/o) {
$is_liste_en_cours = 0;
}
elsif($is_liste_en_cours and /^\s*\d+(\s+\d+)*\s*$/io) {
s/^\s+//; s/\s+$//;
push(@{$listes_PTI{$nom_liste}},split(/\s+/,$_));
}
}
close(Fher);


#dans le .lis (si il existe)
if(-e $flis) {

open(Flis, "<$flis");
$is_liste_en_cours = 0;
while(<Flis>) {
chomp;
if(/^\s*(N\S+)/o) {
$nom_liste = $1;
$is_liste_en_cours = 1;
s/^\s*N\S+\s+//; s/\s+$//;
push(@{$listes_NOEUDS{$nom_liste}},split(/\s+/,$_));
}
elsif(/^\s*noeuds/io or /^\s*elements/io or /^\s*[AFEG]/o) {
$is_liste_en_cours = 0;
}
elsif($is_liste_en_cours and /^\s*\d+(\s+\d+)*\s*$/i) {
s/^\s+//; s/\s+$//;
push(@{$listes_NOEUDS{$nom_liste}},split(/\s+/,$_));
}
}
close(Flis);

open(Flis, "<$flis");
$is_liste_en_cours = 0;
while(<Flis>) {
chomp;
if(/^\s*(A\S+)/o) {
$nom_liste = $1;
$is_liste_en_cours = 1;
s/^\s*A\S+\s+//; s/\s+$//;
push(@{$listes_ARETES{$nom_liste}},split(/\s+/,$_));
}
elsif(/^\s*noeuds/io or /^\s*elements/io or /^\s*[NFEG]/o) {
$is_liste_en_cours = 0;
}
elsif($is_liste_en_cours and /^\s*\d+(\s+\d+)*\s*$/io) {
s/^\s+//; s/\s+$//;
push(@{$listes_ARETES{$nom_liste}},split(/\s+/,$_));
}
}
close(Flis);

open(Flis, "<$flis");
$is_liste_en_cours = 0;
while(<Flis>) {
chomp;
if(/^\s*(F\S+)/o) {
$nom_liste = $1;
$is_liste_en_cours = 1;
s/^\s*F\S+\s+//; s/\s+$//;
push(@{$listes_FACES{$nom_liste}},split(/\s+/,$_));
}
elsif(/^\s*noeuds/io or /^\s*elements/io or /^\s*[NAEG]/o) {
$is_liste_en_cours = 0;
}
elsif($is_liste_en_cours and /^\s*\d+(\s+\d+)*\s*$/io) {
s/^\s+//; s/\s+$//;
push(@{$listes_FACES{$nom_liste}},split(/\s+/,$_));
}
}
close(Flis);

open(Flis, "<$flis");
$is_liste_en_cours = 0;
while(<Flis>) {
chomp;
if(/^\s*(E\S+)/o) {
$nom_liste = $1;
$is_liste_en_cours = 1;
s/^\s*E\S+\s+//; s/\s+$//;
push(@{$listes_ELEMENTS{$nom_liste}},split(/\s+/,$_));
}
elsif(/^\s*noeuds/io or /^\s*elements/io or /^\s*[NAFG]/o) {
$is_liste_en_cours = 0;
}
elsif($is_liste_en_cours and /^\s*\d+(\s+\d+)*\s*$/io) {
s/^\s+//; s/\s+$//;
push(@{$listes_ELEMENTS{$nom_liste}},split(/\s+/,$_));
}
}
close(Flis);

open(Flis, "<$flis");
$is_liste_en_cours = 0;
while(<Flis>) {
chomp;
if(/^\s*(G\S+)/o) {
$nom_liste = $1;
$is_liste_en_cours = 1;
s/^\s*G\S+\s+//; s/\s+$//;
push(@{$listes_PTI{$nom_liste}},split(/\s+/,$_));
}
elsif(/^\s*noeuds/io or /^\s*elements/io or /^\s*[NAFE]/o) {
$is_liste_en_cours = 0;
}
elsif($is_liste_en_cours and /^\s*\d+(\s+\d+)*\s*$/io) {
s/^\s+//; s/\s+$//;
push(@{$listes_PTI{$nom_liste}},split(/\s+/,$_));
}
}
close(Flis);

}#if(-e $flis)

#AFFICHAGE DES LISTES DE NOEUDS
#foreach my $nom (keys(%listes_NOEUDS)) {
# print "$nom : @{$listes_NOEUDS{$nom}}\n";
#}
#AFFICHAGE DES LISTES D ARETES
#foreach my $nom (keys(%listes_ARETES)) {
# print "$nom : @{$listes_ARETES{$nom}}\n";
#}
#AFFICHAGE DES LISTES DE FACES
#foreach my $nom (keys(%listes_FACES)) {
# print "$nom : @{$listes_FACES{$nom}}\n";
#}
#AFFICHAGE DES LISTES D ELEMENTS
#foreach my $nom (keys(%listes_ELEMENTS)) {
# print "$nom : @{$listes_ELEMENTS{$nom}}\n";
#}
#AFFICHAGE DES LISTES DE POINTS D INTEGRATION
#foreach my $nom (keys(%listes_PTI)) {
# print "$nom : @{$listes_PTI{$nom}}\n";
#}

return($nom_maillage, $nb_noeuds, \@tab_noeuds, $nb_elts, \%tab_elements,
\%listes_NOEUDS, \%listes_ARETES,
\%listes_FACES, \%listes_ELEMENTS, \%listes_PTI);
}#sub lecture_mail_her
    (1-1/1)
    Redmine Appliance - Powered by TurnKey Linux