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