X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=Aster%2FCata%2FcataSTA9%2FMacro%2Fpost_gp_ops.py;h=a66baa1fb5372a697274a6a6e57f629484669fa9;hb=69ed0ccae7884aee37bbe54cb1af2983cb51492d;hp=c72135c1bf817a98af792424143b9df4b2f15510;hpb=0de68ab81c740338ae4c434a4e953095b2c8b363;p=tools%2Feficas.git diff --git a/Aster/Cata/cataSTA9/Macro/post_gp_ops.py b/Aster/Cata/cataSTA9/Macro/post_gp_ops.py index c72135c1..a66baa1f 100644 --- a/Aster/Cata/cataSTA9/Macro/post_gp_ops.py +++ b/Aster/Cata/cataSTA9/Macro/post_gp_ops.py @@ -1,4 +1,4 @@ -#@ MODIF post_gp_ops Macro DATE 31/10/2006 AUTEUR REZETTE C.REZETTE +#@ MODIF post_gp_ops Macro DATE 15/04/2008 AUTEUR MACOCCO K.MACOCCO # -*- coding: iso-8859-1 -*- # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== @@ -6,7 +6,7 @@ # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR -# (AT YOUR OPTION) ANY LATER VERSION. +# (AT YOUR OPTION) ANY LATER VERSION. # # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF @@ -27,12 +27,14 @@ def post_gp_ops(self, **args): """ Corps de la macro POST_GP """ + import pdb macro = 'POST_GP' ier=0 from Accas import _F from Utilitai.Utmess import UTMESS - from Utilitai.Table import Table, merge + from Utilitai.Table import Table, merge, Colonne from Utilitai.t_fonction import t_fonction + from Cata.cata import evol_noli import aster # ----- On importe les definitions des commandes a utiliser dans la macro @@ -41,6 +43,13 @@ def post_gp_ops(self, **args): POST_ELEM = self.get_cmd('POST_ELEM') POST_RELEVE_T = self.get_cmd('POST_RELEVE_T') CREA_TABLE = self.get_cmd('CREA_TABLE') + DEFI_LIST_ENTI= self.get_cmd('DEFI_LIST_ENTI') + CALC_ELEM = self.get_cmd('CALC_ELEM') + RECU_FONCTION = self.get_cmd('RECU_FONCTION') + DETRUIRE = self.get_cmd('DETRUIRE') + DEFI_GROUP = self.get_cmd('DEFI_GROUP') + IMPR_CO = self.get_cmd('IMPR_CO') + FIN = self.get_cmd('FIN') # ----- Comptage, commandes + déclaration concept sortant self.set_icmd(1) @@ -51,7 +60,7 @@ def post_gp_ops(self, **args): # 0. ----- Type de calcul identification = self['IDENTIFICATION'] != None if identification: - # 0.1. --- identification : on boule sur les valeurs de TEMP. + # 0.1. --- identification : on boucle sur les valeurs de TEMP. # Pour chaque couple (T, Kjc(T)), on évalue les Ki, Kmoy et # les valeurs de Gpmax, DeltaLmax, inst.max correspondantes. mccalc = self['IDENTIFICATION'] @@ -74,100 +83,434 @@ def post_gp_ops(self, **args): if not type(l_crit) in EnumTypes: l_crit = [l_crit,] + + # Maillage associe au modele + __MAIL = aster.getvectjev( self['MODELE'].nom.ljust(8) + '.MODELE .LGRF ' ) + nom_maillage = __MAIL[0].strip() + + jdc = CONTEXT.get_current_step().jdc + maya = jdc.sds_dict[nom_maillage] + # 1. ----- calcul de G-theta - nbcour = len(self['THETA_2D']) - l_tab = [] - for occ in self['THETA_2D']: - dMC = occ.cree_dict_valeurs(occ.mc_liste) - - __theta = CALC_THETA(MODELE=self['MODELE'], - DIRECTION=self['DIRECTION'], - THETA_2D=_F(GROUP_NO=dMC['GROUP_NO'], - MODULE=1.0, - R_INF=dMC['R_INF'], - R_SUP=dMC['R_SUP']),) - - __gtheta = CALC_G(THETA=_F(THETA=__theta), - EXCIT=self['EXCIT'].List_F(), - RESULTAT=self['RESULTAT'], - TOUT_ORDRE='OUI', - SYME_CHAR=self['SYME_CHAR'], - COMP_ELAS=self['COMP_ELAS'].List_F(),) - - tab = __gtheta.EXTR_TABLE() - - # une Table par couronne - l_tab.append(tab) + + # Cas 2D + if self['THETA_2D'] is not None: + is_2D = True + else: + is_2D = False + + if is_2D: + nbcour = len(self['THETA_2D']) + nb_tranches = 1 + ep_z = 1 + l_tab = [] + for occ in self['THETA_2D']: + dMC = occ.cree_dict_valeurs(occ.mc_liste) + + __theta = CALC_THETA(MODELE=self['MODELE'], + DIRECTION=self['DIRECTION'], + THETA_2D=_F(GROUP_NO=dMC['GROUP_NO'], + MODULE=1.0, + R_INF=dMC['R_INF'], + R_SUP=dMC['R_SUP']),) + + __gtheta = CALC_G(THETA=_F(THETA=__theta), + EXCIT=self['EXCIT'].List_F(), + RESULTAT=self['RESULTAT'], + TOUT_ORDRE='OUI', + SYME_CHAR=self['SYME_CHAR'], + COMP_ELAS=self['COMP_ELAS'].List_F(),) + + tab = __gtheta.EXTR_TABLE() + + # une Table par couronne + l_tab.append(tab) + + else: + #Cas 3D + nbcour = len(self['THETA_3D']) + nb_tranches = self['NB_TRANCHES'] + l_tab = [] + l_noeuds_fissure, pas = getFondFissInfo(self['FOND_FISS']) + nb_noeuds_fissure = len(l_noeuds_fissure) + + for occ in self['THETA_3D']: + dMC = occ.cree_dict_valeurs(occ.mc_liste) + + # on met les mots-clés facultatifs dans des dictionnaires + dpar_theta = {} + if self['DIRECTION'] is not None: + dpar_theta['DIRECTION'] = self['DIRECTION'] + + __gtheta = CALC_G( + THETA=_F(R_INF=dMC['R_INF'], + R_SUP=dMC['R_SUP'], + MODULE=1.0, + FOND_FISS=self['FOND_FISS'], + **dpar_theta), + EXCIT=self['EXCIT'].List_F(), + RESULTAT=self['RESULTAT'], + TOUT_ORDRE='OUI', + SYME_CHAR=self['SYME_CHAR'], + COMP_ELAS=self['COMP_ELAS'].List_F(), + LISSAGE=self['LISSAGE'].List_F() + ) + + + tab = __gtheta.EXTR_TABLE() + + + # une Table par couronne + l_tab.append(tab) + + # 2. ----- Calcul de l'energie élastique en exploitant les groupes de # mailles fournis par la procedure de maillage - l_copo = [grma.strip() for grma in self['GROUP_MA']] - nbcop = len(l_copo) - l_charg = [charg['CHARGE'] for charg in self['EXCIT']] - - __ener = POST_ELEM(MODELE=self['MODELE'], - RESULTAT=self['RESULTAT'], - CHARGE=l_charg, - TOUT_ORDRE='OUI', - ENER_ELAS=_F(GROUP_MA=l_copo), - TITRE='Energie élastique',) - - t_enel = __ener.EXTR_TABLE() - - # 2.1. ----- Indice de chaque copeau et deltaL - d_icop = dict(zip(l_copo, range(1, nbcop + 1))) - - l_lieu = [grma.strip() for grma in t_enel.LIEU.values()] - l_icop = [d_icop[grma] for grma in l_lieu] - t_enel['ICOP'] = l_icop - t_enel.fromfunction('DELTAL', fDL, 'ICOP', { 'pascop' : self['PAS_ENTAILLE'] }) - - # 2.2. ----- Calcul de Gp fonction de Ener.Totale et de deltaL - t_enel.fromfunction('GP', fGp_Etot, ('TOTALE', 'ICOP'), - { 'pascop' : self['PAS_ENTAILLE'], - 'syme' : self['SYME_CHAR'] != 'SANS', - 'R' : self['RAYON_AXIS'] }) - - # 2.3. ----- Tableau de Gp = f(icop) pour chaque instant - if info >= 2: - tGp_t_icop = t_enel['INST', 'DELTAL', 'GP'] - tGp_t_icop.titr = "Gp à chaque instant en fonction de la distance au " \ - "fond d'entaille" - tGp_t_icop.ImprTabCroise() - - # 2.4. ----- Table Gpmax - ttmp = t_enel['NUME_ORDRE', 'INST', 'ICOP', 'DELTAL', 'GP'] - l_numord = list(Set(ttmp.NUME_ORDRE.values())) - l_numord.sort() - for j in l_numord: - tj = ttmp.NUME_ORDRE == j - if self['CRIT_MAXI_GP'] == 'ABSOLU': - t = tj.GP.MAXI() + + l_copo_tot = [grma.strip() for grma in self['GROUP_MA']] + nbcop_tot = len(l_copo_tot) + nbcop = nbcop_tot/nb_tranches + + if self['LIST_EP_COPEAUX'] is not None: + l_ep_copeaux_tot = self['LIST_EP_COPEAUX'] + + l_t_enel = [] + + if self['TRAC_COMP']=='OUI': + # prise en compte de la traction-compression dans le calcul de l'energie + resu2=CALC_ELEM(OPTION=('EQUI_ELNO_SIGM'), + RESULTAT=self['RESULTAT'], + ) + + # indices des mailles du dernier group_ma + # (pour avoir le nombre de mailles par tranche) + l_mailles_last_gm = maya.GROUPEMA.get()[l_copo_tot[-1].ljust(8)] + + # initialisation des concepts reutilises dans la boucle + # on suppose que chaque tranche a le meme nombre de mailles + + kk = 0 + + E_el = [None]*len(l_mailles_last_gm)*nb_tranches + + T_el = [None]*len(l_mailles_last_gm)*nb_tranches + + # on recupere les sd en dehors de la boucle + maya_GROUPEMA = maya.GROUPEMA.get() + maya_NOMMAI = maya.NOMMAI.get() + maya_CONNEX = maya.CONNEX.get() + maya_NOMNOE = maya.NOMNOE.get() + + # liste des tables tb_Gpmax repartie aux noeuds + l_tb_Gpmax_noeuds = [] + + for i in range(0,nb_tranches): + l_copo = l_copo_tot[i*nbcop:(i+1)*nbcop] + l_charg = [charg['CHARGE'] for charg in self['EXCIT']] + + if info >= 2 and not is_2D: + print " Calcul de la tranche %i"%(i+1) + + if self['TRAC_COMP']=='OUI': + + # l_copo est une liste commulative de mailles + # il faut lancer POST_ELEM sur chaque maille de chaque copeau + # puis regarder la trace de SIEF_ELGA sur ce copeau + + # on fera attention a ne pas lancer POST_ELEM sur une maille qui + # a deja ete calculee en stockant son resultat pour la maille en question + d_groupma={} + d_nomma={} + + # indices des mailles des copeaux + for group_ma in l_copo: + d_groupma[group_ma] = maya_GROUPEMA[group_ma.ljust(8)] + + # le dernier copeau contient tous les elements + # on calcule l energie de chaque element de ce copeau + last_copo = l_copo[-1] + + d_ener = {} + + d_nomma = {} + + for k, id_elem in enumerate(d_groupma[last_copo]): + + + # les id des elements dans Aster commencent a 1 + # la liste python commence a 0 + elem = maya_NOMMAI[id_elem-1] + d_nomma[id_elem]=elem + + E_el[kk] = POST_ELEM(MODELE=self['MODELE'], + RESULTAT=self['RESULTAT'], + CHARGE=l_charg, + TOUT_ORDRE='OUI', + ENER_ELAS=_F(MAILLE=elem), + TITRE='Energie élastique',) + + T_el[kk] = E_el[kk].EXTR_TABLE() + + l_enel = T_el[kk].TOTALE.values() + + # signe de la trace <=> signe de la composante VMIS_SG du tenseur EQUI_ELNO_SIGM, + # mais E_enel est par element => on fait une moyenne sur les noeuds de l'element + + list_no = [] + for ind_no in maya_CONNEX[id_elem] : + nomnoe = maya_NOMNOE[ind_no-1] + if nomnoe not in list_no : + list_no.append(nomnoe) + + # print "liste des noeuds de la maille ", id_elem, ": ", list_no + + l_inst = T_el[kk].INST.values() + nb_inst = len(l_inst) + + T_noeuds = Table() + T_noeuds['INST']=l_inst + + # pour chaque noeud de l'element on recupere sa trace + for noeud in list_no: + + VM=RECU_FONCTION(RESULTAT=resu2, + TOUT_INST='OUI', + NOM_CHAM='EQUI_ELNO_SIGM', + NOM_CMP='VMIS_SG', + MAILLE=elem, + NOEUD=noeud); + + T_noeuds[noeud]=VM.Ordo() + + DETRUIRE(CONCEPT=(_F(NOM=VM))) + + T_noeuds.fromfunction('VM_MAIL', moyenne, list_no) + + l_VM_MAIL = T_noeuds.VM_MAIL.values() + + for j, vm in enumerate(l_VM_MAIL): + if vm < 0: + l_enel[j]=-l_enel[j] + + del T_el[kk]['TOTALE'] + T_el[kk][elem]=l_enel + + if k==0: + + # Table de l'energie elastique sur le GROUP_MA + T_el_gm = Table() + T_el_gm['NUME_ORDRE'] = T_el[kk].NUME_ORDRE.values() + T_el_gm['INST'] = T_el[kk].INST.values() + T_el_gm['LIEU'] = [last_copo]*nb_inst + T_el_gm['ENTITE'] = ['GROUP_MA']*nb_inst + + T_el_gm[elem]=l_enel + + kk+=1 + + # sommation sur les mailles du group_ma: + l_nomma = d_nomma.values() + T_el_gm.fromfunction('TOTALE', mysum, l_nomma) + + # Table totale + t_enel=Table(titr="Energie élastique") + t_enel['NUME_ORDRE']=T_el_gm.NUME_ORDRE.values() + t_enel['INST']=T_el_gm.INST.values() + t_enel['LIEU']=T_el_gm.LIEU.values() + t_enel['ENTITE']=T_el_gm.ENTITE.values() + t_enel['TOTALE']=T_el_gm.TOTALE.values() + + # t_enel ne contient jusqu'ici que l'energie elastique du dernier copeau + + # calcul de l'energie elastique pour les autres copeaux + T_el_sub = T_el_gm.copy() + + for k in range(len(l_copo)-2,-1,-1): + group_ma = l_copo[k] + T_el_sub = T_el_sub.copy() + del T_el_sub['LIEU'] + del T_el_sub['TOTALE'] + T_el_sub['LIEU']=[group_ma]*nb_inst + l_id_elem = d_groupma[group_ma] + l_nom_elem = [] + + for id_elem, nom_elem in d_nomma.items(): + if not id_elem in l_id_elem: + # colonne a supprimer + del T_el_sub[nom_elem] + del d_nomma[id_elem] + else: + l_nom_elem.append(nom_elem) + + T_el_sub.fromfunction('TOTALE', sum_and_check, l_nom_elem) + + # Table de l'energie elastique sur le GROUP_MA + T_el_gm_k = Table() + T_el_gm_k['NUME_ORDRE'] =T_el_sub.NUME_ORDRE.values() + T_el_gm_k['INST'] = T_el_sub.INST.values() + T_el_gm_k['LIEU'] = [group_ma]*nb_inst + T_el_gm_k['ENTITE'] = ['GROUP_MA']*nb_inst + T_el_gm_k['TOTALE'] = T_el_sub.TOTALE.values() + + # contribution du group_ma a la table totale: + t_enel = merge(t_enel, T_el_gm_k) + + t_enel.sort('NUME_ORDRE') + + else: + # si self['TRAC_COMP']!='OUI' + # calcul classique de l'energie elastique + + __ener = POST_ELEM(MODELE=self['MODELE'], + RESULTAT=self['RESULTAT'], + CHARGE=l_charg, + TOUT_ORDRE='OUI', + ENER_ELAS=_F(GROUP_MA=l_copo), + TITRE='Energie élastique',) + + t_enel = __ener.EXTR_TABLE() + + # 2.1. ----- Indice de chaque copeau et deltaL + d_icop = dict(zip(l_copo, range(1, nbcop + 1))) + + l_lieu = [grma.strip() for grma in t_enel.LIEU.values()] + + l_icop = [d_icop[grma] for grma in l_lieu] + + t_enel['ICOP'] = l_icop + + l_numord = list(Set(t_enel.NUME_ORDRE.values())) + l_numord.sort() + + if self['PAS_ENTAILLE'] is not None: + t_enel.fromfunction('DELTAL', fDL, 'ICOP', { 'pascop' : self['PAS_ENTAILLE'] }) + else: + l_ep_copeaux_tranche = l_ep_copeaux_tot[i*nbcop:(i+1)*nbcop] + t_enel['DELTAL'] = l_ep_copeaux_tranche*len(l_numord) + + # 2.2. ----- Calcul de Gp fonction de Ener.Totale et de deltaL + if is_2D: + t_enel.fromfunction('GP', fGp_Etot, ('TOTALE', 'DELTAL'), + {'syme' : self['SYME_CHAR'] != 'SANS', + 'R' : self['RAYON_AXIS'],}) else: - t = MaxRelatif(tj, 'GP') - if j == 1: - tb_Gpmax = t + ep_tranche = largeur_tranche(nom_maillage, l_noeuds_fissure, pas, i) + #print "ep_tranche %i: "%i, ep_tranche + t_enel.fromfunction('GP', fGp_Etot, ('TOTALE', 'DELTAL'), + {'syme' : self['SYME_CHAR'] != 'SANS', + 'R' : ep_tranche }) + + #if info >= 2: + # print "Table de l'énergie élastique: ", t_enel + + l_t_enel.append(t_enel) + # 2.3. ----- Tableau de Gp = f(icop) pour chaque instant + if info >= 2: + tGp_t_icop = t_enel['INST', 'DELTAL', 'GP'] + tGp_t_icop.titr = "Gp à chaque instant en fonction de la distance au " \ + "fond d'entaille" + tGp_t_icop.ImprTabCroise() + + # 2.4. ----- Table Gpmax + ttmp = t_enel['NUME_ORDRE', 'INST', 'ICOP', 'DELTAL', 'GP'] + + for j in l_numord: + tj = ttmp.NUME_ORDRE == j + + ## pour tester le comportement de Gpmax quand GP est identiquement nul + #del tj['GP'] + #tj['GP']=[0]*len(tj.GP.values()) + + if self['CRIT_MAXI_GP'] == 'ABSOLU': + t = tj.GP.MAXI() + else: + t = MaxRelatif(tj, 'GP') + + + # cas GP identiquement nul: plusieurs max de GP + # on prend le DELTAL minimum + if len(t.GP.values())>1: + t = t.DELTAL.MINI() + + if j == 1: + tb_Gpmax_i = t + else: + tb_Gpmax_i = tb_Gpmax_i | t + + + tb_Gpmax_i.Renomme('GP', 'GPMAX') + tb_Gpmax_i.Renomme('ICOP', 'ICOPMAX') + tb_Gpmax_i.Renomme('DELTAL', 'DELTALMAX') + tb_Gpmax_i.titr = 'Gpmax à chaque instant' + + # On transfert Gpmax au noeud sommet à gauche et au milieu (si cas quadratique) + # sauf pour la dernière tranche où on transfère également au noeud sommet de droite. + # Tout cela pour pouvoir avoir une table complète avec les G et les Gpmax. + if not is_2D: + tb_Gpmax_i['NUME_TRANCHE']=[i+1]*len(tb_Gpmax_i['GPMAX']) + if i==0: + l_inst = tb_Gpmax_i.INST.values() + nb_inst = len(l_inst) + if pas==1: + tb_Gpmax_i_noeuds = tb_Gpmax_i.copy() + tb_Gpmax_i_noeuds['NOEUD']=[l_noeuds_fissure[i]]*nb_inst + l_tb_Gpmax_noeuds.append(tb_Gpmax_i_noeuds) + else: + tb_Gpmax_i_noeuds_1 = tb_Gpmax_i.copy() + tb_Gpmax_i_noeuds_1['NOEUD'] = [l_noeuds_fissure[pas*i]]*nb_inst + l_tb_Gpmax_noeuds.append(tb_Gpmax_i_noeuds_1) + tb_Gpmax_i_noeuds_2 = tb_Gpmax_i.copy() + tb_Gpmax_i_noeuds_2['NOEUD'] = [l_noeuds_fissure[pas*i+1]]*nb_inst + l_tb_Gpmax_noeuds.append(tb_Gpmax_i_noeuds_2) + if i==nb_tranches-1: + tb_Gpmax_i_noeuds_3 = tb_Gpmax_i.copy() + tb_Gpmax_i_noeuds_3['NOEUD'] = [l_noeuds_fissure[-1]]*nb_inst + l_tb_Gpmax_noeuds.append(tb_Gpmax_i_noeuds_3) + + + + if i == 0: + tb_Gpmax = tb_Gpmax_i else: - tb_Gpmax = tb_Gpmax | t - tb_Gpmax.Renomme('GP', 'GPMAX') - tb_Gpmax.Renomme('ICOP', 'ICOPMAX') - tb_Gpmax.Renomme('DELTAL', 'DELTALMAX') - tb_Gpmax.titr = 'Gpmax à chaque instant' - if info >= 2: - print tb_Gpmax + tb_Gpmax = merge(tb_Gpmax, tb_Gpmax_i) + + # FIN BOUCLE SUR LES TRANCHES + + if not is_2D: + tb_Gpmax_noeuds = Table(para=tb_Gpmax.para+['NOEUD']) + for j, tb in enumerate(l_tb_Gpmax_noeuds): + if j==0: + tb_Gpmax_noeuds = tb + else: + tb_Gpmax_noeuds = merge(tb_Gpmax_noeuds, tb) + # 2.5. ----- extraction de la température en fond d'entaille + #voir le cas 3D => THETA_3D, mais qu'en est-il des tranches? if self['RESU_THER']: - grno_fond = self['THETA_2D'][0]['GROUP_NO'] + #sur un seul noeud ou sur tous les noeuds du fond d'entaille? + + if is_2D: + grno_fond = self['THETA_2D'][0]['GROUP_NO'] + else: + grma_fond = self['THETA_3D'][0]['GROUP_MA'] + grno_fond = "GRNOFOND" + DEFI_GROUP(reuse =maya, + MAILLAGE=maya, + CREA_GROUP_NO=_F(GROUP_MA=grma_fond, + NOM=grno_fond,),); + + l_ordres = DEFI_LIST_ENTI(VALE=l_numord) __relev = POST_RELEVE_T(ACTION=_F(RESULTAT=self['RESU_THER'], OPERATION='EXTRACTION', INTITULE='Temperature', NOM_CHAM='TEMP', - TOUT_ORDRE='OUI', + LIST_ORDRE=l_ordres, NOM_CMP='TEMP', GROUP_NO=grno_fond,),) - t_relev = __relev.EXTR_TABLE()['NUME_ORDRE', 'TEMP'] - + + t_relev = __relev.EXTR_TABLE()['NUME_ORDRE', 'NOEUD', 'TEMP'] # 3. ----- boucle sur les mots-clés facteurs # opérations dépendant de la température @@ -178,7 +521,7 @@ def post_gp_ops(self, **args): # 3.0. ----- Temperature fonction du temps : si on n'a pas de RESU_THER, # on prend la température d'identification. if not self['RESU_THER']: - l_rows = [{'NUME_ORDRE' : i, 'TEMP' : TEMP} for i in l_numord] + l_rows = [{'NUME_ORDRE' : j, 'TEMP' : TEMP} for j in l_numord] t_relev = Table(rows=l_rows, para=('NUME_ORDRE', 'TEMP'), typ=('R', 'R')) flag_mat = True @@ -188,44 +531,73 @@ def post_gp_ops(self, **args): { 'para' : 'E', 'MATER' : MATER }) t_relev.fromfunction('NU', CallRCVALE, 'TEMP', { 'para' : 'NU', 'MATER' : MATER }) - #tb_Gpmax = merge(tb_Gpmax, t_relev, 'NUME_ORDRE') flag_mat = False # 3.2. ----- paramètres dict_constantes = { 'YOUNG' : CallRCVALE(TEMP, 'E', MATER), 'NU' : CallRCVALE(TEMP, 'NU', MATER), - 'R' : self['RAYON_AXIS'], } + if is_2D: + dict_constantes['R'] = self['RAYON_AXIS'] + else: + dict_constantes['R'] = ep_tranche + # 3.3. ----- calcul de Kj(G) l_tabi = [] for k, tab in enumerate(l_tab): - # fusion avec TEMP, E et nu. - tab = merge(tab, t_relev, 'NUME_ORDRE') + #tab: table de la couronne k # calcul de Kj(G) = K_i new_para = 'K_%d' % (k + 1) - tab.fromfunction(new_para, fKj, ('G', 'YOUNG', 'NU'), - { 'R' : self['RAYON_AXIS'] }) - - # renomme G en G_i - tab.Renomme('G', 'G_%d' % (k + 1)) + if is_2D: + # fusion avec TEMP, E et nu + tab = merge(tab, t_relev, 'NUME_ORDRE') + tab.fromfunction(new_para, fKj, ('G', 'YOUNG', 'NU'), + { 'R' : self['RAYON_AXIS'] }) + # renomme G en G_i + tab.Renomme('G', 'G_%d' % (k + 1)) + else: + if self['RESU_THER']: + tab=merge(tab, t_relev, ['NUME_ORDRE', 'NOEUD']) + else: + tab=mergeLineInTable(tab, t_relev, nb_noeuds_fissure) + + # en 3D, le paramètre R n'intervient pas + tab.fromfunction(new_para, fKj, ('G_LOCAL', 'YOUNG', 'NU')) + tab.Renomme('G_LOCAL', 'G_%d' % (k + 1)) + l_tabi.append(tab) # 3.4 ----- Table des Gi, Ki sur les differentes couronnes + Kmoyen - tabK_G = l_tabi[0]['NUME_ORDRE'] - for tab in l_tabi: - tabK_G = merge(tabK_G, tab, 'NUME_ORDRE') + if is_2D: + tabK_G = l_tabi[0]['NUME_ORDRE'] + for tab in l_tabi: + tabK_G = merge(tabK_G, tab, 'NUME_ORDRE') + else: + tabK_G=l_tabi[0] + for i in range(1,len(l_tabi)): + tabK_G = merge(tabK_G, l_tabi[i], ['NUME_ORDRE', 'NOEUD']) tabK_G.titr = 'G et K sur les differentes couronnes + moyennes' - tabK_G.fromfunction('GMOY', moyenne, ['G_%d' % (k + 1) for k in range(nbcour)]) + tabK_G.fromfunction('GMOY', moyenne_positive, ['G_%d' % (k + 1) for k in range(nbcour)]) tabK_G.fromfunction('KMOY', moyenne, ['K_%d' % (k + 1) for k in range(nbcour)]) # 3.5. ----- Contribution à la table globale - tabres = merge(tabK_G, tb_Gpmax, 'NUME_ORDRE') - tabres['OCCURRENCE'] = [iocc + 1] * len(l_numord) - if info >= 2: - print tabres + + if is_2D: + tabres = merge(tabK_G, tb_Gpmax, 'NUME_ORDRE') + tabres['OCCURRENCE'] = [iocc + 1] * len(l_numord) + else: + # tb_Gpmax est une table sur les tranches, + # on l'ajoute dans la table aux noeuds tabres avec la convention: + # au 1er noeud et noeud milieu de la tranche on affecte la valeur de la tranche + # sauf pour la derniere tranche où on affecte la valeur sur les 3 noeuds de la tranche + tabres = tabK_G + tabres = merge(tabK_G, tb_Gpmax_noeuds, ['NUME_ORDRE', 'NOEUD']) + tabres['OCCURRENCE'] = [iocc + 1] * len(l_numord) * nb_noeuds_fissure + #if info >= 2: + # print tabres # 3.5.1. --- Table globale if iocc == 0: @@ -242,37 +614,122 @@ def post_gp_ops(self, **args): 'PROL_DROITE' : 'CONSTANT', 'PROL_GAUCHE' : 'CONSTANT', } - # Gpmax fonction du temps - d_para.update({ 'NOM_RESU' : 'GPMAX' }) - fGp = t_fonction(tabres.INST.values(), tabres.GPMAX.values(), d_para) # 3.6.1. --- identification if identification: KJ_CRIT = l_crit[iocc] - # définition des fonctions pour faire les interpolations - d_para.update({ 'NOM_RESU' : 'DELTALMAX' }) - fdL = t_fonction(tabres.INST.values(), tabres.DELTALMAX.values(), d_para) - - d_para.update({ 'NOM_PARA' : 'KMOY', - 'NOM_RESU' : 'INST', }) - valkmoy = tabres.KMOY.values() - finv = t_fonction(valkmoy, tabres.INST.values(), d_para) - + # on verifie que KJ_CRIT soit compris dans l'intervalle [KMOY_min, KMOY_max] + valkmoy = tabres.KMOY.values() if not (min(valkmoy) <= KJ_CRIT <= max(valkmoy)): - UTMESS('A', macro, 'Interpolation hors du domaine (prolongement ' \ - 'constant utilisé).') - # valeurs à mettre dans la table - ti = finv(KJ_CRIT) - Gpi = fGp(ti) - d_ident = { - 'KJ_CRIT' : KJ_CRIT, - 'INST' : ti, - 'GPMAX' : Gpi, - 'KGPMAX' : fKj(Gpi, **dict_constantes), - 'DELTALMAX' : fdL(ti), - } - lv_ident.append(d_ident) - +# 'constant utilisé).') + UTMESS('A','RUPTURE0_1') + if is_2D: + # définition des fonctions pour faire les interpolations + d_para.update({ 'NOM_RESU' : 'DELTALMAX' }) + # DeltaMax en fonction du temps + fdL = t_fonction(tb_Gpmax.INST.values(), tb_Gpmax.DELTALMAX.values(), d_para) + # Gpmax fonction du temps + d_para.update({ 'NOM_RESU' : 'GPMAX' }) + fGp = t_fonction(tb_Gpmax.INST.values(), tb_Gpmax.GPMAX.values(), d_para) + + d_para.update({ 'NOM_PARA' : 'KMOY', + 'NOM_RESU' : 'INST', }) + valkmoy = tabres.KMOY.values() + # temps en fonction de Kmoy + finv = t_fonction(valkmoy, tabres.INST.values(), d_para) + + # valeurs à mettre dans la table + # temps correspondant à KJ_CRIT + ti = finv(KJ_CRIT) + # GP correspondant au temps critique + Gpi = fGp(ti) + d_ident = { + 'KJ_CRIT' : KJ_CRIT, + 'INST' : ti, + 'GPMAX' : Gpi, + 'KGPMAX' : fKj(Gpi, **dict_constantes), + 'DELTALMAX' : fdL(ti), + } + lv_ident.append(d_ident) + else: + + l_i_noeuds_sommets = range(0,len(l_noeuds_fissure),pas) + t_noeud_Kcrit = Table(para=tabres.para) + + # On determine quel noeud sommet maximise KMOY au cours du temps: + + row_KMOY_max = tabres.KMOY.MAXI() + noeud_KMOY_max = row_KMOY_max.NOEUD.values()[0] + + # avec le noeud ou KJ_CRIT est atteint, on regarde GP a gauche et a droite. + # le GP le plus grand correspond au GPmax + # on garde la tranche ou GP est le plus grand + + id_noeud_KMOY_max = list(l_noeuds_fissure).index(noeud_KMOY_max) + if id_noeud_KMOY_max==0: + # "Gpmax sur la 1ere tranche" + nume_tranche_Gpmax = 1 + elif id_noeud_KMOY_max==(len(l_noeuds_fissure)-1): + # "Gpmax sur la derniere tranche" + nume_tranche_Gpmax = nb_tranches + else: + # "Gpmax sur une tranche intermediaire" + Gpi_tot = Table(para=tb_Gpmax.para) + Gpi_gauche = tb_Gpmax.NUME_TRANCHE==(id_noeud_KMOY_max/pas) + Gpi_tot.append(Gpi_gauche.rows[0]) + Gpi_droite = tb_Gpmax.NUME_TRANCHE==(id_noeud_KMOY_max/pas+1) + Gpi_tot.append(Gpi_droite.rows[0]) + Gpi_tab = Gpi_tot.GPMAX.MAXI() + nume_tranche_Gpmax = Gpi_tab.NUME_TRANCHE.values()[0] + + # tb_Gpmax_TrancheCrit est une table de la meme nature que la table 2D tb_Gpmax + # i.e. valeurs sur la seule tranche qui nous interesse (ou on sait + # que KJ_CRIT sera atteint) + + tb_Gpmax_TrancheCrit = tb_Gpmax.NUME_TRANCHE==nume_tranche_Gpmax + + # avec le noeud ou KJ_CRIT est atteint, on determine le temps + # critique par interpolation + tabres_NoeudCrit = tabres.NOEUD==noeud_KMOY_max + + # la suite est idem 2D, seuls les noms des tables changent + + # définition des fonctions pour faire les interpolations + d_para.update({ 'NOM_RESU' : 'DELTALMAX' }) + # DeltaMax en fonction du temps + fdL = t_fonction(tb_Gpmax_TrancheCrit.INST.values(), + tb_Gpmax_TrancheCrit.DELTALMAX.values(), + d_para) + + # Gpmax fonction du temps + d_para.update({ 'NOM_RESU' : 'GPMAX' }) + fGp = t_fonction(tb_Gpmax_TrancheCrit.INST.values(), + tb_Gpmax_TrancheCrit.GPMAX.values(), + d_para) + + + d_para.update({ 'NOM_PARA' : 'KMOY', + 'NOM_RESU' : 'INST', }) + valkmoy = tabres_NoeudCrit.KMOY.values() + # temps en fonction de Kmoy + finv = t_fonction(valkmoy, tabres_NoeudCrit.INST.values(), d_para) + + # valeurs à mettre dans la table + # temps correspondant a KJ_CRIT + ti = finv(KJ_CRIT) + # GP correspondant au temps critique + Gpi = fGp(ti) + # par rapport a 2D, on ajoute 'NUME_TRANCHE' + d_ident = { + 'KJ_CRIT' : KJ_CRIT, + 'INST' : ti, + 'NUME_TRANCHE' : int(nume_tranche_Gpmax), + 'GPMAX' : Gpi, + 'KGPMAX' : fKj(Gpi, **dict_constantes), + 'DELTALMAX' : fdL(ti), + } + lv_ident.append(d_ident) + # 3.6.2. --- prédiction else: pass @@ -280,9 +737,13 @@ def post_gp_ops(self, **args): # 4. ----- Construction de la table résultat si demandée # 4.1. --- identification if identification: + if is_2D: + para_tab_ident=('KJ_CRIT', 'INST', 'GPMAX', 'KGPMAX', 'DELTALMAX') + else: + para_tab_ident=('KJ_CRIT', 'INST', 'NUME_TRANCHE', 'GPMAX', 'KGPMAX', 'DELTALMAX') tab_ident = Table(rows=lv_ident, - para=('KJ_CRIT', 'INST', 'GPMAX', 'KGPMAX', 'DELTALMAX'), - typ= ('R', 'R', 'R', 'R', 'R'), + para=para_tab_ident, + typ = ('R')*len(para_tab_ident), titr='Identification aux valeurs de tenacités critiques') dprod_result = tab_ident.dict_CREA_TABLE() if info >= 2: @@ -295,7 +756,25 @@ def post_gp_ops(self, **args): 'NOM_RESU' : 'GP_CRIT', }) fGpc = t_fonction(mccalc['TEMP'], mccalc['GP_CRIT'], d_para) - tab_pred = tabl_glob['NUME_ORDRE', 'INST', 'TEMP', 'DELTALMAX', 'GPMAX'] + # en 3D, GPMAX et DELTALMAX ne sont pas dans tab_glob: les recuperer de tb_Gpmax + + if is_2D: + tab_pred = tabl_glob['NUME_ORDRE', 'INST', 'TEMP', 'DELTALMAX', 'GPMAX'] + else: + tab_pred = tb_Gpmax['NUME_ORDRE', 'INST', 'NUME_TRANCHE', 'DELTALMAX', 'GPMAX'] + # on recupere TEMP de tabl_glob + tab_temp_tranche=Table(para=['NUME_ORDRE', 'NUME_TRANCHE', 'TEMP']) + # on fait une moyenne de la temperature sur les noeuds d'une tranche + for ordre in l_numord: + tabl_glob_ORDRE_i = tabl_glob.NUME_ORDRE==ordre + temp_ORDRE_i = tabl_glob_ORDRE_i.TEMP.values() + for i_tranche in range(nb_tranches): + l_temp_noeuds_tranche_i = temp_ORDRE_i[i_tranche : i_tranche+pas+1] + temp_tranche_i = moyenne(*l_temp_noeuds_tranche_i) + d = {'NUME_ORDRE': ordre, 'NUME_TRANCHE': i_tranche+1, 'TEMP': temp_tranche_i} + tab_temp_tranche.append(d) + tab_pred = merge(tab_pred, tab_temp_tranche, ['NUME_ORDRE', 'NUME_TRANCHE']) + tab_pred.fromfunction('GP_CRIT', fGpc, 'TEMP') tab_pred.fromfunction('PREDICTION', crit, ('GP_CRIT', 'GPMAX')) tab_pred.titr = 'Comparaison Gpmax à Gpcrit(T)' @@ -318,10 +797,12 @@ def CallRCVALE(TEMP, para, MATER): return valres # ----------------------------------------------------------------------------- -def fKj(G, YOUNG, NU, R): +def fKj(G, YOUNG, NU, R=1): """Calcul de Kj à partir de G (formule d'Irwin) + R n'intervient pas en 3D """ - return (G / R * YOUNG / (1.0 - NU**2))**0.5 + Kj=(abs(G / R * YOUNG / (1.0 - NU**2)))**0.5 + return Kj # ----------------------------------------------------------------------------- def fDL(ICOP, pascop): @@ -330,16 +811,20 @@ def fDL(ICOP, pascop): return ICOP * pascop # ----------------------------------------------------------------------------- -def fGp_Etot(TOTALE, ICOP, pascop, R, syme=False): +def fGp_Etot(TOTALE, DELTAL, R, syme=False): """Gp(Etotale, K), deltal pris dans le context global. - ICOP : numéro du copeau, - pascop : pas d'entaille. - syme : True s'il y a symétrie. + ICOP : numéro du copeau, + DELTAL : liste des epaisseurs des copeaux + R : rayon en axisymetrique, + longueur de l'élément 1D situé sur le front d'entaille si modèle 3D. + syme : True s'il y a symétrie. """ - fact_axis = 1. + import types + fact_syme = 1. if syme: - fact_axis = 2. - return fact_axis * TOTALE / (fDL(ICOP, pascop) * R) + fact_syme = 2. + Gp_Etot = fact_syme * TOTALE / (DELTAL * R ) + return Gp_Etot # ----------------------------------------------------------------------------- def MaxRelatif(table, nom_para): @@ -369,3 +854,86 @@ def moyenne(*args): """ return sum(args)/len(args) +def moyenne_positive(*args): + """Fonction moyenne + """ + return sum([abs(a) for a in args])/len(args) + +def mysum(*args): + """Fonction sum. + La fonction sum ne peut pas etre appelee sur une liste de parametre + d'une table via fromfunction + """ + return sum(args) + +def sum_and_check(*args): + """Fonction sum. + Verifie si la somme est positive. + Si la somme est negative, on la met egale a zero + """ + somme = sum(args) + if somme<0: + somme=0 + return somme + +# On recupere des infos sur le fond de fissure +def getFondFissInfo(fondfiss): + # >FONFISS .FOND .NOEU < + # >FONFISS .FOND .TYPE < + import aster + l_noeuds_fissure = aster.getvectjev(fondfiss.nom.ljust(8)+'.FOND .NOEU ') + type_mailles = aster.getvectjev(fondfiss.nom.ljust(8)+'.FOND .TYPE ') + if (type_mailles[0].strip() == 'SEG3' ): + pas = 2 + else: + pas = 1 + return l_noeuds_fissure, pas + +######################################################################## +# determination de la distance min entre 2 points consécutifs de la ligne de coupe + +def largeur_tranche(nom_maillage, l_noms_noeuds_fissure, pas, i_tranche): + # >MA .COORDO .VALE < + from math import sqrt + import aster + + # tuple des noms des noeuds du maillage + t_noms_noeuds_maillage = aster.getvectjev(nom_maillage.ljust(8)+'.NOMNOE') + # on convertit en liste pour utiliser la methode index + # qui est plus optimal qu'une boucle sur les indices du tuple + l_noms_noeuds_maillage = list(t_noms_noeuds_maillage) + + l_numeros_noeuds_fissure = [] + for i in range(0,len(l_noms_noeuds_fissure),pas): + nom = l_noms_noeuds_fissure[i] + index = l_noms_noeuds_maillage.index(nom) + l_numeros_noeuds_fissure.append(index) + + coor1=aster.getvectjev(nom_maillage.ljust(8)+'.COORDO .VALE ', + l_numeros_noeuds_fissure[i_tranche]*3,3) + coor2=aster.getvectjev(nom_maillage.ljust(8)+'.COORDO .VALE ', + l_numeros_noeuds_fissure[i_tranche+1]*3,3) + + d=sqrt( (coor1[0]-coor2[0])**2+(coor1[1]-coor2[1])**2+(coor1[2]-coor2[2])**2) + return d + +def mergeLineInTable(multiTable, lineTable, nb_noeuds): + # on ajoute a la table multiTable les colonnes de lineTable + # pour chaque nume_ordre autant de fois qu'il y a de nb_noeuds + from Utilitai.Table import Table, merge + + l_ordre = lineTable.NUME_ORDRE + l_para = lineTable.copy().para + l_para.remove('NUME_ORDRE') + for i, ordre in enumerate(l_ordre): + multiTable_i = multiTable.NUME_ORDRE==ordre + row_i = lineTable.rows[i] + for para in l_para: + valeur_i = row_i[para] + multiTable_i[para] = [valeur_i] * nb_noeuds + if i==0: + newTable=multiTable_i + else: + newTable = merge(newTable, multiTable_i) + + return newTable