Salome HOME
700568410b9e134690f7b84626c40eb669330a4b
[modules/homard.git] / doc / files / yacs_script.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 # Copyright (C) 2013-2016  CEA/DEN, EDF R&D
4 #
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License, or (at your option) any later version.
9 #
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # Lesser General Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 #
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #
21
22 """
23 Lancement d'un calcul ASTER
24 """
25 __revision__ = "V5.11"
26 #
27 import sys
28 import os
29 import tempfile
30 import time
31 #
32 # ==== Debut de personnalisation ====
33 #
34 # opt1_defaut, opt2_defaut : les valeurs par defaut de ces options, selon les cas
35 opt1_defaut = {}
36 opt2_defaut = {}
37 #
38 # ==== Fin de personnalisation ====
39 #
40 class Script :
41 #
42   """
43 Mode d'emploi :
44 ==============
45
46 Cette procedure lance un calcul Aster. Avant de lancer ce script, il faut avoir cree un repertoire pour le calcul. Apres un premier calcul, qui aura ete lance traditionnellement, on aura copie le fichier '*export' sous le nom 'calcul.ref.export' dans ce repertoire.
47
48 Le mode de lancement est le suivant :
49
50 ScriptAster --rep_calc=rep_calc --mesh_file=mesh_file --num=nro [-dump] [-tr [--opt1=inst_deb] [--opt2=inst_fin]] [-h|-help] [-v] [-v_max]
51
52 Arguments obligatoires :
53 ------------------------
54 --rep_calc=rep_calc : le repertoire du calcul.
55 --mesh_file=mesh_file : le fichier contenant le maillage sur lequel on veut calculer. Le nom est absolu ou relatif par rapport au repertoire de calcul ou a $HOME.
56 --num=nro : le numero du calcul, depuis 0.
57
58 Options supplementaires, selon les cas :
59 ----------------------------------------
60 . Pour un cas transitoire avec changement des instants de debut et fin :
61 On doit faire le choix -tr
62 Les numeros des instants varient de 0 a N. On fournit le numero ou l'instant selon les commandes.
63 --opt1=inst_deb : le numero ou l'instant initial ; si absent, on prend 0.
64 --opt2=inst_fin : le numero ou l'instant final ; si absent, on va jusqu'au bout du transitoire.
65 . Pour l'excavation :
66 --opt1=nro_couche : le numero de la couche ; si absent, on prend 1.
67 --opt2=nro_adap : le nombre d'adaptations deja realisees pour la couche ; si absent, on prend 0.
68 . Pour les autres cas :
69 Aucune option supplementaire.
70
71 Arguments optionnels :
72 ----------------------
73 --tr=1 : le calcul est transitoire et on change les instants ; par defaut, pas de changement.
74 --wait=wait : temps d'attente en secondes entre deux examens de l'etat d'un calcul batch ; si absent, on prend 10.
75 -dump : produit le fichier dump du fichier med de resultats ; par defaut, pas de dump.
76
77 -h|-help : produit l'aide, quels que soient les autres arguments
78 -v : mode verbeux simple
79 -v_max : mode verbeux intensif
80
81 Exemples :
82 ----------
83 ./ScriptAster.py --rep_calc=`pwd` --mesh_file=maill.00.med --num=0 -dump
84 ./ScriptAster.py --rep_calc=/scratch/D68518/HOMARD_SVN/trunk/training/tet_aster_ther --mesh_file=/scratch/D68518/Salome/Adapt/resu/maill.02.med --num=2
85   """
86 #
87 #====
88 # 0. Les defauts
89 #====
90 # 0.1. ==> Les constantes de la machine
91 #
92   info_gene = os.uname()
93   #print info_gene
94 #
95   machine = info_gene[1]
96   serveur = machine
97   mclient = machine
98 #
99 # 0.2. ==> Le user
100 #
101   if "LOGNAME" in os.environ :
102     user = os.environ ["LOGNAME"]
103   else :
104     user = "salome"
105   username = user
106   uclient = user
107 #
108 # 0.3. ==> Le lancement d'Aster
109 #
110   aster_root = None
111 #
112   nomjob = None
113   mode = None
114 # Attente en secondes entre deux controles du job
115   attente = "10"
116 #
117 # 0.4. ==> Information
118 #
119   affiche_aide_globale = 0
120   verbose = 0
121   verbose_max = 0
122   dump = 0
123 #
124   message_info = "\n"
125 #
126 #
127 #========================= Debut de la fonction ==================================
128 #
129   def __init__ ( self, liste_arg ) :
130 #
131     """
132 Le constructeur de la classe Script
133     """
134 #
135 # 1. Decodage des arguments
136 #
137     self.rep_calc = None
138     self.numero = None
139     self.mesh_file = None
140     self.opt1 = None
141     self.opt2 = None
142     self.version = None
143     self.tr = 0
144 #
145     for argu in liste_arg :
146 #
147       #print argu
148       l_aux = argu.split("=")
149       #print l_aux
150       if len(l_aux) == 2 :
151         #print l_aux[0]
152         #print l_aux[1]
153         if l_aux[0] == "--rep_calc" :
154           self.rep_calc = l_aux[1]
155         elif l_aux[0] == "--num" :
156           self.numero = int(l_aux[1])
157         elif l_aux[0] == "--mesh_file" :
158           self.mesh_file = l_aux[1]
159         elif l_aux[0] == "--tr" :
160           self.tr = l_aux[1]
161         elif l_aux[0] == "--opt1" :
162           self.opt1 = l_aux[1]
163         elif l_aux[0] == "--opt2" :
164           self.opt2 = l_aux[1]
165         elif l_aux[0] == "--wait" :
166           self.attente = l_aux[1]
167         elif l_aux[0] == "--version" :
168           self.version = l_aux[1]
169       else :
170         saux = argu.upper()
171         if saux in ( "-H", "-HELP" ) :
172           self.affiche_aide_globale = 1
173         elif saux == "-V" :
174           self.verbose = 1
175         elif saux in ( "-V_MAX", "-VMAX" ) :
176           self.verbose = 1
177           self.verbose_max = 1
178         elif saux == "-DUMP" :
179           self.dump = 1
180 #
181 # 2. Les paramètres de base
182 #
183     self.dico = {}
184     self.nomfic_export = None
185     self.nomcas = ""
186     self.numero_str = None
187 #
188     if self.verbose_max :
189       nom_fonction = __name__ + "/__init__"
190       print("\nDans " + nom_fonction + ",")
191       print(". rep_calc       :", self.rep_calc)
192       print(". mesh_file      :", self.mesh_file)
193       print(". numero         :", self.numero)
194       print(". opt1           :", self.opt1)
195       print(". opt2           :", self.opt2)
196       print(". attente        :", self.attente)
197 #
198 #=========================  Fin de la fonction ===================================
199 #
200 #========================= Debut de la fonction ==================================
201 #
202   def compute ( self ) :
203 #
204     """
205 Lancement d'un calcul
206     """
207 #
208     nom_fonction = __name__ + "/compute"
209     blabla = "\nDans " + nom_fonction + ","
210 #
211     erreur = 0
212     message_erreur = " "
213 #
214     dico_resu = {}
215 #
216     while not erreur :
217 #
218 # 1. Preparation du calcul
219 #
220       #print "\n==== self.prepa_calcul () ===="
221       erreur, message_erreur = self.prepa_calcul ()
222       if erreur :
223         break
224 #
225 # 2. Calcul
226 #
227       #print "\n==== self.calcul () ===="
228       erreur, message_erreur, fic_caract, fic_caract_2 = self.calcul ()
229       #print "erreur en sortie de self.calcul :", erreur
230       if erreur :
231         break
232 #
233 # 3. Attente
234 #
235       #print "\n==== calcul_aster_attente.calcul (",fic_caract,") ===="
236       erreur, message_erreur = self.calcul_aster_attente (fic_caract)
237       if erreur :
238         break
239       os.remove(fic_caract)
240       os.remove(fic_caract_2)
241 #
242 # 4. Gestion du resultat
243 #
244       #print "\n==== self.post_aster (dico_resu) ===="
245       erreur, message_erreur, dico_resu = self.post_aster (dico_resu)
246       if erreur :
247         break
248 #
249 # 5. Dump eventuel
250 #
251       if self.dump :
252         #print "\n==== self.dump_resultat() ===="
253         erreur, message_erreur = self.dump_resultat ()
254         if erreur :
255           break
256 #
257       break
258 #
259     if self.verbose_max :
260       print(blabla)
261       print(". erreur :", erreur)
262 #
263     return erreur, message_erreur, dico_resu
264 #
265 #=========================  Fin de la fonction ===================================
266 #
267 #========================= Debut de la fonction ==================================
268 #
269   def prepa_calcul ( self ) :
270 #
271     """
272 Preparation d'un calcul
273     """
274 #
275     nom_fonction = __name__ + "/prepa_calcul"
276     blabla = "\nDans " + nom_fonction + ","
277 #
278     erreur = 0
279     message_erreur = " "
280 #
281     if self.verbose_max :
282       print(blabla)
283       print(". rep_calc       :", self.rep_calc)
284       print(". mesh_file      :", self.mesh_file)
285       print(". tr             :", self.tr)
286 #
287     while not erreur :
288 #
289 # 1. Controles des arguments
290 #
291       erreur, message_erreur = self.controle_argument()
292       if erreur :
293         break
294 #
295 # 2. Modification du fichier export
296 #
297       erreur, message_erreur = self.modif_export()
298       if erreur :
299         break
300 #
301 # 3. Modifications du fichier de commandes
302 # 3.1. Pour un cas transitoire
303 #
304       if self.tr :
305         erreur, message_erreur = self.modif_cas_transitoire()
306         if erreur :
307           break
308 #
309 # 3.2. Pour l'excavation
310 #
311       elif self.nomcas[:6] == "couche" :
312         erreur, message_erreur = self.modif_cas_excavation()
313         if erreur :
314           break
315 #
316       break
317 #
318     if self.verbose_max :
319       print(blabla, "a la fin")
320       print(". erreur :", erreur)
321 #
322     return erreur, message_erreur
323 #
324 #=========================  Fin de la fonction ===================================
325 #
326 #========================= Debut de la fonction ==================================
327 #
328   def controle_argument ( self ) :
329 #
330     """
331 Controle les arguments et stockage de quelques informations
332     """
333 #
334     messages_erreur = { 0 : None,
335                        -1 : "Quel repertoire de calcul ?",
336                        -3 : "Quel fichier de maillage ?",
337                        -4 : "Ce repertoire est inconnu.",
338                        -5 : "Ce fichier est inconnu.",
339                        -8 : "Quel temps d'attente ?",
340                        -9 : "Quel numero de calcul ?",
341                       -20 : "Numeros de pas de temps invalides.",
342                       -30 : "Numero de couche invalide.",
343                       -31 : "Numero d'adaptation invalide." }
344 #
345     nom_fonction = __name__ + "/controle_argument"
346     blabla = "\nDans " + nom_fonction + ","
347 #
348     erreur = 0
349     message_erreur = " "
350 #
351     if self.verbose_max :
352       print(blabla)
353       print(". rep_calc       :", self.rep_calc)
354       print(". mesh_file      :", self.mesh_file)
355       print(". numero         :", self.numero)
356       print(". tr             :", self.tr)
357       print(". opt1           :", self.opt1)
358       print(". opt2           :", self.opt2)
359       print(". attente        :", self.attente)
360 #
361     while not erreur :
362 #
363 # 1. Les repertoire et fichier
364 # 1.1. Il y a bien eu une donnee
365 #
366       if self.rep_calc == None :
367         erreur = -1
368       elif self.mesh_file == None :
369         erreur = -3
370       if erreur < 0 :
371         self.message_info += "Relancer avec -h pour avoir le mode d'emploi."
372         break
373 #
374 # 1.2. Le repertoire de calcul
375 #
376       if "HOME" in os.environ :
377         HOME = os.environ ["HOME"]
378       else :
379         HOME = "/local/home/salome"
380 #
381       if ( self.rep_calc[:1] == "~" ) :
382         self.rep_calc = os.path.join(HOME, self.rep_calc[2:])
383       if not os.path.isdir(self.rep_calc) :
384         self.message_info += "Repertoire " + self.rep_calc
385         erreur = -4
386         break
387       else :
388         aux = os.path.join(os.getcwd(), self.rep_calc)
389         self.rep_calc = os.path.normpath(aux)
390 #
391 # 1.3. Les fichiers
392 #
393       fic = self.mesh_file
394 #
395       if ( fic[:1] == "~" ) :
396         fic = os.path.join(HOME, fic[2:])
397       if not os.path.isfile(fic) :
398         aux = os.path.join(self.rep_calc, fic)
399         if not os.path.isfile(aux) :
400           self.message_info += "Fichier : " + fic
401           erreur = -5
402           break
403         else :
404           fic = os.path.normpath(aux)
405       aux = os.path.join(os.getcwd(), fic)
406 #
407       self.mesh_file = os.path.normpath(aux)
408 #
409 # 2. On en deduit le cas
410 #
411       self.nomcas = os.path.basename(self.rep_calc)
412       if self.verbose_max :
413         print(". Cas :", self.nomcas)
414 #
415 # 3. Le temps d'attente
416 #
417       iaux = None
418       try :
419         iaux = int(self.attente)
420       except :
421         erreur = -8
422         break
423       self.attente = iaux
424 #
425 # 4. Le numero du calcul
426 #
427       if self.numero == None :
428         erreur = -9
429 #
430       if ( self.numero < 100 ) :
431         self.numero_str = "%02d" % self.numero
432       elif ( self.numero < 1000 ) :
433         self.numero_str = "%03d" % self.numero
434       elif ( self.numero < 10000 ) :
435         self.numero_str = "%04d" % self.numero
436       else :
437         self.numero_str = "%d" % self.numero
438 #
439 # 5. Options speciales pour les cas transitoires et pour l'excavation
440 #
441       if ( self.tr or ( self.nomcas[:6] == "couche" ) ) :
442 #
443         if self.opt1 == None :
444           self.opt1 = opt1_defaut[self.nomcas]
445           #print ". opt1 defaut :", self.opt1
446 #
447         if self.opt2 == None :
448           self.opt2 = opt2_defaut[self.nomcas]
449           #print ". opt2 defaut :", self.opt2
450 #
451 # 5.1. Pour un cas transitoire
452 #
453       if self.tr :
454 #
455         iaux1 = None
456         daux1 = None
457         try :
458           iaux1 = int(self.opt1)
459         except :
460           daux1 = float(self.opt1)
461         if ( iaux1 == 0 ) :
462           daux1 = 0.
463 #
464         iaux2 = None
465         daux2 = None
466         try :
467           iaux2 = int(self.opt2)
468         except :
469           daux2 = float(self.opt2)
470 #
471         if ( ( daux1 == None ) or  ( daux2 == None ) ) :
472           #print "------------ ( daux1 == None ) or  ( daux2 == None ) ------------"
473           #print "iaux1, iaux2 =", iaux1, iaux2
474           if iaux2 < iaux1 :
475             erreur = -20
476         elif ( ( iaux1 == None ) or  ( iaux2 == None ) ) :
477           #print "------------ ( iaux1 == None ) or  ( iaux2 == None ) ------------"
478           #print "daux1, daux2 =", daux1, daux2
479           if daux2 < daux1 :
480             erreur = -20
481         else :
482           erreur = -20
483 #
484         if erreur :
485           self.message_info += "opt1 = " + self.opt1
486           self.message_info += "\nopt2 = " + self.opt2
487 #
488 # 5.2. Pour l'excavation
489 #
490       elif self.nomcas[:6] == "couche" :
491 #
492         iaux1 = None
493         try :
494           iaux1 = int(self.opt1)
495         except :
496           erreur = -30
497 #
498         if ( ( iaux1 < 1 ) or ( iaux1 > 20 ) ) :
499           #print "iaux1 =", iaux1
500           erreur = -30
501 #
502         iaux2 = None
503         try :
504           iaux2 = int(self.opt2)
505         except :
506           erreur = -31
507 #
508         if ( iaux2 < 0 ) :
509           #print "iaux1 =", iaux1
510           erreur = -31
511 #
512         if erreur :
513           self.message_info += "nro_mail = " + self.numero
514           self.message_info += "\nopt1 = " + self.opt1
515           self.message_info += "\nopt2 = " + self.opt2
516           break
517 #
518         self.nro_couche = iaux1
519         self.nro_adap = iaux2
520 #
521       break
522 #
523     if erreur :
524       message_erreur = messages_erreur[erreur]
525 #
526     if self.verbose_max :
527       print(". rep_calc  :", self.rep_calc)
528       print(". mesh_file :", self.mesh_file)
529       print(". opt1      :", self.opt1)
530       print(". opt2      :", self.opt2)
531 #
532     return erreur, message_erreur
533 #
534 #=========================  Fin de la fonction ===================================
535 #
536 #========================= Debut de la fonction ==================================
537 #
538   def modif_export ( self ) :
539 #
540     """
541 Modification du fichier export et reperage de quelques informations
542     """
543 #
544     messages_erreur = { 0 : None }
545 #
546     nom_fonction = __name__ + "/modif_export"
547     blabla = "\nDans " + nom_fonction + ","
548 #
549     erreur = 0
550     message_erreur = " "
551 #
552     if self.verbose_max :
553       print(blabla)
554       print(". numero     :", self.numero)
555       print(". mesh_file  :", self.mesh_file)
556 #
557     while not erreur :
558 #
559 # 1. Lecture du fichier export original
560 #
561       fic_export_ref = os.path.join(self.rep_calc, "calcul.ref.export")
562       fic = open (fic_export_ref, "r")
563       les_lignes = fic.readlines()
564       fic.close()
565 #
566 # 2. Ouverture du nouveau fichier export
567 #
568       nomfic = "calcul"
569       if self.nomcas[:6] == "couche" :
570         nomfic += ".%02d" % self.nro_couche
571       nomfic += "." + self.numero_str + ".export"
572       self.nomfic_export = os.path.join(self.rep_calc, nomfic)
573       if self.verbose_max :
574         print(". nouveau fic_export :", self.nomfic_export)
575       fic = open (self.nomfic_export, "w")
576 #
577 # 3. Exploration des lignes
578 #
579       for ligne in les_lignes :
580 #
581 # 3.1. Pas de modification, a priori
582 #
583         ligne_bis = ligne
584         saux = ""
585 #
586 # 3.2. Decodage des composants de la ligne pour un fichier
587 #
588         if ligne[0:2] == "F " :
589 #
590           chgt = False
591 #
592           laux = ligne.split()
593           #print laux
594           typfic = laux[1]
595           statut = laux[3]
596           #print typfic
597 #
598           nomfic_0 = laux[2]
599           if ( ":" in nomfic_0 ) :
600             laux1 = nomfic_0.split(":")
601             saux = laux1[0] + ":"
602             nomfic_0 = laux1[1]
603 #
604 # 3.2.1. Si c'est le fichier de commandes, mise a jour du nom du repertoire
605 #
606           if ( typfic == "comm" ) :
607 #
608             if self.verbose_max :
609               print(". Commandes : mise a jour du nom du repertoire")
610             chgt = True
611             nomfic_l_0 = os.path.basename(nomfic_0)
612             nomfic = os.path.join(self.rep_calc, nomfic_l_0)
613 #
614 # 3.2.2. Si c'est un fichier de resultats ou le fichier de maillage, mise a jour du nom
615 #
616           elif ( ( statut == "R" ) or ( typfic == "mmed" ) ) :
617             if self.verbose_max :
618               print(". Mise a jour du nom")
619             chgt = True
620 #
621 # 3.2.2.1. Le fichier de maillage est celui passe en argument
622 #
623             if typfic == "mmed" :
624               nomfic = self.mesh_file
625 #
626 # 3.2.2.2. Pour les autres fichiers, on recupère le nom initial
627 #
628             else :
629               nomfic_l_0 = os.path.basename(nomfic_0)
630               laux1 = nomfic_l_0.split(".")
631               #print "laux1 =", laux1
632 #
633 # 3.2.2.2.1. Base des noms de fichiers si excavation
634 #
635               if laux1[0] == "couche_n" :
636                 saux0 = "couche_%02d" % self.nro_couche
637               else :
638                 iaux = len(laux1[-1]) + 1
639                 saux0 = nomfic_l_0[:-iaux]
640               #print "saux0 =", saux0
641 #
642 # 3.2.2.2.2. Indicage des fichiers
643 #
644               nomfic_l = saux0 + "." + self.numero_str + "." + laux1[-1]
645               nomfic_l_1 = os.path.dirname(nomfic_0)
646               nomfic = os.path.join(nomfic_l_1, nomfic_l)
647             #print "   ==> ", nomfic
648 #
649           if chgt :
650             ligne_bis  = laux[0] + " " + laux[1] + " " + saux
651             ligne_bis += nomfic + " "
652             ligne_bis += laux[3] + " " + laux[4] + "\n"
653 #
654 # 3.2.2.3. On detruit preventivement les fichiers des resultats
655 #
656           if ( statut == "R" ) :
657             if ( self.nomcas[:6] != "couche" ) :
658               if os.path.isfile(nomfic) :
659                 os.remove(nomfic)
660 #
661 # 3.2.3. Memorisation des noms
662 #
663           self.dico[typfic] = nomfic
664 #
665 # 3.3. Decodage des composants de la ligne pour la base
666 #
667         elif ligne[0:2] == "R " :
668 #
669           laux = ligne.split()
670           #print laux
671           typfic = laux[1]
672           #print typfic
673 #
674 # 3.3.1. Si c'est le fichier de la base, on recupere le nom initial, en ajustant l'indice
675 #
676           if typfic in ( "base", "bhdf" ) :
677 #
678             nomfic_0 = laux[2]
679             if ( ":" in nomfic_0 ) :
680               laux1 = nomfic_0.split(":")
681               saux = laux1[0] + ":"
682               nomfic_0 = laux1[1]
683             nomfic_l_0 = os.path.basename(nomfic_0)
684             laux1 = nomfic_l_0.split(".")
685             if len(laux1) >= 3 :
686               nomfic_l = laux1[0] + "." + self.numero_str + "." + laux1[2]
687             elif len(laux1) >= 2 :
688               if laux1[0] == "couche_nm1" :
689                 saux0 = "couche_%02d" % (self.nro_couche-1)
690               elif laux1[0] == "couche_n" :
691                 saux0 = "couche_%02d" % self.nro_couche
692               else :
693                 saux0 = laux1[0]
694               nomfic_l = saux0 + "." + laux1[1]
695             else :
696               nomfic_l = nomfic_l_0
697             nomfic_l_1 = os.path.dirname(nomfic_0)
698             nomfic = os.path.join(nomfic_l_1, nomfic_l)
699 #
700             ligne_bis  = laux[0] + " " + laux[1] + " " + saux
701             ligne_bis += nomfic + " "
702             ligne_bis += laux[3] + " " + laux[4] + "\n"
703 #
704 # 3.4. Decodage des composants de la ligne pour un parametre
705 #
706         elif ligne[0:2] == "P " :
707 #
708           laux = ligne.split()
709           #print laux
710           if ( len(laux) == 3 ) :
711             aux = laux[2]
712             if laux[1] in ( "username" ) :
713               self.username = aux
714             elif laux[1] in ( "uclient" ) :
715               self.uclient = aux
716             elif laux[1] in ( "aster_root" ) :
717               self.aster_root = aux
718             elif laux[1] in ( "serveur" ) :
719               self.serveur = aux
720             elif laux[1] in ( "mclient" ) :
721               self.mclient = aux
722             #elif laux[1] in ( "display" ) :
723               #aux = self.machine+":0.0"
724             elif laux[1] in ( "nomjob" ) :
725               self.nomjob = aux
726             elif laux[1] in ( "mode" ) :
727               self.mode = aux
728             ligne_bis  = laux[0] + " " + laux[1] + " " + aux  + "\n"
729 #
730 # 3.5. Ecriture de la ligne
731 #
732         fic.write(ligne_bis)
733 #
734       fic.close()
735 #
736       break
737 #
738     if erreur :
739       message_erreur = messages_erreur[erreur]
740 #
741     if self.verbose_max :
742       print(". mclient    ", self.mclient)
743       print(". uclient    ", self.uclient)
744       print(". serveur    ", self.serveur)
745       print(". username   ", self.username)
746       print(". aster_root ", self.aster_root)
747       print(". nomjob     ", self.nomjob)
748       print(". mode       ", self.mode)
749 #
750     return erreur, message_erreur
751 #
752 #=========================  Fin de la fonction ===================================
753 #
754 #========================= Debut de la fonction ==================================
755 #
756   def modif_cas_transitoire ( self ) :
757 #
758     """
759 Modification du fichier de commandes lie au cas transitoire
760     """
761 #
762     messages_erreur = { 0 : None,
763                         2 : "Mot_cle inconnu dans les commandes." }
764 #
765     nom_fonction = __name__ + "/modif_cas_transitoire"
766     blabla = "\nDans " + nom_fonction + ","
767 #
768     erreur = 0
769     message_erreur = " "
770 #
771     if self.verbose_max :
772       print(blabla)
773       print(". opt1 :", self.opt1)
774       print(". opt2 :", self.opt2)
775 #
776     while not erreur :
777 #
778 # 1. Lecture du fichier de commandes
779 #
780       nomfic = os.path.join(self.rep_calc, self.dico["comm"])
781       fic = open (nomfic, "r")
782       les_lignes = fic.readlines()
783       fic.close()
784 #
785 # 2. Ouverture du nouveau fichier de commandes
786 #
787       fic = open (nomfic, "w")
788 #
789 # 3. Exploration des lignes
790 #
791 # 3.0. Reperage de la zone a modifier
792 #
793       A_modifier = 0
794 #
795       for ligne in les_lignes :
796 #
797         if self.verbose_max :
798           print("ligne =", ligne[:-1])
799 #
800 # 3.1. Pas de modification, a priori
801 #
802         ligne_bis = ligne
803 #
804 # 3.2. Reperage de la zone a modifier
805 #
806         if ( "A PERSONNALISER - DEBUT" in ligne ) :
807           A_modifier = 1
808         elif ( "A PERSONNALISER - FIN" in ligne ) :
809           A_modifier = 0
810 #
811 # 3.3. Modification
812 #
813         #print "A_modifier =", A_modifier
814         if A_modifier :
815 #
816           #print "ligne =", ligne[:-1]
817           for iaux in range(2) :
818             if iaux == 0 :
819               mot_cle_ref = "NUME_INST_"
820               lg_mot_cle = 10
821             else :
822               mot_cle_ref = "INST_"
823               lg_mot_cle = 5
824             #print "mot_cle_ref =", mot_cle_ref
825 #
826             if ligne[0:lg_mot_cle] == mot_cle_ref :
827 #
828               if ligne[lg_mot_cle:lg_mot_cle+4] == "INIT" :
829                 aux = self.opt1
830                 motcle = ligne[0:lg_mot_cle+4]
831               elif ligne[lg_mot_cle:lg_mot_cle+3] == "FIN" :
832                 aux = self.opt2
833                 motcle = ligne[0:lg_mot_cle+3]
834               else :
835                 self.message_info += ligne
836                 erreur = 2
837                 break
838 #
839               ligne_bis = motcle + " = " + str(aux) +"\n"
840 #
841           if erreur :
842             break
843 #
844 # 3.4. Ecriture de la ligne
845 #
846         fic.write(ligne_bis)
847 #
848       fic.close()
849 #
850       break
851 #
852 # 4. Gestion des erreurs
853 #
854     if erreur :
855       message_erreur = messages_erreur[erreur]
856 #
857     return erreur, message_erreur
858 #
859 #=========================  Fin de la fonction ===================================
860 #
861 #========================= Debut de la fonction ==================================
862 #
863   def modif_cas_excavation ( self ) :
864 #
865     """
866 Modification du fichier de commandes lie au cas de l'excavation
867     """
868 #
869     messages_erreur = { 0 : None }
870 #
871     nom_fonction = __name__ + "/modif_cas_excavation"
872     blabla = "\nDans " + nom_fonction + ","
873 #
874     erreur = 0
875     message_erreur = " "
876 #
877     if self.verbose_max :
878       print(blabla)
879       print(". numero     :", self.numero)
880       print(". nro_couche :", self.nro_couche)
881       print(". nro_adap   :", self.nro_adap)
882 #
883     while not erreur :
884 #
885 # 1. Lecture du fichier de commandes
886 #
887       nomfic = os.path.join(self.rep_calc, self.dico["comm"])
888       fic = open (nomfic, "r")
889       les_lignes = fic.readlines()
890       fic.close()
891 #
892 # 2. Ouverture du nouveau fichier de commandes
893 #
894       fic = open (nomfic, "w")
895 #
896 # 3. Exploration des lignes
897 #
898 # 3.0. Reperage de la zone a modifier
899 #
900       A_modifier = 0
901 #
902       for ligne in les_lignes :
903 #
904         if self.verbose_max :
905           print("ligne =", ligne[:-1])
906 #
907 # 3.1. Pas de modification, a priori
908 #
909         ligne_bis = ligne
910 #
911 # 3.2. Reperage de la zone a modifier
912 #
913         if ( "A PERSONNALISER - DEBUT" in ligne ) :
914           A_modifier = 1
915         elif ( "A PERSONNALISER - FIN" in ligne ) :
916           A_modifier = 0
917 #
918 # 3.3. Modification
919 #
920         #print "A_modifier =", A_modifier
921         if A_modifier :
922 #
923           #print "ligne =", ligne[:-1]
924           for iaux in range(3) :
925             if iaux == 0 :
926               mot_cle_ref = "nro_mail"
927               lg_mot_cle = 8
928               aux = self.numero
929             elif iaux == 1 :
930               mot_cle_ref = "nro_couche"
931               lg_mot_cle = 10
932               aux = self.nro_couche
933             elif iaux == 2 :
934               mot_cle_ref = "nro_adap"
935               lg_mot_cle = 8
936               aux = self.nro_adap
937             #print "mot_cle_ref =", mot_cle_ref
938 #
939             if ligne[0:lg_mot_cle] == mot_cle_ref :
940               #print "==> aux =", aux, type(aux)
941               ligne_bis = mot_cle_ref + " = " + str(aux) +"\n"
942 #
943 # 3.4. Ecriture de la ligne
944 #
945         fic.write(ligne_bis)
946 #
947       fic.close()
948 #
949       break
950 #
951 # 4. Gestion des erreurs
952 #
953     if erreur :
954       message_erreur = messages_erreur[erreur]
955 #
956     return erreur, message_erreur
957 #
958 #=========================  Fin de la fonction ===================================
959 #
960 #========================= Debut de la fonction ==================================
961 #
962   def calcul ( self ) :
963 #
964     """
965 Lancement d'un calcul
966     """
967 #
968     messages_erreur = { 0 : None }
969 #
970     nom_fonction = __name__ + "/calcul"
971     blabla = "\nDans " + nom_fonction + ","
972 #
973     erreur = 0
974     message_erreur = " "
975 #
976     if self.verbose_max :
977       print(". mclient    ", self.mclient)
978       print(". serveur    ", self.serveur)
979 #
980 # 1. Copie du fichier export sur le serveur de calcul
981 #
982     if ( self.mclient != self.serveur ) :
983 #
984       nomfic_export_dist = self.nomjob + ".export"
985       commande = "scp " + self.nomfic_export + " " + self.username + "@" + self.serveur + ":" + nomfic_export_dist
986       if self.verbose_max :
987         print("Copie du fichier export vers", self.serveur, ":")
988         print(commande)
989       erreur = os.system(commande)
990 #
991 # 2. Commande du lancement
992 #
993     commande_base  = os.path.join(self.aster_root, "bin", "as_run")
994     commande_base += " "
995     if self.mode == "batch" :
996       commande_base += "--serv "
997     commande_base += self.username + "@" + self.serveur + ":"
998     #if self.verbose_max :
999       #print commande_base
1000 #
1001     t_aux = tempfile.mkstemp()
1002     fic_caract   = t_aux[1]
1003     t_aux = tempfile.mkstemp()
1004     fic_caract_2 = t_aux[1]
1005 #
1006 # 3. Lancement
1007 # 3.1. Commande finale
1008 #
1009     if ( self.mclient == self.serveur ) :
1010       commande  = commande_base
1011       commande += commande_base + self.nomfic_export
1012     else :
1013       commande  = "ssh " + self.username + "@" + self.serveur
1014       commande += " \"" + commande_base + nomfic_export_dist + "\""
1015     commande += " 1>" + fic_caract
1016     commande += " 2>" + fic_caract_2
1017     if self.verbose_max :
1018       print("Lancement sur", self.serveur, ":")
1019       print(commande)
1020 #
1021 # 3.2. Lancement vrai
1022 #
1023     erreur = os.system(commande)
1024     if erreur :
1025       messages_erreur[erreur] = "erreur de calcul numero %d" % erreur
1026     else :
1027       self.message_info += "resultat dans le fichier :\n"
1028       #print self.dico
1029       self.message_info += self.dico["rmed"]+"\n"
1030 #
1031     if self.verbose_max :
1032       print(blabla)
1033       print(". erreur     :", erreur)
1034       print(". self.mode  :", self.mode)
1035       print(". fic_caract :", fic_caract)
1036 #
1037     if erreur :
1038       message_erreur = messages_erreur[erreur]
1039 #
1040     return erreur, message_erreur, fic_caract, fic_caract_2
1041 #
1042 #=========================  Fin de la fonction ===================================
1043 #
1044 #========================= Debut de la fonction ==================================
1045 #
1046   def calcul_aster_attente ( self, fic_caract ) :
1047 #
1048     """
1049 Bilan du calcul Aster
1050 fic_caract : fichier caracteristique du job
1051     """
1052 #
1053     nom_fonction = __name__ + "/calcul_aster_attente"
1054     blabla = "\nDans " + nom_fonction + ","
1055 #
1056     erreur = 0
1057     message_erreur = " "
1058 #
1059     if self.verbose_max :
1060       print(". fic_caract :", fic_caract)
1061       print(". nomjob     :", self.nomjob)
1062       print(". rep_calc   :", self.rep_calc)
1063       print(". mode       :", self.mode)
1064       print(". attente    :", self.attente)
1065 #
1066     if ( self.mode != "interactif" ) :
1067 #
1068 # 1. Recuperation du numero de job
1069 #
1070       fic = open (fic_caract, "r")
1071       les_lignes = fic.readlines()
1072       fic.close()
1073   #
1074       for ligne in les_lignes :
1075         #print ligne
1076         if ( len(ligne)>0 ) :
1077           # en batch :
1078           if "JOBID" in ligne :
1079             #print ligne
1080             laux = ligne.split()
1081             laux1 = laux[0].split("=")
1082             numjob = laux1[1]
1083           # en interactif :
1084           elif "num_job" in ligne :
1085             #print ligne
1086             laux = ligne.split("num_job")
1087             laux1 = laux[1].split()
1088             numjob = laux1[0]
1089   #
1090       if self.verbose :
1091         print(". numjob :", numjob)
1092 #
1093 # 2. Commande de l'examen de l'etat du job,
1094 #
1095       fic_etat = os.path.join(self.rep_calc, self.nomjob+".etat")
1096       t_aux = tempfile.mkstemp()
1097       fic_etat_2   = t_aux[1]
1098       commande_base  = os.path.join(self.aster_root, "bin", "as_run")
1099       commande_base += " --actu " + numjob + " " + self.nomjob + " " + self.mode
1100       if self.verbose_max :
1101         print("commande_base =", commande_base)
1102       if ( self.mclient == self.serveur ) :
1103         commande  = commande_base
1104       else :
1105         commande  = "ssh " + self.username + "@" + self.serveur
1106         commande += " \"" + commande_base + "\""
1107       commande += " 1>" + fic_etat
1108       commande += " 2>" + fic_etat_2
1109       if self.verbose_max :
1110         print("Examen sur", self.serveur, ":")
1111         print(commande)
1112 #
1113 # 3. Examen de l'etat du job, jusqu'a la fin
1114 #
1115       encore = 1
1116       while encore :
1117   #
1118         if encore % 4 == 0 :
1119           aux = ((encore-1)*self.attente) / 60
1120           print("..", aux, "mn")
1121           #print diag
1122   #
1123         time.sleep(self.attente)
1124         erreur = os.system(commande)
1125   #
1126         if erreur :
1127           erreur = -1
1128           break
1129         elif os.path.isfile(fic_etat) :
1130           fic = open (fic_etat, "r")
1131           les_lignes = fic.readlines()
1132           fic.close()
1133           if len(les_lignes) > 0 :
1134             if len(les_lignes[0]) > 0 :
1135               laux = les_lignes[0].split()
1136               laux1 = laux[0].split("=")
1137               etat = laux1[1]
1138               laux1 = laux[1].split("=")
1139               diag = laux1[1]
1140               if self.verbose_max :
1141                 print(etat, diag)
1142               if etat in ( "RUN", "PEND" ) :
1143                 encore += 1
1144               else :
1145                 if etat != "ENDED" :
1146                   self.message_info += "Etat du job : " + etat
1147                   erreur = -2
1148                 else :
1149                   if diag[:3] in ( "<S>", "<F>" ) :
1150                     erreur = -3
1151                 if erreur :
1152                   self.message_info = "Diagnostic du job : " + diag + "\n"
1153                 encore = 0
1154                 break
1155             else :
1156               encore += 1
1157           else :
1158             encore += 1
1159         else :
1160           erreur = -4
1161           break
1162 #
1163       os.remove(fic_etat_2)
1164 #
1165     if self.verbose_max :
1166       print(blabla)
1167       print(". erreur :", erreur)
1168 #
1169     if erreur :
1170       message_erreur = "Erreur dans le calcul"
1171 #
1172     return erreur, message_erreur
1173 #
1174 #=========================  Fin de la fonction ===================================
1175 #
1176 #========================= Debut de la fonction ==================================
1177 #
1178   def post_aster ( self, dico_resu_init ) :
1179 #
1180     """
1181 Affichage de resultats selon les cas
1182     """
1183 #
1184     messages_erreur = { 0 : None,
1185                         1 : "Ce fichier est inconnu." }
1186 #
1187     nom_fonction = __name__ + "/post_aster"
1188     blabla = "\nDans " + nom_fonction + ","
1189 #
1190     erreur = 0
1191     message_erreur = " "
1192 #
1193     dico_resu = {}
1194     dico_resu.update(dico_resu_init)
1195 #
1196     while not erreur :
1197 #
1198 # 1. Exploration du fichier resu
1199 #
1200 # 1.1. Recuperation du contenu
1201 #
1202       nomfic = self.dico["resu"]
1203       chaine = "V_TEST"
1204       nuocc = 1
1205       erreur, message_erreur, info = self.post_aster_1 ( nomfic, chaine, nuocc )
1206       if ( erreur > 0 ) :
1207         break
1208 #
1209 # 1.2. Details
1210 #
1211       if ( erreur == 0 ) :
1212         self.message_info += info[:-1]
1213         info = info.replace(chaine, " ")
1214         laux = info[:-1].split()
1215         aux = laux[0]
1216         if ( "D" in aux ) :
1217           aux = aux.replace("D", "E")
1218         dico_resu[chaine] = float(aux)
1219       else :
1220         erreur = 0
1221         message_erreur = " "
1222 #
1223 # 2. Exploration du fichier mess
1224 # 2.1. Que chercher ?
1225 #
1226       for chaine in ( "INSTANT", "NOMBRE DE NOEUDS", "NOMBRE DE MAILLES" ) :
1227 #
1228 # 2.2. Recuperation du contenu
1229 #
1230         nomfic = self.dico["mess"]
1231         if chaine == "INSTANT" :
1232           nuocc = 0
1233         else :
1234           nuocc = 1
1235         erreur, message_erreur, info = self.post_aster_1 ( nomfic, chaine, nuocc )
1236         if ( erreur > 0 ) :
1237           break
1238 #
1239 # 2.3. Details
1240 #
1241         if ( erreur == 0 ) :
1242           self.message_info += info[:-1]
1243           if chaine == "INSTANT" :
1244             l_aux = info[:-1].split()
1245             lg_aux = len(l_aux)
1246             for iaux in range(lg_aux) :
1247               if ( "ORDRE" in l_aux[iaux] ) :
1248                 if l_aux[iaux+1] == ":" :
1249                   jaux = iaux+2
1250                 else :
1251                   jaux = iaux+1
1252                 ordre = int(l_aux[jaux])
1253                 dico_resu["ORDRE"] = ordre
1254                 dico_resu["PAS_DE_TEMPS"] = ordre
1255           elif chaine in ( "NOMBRE DE NOEUDS", "NOMBRE DE MAILLES" ) :
1256             l_aux = info[:-1].split(chaine)
1257             dico_resu[chaine] = int(l_aux[1])
1258         else :
1259           erreur = 0
1260           message_erreur = " "
1261 #
1262       if erreur :
1263         break
1264 #
1265 # 3. Fichier de resultats au format med
1266 #
1267       dico_resu["FileName"] = self.dico["rmed"]
1268 #
1269       break
1270 #
1271     if self.verbose :
1272       print(blabla)
1273       print(". erreur :", erreur)
1274       print(". dico_resu :", dico_resu)
1275 #
1276     if erreur :
1277       message_erreur = messages_erreur[erreur]
1278 #
1279     return erreur, message_erreur, dico_resu
1280 #
1281 #=========================  Fin de la fonction ===================================
1282 #
1283 #========================= Debut de la fonction ==================================
1284 #
1285   def post_aster_1 ( self, nomfic, chaine, nuocc ) :
1286 #
1287     """
1288 Decodage de fichier
1289 nomfic = nom du fichier a decoder
1290 chaine = chaine a chercher
1291 nuocc = numero de l'occurence a chercher, 0 si toutes
1292 Retour :
1293 codret = 0 : tout va bien
1294          1 : le fichier de resultats est absent
1295         -1 : la chaine est absente
1296 message_erreur = "" : tout va bien
1297                != "" si probleme
1298 info = la ou les lignes recherchees
1299     """
1300 #
1301     messages_erreur = { 0 : None,
1302                        -1 : "La chaine est absente.",
1303                         1 : "Ce fichier est inconnu." }
1304 #
1305     nom_fonction = __name__ + "/post_aster_1"
1306     blabla = "\nDans " + nom_fonction + " :"
1307     if self.verbose_max :
1308       print(blabla, "nomfic =", nomfic, "chaine =", chaine, ", nuocc =", nuocc)
1309 #
1310     trouve = False
1311     erreur = 0
1312     message_erreur = " "
1313     info = ""
1314 #
1315     while not erreur :
1316 #
1317 # 1. Lecture du fichier
1318 #
1319       if not os.path.isfile(nomfic) :
1320         self.message_info += "\nFichier "+nomfic+"\n"
1321         erreur = 1
1322         break
1323       fic = open (nomfic, "r")
1324       les_lignes = fic.readlines()
1325       fic.close()
1326 #
1327 # 2. Exploration des lignes
1328 # 2.1. On recupere tout
1329 #
1330       if chaine == None :
1331 #
1332         for ligne in les_lignes :
1333           info += ligne
1334 #
1335 # 2.2. On cible
1336 #
1337       else :
1338 #
1339         iaux = 0
1340         for ligne in les_lignes :
1341           if chaine in ligne :
1342             iaux += 1
1343             if ( ( nuocc == 0 ) or ( iaux == nuocc ) ) :
1344               info += ligne
1345               if ( not trouve ) :
1346                 self.message_info += "\n"
1347                 trouve = True
1348 #
1349       break
1350 #
1351     if ( not trouve ) :
1352       erreur = -1
1353 #
1354     if ( self.verbose_max or ( erreur>0 ) ) :
1355       print(blabla, "nomfic =", nomfic, "chaine =", chaine, ", nuocc =", nuocc)
1356       print(". erreur =", erreur)
1357 #
1358     if erreur :
1359       message_erreur = messages_erreur[erreur]
1360 #
1361     return erreur, message_erreur, info
1362 #
1363 #=========================  Fin de la fonction ===================================
1364 #
1365 #========================= Debut de la fonction ==================================
1366 #
1367   def dump_resultat ( self ) :
1368 #
1369     """
1370 Dump du resultat du calcul
1371     """
1372 #
1373     messages_erreur = { 0 : None }
1374 #
1375     nom_fonction = __name__ + "/dump_resultat"
1376     blabla = "\nDans " + nom_fonction + ","
1377 #
1378     erreur = 0
1379     message_erreur = " "
1380 #
1381 # 1. Lancement
1382 #
1383     nomfic_donn = os.path.join(self.rep_calc, "donn")
1384     fic = open (nomfic_donn, "w")
1385     fic.write("1\n1\n1\n")
1386     fic.close()
1387     fic_dump = self.dico["rmed"]+".dump"
1388     commande = "mdump " + self.dico["rmed"] + "<" + nomfic_donn + ">" + fic_dump
1389     #print commande
1390     erreur = os.system(commande)
1391     if erreur :
1392       messages_erreur[erreur] = "Erreur de dump numero %d" % erreur
1393     else :
1394       self.message_info += "\nDump dans le fichier :\n"
1395       self.message_info += fic_dump+"\n"
1396 #
1397     if self.verbose_max :
1398       print(blabla)
1399       print(". erreur :", erreur)
1400 #
1401     os.remove(nomfic_donn)
1402 #
1403     if erreur :
1404       message_erreur = messages_erreur[erreur]
1405 #
1406     return erreur, message_erreur
1407 #
1408 #=========================  Fin de la fonction ===================================
1409 #
1410 #
1411 if __name__ == "__main__" :
1412 #
1413   #print "Arguments a l'entree de",  sys.argv[0], ":", sys.argv[1:], "\n"
1414 #
1415   Script_A = Script(sys.argv[1:])
1416 #
1417   if Script_A.affiche_aide_globale :
1418     Script_A.message_info = Script_A.__doc__
1419     erreur_m = 0
1420     message_erreur_m = ""
1421   else :
1422     dico_resu_m = {}
1423     erreur_m, message_erreur_m, dico_resu_m = Script_A.compute ()
1424 #
1425   sys.stdout.write(Script_A.message_info+"\n")
1426   sys.stderr.write(message_erreur_m+"\n")
1427   sys.exit(erreur_m)