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