Salome HOME
CCAR: merge de la version 1.14 dans la branche principale
[tools/eficas.git] / Aster / Cata / cataSTA8 / Macro / calc_fonction_ops.py
1 #@ MODIF calc_fonction_ops Macro  DATE 03/10/2007   AUTEUR SALMONA L.SALMONA 
2 # -*- coding: iso-8859-1 -*-
3 #            CONFIGURATION MANAGEMENT OF EDF VERSION
4 # ======================================================================
5 # COPYRIGHT (C) 1991 - 2005  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 import copy
22 import traceback
23 from math import pi
24
25
26 # -----------------------------------------------------------------------------
27 def tocomplex(arg):
28     if arg[0]=='RI' : return complex(arg[1],arg[2])
29     if arg[0]=='MP' : return complex(arg[1]*cos(arg[2]),arg[1]*sin(arg[2]))
30
31
32 # -----------------------------------------------------------------------------
33 def calc_fonction_ops(self,FFT,DERIVE,INTEGRE,LISS_ENVELOP,
34                       SPEC_OSCI,ABS,COMB,COMB_C,COMPOSE,EXTRACTION,
35                       ENVELOPPE,ASSE,CORR_ACCE,PUISSANCE,INVERSE,
36                       NOM_PARA,NOM_RESU,INTERPOL,PROL_DROITE,
37                       PROL_GAUCHE,NOM_PARA_FONC,INTERPOL_FONC,PROL_DROITE_FONC,
38                       PROL_GAUCHE_FONC,INFO,**args):
39    """
40       Ecriture de la macro CALC_FONCTION
41    """
42    ier=0
43    from Utilitai.t_fonction import t_fonction, t_fonction_c, t_nappe, homo_support_nappe, \
44             FonctionError, ParametreError, InterpolationError, ProlongementError
45    from Utilitai import liss_enveloppe
46    from Accas import _F
47    from Cata.cata import nappe_sdaster,fonction_sdaster,fonction_c
48    from Utilitai.Utmess import UTMESS
49    from Numeric import alltrue,less,array,reshape,cos,sin,exp,sqrt
50    from Numeric import choose,zeros,Float
51    import aster_fonctions
52    EnumTypes = (list, tuple)
53    
54    ### On importe les definitions des commandes a utiliser dans la macro
55    DEFI_FONCTION  = self.get_cmd('DEFI_FONCTION')
56    IMPR_FONCTION  = self.get_cmd('IMPR_FONCTION')
57    DEFI_NAPPE     = self.get_cmd('DEFI_NAPPE')
58    
59    ### Comptage commandes + déclaration concept sortant
60    self.set_icmd(1)
61    self.DeclareOut('C_out',self.sd)
62    
63    # éléments de contexte
64    ctxt = Context()
65    ### l'ensemble est dans un try/except pour recuperer les erreurs du module t_fonction
66    try:
67       ###
68       if (INTEGRE     != None):
69          __ff=INTEGRE['FONCTION'].convert()
70          ctxt.f = __ff.nom
71          if INTEGRE['METHODE']=='TRAPEZE' :
72             __ex=__ff.trapeze(INTEGRE['COEF'])
73          elif INTEGRE['METHODE']=='SIMPSON' :
74             __ex=__ff.simpson(INTEGRE['COEF'])
75       ###
76       if (DERIVE      != None):
77          __ff=DERIVE['FONCTION'].convert()
78          ctxt.f = __ff.nom
79          __ex=__ff.derive()
80       ###
81       if (INVERSE     != None):
82          __ff=INVERSE['FONCTION'].convert()
83          ctxt.f = __ff.nom
84          __ex=__ff.inverse()
85       ###
86       if (ABS         != None): 
87          __ff=ABS['FONCTION'].convert()
88          ctxt.f = __ff.nom
89          __ex=__ff.abs()
90       ###
91       if (COMPOSE     != None): 
92          __ff=COMPOSE['FONC_RESU'].convert()
93          __fg=COMPOSE['FONC_PARA'].convert()
94          ctxt.f = [__ff.nom, __fg.nom]
95          __ex=__ff[__fg]
96       ###
97       if (ASSE        != None):
98          __f0=ASSE['FONCTION'][0].convert()
99          __f1=ASSE['FONCTION'][1].convert()
100          ctxt.f = [__f0.nom, __f1.nom]
101          __ex=__f0.cat(__f1,ASSE['SURCHARGE'])
102       ###
103       if (COMB != None):
104          list_fonc=[]
105          if isinstance(self.sd,nappe_sdaster):
106             for mcfact in COMB :
107                list_fonc.append(mcfact['FONCTION'].convert())
108             ctxt.f = [f.nom for f in list_fonc]
109             list_fonc = homo_support_nappe(list_fonc)
110          elif isinstance(self.sd,fonction_sdaster):
111             for mcfact in COMB :
112                __ex=mcfact['FONCTION'].convert()
113                list_fonc.append(__ex)
114          
115          __ex = 0.
116          for item, comb in zip(list_fonc, COMB):
117             ctxt.f = item.nom
118             __ex = item * comb['COEF'] + __ex
119          # on prend les paramètres de la 1ère fonction
120          __ex.para = copy.copy(list_fonc[0].para)
121       ###
122       if (COMB_C != None):
123          list_fonc=[]
124          if isinstance(self.sd,nappe_sdaster):
125             for mcfact in COMB_C:
126                list_fonc.append(mcfact['FONCTION'].convert())
127             ctxt.f = [f.nom for f in list_fonc]
128             list_fonc = homo_support_nappe(list_fonc)
129          elif isinstance(self.sd,fonction_sdaster) or isinstance(self.sd,fonction_c):
130             for mcfact in COMB_C :
131                __ex=mcfact['FONCTION'].convert(arg='complex')
132                list_fonc.append(__ex)
133       
134          __ex = 0.
135          for item, comb in zip(list_fonc, COMB_C):
136             if comb['COEF_R'] != None:
137                coef = complex(comb['COEF_R'])
138             elif comb['COEF_C'] != None:
139                if type(comb['COEF_C']) in EnumTypes:
140                   coef = tocomplex(comb['COEF_C'])
141                else:
142                   coef = comb['COEF_C']
143             ctxt.f = item.nom
144             __ex = item * coef + __ex
145          # on prend les paramètres de la 1ère fonction
146          __ex.para = copy.copy(list_fonc[0].para)
147       
148       ### mot clé LIST_PARA uniquement présent si COMB ou COMB_C
149       if (COMB != None) or (COMB_C != None) :
150          if (args['LIST_PARA'] != None) :
151             __ex=__ex.evalfonc(args['LIST_PARA'].Valeurs())
152       ###
153       if (PUISSANCE   != None): 
154          __ff=PUISSANCE['FONCTION'].convert()
155          ctxt.f = __ff.nom
156          __ex=__ff
157          for i in range(PUISSANCE['EXPOSANT']-1):
158             __ex=__ex*__ff
159       ###
160       if (EXTRACTION  != None):
161          if EXTRACTION['PARTIE']=='REEL':
162             __ex=EXTRACTION['FONCTION'].convert(arg='real')
163          if EXTRACTION['PARTIE']=='IMAG':
164             __ex=EXTRACTION['FONCTION'].convert(arg='imag')
165          if EXTRACTION['PARTIE']=='MODULE':
166             __ex=EXTRACTION['FONCTION'].convert(arg='modul')
167          if EXTRACTION['PARTIE']=='PHASE':
168             __ex=EXTRACTION['FONCTION'].convert(arg='phase')
169       ###
170       if (ENVELOPPE   != None):
171          list_fonc=[]
172          l_env=ENVELOPPE['FONCTION']
173          if type(l_env) not in EnumTypes:
174             l_env=(l_env,)
175          if isinstance(self.sd,nappe_sdaster):
176             for f in l_env:
177                list_fonc.append(f.convert())
178             ctxt.f = [f.nom for f in list_fonc]
179             list_fonc = homo_support_nappe(list_fonc)
180             vale_para=list_fonc[0].vale_para
181             para     =list_fonc[0].para
182             l_fonc_f =[]
183             for i in range(len(vale_para)):
184                __ff=list_fonc[0].l_fonc[i]
185                for nap in list_fonc[1:] :
186                   ctxt.f = nap.l_fonc[i].nom
187                   __ff=__ff.enveloppe(nap.l_fonc[i], ENVELOPPE['CRITERE'])
188                l_fonc_f.append(__ff)
189             __ex=t_nappe(vale_para,l_fonc_f,para)
190          elif isinstance(self.sd,fonction_sdaster):
191             for f in l_env:
192                list_fonc.append(f.convert())
193             __ex=list_fonc[0]
194             for f in list_fonc[1:]:
195                ctxt.f = [__ex.nom, f.nom]
196                __ex = __ex.enveloppe(f, ENVELOPPE['CRITERE'])
197       ###
198       if (CORR_ACCE   != None):
199          __ex=CORR_ACCE['FONCTION'].convert()
200          ctxt.f = __ex.nom
201          para=copy.copy(__ex.para)
202          # suppression de la tendance de l accelero
203          __ex=__ex.suppr_tend()
204          # calcul de la vitesse
205          __ex=__ex.trapeze(0.)
206          # calcul de la tendance de la vitesse : y = a1*x +a0
207          __ex=__ex.suppr_tend()
208          if CORR_ACCE['CORR_DEPL']=='OUI':
209             # suppression de la tendance deplacement
210             # calcul du deplacement : integration
211             __ex=__ex.trapeze(0.)
212             # calcul de la tendance du déplacement : y = a1*x +a0
213             __ex=__ex.suppr_tend()
214             # regeneration de la vitesse : derivation
215             __ex=__ex.derive()
216          # regeneration de l accelero : derivation
217          __ex=__ex.derive()
218          __ex.para=para
219       ###
220       if (FFT         != None):
221          if isinstance(self.sd,fonction_c):
222             __ff=FFT['FONCTION'].convert()
223             ctxt.f = __ff.nom
224             __ex=__ff.fft(FFT['METHODE'])
225          if isinstance(self.sd,fonction_sdaster):
226             __ff=FFT['FONCTION'].convert(arg='complex')
227             ctxt.f = __ff.nom
228             __ex=__ff.fft(FFT['METHODE'],FFT['SYME'])
229       ###
230       if (SPEC_OSCI   != None):
231          if SPEC_OSCI['AMOR_REDUIT']==None:
232             l_amor=[0.02, 0.05, 0.1]
233             UTMESS('I','CALC_FONCTION',' : génération par défaut de 3 amortissements :'+str(l_amor))
234          else:
235             if type(SPEC_OSCI['AMOR_REDUIT']) not in EnumTypes :
236                l_amor=[SPEC_OSCI['AMOR_REDUIT'],]
237             else:
238                l_amor= SPEC_OSCI['AMOR_REDUIT']
239          if SPEC_OSCI['FREQ']==None and SPEC_OSCI['LIST_FREQ']==None:
240             l_freq=[]
241             for i in range(56):
242                l_freq.append( 0.2+0.050*i)
243             for i in range( 8):
244                l_freq.append( 3.0+0.075*i)
245             for i in range(14):
246                l_freq.append( 3.6+0.100*i)
247             for i in range(24):
248                l_freq.append( 5.0+0.125*i)
249             for i in range(28):
250                l_freq.append( 8.0+0.250*i)
251             for i in range( 6):
252                l_freq.append(15.0+0.500*i)
253             for i in range( 4):
254                l_freq.append(18.0+1.000*i)
255             for i in range(10):
256                l_freq.append(22.0+1.500*i)
257             texte=[]
258             for i in range(len(l_freq)/5) :
259                texte.append(' %f %f %f %f %f' %tuple(l_freq[i*5:i*5+5]))
260             UTMESS('I','CALC_FONCTION',' : génération par défaut de 150 fréquences :\n'+'\n'.join(texte))
261          elif SPEC_OSCI['LIST_FREQ']!=None:
262             l_freq=SPEC_OSCI['LIST_FREQ'].Valeurs()
263          elif SPEC_OSCI['FREQ']!=None:
264             if type(SPEC_OSCI['FREQ']) not in EnumTypes:
265                l_freq=[SPEC_OSCI['FREQ'],]
266             else:
267                l_freq= SPEC_OSCI['FREQ']
268          if min(l_freq)<1.E-10 :
269             UTMESS('S','CALC_FONCTION','Les fréquences doivent etre strictement positives.')
270          if abs(SPEC_OSCI['NORME'])<1.E-10 :
271             UTMESS('S','CALC_FONCTION',' : SPEC_OSCI, la norme ne peut etre nulle')
272          if SPEC_OSCI['NATURE_FONC']!='ACCE' :
273             UTMESS('S','CALC_FONCTION',' : SPEC_OSCI, le type de la fonction doit etre ACCE')
274          if SPEC_OSCI['METHODE']!='NIGAM' :
275             UTMESS('S','CALC_FONCTION',' : SPEC_OSCI, seule la méthode NIGAM est codée')
276          eps=1.e-6
277          for amor in l_amor :
278             if amor>(1-eps) :
279                UTMESS('S','CALC_FONCTION',' : SPEC_OSCI, la méthode choisie '\
280                         'suppose des amortissements sous-critiques, amor<1.')
281       
282          __ff=SPEC_OSCI['FONCTION'].convert()
283          ctxt.f = __ff.nom
284          
285          # appel à SPEC_OSCI
286          spectr = aster_fonctions.SPEC_OSCI(__ff.vale_x, __ff.vale_y, l_freq, l_amor)
287       
288          # construction de la nappe
289          vale_para = l_amor
290          para      = { 'INTERPOL'      : ['LIN','LOG'],
291                        'NOM_PARA_FONC' : 'FREQ',
292                        'NOM_PARA'      : 'AMOR',
293                        'PROL_DROITE'   : 'EXCLU',
294                        'PROL_GAUCHE'   : 'EXCLU',
295                        'NOM_RESU'      : SPEC_OSCI['NATURE'] }
296          para_fonc = { 'INTERPOL'      : ['LOG','LOG'],
297                        'NOM_PARA'      : 'FREQ',
298                        'PROL_DROITE'   : 'CONSTANT',
299                        'PROL_GAUCHE'   : 'EXCLU',
300                        'NOM_RESU'      : SPEC_OSCI['NATURE'] }
301          if   SPEC_OSCI['NATURE']=='DEPL':
302             ideb = 0
303          elif SPEC_OSCI['NATURE']=='VITE':
304             ideb = 1
305          else:
306             ideb = 2
307          l_fonc = []
308          for iamor in range(len(l_amor)) :
309             l_fonc.append(t_fonction(l_freq,spectr[iamor,ideb,:]/SPEC_OSCI['NORME'],para_fonc))
310          __ex=t_nappe(vale_para,l_fonc,para)
311       ###
312       if (LISS_ENVELOP!= None):
313          __ff=LISS_ENVELOP['NAPPE'].convert()
314          sp_nappe=liss_enveloppe.nappe(listFreq=__ff.l_fonc[0].vale_x, listeTable=[f.vale_y for f in __ff.l_fonc], listAmor=__ff.vale_para, entete="")
315          sp_lisse=liss_enveloppe.lissage(nappe=sp_nappe,fmin=LISS_ENVELOP['FREQ_MIN'],fmax=LISS_ENVELOP['FREQ_MAX'],elarg=LISS_ENVELOP['ELARG'],tole_liss=LISS_ENVELOP['TOLE_LISS'])
316          para_fonc=__ff.l_fonc[0].para
317          l_fonc=[]
318          for val in sp_lisse.listTable: 
319             l_fonc.append(t_fonction(sp_lisse.listFreq,val,para_fonc))
320          __ex=t_nappe(vale_para=sp_lisse.listAmor,l_fonc=l_fonc,para=__ff.para)
321
322    except InterpolationError, msg:
323       UTMESS('F', 'CALC_FONCTION', 'Un problème d interpolation a été rencontré'+ctxt.f+'Vérifier les valeurs fournies derrière'+
324       'le mot-clé INTERPOL lors de la création de cette(ces) fonction(s). Debug '+str(msg))
325    except ParametreError, msg:
326       UTMESS('F', 'CALC_FONCTION', 'Un problème concernant le nom des abscisses ou ordonnées a été rencontré'+ctxt.f+
327       'Vérifier la valeur fournie derrière les mots-clés NOM_PARA/NOM_RESU lors de la création de cette(ces) fonction(s).'+
328       'Debug : '+str(msg))
329    except ProlongementError, msg:
330       UTMESS('F', 'CALC_FONCTION','Un problème concernant le prolongement de la (des) fonction(s) a été rencontré.'+ctxt.f+
331       'Vérifier la valeur fournie derrière les mots-clés PROL_GAUCHE/PROL_DROITE lors de la création de cette(ces) fonction(s)'+
332       'Debug'+str(msg))
333    except FonctionError, msg:
334       UTMESS('F', 'CALC_FONCTION', 'Une erreur s est produite lors de l opération'+ctxt.f+'Debug :'+str(msg)+
335       'Remontée d erreur (pour aider a l analyse) :'+traceback.format_exc())
336
337    ### creation de la fonction produite par appel à DEFI_FONCTION
338    ### on récupère les paramètres issus du calcul de __ex
339    ### et on les surcharge par ceux imposés par l'utilisateur
340    
341    if isinstance(__ex,t_fonction) or isinstance(__ex,t_fonction_c):
342       para=__ex.para
343       if NOM_PARA   !=None : para['NOM_PARA']   =NOM_PARA
344       if NOM_RESU   !=None : para['NOM_RESU']   =NOM_RESU
345       if PROL_DROITE!=None : para['PROL_DROITE']=PROL_DROITE
346       if PROL_GAUCHE!=None : para['PROL_GAUCHE']=PROL_GAUCHE
347       if INTERPOL   !=None : para['INTERPOL']   =INTERPOL
348       if   isinstance(__ex,t_fonction_c): para['VALE_C'] = __ex.tabul()
349       elif isinstance(__ex,t_fonction)  : para['VALE']   = __ex.tabul()
350       C_out=DEFI_FONCTION(**para)
351    elif isinstance(__ex,t_nappe):
352       def_fonc=[]
353       for f in __ex.l_fonc :
354          para=f.para
355          def_fonc.append(_F(VALE       =f.tabul(),
356                             INTERPOL   =f.para['INTERPOL'],
357                             PROL_DROITE=f.para['PROL_DROITE'],
358                             PROL_GAUCHE=f.para['PROL_GAUCHE'],))
359       para=__ex.para
360       if NOM_PARA      !=None : para['NOM_PARA']   =NOM_PARA
361       if NOM_RESU      !=None : para['NOM_RESU']   =NOM_RESU
362       if PROL_DROITE   !=None : para['PROL_DROITE']=PROL_DROITE
363       if PROL_GAUCHE   !=None : para['PROL_GAUCHE']=PROL_GAUCHE
364       if NOM_PARA_FONC !=None : para['NOM_PARA_FONC']   =INTERPOL
365       if INTERPOL_FONC !=None : para['INTERPOL']   =INTERPOL
366       C_out=DEFI_NAPPE(PARA=__ex.vale_para.tolist(),DEFI_FONCTION=def_fonc,**para)
367    if INFO > 1:
368       IMPR_FONCTION(FORMAT='TABLEAU',
369                     UNITE=6,
370                     COURBE=_F(FONCTION=C_out),)
371    return ier
372
373
374 # -----------------------------------------------------------------------------
375 class Context(object):
376    """Permet de stocker des éléments de contexte pour aider au
377    diagnostic lors de l'émission de message.
378    usage :
379       context = Context()
380       context.f = 'nomfon'
381       print context.f
382    """
383    def __init__(self):
384       self.__nomf = None
385    
386    def get_val(self):
387       """Retourne le texte formatté.
388       """
389       nomf = self.__nomf
390       if type(nomf) not in (list, tuple):
391          nomf = [nomf,]
392       pluriel = ''
393       if len(nomf) > 1:
394          pluriel = 's'
395       try:
396          res = """Fonction%(s)s concernée%(s)s : %(nomf)s""" % {
397             's'    : pluriel,
398             'nomf' : ', '.join(nomf),
399          }
400       except:
401          res = 'erreur de programmation !'
402       return res
403    
404    def set_val(self, value):
405       self.__nomf = value
406    
407    def del_val(self):
408       del self.__nomf
409    
410    f = property(get_val, set_val, del_val, "")