1 #@ MODIF post_gp_ops Macro DATE 31/10/2006 AUTEUR REZETTE C.REZETTE
2 # -*- coding: iso-8859-1 -*-
3 # CONFIGURATION MANAGEMENT OF EDF VERSION
4 # ======================================================================
5 # COPYRIGHT (C) 1991 - 2006 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.
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.
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 # ======================================================================
21 from types import ListType, TupleType
22 EnumTypes = (ListType, TupleType)
25 # -----------------------------------------------------------------------------
26 def post_gp_ops(self, **args):
28 Corps de la macro POST_GP
33 from Utilitai.Utmess import UTMESS
34 from Utilitai.Table import Table, merge
35 from Utilitai.t_fonction import t_fonction
38 # ----- On importe les definitions des commandes a utiliser dans la macro
39 CALC_THETA = self.get_cmd('CALC_THETA')
40 CALC_G = self.get_cmd('CALC_G')
41 POST_ELEM = self.get_cmd('POST_ELEM')
42 POST_RELEVE_T = self.get_cmd('POST_RELEVE_T')
43 CREA_TABLE = self.get_cmd('CREA_TABLE')
45 # ----- Comptage, commandes + déclaration concept sortant
47 self.DeclareOut('result', self.sd)
48 self.DeclareOut('tabresult', self['TABL_RESU'])
51 # 0. ----- Type de calcul
52 identification = self['IDENTIFICATION'] != None
54 # 0.1. --- identification : on boule sur les valeurs de TEMP.
55 # Pour chaque couple (T, Kjc(T)), on évalue les Ki, Kmoy et
56 # les valeurs de Gpmax, DeltaLmax, inst.max correspondantes.
57 mccalc = self['IDENTIFICATION']
58 l_crit = mccalc['KJ_CRIT']
60 l_temp = mccalc['TEMP']
62 # 0.2. --- prédiction : on ne fait qu'une itération.
63 # Il faut un RESU_THER (sinon on utilise la température du
64 # premier Gpcrit et cà n'a pas trop d'intéret).
65 # A chaque instant, on regarde à quelle température est le
66 # fond d'entaille et on compare Gpmax à cet instant au Gpcrit.
67 mccalc = self['PREDICTION']
68 l_crit = mccalc['GP_CRIT']
70 l_temp = mccalc['TEMP'][0]
72 if not type(l_temp) in EnumTypes:
74 if not type(l_crit) in EnumTypes:
77 # 1. ----- calcul de G-theta
78 nbcour = len(self['THETA_2D'])
80 for occ in self['THETA_2D']:
81 dMC = occ.cree_dict_valeurs(occ.mc_liste)
83 __theta = CALC_THETA(MODELE=self['MODELE'],
84 DIRECTION=self['DIRECTION'],
85 THETA_2D=_F(GROUP_NO=dMC['GROUP_NO'],
90 __gtheta = CALC_G(THETA=_F(THETA=__theta),
91 EXCIT=self['EXCIT'].List_F(),
92 RESULTAT=self['RESULTAT'],
94 SYME_CHAR=self['SYME_CHAR'],
95 COMP_ELAS=self['COMP_ELAS'].List_F(),)
97 tab = __gtheta.EXTR_TABLE()
99 # une Table par couronne
102 # 2. ----- Calcul de l'energie élastique en exploitant les groupes de
103 # mailles fournis par la procedure de maillage
104 l_copo = [grma.strip() for grma in self['GROUP_MA']]
106 l_charg = [charg['CHARGE'] for charg in self['EXCIT']]
108 __ener = POST_ELEM(MODELE=self['MODELE'],
109 RESULTAT=self['RESULTAT'],
112 ENER_ELAS=_F(GROUP_MA=l_copo),
113 TITRE='Energie élastique',)
115 t_enel = __ener.EXTR_TABLE()
117 # 2.1. ----- Indice de chaque copeau et deltaL
118 d_icop = dict(zip(l_copo, range(1, nbcop + 1)))
120 l_lieu = [grma.strip() for grma in t_enel.LIEU.values()]
121 l_icop = [d_icop[grma] for grma in l_lieu]
122 t_enel['ICOP'] = l_icop
123 t_enel.fromfunction('DELTAL', fDL, 'ICOP', { 'pascop' : self['PAS_ENTAILLE'] })
125 # 2.2. ----- Calcul de Gp fonction de Ener.Totale et de deltaL
126 t_enel.fromfunction('GP', fGp_Etot, ('TOTALE', 'ICOP'),
127 { 'pascop' : self['PAS_ENTAILLE'],
128 'syme' : self['SYME_CHAR'] != 'SANS',
129 'R' : self['RAYON_AXIS'] })
131 # 2.3. ----- Tableau de Gp = f(icop) pour chaque instant
133 tGp_t_icop = t_enel['INST', 'DELTAL', 'GP']
134 tGp_t_icop.titr = "Gp à chaque instant en fonction de la distance au " \
136 tGp_t_icop.ImprTabCroise()
138 # 2.4. ----- Table Gpmax
139 ttmp = t_enel['NUME_ORDRE', 'INST', 'ICOP', 'DELTAL', 'GP']
140 l_numord = list(Set(ttmp.NUME_ORDRE.values()))
143 tj = ttmp.NUME_ORDRE == j
144 if self['CRIT_MAXI_GP'] == 'ABSOLU':
147 t = MaxRelatif(tj, 'GP')
151 tb_Gpmax = tb_Gpmax | t
152 tb_Gpmax.Renomme('GP', 'GPMAX')
153 tb_Gpmax.Renomme('ICOP', 'ICOPMAX')
154 tb_Gpmax.Renomme('DELTAL', 'DELTALMAX')
155 tb_Gpmax.titr = 'Gpmax à chaque instant'
159 # 2.5. ----- extraction de la température en fond d'entaille
160 if self['RESU_THER']:
161 grno_fond = self['THETA_2D'][0]['GROUP_NO']
162 __relev = POST_RELEVE_T(ACTION=_F(RESULTAT=self['RESU_THER'],
163 OPERATION='EXTRACTION',
164 INTITULE='Temperature',
168 GROUP_NO=grno_fond,),)
169 t_relev = __relev.EXTR_TABLE()['NUME_ORDRE', 'TEMP']
172 # 3. ----- boucle sur les mots-clés facteurs
173 # opérations dépendant de la température
174 MATER = self['MATER']
177 for iocc, TEMP in enumerate(l_temp):
178 # 3.0. ----- Temperature fonction du temps : si on n'a pas de RESU_THER,
179 # on prend la température d'identification.
180 if not self['RESU_THER']:
181 l_rows = [{'NUME_ORDRE' : i, 'TEMP' : TEMP} for i in l_numord]
182 t_relev = Table(rows=l_rows, para=('NUME_ORDRE', 'TEMP'), typ=('R', 'R'))
185 # 3.1. ----- extrait du matériau E(TEMP) et NU(TEMP) (si nécessaire)
187 t_relev.fromfunction('YOUNG', CallRCVALE, 'TEMP',
188 { 'para' : 'E', 'MATER' : MATER })
189 t_relev.fromfunction('NU', CallRCVALE, 'TEMP',
190 { 'para' : 'NU', 'MATER' : MATER })
191 #tb_Gpmax = merge(tb_Gpmax, t_relev, 'NUME_ORDRE')
194 # 3.2. ----- paramètres
196 'YOUNG' : CallRCVALE(TEMP, 'E', MATER),
197 'NU' : CallRCVALE(TEMP, 'NU', MATER),
198 'R' : self['RAYON_AXIS'],
201 # 3.3. ----- calcul de Kj(G)
203 for k, tab in enumerate(l_tab):
204 # fusion avec TEMP, E et nu.
205 tab = merge(tab, t_relev, 'NUME_ORDRE')
207 # calcul de Kj(G) = K_i
208 new_para = 'K_%d' % (k + 1)
209 tab.fromfunction(new_para, fKj, ('G', 'YOUNG', 'NU'),
210 { 'R' : self['RAYON_AXIS'] })
213 tab.Renomme('G', 'G_%d' % (k + 1))
216 # 3.4 ----- Table des Gi, Ki sur les differentes couronnes + Kmoyen
217 tabK_G = l_tabi[0]['NUME_ORDRE']
219 tabK_G = merge(tabK_G, tab, 'NUME_ORDRE')
220 tabK_G.titr = 'G et K sur les differentes couronnes + moyennes'
221 tabK_G.fromfunction('GMOY', moyenne, ['G_%d' % (k + 1) for k in range(nbcour)])
222 tabK_G.fromfunction('KMOY', moyenne, ['K_%d' % (k + 1) for k in range(nbcour)])
224 # 3.5. ----- Contribution à la table globale
225 tabres = merge(tabK_G, tb_Gpmax, 'NUME_ORDRE')
226 tabres['OCCURRENCE'] = [iocc + 1] * len(l_numord)
230 # 3.5.1. --- Table globale
234 tabl_glob = merge(tabl_glob, tabres)
235 tabl_glob.titr = 'G, K sur les differentes couronnes, Gmoy, Kmoy et ' \
236 'Gpmax fonctions du temps'
238 # 3.6. ----- traitement selon identification / prédiction
240 'INTERPOL' : ['LIN', 'LIN'],
242 'PROL_DROITE' : 'CONSTANT',
243 'PROL_GAUCHE' : 'CONSTANT',
245 # Gpmax fonction du temps
246 d_para.update({ 'NOM_RESU' : 'GPMAX' })
247 fGp = t_fonction(tabres.INST.values(), tabres.GPMAX.values(), d_para)
249 # 3.6.1. --- identification
251 KJ_CRIT = l_crit[iocc]
252 # définition des fonctions pour faire les interpolations
253 d_para.update({ 'NOM_RESU' : 'DELTALMAX' })
254 fdL = t_fonction(tabres.INST.values(), tabres.DELTALMAX.values(), d_para)
256 d_para.update({ 'NOM_PARA' : 'KMOY',
257 'NOM_RESU' : 'INST', })
258 valkmoy = tabres.KMOY.values()
259 finv = t_fonction(valkmoy, tabres.INST.values(), d_para)
261 if not (min(valkmoy) <= KJ_CRIT <= max(valkmoy)):
262 UTMESS('A', macro, 'Interpolation hors du domaine (prolongement ' \
263 'constant utilisé).')
264 # valeurs à mettre dans la table
271 'KGPMAX' : fKj(Gpi, **dict_constantes),
272 'DELTALMAX' : fdL(ti),
274 lv_ident.append(d_ident)
276 # 3.6.2. --- prédiction
280 # 4. ----- Construction de la table résultat si demandée
281 # 4.1. --- identification
283 tab_ident = Table(rows=lv_ident,
284 para=('KJ_CRIT', 'INST', 'GPMAX', 'KGPMAX', 'DELTALMAX'),
285 typ= ('R', 'R', 'R', 'R', 'R'),
286 titr='Identification aux valeurs de tenacités critiques')
287 dprod_result = tab_ident.dict_CREA_TABLE()
291 # 4.2. --- prédiction
293 # définition de la fonction GPcrit = f(TEMP)
294 d_para.update({ 'NOM_PARA' : 'TEMP',
295 'NOM_RESU' : 'GP_CRIT', })
296 fGpc = t_fonction(mccalc['TEMP'], mccalc['GP_CRIT'], d_para)
298 tab_pred = tabl_glob['NUME_ORDRE', 'INST', 'TEMP', 'DELTALMAX', 'GPMAX']
299 tab_pred.fromfunction('GP_CRIT', fGpc, 'TEMP')
300 tab_pred.fromfunction('PREDICTION', crit, ('GP_CRIT', 'GPMAX'))
301 tab_pred.titr = 'Comparaison Gpmax à Gpcrit(T)'
302 dprod_result = tab_pred.dict_CREA_TABLE()
304 # 9. ----- création de la table_sdaster résultat
305 dprod = tabl_glob.dict_CREA_TABLE()
306 result = CREA_TABLE(**dprod)
307 tabresult = CREA_TABLE(**dprod_result)
311 # -----------------------------------------------------------------------------
312 def CallRCVALE(TEMP, para, MATER):
313 """Fonction appelant RCVALE et retourne la valeur d'un paramètre.
315 valres, flag_ok = MATER.RCVALE('ELAS', 'TEMP', TEMP, para)
316 assert list(flag_ok).count('OK') != 1, \
317 'Erreur lors de la récupération des valeurs du matériau.'
320 # -----------------------------------------------------------------------------
321 def fKj(G, YOUNG, NU, R):
322 """Calcul de Kj à partir de G (formule d'Irwin)
324 return (G / R * YOUNG / (1.0 - NU**2))**0.5
326 # -----------------------------------------------------------------------------
327 def fDL(ICOP, pascop):
328 """DeltaL = numéro copeau * pas d'entaille
332 # -----------------------------------------------------------------------------
333 def fGp_Etot(TOTALE, ICOP, pascop, R, syme=False):
334 """Gp(Etotale, K), deltal pris dans le context global.
335 ICOP : numéro du copeau,
336 pascop : pas d'entaille.
337 syme : True s'il y a symétrie.
342 return fact_axis * TOTALE / (fDL(ICOP, pascop) * R)
344 # -----------------------------------------------------------------------------
345 def MaxRelatif(table, nom_para):
346 """Extrait le dernier maxi du champ `nom_para` de la table.
348 l_val = getattr(table, nom_para).values()
355 return getattr(table, nom_para) == Vlast
357 # -----------------------------------------------------------------------------
358 def crit(GP_CRIT, GPMAX):
359 """Retourne 1 quand GP_CRIT > GPMAX
366 # -----------------------------------------------------------------------------
370 return sum(args)/len(args)