Projet

Général

Profil

perl script : convert Gmsh results into a .maple format » hz_gmsh2maple.pl

Julien Troufflard, 01/02/2023 18:14

 
#!/usr/bin/env perl
use strict;
use warnings;
use English;
use File::Glob qw(bsd_glob);
use File::Basename;
use IO::File;
use List::MoreUtils qw(uniq);
my $NOM_PROG = basename $PROGRAM_NAME;
#pattern d un reel pour les regex (desormais redondant avec $RE{num}{real} de Regexp::Common)
my $format_reel = '[+-]?[\.]?\d+[\.]?\d*(?:[eE][+-]?\d*)?';


my $VERSION = '1.00';
#####################################################################################################
# script pour visualiser un ou plusieurs maillages dans Gmsh #
# version 1.00 : version initiale (version testee sur : MacOSX Darwin) #
#####################################################################################################



#
# note :
# l une des difficultes du traitement est que la numerotation des noeuds dans le fichier Gmsh n est pas
# la meme que les fichiers maillage .her dans le cas ou il y a plusieurs maillages.
#
# On doit donc connaitre les maillages .her, et en particulier connaitre l ordre dans lequel ils ont ete
# declares dans la sortie Gmsh (fichier .CVisu). En general, c est le meme ordre que dans le fichier .info du calcul.
# La connaissance des fichiers maillages et de leur ordre permettra de se baser sur les listes de references
# existantes pour ces maillages et de determiner la correspondance entre numero de noeud du fichier .her et
# numero de noeud qui lui correspond dans le fichier Gmsh .pos
#
# Cette problematique est a l origine du choix de passer par un fichier de commande (voir aide du script).
# De toute facon, il est egalement plus simple de passer par un fichier de commande pour definir les sorties (qui peuvent
# etre nombreuses)
#







sub affichage_aide {
use Text::Wrap;
#config du package Text::Wrap
$Text::Wrap::columns = 101;#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 "But : convertir des donnees Gmsh (fichiers .pos) en fichier de type .maple\n";
print "\n";
print "Usage :\n";
print wrap(" "," $indent_NOM_PROG ", " $NOM_PROG [-h|help] [-v] [-l] [-trame nom_fic]\n",
"rep_Gmsh fic_cmd fic_maple\n");
print "\n";
print "Arguments :\n";
print " o rep_Gmsh : repertoire Gmsh\n";
print " o fic_cmd : fichier de commande de sortie (voir \"Fonctionnement\")\n";
print " o fic_maple : fichier de type .maple a creer\n";
print "\n";
print "Fonctionnement :\n";
print wrap(" ", " ",
"$NOM_PROG lit le fichier \"fic_cmd\" qui contient les mots-cles MAILLAGES et SORTIES. ",
"Il produira le fichier \"fic_maple\" ",
"qui contiendra un certain nombre de colonnes dans l ordre de ce qui est indique au mot-cle SORTIES.\n",
"\n",
"Le fichier \"fic_cmd\" aura la structure suivante :\n",
"---------------------------------------------------------\n",
"MAILLAGES #(mot-cle de declaration des maillages dans l ordre du .CVisu)\n",
"nom_fichier #(fichier .her maillage 1)\n",
"nom_fichier #(fichier .her maillage 2)\n",
"...\n",
"nom_fichier #(fichier .her maillage N)\n",
"\n",
"SORTIES #(mot-cle de declaration des grandeurs a sortir)\n",
"numero maillage\n",
"[STAT ]numero ou ref_noeuds var_1 var_2 ... var_N #(noeud ou liste suivi des grandeurs voulues)\n",
" #(eventuellement precede du mot-cle STAT)\n",
"numero maillage\n",
"[STAT ]numero ou ref_noeuds var_1 var_2 ... var_N #(noeud ou liste suivi des grandeurs voulues)\n",
" #(eventuellement precede du mot-cle STAT)\n",
"...\n",
"numero maillage\n",
"[STAT ]numero ou ref_noeuds var_1 var_2 ... var_N #(noeud ou liste suivi des grandeurs voulues)\n",
" #(eventuellement precede du mot-cle STAT)\n",
"---------------------------------------------------------\n",
"\n",
"L option -trame permet de generer un exemple de fichier de commande (voir Options).\n",
"\n",
"Le symbole \"#\" permet d ecrire des commentaires.\n",
"\n",
"Le mot-cle \"STAT\" permet d indiquer que l on souhaite une statistique (somme, moyenne, min, max) sur ",
"l ensemble des noeuds plutot que les valeurs par noeud.\n",
"\n",
"Dans le cas a plusieurs maillages, il est tres important de les declarer dans le meme ordre que\n",
"celui dans le fichier .CVisu du calcul qui a cree le repertoire Gmsh.\n"
);
print "\n";
print "Options :\n";
print " -v : affichage du numero de version\n";
print "\n";
print " -l : affichage des grandeurs disponibles dans le repertoire \"rep_Gmsh\"\n";
print " **NB : dans ce cas, on peut lancer le script de la maniere suivante :\n";
print " > $NOM_PROG -l rep_Gmsh\n";
print "\n";
print " -trame nom_fic : genere une trame de fichier de commande\n";
print " **NB : dans ce cas, on peut lancer le script de la\n";
print " maniere suivante :\n";
print " > $NOM_PROG -trame nom_fic\n";
print "\n";
print "Auteur :\n";
print " TROUFFLARD Julien\n";
print " julien.troufflard\@free.fr\n";
print "----------------------------------------\n";
}



#------------------------------------
#pas d arguments ou option -h ou -help => affichage de l aide et arret du programme
#------------------------------------
#cas sans argument
if($#ARGV == -1) {
affichage_aide();
exit;
}
# cas option -h/-help (rq : insensible a la casse)
foreach my $arg (@ARGV) {
if(($arg =~ /^-h$/i) or ($arg =~ /^-help$/i)) {
affichage_aide();
exit;
}
}

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

#------------------------------------
#option -trame => creation du fichier de commande et arret du programme
#------------------------------------
for(my $i=0; $i<=$#ARGV; $i++) {
if($ARGV[$i] eq '-trame') {
defined($ARGV[$i+1]) or die "\n**Erreur (prog:$NOM_PROG,opt:-trame) : argument manquant (voir aide -h|-help)...\n\n";
print_fic_cmd($ARGV[$i+1]);
print "\nFichier cree : $ARGV[$i+1]\n\n";
exit;
}
}




#------------------------------------
#recuperation des arguments et options
#------------------------------------
my $rep_Gmsh;#repertoire Gmsh
my $fic_cmd;#fichier de commande
my $fic_maple_a_creer;#fichier de type .maple a creer

my $is_opt_l = 0;#indicateur de l option -l (affichage de la liste des grandeurs dispo dans le repertoire $rep_Gmsh)

#on parcourt la liste des arguments (on traite les options connues et on stocke les autres dans @args)
my $opt;
my @args;
while($#ARGV != -1) {
$opt = shift(@ARGV);

#option -l
if($opt eq '-l') {
$is_opt_l = 1;
}

#cas d une option inconnue
elsif($opt =~ /^-/) {
warn "**Attention : option $opt inconnue (on ignore cette option)...\n";
}

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



#recuperation des arguments obligatoires
#
#-on recupere d abord le repertoire Gmsh (pour appliquer directement une eventuelle option -l)
($#args >= 0) or die "\n**Erreur (prog:$NOM_PROG) : arguments manquants (voir aide : option -h ou -help)...\n\n";
$rep_Gmsh = shift(@args);
$rep_Gmsh =~ s/\/+$//;

#verif existence repertoire Gmsh
(-d $rep_Gmsh) or die "\n**Erreur (prog:$NOM_PROG) : repertoire Gmsh ($rep_Gmsh/) introuvable...\n\n";

#construction de la table des grandeurs et fichiers associes dans le repertoire Gmsh
my %table_grandeurs_rep_Gmsh;
#table de hashage : @{$table_grandeurs_rep_Gmsh{'liste_grandeurs'}} = (liste des noms de grandeur)
#
# $table_grandeurs_rep_Gmsh{nom grandeur}{'fichier'} = fichier .pos correspondant a la grandeur
# $table_grandeurs_rep_Gmsh{nom grandeur}{'nb_composantes'} = nombre de composantes de la grandeur
#
make_table_grandeurs_Gmsh($rep_Gmsh, \%table_grandeurs_rep_Gmsh);


#cas particulier : aucune grandeurs dispo
if($#{$table_grandeurs_rep_Gmsh{'liste_grandeurs'}} == -1) {
die "\n**Erreur (prog:$NOM_PROG) : aucune grandeur n a ete trouve dans le repertoire Gmsh ($rep_Gmsh/) (plus precisement, aucun fichier d extension .pos n existe dans ce repertoire)...\n\n";
}



#option -l => affichage des grandeurs disponibles et sortie du programme
if($is_opt_l) {
print "\n";
print "--------------------------------------------------------------\n";
print "Liste des grandeurs dans le repertoire $rep_Gmsh/ :\n";
print "--------------------------------------------------------------\n";
foreach my $grandeur (@{$table_grandeurs_rep_Gmsh{'liste_grandeurs'}}) {
my $fpos = basename $table_grandeurs_rep_Gmsh{$grandeur}{'fichier'};
print " - $grandeur ( fichier : $fpos )\n";
}
print "\n";
exit;
}


#-on recupere le fichier de commande et le fichier .maple a creer
($#args >= 1) or die "\n**Erreur (prog:$NOM_PROG) : arguments manquants (voir aide : option -h ou -help)...\n\n";
$fic_cmd = shift(@args);
$fic_maple_a_creer = shift(@args);


#verif existence fichier commande
(-e $fic_cmd) or die "\n**Erreur (prog:$NOM_PROG) : fichier de commande ($fic_cmd) introuvable...\n\n";



#saisie des infos dans le fichier de commande
#
# - table des fichiers maillage
my %FHER;
# table de hashage : $FHER{'nb_maillages'} = nombre de maillages
#
# $FHER{i}{'nb_noeuds'} = nombre de noeuds du maillage i
# $FHER{i}{'fichier'} = fichier .her du maillage i
#
$FHER{'nb_maillages'} = 0;


my $is_mot_cle_MAILLAGES_ok = 0;
my $is_mot_cle_SORTIES_ok = 0;

open(FIC, "<$fic_cmd");
my $nb_ligne_cmd = 0;
while(<FIC>) {
$nb_ligne_cmd++;

next if(/^\s*\#/);
s/\s*#.*$//;
next if(/^\s*$/);
next if(not /^\s*MAILLAGES\s*$/);

$is_mot_cle_MAILLAGES_ok = 1;

while(<FIC>) {
$nb_ligne_cmd++;

next if(/^\s*\#/);
s/\s*#.*$//;
next if(/^\s*$/);
if(/^\s*SORTIES\s*$/) {
$is_mot_cle_SORTIES_ok = 1;
last;
}

my ($fher) = split;
my $nb_noeuds = nb_noeuds_maillage($fher);
($nb_noeuds > 0) or die "\n**Erreur (prog:$NOM_PROG) : (ligne $nb_ligne_cmd fichier $fic_cmd) le fichier de maillage $fher n est pas valide (impossible d y saisir le nombre de noeuds)...\n\n";
$FHER{'nb_maillages'}++;
$FHER{$FHER{'nb_maillages'}}{'fichier'} = $fher;
$FHER{$FHER{'nb_maillages'}}{'nb_noeuds'} = $nb_noeuds;
}
last;
}

$is_mot_cle_MAILLAGES_ok or die "\n**Erreur (prog:$NOM_PROG) : le mot-cle MAILLAGES n a pas ete trouve dans le fichier $fic_cmd ...\n\n";
$is_mot_cle_SORTIES_ok or die "\n**Erreur (prog:$NOM_PROG) : le mot-cle SORTIES n a pas ete trouve dans le fichier $fic_cmd ...\n\n";


# - table des grandeurs a sortir
my %SORTIES;
# table de hashage : $SORTIES{'nb_sorties'} = nombre de commandes de sortie
#
# $SORTIES{i}{'no_maillage'} = numero maillage de la commande
# $SORTIES{i}{'ref_noeud'} = noeud ou nom de la liste de ref
# @{$SORTIES{i}{'liste_noeuds_her'} = liste des noeuds concernes dans les fichiers .her
# @{$SORTIES{i}{'liste_noeuds_Gmsh'} = liste des noeuds concernes dans les fichiers Gmsh (en tenant compte du decalage de la numerotation dans le cas a plusieurs maillages)
# @{$SORTIES{i}{'liste_grandeurs'}} = liste des grandeurs a sortir pour ce/ces noeud(s)
#
while(<FIC>) {
$nb_ligne_cmd++;

next if(/^\s*\#/);
s/\s*#.*$//;
next if(/^\s*$/);
next if(not /^\s*(\d+)\s*$/);

my $no_maillage = $1;
($no_maillage <= $FHER{'nb_maillages'}) or die "\n**Erreur (prog:$NOM_PROG) : (ligne $nb_ligne_cmd fichier $fic_cmd) le numero de maillage ($no_maillage) est plus grand que le nombre total de maillages ($FHER{'nb_maillages'}...\n\n";

while(<FIC>) {
$nb_ligne_cmd++;

next if(/^\s*\#/);
s/\s*#.*$//;
next if(/^\s*$/);
next if(not (/^\s*(STAT)?\s*\d+\s+\S/ or /^\s*(STAT)?\s*N\S+\s+\S/));

$SORTIES{'nb_sorties'}++;

#cas d une statistique sur les noeuds
if(/^\s*STAT\s+/) {
s/\s*STAT\s+//;
$SORTIES{$SORTIES{'nb_sorties'}}{'STAT'} = 1;
}

@_ = split;
my $ref_noeud = shift(@_);#pour l instant on ne sait pas si c est un noeud ou une liste de reference de noeuds
my @grandeurs = @_;

$SORTIES{$SORTIES{'nb_sorties'}}{'no_maillage'} = $no_maillage;
$SORTIES{$SORTIES{'nb_sorties'}}{'ref_noeud'} = $ref_noeud;

#verif ref noeud et remplissage des listes
#-- cas d un numero de noeud
if($ref_noeud =~ /^\d+$/) {
($ref_noeud <= $FHER{$no_maillage}{'nb_noeuds'}) or die "\n**Erreur (prog:$NOM_PROG) : (ligne $nb_ligne_cmd fichier $fic_cmd) le noeud $ref_noeud n existe pas dans le maillage $no_maillage (fichier $FHER{$no_maillage}{'fichier'})...\n\n";
@{$SORTIES{$SORTIES{'nb_sorties'}}{'liste_noeuds_her'}} = ($ref_noeud);
}
#-- cas d une liste de reference
else {
#lecture du maillage concerne
my ($nom_maillage, $nb_noeuds, $ref_tab_noeuds, $nb_elts, $ref_tab_elements, @ref_listes) = lecture_mail_her($FHER{$no_maillage}{'fichier'});
#-on ajoute automatiquement la reference N_tout (tous les noeuds) si elle n existe pas
if(not defined $ref_listes[0]->{'N_tout'}[0]) {
push(@{$ref_listes[0]->{'N_tout'}}, 1 .. $nb_noeuds);
}

#verif existence reference
(defined $ref_listes[0]->{$ref_noeud}[0]) or die "\nErreur (prog:$NOM_PROG) : (ligne $nb_ligne_cmd fichier $fic_cmd) liste de reference $ref_noeud n existe pas dans le maillage $no_maillage (fichier $FHER{$no_maillage}{'fichier'})...\n\n";
@{$SORTIES{$SORTIES{'nb_sorties'}}{'liste_noeuds_her'}} = @{$ref_listes[0]->{$ref_noeud}};
}

#conversion de la liste de noeuds en numerotation Gmsh
# (on applique un decalage egal a la somme des noeuds des maillages precedant le maillage $no_maillage)
my $decalage_no_noeud_Gmsh = 0;
for(my $i=1; $i<=$no_maillage-1; $i++) {$decalage_no_noeud_Gmsh += $FHER{$i}{'nb_noeuds'};}
foreach my $noeud_her (@{$SORTIES{$SORTIES{'nb_sorties'}}{'liste_noeuds_her'}}) {
push(@{$SORTIES{$SORTIES{'nb_sorties'}}{'liste_noeuds_Gmsh'}}, $noeud_her + $decalage_no_noeud_Gmsh);
}
#verif des grandeurs demandees
foreach my $grandeur (@grandeurs) {
(defined $table_grandeurs_rep_Gmsh{$grandeur}) or die "\nErreur (prog:$NOM_PROG) : (ligne $nb_ligne_cmd fichier $fic_cmd) grandeur $grandeur n existe pas dans le repertoire Gmsh $rep_Gmsh/ ...\n\n";
push(@{$SORTIES{$SORTIES{'nb_sorties'}}{'liste_grandeurs'}}, $grandeur);
}

last;
}#while(<FIC>)

}#while(<FIC>)
close(FIC);


($SORTIES{'nb_sorties'} > 0) or die "\nErreur (prog:$NOM_PROG) : aucune sortie n a ete trouve dans le fichier $fic_cmd ...\n\n";



#ecriture de l en-tete du fichier .maple
#
#
#
open(Fmaple, ">$fic_maple_a_creer");

print Fmaple "#fichier cree par le script : $NOM_PROG\n";
print Fmaple "#fichier de commande : $fic_cmd\n";
print Fmaple "#repertoire Gmsh : $rep_Gmsh/\n";
print Fmaple "#\n";
print Fmaple "#--------------------------------------\n";
print Fmaple "#lien entre grandeur et fichier .pos\n";
print Fmaple "#--------------------------------------\n";
foreach my $grandeur (@{$table_grandeurs_rep_Gmsh{'liste_grandeurs'}}) {
print Fmaple "# - $grandeur ==> fichier : $table_grandeurs_rep_Gmsh{$grandeur}{'fichier'}\n";
}
print Fmaple "#\n";
print Fmaple "#----------------------------\n";
print Fmaple "#description des colonnes\n";
print Fmaple "#----------------------------\n";
print Fmaple "#\n";
my $nb_colonnes = 1;
print Fmaple "#[$nb_colonnes] temps\n";
print Fmaple "#\n";
for(my $no_sortie=1; $no_sortie<=$SORTIES{'nb_sorties'}; $no_sortie++) {

my $fher = $FHER{$SORTIES{$no_sortie}{'no_maillage'}}{'fichier'};
my $ref_noeud = $SORTIES{$no_sortie}{'ref_noeud'};
my @grandeurs = @{$SORTIES{$no_sortie}{'liste_grandeurs'}};
my @liste_noeuds_her = @{$SORTIES{$no_sortie}{'liste_noeuds_her'}};
my @liste_noeuds_Gmsh = @{$SORTIES{$no_sortie}{'liste_noeuds_Gmsh'}};
my $is_STAT = 0; $is_STAT = 1 if(defined $SORTIES{$no_sortie}{'STAT'});

print Fmaple "#\n";
print Fmaple "#-- sortie $no_sortie --\n";
print Fmaple "# ----------------------------------\n";
print Fmaple "# > maillage : $fher\n";
print Fmaple "# > liste noeuds : $ref_noeud\n";
print Fmaple "# > liste grandeurs : @grandeurs\n";
print Fmaple "# > ==> STATISTIQUE : somme, moyenne, min, max\n" if($is_STAT);
print Fmaple "# ----------------------------------\n";

#cas d une STATISTIQUE
if($is_STAT) {
print Fmaple "# STATISTIQUE :";
foreach my $grandeur (@grandeurs) {
print Fmaple " ";
my $nb_comp = $table_grandeurs_rep_Gmsh{$grandeur}{'nb_composantes'};
if($nb_comp == 1) {
$nb_colonnes++;
print Fmaple " [$nb_colonnes] $grandeur(SOMME)";
$nb_colonnes++;
print Fmaple " [$nb_colonnes] $grandeur(MOYENNE)";
$nb_colonnes++;
print Fmaple " [$nb_colonnes] $grandeur(MIN)";
$nb_colonnes++;
print Fmaple " [$nb_colonnes] $grandeur(MAX)";
}
else {
for(my $i=1; $i<=$nb_comp; $i++) {
$nb_colonnes++;
print Fmaple " [$nb_colonnes] $grandeur(comp_$i, SOMME)";
$nb_colonnes++;
print Fmaple " [$nb_colonnes] $grandeur(comp_$i, MOYENNE)";
$nb_colonnes++;
print Fmaple " [$nb_colonnes] $grandeur(comp_$i, MIN)";
$nb_colonnes++;
print Fmaple " [$nb_colonnes] $grandeur(comp_$i, MAX)";

print Fmaple "\n# : " if($i != $nb_comp);
}
}
}
print Fmaple "\n";
}

#cas normal
else {
foreach my $no_noeud_her (@liste_noeuds_her) {
print Fmaple "# noeud\_$no_noeud_her :";
foreach my $grandeur (@grandeurs) {
print Fmaple " ";
my $nb_comp = $table_grandeurs_rep_Gmsh{$grandeur}{'nb_composantes'};
if($nb_comp == 1) {
$nb_colonnes++;
print Fmaple " [$nb_colonnes] $grandeur";
}
else {
for(my $i=1; $i<=$nb_comp; $i++) {
$nb_colonnes++;
print Fmaple " [$nb_colonnes] $grandeur(comp_$i)";
}
}
}
print Fmaple "\n";
}
}

}#for(my $no_sortie=1; $no_sortie<=$SORTIES{'nb_sorties'}; $no_sortie++)

print Fmaple "#\n";
print Fmaple "#\n";
print Fmaple "\n";



#---------------------------
#ecriture des donnees
#---------------------------

#-d abord : saisie du temps (on se base sur le fichier .pos de la premiere grandeur de la table des grandeurs)
my @liste_temps;
$_ = $table_grandeurs_rep_Gmsh{'liste_grandeurs'}[0];
my $fic = $table_grandeurs_rep_Gmsh{$_}{'fichier'};
open(FIC, "<$fic");
while(<FIC>) {
next if(not /^\s*\$nodedata\s*$/io);
for(1 .. 3) {<FIC>;}
$_ = <FIC>;
my ($temps) = split;
($temps =~ /^$format_reel$/) or die "\nErreur (prog:$NOM_PROG) : temps non conforme ($temps) ligne $. du fichier $fic ...\n\n";
push(@liste_temps, $temps);
}
close(FIC);



#-ensuite comme on va lire les fichiers nodedata par nodedata simultanement
# => on les ouvre tous via un hash de handle de fichiers
my %handle;
# => on cree la liste de noeuds (numerotation Gmsh) concernes pour chaque grandeur parmi toutes les sorties
my %liste_noeuds_Gmsh_grandeur;# @{$liste_noeuds_Gmsh_grandeur{nom grandeur}} = (liste de noeuds triee ordre croissant)
# => on creera un hash de valeur que l on rangera correctement dans l ordre des colonnes prevu
my %hash_valeurs;# $hash_valeurs{no noeud Gmsh}{grandeur}{no composante} = valeur
# (NB : no noeud Gmsh vient de la liste @{$SORTIES{no_sortie}{'liste_noeuds_Gmsh'})

#creation du handle de fichier pour chaque grandeur demandee
my %table_tmp_grandeurs_demandees;
my @liste_grandeurs_demandees;
my %handle_line_number;# (NB : hash permettant de connaitre la ligne courante de chaque fichier pour plus tard)
for(my $no_sortie=1; $no_sortie<=$SORTIES{'nb_sorties'}; $no_sortie++) {
foreach my $grandeur (@{$SORTIES{$no_sortie}{'liste_grandeurs'}}) {
if(not defined $table_tmp_grandeurs_demandees{$grandeur}) {
$table_tmp_grandeurs_demandees{$grandeur} = 1;
push(@liste_grandeurs_demandees, $grandeur);
$handle{$grandeur} = IO::File->new();
$handle{$grandeur}->open("<$table_grandeurs_rep_Gmsh{$grandeur}{'fichier'}");
$handle_line_number{$grandeur} = 0;
}
}
}

#liste de noeuds (numerotation Gmsh) concernes pour chaque grandeur parmi toutes les sorties
for(my $no_sortie=1; $no_sortie<=$SORTIES{'nb_sorties'}; $no_sortie++) {
my @grandeurs = @{$SORTIES{$no_sortie}{'liste_grandeurs'}};
my @liste_noeuds_Gmsh = @{$SORTIES{$no_sortie}{'liste_noeuds_Gmsh'}};

foreach my $grandeur (@grandeurs) {
push(@{$liste_noeuds_Gmsh_grandeur{$grandeur}}, @liste_noeuds_Gmsh);
}
}
#tri ordre croissant et suppression des doublons eventuels
foreach my $grandeur (@liste_grandeurs_demandees) {
@{$liste_noeuds_Gmsh_grandeur{$grandeur}} = sort {$a <=> $b} @{$liste_noeuds_Gmsh_grandeur{$grandeur}};
@{$liste_noeuds_Gmsh_grandeur{$grandeur}} = uniq @{$liste_noeuds_Gmsh_grandeur{$grandeur}};
}


#debut de la lecture
foreach my $temps (@liste_temps) {

#positionnement de tous les fichiers sur le prochain $nodedata (et verif du temps)
# plus exactement : on se positionnera juste avant le debut des valeurs noeud composantes... du nodedata
foreach my $grandeur (@liste_grandeurs_demandees) {
while($_ = $handle{$grandeur}->getline) {
$handle_line_number{$grandeur}++;
last if(/^\s*\$nodedata\s*$/io);
}
#verif temps
for(1 .. 3) {$handle{$grandeur}->getline; $handle_line_number{$grandeur}++;}
$_ = $handle{$grandeur}->getline; $handle_line_number{$grandeur}++;
my ($temps_) = split;
($temps_ = $temps) or die "\nErreur (prog:$NOM_PROG) : temps non conforme ($temps) ligne $handle_line_number{$grandeur} du fichier $table_grandeurs_rep_Gmsh{$grandeur}{'fichier'} ...\n\n";
#positionnement final juste avant le debut des valeurs du nodedata
for(1 .. 4) {$handle{$grandeur}->getline; $handle_line_number{$grandeur}++;}
}


#parcours de chaque grandeur
#pour l instant on parcours les noeuds de chaque sortie dans l ordre croissant et dans la numerotation Gmsh
#==> remplissage de $hash_valeurs{no noeud Gmsh}{grandeur}{no composante}
foreach my $grandeur (@liste_grandeurs_demandees) {
foreach my $no_noeud_Gmsh (@{$liste_noeuds_Gmsh_grandeur{$grandeur}}) {
while($_ = $handle{$grandeur}->getline) {
$handle_line_number{$grandeur}++;
@_ = split;
next if($_[0] != $no_noeud_Gmsh);

for(my $no_comp=1; $no_comp<=$#_; $no_comp++) {
$hash_valeurs{$no_noeud_Gmsh}{$grandeur}{$no_comp} = $_[$no_comp];
}
last;
}
}
}

#parcours de chaque sortie dans le meme ordre que l en-tete afin d ecrire les colonnes dans le bon ordre
#-ecriture du temps
print Fmaple "$temps";

#-ecriture des grandeurs pour chaque sortie
for(my $no_sortie=1; $no_sortie<=$SORTIES{'nb_sorties'}; $no_sortie++) {

my @grandeurs = @{$SORTIES{$no_sortie}{'liste_grandeurs'}};
my @liste_noeuds_Gmsh = @{$SORTIES{$no_sortie}{'liste_noeuds_Gmsh'}};
my $is_STAT = 0; $is_STAT = 1 if(defined $SORTIES{$no_sortie}{'STAT'});

#cas d une STATISTIQUE
if($is_STAT) {
foreach my $grandeur (@grandeurs) {

my $nb_comp = $table_grandeurs_rep_Gmsh{$grandeur}{'nb_composantes'};

if($nb_comp == 1) {
my $somme = 0.;
my $moyenne;
my ($min,$max);
my $nb_val = $#{$SORTIES{$no_sortie}{'liste_noeuds_Gmsh'}} + 1;
foreach my $no_noeud_Gmsh (@{$SORTIES{$no_sortie}{'liste_noeuds_Gmsh'}}) {
my $val = $hash_valeurs{$no_noeud_Gmsh}{$grandeur}{1};
$somme += $val;
$min = $max = $val if(not defined $min);
$min = $val if($val < $min);
$max = $val if($val > $max);
}
$moyenne = $somme/$nb_val;
print Fmaple " $somme $moyenne $min $max";
}
else {
for(my $i=1; $i<=$nb_comp; $i++) {
my $somme = 0.;
my $moyenne;
my ($min,$max);
my $nb_val = $#{$SORTIES{$no_sortie}{'liste_noeuds_Gmsh'}} + 1;
foreach my $no_noeud_Gmsh (@{$SORTIES{$no_sortie}{'liste_noeuds_Gmsh'}}) {
my $val = $hash_valeurs{$no_noeud_Gmsh}{$grandeur}{$i};
$somme += $val;
$min = $max = $val if(not defined $min);
$min = $val if($val < $min);
$max = $val if($val > $max);
}
$moyenne = $somme/$nb_val;
print Fmaple " $somme $moyenne $min $max";
}
}
}
}

#cas normal
else {
foreach my $no_noeud_Gmsh (@liste_noeuds_Gmsh) {
foreach my $grandeur (@grandeurs) {
my $nb_comp = $table_grandeurs_rep_Gmsh{$grandeur}{'nb_composantes'};
if($nb_comp == 1) {
print Fmaple " $hash_valeurs{$no_noeud_Gmsh}{$grandeur}{1}";
}
else {
for(my $i=1; $i<=$nb_comp; $i++) {
print Fmaple " $hash_valeurs{$no_noeud_Gmsh}{$grandeur}{$i}";
}
}
}
}
}
}#for(my $no_sortie=1; $no_sortie<=$SORTIES{'nb_sorties'}; $no_sortie++)
print Fmaple "\n";


}#foreach my $temps (@liste_temps)



close(Fmaple);

#fermeture des fichiers .pos
foreach my $grandeur (@liste_grandeurs_demandees) {
close($handle{$grandeur});
}

print "\nFichier cree : $fic_maple_a_creer\n\n";





#----------------
#subroutine make_table_grandeurs_Gmsh
#
# construction de la table de hashage des grandeurs d un repertoire Gmsh
#
# entree :
# - repertoire Gmsh
# - reference vers la table de hashage des grandeurs du repertoire Gmsh
#
sub make_table_grandeurs_Gmsh {
my $rep_Gmsh = shift;
my $ref_table_grandeurs = shift;

my @fpos;
foreach my $fichier (bsd_glob("$rep_Gmsh/*_Gmsh.pos")) {
(-T $fichier) or next;
is_fic_pos_valide($fichier) or next;

my $fichier_bn = basename $fichier;
push(@fpos, $fichier_bn);
}

my $racine_commune = chaine_commune(@fpos);

foreach my $fpos (@fpos) {
my $grandeur = $fpos;
$grandeur =~ s/^$racine_commune//;
$grandeur =~ s/_Gmsh.pos$//;
$grandeur =~ s/_ddl_noe$//;
$grandeur =~ s/_pti$//;
$grandeur =~ s/_evolue_noe$//;
$grandeur =~ s/_ddl_etendu_noe$//;

$ref_table_grandeurs->{$grandeur}{'fichier'} = "$rep_Gmsh/$fpos";
$ref_table_grandeurs->{$grandeur}{'nb_composantes'} = get_nb_comp_fpos("$rep_Gmsh/$fpos");

push(@{$ref_table_grandeurs->{'liste_grandeurs'}}, $grandeur);
}

}#sub make_table_grandeurs_Gmsh
#----------------


#----------------
#subroutine get_nb_comp_fpos
#
# saisie du nombre de composantes d une grandeur dans un fichier Gmsh .pos
#
# entree :
# - nom fichier .pos
#
# sortie :
# - nombre de composantes
#
sub get_nb_comp_fpos {
my $fpos = shift;

open(my $Hlocal, "<$fpos");
while(<$Hlocal>) {
next if(not /^\s*\$nodedata\s*$/io);
for(1 .. 6) {<$Hlocal>;}
$_ = <$Hlocal>;
my ($nb_comp) = split;
($nb_comp =~ /^\d+$/) or die "\nErreur (prog:$NOM_PROG) : impossible de lire le nombre de composantes dans le fichier $fpos ...\n\n";
close($Hlocal);
return $nb_comp;
}
close($Hlocal);

die "\nErreur (prog:$NOM_PROG) : impossible de lire le nombre de composantes dans le fichier $fpos ...\n\n";
}#sub get_nb_comp_fpos
#----------------



#----------------
#subroutine print_fic_cmd
#
# ecriture d un fichier exemple de commande
#
# entree :
# - nom fichier a creer
sub print_fic_cmd {
my $fic_cmd = shift;

open(my $Hlocal, ">$fic_cmd");
print $Hlocal "MAILLAGES #mot-cle de declaration des fichiers maillage\n";
print $Hlocal "nom_fichier_1.her\n";
print $Hlocal "nom_fichier_2.her\n";
print $Hlocal "\n";
print $Hlocal "SORTIES #mot-cle de declaration des sorties de grandeurs\n";
print $Hlocal "1 #maillage 1\n";
print $Hlocal "N_tout EPS11 SIG11 #sortie aux noeuds N_tout du maillage 1\n";
print $Hlocal "\n";
print $Hlocal "2 #maillage 2\n";
print $Hlocal "129 Def_principaleI Sigma_principaleI #sortie au noeud 129 du maillage 2\n";
print $Hlocal "\n";
print $Hlocal "1 #maillage 1\n";
print $Hlocal "N_S def_duale_mises contrainte_mises #sortie aux noeuds N_S du maillage 1\n";
print $Hlocal "\n";
print $Hlocal "1 #maillage 1\n";
print $Hlocal "STAT N_S def_duale_mises contrainte_mises #idem precedent mais cette fois on veut une STATISTIQUE sur la liste N_S\n";
close($Hlocal);
}#sub print_fic_cmd
#----------------


#----------------
#subroutine is_fic_pos_valide
#
# verification rapide de la valide d un fichier .pos (par une heuristique : presence du mot-cle $nodedata au moins une fois)
#
# entree :
# - nom fichier a verifier
#
# sortie :
# - indicateur (1 si fichier valide, sinon 0)
#
sub is_fic_pos_valide {
my $fic = shift;

open(my $Hlocal, "<$fic");
while(<$Hlocal>) {
next if(not /^\s*\$nodedata\s*$/io);
close($Hlocal);
return 1;
}
close($Hlocal);

return 0;
}#sub is_fic_pos_valide


#----------------
#subroutine nb_noeuds_maillage
#
# renvoie le nombre de noeuds si le fichier est un maillage .her valide (par une heuristique sur NOEUDS)
# sinon 0
#
# entree :
# - nom fichier
#
# sortie :
# - nombre de noeuds (ou 0 si le maillage n est pas valide)
sub nb_noeuds_maillage {
my $fher = shift;

my $nb_noeuds = 0;

open(my $Hlocal, "<$fher");
while(<$Hlocal>) {
next if(not /^\s*(\d+)\s+NOEUDS/o);
$nb_noeuds = $1;
last;
}
close($Hlocal);

return $nb_noeuds;
}#sub nb_noeuds_maillage


#----------------
#subroutine chaine_commune
#
# determine la chaine de caracteres commune a une liste de chaine de caractere (en commencant par le debut des chaines)
#
# entree :
# - liste de chaines de caracteres
#
# sortie :
# - chaine commune
#
sub chaine_commune {
my @liste = @_;

return '' if($#liste == -1);

my $chaine_commune = '';
MAIN:while(length($liste[0]) > 0) {
$liste[0] =~ s/^(.)//;
my $lettre_commune = $1;
for(my $i=1; $i<=$#liste; $i++) {
last MAIN if(length($liste[$i]) == 0);
$liste[$i] =~ s/^(.)//;
my $lettre = $1;
last MAIN if($lettre ne $lettre_commune);
}
$chaine_commune .= $lettre_commune;
}

return $chaine_commune;
}#sub chaine_commune



#----------------
#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/6)
Redmine Appliance - Powered by TurnKey Linux