ANSA官方自带脚本Pids2Mids.py(路径:..\BETA_CAE_Systems\ansa_v22.0.0\scripts\Properties)主要功能是:对材料进行重编号,使mat与prop拥有相同的标识。若某一材料被多个prop共用,则复 制该材料,确保实现prop-mat一一对应关系。源码如下:'''==================================================* HEADER==================================================Developed by:Irene MakropoulouDate:26/01/2011 BETA CAE Systems Kato Scholari, Thessaloniki, GR-57500, Epanomi, Greece Tel: +302392021420 , +302311993300 Fax: +302392021417 E-mail: ansa@beta-cae.com URL: http://www.beta-cae.com Copyright (c) 2011 BETA CAE Systems All rights reserved.=================================================* DISCLAIMER=================================================BETA CAE Systems assumes no responsibility or liability for any damages, errors, inaccuracies or data loss caused by installation or use of this software.=================================================* HISTORY=================================================Date: Updater: Modifications:-------------------------------------------------Date: Updater:Modifications:-------------------------------------------------''''''Name: Pids2MidsDescription: Renumbers materials so that they have the same id with the properties. In case one material is used by more than one properties, copies of this material are generated in order for the 1-1 correspondence to be generated.'''import ansafrom ansa import basefrom ansa import constants@ansa.session.defbutton('PROPERTIES', 'Pids2Mids')def Pids2MidsMain(): """ Renumbers materials so that they have the same id with the properties. In case one material is used by more than one properties, copies of this material are generated in order for the 1-1 correspondence to be generated. """ ptypes = base.TypesInCategory(0, "__PROPERTIES__") props = base.CollectEntities(0, None, ptypes) mtypes = base.TypesInCategory(0, "__MATERIALS__") PidToMatEnt = dict() OrigMatEntToMid = dict() IsMIDAllocated = dict() for p_ent in props: p_mats = _CollectMatsFromProp(p_ent) if len(p_mats) > 1: print ("More than one mats associated with PID ", p_ent._id) m_ent = p_mats[0] PidToMatEnt [p_ent._id] = m_ent; OrigMatEntToMid [m_ent] = p_mats[0]._id IsMIDAllocated [p_mats[0]._id] = 1 respect_frozen = True force = False j = 0 IsAlreadyModified = dict() for pid, mat_ent in PidToMatEnt.items(): trgt_mid = pid orig_mid = OrigMatEntToMid[mat_ent] if mat_ent in IsAlreadyModified: new_mat_ent = base.CopyEntity(None, mat_ent) mat_ent = new_mat_ent prop_ent = base.GetEntity (0, "__PROPERTIES__", pid) _SetMaterialToProperty (prop_ent, mat_ent._id) OrigMatEntToMid [mat_ent] = mat_ent._id IsMIDAllocated [mat_ent._id] = 1 if trgt_mid == mat_ent._id: continue IsMatWithSameId = base.GetEntity(0, "__MATERIALS__", trgt_mid) if not IsMatWithSameId: ret = base.SetEntityId(mat_ent, trgt_mid, force, respect_frozen) IsAlreadyModified [mat_ent] = 1 else: is_matid_set = False temp_id = 99999999 while not is_matid_set: if not temp_id in IsMIDAllocated: print('mpika') base.SetEntityId(IsMatWithSameId, temp_id, force, respect_frozen) OrigMatEntToMid[IsMatWithSameId] = temp_id base.SetEntityId(mat_ent, trgt_mid, force, respect_frozen) is_matid_set = True IsAlreadyModified[mat_ent] = 1 else: temp_id -= 1 del PidToMatEnt del OrigMatEntToMid del IsMIDAllocated del IsAlreadyModified print("Done")def _CollectMatsFromProp(p_ent): all_decks = {1:"MID1", 2:"MID", 3:"MID", 4:"IMAT", 5:"MID", 6:"MID"} cur_deck = base.CurrentDeck() ret = base.GetEntityCardValues(0, p_ent, (all_decks[cur_deck],)) m_ent = base.GetEntity(0, "__MATERIALS__", ret[all_decks[cur_deck]]) return [m_ent]def _SetMaterialToProperty(p_ent, mid): all_decks = {1:"MID1", 2:"MID", 3:"MID", 4:"IMAT", 5:"MID", 6:"MID"} cur_deck = base.CurrentDeck() base.SetEntityCardValues (0, p_ent, {all_decks[cur_deck]:mid}) return;
官方源码仅仅考虑了NASTRAN、LS-DYNA、PAM-CRASH、ABAQUS、RADIOSS、ANSYS 6种求解器,在实际使用过程中,像OPTISTRUCT、MARC等常用求解器均不支持,另外,官方源码实现方式冗余复杂,导致开发工程师解析困难。基于上述两点,笔者对该功能进行了重写。新代码覆盖了ANSA当前支持的所有25种求解器,并且通过对prop-mat一一对应解构并且巧用空位mid,将代码的时间复杂度由O(n2)降低为O(n)。实现源码如下:from ansa import base, sessionfrom typing import List, Dict, Setclass Pids2Mids(object): deck2MatField:Dict[int, str] = { 1: 'MID1', 2: 'MID', 3: 'MID', 4: 'IMAT', 5: 'MID', 6: 'MID', 7: 'MID', 8: 'MID', 9: 'MID', 10: 'MID', 11: 'MID', 12: 'MID', 13: 'MID', 14: 'MID', 15: 'Material', 16: 'MATNO', 17: 'MID', 18: 'MID', 19: 'MID', 20: 'MID', 21: 'MID', 22: 'MID1', 23: 'MID', 24: 'MID', 25: 'mid' } def __init__(self): self.curDeck:int = base.CurrentDeck() self.midField:str = self.deck2MatField[self.curDeck] self.props2MatsDict:Dict[base.Entity, base.Entity] = dict() def createPid2MidDict(self)->Set[int]: ''' 用于构造prop2Mat字典。若一个mat被多个prop应用,复 制mat重新赋予给prop, 确保prop-mat具有一一对应的关系。同时构建一个matSet用于存储当前所有mat ID 用于后续调整MID过程中ID冲突检查。 ''' matSet:Set[int] = set() props:List[base.Entity] = base.CollectEntitiesI(self.curDeck, None, '__PROPERTIES__') for prop in props: mat:base.Entity = prop.get_entity_values(self.curDeck, (self.midField, ))[self.midField] if mat._id in matSet: mat = base.CopyEntity(None, mat) prop.set_entity_values(self.curDeck, {self.midField: mat._id}) self.props2MatsDict[prop] = mat matSet.add(mat._id) return matSet def run(self): midSet:Set[int] = self.createPid2MidDict() tempMid:int = 1 while tempMid in midSet: tempMid += 1 for prop, mat in self.props2MatsDict.items(): if prop._id==mat._id: continue oldMid:int = mat._id tempMat:base.Entity = base.GetEntity(self.curDeck, '__MATERIALS__', int(prop._id)) if tempMat: base.SetEntityId(tempMat, tempMid, False, True) base.SetEntityId(mat, prop._id, False, True) tempMid = oldMid print('Done!!!') return None def Pids2MidsMain(): pidObj = Pids2Mids() pidObj.run() if __name__ == '__main__': Pids2MidsMain()