Projet

Général

Profil

Perl script : viewing Herezh meshes in Gmsh » hz_visuMail.pl

version 1.024 (ajout option -lis_i : ajouter un fichier de listes de référence pour le i-ème maillage) - Julien Troufflard, 01/12/2015 18:38

 
1
#!/usr/bin/env perl
2

    
3
use strict;
4
use warnings;
5
use English;
6
use File::Spec::Functions qw(rel2abs);
7
use File::Basename;
8
my $NOM_PROG = basename $PROGRAM_NAME;
9

    
10

    
11
my $VERSION = '1.024';
12
#####################################################################################################
13
#  script pour visualiser un ou plusieurs maillages dans Gmsh                                       #
14
#  version 1.00 : version initiale                                                                  #
15
#                 (version testee sur : MacOSX Darwin, Linux Debian)                                #
16
#  version 1.01 : which du package File::Which n est plus utilise pour verifier l existence         #
17
#                 d une commande (pour eviter une erreur dans le cas ou ce package n est pas        #
18
#                 installe). A la place, on regarde la variable $PATH via la subroutine verif_cmd() #
19
#                 (version testee sur : MacOSX Darwin, Linux Debian, Linux Mint 16)                 #
20
#  version 1.02 : modification de la facon dont le calcul Herezh temporaire est lance de maniere    #
21
#                 a faciliter l arret du programme avec ctrl+c. Le signal ctrl+c est capture via    #
22
#                 $SIG{INT} et le calcul Herezh est lance dans un processus fils fork() pour        #
23
#                 permettre l application de la subroutine pointee par $SIG{INT}                    #
24
#                 ( cette modif permet de stopper l execution du programme dans le cas ou           #
25
#                   l utilisateur n a pas envie d attendre la fin d un calcul Herezh trop long )    #
26
#  version 1.021 : (((rien de special)))                                                            #
27
#                    1) il y a avait un "lectureCommandesVisu" inutile dans le calcul temporaire    #
28
#                       mais qui ne posait pas de souci. Il est supprime par securite               #
29
#                    2) ajout du pragma "use warnings;" et donc en consequence => legere modif de   #
30
#                       la subroutine lecture_mail_her() pour debugger quelques warnings            #
31
#  version 1.022 : ajout de ./ dans l appel system() d execution de Herezh via lien symbolique      #
32
#                  (car dans le cas ou le repertoire courant ne figure pas dans les PATH, ce lien   #
33
#                   symbolique qui est cree dans le repertoire courant n etait pas trouve et donc,  #
34
#                   Herezh n etait pas lance)                                                       #
35
#  version 1.023 : ajout de l option -quit (execution normale du script mais sans lancement de la   #
36
#                  visu gmsh). Typiquement, cette option est utilisee conjointement a -saveVisu, ce #
37
#                  qui permet de generer le fichier de visu, le sauvegarder et quitter              #
38
#  version 1.024 : ajout option -lis_[i] : ajout d un fichier .lis pour le maillage i               #
39
#                  exemple : -lis_2 toto.lis => ajoute les references de toto.lis pour le 2eme      #
40
#                                               maillage                                            #
41
#                  exemple : -lis_3 toto.lis -lis_3 titi.lis => ajoute les references de toto.lis   #
42
#                                                               et titi.lis pour le 3eme maillage   #
43
#####################################################################################################
44

    
45

    
46

    
47

    
48
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
49
# VARIABLES QUE L UTILISATEUR PEUT ETRE AMENE A RENSEIGNER  #
50
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
51
#
52
# les variables $exeHZ et $exeGMSH servent a imposer le choix des executables Herezh et Gmsh
53
#   (rq : les alias shell ne fonctionneront pas)
54
#
55
#commande HZ++ definie par l utilisateur (modifiable egalement avec l option -exeHZ)
56
my $exeHZ; # = 'mon_executable_a_moi';
57
#commande gmsh definie par l utilisateur (modifiable egalement avec l option -exeGMSH)
58
my $exeGMSH; # = 'mon_executable_a_moi';
59

    
60

    
61
#commande Herezh par defaut selon la plateforme
62
#  rq : ces variables seront utilisees uniquement si la variable $exeHZ n a pas ete definie
63
my $EXE_HZ_Linux64bits = 'HZppfast64';#linux 64 bits
64
my $EXE_HZ_MacOSX = 'HZppfast_Vn-1';#MacOSX
65
my $EXE_HZ_autres = 'HZppfast';#tous les autres systemes
66
#commande gmsh par defaut (quelque soit la plateforme)
67
#  rq : cette variable sera utilisee uniquement si la variable $exeGMSH n a pas ete definie
68
my $exeGMSH_defaut = 'gmsh';
69

    
70
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
71
# FIN VARIABLES UTILISATEUR                                 #
72
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
73

    
74

    
75

    
76

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

    
82
  #indentation pour l affichage de Usage 2
83
  my $indent_Usage2 = ""; $indent_Usage2 .= " " for(1 .. length("          > $NOM_PROG "));
84

    
85
  print "--------------------------------\n";
86
  print " script $NOM_PROG\n";
87
  print "--------------------------------\n";
88
  print "\n";
89
  print "But : visualiser des maillages Herezh avec Gmsh\n";
90
  print "\n";
91
  print "Usage 1 : mode interactif\n";
92
  print "          > $NOM_PROG\n";
93
  print "Usage 2 : lancement avec arguments\n";
94
  print wrap("          ",$indent_Usage2, "> $NOM_PROG [-h|help] [-v] [-exeHZ path_HZ] [-exeGMSH path_GMSH] [-saveVisu] fher_1 [fher_2 .. fher_N]\n");
95
  print "\n";
96
  print "Arguments :\n";
97
  print "     - fic_1   : 1er maillage .her\n";
98
  print "     - [fher_2 .. fher_N] : maillages .her supplementaires eventuels\n";
99
  print "\n";
100
  print "Fonctionnement :\n";
101
  print "     $NOM_PROG lance un calcul herezh pour creer un fichier .msh\n";
102
  print "   qui est ensuite visualise dans Gmsh. La visualisation des references est\n";
103
  print "   desactivee a l ouverture (exceptee la derniere vue qui est specialement\n";
104
  print "   creee par ce script pour afficher les elements en vue solide)\n";
105
  print "     Le code couleur pour les references est :\n";
106
  print "                - reference de noeuds   => rouge\n";
107
  print "                - reference d  aretes   => jaune\n";
108
  print "                - reference de faces    => vert\n";
109
  print "                - reference d  elements => bleu\n";
110
  print "                - reference de points d integration => mauve\n";
111
  print "     Dans le cas de maillages avec beaucoup d elements, la preparation des fichiers\n";
112
  print "   peut prendre du temps. Il est alors conseille d utiliser l option -saveVisu pour\n";
113
  print "   conserver les fichiers de visualisation pour pouvoir les reouvrir ulterieurment\n";
114
  print "   sans avoir a reexecuter ce script.\n";
115
  print "\n";
116
  print "Options :\n";
117
  print "   -v : affichage du numero de version\n";
118
  print "\n";
119
  print "   -exeHZ path_HZ : choisir l executable Herezh++. Le calcul Herezh se\n";
120
  print "                    fera avec l executable path_HZ\n";
121
  print "                       par defaut : linux 64 bits   => path_HZ=HZppfast64\n";
122
  print "                                    MacOSX (darwin) => path_HZ=HZppfast_Vn-1\n";
123
  print "                                    autres          => path_HZ=HZppfast\n";
124
  print "                    (a noter que les alias shell ne fonctionneront pas)\n";
125
  print "                    (a noter que cette option fonctionne aussi en mode interactif)\n";
126
  print "\n";
127
  print "   -exeGMSH path_GMSH : choisir l executable Gmsh. La visualisation Gmsh se\n";
128
  print "                        fera avec l executable path_GMSH\n";
129
  print "                         par defaut : path_GMSH=gmsh (quelque soit la plateforme)\n";
130
  print "                        (a noter que les alias shell ne fonctionneront pas)\n";
131
  print "                        (a noter que cette option fonctionne aussi en mode interactif)\n";
132
  print "\n";
133
  print "   -saveVisu  : sauvegarde des fichiers .geo et .msh de visu\n";
134
  print "\n";
135
  print "   -quit  : executer le script sans lancer la visualisation Gmsh\n";
136
  print "\n";
137
  print "   -lis_i fic.lis  : ajout de fichiers de listed de reference pour le maillage f_her_i\n";
138
  print "                     (cette option peut repetee autant de fois que necessaire)\n";
139
  print "                     exemple : $NOM_PROG -lis_1 mon_fic.lis  maillage.her\n";
140
  print "\n";
141
  print "Exemples :\n";
142
  print "   o visualiser les maillages mail1.her et mail2.her :\n";
143
  print "       > $NOM_PROG mail1.her mail2.her\n";
144
  print "   o visualiser le maillage mail1.her en choisissant l executable Herezh :\n";
145
  print "       > $NOM_PROG -exeHZ HZpp_perso mail1.her\n";
146
  print "   o visualiser le maillage mail1.her et sauvegarder les fichiers de visu :\n";
147
  print "       > $NOM_PROG -saveVisu  mail1.her\n";
148
  print "   o visualiser le maillage mail1.her en choisissant l executable Herezh et\n";
149
  print "     et l executable Gmsh (exemple dans le cas ou les executables se trouvent\n";
150
  print "     quelque part dans le HOME)\n";
151
  print "       > $NOM_PROG -exeHZ ~/mon_rep_HZ/HZpp -exeGMSH ~/mon_rep_GMSH/gmsh  mail1.her\n";
152
  print "   o creer et sauvegarder les fichiers de visualisation sans lancer la visualisation :\n";
153
  print "       > $NOM_PROG -saveVisu -quit  mail1.her\n";
154
  print "   o visualiser 2 maillages en ajoutant 2 fichiers .lis supplementaires pour le 2eme\n";
155
  print "     maillage :\n";
156
  print "       > $NOM_PROG -lis_2 ref_sup.lis -lis_2 autres_ref_sup.lis  mail1.her mail2.her\n";
157
  print "\n";
158
  print "Auteur :\n";
159
  print "   TROUFFLARD Julien\n";
160
  print "       julien.troufflard\@univ-ubs.fr\n";
161
  print "       julien.troufflard\@free.fr\n";
162
  print "--------------------------------\n";
163
}
164

    
165

    
166

    
167
#------------------------------------
168
#option -h ou -help => affichage de l aide et arret
169
#------------------------------------
170
# rq : insensible a la casse
171
foreach my $arg (@ARGV) {
172
  if(($arg =~ /^-h$/i) or ($arg =~ /^-help$/i)) {
173
    affichage_aide();
174
    exit;
175
  }
176
}
177

    
178
#------------------------------------
179
#option -v => affichage de la version et arret
180
#------------------------------------
181
foreach my $arg (@ARGV) {
182
  if($arg eq '-v') {
183
    print "\n $NOM_PROG : version $VERSION\n\n";
184
    exit;
185
  }
186
}
187

    
188

    
189

    
190
#------------------------------------
191
#recuperation des arguments et options
192
#------------------------------------
193
my @liste_fher;#liste des maillages
194
my $is_opt_saveVisu = 0;#indicateur de l option -saveVisu (sauvegarde des fichiers .geo et _Gmsh.msh de visualisation)
195
my $is_opt_quit = 0;#indicateur de l option -quit (execution normale du script excepte le fait que la visu Gmsh n est pas lancee)
196
my %FLIS_i;#table des .lis supplementaires indiques par une ou plusieurs options -lis_i
197
           #  fonctionnement de la variable :
198
           #             $FLIS_i{no maillage}{'IS_LIS_SUP'} = 1 ou non defini (sert d indicateur pour savoir si il y a des .lis supplementaires)
199
           #             @{ $FLIC_i{no maillage}{'LISTE'} } = (liste des fichiers .lis supplementaires)
200

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

    
207
  #option -exeHZ
208
  if($opt eq '-exeHZ') {
209
    ($#ARGV >= 0) or die "\nErreur (prog:$NOM_PROG,opt:-exeHZ) : pas assez d arguments donnes pour cette option...\n\n";
210
    $exeHZ = shift(@ARGV);
211
  }
212
  #option -exeGMSH
213
  elsif($opt eq '-exeGMSH') {
214
    ($#ARGV >= 0) or die "\nErreur (prog:$NOM_PROG,opt:-exeGMSH) : pas assez d arguments donnes pour cette option...\n\n";
215
    $exeGMSH = shift(@ARGV);
216
  }
217
  #option -saveVisu
218
  elsif($opt eq '-saveVisu') {
219
    $is_opt_saveVisu = 1;
220
  }
221
  #option -quit
222
  elsif($opt eq '-quit') {
223
    $is_opt_quit = 1;
224
  }
225
  #option -lis_i
226
  elsif($opt =~ /^-lis_(\d+)$/) {
227
    my $no_maillage = $1;
228
    ($#ARGV >= 0) or die "\nErreur (prog:$NOM_PROG,opt:-lis_$no_maillage) : pas assez d arguments donnes pour cette option...\n\n";
229
    my $flis_sup = shift(@ARGV);
230
    (-e $flis_sup) or die "\nErreur (prog:$NOM_PROG,opt:-lis_$no_maillage) : fichier $flis_sup introuvable...\n\n";
231
    #on retranche 1 au numero de maillage car plus loin dans le script, les numeros de maillage commence a 0 (liste de 0 a N-1 maillages)
232
    $no_maillage--;
233
    #indicateur de presence d au moins 1 fichier .lis supplementaire pour le maillage n? $no_maillage
234
    $FLIS_i{$no_maillage}{'IS_LIS_SUP'} = 1;
235
    #ajout du fichier dans la liste
236
    push(@{ $FLIS_i{$no_maillage}{'LISTE'} }, $flis_sup);
237
  }
238

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

    
244
  #autres arguments
245
  else {
246
    push(@args,$opt);
247
  }
248
}#while($#ARGV != -1)
249

    
250

    
251
#---------------------
252
#verif de l executable Herezh
253
#---------------------
254
#si la variable $exeHZ n a pas ete renseigne au prealable => on selectionne l executable par defaut en fonction de la plateforme
255
if(not defined($exeHZ)) {
256
  #- - - - - -
257
  #type de plateforme
258
  #- - - - - -
259
  my $type_OS;
260
  #-avec uname
261
  if(verif_cmd('uname')) {
262
    $type_OS = qx(uname -a);
263
    chomp($type_OS);
264
  }
265
  #-sinon : warning (OS inconnue)
266
  else {warn "**Attention : impossible de saisir le type de systeme d exploitation avec uname -a ...\n";}
267

    
268
  #selection de l executable Herezh
269
  #-linux 64 bits
270
  if($type_OS =~ /linux/i and $type_OS =~ /x86_64/i) {$exeHZ = $EXE_HZ_Linux64bits;}
271
  #-MacOSX (darwin)
272
  elsif($type_OS =~ /darwin/i) {$exeHZ = $EXE_HZ_MacOSX;}
273
  #-tous les autres (y compris linux 32 bits)
274
  else{$exeHZ = $EXE_HZ_autres;}
275
}
276
#verif de l executable Herezh
277
verif_cmd($exeHZ) or die "\n**Erreur (prog:$NOM_PROG) : executable Herezh ($exeHZ) introuvable (pour eviter cette erreur : vous pouvez soit utiliser l option -exeHZ, soit renseigner directement la commande Herezh dans la variable \$exeHZ au debut du script)...\n\n";
278

    
279
#---------------------
280
#verif de l executable Gmsh
281
#---------------------
282
#si la variable $exeGMSH n a pas ete renseigne au prealable => on selectionne l executable par defaut
283
$exeGMSH = $exeGMSH_defaut if(not defined($exeGMSH));
284
#verif de l executable Gmsh
285
verif_cmd($exeGMSH) or die "\n**Erreur (prog:$NOM_PROG) : executable Gmsh ($exeGMSH) introuvable (pour eviter cette erreur : vous pouvez soit utiliser l option -exeGMSH, soit renseigner directement la commande Gmsh dans la variable \$exeGMSH au debut du script)...\n\n";
286

    
287

    
288

    
289

    
290

    
291
#---------------------
292
#liste des maillages (on en profite pour faire des verifs sur la validite du fichier)
293
#---------------------
294
#
295
# la liste @args va servir de liste temporaire pour la saisie des noms de fichier
296
#
297
#cas avec arguments
298
if($#args >= 0) {
299
  #rien a faire pour l instant (la liste @args a deja ete remplie par les arguments)
300
}
301
#cas en mode interactif (on remplit la liste @args avec un menu interactif)
302
else {
303
  print "\nChoix des maillages a visualiser :\n";
304
  print "    (taper liste pour afficher la liste actuelle)\n";
305
  my $choix = -1;
306
  while() {
307
    print "  Donner un nom de maillage (f pour finir) : ";
308
    $choix = <STDIN>; chomp($choix);
309
    next if($choix eq '');#cas ou l utilisateur a tape "Entree"
310

    
311
    #choix f => on arrete la saisie
312
    last if($choix eq 'f');
313

    
314
    if($choix eq 'liste') {
315
      print "  Liste actuelle :\n @args\n\n" if($choix eq 'liste');
316
      next;
317
    }
318

    
319
    push(@args, $choix);
320
  }
321
  print "\n";
322
}
323
#-verif de la validite des maillages
324
foreach my $arg (@args) {
325
  $arg .= '.her' if(not $arg =~ /\.her$/);#rajout de l extension .her si manquante
326
  #existence du fichier
327
  (-e $arg) or do {warn "**Attention : fichier $arg introuvable (on ignore ce fichier)...\n"; next;};
328
  #ouverture du fichier
329
  open(FIC, "<$arg") or do {warn "**Attention : impossible d ouvrir le fichier $arg (on ignore ce fichier)...\n"; next;};
330
  #est-ce un maillage Herezh ? (verif par la presence des mots noeuds et NOEUDS)
331
  my ($is_noeuds, $is_NOEUDS) = (0,0);
332
  while(<FIC>) {
333
    $is_noeuds = 1 if(/^\s*noeuds/);
334
    $is_NOEUDS = 1 if(/^\s*\d+\s+NOEUDS/);
335
    last if($is_NOEUDS);
336
  }
337
  close(FIC);
338
  $is_noeuds or do {warn "**Attention : le fichier $arg ne contient pas le mot \"noeuds\" (on ignore ce fichier)...\n"; next;};
339
  $is_NOEUDS or do {warn "**Attention : le fichier $arg ne contient pas le mot \"NOEUDS\" (on ignore ce fichier)...\n"; next;};
340

    
341
  #fichier ok => ajout a la liste
342
  push(@liste_fher, $arg);
343
}
344

    
345
#si a ce stade, la liste des maillages est vide => on arrete le programme
346
($#liste_fher > -1) or die "\nArret du programme car aucun maillage valide n a ete fourni...\n\n";
347

    
348

    
349

    
350
#---------------------
351
#verif des maillages (constitution de la liste des noms de maillage)
352
#---------------------
353
print "  verification des maillages...\n";
354
my @liste_nom_maillage;
355
#-verif 1 : si il y a un seul maillage et qu il n a pas de nom, on indique "premier_maillage" dans la liste des noms de maillages
356
if($#liste_fher == 0) {
357
  my $nom_maillage = '';
358
  open(FIC, "<$liste_fher[0]") or die "\n**Erreur (prog:$NOM_PROG) : impossible d ouvrir le fichier $liste_fher[0] ...\n\n";
359
  while(<FIC>) {
360
    last if(/^\s*noeuds/);
361
    next if(not /^\s*nom_maillage\s+(\S+)/);
362
    $nom_maillage = $1;
363
    last;
364
  }
365
  close(FIC);
366
  $nom_maillage = 'premier_maillage' if($nom_maillage eq '');
367
  push(@liste_nom_maillage, $nom_maillage);
368
}
369

    
370
#-verif 2 : si il y a plusieurs maillages, il faut qu il ait chacun un nom_maillage different (sinon arret du programme)
371
if($#liste_fher > 0) {
372
  my $is_maillage_ok = 1;
373
  foreach my $fher (@liste_fher) {
374
    my $nom_maillage = '';
375
    open(FIC, "<$fher") or die "\n**Erreur (prog:$NOM_PROG) : impossible d ouvrir le fichier $fher ...\n\n";;
376
    while(<FIC>) {
377
      next if(not /^\s*nom_maillage\s+(\S+)/);
378
      $nom_maillage = $1;
379
      last;
380
    }
381
    close(FIC);
382
    push(@liste_nom_maillage, $nom_maillage);
383
  }
384

    
385
  my @maillages_deja_traites; for(my $i=0; $i<=$#liste_nom_maillage; $i++) {$maillages_deja_traites[$i] = 0;}
386
  for(my $i=0; $i<=$#liste_nom_maillage; $i++) {
387
    next if($maillages_deja_traites[$i]);
388

    
389
    #cas d un maillage sans nom
390
    if($liste_nom_maillage[$i] eq '') {
391
      warn "**Erreur (prog:$NOM_PROG) : le maillage $liste_fher[$i] n a pas de nom (nom_maillage non specifie)...\n";
392
      $is_maillage_ok = 0;
393
      next;
394
    }
395

    
396
    #cas d un maillage ayant le meme nom qu un ou plusieurs autres maillages
397
    my @liste_maillages_meme_nom = ();
398
    for(my $j=$i+1; $j<=$#liste_nom_maillage; $j++) {
399
      if($liste_nom_maillage[$i] eq $liste_nom_maillage[$j]) {
400
        $maillages_deja_traites[$j] = 1;
401
        push(@liste_maillages_meme_nom, $liste_fher[$j]);
402
      }
403
    }
404
    if($#liste_maillages_meme_nom > -1) {
405
      warn "**Erreur (prog:$NOM_PROG) : les maillages suivants ont le meme nom => $liste_fher[$i] @liste_maillages_meme_nom\n";
406
      $is_maillage_ok = 0;
407
    }
408
  }
409

    
410
  #arret du programme si on a trouve des maillages sans nom ou des noms utilises plusieurs fois
411
  $is_maillage_ok or die "\nArret du programme a cause d un probleme sur les noms de maillages...\n\n";
412
}
413

    
414

    
415
#---------------------
416
#listes des elements 1D, 2D et 3D (pour affecter des lois de type LOI_RIEN)
417
#---------------------
418
print "  preparation du calcul Herezh...\n";
419
#-prefixes et suffixe pour la reconnaissance des elements 1D, 2D et axisymetriques
420
my @PREFIXE_1D = qw(POUT);
421
my @PREFIXE_2D = qw(TRIA QUAD);
422
my @SUFFIXE_AXI = qw(_AXI);
423

    
424
#-table de hachage pour definir pour chaque maillage, la liste des elements 1D, 2D, 3D (rq : les elements AXI sont consideres comme 3D car il necessite une loi 3D)
425
my %TAB_DIM_LOI;#@{$TAB_DIM_LOI{indice maillage}{dim loi}} = (liste elements) (par exemple, pour le premier maillage => @{$TAB_DIM_LOI{0}{'3D'}} = (1,5,10)
426

    
427
#on boucle sur les maillages pour constituer les listes d elements par dimension de loi de comportement pour chaque maillage
428
# rq : on en profite pour reperer si il y a au moins 1 element 1D et au moins un element 2D (pour savoir si il faudra renseigner le mot-cle sections et epaisseurs)
429
my $is_elt_1D = 0;#indicateur de la presence d au moins 1 element 1D
430
my $is_elt_2D = 0;#indicateur de la presence d au moins 1 element 2D
431
my $nb_elts_tot = 0;
432
for(my $no_mail=0; $no_mail<=$#liste_fher; $no_mail++) {
433
  #saisie des elements
434
  my ($nb_elts, $ref_elements);
435
  ($_, $_, $_, $nb_elts, $ref_elements) = lecture_mail_her($liste_fher[$no_mail]);
436
  $nb_elts_tot += $nb_elts;
437
  my @ELEM_1D = ();
438
  my @ELEM_2D = ();
439
  my @ELEM_3D = ();
440
  ELEM:for(my $i=1; $i<=$nb_elts; $i++) {
441
    #verif si element AXI (=> loi LOI_RIEN3D )
442
    foreach my $suffixe (@SUFFIXE_AXI) {
443
      @_ = split(/\s+/, $ref_elements->{$i}{'TYPE'});
444
      if($_[0] =~ /$suffixe\s*$/) {
445
        push(@ELEM_3D, $i);
446
        next ELEM;
447
      }
448
    }
449
    #verif si element 1D (=> loi LOI_RIEN1D )
450
    foreach my $prefixe (@PREFIXE_1D) {
451
      if($ref_elements->{$i}{'TYPE'} =~ /^\s*$prefixe/) {
452
        push(@ELEM_1D, $i);
453
        $is_elt_1D = 1;
454
        next ELEM;
455
      }
456
    }
457
    #verif si element 2D (=> loi LOI_RIEN2D_C )
458
    foreach my $prefixe (@PREFIXE_2D) {
459
      if($ref_elements->{$i}{'TYPE'} =~ /^\s*$prefixe/) {
460
        push(@ELEM_2D, $i);
461
        $is_elt_2D = 1;
462
        next ELEM;
463
      }
464
    }
465
    #sinon, c est un element 3D (=> loi LOI_RIEN3D )
466
    push(@ELEM_3D, $i);
467
  }#FIN BOUCLE SUR LES ELEMENTS DU MAILLAGE indice $no_mail
468

    
469
  #remplissage de la table pour ce maillage
470
  push(@{$TAB_DIM_LOI{$no_mail}{'1D'}}, @ELEM_1D);
471
  push(@{$TAB_DIM_LOI{$no_mail}{'2D'}}, @ELEM_2D);
472
  push(@{$TAB_DIM_LOI{$no_mail}{'3D'}}, @ELEM_3D);
473

    
474
}#FIN BOUCLE SUR LES MAILLAGES
475

    
476

    
477

    
478
#--------------------
479
#nom des fichiers .info, .CVisu, _Gmsh.msh et .geo temporaires (on s assure qu ils n existent pas deja)
480
#--------------------
481
my $racine_fic_tmp = $NOM_PROG; $racine_fic_tmp =~ s/\.\S+$//;
482
my $no = 0;
483
$racine_fic_tmp .= "_$no";
484
my $finfo = "$racine_fic_tmp.info";#fichier de calcul temporaire
485
my $fCVisu = "$racine_fic_tmp.CVisu";#.CVisu associe
486
my $fGmsh = "$racine_fic_tmp\_Gmsh.msh";#.msh qui va etre cree apres calcul
487
my $fgeo = "$racine_fic_tmp.geo";#.geo qui sera utilise pour lancer la visu
488

    
489
while(-e $finfo or -e $fCVisu or -e $fGmsh or -e $fgeo) {
490
  $no++;
491
  $racine_fic_tmp = $NOM_PROG; $racine_fic_tmp =~ s/\.\S+$//;
492
  $racine_fic_tmp .= "_$no";
493
  $finfo = "$racine_fic_tmp.info";
494
  $fCVisu = "$racine_fic_tmp.CVisu";
495
  $fGmsh = "$racine_fic_tmp\_Gmsh.msh";
496
  $fgeo = "$racine_fic_tmp.geo";
497
}
498
#-memorisation des eventuels fichiers deja existants qui commencent comme le fichier .info (pour ne pas les effacer a la fin du script)
499
my @liste_fic_a_ne_pas_effacer = glob("$racine_fic_tmp*");
500

    
501

    
502
#####################################################################
503
# a partir de maintenant, le signal ctrl+c est recupere et gere par une subroutine pour s assurer d effacer tous les fichiers
504
#   temporaires et de tuer l eventuel processus Herezh si l utilisateur fait un ctrl+c (typiquement pour arreter un calcul Herezh trop long)
505
#####################################################################
506

    
507
#-on reperera le processus Herezh via un nom de lien symbolique genere a partir du PID du processus de ce script Perl $PID (qui sera donc unique a priori)
508
my $HZ_symbolic_link = 'HZppfast_'.$PID.'_hz_visuMail';
509
my $absolute_path_cmd = absolute_path_cmd($exeHZ);
510
#-creation du lien symbolique
511
system("ln -s $absolute_path_cmd $HZ_symbolic_link");
512
#-capture du signal ctrl+c
513
$SIG{INT} = sub {
514
  #kill des processus Herezh (on les repere grace au nom du lien symbolique $HZ_symbolic_link
515
  foreach my $processus (qx(ps -U $ENV{USER} -o pid,%cpu,command | grep $HZ_symbolic_link | grep -v grep)) {
516
    next if(not $processus =~ /^\s*(\d+)/);
517
    kill("TERM", $1);
518
  }
519

    
520
  #destruction des fichiers temporaires
521
  efface_fic_temporaires();
522

    
523
  die "\nArret du programme a cause d un ctrl+c ...\n\n";
524
};
525

    
526

    
527

    
528

    
529
#---------------------
530
#ecriture du .info
531
#---------------------
532
open(FIC, ">$finfo");
533
print FIC "dimension 3\n\n";
534

    
535
print FIC "niveau_commentaire 1\n\n";
536

    
537
#on choisit de lancer le calcul en dynamique_explicite en prevision des maillages a grand nombre de noeuds (plus rapide que non_dynamique pour faire un increment)
538
print FIC "TYPE_DE_CALCUL\ndynamique_explicite\n";
539

    
540
#ecriture des maillages et de references d elements speciales
541
for(my $no_mail=0; $no_mail<=$#liste_fher; $no_mail++) {
542
  my $fher = $liste_fher[$no_mail];
543
  my $flis = $fher; $flis =~ s/.her$/.lis/;
544
  print FIC "\n< $fher\n";
545
  print FIC "< $flis\n" if(-e $flis);#inclusion du .lis si il existe
546
  #ajout de .lis supplementaire si l option -lis_i a ete utilisee
547
  if(defined $FLIS_i{$no_mail}{'IS_LIS_SUP'}) {
548
    print FIC "< $_\n" for @{ $FLIS_i{$no_mail}{'LISTE'} };
549
  }
550
  #set d elements speciaux en fonction de la dimension de la loi de comportement
551
  #  rq : on utilise une subroutine qui ecrit les references avec 15 elements max par ligne (sinon bug Herezh si il y a trop d elements par ligne)
552
  foreach my $dim ('1D', '2D', '3D') {
553
    next if($#{$TAB_DIM_LOI{$no_mail}{$dim}} == -1);#pas d ecriture si aucun element de dimension $dim
554
    ecrire_liste_N_E(*FIC, "E_tmp_visu_elem_$dim", @{$TAB_DIM_LOI{$no_mail}{$dim}});
555
  }
556
}
557

    
558
print FIC "\nchoix_materiaux\n";
559
for(my $no_mail=0; $no_mail<=$#liste_fher; $no_mail++) {
560
  #choix materiau par dimension de loi
561
  foreach my $dim ('1D', '2D', '3D') {
562
    next if($#{$TAB_DIM_LOI{$no_mail}{$dim}} == -1);#pas d ecriture si aucun element de dimension $dim
563
    print FIC "nom_mail= $liste_nom_maillage[$no_mail] E_tmp_visu_elem_$dim MAT$dim\n";
564
  }
565
}
566

    
567
print FIC "\nmateriaux\n";
568
print FIC "MAT1D LOI_RIEN1D\nMAT2D LOI_RIEN2D_C\nMAT3D LOI_RIEN3D\n\n";
569

    
570
print FIC "masse_volumique\n";
571
for(my $no_mail=0; $no_mail<=$#liste_fher; $no_mail++) {
572
  foreach my $dim ('1D', '2D', '3D') {
573
    next if($#{$TAB_DIM_LOI{$no_mail}{$dim}} == -1);#pas d ecriture si aucun element de dimension $dim
574
    print FIC "nom_mail= $liste_nom_maillage[$no_mail] E_tmp_visu_elem_$dim 1.\n";
575
  }
576
}
577

    
578
#sections pour les eventuels elements 1D
579
if($is_elt_1D) {
580
  print FIC "\nsections\n";
581
  for(my $no_mail=0; $no_mail<=$#liste_fher; $no_mail++) {
582
    next if($#{$TAB_DIM_LOI{$no_mail}{'1D'}} == -1);#pas d ecriture si aucun element de dimension $dim
583
    print FIC "nom_mail= $liste_nom_maillage[$no_mail] E_tmp_visu_elem_1D 1.\n";
584
  }
585
}
586

    
587
#epaisseurs pour les eventuels elements 2D
588
if($is_elt_2D) {
589
  print FIC "\nepaisseurs\n";
590
  for(my $no_mail=0; $no_mail<=$#liste_fher; $no_mail++) {
591
    next if($#{$TAB_DIM_LOI{$no_mail}{'2D'}} == -1);#pas d ecriture si aucun element de dimension $dim
592
    print FIC "nom_mail= $liste_nom_maillage[$no_mail] E_tmp_visu_elem_2D 1.\n";
593
  }
594
}
595

    
596
print FIC "\ncharges\n\n";
597
print FIC "blocages\n\n";
598

    
599
#controle => un seul increment
600
print FIC "controle\n";
601
print FIC "DELTAt 1.\n";
602
print FIC "TEMPSFIN 1.\n";
603
print FIC "SAUVEGARDE 0\n";
604
print FIC "MAXINCRE 1\n";
605

    
606
print FIC "\npara_pilotage_equi_global\n\n";
607

    
608
print FIC "para_syteme_lineaire\n\n";
609

    
610
print FIC "para_affichage\nFREQUENCE_SORTIE_FIL_DU_CALCUL 1\n\n";
611

    
612
print FIC "resultats pas_de_sortie_finale_\nCOPIE 0\n\n";
613

    
614
print FIC "_fin_point_info_\n";
615
close(FIC);
616

    
617

    
618
#---------------------
619
#ecriture du .CVisu
620
#---------------------
621
open(FIC, ">$fCVisu");
622
print FIC "
623
debut_fichier_commande_visu
624

    
625
  debut_visualisation_Gmsh
626
    debut_maillage_initial
627
      actif 1
628
      pseudo-homothetie_sur_les_maillages_ 0
629
      visualisation_references_sur_les_maillages_ 1
630
    fin_maillage_initial
631

    
632
    debut_choix_maillage
633
      actif 0
634
      1";
635
for(my $i=1; $i<=$#liste_fher; $i++) {$_ = $i + 1; print FIC " $_";}
636
print FIC " fin_choix_maillage
637
  fin_visualisation_Gmsh
638

    
639
fin_fichier_commande_visu
640
";
641
close(FIC);
642

    
643

    
644

    
645
#---------------------
646
#lancement du calcul
647
#---------------------
648
#-on lance le calcul avec redirection dans un fichier .log (au cas ou le calcul a plante => on propose la lecture de ce .log a l utilisateur)
649
my $fredir = "$racine_fic_tmp.log";
650
print "  creation du fichier _Gmsh.msh (calcul Herezh en cours)...\n";
651
system("rm -f $fGmsh $fredir");
652
system("echo \'#\' > $fredir; echo \'#fichier genere suite a l execution du script $NOM_PROG\' >> $fredir; echo \'#\' >> $fredir; echo \'\' >> $fredir");#affichage d un en-tete dans le fichier .log pour indiquer que ce fichier a ete cree lors de l execution de ce script
653
#-lancement de Herezh dans un processus fils pour permettre un ctrl+c a l utilisateur (et donc le traitement de la subroutine pointee par $SIG{INT})
654
my $pid_fils = fork();
655
#---------- processus fils
656
            if($pid_fils == 0) {
657
              system("echo n | ./$HZ_symbolic_link -f $finfo >> $fredir");#on lance avec "echo n" pour repondre automatiquement "non" au cas ou il y a une erreur de calcul Herezh
658
              exit;
659
            }
660
#---------- fin du processus fils
661
#attente de la fin du processus fils par son pere
662
waitpid($pid_fils, 0);
663

    
664

    
665
#cas ou la calcul n a pas fonctionne (si le fichier _Gmsh.msh n a pas ete cree)
666
#  => on propose a l utilisateur de visualiser le .log pour savoir ce qui s est passe
667
if(not -e $fGmsh) {
668
  print "\n**Erreur (prog:$NOM_PROG) : le calcul Herezh++ n a pas fonctionne (le fichier pour Gmsh n a pas ete cree)...\n\n";
669
  my $choix = -1;
670
  while($choix ne 'o' and $choix ne 'n') {
671
    print "  Voulez-vous visualiser l affichage Herezh++ du calcul ? (o/n) ";
672
    $choix = <STDIN>; chomp($choix); $choix = lc($choix);
673
  }
674
  if($choix eq 'o') {
675
    print "  => voir fichier $fredir\n";
676
    #on ajoute le fichier .log a la liste de fichiers a ne pas effacer
677
    push(@liste_fic_a_ne_pas_effacer, $fredir);
678
  }
679

    
680
  #destruction des fichiers temporaires
681
  efface_fic_temporaires();
682

    
683
  #arret du programme
684
  die "\nArret du programme a cause d un probleme d execution Herezh++...\n\n";
685
}
686

    
687

    
688
#---------------------
689
#lecture du .msh et reecriture pour modifier les couleurs selon le type de reference (noeud, arete, face, element)
690
#  et pour saisir la liste des types de reference dans l ordre du fichier .msh pour affecter des options Gmsh suivant le type de reference
691
#---------------------
692

    
693
#on affecte une isovaleur par couleur :
694
#   - 0 => gris    (dedie a l affichage du maillage)
695
#   - 1 => bleu    (dedie a l affichage des refs d  elements)
696
#   - 2 => vert    (dedie a l affichage des refs de faces)
697
#   - 3 => jaune   (dedie a l affichage des refs d  aretes)
698
#   - 4 => rouge   (dedie a l affichage des refs de noeuds)
699
#   - 5 => mauve   (dedie a l affichage des refs de points d integration)
700
my $couleur_RGB_maillage = '{190, 190, 190, 255}';#gris
701
my $couleur_RGB_element  = '{  0,   150, 255, 255}';#bleu
702
my $couleur_RGB_face     = '{  0, 255,   0, 255}';#vert
703
my $couleur_RGB_arete    = '{240, 200,   0, 255}';#jaune
704
my $couleur_RGB_noeud    = '{255,   0,   0, 255}';#rouge
705
my $couleur_RGB_pti      = '{238, 130,   238, 255}';#mauve
706

    
707
#jeu de couleur par type de reference (on utilise les isovaleur gmsh qui vont du bleu fonce au rouge fonce en passant par le vert et le jaune)
708
#  rq : pour donner une idee des couleur, si on fixe les bornes d isovaleur entre [1:4], on a : 1.7=bleu clair, 2.5=vert, 3=>jaune, 3.6=rouge fonce
709
my %table_couleur_type_ref = ('pt_integr'=>5, 'noeud'=>4, 'arete'=>3, 'face'=>2, 'element'=>1);
710

    
711
#on va lister les types de ref
712
my @liste_type_reference;#liste des types de references
713

    
714
#fichier temporaire
715
my $ftmp = $fGmsh.rand(9999999); while(-e $ftmp) {$ftmp = $fGmsh.rand(9999999);}
716
open(FIC, "<$fGmsh");
717
open(Ftmp, ">$ftmp");
718
my $is_Element_data = 0;
719
my $couleur_type_ref;
720
print "  modification du fichier _Gmsh.msh...\n";
721
while(my $ligne = <FIC>) {
722

    
723
  #cas d un element data => on le recopie si il s agit d une reference existant reellement dans les maillages (avec la bonne isovaleur suivant le type de reference)
724
  if($ligne =~ /^\s*\$ElementData\s*$/i) {
725
    my $entete = $ligne;
726
    #on lit jusqu au nom de la reference
727
    while($ligne = <FIC>) {
728
      $entete .= $ligne;
729
      last if($ligne =~ /^\s*\"/);
730
    }
731

    
732
    #selection de l isovaleur en fonction du type de reference
733
    #-ref de noeuds
734
    if($ligne =~ /^\s*\"\s*N(\S+)/) {
735
      push(@liste_type_reference, 'noeud');
736
      $couleur_type_ref = $table_couleur_type_ref{'noeud'};
737
    }
738
    #-ref d aretes
739
    elsif($ligne =~ /^\s*\"\s*A(\S+)/) {
740
      push(@liste_type_reference, 'arete');
741
      $couleur_type_ref = $table_couleur_type_ref{'arete'};
742
    }
743
    #-ref de faces
744
    elsif($ligne =~ /^\s*\"\s*F(\S+)/) {
745
      push(@liste_type_reference, 'face');
746
      $couleur_type_ref = $table_couleur_type_ref{'face'};
747
    }
748
    #-ref d elements
749
    elsif($ligne =~ /^\s*\"\s*E(\S+)/) {
750
      push(@liste_type_reference, 'element');
751
      $couleur_type_ref = $table_couleur_type_ref{'element'};
752
    }
753
    #-ref de points d integration
754
    elsif($ligne =~ /^\s*\"\s*G(\S+)/) {
755
      push(@liste_type_reference, 'pt_integr');
756
      $couleur_type_ref = $table_couleur_type_ref{'pt_integr'};
757
    }
758

    
759
    #si le nom est une reference d elements creee par ce script => on ne l ecrit pas, on lit jusqu a la fin de l element data et on supprime cette ref de la liste @liste_type_reference
760
    if($ligne =~ /E_tmp_visu_elem_/) {
761
      while($ligne = <FIC>) {last if($ligne =~ /^\s*\$EndElementData\s*$/i);}
762
      pop(@liste_type_reference);#suppression du dernier element de la liste
763
    }
764
    #si c est une reference reellement dans le maillage, on recopie l en-tete actuel et on recopie l element data avec l isovaleur
765
    else {
766
      $is_Element_data = 1;
767
      print Ftmp $entete;
768
      while($ligne = <FIC>) {
769
        $ligne = "$1 $couleur_type_ref\n" if ($ligne =~ /^\s*(\d+)\s+\d+\s*$/);
770
        print Ftmp $ligne;
771
        last if($ligne =~ /^\s*\$EndElementData\s*$/i);
772
      }
773
    }
774
  }#if($ligne =~ /^\s*\$ElementData\s*$/i)
775

    
776
  #cas general : on recopie simplement la ligne courante
777
  else {
778
    print Ftmp $ligne;
779
  }
780
}
781
close(FIC);
782

    
783
#rajout d une ref supplementaire contenant tous les elements pour affichage des faces des elements 2D et 3D (on leur affecte l isovaleur 0, c est a dire couleur gris)
784
#  rq : les elements 1D se retrouvent egalement dans cette ref
785
print Ftmp "\$ElementData
786
1
787
\"Activer/Desactiver vue elements 2D 3D\"
788
0
789
3
790
0
791
1
792
$nb_elts_tot\n";
793
for(my $i=1; $i<=$nb_elts_tot; $i++) {
794
  print Ftmp "$i 0\n";#isovaleur 0
795
}
796
print Ftmp "\$EndElementData\n";
797
close(Ftmp);
798
system("mv -f $ftmp $fGmsh");
799

    
800

    
801
#---------------------
802
#lancement de la visu Gmsh
803
#---------------------
804
#-on cree un fichier .geo pour y ecrire dans l ordre :
805
#  - des options generales a toutes les vues
806
#  - un Merge du .msh
807
#  - des options au cas par cas par type de reference
808
open(FIC, ">$fgeo");
809

    
810
#variable donnant le nom du fichier .msh
811
print FIC "//nom du fichier .msh\n";
812
print FIC "fichier_msh = \"$fGmsh\";\n\n";
813

    
814
#-options generales
815
print FIC '
816
Geometry.Light = 0;     //desactivation de la lumiere (geometrie)
817
Mesh.Light = 0;         //desactivation de la lumiere (maillage)
818
View.Light = 0;         //desactivation de la lumiere (vue)
819
Mesh.ColorCarousel = 0; //type de couleur (0=by element type, 1=by elementary entity, 2=by physical entity, 3=by partition)
820
Geometry.Points = 0;    //affichage des points (=0 desactiver, =1 activer)
821
Mesh.Points = 0;        //affichage des noeuds (=0 desactiver, =1 activer)
822
Mesh.Lines = 1;         //affichage des lignes (elements 1D) (=0 desactiver, =1 activer)
823
Mesh.SurfaceEdges = 1;  //affichage des aretes des elements 2D (=0 desactiver, =1 activer)
824
Mesh.SurfaceFaces = 0;  //affichage des faces des elements 2D (=0 desactiver, =1 activer)
825
Mesh.VolumeEdges = 1;   //affichage des aretes des elements 3D (=0 desactiver, =1 activer)
826
Mesh.VolumeFaces = 0;   //affichage des faces des elements 3D (=0 desactiver, =1 activer)
827
View.Visible = 0;       //desactivation de toutes les vues au demarrage
828
View.ShowScale = 0;     //desactivation de la vue de l echelle d isovaleur
829
View.RangeType = 2;     //type de bornes des isovaleurs (2=Custom)
830
View.CustomMin = 0;     //borne mini isovaleur (rappel de la convention adoptee pour $NOM_PROG : 0=>maillage, 1=>element, 2=>face, 3=>arete, 4=>noeud, 5=>point integration)
831
View.CustomMax = 5;     //borne maxi isovaleur
832
View.PointType = 1;     //type d affichage des points (1=3D sphere)
833
View.PointSize = 4.;    //taille des points
834
View.LineType = 1;      //type d affichage des lignes (1=3D cylinder)
835
View.LineWidth = 3.;    //taille des lignes
836

    
837
Mesh.PointSize = 3.;   //taille des noeuds
838
Mesh.Color.Points = {0,0,0};          //on met toutes les couleurs des elements en noir pour que les noeuds et les aretes des elements soient en noir
839
Mesh.Color.Lines = {0,0,0};           // la couleur des faces des elements 2D et 3D sera geree par l isovaleur 0 (gris) de la derniere View intitulee : Activer/Desactiver vue elements 2D 3D
840
Mesh.Color.Triangles = {0,0,0};
841
Mesh.Color.Quadrangles = {0,0,0};
842
Mesh.Color.Tetrahedra = {0,0,0};
843
Mesh.Color.Hexahedra = {0,0,0};
844
Mesh.Color.Prisms = {0,0,0};
845
Mesh.Color.Pyramids = {0,0,0};
846
';
847

    
848
#echelle de couleur des isovaleurs
849
print FIC "//couleur isovaleur :  couleur 1 (gris)  => isovaleur=0 (maillage)\n";
850
print FIC "//                     couleur 2 (bleu)  => isovaleur=1 (ref elements)\n";
851
print FIC "//                     couleur 3 (vert)  => isovaleur=2 (ref faces)\n";
852
print FIC "//                     couleur 4 (jaune) => isovaleur=3 (ref aretes)\n";
853
print FIC "//                     couleur 5 (rouge) => isovaleur=4 (ref noeuds)\n";
854
print FIC "//                     couleur 6 (mauve) => isovaleur=5 (ref points integration)\n";
855
#             valeur isovaleur      0                        1                    2                  3                   4                    5
856
print FIC "View.ColorTable = {$couleur_RGB_maillage, $couleur_RGB_element, $couleur_RGB_face, $couleur_RGB_arete, $couleur_RGB_noeud, $couleur_RGB_pti};\n";
857

    
858
#-Merge du fichier .msh (rq : on passe par Sprintf pour utiliser la variable fichier_msh definie au debut)
859
print FIC "\nMerge Sprintf(fichier_msh);\n\n";
860

    
861
#on indique d afficher la vue speciale qui sert a afficher les faces des elements 2D 3D (la derniere qui a ete cree)
862
#  rq : pour cette vue, on remet l affichage classique pour les points et les lignes
863
print FIC "//options speciales pour la derniere vue qui sert a l affichage des faces des elements 2D et 3D\n";
864
$_ = $#liste_type_reference + 1;#cette vue n est pas enregistree dans la liste, son numero est donc egal a la derniere + 1
865
print FIC "View[$_].Visible = 1;\n";
866
print FIC "View[$_].PointType = 0;     //type d affichage des points (0=Color dot)\n";
867
print FIC "View[$_].PointSize = 3.;    //taille des points\n";
868
print FIC "View[$_].LineType = 0;		//type d affichage des lignes (0=Color segment)\n";
869
print FIC "View[$_].LineWidth = 1.; 	//taille des lignes\n";
870
print FIC "View[$_].Explode = 0.999;   //on reduit legerement la taille de cette vue pour eviter un conflit de couleur quand on affiche des ref de faces ou d elements par dessus\n";
871

    
872
close(FIC);
873

    
874
#lancement de la visualisation (si l option -quit a ete utilisee)
875
if($is_opt_quit) {
876
  print "\nopt -quit : pas de visualisation Gmsh...\n\n";
877
}
878
else {
879
  print "  visu Gmsh en cours (via fichiers $fgeo et $fGmsh)...\n";
880
  system("$exeGMSH $fgeo");
881
}
882

    
883
#cas de l option -saveVisu (sauvegarde des fichiers .geo et _Gmsh.msh)
884
if($is_opt_saveVisu) {
885
  #on ajoute les fichiers .geo et _Gmsh.msh a la liste des fichiers a ne pas effacer
886
  push(@liste_fic_a_ne_pas_effacer, $fgeo, $fGmsh);
887
  print "\nopt -saveVisu => Les fichiers $fgeo et $fGmsh ont ete sauvegardes...\n\n";
888
}
889

    
890
#destruction des fichiers temporaires
891
efface_fic_temporaires();
892

    
893

    
894

    
895

    
896

    
897

    
898
#rq : cette subroutine utilise les variables globales $racine_fic_tmp et @liste_fic_a_ne_pas_effacer
899
sub efface_fic_temporaires {
900
  #on transforme la liste des fichiers a ne pas effacer en table d indicateur (liste @liste_fic_a_ne_pas_effacer)
901
  my %NE_PAS_EFFACER;
902
  foreach my $fic (@liste_fic_a_ne_pas_effacer) {$NE_PAS_EFFACER{$fic} = 1;}
903
  #on saisit la liste actuelle des fichiers qui commencent comme le fichier .info
904
  my @liste_fic_actuelle = glob("$racine_fic_tmp*");
905
  #on efface seulement ceux qui n ont pas d indicateur %NE_PAS_EFFACER
906
  foreach my $fic (@liste_fic_actuelle) {
907
    system("rm -rf $fic") if(not defined($NE_PAS_EFFACER{$fic}));
908
  }
909
  #on efface le fichier inutile "ancienNom"
910
  system("rm -f ancienNom");
911

    
912
  #on efface le lien symbolique vers la commande Herezh
913
  system("rm -f $HZ_symbolic_link");
914
}
915

    
916

    
917
#surcouche de which pour traiter le cas d une commande en chemin absolu (cas qui apparemment ne marche pas avec la sub which d origine du package File::Which ??!!?!??!!!)
918
# N EST PLUS UTILISE DEPUIS LA VERSION 1.01 => A LA PLACE, ON UTILISE LA SUB verif_cmd()
919
##sub which_absolute {
920
##  use File::Which;
921
##  my $cmd = shift;
922
##  my @path;
923
##  #cas d une commande avec chemin absolu
924
##  if($cmd =~ /^\// and -x $cmd) {
925
##    @path = ($cmd);
926
##  }
927
##  #commande which classique
928
##  push(@path, which($cmd));
929
##  return(@path);
930
##}
931

    
932
#cette subroutine verifie l existence d une commande dans $PATH (remplace l utilisation de which depuis la version 1.01)
933
sub verif_cmd {
934
  my $cmd = shift;
935

    
936
  #verif directe : est-ce que le fichier existe et est executable
937
  return 1 if(-x $cmd);
938

    
939
  #sinon, on regarde dans les path
940
  foreach my $path (split(/\s*:\s*/, $ENV{PATH})) {
941
    return 1 if(-x "$path/$cmd");
942
  }
943

    
944
  #cas ou la commande n existe pas
945
  return 0;
946
}
947

    
948
#cette subroutine renvoie le chemin absolu vers une commande (renvoie 0 si commande introuvable ou non executable)
949
#  strategie :
950
#     1- si la commande commence par "." ou "/" => on renvoie simplement son path absolu
951
#     2- ensuite, on donne la priorite aux commandes presentes dans $PATH
952
#      par exemple, si la commande toto.x est presente a la fois dans le repertoire courant et dans le repertoire de $PATH /Users/Dupont/bin :
953
#                   alors si on passe la commande "toto.x" a cette subroutine, elle va renvoyer le path absolu vers le fichier present dans
954
#                   /Users/Dupont/bin. Ce qui force l utilisateur a presciser par un "./" si il veut la commande du repertoire courant "./toto.x"
955
sub absolute_path_cmd {
956
  my $cmd = shift;
957

    
958
  my $absolute_cmd = 0;
959

    
960
  #1- commande commence par "." ou "/" => on renvoie simplement son path absolu
961
  if(($cmd =~ /^\./ or $cmd =~ /^\//) and -e $cmd) {
962
    $absolute_cmd = rel2abs($cmd);
963
  }
964

    
965
  #2-
966
    #2-a : d abord dans les $PATH
967
    foreach my $path (split(/\s*:\s*/, $ENV{PATH})) {
968
      if(-e "$path/$cmd") {
969
        $absolute_cmd = rel2abs("$path/$cmd");
970
        last;
971
      }
972
    }
973
    #2-b : ensuite dans les repertoires hors $PATH
974
    if(-e $cmd) {
975
      $absolute_cmd = rel2abs($cmd);
976
    }
977

    
978

    
979
  if($absolute_cmd ne "0" and not -x $absolute_cmd) {
980
    warn "**Attention (sub:verif_commande) : la commande $cmd existe ($absolute_cmd) mais le fichier n est pas executable...\n";
981
    return 0;
982
  }
983

    
984
  return $absolute_cmd;
985
}#sub absolute_path_cmd
986

    
987

    
988
#ecrire une liste de noeuds ou d elements
989
#  rq : a priori, si on met trop de noeuds/elements sur une meme ligne, Herezh plante (donc on se limite 15 nombres par ligne)
990
sub ecrire_liste_N_E {
991
  my $handle = shift;#le handle de fichier est passe par une variable
992
  my $nom_liste = shift;
993
  my @liste_no = @_;#liste des noeuds ou d elements
994

    
995
  my $cpt; my $cpt_max = 15; my $nb_blancs;
996

    
997
  $nb_blancs = ""; $nb_blancs .= " " for(1 .. length($nom_liste));
998
  $_ = shift(@liste_no);
999
  print $handle " $nom_liste $_";
1000
  $cpt = 1;
1001
  foreach my $no (@liste_no) {
1002
    $cpt++;
1003
    if($cpt == 1) {print $handle " $nb_blancs $no";}
1004
    elsif($cpt == $cpt_max) {print $handle " $no\n"; $cpt = 0;}
1005
    else {print $handle " $no";}
1006
  }
1007
  print $handle "\n" if($cpt != $cpt_max);
1008
}#sub ecrire_liste_noeuds
1009

    
1010

    
1011
#----------------
1012
#sub qui lit un maillage herezh++ pour recuperer les noeuds, les elements et les listes de references
1013
#et les renvoier sous forme de reference (lecture du .her et d un .lis si il existe)
1014
#
1015
# exemple d appel :
1016
#  my ($nom_maillage, $nb_noeuds, $ref_tab_noeuds, $nb_elts, $ref_tab_elements, @ref_listes) = lecture_mail_her("fic_her.her");
1017
#
1018
#  avec - $nom_maillage     : nom du maillage (si il y en a un. sinon $nom_maillage sera egal a undef
1019
#       - $nb_noeuds        : nombre de noeuds (entier)
1020
#       - $ref_tab_noeuds   : reference vers un tableau de noeuds => $ref_tab_noeuds->[no noeud][0] : coordonnee x
1021
#                                                                    $ref_tab_noeuds->[no noeud][1] : coordonnee y
1022
#                                                                    $ref_tab_noeuds->[no noeud][2] : coordonnee z)
1023
#       - $nb_elts          : nombre d elements (entier)
1024
#       - $ref_tab_elements : reference vers une table de hashage => $ref_tab_elements->{no elt}{'TYPE'}      : type d element
1025
#                                                                    @{$ref_tab_elements->{no elt}{'CONNEX'}} : (liste des noeuds)
1026
#       - @ref_listes       : liste de references vers les tables de hashage contenant les listes de references de noeuds, aretes, faces et elements
1027
#                             => $ref_listes[0] : reference vers la table de hashage des listes de noeuds  => @{$ref_listes[0]->{'nom liste'}} : (liste des noeuds)
1028
#                                $ref_listes[1] : reference vers la table de hashage des listes d aretes   => @{$ref_listes[1]->{'nom liste'}} : (liste des aretes)
1029
#                                $ref_listes[2] : reference vers la table de hashage des listes de faces   => @{$ref_listes[2]->{'nom liste'}} : (liste des faces)
1030
#                                $ref_listes[3] : reference vers la table de hashage des listes d elements => @{$ref_listes[3]->{'nom liste'}} : (liste des elements)
1031
#
1032
sub lecture_mail_her {
1033
  my $fher = shift;
1034

    
1035
  $fher .= '.her' if(not $fher =~ /\.her$/);
1036

    
1037
  my $nom_maillage;
1038

    
1039
  #------------------------
1040
  # lecture du maillage .her
1041
  #------------------------
1042
  #-lecture de noeuds
1043
  my @tab_noeuds; my $nb_noeuds;
1044
  my $no_noeud = 0;
1045
  open(Fher, "<$fher") or die "\nErreur (sub:lecture_mail_her) : impossible d ouvrir le fichier $fher ...\n\n";
1046
  while(<Fher>) {
1047
    if(/^\s*nom_maillage\s+(\S+)/) {$nom_maillage = $1; next;}
1048
    next if(not /(\d+)\s+NOEUDS/);
1049
    $nb_noeuds = $1;
1050
    last;
1051
  }
1052
  while(<Fher>) {
1053
    last if($no_noeud == $nb_noeuds);
1054
    next if(not /^\s*(\d+)\s+(\S+)\s+(\S+)\s+(\S+)\s*$/);
1055
    $no_noeud = $1;
1056
    @{$tab_noeuds[$no_noeud]} = ($2,$3,$4);
1057
  }
1058

    
1059
  #-lecture des elements
1060
  my %tab_elements; my $nb_elts;
1061
  my $no_elt = 0;
1062
  while(<Fher>) {
1063
    next if(not /(\d+)\s+ELEMENTS/);
1064
    $nb_elts = $1;
1065
    last;
1066
  }
1067
  while(<Fher>) {
1068
    last if($no_elt == $nb_elts);
1069
    next if(not /^\s*\d+\s+\w+\s+\w+/);
1070
    s/^\s+//;s/\s+$//;
1071
    $_ =~ /^(\d+)\s+/;
1072
    $no_elt = $1; s/^(\d+)\s+//;
1073
    $_ =~ /\s+(\d+(?:\s+\d+)*)$/;
1074
    @{$tab_elements{$no_elt}{'CONNEX'}} = split(/\s+/, $1); s/\s+(\d+(?:\s+\d+)*)$//;
1075
    $tab_elements{$no_elt}{'TYPE'} = $_; $tab_elements{$no_elt}{'TYPE'} =~ s/\s+/ /g;
1076
  }
1077
  close(Fher);
1078

    
1079

    
1080
  #------------------------
1081
  # lecture des references (dans le .her et dans un eventuel .lis)
1082
  #------------------------
1083
  my $flis = $fher; $flis =~ s/.her$/.lis/;
1084
  my $nom_liste;
1085
  my $is_liste_en_cours;
1086
  my %listes_NOEUDS;
1087
  my %listes_ARETES;
1088
  my %listes_FACES;
1089
  my %listes_ELEMENTS;
1090

    
1091
  #-dans le .her
1092
  open(Fher, "<$fher");
1093
  $is_liste_en_cours = 0;
1094
  while(<Fher>) {
1095
    chomp;
1096
    if(/^\s*(N\S+)/) {
1097
      $nom_liste = $1;
1098
      $is_liste_en_cours = 1;
1099
      s/^\s*N\S+\s+//; s/\s+$//;
1100
      push(@{$listes_NOEUDS{$nom_liste}},split(/\s+/,$_));
1101
    }
1102
    elsif(/^\s*noeuds/i or /^\s*elements/i or /^\s*[AFE]/) {
1103
      $is_liste_en_cours = 0;
1104
    }
1105
    elsif($is_liste_en_cours and /^\s*\d+(\s+\d+)*\s*$/i) {
1106
      s/^\s+//; s/\s+$//;
1107
      push(@{$listes_NOEUDS{$nom_liste}},split(/\s+/,$_));
1108
    }
1109
  }
1110
  close(Fher);
1111

    
1112
  open(Fher, "<$fher");
1113
  $is_liste_en_cours = 0;
1114
  while(<Fher>) {
1115
    chomp;
1116
    if(/^\s*(A\S+)/) {
1117
      $nom_liste = $1;
1118
      $is_liste_en_cours = 1;
1119
      s/^\s*A\S+\s+//; s/\s+$//;
1120
      push(@{$listes_ARETES{$nom_liste}},split(/\s+/,$_));
1121
    }
1122
    elsif(/^\s*noeuds/i or /^\s*elements/i or /^\s*[NFE]/) {
1123
      $is_liste_en_cours = 0;
1124
    }
1125
    elsif($is_liste_en_cours and /^\s*\d+(\s+\d+)*\s*$/i) {
1126
      s/^\s+//; s/\s+$//;
1127
      push(@{$listes_ARETES{$nom_liste}},split(/\s+/,$_));
1128
    }
1129
  }
1130
  close(Fher);
1131

    
1132
  open(Fher, "<$fher");
1133
  $is_liste_en_cours = 0;
1134
  while(<Fher>) {
1135
    chomp;
1136
    if(/^\s*(F\S+)/) {
1137
      $nom_liste = $1;
1138
      $is_liste_en_cours = 1;
1139
      s/^\s*F\S+\s+//; s/\s+$//;
1140
      push(@{$listes_FACES{$nom_liste}},split(/\s+/,$_));
1141
    }
1142
    elsif(/^\s*noeuds/i or /^\s*elements/i or /^\s*[NAE]/) {
1143
      $is_liste_en_cours = 0;
1144
    }
1145
    elsif($is_liste_en_cours and /^\s*\d+(\s+\d+)*\s*$/i) {
1146
      s/^\s+//; s/\s+$//;
1147
      push(@{$listes_FACES{$nom_liste}},split(/\s+/,$_));
1148
    }
1149
  }
1150
  close(Fher);
1151

    
1152
  open(Fher, "<$fher");
1153
  $is_liste_en_cours = 0;
1154
  while(<Fher>) {
1155
    chomp;
1156
    if(/^\s*(E\S+)/) {
1157
      $nom_liste = $1;
1158
      $is_liste_en_cours = 1;
1159
      s/^\s*E\S+\s+//; s/\s+$//;
1160
      push(@{$listes_ELEMENTS{$nom_liste}},split(/\s+/,$_));
1161
    }
1162
    elsif(/^\s*noeuds/i or /^\s*elements/i or /^\s*[NAF]/) {
1163
      $is_liste_en_cours = 0;
1164
    }
1165
    elsif($is_liste_en_cours and /^\s*\d+(\s+\d+)*\s*$/i) {
1166
      s/^\s+//; s/\s+$//;
1167
      push(@{$listes_ELEMENTS{$nom_liste}},split(/\s+/,$_));
1168
    }
1169
  }
1170
  close(Fher);
1171

    
1172

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

    
1176
  open(Flis, "<$flis") or die "\nErreur (sub:lecture_mail_her) : impossible d ouvrir le fichier $flis ...\n\n";
1177
  $is_liste_en_cours = 0;
1178
  while(<Flis>) {
1179
    chomp;
1180
    if(/^\s*(N\S+)/) {
1181
      $nom_liste = $1;
1182
      $is_liste_en_cours = 1;
1183
      s/^\s*N\S+\s+//; s/\s+$//;
1184
      push(@{$listes_NOEUDS{$nom_liste}},split(/\s+/,$_));
1185
    }
1186
    elsif(/^\s*noeuds/i or /^\s*elements/i or /^\s*[AFE]/) {
1187
      $is_liste_en_cours = 0;
1188
    }
1189
    elsif($is_liste_en_cours and /^\s*\d+(\s+\d+)*\s*$/i) {
1190
      s/^\s+//; s/\s+$//;
1191
      push(@{$listes_NOEUDS{$nom_liste}},split(/\s+/,$_));
1192
    }
1193
  }
1194
  close(Flis);
1195

    
1196
  open(Flis, "<$flis");
1197
  $is_liste_en_cours = 0;
1198
  while(<Flis>) {
1199
    chomp;
1200
    if(/^\s*(A\S+)/) {
1201
      $nom_liste = $1;
1202
      $is_liste_en_cours = 1;
1203
      s/^\s*A\S+\s+//; s/\s+$//;
1204
      push(@{$listes_ARETES{$nom_liste}},split(/\s+/,$_));
1205
    }
1206
    elsif(/^\s*noeuds/i or /^\s*elements/i or /^\s*[NFE]/) {
1207
      $is_liste_en_cours = 0;
1208
    }
1209
    elsif($is_liste_en_cours and /^\s*\d+(\s+\d+)*\s*$/i) {
1210
      s/^\s+//; s/\s+$//;
1211
      push(@{$listes_ARETES{$nom_liste}},split(/\s+/,$_));
1212
    }
1213
  }
1214
  close(Flis);
1215

    
1216
  open(Flis, "<$flis");
1217
  $is_liste_en_cours = 0;
1218
  while(<Flis>) {
1219
    chomp;
1220
    if(/^\s*(F\S+)/) {
1221
      $nom_liste = $1;
1222
      $is_liste_en_cours = 1;
1223
      s/^\s*F\S+\s+//; s/\s+$//;
1224
      push(@{$listes_FACES{$nom_liste}},split(/\s+/,$_));
1225
    }
1226
    elsif(/^\s*noeuds/i or /^\s*elements/i or /^\s*[NAE]/) {
1227
      $is_liste_en_cours = 0;
1228
    }
1229
    elsif($is_liste_en_cours and /^\s*\d+(\s+\d+)*\s*$/i) {
1230
      s/^\s+//; s/\s+$//;
1231
      push(@{$listes_FACES{$nom_liste}},split(/\s+/,$_));
1232
    }
1233
  }
1234
  close(Flis);
1235

    
1236
  open(Flis, "<$flis");
1237
  $is_liste_en_cours = 0;
1238
  while(<Flis>) {
1239
    chomp;
1240
    if(/^\s*(E\S+)/) {
1241
      $nom_liste = $1;
1242
      $is_liste_en_cours = 1;
1243
      s/^\s*E\S+\s+//; s/\s+$//;
1244
      push(@{$listes_ELEMENTS{$nom_liste}},split(/\s+/,$_));
1245
    }
1246
    elsif(/^\s*noeuds/i or /^\s*elements/i or /^\s*[NAF]/) {
1247
      $is_liste_en_cours = 0;
1248
    }
1249
    elsif($is_liste_en_cours and /^\s*\d+(\s+\d+)*\s*$/i) {
1250
      s/^\s+//; s/\s+$//;
1251
      push(@{$listes_ELEMENTS{$nom_liste}},split(/\s+/,$_));
1252
    }
1253
  }
1254
  close(Flis);
1255

    
1256
  }#if(-e $flis)
1257

    
1258
  #AFFICHAGE DES LISTES DE NOEUDS
1259
  #foreach my $nom (keys(%listes_NOEUDS)) {
1260
  #  print "$nom : @{$listes_NOEUDS{$nom}}\n";
1261
  #}
1262
  #AFFICHAGE DES LISTES D ARETES
1263
  #foreach my $nom (keys(%listes_ARETES)) {
1264
  #  print "$nom : @{$listes_ARETES{$nom}}\n";
1265
  #}
1266
  #AFFICHAGE DES LISTES DE FACES
1267
  #foreach my $nom (keys(%listes_FACES)) {
1268
  #  print "$nom : @{$listes_FACES{$nom}}\n";
1269
  #}
1270
  #AFFICHAGE DES LISTES D ELEMENTS
1271
  #foreach my $nom (keys(%listes_ELEMENTS)) {
1272
  #  print "$nom : @{$listes_ELEMENTS{$nom}}\n";
1273
  #}
1274

    
1275
  return($nom_maillage, $nb_noeuds, \@tab_noeuds, $nb_elts, \%tab_elements,
1276
         \%listes_NOEUDS, \%listes_ARETES,
1277
         \%listes_FACES, \%listes_ELEMENTS);
1278
}#sub lecture_mail_her
(7-7/24)
Redmine Appliance - Powered by TurnKey Linux