Salome HOME
4a09ee4ba78a5cb1f1f230bba4a323539703c04b
[modules/homard.git] / doc / files / yacs_script.py
1 #!/usr/bin/env python
2 # -*- coding: iso-8859-1 -*-
3 # Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
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.8"
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 os.environ.has_key("LOGNAME") :
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 os.environ.has_key("HOME") :
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     fic_caract   = tempfile.mktemp()
1002     fic_caract_2 = tempfile.mktemp()
1003 #
1004 # 3. Lancement
1005 # 3.1. Commande finale
1006 #
1007     if ( self.mclient == self.serveur ) :
1008       commande  = commande_base
1009       commande += commande_base + self.nomfic_export
1010     else :
1011       commande  = "ssh " + self.username + "@" + self.serveur
1012       commande += " \"" + commande_base + nomfic_export_dist + "\""
1013     commande += " 1>" + fic_caract
1014     commande += " 2>" + fic_caract_2
1015     if self.verbose_max :
1016       print "Lancement sur", self.serveur, ":"
1017       print commande
1018 #
1019 # 3.2. Lancement vrai
1020 #
1021     erreur = os.system(commande)
1022     if erreur :
1023       messages_erreur[erreur] = "erreur de calcul numero %d" % erreur
1024     else :
1025       self.message_info += "resultat dans le fichier :\n"
1026       #print self.dico
1027       self.message_info += self.dico["rmed"]+"\n"
1028 #
1029     if self.verbose_max :
1030       print blabla
1031       print ". erreur     :", erreur
1032       print ". self.mode  :", self.mode
1033       print ". fic_caract :", fic_caract
1034 #
1035     if erreur :
1036       message_erreur = messages_erreur[erreur]
1037 #
1038     return erreur, message_erreur, fic_caract, fic_caract_2
1039 #
1040 #=========================  Fin de la fonction ===================================
1041 #
1042 #========================= Debut de la fonction ==================================
1043 #
1044   def calcul_aster_attente ( self, fic_caract ) :
1045 #
1046     """
1047 Bilan du calcul Aster
1048 fic_caract : fichier caracteristique du job
1049     """
1050 #
1051     nom_fonction = __name__ + "/calcul_aster_attente"
1052     blabla = "\nDans " + nom_fonction + ","
1053 #
1054     erreur = 0
1055     message_erreur = " "
1056 #
1057     if self.verbose_max :
1058       print ". fic_caract :", fic_caract
1059       print ". nomjob     :", self.nomjob
1060       print ". rep_calc   :", self.rep_calc
1061       print ". mode       :", self.mode
1062       print ". attente    :", self.attente
1063 #
1064     if ( self.mode != "interactif" ) :
1065 #
1066 # 1. Recuperation du numero de job
1067 #
1068       fic = open (fic_caract, "r")
1069       les_lignes = fic.readlines()
1070       fic.close()
1071   #
1072       for ligne in les_lignes :
1073         #print ligne
1074         if ( len(ligne)>0 ) :
1075           # en batch :
1076           if "JOBID" in ligne :
1077             #print ligne
1078             laux = ligne.split()
1079             laux1 = laux[0].split("=")
1080             numjob = laux1[1]
1081           # en interactif :
1082           elif "num_job" in ligne :
1083             #print ligne
1084             laux = ligne.split("num_job")
1085             laux1 = laux[1].split()
1086             numjob = laux1[0]
1087   #
1088       if self.verbose :
1089         print ". numjob :", numjob
1090 #
1091 # 2. Commande de l'examen de l'etat du job,
1092 #
1093       fic_etat = os.path.join(self.rep_calc, self.nomjob+".etat")
1094       fic_etat_2 = tempfile.mktemp()
1095       commande_base  = os.path.join(self.aster_root, "bin", "as_run")
1096       commande_base += " --actu " + numjob + " " + self.nomjob + " " + self.mode
1097       if self.verbose_max :
1098         print "commande_base =", commande_base
1099       if ( self.mclient == self.serveur ) :
1100         commande  = commande_base
1101       else :
1102         commande  = "ssh " + self.username + "@" + self.serveur
1103         commande += " \"" + commande_base + "\""
1104       commande += " 1>" + fic_etat
1105       commande += " 2>" + fic_etat_2
1106       if self.verbose_max :
1107         print "Examen sur", self.serveur, ":"
1108         print commande
1109 #
1110 # 3. Examen de l'etat du job, jusqu'a la fin
1111 #
1112       encore = 1
1113       while encore :
1114   #
1115         if encore % 4 == 0 :
1116           aux = ((encore-1)*self.attente) / 60
1117           print "..", aux, "mn"
1118           #print diag
1119   #
1120         time.sleep(self.attente)
1121         erreur = os.system(commande)
1122   #
1123         if erreur :
1124           erreur = -1
1125           break
1126         elif os.path.isfile(fic_etat) :
1127           fic = open (fic_etat, "r")
1128           les_lignes = fic.readlines()
1129           fic.close()
1130           if len(les_lignes) > 0 :
1131             if len(les_lignes[0]) > 0 :
1132               laux = les_lignes[0].split()
1133               laux1 = laux[0].split("=")
1134               etat = laux1[1]
1135               laux1 = laux[1].split("=")
1136               diag = laux1[1]
1137               if self.verbose_max :
1138                 print etat, diag
1139               if etat in ( "RUN", "PEND" ) :
1140                 encore += 1
1141               else :
1142                 if etat != "ENDED" :
1143                   self.message_info += "Etat du job : " + etat
1144                   erreur = -2
1145                 else :
1146                   if diag[:3] in ( "<S>", "<F>" ) :
1147                     erreur = -3
1148                 if erreur :
1149                   self.message_info = "Diagnostic du job : " + diag + "\n"
1150                 encore = 0
1151                 break
1152             else :
1153               encore += 1
1154           else :
1155             encore += 1
1156         else :
1157           erreur = -4
1158           break
1159 #
1160       os.remove(fic_etat_2)
1161 #
1162     if self.verbose_max :
1163       print blabla
1164       print ". erreur :", erreur
1165 #
1166     if erreur :
1167       message_erreur = "Erreur dans le calcul"
1168 #
1169     return erreur, message_erreur
1170 #
1171 #=========================  Fin de la fonction ===================================
1172 #
1173 #========================= Debut de la fonction ==================================
1174 #
1175   def post_aster ( self, dico_resu_init ) :
1176 #
1177     """
1178 Affichage de resultats selon les cas
1179     """
1180 #
1181     messages_erreur = { 0 : None,
1182                         1 : "Ce fichier est inconnu." }
1183 #
1184     nom_fonction = __name__ + "/post_aster"
1185     blabla = "\nDans " + nom_fonction + ","
1186 #
1187     erreur = 0
1188     message_erreur = " "
1189 #
1190     dico_resu = {}
1191     for cle in dico_resu_init.keys() :
1192       dico_resu[cle] = dico_resu_init[cle]
1193 #
1194     while not erreur :
1195 #
1196 # 1. Exploration du fichier resu
1197 #
1198 # 1.1. Recuperation du contenu
1199 #
1200       nomfic = self.dico["resu"]
1201       chaine = "V_TEST"
1202       nuocc = 1
1203       erreur, message_erreur, info = self.post_aster_1 ( nomfic, chaine, nuocc )
1204       if ( erreur > 0 ) :
1205         break
1206 #
1207 # 1.2. Details
1208 #
1209       if ( erreur == 0 ) :
1210         self.message_info += info[:-1]
1211         info = info.replace(chaine, " ")
1212         laux = info[:-1].split()
1213         aux = laux[0]
1214         if ( "D" in aux ) :
1215           aux = aux.replace("D", "E")
1216         dico_resu[chaine] = float(aux)
1217       else :
1218         erreur = 0
1219         message_erreur = " "
1220 #
1221 # 2. Exploration du fichier mess
1222 # 2.1. Que chercher ?
1223 #
1224       for chaine in ( "INSTANT", "NOMBRE DE NOEUDS", "NOMBRE DE MAILLES" ) :
1225 #
1226 # 2.2. Recuperation du contenu
1227 #
1228         nomfic = self.dico["mess"]
1229         if chaine == "INSTANT" :
1230           nuocc = 0
1231         else :
1232           nuocc = 1
1233         erreur, message_erreur, info = self.post_aster_1 ( nomfic, chaine, nuocc )
1234         if ( erreur > 0 ) :
1235           break
1236 #
1237 # 2.3. Details
1238 #
1239         if ( erreur == 0 ) :
1240           self.message_info += info[:-1]
1241           if chaine == "INSTANT" :
1242             l_aux = info[:-1].split()
1243             lg_aux = len(l_aux)
1244             for iaux in range(lg_aux) :
1245               if ( "ORDRE" in l_aux[iaux] ) :
1246                 if l_aux[iaux+1] == ":" :
1247                   jaux = iaux+2
1248                 else :
1249                   jaux = iaux+1
1250                 ordre = int(l_aux[jaux])
1251                 dico_resu["ORDRE"] = ordre
1252                 dico_resu["PAS_DE_TEMPS"] = ordre
1253           elif chaine in ( "NOMBRE DE NOEUDS", "NOMBRE DE MAILLES" ) :
1254             l_aux = info[:-1].split(chaine)
1255             dico_resu[chaine] = int(l_aux[1])
1256         else :
1257           erreur = 0
1258           message_erreur = " "
1259 #
1260       if erreur :
1261         break
1262 #
1263 # 3. Fichier de resultats au format med
1264 #
1265       dico_resu["FileName"] = self.dico["rmed"]
1266 #
1267       break
1268 #
1269     if self.verbose :
1270       print blabla
1271       print ". erreur :", erreur
1272       print ". dico_resu :", dico_resu
1273 #
1274     if erreur :
1275       message_erreur = messages_erreur[erreur]
1276 #
1277     return erreur, message_erreur, dico_resu
1278 #
1279 #=========================  Fin de la fonction ===================================
1280 #
1281 #========================= Debut de la fonction ==================================
1282 #
1283   def post_aster_1 ( self, nomfic, chaine, nuocc ) :
1284 #
1285     """
1286 Decodage de fichier
1287 nomfic = nom du fichier a decoder
1288 chaine = chaine a chercher
1289 nuocc = numero de l'occurence a chercher, 0 si toutes
1290 Retour :
1291 codret = 0 : tout va bien
1292          1 : le fichier de resultats est absent
1293         -1 : la chaine est absente
1294 message_erreur = "" : tout va bien
1295                != "" si probleme
1296 info = la ou les lignes recherchees
1297     """
1298 #
1299     messages_erreur = { 0 : None,
1300                        -1 : "La chaine est absente.",
1301                         1 : "Ce fichier est inconnu." }
1302 #
1303     nom_fonction = __name__ + "/post_aster_1"
1304     blabla = "\nDans " + nom_fonction + " :"
1305     if self.verbose_max :
1306       print blabla, "nomfic =", nomfic, "chaine =", chaine, ", nuocc =", nuocc
1307 #
1308     trouve = False
1309     erreur = 0
1310     message_erreur = " "
1311     info = ""
1312 #
1313     while not erreur :
1314 #
1315 # 1. Lecture du fichier
1316 #
1317       if not os.path.isfile(nomfic) :
1318         self.message_info += "\nFichier "+nomfic+"\n"
1319         erreur = 1
1320         break
1321       fic = open (nomfic, "r")
1322       les_lignes = fic.readlines()
1323       fic.close()
1324 #
1325 # 2. Exploration des lignes
1326 # 2.1. On recupere tout
1327 #
1328       if chaine == None :
1329 #
1330         for ligne in les_lignes :
1331           info += ligne
1332 #
1333 # 2.2. On cible
1334 #
1335       else :
1336 #
1337         iaux = 0
1338         for ligne in les_lignes :
1339           if chaine in ligne :
1340             iaux += 1
1341             if ( ( nuocc == 0 ) or ( iaux == nuocc ) ) :
1342               info += ligne
1343               if ( not trouve ) :
1344                 self.message_info += "\n"
1345                 trouve = True
1346 #
1347       break
1348 #
1349     if ( not trouve ) :
1350       erreur = -1
1351 #
1352     if ( self.verbose_max or ( erreur>0 ) ) :
1353       print blabla, "nomfic =", nomfic, "chaine =", chaine, ", nuocc =", nuocc
1354       print ". erreur =", erreur
1355 #
1356     if erreur :
1357       message_erreur = messages_erreur[erreur]
1358 #
1359     return erreur, message_erreur, info
1360 #
1361 #=========================  Fin de la fonction ===================================
1362 #
1363 #========================= Debut de la fonction ==================================
1364 #
1365   def dump_resultat ( self ) :
1366 #
1367     """
1368 Dump du resultat du calcul
1369     """
1370 #
1371     messages_erreur = { 0 : None }
1372 #
1373     nom_fonction = __name__ + "/dump_resultat"
1374     blabla = "\nDans " + nom_fonction + ","
1375 #
1376     erreur = 0
1377     message_erreur = " "
1378 #
1379 # 1. Lancement
1380 #
1381     nomfic_donn = os.path.join(self.rep_calc, "donn")
1382     fic = open (nomfic_donn, "w")
1383     fic.write("1\n1\n1\n")
1384     fic.close()
1385     fic_dump = self.dico["rmed"]+".dump"
1386     commande = "mdump " + self.dico["rmed"] + "<" + nomfic_donn + ">" + fic_dump
1387     #print commande
1388     erreur = os.system(commande)
1389     if erreur :
1390       messages_erreur[erreur] = "Erreur de dump numero %d" % erreur
1391     else :
1392       self.message_info += "\nDump dans le fichier :\n"
1393       self.message_info += fic_dump+"\n"
1394 #
1395     if self.verbose_max :
1396       print blabla
1397       print ". erreur :", erreur
1398 #
1399     os.remove(nomfic_donn)
1400 #
1401     if erreur :
1402       message_erreur = messages_erreur[erreur]
1403 #
1404     return erreur, message_erreur
1405 #
1406 #=========================  Fin de la fonction ===================================
1407 #
1408 #
1409 if __name__ == "__main__" :
1410 #
1411   #print "Arguments a l'entree de",  sys.argv[0], ":", sys.argv[1:], "\n"
1412 #
1413   Script_A = Script(sys.argv[1:])
1414 #
1415   if Script_A.affiche_aide_globale :
1416     Script_A.message_info = Script_A.__doc__
1417     erreur_m = 0
1418     message_erreur_m = ""
1419   else :
1420     dico_resu_m = {}
1421     erreur_m, message_erreur_m, dico_resu_m = Script_A.compute ()
1422 #
1423   sys.stdout.write(Script_A.message_info+"\n")
1424   sys.stderr.write(message_erreur_m+"\n")
1425   sys.exit(erreur_m)