Salome HOME
Copyright update 2022
[modules/homard.git] / doc / files / yacs_script.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 # Copyright (C) 2013-2022  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       self.rep_calc = os.path.expanduser(self.rep_calc)
377       if not os.path.isdir(self.rep_calc) :
378         self.message_info += "Repertoire " + self.rep_calc
379         erreur = -4
380         break
381       else :
382         aux = os.path.join(os.getcwd(), self.rep_calc)
383         self.rep_calc = os.path.normpath(aux)
384 #
385 # 1.3. Les fichiers
386 #
387       fic = self.mesh_file
388 #
389       fic = os.path.expanduser(fic)
390       if not os.path.isfile(fic) :
391         aux = os.path.join(self.rep_calc, fic)
392         if not os.path.isfile(aux) :
393           self.message_info += "Fichier : " + fic
394           erreur = -5
395           break
396         else :
397           fic = os.path.normpath(aux)
398       aux = os.path.join(os.getcwd(), fic)
399 #
400       self.mesh_file = os.path.normpath(aux)
401 #
402 # 2. On en deduit le cas
403 #
404       self.nomcas = os.path.basename(self.rep_calc)
405       if self.verbose_max :
406         print(". Cas :", self.nomcas)
407 #
408 # 3. Le temps d'attente
409 #
410       iaux = None
411       try :
412         iaux = int(self.attente)
413       except :
414         erreur = -8
415         break
416       self.attente = iaux
417 #
418 # 4. Le numero du calcul
419 #
420       if self.numero == None :
421         erreur = -9
422 #
423       if ( self.numero < 100 ) :
424         self.numero_str = "%02d" % self.numero
425       elif ( self.numero < 1000 ) :
426         self.numero_str = "%03d" % self.numero
427       elif ( self.numero < 10000 ) :
428         self.numero_str = "%04d" % self.numero
429       else :
430         self.numero_str = "%d" % self.numero
431 #
432 # 5. Options speciales pour les cas transitoires et pour l'excavation
433 #
434       if ( self.tr or ( self.nomcas[:6] == "couche" ) ) :
435 #
436         if self.opt1 == None :
437           self.opt1 = opt1_defaut[self.nomcas]
438           #print ". opt1 defaut :", self.opt1
439 #
440         if self.opt2 == None :
441           self.opt2 = opt2_defaut[self.nomcas]
442           #print ". opt2 defaut :", self.opt2
443 #
444 # 5.1. Pour un cas transitoire
445 #
446       if self.tr :
447 #
448         iaux1 = None
449         daux1 = None
450         try :
451           iaux1 = int(self.opt1)
452         except :
453           daux1 = float(self.opt1)
454         if ( iaux1 == 0 ) :
455           daux1 = 0.
456 #
457         iaux2 = None
458         daux2 = None
459         try :
460           iaux2 = int(self.opt2)
461         except :
462           daux2 = float(self.opt2)
463 #
464         if ( ( daux1 == None ) or  ( daux2 == None ) ) :
465           #print "------------ ( daux1 == None ) or  ( daux2 == None ) ------------"
466           #print "iaux1, iaux2 =", iaux1, iaux2
467           if iaux2 < iaux1 :
468             erreur = -20
469         elif ( ( iaux1 == None ) or  ( iaux2 == None ) ) :
470           #print "------------ ( iaux1 == None ) or  ( iaux2 == None ) ------------"
471           #print "daux1, daux2 =", daux1, daux2
472           if daux2 < daux1 :
473             erreur = -20
474         else :
475           erreur = -20
476 #
477         if erreur :
478           self.message_info += "opt1 = " + self.opt1
479           self.message_info += "\nopt2 = " + self.opt2
480 #
481 # 5.2. Pour l'excavation
482 #
483       elif self.nomcas[:6] == "couche" :
484 #
485         iaux1 = None
486         try :
487           iaux1 = int(self.opt1)
488         except :
489           erreur = -30
490 #
491         if ( ( iaux1 < 1 ) or ( iaux1 > 20 ) ) :
492           #print "iaux1 =", iaux1
493           erreur = -30
494 #
495         iaux2 = None
496         try :
497           iaux2 = int(self.opt2)
498         except :
499           erreur = -31
500 #
501         if ( iaux2 < 0 ) :
502           #print "iaux1 =", iaux1
503           erreur = -31
504 #
505         if erreur :
506           self.message_info += "nro_mail = " + self.numero
507           self.message_info += "\nopt1 = " + self.opt1
508           self.message_info += "\nopt2 = " + self.opt2
509           break
510 #
511         self.nro_couche = iaux1
512         self.nro_adap = iaux2
513 #
514       break
515 #
516     if erreur :
517       message_erreur = messages_erreur[erreur]
518 #
519     if self.verbose_max :
520       print(". rep_calc  :", self.rep_calc)
521       print(". mesh_file :", self.mesh_file)
522       print(". opt1      :", self.opt1)
523       print(". opt2      :", self.opt2)
524 #
525     return erreur, message_erreur
526 #
527 #=========================  Fin de la fonction ===================================
528 #
529 #========================= Debut de la fonction ==================================
530 #
531   def modif_export ( self ) :
532 #
533     """
534 Modification du fichier export et reperage de quelques informations
535     """
536 #
537     messages_erreur = { 0 : None }
538 #
539     nom_fonction = __name__ + "/modif_export"
540     blabla = "\nDans " + nom_fonction + ","
541 #
542     erreur = 0
543     message_erreur = " "
544 #
545     if self.verbose_max :
546       print(blabla)
547       print(". numero     :", self.numero)
548       print(". mesh_file  :", self.mesh_file)
549 #
550     while not erreur :
551 #
552 # 1. Lecture du fichier export original
553 #
554       fic_export_ref = os.path.join(self.rep_calc, "calcul.ref.export")
555       fic = open (fic_export_ref, "r")
556       les_lignes = fic.readlines()
557       fic.close()
558 #
559 # 2. Ouverture du nouveau fichier export
560 #
561       nomfic = "calcul"
562       if self.nomcas[:6] == "couche" :
563         nomfic += ".%02d" % self.nro_couche
564       nomfic += "." + self.numero_str + ".export"
565       self.nomfic_export = os.path.join(self.rep_calc, nomfic)
566       if self.verbose_max :
567         print(". nouveau fic_export :", self.nomfic_export)
568       fic = open (self.nomfic_export, "w")
569 #
570 # 3. Exploration des lignes
571 #
572       for ligne in les_lignes :
573 #
574 # 3.1. Pas de modification, a priori
575 #
576         ligne_bis = ligne
577         saux = ""
578 #
579 # 3.2. Decodage des composants de la ligne pour un fichier
580 #
581         if ligne[0:2] == "F " :
582 #
583           chgt = False
584 #
585           laux = ligne.split()
586           #print laux
587           typfic = laux[1]
588           statut = laux[3]
589           #print typfic
590 #
591           nomfic_0 = laux[2]
592           if ( ":" in nomfic_0 ) :
593             laux1 = nomfic_0.split(":")
594             saux = laux1[0] + ":"
595             nomfic_0 = laux1[1]
596 #
597 # 3.2.1. Si c'est le fichier de commandes, mise a jour du nom du repertoire
598 #
599           if ( typfic == "comm" ) :
600 #
601             if self.verbose_max :
602               print(". Commandes : mise a jour du nom du repertoire")
603             chgt = True
604             nomfic_l_0 = os.path.basename(nomfic_0)
605             nomfic = os.path.join(self.rep_calc, nomfic_l_0)
606 #
607 # 3.2.2. Si c'est un fichier de resultats ou le fichier de maillage, mise a jour du nom
608 #
609           elif ( ( statut == "R" ) or ( typfic == "mmed" ) ) :
610             if self.verbose_max :
611               print(". Mise a jour du nom")
612             chgt = True
613 #
614 # 3.2.2.1. Le fichier de maillage est celui passe en argument
615 #
616             if typfic == "mmed" :
617               nomfic = self.mesh_file
618 #
619 # 3.2.2.2. Pour les autres fichiers, on recupère le nom initial
620 #
621             else :
622               nomfic_l_0 = os.path.basename(nomfic_0)
623               laux1 = nomfic_l_0.split(".")
624               #print "laux1 =", laux1
625 #
626 # 3.2.2.2.1. Base des noms de fichiers si excavation
627 #
628               if laux1[0] == "couche_n" :
629                 saux0 = "couche_%02d" % self.nro_couche
630               else :
631                 iaux = len(laux1[-1]) + 1
632                 saux0 = nomfic_l_0[:-iaux]
633               #print "saux0 =", saux0
634 #
635 # 3.2.2.2.2. Indicage des fichiers
636 #
637               nomfic_l = saux0 + "." + self.numero_str + "." + laux1[-1]
638               nomfic_l_1 = os.path.dirname(nomfic_0)
639               nomfic = os.path.join(nomfic_l_1, nomfic_l)
640             #print "   ==> ", nomfic
641 #
642           if chgt :
643             ligne_bis  = laux[0] + " " + laux[1] + " " + saux
644             ligne_bis += nomfic + " "
645             ligne_bis += laux[3] + " " + laux[4] + "\n"
646 #
647 # 3.2.2.3. On detruit preventivement les fichiers des resultats
648 #
649           if ( statut == "R" ) :
650             if ( self.nomcas[:6] != "couche" ) :
651               if os.path.isfile(nomfic) :
652                 os.remove(nomfic)
653 #
654 # 3.2.3. Memorisation des noms
655 #
656           self.dico[typfic] = nomfic
657 #
658 # 3.3. Decodage des composants de la ligne pour la base
659 #
660         elif ligne[0:2] == "R " :
661 #
662           laux = ligne.split()
663           #print laux
664           typfic = laux[1]
665           #print typfic
666 #
667 # 3.3.1. Si c'est le fichier de la base, on recupere le nom initial, en ajustant l'indice
668 #
669           if typfic in ( "base", "bhdf" ) :
670 #
671             nomfic_0 = laux[2]
672             if ( ":" in nomfic_0 ) :
673               laux1 = nomfic_0.split(":")
674               saux = laux1[0] + ":"
675               nomfic_0 = laux1[1]
676             nomfic_l_0 = os.path.basename(nomfic_0)
677             laux1 = nomfic_l_0.split(".")
678             if len(laux1) >= 3 :
679               nomfic_l = laux1[0] + "." + self.numero_str + "." + laux1[2]
680             elif len(laux1) >= 2 :
681               if laux1[0] == "couche_nm1" :
682                 saux0 = "couche_%02d" % (self.nro_couche-1)
683               elif laux1[0] == "couche_n" :
684                 saux0 = "couche_%02d" % self.nro_couche
685               else :
686                 saux0 = laux1[0]
687               nomfic_l = saux0 + "." + laux1[1]
688             else :
689               nomfic_l = nomfic_l_0
690             nomfic_l_1 = os.path.dirname(nomfic_0)
691             nomfic = os.path.join(nomfic_l_1, nomfic_l)
692 #
693             ligne_bis  = laux[0] + " " + laux[1] + " " + saux
694             ligne_bis += nomfic + " "
695             ligne_bis += laux[3] + " " + laux[4] + "\n"
696 #
697 # 3.4. Decodage des composants de la ligne pour un parametre
698 #
699         elif ligne[0:2] == "P " :
700 #
701           laux = ligne.split()
702           #print laux
703           if ( len(laux) == 3 ) :
704             aux = laux[2]
705             if laux[1] in ( "username" ) :
706               self.username = aux
707             elif laux[1] in ( "uclient" ) :
708               self.uclient = aux
709             elif laux[1] in ( "aster_root" ) :
710               self.aster_root = aux
711             elif laux[1] in ( "serveur" ) :
712               self.serveur = aux
713             elif laux[1] in ( "mclient" ) :
714               self.mclient = aux
715             #elif laux[1] in ( "display" ) :
716               #aux = self.machine+":0.0"
717             elif laux[1] in ( "nomjob" ) :
718               self.nomjob = aux
719             elif laux[1] in ( "mode" ) :
720               self.mode = aux
721             ligne_bis  = laux[0] + " " + laux[1] + " " + aux  + "\n"
722 #
723 # 3.5. Ecriture de la ligne
724 #
725         fic.write(ligne_bis)
726 #
727       fic.close()
728 #
729       break
730 #
731     if erreur :
732       message_erreur = messages_erreur[erreur]
733 #
734     if self.verbose_max :
735       print(". mclient    ", self.mclient)
736       print(". uclient    ", self.uclient)
737       print(". serveur    ", self.serveur)
738       print(". username   ", self.username)
739       print(". aster_root ", self.aster_root)
740       print(". nomjob     ", self.nomjob)
741       print(". mode       ", self.mode)
742 #
743     return erreur, message_erreur
744 #
745 #=========================  Fin de la fonction ===================================
746 #
747 #========================= Debut de la fonction ==================================
748 #
749   def modif_cas_transitoire ( self ) :
750 #
751     """
752 Modification du fichier de commandes lie au cas transitoire
753     """
754 #
755     messages_erreur = { 0 : None,
756                         2 : "Mot_cle inconnu dans les commandes." }
757 #
758     nom_fonction = __name__ + "/modif_cas_transitoire"
759     blabla = "\nDans " + nom_fonction + ","
760 #
761     erreur = 0
762     message_erreur = " "
763 #
764     if self.verbose_max :
765       print(blabla)
766       print(". opt1 :", self.opt1)
767       print(". opt2 :", self.opt2)
768 #
769     while not erreur :
770 #
771 # 1. Lecture du fichier de commandes
772 #
773       nomfic = os.path.join(self.rep_calc, self.dico["comm"])
774       fic = open (nomfic, "r")
775       les_lignes = fic.readlines()
776       fic.close()
777 #
778 # 2. Ouverture du nouveau fichier de commandes
779 #
780       fic = open (nomfic, "w")
781 #
782 # 3. Exploration des lignes
783 #
784 # 3.0. Reperage de la zone a modifier
785 #
786       A_modifier = 0
787 #
788       for ligne in les_lignes :
789 #
790         if self.verbose_max :
791           print("ligne =", ligne[:-1])
792 #
793 # 3.1. Pas de modification, a priori
794 #
795         ligne_bis = ligne
796 #
797 # 3.2. Reperage de la zone a modifier
798 #
799         if ( "A PERSONNALISER - DEBUT" in ligne ) :
800           A_modifier = 1
801         elif ( "A PERSONNALISER - FIN" in ligne ) :
802           A_modifier = 0
803 #
804 # 3.3. Modification
805 #
806         #print "A_modifier =", A_modifier
807         if A_modifier :
808 #
809           #print "ligne =", ligne[:-1]
810           for iaux in range(2) :
811             if iaux == 0 :
812               mot_cle_ref = "NUME_INST_"
813               lg_mot_cle = 10
814             else :
815               mot_cle_ref = "INST_"
816               lg_mot_cle = 5
817             #print "mot_cle_ref =", mot_cle_ref
818 #
819             if ligne[0:lg_mot_cle] == mot_cle_ref :
820 #
821               if ligne[lg_mot_cle:lg_mot_cle+4] == "INIT" :
822                 aux = self.opt1
823                 motcle = ligne[0:lg_mot_cle+4]
824               elif ligne[lg_mot_cle:lg_mot_cle+3] == "FIN" :
825                 aux = self.opt2
826                 motcle = ligne[0:lg_mot_cle+3]
827               else :
828                 self.message_info += ligne
829                 erreur = 2
830                 break
831 #
832               ligne_bis = motcle + " = " + str(aux) +"\n"
833 #
834           if erreur :
835             break
836 #
837 # 3.4. Ecriture de la ligne
838 #
839         fic.write(ligne_bis)
840 #
841       fic.close()
842 #
843       break
844 #
845 # 4. Gestion des erreurs
846 #
847     if erreur :
848       message_erreur = messages_erreur[erreur]
849 #
850     return erreur, message_erreur
851 #
852 #=========================  Fin de la fonction ===================================
853 #
854 #========================= Debut de la fonction ==================================
855 #
856   def modif_cas_excavation ( self ) :
857 #
858     """
859 Modification du fichier de commandes lie au cas de l'excavation
860     """
861 #
862     messages_erreur = { 0 : None }
863 #
864     nom_fonction = __name__ + "/modif_cas_excavation"
865     blabla = "\nDans " + nom_fonction + ","
866 #
867     erreur = 0
868     message_erreur = " "
869 #
870     if self.verbose_max :
871       print(blabla)
872       print(". numero     :", self.numero)
873       print(". nro_couche :", self.nro_couche)
874       print(". nro_adap   :", self.nro_adap)
875 #
876     while not erreur :
877 #
878 # 1. Lecture du fichier de commandes
879 #
880       nomfic = os.path.join(self.rep_calc, self.dico["comm"])
881       fic = open (nomfic, "r")
882       les_lignes = fic.readlines()
883       fic.close()
884 #
885 # 2. Ouverture du nouveau fichier de commandes
886 #
887       fic = open (nomfic, "w")
888 #
889 # 3. Exploration des lignes
890 #
891 # 3.0. Reperage de la zone a modifier
892 #
893       A_modifier = 0
894 #
895       for ligne in les_lignes :
896 #
897         if self.verbose_max :
898           print("ligne =", ligne[:-1])
899 #
900 # 3.1. Pas de modification, a priori
901 #
902         ligne_bis = ligne
903 #
904 # 3.2. Reperage de la zone a modifier
905 #
906         if ( "A PERSONNALISER - DEBUT" in ligne ) :
907           A_modifier = 1
908         elif ( "A PERSONNALISER - FIN" in ligne ) :
909           A_modifier = 0
910 #
911 # 3.3. Modification
912 #
913         #print "A_modifier =", A_modifier
914         if A_modifier :
915 #
916           #print "ligne =", ligne[:-1]
917           for iaux in range(3) :
918             if iaux == 0 :
919               mot_cle_ref = "nro_mail"
920               lg_mot_cle = 8
921               aux = self.numero
922             elif iaux == 1 :
923               mot_cle_ref = "nro_couche"
924               lg_mot_cle = 10
925               aux = self.nro_couche
926             elif iaux == 2 :
927               mot_cle_ref = "nro_adap"
928               lg_mot_cle = 8
929               aux = self.nro_adap
930             #print "mot_cle_ref =", mot_cle_ref
931 #
932             if ligne[0:lg_mot_cle] == mot_cle_ref :
933               #print "==> aux =", aux, type(aux)
934               ligne_bis = mot_cle_ref + " = " + str(aux) +"\n"
935 #
936 # 3.4. Ecriture de la ligne
937 #
938         fic.write(ligne_bis)
939 #
940       fic.close()
941 #
942       break
943 #
944 # 4. Gestion des erreurs
945 #
946     if erreur :
947       message_erreur = messages_erreur[erreur]
948 #
949     return erreur, message_erreur
950 #
951 #=========================  Fin de la fonction ===================================
952 #
953 #========================= Debut de la fonction ==================================
954 #
955   def calcul ( self ) :
956 #
957     """
958 Lancement d'un calcul
959     """
960 #
961     messages_erreur = { 0 : None }
962 #
963     nom_fonction = __name__ + "/calcul"
964     blabla = "\nDans " + nom_fonction + ","
965 #
966     erreur = 0
967     message_erreur = " "
968 #
969     if self.verbose_max :
970       print(". mclient    ", self.mclient)
971       print(". serveur    ", self.serveur)
972 #
973 # 1. Copie du fichier export sur le serveur de calcul
974 #
975     if ( self.mclient != self.serveur ) :
976 #
977       nomfic_export_dist = self.nomjob + ".export"
978       commande = "scp " + self.nomfic_export + " " + self.username + "@" + self.serveur + ":" + nomfic_export_dist
979       if self.verbose_max :
980         print("Copie du fichier export vers", self.serveur, ":")
981         print(commande)
982       erreur = os.system(commande)
983 #
984 # 2. Commande du lancement
985 #
986     commande_base  = os.path.join(self.aster_root, "bin", "as_run")
987     commande_base += " "
988     if self.mode == "batch" :
989       commande_base += "--serv "
990     commande_base += self.username + "@" + self.serveur + ":"
991     #if self.verbose_max :
992       #print commande_base
993 #
994     t_aux = tempfile.mkstemp()
995     fic_caract   = t_aux[1]
996     t_aux = tempfile.mkstemp()
997     fic_caract_2 = t_aux[1]
998 #
999 # 3. Lancement
1000 # 3.1. Commande finale
1001 #
1002     if ( self.mclient == self.serveur ) :
1003       commande  = commande_base
1004       commande += commande_base + self.nomfic_export
1005     else :
1006       commande  = "ssh " + self.username + "@" + self.serveur
1007       commande += " \"" + commande_base + nomfic_export_dist + "\""
1008     commande += " 1>" + fic_caract
1009     commande += " 2>" + fic_caract_2
1010     if self.verbose_max :
1011       print("Lancement sur", self.serveur, ":")
1012       print(commande)
1013 #
1014 # 3.2. Lancement vrai
1015 #
1016     erreur = os.system(commande)
1017     if erreur :
1018       messages_erreur[erreur] = "erreur de calcul numero %d" % erreur
1019     else :
1020       self.message_info += "resultat dans le fichier :\n"
1021       #print self.dico
1022       self.message_info += self.dico["rmed"]+"\n"
1023 #
1024     if self.verbose_max :
1025       print(blabla)
1026       print(". erreur     :", erreur)
1027       print(". self.mode  :", self.mode)
1028       print(". fic_caract :", fic_caract)
1029 #
1030     if erreur :
1031       message_erreur = messages_erreur[erreur]
1032 #
1033     return erreur, message_erreur, fic_caract, fic_caract_2
1034 #
1035 #=========================  Fin de la fonction ===================================
1036 #
1037 #========================= Debut de la fonction ==================================
1038 #
1039   def calcul_aster_attente ( self, fic_caract ) :
1040 #
1041     """
1042 Bilan du calcul Aster
1043 fic_caract : fichier caracteristique du job
1044     """
1045 #
1046     nom_fonction = __name__ + "/calcul_aster_attente"
1047     blabla = "\nDans " + nom_fonction + ","
1048 #
1049     erreur = 0
1050     message_erreur = " "
1051 #
1052     if self.verbose_max :
1053       print(". fic_caract :", fic_caract)
1054       print(". nomjob     :", self.nomjob)
1055       print(". rep_calc   :", self.rep_calc)
1056       print(". mode       :", self.mode)
1057       print(". attente    :", self.attente)
1058 #
1059     if ( self.mode != "interactif" ) :
1060 #
1061 # 1. Recuperation du numero de job
1062 #
1063       fic = open (fic_caract, "r")
1064       les_lignes = fic.readlines()
1065       fic.close()
1066   #
1067       for ligne in les_lignes :
1068         #print ligne
1069         if ( len(ligne)>0 ) :
1070           # en batch :
1071           if "JOBID" in ligne :
1072             #print ligne
1073             laux = ligne.split()
1074             laux1 = laux[0].split("=")
1075             numjob = laux1[1]
1076           # en interactif :
1077           elif "num_job" in ligne :
1078             #print ligne
1079             laux = ligne.split("num_job")
1080             laux1 = laux[1].split()
1081             numjob = laux1[0]
1082   #
1083       if self.verbose :
1084         print(". numjob :", numjob)
1085 #
1086 # 2. Commande de l'examen de l'etat du job,
1087 #
1088       fic_etat = os.path.join(self.rep_calc, self.nomjob+".etat")
1089       t_aux = tempfile.mkstemp()
1090       fic_etat_2   = t_aux[1]
1091       commande_base  = os.path.join(self.aster_root, "bin", "as_run")
1092       commande_base += " --actu " + numjob + " " + self.nomjob + " " + self.mode
1093       if self.verbose_max :
1094         print("commande_base =", commande_base)
1095       if ( self.mclient == self.serveur ) :
1096         commande  = commande_base
1097       else :
1098         commande  = "ssh " + self.username + "@" + self.serveur
1099         commande += " \"" + commande_base + "\""
1100       commande += " 1>" + fic_etat
1101       commande += " 2>" + fic_etat_2
1102       if self.verbose_max :
1103         print("Examen sur", self.serveur, ":")
1104         print(commande)
1105 #
1106 # 3. Examen de l'etat du job, jusqu'a la fin
1107 #
1108       encore = 1
1109       while encore :
1110   #
1111         if encore % 4 == 0 :
1112           aux = ((encore-1)*self.attente) / 60
1113           print("..", aux, "mn")
1114           #print diag
1115   #
1116         time.sleep(self.attente)
1117         erreur = os.system(commande)
1118   #
1119         if erreur :
1120           erreur = -1
1121           break
1122         elif os.path.isfile(fic_etat) :
1123           fic = open (fic_etat, "r")
1124           les_lignes = fic.readlines()
1125           fic.close()
1126           if len(les_lignes) > 0 :
1127             if len(les_lignes[0]) > 0 :
1128               laux = les_lignes[0].split()
1129               laux1 = laux[0].split("=")
1130               etat = laux1[1]
1131               laux1 = laux[1].split("=")
1132               diag = laux1[1]
1133               if self.verbose_max :
1134                 print(etat, diag)
1135               if etat in ( "RUN", "PEND" ) :
1136                 encore += 1
1137               else :
1138                 if etat != "ENDED" :
1139                   self.message_info += "Etat du job : " + etat
1140                   erreur = -2
1141                 else :
1142                   if diag[:3] in ( "<S>", "<F>" ) :
1143                     erreur = -3
1144                 if erreur :
1145                   self.message_info = "Diagnostic du job : " + diag + "\n"
1146                 encore = 0
1147                 break
1148             else :
1149               encore += 1
1150           else :
1151             encore += 1
1152         else :
1153           erreur = -4
1154           break
1155 #
1156       os.remove(fic_etat_2)
1157 #
1158     if self.verbose_max :
1159       print(blabla)
1160       print(". erreur :", erreur)
1161 #
1162     if erreur :
1163       message_erreur = "Erreur dans le calcul"
1164 #
1165     return erreur, message_erreur
1166 #
1167 #=========================  Fin de la fonction ===================================
1168 #
1169 #========================= Debut de la fonction ==================================
1170 #
1171   def post_aster ( self, dico_resu_init ) :
1172 #
1173     """
1174 Affichage de resultats selon les cas
1175     """
1176 #
1177     messages_erreur = { 0 : None,
1178                         1 : "Ce fichier est inconnu." }
1179 #
1180     nom_fonction = __name__ + "/post_aster"
1181     blabla = "\nDans " + nom_fonction + ","
1182 #
1183     erreur = 0
1184     message_erreur = " "
1185 #
1186     dico_resu = {}
1187     dico_resu.update(dico_resu_init)
1188 #
1189     while not erreur :
1190 #
1191 # 1. Exploration du fichier resu
1192 #
1193 # 1.1. Recuperation du contenu
1194 #
1195       nomfic = self.dico["resu"]
1196       chaine = "V_TEST"
1197       nuocc = 1
1198       erreur, message_erreur, info = self.post_aster_1 ( nomfic, chaine, nuocc )
1199       if ( erreur > 0 ) :
1200         break
1201 #
1202 # 1.2. Details
1203 #
1204       if ( erreur == 0 ) :
1205         self.message_info += info[:-1]
1206         info = info.replace(chaine, " ")
1207         laux = info[:-1].split()
1208         aux = laux[0]
1209         if ( "D" in aux ) :
1210           aux = aux.replace("D", "E")
1211         dico_resu[chaine] = float(aux)
1212       else :
1213         erreur = 0
1214         message_erreur = " "
1215 #
1216 # 2. Exploration du fichier mess
1217 # 2.1. Que chercher ?
1218 #
1219       for chaine in ( "INSTANT", "NOMBRE DE NOEUDS", "NOMBRE DE MAILLES" ) :
1220 #
1221 # 2.2. Recuperation du contenu
1222 #
1223         nomfic = self.dico["mess"]
1224         if chaine == "INSTANT" :
1225           nuocc = 0
1226         else :
1227           nuocc = 1
1228         erreur, message_erreur, info = self.post_aster_1 ( nomfic, chaine, nuocc )
1229         if ( erreur > 0 ) :
1230           break
1231 #
1232 # 2.3. Details
1233 #
1234         if ( erreur == 0 ) :
1235           self.message_info += info[:-1]
1236           if chaine == "INSTANT" :
1237             l_aux = info[:-1].split()
1238             lg_aux = len(l_aux)
1239             for iaux in range(lg_aux) :
1240               if ( "ORDRE" in l_aux[iaux] ) :
1241                 if l_aux[iaux+1] == ":" :
1242                   jaux = iaux+2
1243                 else :
1244                   jaux = iaux+1
1245                 ordre = int(l_aux[jaux])
1246                 dico_resu["ORDRE"] = ordre
1247                 dico_resu["PAS_DE_TEMPS"] = ordre
1248           elif chaine in ( "NOMBRE DE NOEUDS", "NOMBRE DE MAILLES" ) :
1249             l_aux = info[:-1].split(chaine)
1250             dico_resu[chaine] = int(l_aux[1])
1251         else :
1252           erreur = 0
1253           message_erreur = " "
1254 #
1255       if erreur :
1256         break
1257 #
1258 # 3. Fichier de resultats au format med
1259 #
1260       dico_resu["FileName"] = self.dico["rmed"]
1261 #
1262       break
1263 #
1264     if self.verbose :
1265       print(blabla)
1266       print(". erreur :", erreur)
1267       print(". dico_resu :", dico_resu)
1268 #
1269     if erreur :
1270       message_erreur = messages_erreur[erreur]
1271 #
1272     return erreur, message_erreur, dico_resu
1273 #
1274 #=========================  Fin de la fonction ===================================
1275 #
1276 #========================= Debut de la fonction ==================================
1277 #
1278   def post_aster_1 ( self, nomfic, chaine, nuocc ) :
1279 #
1280     """
1281 Decodage de fichier
1282 nomfic = nom du fichier a decoder
1283 chaine = chaine a chercher
1284 nuocc = numero de l'occurence a chercher, 0 si toutes
1285 Retour :
1286 codret = 0 : tout va bien
1287          1 : le fichier de resultats est absent
1288         -1 : la chaine est absente
1289 message_erreur = "" : tout va bien
1290                != "" si probleme
1291 info = la ou les lignes recherchees
1292     """
1293 #
1294     messages_erreur = { 0 : None,
1295                        -1 : "La chaine est absente.",
1296                         1 : "Ce fichier est inconnu." }
1297 #
1298     nom_fonction = __name__ + "/post_aster_1"
1299     blabla = "\nDans " + nom_fonction + " :"
1300     if self.verbose_max :
1301       print(blabla, "nomfic =", nomfic, "chaine =", chaine, ", nuocc =", nuocc)
1302 #
1303     trouve = False
1304     erreur = 0
1305     message_erreur = " "
1306     info = ""
1307 #
1308     while not erreur :
1309 #
1310 # 1. Lecture du fichier
1311 #
1312       if not os.path.isfile(nomfic) :
1313         self.message_info += "\nFichier "+nomfic+"\n"
1314         erreur = 1
1315         break
1316       fic = open (nomfic, "r")
1317       les_lignes = fic.readlines()
1318       fic.close()
1319 #
1320 # 2. Exploration des lignes
1321 # 2.1. On recupere tout
1322 #
1323       if chaine == None :
1324 #
1325         for ligne in les_lignes :
1326           info += ligne
1327 #
1328 # 2.2. On cible
1329 #
1330       else :
1331 #
1332         iaux = 0
1333         for ligne in les_lignes :
1334           if chaine in ligne :
1335             iaux += 1
1336             if ( ( nuocc == 0 ) or ( iaux == nuocc ) ) :
1337               info += ligne
1338               if ( not trouve ) :
1339                 self.message_info += "\n"
1340                 trouve = True
1341 #
1342       break
1343 #
1344     if ( not trouve ) :
1345       erreur = -1
1346 #
1347     if ( self.verbose_max or ( erreur>0 ) ) :
1348       print(blabla, "nomfic =", nomfic, "chaine =", chaine, ", nuocc =", nuocc)
1349       print(". erreur =", erreur)
1350 #
1351     if erreur :
1352       message_erreur = messages_erreur[erreur]
1353 #
1354     return erreur, message_erreur, info
1355 #
1356 #=========================  Fin de la fonction ===================================
1357 #
1358 #========================= Debut de la fonction ==================================
1359 #
1360   def dump_resultat ( self ) :
1361 #
1362     """
1363 Dump du resultat du calcul
1364     """
1365 #
1366     messages_erreur = { 0 : None }
1367 #
1368     nom_fonction = __name__ + "/dump_resultat"
1369     blabla = "\nDans " + nom_fonction + ","
1370 #
1371     erreur = 0
1372     message_erreur = " "
1373 #
1374 # 1. Lancement
1375 #
1376     nomfic_donn = os.path.join(self.rep_calc, "donn")
1377     fic = open (nomfic_donn, "w")
1378     fic.write("1\n1\n1\n")
1379     fic.close()
1380     fic_dump = self.dico["rmed"]+".dump"
1381     commande = "mdump " + self.dico["rmed"] + "<" + nomfic_donn + ">" + fic_dump
1382     #print commande
1383     erreur = os.system(commande)
1384     if erreur :
1385       messages_erreur[erreur] = "Erreur de dump numero %d" % erreur
1386     else :
1387       self.message_info += "\nDump dans le fichier :\n"
1388       self.message_info += fic_dump+"\n"
1389 #
1390     if self.verbose_max :
1391       print(blabla)
1392       print(". erreur :", erreur)
1393 #
1394     os.remove(nomfic_donn)
1395 #
1396     if erreur :
1397       message_erreur = messages_erreur[erreur]
1398 #
1399     return erreur, message_erreur
1400 #
1401 #=========================  Fin de la fonction ===================================
1402 #
1403 #
1404 if __name__ == "__main__" :
1405 #
1406   #print "Arguments a l'entree de",  sys.argv[0], ":", sys.argv[1:], "\n"
1407 #
1408   Script_A = Script(sys.argv[1:])
1409 #
1410   if Script_A.affiche_aide_globale :
1411     Script_A.message_info = Script_A.__doc__
1412     erreur_m = 0
1413     message_erreur_m = ""
1414   else :
1415     dico_resu_m = {}
1416     erreur_m, message_erreur_m, dico_resu_m = Script_A.compute ()
1417 #
1418   sys.stdout.write(Script_A.message_info+"\n")
1419   sys.stderr.write(message_erreur_m+"\n")
1420   sys.exit(erreur_m)