def _run(self): """SPEC_OSCI""" import aster_fonctions f_in = self._lf[0] l_freq, l_amor = self._dat['FREQ'], self._dat['AMOR'] kw = self.kw l_fonc_f = [] # construction de la nappe vale_para = l_amor para = { 'INTERPOL': ['LIN', 'LOG'], 'NOM_PARA_FONC': 'FREQ', 'NOM_PARA': 'AMOR', 'PROL_DROITE': 'EXCLU', 'PROL_GAUCHE': 'EXCLU', 'NOM_RESU': kw['NATURE'] } para_fonc = { 'INTERPOL': ['LOG', 'LOG'], 'NOM_PARA': 'FREQ', 'PROL_DROITE': 'CONSTANT', 'PROL_GAUCHE': 'EXCLU', 'NOM_RESU': kw['NATURE'] } if kw['NATURE'] == 'DEPL': ideb = 0 elif kw['NATURE'] == 'VITE': ideb = 1 else: ASSERT(kw['NATURE'] == 'ACCE') ideb = 2 if kw['METHODE'] == 'RICE': # appel à DSP2SRO ASSERT(kw['NATURE_FONC'] == 'DSP') deuxpi = 2. * math.pi f_dsp = t_fonction(f_in.vale_x * deuxpi, f_in.vale_y / deuxpi, f_in.para) for iamor in l_amor: spectr = DSP2SRO(f_dsp, iamor, kw['DUREE'], l_freq, ideb) vale_y = spectr.vale_y / kw['NORME'] l_fonc_f.append(t_fonction(l_freq, vale_y, para_fonc)) elif kw['METHODE'] == 'NIGAM': # appel à SPEC_OSCI ASSERT(kw['NATURE_FONC'] == 'ACCE') spectr = aster_fonctions.SPEC_OSCI(f_in.vale_x, f_in.vale_y, l_freq, l_amor) for iamor in range(len(l_amor)): vale_y = spectr[iamor, ideb, :] / kw['NORME'] l_fonc_f.append(t_fonction(l_freq, vale_y, para_fonc)) elif kw['METHODE'] == 'HARMO': # appel à ACCE2DSP ASSERT(kw['NATURE_FONC'] == 'ACCE') for iamor in l_amor: spectr = ACCE2SRO(f_in, iamor, l_freq, ideb) vale_y = spectr.vale_y / kw['NORME'] l_fonc_f.append(t_fonction(l_freq, vale_y, para_fonc)) self.resu = t_nappe(vale_para, l_fonc_f, para)
def _build_data(self): """Read keywords to build the data""" CalcFonctionOper._build_list_fonc(self) kw = self.kw self._dat = {} # amor if kw['AMOR_REDUIT'] is None: l_amor = [0.02, 0.05, 0.1] UTMESS('I', 'FONCT0_31', valr=l_amor) else: l_amor = force_list(kw['AMOR_REDUIT']) eps = 1.e-6 for amor in l_amor: if amor > (1 - eps): UTMESS('S', 'FONCT0_36') self._dat['AMOR'] = l_amor # freq if kw['LIST_FREQ'] is not None: l_freq = kw['LIST_FREQ'].Valeurs() elif kw['FREQ'] is not None: l_freq = force_list(kw['FREQ']) else: l_freq = [] for i in range(56): l_freq.append(0.2 + 0.050 * i) for i in range(8): l_freq.append(3.0 + 0.075 * i) for i in range(14): l_freq.append(3.6 + 0.100 * i) for i in range(24): l_freq.append(5.0 + 0.125 * i) for i in range(28): l_freq.append(8.0 + 0.250 * i) for i in range(6): l_freq.append(15.0 + 0.500 * i) for i in range(4): l_freq.append(18.0 + 1.0 * i) for i in range(10): l_freq.append(22.0 + 1.500 * i) texte = [] for i in range(len(l_freq) / 5): texte.append(' %f %f %f %f %f' % tuple(l_freq[i * 5:i * 5 + 5])) UTMESS('I', 'FONCT0_32', vali=len(l_freq), valk=os.linesep.join(texte)) if min(l_freq) < 1.E-10: UTMESS('F', 'FONCT0_43') self._dat['FREQ'] = l_freq # check if abs(kw['NORME']) < 1.E-10: UTMESS('S', 'FONCT0_33') if kw['NATURE_FONC'] == 'DSP': ASSERT(kw['METHODE'] == 'RICE')
def lire_nb_valeurs(file_object, nb, extend_to, conversion, nb_bloc=1, nb_ignore=0, max_per_line=-1, regexp_label=None): """Lit nb valeurs dans file_object et les ajoute à extend_to après les avoir converties en utilisant la fonction conversion. Ignore nb_ignore lignes pour chacun des nb_bloc lus et lit au maximum max_per_line valeurs par ligne. Retourne le nombre de lignes lues.""" if max_per_line < 0: max_per_line = nb ln = 0 _printDBG("LIRE_NB_VALEURS nb=", nb, ", nb_bloc=", nb_bloc, ", nb_ignore=", nb_ignore) for i in range(nb_bloc): val = [] j = 0 label = [] while j < nb_ignore: ln += 1 line = file_object.readline() if line.strip() == '': continue j += 1 label.append(line) if nb_ignore: _printDBG("IGNORE", label) slabel = ''.join(label) if regexp_label: mat = re.search(regexp_label, slabel, re.M) if mat is None: _printDBG("LABEL", regexp_label, "non trouve, recule de", nb_ignore, "lignes.", i, "bloc(s) lu(s).") curpos = file_object.tell() file_object.seek(curpos - len(slabel)) return 0 while len(val) < nb: ln += 1 line = file_object.readline() if line.strip() == '': continue add = [conversion(v) for v in line.split()[:max_per_line]] val.extend(add) ASSERT( len(val) == nb, "%d valeurs attendues, %d valeurs lues" % (nb, len(val))) extend_to.extend(val) _printDBG("BLOC", i, ",", nb, "valeurs lues, debut :", repr(val[:3])) return ln
def __setitem__(self, key, value): ASSERT(self.get(key) is None) self.set(key, value)
def check(self): """Vérification des règles impossible à écrire dans le .capy""" # tâches à la demande if self['TYPE_RESU'] in ('HARM_GENE', 'TRAN_GENE', 'TABLE', 'CHARGE'): self.set('_calc_impe', True) self.set('_calc_forc', True) elif self['TYPE_RESU'] in ('FICHIER', 'TABLE_CONTROL'): if self.get('UNITE_RESU_IMPE') is not None: self.set('_calc_impe', True) if self.get('UNITE_RESU_FORC') is not None: self.set('_calc_forc', True) else: if self['EXCIT_SOL'] is not None: self.set('_calc_forc', True) self.set('_hasPC', self.get('GROUP_MA_CONTROL') is not None) # unités logiques if self.get('UNITE_RESU_IMPE') is None: self.set('_exec_Miss', True) self['UNITE_RESU_IMPE'] = self.UL.Libre(action='ASSOCIER') if self.get('UNITE_RESU_FORC') is None: self.set('_exec_Miss', True) self['UNITE_RESU_FORC'] = self.UL.Libre(action='ASSOCIER') # fréquences if self['TYPE_RESU'] not in ('CHARGE'): if self['LIST_FREQ'] is not None \ and self['TYPE_RESU'] not in ('FICHIER', 'HARM_GENE', 'TABLE_CONTROL'): raise aster.error('MISS0_17') # si base modale, vérifier/compléter les amortissements réduits if self['TYPE_RESU'] not in ('CHARGE'): if self['BASE_MODALE']: res = aster.dismoi('NB_MODES_DYN', self['BASE_MODALE'].nom, 'RESULTAT', 'C') ASSERT(res[0] == 0) self['_NBM_DYN'] = res[1] res = aster.dismoi('NB_MODES_STA', self['BASE_MODALE'].nom, 'RESULTAT', 'C') ASSERT(res[0] == 0) self['_NBM_STAT'] = res[1] if self['AMOR_REDUIT']: self.set('AMOR_REDUIT', force_list(self['AMOR_REDUIT'])) nval = len(self['AMOR_REDUIT']) if nval < self['_NBM_DYN']: # complète avec le dernier nadd = self['_NBM_DYN'] - nval self._keywords['AMOR_REDUIT'].extend([ self['AMOR_REDUIT'][-1], ] * nadd) nval = self['_NBM_DYN'] if nval < self['_NBM_DYN'] + self['_NBM_STAT']: # on ajoute 0. self._keywords['AMOR_REDUIT'].append(0.) # la règle ENSEMBLE garantit que les 3 GROUP_MA_xxx sont tous absents # ou tous présents if self['TYPE_RESU'] not in ('CHARGE'): if self['ISSF'] != 'NON': if self['GROUP_MA_FLU_STR'] is None: UTMESS('F', 'MISS0_22') if self['MATER_FLUIDE'] is None: UTMESS('F', 'MISS0_23')
def post_erreur_ops(self, OPTION, CHAM_GD, MODELE, GROUP_MA, **args): """ Macro POST_ERREUR permettant de calculer les erreurs en termes de norme en énergie, norme L2 du déplacement et norme L2 de la pression de contact """ import aster from Accas import _F from Utilitai.Utmess import UTMESS, ASSERT ier = 0 # La macro compte pour 1 dans la numerotation des commandes self.set_icmd(1) # Le concept sortant (de type table_sdaster ou dérivé) est tabout self.DeclareOut('tabout', self.sd) # On importe les definitions des commandes a utiliser dans la macro # Le nom de la variable doit etre obligatoirement le nom de la commande CREA_TABLE = self.get_cmd('CREA_TABLE') DETRUIRE = self.get_cmd('DETRUIRE') POST_ELEM = self.get_cmd('POST_ELEM') CREA_CHAMP = self.get_cmd('CREA_CHAMP') CREA_RESU = self.get_cmd('CREA_RESU') FORMULE = self.get_cmd('FORMULE') CALC_TABLE = self.get_cmd('CALC_TABLE') IMPR_RESU = self.get_cmd('IMPR_RESU') # récupération du phenomene iret,ibid,phenomene = aster.dismoi('PHENOMENE', MODELE.nom, 'MODELE', 'F') # seul le phénomène mécanique est pris en charge if (phenomene != 'MECANIQUE'): UTMESS('F', 'PREPOST_11') # récupération de la modélisation iret,ibid,modelisation = aster.dismoi('MODELISATION', MODELE.nom, 'MODELE', 'F') # # assertion : modèle isoparamétrique # ASSERT(modelisation in ('D_PLAN', 'C_PLAN', 'AXIS', '3D')) # le modele comporte-t-il des fissures X-FEM ? iret,nfismo,kbid = aster.dismoi('NB_FISS_XFEM', MODELE.nom, 'MODELE', 'F') lxfem = nfismo > 0 # récupération du maillage inclus dans le modele iret,ibid,nom_mail = aster.dismoi('NOM_MAILLA', MODELE.nom, 'MODELE', 'F') nom_mail = nom_mail.strip() __MA = self.get_concept(nom_mail) # récupération de la dimension géométrique iret,dime,kbid = aster.dismoi('DIM_GEOM', __MA.nom, 'MAILLAGE', 'F') # extraction des coordonnées des noeuds du maillage __CHXN=CREA_CHAMP(OPERATION='EXTR', TYPE_CHAM='NOEU_GEOM_R', NOM_CHAM='GEOMETRIE', MAILLAGE=__MA, INFO=1); # calcul des coordonnées des points d'intégration des éléments du maillage __CHXG=CREA_CHAMP(OPERATION='DISC', TYPE_CHAM='ELGA_GEOM_R', PROL_ZERO='OUI', CHAM_GD=__CHXN, MODELE=MODELE, ); # si un seul GROUP_MA, on le convertit en liste # if type(GROUP_MA) not in (list, tuple): # GROUP_MA = [GROUP_MA] # recuperation du nombre de groupes nb_group=len(GROUP_MA) # creation de la fonction nulle if (dime == 3): __ZERO=FORMULE(NOM_PARA=('X','Y','Z'), VALE='0.') else: __ZERO=FORMULE(NOM_PARA=('X','Y'), VALE='0.') if(OPTION=='DEPL_RELA'): # 1. création du champ de fonctions solution analytiques au points d'intégration l_DDL=('DX', 'DY', 'DZ') # récuparation de la liste des fonctions correspondant à DX, DY, DZ # si l'utilisateur n'a pas renseigné une fonction, on prend la fonction nulle # on associe chaque composantes du vecteur des deplacements (DX, DY, DZ) # a la liste de fonctions donnees par l'utlisateur. Si l'uilisateur n'a pas renseigné une # composante, elle sera pas prise en compte dans l'evaluation de la solution analytique # dictionnaire associant une composante a la liste de fonctions correspondantes ddl2func={} # dictionnaire associant une composante a un indice pour avoir par exemple : # DX -> X1, DY -> X2 ddl2ind={} i=1 # boucle sur la liste des composantes (DX, DY, DZ) for ddl in l_DDL: # recuperation de la liste de fonctions associees a la composante courante l_ddl=args[ddl] # mise a jour des mappings si la liste existe if l_ddl != None: # assertion : l'utilisateur associe une et une seule fonction pour chaque groupe if len(l_ddl) != nb_group: UTMESS('F', 'PREPOST_12', valk=ddl) ddl2func[ddl]=l_ddl ddl2ind[ddl]=i i=i+1 # si l'utilisateur n'a fourni aucune composante, on construit un champ nul if not ddl2func: ddl=l_DDL[0] ddl2func[ddl]=[__ZERO]*nb_group ddl2ind[ddl]=1 # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP l_F=[] # boucle sur la liste des composantes (DX, DY, DZ) for ddl in ddl2func: l_ddl=ddl2func[ddl] ind=ddl2ind[ddl] # boucle sur la liste des groupes for ig, group in enumerate(GROUP_MA): # creation du mot-clef facteur pour le groupe # et la composante courante d_affe={} d_affe['GROUP_MA']=group d_affe['NOM_CMP']='X' + str(ind) d_affe['VALE_F']=l_ddl[ig] # stockage du mot-clef facteur dans la liste l_F.append(_F(**d_affe)) __UanaFG=CREA_CHAMP(OPERATION='AFFE', TYPE_CHAM='ELGA_NEUT_F', MODELE=MODELE, PROL_ZERO='OUI', AFFE=l_F, ); # 2. Evaluation de la solution analytique aux points d'intégration __UanaG=CREA_CHAMP(OPERATION='EVAL', TYPE_CHAM='ELGA_NEUT_R', CHAM_F=__UanaFG, CHAM_PARA=__CHXG, ); # 3. Conversion du champ solution analytique en champ de déplacement # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP l_F=[] # boucle sur la liste des composantes (DX, DY, DZ) for ddl in ddl2func: ind=ddl2ind[ddl] # boucle sur la liste des groupes for ig, group in enumerate(GROUP_MA): # creation du mot-clef facteur pour le groupe # et le ddl courants d_asse={} d_asse['GROUP_MA']=group d_asse['CHAM_GD']=__UanaG d_asse['NOM_CMP']='X' + str(ind) d_asse['NOM_CMP_RESU']=ddl # stockage du mot-clef facteur dans la liste l_F.append(_F(**d_asse)) __UanaR=CREA_CHAMP(OPERATION='ASSE', TYPE_CHAM='ELGA_DEPL_R', MODELE=MODELE, PROL_ZERO='OUI', ASSE=l_F); # 4. création d'un champ contenant les déplacements calculés sur les groupes considérés # cette etape est facile a faire en FEM, mais parait plus delicate en X-FEM ; elle est # donc laisse de cote pour le moment # 5. discrétisation des déplacements calculés aux points d'intégration if not lxfem: __UcalG=CREA_CHAMP(OPERATION='DISC', TYPE_CHAM='ELGA_DEPL_R', MODELE=MODELE, PROL_ZERO='OUI', CHAM_GD=CHAM_GD, ); else: cham_mater=args['CHAM_MATER'] # dans le cas X-FEM, on assemble le champ de deplacement aux points de Gauss pour # se ramener un champ de la forme (DX, DY, H1X, H1Y, ..., E1X, E1Y, ...) a la forme # (DX, DY, DZ) if cham_mater is None: __UcalG=CREA_CHAMP(OPERATION='ASSE_DEPL', TYPE_CHAM='ELGA_DEPL_R', PROL_ZERO='OUI', CHAM_GD=CHAM_GD, MODELE=MODELE, ); else: __UcalG=CREA_CHAMP(OPERATION='ASSE_DEPL', TYPE_CHAM='ELGA_DEPL_R', PROL_ZERO='OUI', CHAM_MATER=cham_mater, CHAM_GD=CHAM_GD, MODELE=MODELE, ); # 6. création du champ différence entre les déplacements calculés et analytiques # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP l_F=[] # boucle sur les groupes for ig, group in enumerate(GROUP_MA): # boucles sur les ddl DX, DY et DZ for i in range(dime): # creation du mot-clef facteur pour le groupe # et le ddl courants # * traitement des déplacements calculés d_asse={} d_asse['GROUP_MA']=group d_asse['CHAM_GD']=__UcalG d_asse['CUMUL']='OUI' d_asse['COEF_R']=1. d_asse['NOM_CMP']=l_DDL[i] d_asse['NOM_CMP_RESU']=l_DDL[i] # stockage du mot-clef facteur dans la liste l_F.append(_F(**d_asse)) # * traitement des déplacements analytiques d_asse={} d_asse['GROUP_MA']=group d_asse['CHAM_GD']=__UanaR d_asse['CUMUL']='OUI' d_asse['COEF_R']=-1. d_asse['NOM_CMP']=l_DDL[i] d_asse['NOM_CMP_RESU']=l_DDL[i] # stockage du mot-clef facteur dans la liste l_F.append(_F(**d_asse)) __UdiffG=CREA_CHAMP(OPERATION='ASSE', TYPE_CHAM='ELGA_DEPL_R', MODELE=MODELE, PROL_ZERO='OUI', ASSE=l_F); # calcul de la norme L2 du deplacement pour la solution analytique et le champ difference, pour chaque groupe l_ref_norm=[] l_diff_norm=[] ref_norm_tot=0. diff_norm_tot=0. for group in GROUP_MA: # 8. calcul de la norme L2 du champ de déplacement analytique __TanaDEP =POST_ELEM(NORME=(_F(TYPE_NORM='L2', GROUP_MA=group, CHAM_GD=__UanaR, MODELE=MODELE,),)); # extraction de la norme L2 du champ de déplacement analytique tab = __TanaDEP.EXTR_TABLE() col_ref = getattr(tab, 'VALE_NORM') l_ref=col_ref.values() ref=l_ref[0] # ajout de la contribution du groupe courant a la liste des normes L2 des champs de déplacement analytiques l_ref_norm.append(ref) # ajout e la contribution du groupe courant a la norme L2 du deplacement analytique totale ref_norm_tot+=ref**2 # 9. calcul de la norme L2 du champ de déplacement différence __TdiffDEP=POST_ELEM(NORME=(_F(TYPE_NORM='L2', GROUP_MA=group, CHAM_GD=__UdiffG, MODELE=MODELE,),)); # extraction de la norme L2 du champ de déplacement difference tab = __TdiffDEP.EXTR_TABLE() col_diff = getattr(tab, 'VALE_NORM') l_diff=col_diff.values() diff=l_diff[0] # ajout de la contribution du groupe courant a la liste des normes L2 des champs de déplacement difference l_diff_norm.append(diff) # ajout e la contribution du groupe courant a la norme L2 du deplacement difference totale diff_norm_tot+=diff**2 # liberation des objets temporaires pour la prochaine iteration DETRUIRE(CONCEPT=_F(NOM=__TanaDEP), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__TdiffDEP), INFO=1) # ajout de normes en energie pour l'ensemble des groupes ref_norm_tot=math.sqrt(ref_norm_tot) l_ref_norm.append(ref_norm_tot) diff_norm_tot=math.sqrt(diff_norm_tot) l_diff_norm.append(diff_norm_tot) # creation de la variable TITRE TITRE="ERREUR EN NORME L2 DU DEPLACEMENT" # destruction des objets temporaires pour le calcul de l'erreur en deplacement DETRUIRE(CONCEPT=_F(NOM=__UanaFG), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__UanaG), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__UanaR), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__UcalG), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__UdiffG), INFO=1) if(OPTION=='ENER_RELA'): #Extraction du nom de materiau CHAM_MATER=args['CHAM_MATER'] #Extraction du type de deformation DEFORMATION=args['DEFORMATION'] # 1. création du champ de fonctions solution analytiques au points d'intégration l_SIGM=('SIXX', 'SIYY', 'SIZZ', 'SIXY', 'SIXZ', 'SIYZ') # récuparation de la liste des fonctions correspondant à SIXX, SIYY, SIZZ, SIXY, SIXZ, SIYZ # si l'utilisateur n'a pas renseigné une fonction, on prend la fonction nulle # on associe chaque composantes du tenseur des contraintes (SIXX, SIYY, SIZZ, SIXY, SIXZ, SIYZ) # a la liste de fonxtions donnees par l'utlisateur. Si l'uilisateur n'a pas renseigné une # composante, elle sera pas prise en compte dans l'evaluation de la solution analytique # dictionnaire associant une composante a la liste de fonctions coreespondantes sig2func={} # dictionnaire associant une composante a un indice pour avoir par exemple : # SIXX -> X1, SIYY -> X2 sig2ind={} i=1 # boucle sur la liste des composantes (SIXX, SIYY, SIZZ, SIXY, SIXZ, SIYZ) for sig in l_SIGM: # recuperation de la liste de fonctions associees a la composante courante l_sig=args[sig] # mise a jour des mappings si la liste existe if l_sig != None: # assertion : l'utilisateur associe une et une seule fonction pour chaque groupe if len(l_sig) != nb_group: UTMESS('F', 'PREPOST_12', valk=sig) sig2func[sig]=l_sig sig2ind[sig]=i i=i+1 # si l'utilisateur n'a fourni aucune composante, on construit un champ nul if not sig2func: sig=l_SIGM[0] sig2func[sig]=[__ZERO]*nb_group sig2ind[sig]=1 # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP l_F=[] # boucle sur la liste des composantes (SIXX, SIYY, SIZZ, SIXY, SIXZ, SIYZ) for sig in sig2func: l_sig=sig2func[sig] ind=sig2ind[sig] # boucle sur la liste des groupes for ig, group in enumerate(GROUP_MA): # creation du mot-clef facteur pour le groupe # et la composante courante d_affe={} d_affe['GROUP_MA']=group d_affe['NOM_CMP']='X' + str(ind) d_affe['VALE_F']=l_sig[ig] # stockage du mot-clef facteur dans la liste l_F.append(_F(**d_affe)) __SI_ana_F=CREA_CHAMP(OPERATION='AFFE', TYPE_CHAM='ELGA_NEUT_F', MODELE=MODELE, PROL_ZERO='OUI', AFFE=l_F,); # 2. Evaluation de la solution analytique aux points d'intégration __SanaCHAM=CREA_CHAMP(OPERATION='EVAL', TYPE_CHAM='ELGA_NEUT_R', CHAM_F=__SI_ana_F, CHAM_PARA=__CHXG, ); # 3. Conversion du champ solution analytique en champ de contrainte # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP l_F=[] # boucle sur la liste des composantes (SIXX, SIYY, SIZZ, SIXY, SIXZ, SIYZ) for sig in sig2func: ind=sig2ind[sig] # boucle sur la liste des groupes for ig, group in enumerate(GROUP_MA): # creation du mot-clef facteur pour le groupe # et le SIGM courants d_asse={} d_asse['GROUP_MA']=group d_asse['CHAM_GD']=__SanaCHAM d_asse['NOM_CMP']='X' + str(ind) d_asse['NOM_CMP_RESU']=sig # stockage du mot-clef facteur dans la liste l_F.append(_F(**d_asse)) __SI_ana_R=CREA_CHAMP(OPERATION='ASSE', TYPE_CHAM='ELGA_SIEF_R', MODELE=MODELE, PROL_ZERO='OUI', ASSE=l_F); # 4. création du champ différence entre les contraintes calculés et analytiques # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP l_F=[] # boucle sur les groupes for ig, group in enumerate(GROUP_MA): # boucles sur les composantes: SIXX, SIYY, SIZZ, SIXY, SIXZ, SIYZ for i in range(2*dime): # creation du mot-clef facteur pour le groupe # et le SIGM courants # * traitement des contraintes calculés d_asse={} d_asse['GROUP_MA']=group d_asse['CHAM_GD']=CHAM_GD d_asse['CUMUL']='OUI' d_asse['COEF_R']=1. d_asse['NOM_CMP']=l_SIGM[i] d_asse['NOM_CMP_RESU']=l_SIGM[i] # stockage du mot-clef facteur dans la liste l_F.append(_F(**d_asse)) # * traitement des contraintes analytiques d_asse={} d_asse['GROUP_MA']=group d_asse['CHAM_GD']=__SI_ana_R d_asse['CUMUL']='OUI' d_asse['COEF_R']=-1. d_asse['NOM_CMP']=l_SIGM[i] d_asse['NOM_CMP_RESU']=l_SIGM[i] # stockage du mot-clef facteur dans la liste l_F.append(_F(**d_asse)) __SI_diff=CREA_CHAMP(OPERATION='ASSE', TYPE_CHAM='ELGA_SIEF_R', MODELE=MODELE, PROL_ZERO='OUI', ASSE=l_F); # 5. création d'un champ de deplacement nul partout # ce champ de deplacement est essentiel pour calculer les normes, mais n'aucun impact sur les resultats l_DDL=('DX', 'DY', 'DZ') # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP l_F=[] # boucle sur les groupes for ig, group in enumerate(GROUP_MA): # boucles sur les ddl DX, DY et DZ for i in range(dime): # creation du mot-clef facteur pour le groupe # et le ddl courants d_affe={} d_affe['GROUP_MA']=group d_affe['NOM_CMP']=l_DDL[i] d_affe['VALE']=0. # stockage du mot-clef facteur dans la liste l_F.append(_F(**d_affe)) __U=CREA_CHAMP(OPERATION='AFFE', TYPE_CHAM='NOEU_DEPL_R', MAILLAGE=__MA, AFFE=l_F); # 6. création d'un champ resultat a partir de champ de contrainte analytique __SIanaRES=CREA_RESU(OPERATION='AFFE', TYPE_RESU='EVOL_NOLI', NOM_CHAM='SIEF_ELGA', COMPORTEMENT = (_F(RELATION = 'ELAS', DEFORMATION = DEFORMATION,),), AFFE=_F(CHAM_GD=__SI_ana_R, MODELE=MODELE, CHAM_MATER=CHAM_MATER, INST = (1.0),), ); __SIanaRES=CREA_RESU(reuse=__SIanaRES, OPERATION='AFFE', TYPE_RESU='EVOL_NOLI', NOM_CHAM='DEPL', COMPORTEMENT = (_F(RELATION = 'ELAS', DEFORMATION = DEFORMATION,),), AFFE=_F(CHAM_GD=__U, MODELE=MODELE, CHAM_MATER=CHAM_MATER, INST = (1.0),), ); # 7. création d'un champ resultat a partir de champ de contrainte difference __SI_DIFFR=CREA_RESU(OPERATION='AFFE', TYPE_RESU='EVOL_NOLI', NOM_CHAM='SIEF_ELGA', COMPORTEMENT = (_F(RELATION = 'ELAS', DEFORMATION = DEFORMATION,),), AFFE=_F(CHAM_GD=__SI_diff, MODELE=MODELE, CHAM_MATER=CHAM_MATER, INST = (1.0),), ); __SI_DIFFR=CREA_RESU(reuse=__SI_DIFFR, OPERATION='AFFE', TYPE_RESU='EVOL_NOLI', NOM_CHAM='DEPL', COMPORTEMENT = (_F(RELATION = 'ELAS', DEFORMATION = DEFORMATION,),), AFFE=_F(CHAM_GD=__U, MODELE=MODELE, CHAM_MATER=CHAM_MATER, INST = (1.0),), ); # 8. calcul de l'energie a partir du champ de contraintes analytique __TanaSIG = POST_ELEM(RESULTAT=__SIanaRES,ENER_ELAS=_F(GROUP_MA=GROUP_MA), ); # 9. calcul de l'energie a partir du champ de contraintes difference __TdiffSIG= POST_ELEM(RESULTAT=__SI_DIFFR,ENER_ELAS=_F(GROUP_MA=GROUP_MA), ); #creation de la table finale tab = __TanaSIG.EXTR_TABLE() col_ref = getattr(tab, 'TOTALE') l_ref=col_ref.values() tab = __TdiffSIG.EXTR_TABLE() col_diff = getattr(tab, 'TOTALE') l_diff=col_diff.values() # assertion: les longueurs de l_ref et l_diff sont egales au nombre de groupes ASSERT( len(l_ref) == nb_group and len(l_diff) == nb_group ) # calcul des normes en energie pour chaque groupe l_ref_norm=[] l_diff_norm=[] for i in range(nb_group): l_ref_norm.append(math.sqrt(l_ref[i])) l_diff_norm.append(math.sqrt(l_diff[i])) # ajout de normes en energie pour l'ensemble des groupes ref_norm_tot=math.sqrt(sum(l_ref)) l_ref_norm.append(ref_norm_tot) diff_norm_tot=math.sqrt(sum(l_diff)) l_diff_norm.append(diff_norm_tot) # ajout des energies pour l'ensemble des groupes l_ref.append(sum(l_ref)) l_diff.append(sum(l_diff)) # creation de la variable TITRE TITRE="ERREUR EN NORME ENERGIE" # destruction des objets temporaires pour le calcul de l'erreur en energie DETRUIRE(CONCEPT=_F(NOM=__SI_ana_F), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__SanaCHAM), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__SI_ana_R), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__SI_diff), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__U), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__SIanaRES), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__SI_DIFFR), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__TanaSIG), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__TdiffSIG), INFO=1) if(OPTION=='LAGR_RELA'): # le calcul de la norme L2 de la pression de contact sur une fissure XFEM n'est # pas encore diponible if lxfem: UTMESS('F', 'XFEM_14') # 1. création du champ de fonctions solution analytiques au points d'intégration # récuparation de la liste des fonctions correspondant à LAGS_C # si l'utilisateur n'a pas renseigné une fonction, on prend la fonction nulle l_LAGS=args['LAGS_C'] if l_LAGS is None: l_LAGS=[__ZERO]*nb_group # assertion : ici, on a une et une seule fonction LAGS_C pour chaque groupe if len(l_LAGS) != nb_group: UTMESS('F', 'PREPOST_12', valk="LAGS_C") # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP l_F=[] # boucle sur les groupes for ig, group in enumerate(GROUP_MA): # récupération de la fonction LAGS_C pour le groupe courant LAGS=l_LAGS[ig] # creation du mot-clef facteur pour le groupe # courant d_affe={} d_affe['GROUP_MA']=group d_affe['NOM_CMP']='X3' d_affe['VALE_F']=LAGS # stockage du mot-clef facteur dans la liste l_F.append(_F(**d_affe)) __PanaFG=CREA_CHAMP(OPERATION='AFFE', TYPE_CHAM='ELGA_NEUT_F', MODELE=MODELE, PROL_ZERO='OUI', AFFE=l_F, ); # 2. Evaluation de la solution analytique aux points d'intégration __PanaG=CREA_CHAMP(OPERATION='EVAL', TYPE_CHAM='ELGA_NEUT_R', CHAM_F=__PanaFG, CHAM_PARA=__CHXG, ); # 3. Conversion du champ solution analytique en champ de déplacement # N.B.: L'intégration de la pression asocciée au ddl LAG_C donne 0 ! # On l'associe donc à un autre ddl choisi arbitrairement : DZ. # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP l_F=[] # boucle sur les groupes for ig, group in enumerate(GROUP_MA): # creation du mot-clef facteur pour le groupe # et le ddl courants d_asse={} d_asse['GROUP_MA']=group d_asse['CHAM_GD']=__PanaG d_asse['NOM_CMP']='X3' d_asse['NOM_CMP_RESU']='DZ' # stockage du mot-clef facteur dans la liste l_F.append(_F(**d_asse)) __PanaR=CREA_CHAMP(OPERATION='ASSE', TYPE_CHAM='ELGA_DEPL_R', MODELE=MODELE, PROL_ZERO='OUI', ASSE=l_F); # 4. création d'un champ contenant les déplacements calculés sur les groupes considérés # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP l_F=[] # boucle sur les groupes for ig, group in enumerate(GROUP_MA): # creation du mot-clef facteur pour le groupe # et le ddl courants d_asse={} d_asse['GROUP_MA']=group d_asse['CHAM_GD']=CHAM_GD d_asse['NOM_CMP_RESU']='X3' d_asse['NOM_CMP']='LAGS_C' # stockage du mot-clef facteur dans la liste l_F.append(_F(**d_asse)) __PcalN=CREA_CHAMP(OPERATION='ASSE', TYPE_CHAM='NOEU_NEUT_R', MAILLAGE=__MA, ASSE=l_F); # 5. discrétisation des déplacements calculés aux points d'intégration __PcalG=CREA_CHAMP(OPERATION='DISC', TYPE_CHAM='ELGA_NEUT_R', MODELE=MODELE, PROL_ZERO='OUI', CHAM_GD=__PcalN, ); # 6. création du champ différence entre les déplacements calculés et analytiques # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP l_F=[] # boucle sur les groupes for ig, group in enumerate(GROUP_MA): # * traitement des déplacements calculés d_asse={} d_asse['GROUP_MA']=group d_asse['CHAM_GD']=__PcalG d_asse['CUMUL']='OUI' d_asse['COEF_R']=1. d_asse['NOM_CMP']='X3' d_asse['NOM_CMP_RESU']='DZ' # stockage du mot-clef facteur dans la liste l_F.append(_F(**d_asse)) # * traitement des déplacements analytiques d_asse={} d_asse['GROUP_MA']=group d_asse['CHAM_GD']=__PanaG d_asse['CUMUL']='OUI' d_asse['COEF_R']=-1. d_asse['NOM_CMP']='X3' d_asse['NOM_CMP_RESU']='DZ' # stockage du mot-clef facteur dans la liste l_F.append(_F(**d_asse)) __PdiffG=CREA_CHAMP(OPERATION='ASSE', TYPE_CHAM='ELGA_DEPL_R', MODELE=MODELE, PROL_ZERO='OUI', ASSE=l_F); # calcul de la norme L2 du deplacement pour la solution analytique et le champ difference, pour chaque groupe l_ref_norm=[] l_diff_norm=[] ref_norm_tot=0. diff_norm_tot=0. for group in GROUP_MA: # 8. calcul de la norme L2 du champ de déplacement analytique __TanaP =POST_ELEM(NORME=(_F(TYPE_NORM='L2', GROUP_MA=group, CHAM_GD=__PanaR, MODELE=MODELE,),)); # extraction de la norme L2 du champ de déplacement analytique tab = __TanaP.EXTR_TABLE() col_ref = getattr(tab, 'VALE_NORM') l_ref=col_ref.values() ref=l_ref[0] # ajout de la contribution du groupe courant a la liste des normes L2 des champs de déplacement analytiques l_ref_norm.append(ref) # ajout e la contribution du groupe courant a la norme L2 du deplacement analytique totale ref_norm_tot+=ref**2 # 9. calcul de la norme L2 du champ de déplacement différence __TdiffP=POST_ELEM(NORME=(_F(TYPE_NORM='L2', GROUP_MA=group, CHAM_GD=__PdiffG, MODELE=MODELE,),)); # extraction de la norme L2 du champ de déplacement difference tab = __TdiffP.EXTR_TABLE() col_diff = getattr(tab, 'VALE_NORM') l_diff=col_diff.values() diff=l_diff[0] # ajout de la contribution du groupe courant a la liste des normes L2 des champs de déplacement difference l_diff_norm.append(diff) # ajout e la contribution du groupe courant a la norme L2 du deplacement difference totale diff_norm_tot+=diff**2 # liberation des objets temporaires pour la prochaine iteration DETRUIRE(CONCEPT=_F(NOM=__TanaP), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__TdiffP), INFO=1) # ajout de normes en energie pour l'ensemble des groupes ref_norm_tot=math.sqrt(ref_norm_tot) l_ref_norm.append(ref_norm_tot) diff_norm_tot=math.sqrt(diff_norm_tot) l_diff_norm.append(diff_norm_tot) # creation de la variable TITRE TITRE="ERREUR EN NORME L2 DE LA PRESSION" # destruction des objets temporaires pour le calcul de l'erreur en deplacement DETRUIRE(CONCEPT=_F(NOM=__PanaFG), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__PanaG), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__PanaR), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__PcalN), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__PcalG), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__PdiffG), INFO=1) # ici, quelle que soit la norme considérée, les objets suivants sont définis : # * l_diff_norm : liste des normes du champ différence, pour chaque groupe + # norme du champ différence sur l'union des groupes # creation de la liste GROUP_MA + "TOTAL" l_group=list(GROUP_MA) l_group.append("TOTAL") if (OPTION == 'ENER_RELA'): tabout=CREA_TABLE(LISTE=(_F(LISTE_K=l_group, PARA="GROUP_MA"), _F(LISTE_R=l_diff, PARA ="DIFFERENCE",), _F(LISTE_R=l_ref, PARA ="REFERENCE",), ), TITRE=TITRE, ); else: tabout=CREA_TABLE(LISTE=(_F(LISTE_K=l_group, PARA="GROUP_MA"), _F(LISTE_R=l_diff_norm, PARA ="DIFFERENCE",), _F(LISTE_R=l_ref_norm, PARA ="REFERENCE",), ), TITRE=TITRE, ); # on ne calcule l'erreur relative que si la reference est non nulle if ref_norm_tot > 1.e-16: __Terr=CREA_TABLE(LISTE=(_F(LISTE_K=("TOTAL"), PARA="GROUP_MA"), _F(LISTE_R=(diff_norm_tot/ref_norm_tot), PARA ="ERREUR RELATIVE") ) ) tabout=CALC_TABLE(reuse=tabout, TABLE=tabout, ACTION =_F(OPERATION="COMB", TABLE=__Terr, NOM_PARA="GROUP_MA"), TITRE=TITRE, ) # destruction des objets temporaires generiques # N.B.: __MA est une reference au maillage, il ne faut pas le detruire ! DETRUIRE(CONCEPT=_F(NOM=__CHXN), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__CHXG), INFO=1) DETRUIRE(CONCEPT=_F(NOM=__ZERO), INFO=1) return ier
def bloc_cara(typ_carel, l_elem, epx, group, select, directive, mot_cle_aster, mot_cle_epx, cara_aster, cara_epx, coef_mult, is_vale_aster, mode_epx, mode_from_cara, titre, verif, dic_gr_cara_supp): """ Analyse les données contenues dans une liste d'instances 'l_elem' du mot clé facteur 'typ_carel' de AFFE_CARA_ELEM. 'l_elem' contient la plupart du temps un seul élément, sauf dans le cas de typ_carel='DISCRET'. """ l_elem = tolist(l_elem) mot_cle_epx_select = None l_cara = [] l_vale = [] mot_cle_ignor = ['GROUP_MA'] for elem in l_elem: for i_dic, sele in enumerate(select): # sélection de la bonne traduction good_trad = True for cle in sele.keys(): if elem.has_key(cle): if sele[cle] is not None: valcle = elem[cle] if type(elem[cle]) is list or type(elem[cle]) is tuple: if len(elem[cle]) == 1: valcle = elem[cle][0] if valcle != sele[cle]: good_trad = False break if not good_trad: continue # la traduction est sélectionnée mot_cle_ok = [] mot_cle_ok.extend(sele.keys()) if mot_cle_aster[i_dic]: # le mot-clé est présent en tant que mot-clé if elem.has_key(mot_cle_aster[i_dic]): val_cle = elem[mot_cle_aster[i_dic]]*coef_mult[i_dic] vale = [] cara = [] if not mot_cle_aster[i_dic] in mot_cle_ok: mot_cle_ok.append(mot_cle_aster[i_dic]) # le mot-clé est la valeur de 'CARA' else: cara_in = tolist(elem['CARA']) ASSERT(len(cara_in) == 1) ASSERT(cara_in[0] == mot_cle_aster[i_dic]) if not 'CARA' in mot_cle_ok: mot_cle_ok.append('CARA') if not 'VALE' in mot_cle_ok: mot_cle_ok.append('VALE') valeur = tolist(elem['VALE']) if cara_epx[i_dic]: # is_vale_aster est obligatoire dans ce cas ASSERT(is_vale_aster[i_dic]) cara = list(cara_epx[i_dic]) vale = [None] * len(cara) k_valeur = 0 for i_log, logi in enumerate(is_vale_aster[i_dic]): if logi: vale[i_log] = valeur[k_valeur]*coef_mult[i_dic][i_log] k_valeur += 1 val_cle = '' else: ASSERT(len(valeur) == 1) val_cle = valeur[0]*coef_mult[i_dic] vale = [] cara = [] # couple CARA/VALE avec plusieurs caractéristiques else: if not 'CARA' in mot_cle_ok: mot_cle_ok.append('CARA') if not 'VALE' in mot_cle_ok: mot_cle_ok.append('VALE') val_cle = '' cara_in = tolist(elem['CARA']) vale_in = tolist(elem['VALE']) cara = cara_epx[i_dic] vale = [None] * len(cara) for i, car in enumerate(cara_in): if not car in cara_aster[i_dic]: UTMESS('F', 'PLEXUS_8', valk=(car, typ_carel)) val = vale_in[i] index = cara_aster[i_dic].index(car) vale[index] = val*coef_mult[i_dic][index] # traitement des doublons (cas ou aster est plus riche qu'EPX # on verifie que les doublons ont la meme valeur i = 0 while i< len(cara): car1 = cara[i] while cara.count(car1)>1: index = cara[i+1:].index(car1) index+= i+1 if vale[i] == vale[index]: cara.pop(index) vale.pop(index) else: UTMESS('F','PLEXUS_16', valk = [typ_carel, mot_cle_aster[i_dic]], vali = [i+1, index+1]) i+=1 # verif des mots-clés autorisés mc_verif = [] if verif[i_dic]: mc_verif = verif[i_dic].keys() for key in elem.keys(): if key in mot_cle_ok: continue elif key in mot_cle_ignor: continue elif key in mc_verif: continue else: UTMESS('F', 'PLEXUS_45', valk=[key, typ_carel]) # on complete VALE avec des donnees provenant d'ailleurs if None in vale: for i, val in enumerate(vale): if val is None: car = cara[i] # s'il y a en même temps K_T_D_L et A_T_D_L sur des DISCRET en repère local # VX, VY et VZ vont être présents deux fois : on ne les ajoutes pas dans ce cas if car in l_cara: cara[i] = None continue if not dic_gr_cara_supp.has_key(group): UTMESS( 'F', 'PLEXUS_12', valk=(car, typ_carel, group)) if not car in dic_gr_cara_supp[group]: UTMESS( 'F', 'PLEXUS_12', valk=(car, typ_carel, group)) if type(dic_gr_cara_supp[group][car]) == int: vale[i] = dic_gr_cara_supp[group][car]*int(coef_mult[i_dic][i]) else: vale[i] = dic_gr_cara_supp[group][car]*coef_mult[i_dic][i] while None in cara: cara.remove(None) vale.remove(None) # if verif[i_dic]: for mc_aster in verif[i_dic].keys(): if verif[i_dic][mc_aster] is None: continue elif elem.has_key(mc_aster): if elem[mc_aster] not in verif[i_dic][mc_aster]: liste_ok = ', '.join(verif[i_dic][mc_aster]) UTMESS('F', 'PLEXUS_4', valk=(typ_carel, mc_aster, elem[mc_aster], liste_ok)) else: UTMESS('F', 'PLEXUS_56', valk=(typ_carel, mc_aster)) if mot_cle_epx_select == None: mot_cle_epx_select = mot_cle_epx[i_dic] directive_select = directive[i_dic] val_cle_select = val_cle titre_select = titre[i_dic] mode_epx_select = mode_epx[i_dic] else: if (mot_cle_epx_select != mot_cle_epx[i_dic] or directive_select != directive[i_dic] or val_cle_select != val_cle or titre_select != titre[i_dic] or mode_epx_select != mode_epx[i_dic]): raise Exception('Erreur dev : Incohérence des donnees') l_cara.extend(cara) l_vale.extend(vale) if mot_cle_epx_select == None: UTMESS('F','PLEXUS_52',valk = [typ_carel]) bloc_donnees = BLOC_DONNEES(mot_cle_epx_select, l_group=group, val_cle=val_cle_select, cara=l_cara, vale=l_vale, titre=titre_select) epx[directive_select].add_bloc(bloc_donnees) if mode_epx_select is not None: if not mode_from_cara.has_key(group): mode_from_cara[group] = mode_epx_select else: if mode_from_cara[group] != mode_epx_select: UTMESS('F', 'PLEXUS_9', valk=(mode_from_cara[group], mode_epx_select, group)) return epx, mode_from_cara