]> SALOME platform Git repositories - tools/eficas.git/blob - Aster/Cata/cataSTA10/ops.py
Salome HOME
258662733de4cfce1b1bbecb0a3402cc13e9f145
[tools/eficas.git] / Aster / Cata / cataSTA10 / ops.py
1 #@ MODIF ops Cata  DATE 23/03/2010   AUTEUR COURTOIS M.COURTOIS 
2 # -*- coding: iso-8859-1 -*-
3 #            CONFIGURATION MANAGEMENT OF EDF VERSION
4 # ======================================================================
5 # COPYRIGHT (C) 1991 - 2001  EDF R&D                  WWW.CODE-ASTER.ORG
6 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
7 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
8 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR   
9 # (AT YOUR OPTION) ANY LATER VERSION.                                 
10 #
11 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT 
12 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF          
13 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU    
14 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.                            
15 #
16 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE   
17 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,       
18 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.      
19 # ======================================================================
20
21
22 # Modules Python
23 import types
24 import string,linecache,os,traceback,re
25 import pickle
26 import re
27
28 # Modules Eficas
29 import Accas
30 from Accas import ASSD
31 from Noyau.ascheckers     import CheckLog
32
33 try:
34    import aster
35    aster_exists = True
36    # Si le module aster est présent, on le connecte
37    # au JDC
38    import Build.B_CODE
39    Build.B_CODE.CODE.codex=aster
40    
41    from Utilitai.Utmess   import UTMESS
42    from Build.B_SENSIBILITE_MEMO_NOM_SENSI import MEMORISATION_SENSIBILITE
43    from Execution.E_Global import MessageLog
44 except:
45    aster_exists = False
46
47
48 def commun_DEBUT_POURSUITE(jdc, PAR_LOT, IMPR_MACRO, CODE, DEBUG, IGNORE_ALARM):
49    """Fonction sdprod partie commune à DEBUT et POURSUITE.
50    (on stocke un entier au lieu du logique)
51    """
52    jdc.par_lot    = PAR_LOT
53    jdc.impr_macro = int(IMPR_MACRO == 'OUI')
54    jdc.jxveri     = int(CODE != None or (DEBUG != None and DEBUG['JXVERI'] == 'OUI'))
55    jdc.sdveri     = int(DEBUG != None and DEBUG['SDVERI'] == 'OUI')
56    jdc.fico       = None
57    jdc.sd_checker = CheckLog()
58    if CODE != None:
59       jdc.fico = CODE['NOM']
60    if aster_exists:
61       # en POURSUITE, ne pas écraser la mémorisation existante.
62       if not hasattr(jdc, 'memo_sensi'):
63          jdc.memo_sensi = MEMORISATION_SENSIBILITE()
64       jdc.memo_sensi.reparent(jdc)
65
66       # ne faire qu'une fois
67       if not hasattr(jdc, 'msg_init'):
68          # messages d'alarmes désactivés
69          if IGNORE_ALARM:
70             if not type(IGNORE_ALARM) in (list, tuple):
71                IGNORE_ALARM = [IGNORE_ALARM]
72             for idmess in IGNORE_ALARM:
73                MessageLog.disable_alarm(idmess)
74                
75       # en POURSUITE, conserver le catalogue de comportement picklé
76       if not hasattr(jdc, 'catalc'):
77          from Comportement import catalc
78          jdc.catalc = catalc
79
80       jdc.msg_init = True
81
82
83 def DEBUT(self, PAR_LOT, IMPR_MACRO, CODE, DEBUG, IGNORE_ALARM, **args):
84    """
85        Fonction sdprod de la macro DEBUT
86    """
87    # La commande DEBUT ne peut exister qu'au niveau jdc
88    if self.jdc is not self.parent :
89       raise Accas.AsException("La commande DEBUT ne peut exister qu'au niveau jdc")
90
91    commun_DEBUT_POURSUITE(self.jdc, PAR_LOT, IMPR_MACRO, CODE, DEBUG, IGNORE_ALARM)
92
93
94 def build_debut(self,**args):
95    """
96    Fonction ops pour la macro DEBUT
97    """
98    self.jdc.UserError=self.codex.error
99
100    if self.jdc.par_lot == 'NON' :
101       self.jdc._Build()
102    # On execute la fonction debut pour initialiser les bases
103    # Cette execution est indispensable avant toute autre action sur ASTER
104    # op doit etre un entier car la fonction debut appelle GCECDU qui demande
105    # le numero de l'operateur associé (getoper)
106    self.definition.op=0
107    self.set_icmd(1)
108    lot,ier=self.codex.debut(self,1)
109    # On remet op a None juste apres pour eviter que la commande DEBUT
110    # ne soit executée dans la phase d'execution
111    self.definition.op=None
112    return ier
113
114 def POURSUITE(self, PAR_LOT, IMPR_MACRO, CODE, DEBUG, IGNORE_ALARM, **args):
115    """
116        Fonction sdprod de la macro POURSUITE
117    """
118    # La commande POURSUITE ne peut exister qu'au niveau jdc
119    if self.jdc is not self.parent :
120       raise Accas.AsException("La commande POURSUITE ne peut exister qu'au niveau jdc")
121
122    commun_DEBUT_POURSUITE(self.jdc, PAR_LOT, IMPR_MACRO, CODE, DEBUG, IGNORE_ALARM)
123    
124    if (self.codex and os.path.isfile("glob.1") or os.path.isfile("bhdf.1")):
125      # Le module d'execution est accessible et glob.1 est present
126      # Pour eviter de rappeler plusieurs fois la sequence d'initialisation
127      # on memorise avec l'attribut fichier_init que l'initialisation
128      # est réalisée
129      if hasattr(self,'fichier_init'):return
130      self.fichier_init='glob.1'
131      self.jdc.initexec()
132      # le sous programme fortran appelé par self.codex.poursu demande le numero
133      # de l'operateur (GCECDU->getoper), on lui donne la valeur 0
134      self.definition.op=0
135      lot,ier,lonuti,concepts=self.codex.poursu(self,1)
136      # Par la suite pour ne pas executer la commande pendant la phase
137      # d'execution on le remet à None
138      self.definition.op=None
139      # On demande la numerotation de la commande POURSUITE avec l'incrément
140      # lonuti pour qu'elle soit numérotée à la suite des commandes existantes.
141 ####CD     self.set_icmd(lonuti)    Non : on repart à zéro
142      pos=0
143      d={}
144      while pos+80 < len(concepts)+1:
145        nomres=concepts[pos:pos+8]
146        concep=concepts[pos+8:pos+24]
147        nomcmd=concepts[pos+24:pos+40]
148        statut=concepts[pos+40:pos+48]
149        print nomres,concep,nomcmd,statut
150        if nomres[0] not in (' ','.','&') and statut != '&DETRUIT':
151           exec nomres+'='+string.lower(concep)+'()' in self.parent.g_context,d
152        elif statut == '&DETRUIT' : self.jdc.nsd = self.jdc.nsd+1
153        pos=pos+80
154      # ces ASSD seront écrasées par le pick.1,
155      # on vérifiera la cohérence de type entre glob.1 et pick.1
156      for k,v in d.items():
157        self.parent.NommerSdprod(v,k)
158      self.g_context=d
159
160      # Il peut exister un contexte python sauvegardé sous forme  pickled
161      # On récupère ces objets après la restauration des concepts pour que
162      # la récupération des objets pickled soit prioritaire.
163      # On vérifie que les concepts relus dans glob.1 sont bien tous
164      # presents sous le meme nom et du meme type dans pick.1
165      # Le contexte est ensuite updaté (surcharge) et donc enrichi des
166      # variables qui ne sont pas des concepts.
167      # On supprime du pickle_context les concepts valant None, ca peut 
168      # etre le cas des concepts non executés, placés après FIN.
169      pickle_context=get_pickled_context()
170      if pickle_context==None :
171         UTMESS('F','SUPERVIS_86')
172         return
173      self.jdc.restore_pickled_attrs(pickle_context)
174      from Cata.cata  import ASSD,entier
175      from Noyau.N_CO import CO
176      for elem in pickle_context.keys():
177          if isinstance(pickle_context[elem], ASSD):
178             pickle_class=pickle_context[elem].__class__
179             # on rattache chaque assd au nouveau jdc courant (en poursuite)
180             pickle_context[elem].jdc=self.jdc
181             pickle_context[elem].parent=self.jdc
182             # le marquer comme 'executed'
183             pickle_context[elem].executed = 1
184             # pour que sds_dict soit cohérent avec g_context
185             self.jdc.sds_dict[elem] = pickle_context[elem]
186             if elem != pickle_context[elem].nom:
187                name = re.sub('_([0-9]+)$', '[\\1]', pickle_context[elem].nom)
188                UTMESS('A', 'SUPERVIS_93', valk=(elem, name))
189                del pickle_context[elem]
190                continue
191             # rétablir le parent pour les attributs de la SD
192             pickle_context[elem].reparent_sd()
193             if elem in self.g_context.keys():
194                poursu_class=self.g_context[elem].__class__
195                if poursu_class!=pickle_class :
196                   UTMESS('F','SUPERVIS_87',valk=[elem])
197                   return
198             elif isinstance(pickle_context[elem],ASSD) and pickle_class not in (CO,entier) : 
199             # on n'a pas trouvé le concept dans la base et sa classe est ASSD : ce n'est pas normal
200             # sauf dans le cas de CO : il n'a alors pas été typé et c'est normal qu'il soit absent de la base
201             # meme situation pour le type 'entier' produit uniquement par DEFI_FICHIER
202                UTMESS('F','SUPERVIS_88',valk=[elem,str(pickle_class)])
203                return
204          if pickle_context[elem]==None : del pickle_context[elem]
205      self.g_context.update(pickle_context)
206      return
207
208    else:
209      # Si le module d'execution n est pas accessible ou glob.1 absent on 
210      # demande un fichier (EFICAS)
211      # Il faut éviter de réinterpréter le fichier à chaque appel de
212      # POURSUITE
213      if hasattr(self,'fichier_init'):
214         return
215      self.make_poursuite()
216
217 def get_pickled_context():
218     """
219        Cette fonction permet de réimporter dans le contexte courant du jdc (jdc.g_context)
220        les objets python qui auraient été sauvegardés, sous forme pickled, lors d'une 
221        précédente étude. Un fichier pick.1 doit etre présent dans le répertoire de travail
222     """
223     fpick = 'pick.1'
224     if not os.path.isfile(fpick):
225        return None
226    
227     # Le fichier pick.1 est présent. On essaie de récupérer les objets python sauvegardés
228     context={}
229     try:
230        file=open(fpick,'r')
231        # Le contexte sauvegardé a été picklé en une seule fois. Il est seulement
232        # possible de le récupérer en bloc. Si cette opération echoue, on ne récupère
233        # aucun objet.
234        context=pickle.load(file)
235        file.close()
236     except:
237        # En cas d'erreur on ignore le contenu du fichier
238        traceback.print_exc()
239        return None
240
241     return context
242
243 def POURSUITE_context(self,d):
244    """
245        Fonction op_init de la macro POURSUITE
246    """
247    # self représente la macro POURSUITE ...
248    d.update(self.g_context)
249    # Une commande POURSUITE n'est possible qu'au niveau le plus haut
250    # On ajoute directement les concepts dans le contexte du jdc
251    # XXX est ce que les concepts ne sont pas ajoutés plusieurs fois ??
252    for v in self.g_context.values():
253       if isinstance(v,ASSD) :
254          self.jdc.sds.append(v)
255
256 def build_poursuite(self,**args):
257    """
258    Fonction ops pour la macro POURSUITE
259    """
260    # Pour POURSUITE on ne modifie pas la valeur initialisee dans ops.POURSUITE
261    # Il n y a pas besoin d executer self.codex.poursu (c'est deja fait dans
262    # la fonction sdprod de la commande (ops.POURSUITE))
263    self.set_icmd(1)
264    self.jdc.UserError=self.codex.error
265    return 0
266
267 def INCLUDE(self,UNITE,**args):
268    """ 
269        Fonction sd_prod pour la macro INCLUDE
270    """
271    if not UNITE : return
272    if hasattr(self,'unite'):return
273    self.unite=UNITE
274
275    if self.jdc and self.jdc.par_lot == 'NON':
276       # On est en mode commande par commande, on appelle la methode speciale
277       self.Execute_alone()
278
279    self.make_include(unite=UNITE)
280
281 def INCLUDE_context(self,d):
282    """ 
283        Fonction op_init pour macro INCLUDE
284    """
285    for k,v in self.g_context.items():
286       d[k]=v
287
288 def build_include(self,**args):
289    """
290    Fonction ops de la macro INCLUDE appelée lors de la phase de Build
291    """
292    # Pour presque toutes les commandes (sauf FORMULE et POURSUITE)
293    # le numero de la commande n est pas utile en phase de construction
294    # La macro INCLUDE ne sera pas numérotée (incrément=None)
295    ier=0
296    self.set_icmd(None)
297    icmd=0
298    # On n'execute pas l'ops d'include en phase BUILD car il ne sert a rien.
299    #ier=self.codex.opsexe(self,icmd,-1,1)
300    return ier
301
302 def detruire(self,d):
303    """
304        Cette fonction est la fonction op_init de la PROC DETRUIRE
305    """
306    list_co = set()
307    sd = []
308    # par nom de concept (typ=assd)
309    if self["CONCEPT"] != None:
310       for mc in self["CONCEPT"]:
311          mcs = mc["NOM"]
312          if type(mcs) not in (list, tuple):
313             mcs = [mcs]
314          list_co.update(mcs)
315    # par chaine de caractères (typ='TXM')
316    if self["OBJET"] != None:
317       for mc in self["OBJET"]:
318          mcs = mc["CHAINE"]
319          if type(mcs) not in (list, tuple):
320             mcs = [mcs]
321          # longueur <= 8, on cherche les concepts existants
322          for nom in mcs:
323             assert type(nom) in (str, unicode), 'On attend une chaine de caractères : %s' % nom
324             if len(nom.strip()) <= 8:
325                if self.jdc.sds_dict.get(nom) != None:
326                   list_co.add(self.jdc.sds_dict[nom])
327                elif d.get(nom) != None:
328                   list_co.add(d[nom])
329             #else uniquement destruction des objets jeveux
330    
331    for co in list_co:
332       assert isinstance(co, ASSD), 'On attend un concept : %s (type=%s)' % (co, type(co))
333       nom = co.nom
334       # traitement particulier pour les listes de concepts, on va mettre à None
335       # le terme de l'indice demandé dans la liste :
336       # nomconcept_i est supprimé, nomconcept[i]=None
337       i = nom.rfind('_')
338       if i > 0 and not nom.endswith('_'):
339          concept_racine = nom[:i]
340          if d.has_key(concept_racine) and type(d[concept_racine]) is list:
341             try:
342                num = int(nom[i+1:])
343                d[concept_racine][num] = None
344             except (ValueError, IndexError):
345                # cas : RESU_aaa ou (RESU_8 avec RESU[8] non initialisé)
346                pass
347       # pour tous les concepts :
348       if d.has_key(nom):
349          del d[nom]
350       if self.jdc.sds_dict.has_key(nom):
351          del self.jdc.sds_dict[nom]
352       # On signale au parent que le concept s n'existe plus apres l'étape self 
353       self.parent.delete_concept_after_etape(self, co)
354       # marque comme détruit == non executé
355       co.executed = 0
356
357
358 def subst_materiau(text,NOM_MATER,EXTRACTION,UNITE_LONGUEUR):
359    """
360        Cette fonction retourne un texte obtenu à partir du texte passé en argument (text)
361        en substituant le nom du materiau par NOM_MATER 
362        et en réalisant les extractions spéciifées dans EXTRACTION
363    """
364    lines=string.split(text,'\n')
365
366 ##### traitement de UNIT : facteur multiplicatif puissance de 10
367    regmcsu=re.compile(r" *(.*) *= *([^ ,]*) *## +([^ ]*) *([^ ]*)")
368    ll_u=[]
369    for l in lines:
370        m=regmcsu.match(l)
371        if m:
372           if m.group(3) == "UNIT":
373              if   UNITE_LONGUEUR=='M'  : coef = '0'
374              elif UNITE_LONGUEUR=='MM' : coef = m.group(4)
375              ll_u.append(m.group(1)+" = "+m.group(2)+coef)
376           else : ll_u.append(l)
377        else : ll_u.append(l)
378
379 ##### traitement de EXTRACTION
380    if EXTRACTION:
381      regmcf=re.compile(r" *(.*) *= *_F\( *## +(.*) +(.*)")
382      regmcs=re.compile(r" *(.*) *= *([^ ,]*) *, *## +([^ ]*) *([^ ]*)")
383      regfin=re.compile(r" *\) *")
384      ll=[]
385      temps={};lmcf=[]
386      for e in EXTRACTION:
387        mcf=e['COMPOR']
388        lmcf.append(mcf)
389        temps[mcf]=e['TEMP_EVAL']
390      FLAG=0
391      for l in ll_u:
392        m=regmcf.match(l)
393        if m: # On a trouve un mot cle facteur "commentarise"
394          if m.group(2) == "SUBST": # il est de plus substituable
395            if temps.has_key(m.group(3)): # Il est a substituer
396              ll.append(" "+m.group(3)+"=_F(")
397              mcf=m.group(3)
398              TEMP=temps[mcf]
399              FLAG=1 # Indique que l'on est en cours de substitution
400            else: # Il n est pas a substituer car il n est pas dans la liste demandee
401              ll.append(l)
402          else: # Mot cle facteur commentarise non substituable
403            ll.append(l)
404        else:  # La ligne ne contient pas un mot cle facteur commentarise
405          if FLAG == 0: # On n est pas en cours de substitution
406            ll.append(l)
407          else: # On est en cours de substitution. On cherche les mots cles simples commentarises
408            m=regmcs.match(l)
409            if m: # On a trouve un mot cle simple commentarise
410              if m.group(3) == "EVAL":
411                ll.append("  "+m.group(1)+' = '+m.group(4)+"("+str(TEMP)+'),')
412              elif m.group(3) == "SUPPR":
413                pass
414              else:
415                ll.append(l)
416            else: # On cherche la fin du mot cle facteur en cours de substitution
417              m=regfin.match(l)
418              if m: # On l a trouve. On le supprime de la liste
419                FLAG=0
420                del temps[mcf]
421              ll.append(l)
422    else:
423      ll=ll_u
424
425    lines=ll
426    ll=[]
427    for l in lines:
428      l=re.sub(" *MAT *= *",NOM_MATER+" = ",l,1)
429      ll.append(l)
430    text=string.join(ll,'\n')
431    return text
432
433 def post_INCLUDE(self):
434   """
435       Cette fonction est executée apres toutes les commandes d'un INCLUDE (RETOUR)
436       Elle sert principalement pour les INCLUDE_MATERIAU : remise a blanc du prefixe Fortran
437   """
438   self.codex.opsexe(self,0,-1,2)
439
440 def INCLUDE_MATERIAU(self,NOM_AFNOR,TYPE_MODELE,VARIANTE,TYPE_VALE,NOM_MATER,
441                     EXTRACTION,UNITE_LONGUEUR,INFO,**args):
442   """ 
443       Fonction sd_prod pour la macro INCLUDE_MATERIAU
444   """
445   mat=string.join((NOM_AFNOR,'_',TYPE_MODELE,'_',VARIANTE,'.',TYPE_VALE),'')
446   if not hasattr(self,'mat') or self.mat != mat or self.nom_mater != NOM_MATER :
447     # On récupère le répertoire des matériaux dans les arguments 
448     # supplémentaires du JDC
449     rep_mat=self.jdc.args.get("rep_mat","NOrep_mat")
450     f=os.path.join(rep_mat,mat)
451     self.mat=mat
452     self.nom_mater=NOM_MATER
453     if not os.path.isfile(f):
454        del self.mat
455        self.make_contexte(f,"#Texte sans effet pour reinitialiser le contexte a vide\n")
456        raise "Erreur sur le fichier materiau: "+f
457     # Les materiaux sont uniquement disponibles en syntaxe Python
458     # On lit le fichier et on supprime les éventuels \r
459     text=string.replace(open(f).read(),'\r\n','\n')
460     # On effectue les substitutions necessaires
461     self.text= subst_materiau(text,NOM_MATER,EXTRACTION,UNITE_LONGUEUR)
462     if INFO == 2:
463       print "INCLUDE_MATERIAU: ", self.mat,' ',NOM_MATER,'\n'
464       print self.text
465     # on execute le texte fourni dans le contexte forme par
466     # le contexte de l etape pere (global au sens Python)
467     # et le contexte de l etape (local au sens Python)
468     # Il faut auparavant l'enregistrer aupres du module linecache (utile pour nommage.py)
469     linecache.cache[f]=0,0,string.split(self.text,'\n'),f
470
471     self.postexec=post_INCLUDE
472
473     if self.jdc.par_lot == 'NON':
474       # On est en mode commande par commande, on appelle la methode speciale
475       self.Execute_alone()
476
477     self.make_contexte(f,self.text)
478     for k,v in self.g_context.items() :
479         if isinstance(v,ASSD) and k!=v.nom : del self.g_context[k]
480
481 def build_procedure(self,**args):
482     """
483     Fonction ops de la macro PROCEDURE appelée lors de la phase de Build
484     """
485     ier=0
486     # Pour presque toutes les commandes (sauf FORMULE et POURSUITE)
487     # le numero de la commande n est pas utile en phase de construction
488     # On ne numérote pas une macro PROCEDURE (incrément=None)
489     self.set_icmd(None)
490     icmd=0
491     #ier=self.codex.opsexe(self,icmd,-1,3)
492     return ier
493
494 def build_DEFI_FICHIER(self,**args):
495     """
496     Fonction ops de la macro DEFI_FICHIER
497     """
498     ier=0
499     self.set_icmd(1)
500     icmd=0
501     ier=self.codex.opsexe(self,icmd,-1,26)
502     return ier