首页/文章/ 详情

ANSA二次开发:SegregatePID功能解析

7月前浏览737

ANSA自带脚本SegregatePID.py(路径:..\BETA_CAE_Systems\ansa_v22.0.0\scripts\Properties)主要功能是:若一个property中存在多个部件,利用该脚本可以对这个property进行拆分,拆分后一个部件对应一个property,且每个新的prop属性和初始prop完全一致。

源码如下:






















































































'''==================================================*                    HEADER==================================================Developed by:Nikolas DrivakosDate:15/02/2013                                 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:SegregatePIDDescription: It assigns new PID to all "islands" of faces or FE that belong to the selected properties / FE'''import ansafrom ansa import basefrom ansa import constants@ansa.session.defbutton('PROPERTIES', 'SegregatePID')def SegregatePIDMain():  """  It assigns new PID to all "islands" of faces or FE that belong to the selected properties / FE  """  props = base.PickEntities(constants.NASTRAN, ("PSHELL",))    if not props:    print('No PSHELLs were found')    return 1  m_faces = dict()  m_elems = dict()    for prop in props:    faces = base.CollectEntities(constants.NASTRAN, prop, "FACE", True)    if not faces:      continue    elem_in_faces = base.CollectEntities(base.NASTRAN, faces, "SHELL", True)    for face in faces:      if face in m_faces:        continue      base.Or(face)      base.Neighb('ALL')      new_faces = base.CollectEntities(constants.NASTRAN, new_faces, "FACE", filter_visible=True)      prop_new = base.CopyEntity(None, prop)      for new_face in new_faces:        base.SetEntityCardValues(constants.NASTRAN, new_face, {"PID":prop_new._id})        m_faces[new_face] = 1    for elem_in_face in elem_in_faces:      m_elems [elem_in_face] = 1  del m_faces    elems = base.CollectEntities(constants.NASTRAN, props, "SHELL")  for elem in elems:    if elem in m_elems:       continue    ret = base.GetEntityCardValues(NASTRAN, elem, ("PID",))    old_prop = base.GetEntity(constants.NASTRAN,"PSHELL", ret['PID'])    base.Or(elem)    base.Neighb("ALL")    prop_new = base.CopyEntity(None, old_prop)    new_elems = base.CollectEntities(constants.NASTRAN, None, "SHELL", filter_visible=True)    for new_elem in new_elems:      base.SetEntityCardValues(constants.NASTRAN, new_elem, {"PID":prop_new._id})      m_elems[new_elem] = 1

但该源码存在如下几个缺陷:

1. 代码有误:
71行,base.NASTRAN应为constants.NASTRAN

elem_in_faces = base.CollectEntities(constants.NASTRAN, faces, "SHELL", True)
77行,new_faces使用前为定义,可将代码改为:

new_faces = base.CollectEntities(constants.NASTRAN, None, "FACE", filter_visible=True)
92行,NASTRAN应为constants.NASTRAN

ret = base.GetEntityCardValues(constants.NASTRAN, elem, ("PID",))
2. 该脚本对于网格仅考虑了shell类型,在实际使用中应考虑到solid类型;
3. 该脚本运行速度较慢,25个property包含263个部件的一个总成进行拆分需要11.5秒,通过对代码进行优化,相同的子总成拆分可在0.5秒内完成。改进后的代码如下:







































from ansa import basefrom ansa import constantsfrom typing import List, Union, TupleDECK = constants.NASTRAN
def SegregatePIDMain():  # 拾取待拆分的property  props:Union[List[base.Entity], None] =  base.PickEntities(DECK, ("PSHELL",))    if not props:    print('当前模型不存在propety,请先导入模型...')    return None
  # 按face的独立性进行拆分  elemInFaces:List[base.Entity] = list()  for prop in props:    faces:List[base.Entity] = base.CollectEntities(DECK, prop, 'FACE', recursive=True)    if not faces:continue    while faces:      newFaces:List[base.Entity] = base.GatherFaces(faces[0], 40.0, visibility='visible', container='PID_region')      newProp:base.Entity = base.CopyEntity(None, prop)      _ = [newFace.set_entity_values(DECK, {'PID': newProp._id}) for newFace in newFaces]      faces = list(set(faces)-set(newFaces))    elemInFaces.extend(base.CollectEntities(DECK, faces, ('SHELL', 'SOLID'), recursive=True))    # 按网格的独立性进行拆分  for prop in props:    elems:List[base.Entity] = base.CollectEntities(DECK, prop, ('SHELL', 'SOLID'), recursive=True)    elems = list(set(elems)-set(elemInFaces))    while elems:      elem = elems[0]      newElems:List[base.Entity] = base.GatherElements(DECK, type='Same', search_mode='Connectivity', gather_from='Visible', gather_from_containers=elem, source=elem)      if not newElems: newElems = [elem]      else: newElems = newElems[elem]            newProp:base.Entity = base.CopyEntity(None, prop)      _ = [newElem.set_entity_values(DECK, {'PID': newProp._id}) for newElem in newElems]      elems = list(set(elems)-set(newElems))  return None
通过上述优化,运行效率大大提高。不过该功能仅仅对prop进行了拆分,在实际使用过程中,还存在需要对part按prop进行拆分,即一个part对应一个prop,有时还需要一个prop对应一个部件,即三者需要一一对应。为实现上述需要,笔者进行了相关功能实现,具体如下:































































































































































from ansa import basefrom ansa import constantsfrom ansa import guitkfrom typing import List, Union, TupleDECK = constants.NASTRANclass Segregate(object):  selectTypes:Tuple[str] = ('Visible', 'All', 'Selected')  entTypes:Tuple[str] = ('AnsaPart', 'Property')    def __init__(self):    self.mainWindow = guitk.BCWindowCreate('模型拆分器', guitk.constants.BCOnExitDestroy)    self.mainBox = guitk.BCVBoxCreate(self.mainWindow)    self.init()    guitk.BCShow(self.mainWindow)    def init(self):    selectBox = guitk.BCVBoxCreate(self.mainBox)    selectTypeBox = guitk.BCHBoxCreate(selectBox)    guitk.BCLabelCreate(selectTypeBox, '选择方式: ')    self.selectTypeCombo = guitk.BCComboBoxCreate(selectTypeBox, self.selectTypes)    guitk.BCComboBoxSetCurrentItem(self.selectTypeCombo, 0)        entTypeBox = guitk.BCHBoxCreate(selectBox)    guitk.BCLabelCreate(entTypeBox, '选择对象类型: ')    self.entTypeCombo = guitk.BCComboBoxCreate(entTypeBox, self.entTypes)    guitk.BCComboBoxSetCurrentItem(self.entTypeCombo, 0)        self.propSegCheckBox = guitk.BCCheckBoxCreate(entTypeBox, '是否按PID拆分')    guitk.BCCheckBoxSetChecked(self.propSegCheckBox, False)    guitk.BCShow(self.propSegCheckBox)    guitk.BCComboBoxSetCurrentIndexChangedFunction(self.entTypeCombo, self.entTypeComboChangedFunc, None)        controlBox = guitk.BCHBoxCreate(self.mainBox)    self.okButton = guitk.BCPushButtonCreate(controlBox, 'OK', self.okFunc, None)    self.cancelButton = guitk.BCPushButtonCreate(controlBox, 'Cancal', self.rejectFunc, None)    return None    @property  def curSelectType(self)->str:    val:str = guitk.BCComboBoxCurrentText(self.selectTypeCombo)    return val if val else ''    @property  def curEntType(self)->str:    val:str = guitk.BCComboBoxCurrentText(self.entTypeCombo)    return val if val else ''    @property  def isSegAsPID(self)->bool:    return guitk.BCCheckBoxIsChecked(self.propSegCheckBox)    def entTypeComboChangedFunc(self, combo, index, data)->None:    if index==0:      guitk.BCShow(self.propSegCheckBox)    else:      guitk.BCCheckBoxSetChecked(self.propSegCheckBox, False)      guitk.BCHide(self.propSegCheckBox)    return None    def collectEntities(self)->Union[List[base.Entity], None]:    stype:str = self.curSelectType    if stype not in self.selectTypes:      print('当前选择类型设置有误,请重新设置!')      return None        entTypes:Tuple[str] = ('ANSAPART', ) if self.curEntType==self.entTypes[0] else ('PSHELL', 'PSOLID')    if stype==self.selectTypes[0]:      entities:List[base.Entity] = base.CollectEntities(DECK, None, entTypes, filter_visible=True)    elif stype==self.selectTypes[1]:      entities:List[base.Entity] = base.CollectEntities(DECK, None, entTypes, filter_visible=False)    else:      entities:Union[List[base.Entity], None] = base.PickEntities(DECK, entTypes)    return entities    @staticmethod  def segregateAsFace(props:List[base.Entity])->List[base.Entity]:    elemInFaces:List[base.Entity] = list()    for prop in props:      faces:List[base.Entity] = base.CollectEntities(DECK, prop, 'FACE', recursive=True)      if not faces:continue      while faces:        newFaces:List[base.Entity] = base.GatherFaces(faces[0], 40.0, visibility='visible', container='PID_region')        newProp:base.Entity = base.CopyEntity(None, prop)        _ = [newFace.set_entity_values(DECK, {'PID': newProp._id}) for newFace in newFaces]        faces = list(set(faces)-set(newFaces))      elemInFaces.extend(base.CollectEntities(DECK, faces, ('SHELL', 'SOLID'), recursive=True))    return elemInFaces    @staticmethod  def segregateAsElem(props:List[base.Entity], outsideElems:List[base.Entity]=None)->None:    if outsideElems is None: outsideElems = []    for prop in props:      elems:List[base.Entity] = base.CollectEntities(DECK, prop, ('SHELL', 'SOLID'), recursive=True)      elems = list(set(elems)-set(outsideElems))      while elems:        elem = elems[0]        newElems:List[base.Entity] = base.GatherElements(DECK, type='Same', search_mode='Connectivity', gather_from='Visible', gather_from_containers=elem, source=elem)        if not newElems: newElems = [elem]        else: newElems = newElems[elem]                newProp:base.Entity = base.CopyEntity(None, prop)        _ = [newElem.set_entity_values(DECK, {'PID': newProp._id}) for newElem in newElems]        elems = list(set(elems)-set(newElems))    return None    @class method  def segregateAsPID(cls, props:List[base.Entity])->None:    elemInFaces:List[base.Entity] = cls.segregateAsFace(props)    return cls.segregateAsElem(props, elemInFaces)    @class method  def segregateAsPart(cls, parts:List[base.Entity])->None:    for part in parts:      PIDNumber:int = part.get_entity_values(DECK, ('PIDs Number', ))['PIDs Number']      if PIDNumber==0:        base.DeleteEntity(part)        continue      elif PIDNumber==1:        continue          props:List[base.Entity] = base.CollectEntities(DECK, part, '__PROPERTIES__', recursive=True)      if not props:continue      newParts:List[base.Entity] = list()      for prop in props[1:]:        count:int = 1        newPart:base.Entity = base.NewPart(f'{part._name}_I0001')        while not newPart:          count += 1          newPart = base.NewPart(f'{part._name}_I{count:0>4d}')        newParts.append(newPart)        entities:List[base.Entity] = base.CollectEntities(DECK, prop, ('FACE', 'SHELL', 'SOLID'), recursive=True)        base.SetEntityPart(entities, newPart)      base.ConnectPartInstances(part, newParts)            ret = base.GetPartDepth(part)      parent:base.Entity = None if not ret else ret['parent_part']      if parent: base.SetEntityPart(newParts, parent)    return None      def okFunc(self, window, data):    entities:Union[List[base.Entity], None] = self.collectEntities()    if not entities: return None        if self.curEntType==self.entTypes[0]:      if self.isSegAsPID:        props:List[base.Entity] = base.CollectEntities(DECK, entities, ('PSHELL', 'PSOLID'), recursive=True)        self.segregateAsPID(props)      self.segregateAsPart(entities)      base.Compress({'Groups/Parts':1, 'PSHELL': 1, 'PSOLID': 1}, DECK)    else:      self.segregateAsPID(entities)      base.Compress({'PSHELL': 1, 'PSOLID': 1}, DECK)        self.rejectFunc(window, data)    return None    def rejectFunc(self, window, data):    guitk.BCDestroy(self.mainWindow)    return 0
该脚本创建了一个功能界面用于对拆分功能进行设置。
选择方式有三种方式:visible, all,selected。visible可直接对可见的部件进行拆分;all可直接对整个模型进行拆分;selected模式需要人为介入进行手动选择;
选择对象类型存在两种:AnsaPart、Property。
AnsaPart对一个part中的property进行拆分,若勾选了“是否按PID拆分”,则先按部件对property进行拆分,然后再进行AnsaPart进行拆分以确保part、property、部件一一对应。
Property 按部件对property进行拆分以确保一个部件对应一个property。
未经作者同意,不得转载该文!!!

来源:檐苔
SystemNastran二次开发ANSAUMSCL
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2026-03-05
最近编辑:7月前
青瓦松
硕士 签名征集中
获赞 46粉丝 13文章 63课程 0
点赞
收藏
作者推荐

机器学习与深度学习引言学习笔记

一. 引言传统编程的局限性传统程序依赖人工设计的业务逻辑,需考虑所有边界情况(如购物车功能)。复杂任务(如天气预测、图像识别)无法通过规则实现,需数据驱动方案。机器学习的定义目标:从经验(数据)中学习,提高任务性能。核心流程:定义模型 → 用数据集调整参数 → 优化目标函数(如损失函数)。日常生活中的应用语音助手(如“Hey Siri”唤醒词识别):音频特征→标签映射。图像分类:模型通过调整参数识别特征(如猫狗分类)。二. 机器学习的关键组件数据特征与标签:样本由特征向量(如像素值)和标签(如类别)组成。数据质量:需避免偏差(如医疗数据缺乏某些人群样本)。数据规模:深度学习高度依赖大数据,但需注意分布偏移(训练与测试数据差异)。模型表示学习:深度学习通过多层非线性转换自动提取特征。模型族:如神经网络,参数调整生成不同行为(如不同唤醒词识别)。目标函数损失函数:量化模型有效性(如平方误差用于回归,交叉熵用于分类)。过拟合:模型在训练集表现好,但测试集性能差(需验证泛化能力)。优化算法梯度下降:通过计算损失梯度调整参数,逐步逼近最优解。训练步骤:随机初始化→数据采样→参数更新→重复优化。三. 机器学习的核心问题类型监督学习回归:预测连续值(如房价、降雨量),使用平方误差损失。分类:预测离散类别(如二分类:垃圾邮件检测;多分类:手写数字识别)。多标签分类:样本同时属于多个类别(如文章标签)。推荐系统:个性化推荐(如亚马逊商品推荐),可能受反馈循环影响。序列学习:处理可变长度输入/输出(如语音识别、机器翻译)。无监督学习聚类:无标签数据分组(如客户行为分析)。主成分分析(PCA):降维提取关键特征。生成对抗网络(GANs):合成数据(如生成逼真图像)。强化学习定义:智能体与环境交互,通过奖励调整策略(如AlphaGo)。关键挑战:信用分配(确定哪些动作影响奖励)、部分可观测性(如自动驾驶感知)。应用场景:游戏AI、机器人控制。四. 机器学习的起源与发展早期理论基础统计与优化:高斯分布、费舍尔的线性判别分析。信息论:香农的信息度量,图灵的“机器思考”问题。神经网络的发展早期模型:赫布学习(神经元强化机制)、感知机。深度学习复兴:大数据(如ImageNet)与GPU算力推动。深度学习的突破关键技术:Dropout正则化、注意力机制、端到端训练。框架演进:TensorFlow、PyTorch等简化模型开发。五. 深度学习的成功案例语音与视觉语音识别:错误率接近人类(如Siri、Alexa)。图像分类:ImageNet竞赛Top-5错误率从28%降至2.25%。游戏与决策AlphaGo:结合深度网络与蒙特卡洛树搜索击败人类冠军。自动驾驶:通过感知与推理实现部分自主(如特斯拉)。生成模型GANs应用:生成逼真图像(如人脸合成)、风格迁移。六. 深度学习的特点与挑战核心特点端到端学习:替代人工特征工程(如传统Canny边缘检测→自动学习滤波器)。非参数模型:大数据驱动灵活建模(如深度网络)。挑战与伦理数据偏见:模型可能继承历史偏见(如招聘算法偏好特定群体)。隐私与安全:大规模数据采集的隐私风险。自动化风险:职业替代(如司机、客服)。来源:檐苔

未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习计划 福利任务
下载APP
联系我们
帮助与反馈