10分钟入门 ANSA API


  扫描下方二维码关注我的微信公众号 – CAE软件二次开发Lab阅读全文!


10分钟入门 ANSA API

这是 ANSA API 的简短介绍,主要面向新用户。如果您想深入了解所有详细信息,可以阅读完整的 ANSA API 文档。

Script Editor (脚本编辑器)

无论您是经验丰富的开发人员还是编程领域的初学者,脚本编辑器(Script Editor)都将是您的好朋友,至少对于初次尝试使用 ANSA API的你来说。虽然它主要设计用来为简单 python 脚本提供开发环境,但脚本编辑器(Script Editor)是一个集成了ANSA 核心功能( ANSA core functionality)的完整的编辑环境,同时提供非常有用的搜索和文档帮助功能。要从 ANSA 中访问脚本编辑器,请从菜单按钮Tools –> Script –> Script Editor进入。打开脚本编辑器窗口后,您可以使用File菜单中相应的选项开始编辑新文件或打开已存在的文件。

在脚本编辑器中的新文件如下所示:

Script Editor窗口的主要部分是编辑器,其中特别对 python 和 ANSA API 关键字高亮显示,而右侧是搜索工具栏。通过双击列表中选定的函数,相应的帮助文本将显示在屏幕底部的Help窗口中,或者通过右键单击该函数则自动将其写入当前文件中光标所在位置。当您按下运行(Run)按钮时,将执行代码,所有相关消息将显示在Output(输出)窗口中。

Modules(模块)

ANSA API 由一系列直接与 ANSA 交互的函数和类组成。它们分为不同的模块,各模块将每个组件中包含的不同功能分开。在使用其函数和类之前,需要导入每个模块。

ANSA 的基本模块是base module,它包含负责对topodeckvisibilityelement数据操作的所有函数和类。在使用base module时,一般需要导入constants module,因为它包含所有 ANSA 常量和保留方法的集合,例如所有可用deck的deck常量。

保留的deck常量如下:

    NASTRAN, LSDYNA, PAMCRASH, ABAQUS, RADIOSS, ANSYS, FLUENT,
    FLUENT2D, STAR, UH3D, CFDPP, OPENFOAM, PERMAS, MOLDEX3D,
    RADTHERM, SESTRA, THESEUS

访问deck常量也很简单,如下例所示:

from ansa import constants

constants.NASTRAN
constants.ABAQUS

在ANSA中访问数据

ANSA实体

ANSA数据库的每个实体,无论是节点(Node)、单元(Element)、属性(Property),甚至连接(Connection,实际上都是类base.Entity的对象。这意味着所有这些对象共享相同的状态和行为,从base.Entit定义它们所属的实体类。此类对象可以通过脚本直接创建,或者可以使用相应的函数检索现有的对象。

其中一些常用的只读属性如下:

_id
   返回 ANSA 实体 ID。
_name
   返回 ANSA 实体名称。
_comment
    返回 ANSA 实体注释。

以及一些可以修改的属性:

position
    直接获取并设置类点实体(point-like Entities)的全局x、y、z坐标。

例如,获取节点的 ID 和名称就这么简单:

name = node,_name
nid = node._id

为了改变节点的位置,我们可以直接为其分配一个包含 3 个值的元组(tuple):

print(node.position) # 打印坐标当前坐标位置
node.position = (6,7,4) # 设置节点新坐标为 x=6, y=7, z=4

它们共用如下所示的一些常用方法:

Entity(deck, id, type, facet, edge_index)
    实体对象构造函数;返回创建的实体对象。
ansa_type(deck)
    返回指定卡片组中实体的 ANSA 类型。
card_fields(deck)
    返回包含所有活动卡片字段(card fields)名称的列表。
get_entity_values(deck, fields)
   使用编辑卡的字段名称从实体获取值。此方法直接返回引用实体对象字段的实体对象。字段参数是包含从中提取值的卡片字段标签名称的列表。
set_entity_values(deck, fields)
    使用实体的编辑卡字段设置或更改实体的值。成功时返回零,错误时返回非零。字段参数是一个字典,其键值为带ANSA card标签的名称,并值为卡片字段的值。通过使用此方法,可以将实体对象设置为相应字段的值。

上述所述对实体编辑卡及其卡片字段标签的某些功能,我们将在以下内容中
对其进行讲解。

ANSA实体编辑卡片

ANSA 中的大多数实体都有一张卡片,其中包含有关它们的所有必要信息。每个实体的类型非常重要,因为为了访问卡片及其内容,必须使用关键字。实体的类型显示在卡片的窗口标题上的括括号之中。例如,NASTRAN 'shell'具有类型为 SHELL的卡片,这是处理此类实体时必须使用的关键字,而另一方面,LS-DYNA 'shell'具有类型为 ELEMENT_SHELL的卡片。卡片字段的标签也很重要,因为它们必须用于获取或更改其值。

在shell单元上使用前面介绍的base.Entity类的方法的简单实例如下:

# 在NASTRAN模板下获取单元类型。
ansa_type = elem.ansa_type(constants.NASTRAN)
print('The type of the element:', ansa_type)

# 返回包含编辑卡的所有活动字段的列表。
card_fields = elem.card_fields(constants.NASTRAN)
print('All the active card fields:', card_fields)

# 在字典中检索元素的类型、PID和网格节点。
elem_fields = elem.get_entity_values(constants.NASTRAN, ('type', 'PID', 'G1', 'G2', 'G3', 'G4'))
print('The returned dictionary:', elem_fields)

# 设置一个新的PID
elem.set_entity_values(constants.NASTRAN, {'PID': 300})

检索实体(Retrieving Entities)

有很多方法可以从 ANSA 数据库中检索实体,其中最常见的是用于大量实体集合(massive collection)的base.CollectEntitiesbase.NametoEnts,而base.GetEntity是用对象的ID来检索单个实体。

大量实体集合(Massive collection of Entities)

base.CollectEntities()函数的一个优点是它可用于查找其他容器实体(container-entities)使用的实体,同时它是可以获取可见实体(visible entities)的唯一函数。其语法非常灵活,可以接受列表/元组或单个单元,同时也可以指定可变数量的输入参数。其所需必须的参数是deck、函数将搜索的容器和要获取的搜索类型。

我们可通过如下示例来了解此函数的功能。

import ansa
from ansa import base
from ansa import constants

def main():
    # 定义要在元组中收集的实体的关键字。
    # 这些关键字取自卡片的标题。
    search_types = ('PSHELL', 'PSOLID')
    ents = base.CollectEntities(constants.NASTRAN, None, search_types)
    print('Number of entities collected:', len(ents))

在此方法中,由于搜索类型是多个,因此它们作为元组传递给函数。函数的第二个参数(指示要搜索的容器)设置为“无(None)”,以便函数从整个数据库中收集实体。函数的输出是一个列表,其中包含数据库的 PSHEL和PSOLID 的对象。

如果要收集数据库的所有属性或所有材料,应使用指示实体类别的字符串:

def main():
    all_props = base.CollectEntities(constants.NASTRAN, None, '__PROPERTIES__')
    print('Number of properties collected:', len(all_props))

    all_mats = base.CollectEntities(constants.NASTRAN, None, '__MATERIALS__')
    print('Number of materials collected:', len(all_mats))

现在假设您只想获取 SHELLs所使用的GRIDs。在这种情况下,您不想搜索整个数据库上的GRIDs,而只在现有的SHELLs上搜索GRIDs。为了做到这一点,首先您需要收集所有 SHELLs,然后收集所有GRIDs,并将将收集的shell作为container参数。请记住,容器可以是列表,也可以是单个对象。

def main():
    # 首先,在整个数据库中收集shells
    shells = base.CollectEntities(constants.NASTRAN, None, "SHELL")
    print('Number of shells:', len(shells))

    # 然后,收集这些shells的grids
    grids = base.CollectEntities(constants.NASTRAN, shells, "GRID")
    print('Number of grids used from shells:', len(grids))

定义实体类型的第三个参数也可以设置为False。这可用于收集包含在上级实体中的所有实体。这在SETsPARTs、 或 Connections中是有意义的。在下面的示例中,我们收集Sets中的所有实体。

def main():
    # 收集数据库中的sets
    sets = base.CollectEntities(constants.NASTRAN, None, "SET")
    print('Number of sets:', len(sets))

    # 收集sets中所含的所有对象
    ents = base.CollectEntities(constants.NASTRAN, sets, False)
    print('Number of entities in sets:', len(ents))

函数base.CollectEntities()的另一个功能是获取可见实体( visible entities)。通过将“filter_visible”参数设置为True,可以实现获取可见实体,如下示例所示:

def main():
    shells = base.CollectEntities(constants.NASTRAN, None, 'SHELL', filter_visible=True)
    print('Number of visible shells:', len(shells))

作为一个更完整的示例,假设我们想要创建一个函数,该函数查找坐标小于给定值的所有节点,并将其重命名为:NODE WITH ID: <id> AND XCOORD: <xcoord>。为了做到这一点,我们需要使用函数base.CollectEntities()Entity.set_entity_values()

from ansa import base
from ansa import constants

def rename_nodes(val):
    # 收集所有节点
    nodes = base.CollectEntities(constants.NASTRAN, None, 'GRID')

    nodes_list = []
    for node in nodes:
        if node.position[0] < val:
            nodes_list.append(node)
            name = 'NODE WITH ID: %d AND XCOORD: %.5f' % (node._id, node.position[0])
            node.set_entity_values(constants.NASTRAN, {'Name': name})

    print('Number of nodes with x coordinate less than %d: %s' % (val, len(nodes_list)))
    return nodes_list

根据实体的名称收集实体

除了ID之外,名称还可用作搜索关键字来获取任意类型的实体。其所使用的函数是base.NameToEnts,它采用一个包含搜索模式的参数,也接受Perl正则表达式(Perl regular expressions),以及两个包含多面板和搜索模式的可选参数。它返回一个列表,其中包含对名称匹配成功的所有实体的引用。此函数主要与Entity.ansa_type组合使用,以便区分实体的类型。在下面的示例中,假设必须搜索整个数据库,以便收集和存储名称以“Default”开头的任何PSHELLs和PSHELLs。

def main():
    # 收集满足搜索模式的实体
    ents = base.NameToEnts("^Default.*")
    if not ents:
        print('No entities were found.')
        return

    pshells = []
    psolids = []

    for ent in ents:
        # 识别实体类型
        if ent.ansa_type(constants.NASTRAN) == "PSHELL":
            pshells.append(ent)
        if ent.ansa_type(constants.NASTRAN) == "PSOLID":
            psolids.append(ent)

    print('The collected PSHELLS:', pshells)
    print('The collected PSOLIDS:', psolids)

获取单个实体

为了获得实体的单个对象,需要使用base.GetEntity函数。需要实体的类型和ID,以便获取对实体对象的引用。

def GetSingleEntity():
    node = base.GetEntity(constants.NASTRAN, 'GRID', 100)
    print('The retrieved node:', node._id)

在上面的示例中,将返回 ID为100的GRID对象。

在该函数用于获取属性、材料或模型浏览器容器( model browser containers)时,其不一定需要类型参数。在这种情况下,可以使用关键字"__MATERIALS__"、"__PROPERTIES__"、"__MBCONTAINERS__",而不是实体类型。

def main():
    prop = base.GetEntity(constants.NASTRAN, '__PROPERTIES__', 10)
    mat = base.GetEntity(constants.NASTRAN, '__MATERIALS__', 10)
    mb = base.GetEntity(constants.NASTRAN, '__MBCONTAINERS__', 10)

注意:
base.GetEntity()函数不能通过模块ID( Module Id)从部件管理器(PART MANAGER)那里收集 ANSAPARTSANSAGROUP。而是使用base.GetPartFromModuleId函数。

创建实体

除了检索现有实体外,ANSA API还可用于创建新实体,如节点、属性、材料等。可用于此目的的函数base.CreateEntity。为了获得对新创建的实体的引用,必须声明实体类型关键字和包含标签-值(labels – values)对的字典。

def CreateGrid():
    fields = {'X1': 3.5, 'X2': 10.8, 'X3': 246.7}
    new_grid = base.CreateEntity(constants.NASTRAN, 'GRID', fields)
    print('The id of the new grid:', new_grid._id)

在创建实体期间,ANSA会自动填充其定义所需的所有字段,但除过用户未指定的所有字段(例如,ID)。

注意
并非所有ANSA实体都可以使用base.CreateEntity()函数创建。其中一些功能要求使用特定函数,如 base.NewPart、base.NewGroup等。

在容器中组织数据

创建或收集ANSA实体/数据(ANSA entities/data)后,通常需要在容器(如,集合(Set)、部件(Part)、组(Group)或包含(Include))中组织它们,以便轻松检索它们或大规模地应用它们的操作。

以下是在相当简单的场景中使用上述容器的一些示例。

模型浏览器 – 零件、组 (Model Browser – Parts, Groups)

模型浏览器是一个GUI窗口,用户可以在其中查看所有现有的组和部件,其中包含所有实体。为了创建新组或新零件必须使用base.NewGroupbase.NewPart函数。此外,为了在零件中添加数据,以及添加组中的零件,必须使用base.SetEntityPart函数。

假设我们要创建一个名为“foo”的组,其中包含名为“bar”的部分,并添加用户能够从ANSA接口选取的任何数量的单元。下面的示例演示如何实现此目的:

import ansa
from ansa import base

def main():
    # 让用户从界面中拾取(pick)单元
    elems = base.PickEntities(0, '__ELEMENTS__')
    print('Number of elements picked:', elems)

    # 创建组和部件
    group = base.NewGroup('foo')
    part = base.NewPart('bar')

    # 在group中添加部件
    base.SetEntityPart(part, group)

    # 在部件中添加单元
    base.SetEntityPart(elems, part)

包管理器(Includes Manager)

“包管理器(Includes Manager)”处理数据库的所有“包含”实体(Includes Manager),类似于模型浏览器和零件。可以使用函数基创建”包括”。可以使用函数base.CreateEntity创建,并用base.AddToInclude.添加实体到任何包含(include)中。

例如,我们可以创建一个“包含”并在其中添加一些单元:

import ansa
from ansa import base

def main():
    elems = base.PickEntities(0, '__ELEMENTS__')
    print('Number of elements picked:', elems)

    # 创建一个“包含”
    include = base.CreateEntity(0, 'INCLUDE')
    print('The created Include:', include._id)

    # 在inclue中添加单元
    base.AddToInclude(include, elems)

集合(Sets)

集合是一个实体,它可以容纳任何类型的ANSA实体,以便组织这些数据或大规模地对它们应用操作。使用base.CreateEntity创建一个集合,并并base.AddToSet在其中添加实体。

将属性添加到新创建的集合中的一个简单示例如下所示:

import ansa
from ansa import base
from ansa import constants

def main():
    # 检索属性
    prop = base.GetEntity(constants.NASTRAN, '__PROPERTIES__', 600)

    # 创建集合
    my_set = base.CreateEntity(constants.NASTRAN, 'SET', {'Name': 'SetWithProp'})
    print('The created Set:', my_set._id)

    # 将集合添加到集合中
    base.AddToSet(my_set, prop)

注意:
如果尝试创建与现有集合同名的集合,则函数base.CreateEntity()将返回None。这是因为ANSA中的集合其用唯一名称标识而不是 ID,就像许多其他ANSA实体一样。为了确保始终创建集合成功,可以用以下函数实现,该函数在集合名称的末尾追加一个数字:

import ansa
from ansa import base
from ansa import constants

def create_set(name):
    my_set = base.CreateEntity(constants.NASTRAN, 'SET', {'Name': name})

    n = 1
    while not my_set:
        my_set = base.CreateEntity(constants.NASTRAN, 'SET', {'Name': name + str(n)})
        n += 1

    return my_set

在本教程结尾,让我们看一个示例,该示例结合了上述所介绍的一些API函数。

首先,假设我们要查找x坐标小于1600的所有节点,并如上例所示相应地重命名它们。然后,我们希望将所有这些已标识的节点添加到名为“MyTempSet”的集合中,但还要确保始终创建此集集合(避免命名冲突)。

import ansa
from ansa import base
from ansa import constants

def _create_set(name):
    my_set = base.CreateEntity(constants.NASTRAN, 'SET', {'Name': name})

    n = 1
    while not my_set:
        my_set = base.CreateEntity(constants.NASTRAN, 'SET', {'Name': name + str(n)})
        n += 1

    return my_set

def _rename_nodes():
    nodes = base.CollectEntities(constants.NASTRAN, None, 'GRID')
    nodes_list = []
    for node in nodes:
        if node.position[0] < val:
            nodes_list.append(node)
            name = 'NODE WITH ID: %d AND XCOORD: %.5f' % (node._id, node.position[0])
            node.set_entity_values(constants.NASTRAN, {'Name': name})

    return nodes_list

def main():
    nodes = _rename_nodes(1600)
    my_set = _create_set('MyTempSet')
    base.AddToSet(my_set, nodes)

请注意,我们提供一个包含所有节点的列表,其用到base.AddToSet()函数。将所有实体对象收集到列表中并仅调用base.AddToSet()函数一次,相比与对每个实体对象多次调用该函数相比要快得多。

通常,接受单个实体或实体列表的函数在提供实体对象列表时运行得更快,并且只调用一次。您可以阅读ANSA帮助文档中代码优化章节获得更多的优化代码建议。

注意:
这只是对ANSA API的简短介绍,您可以阅读完整的ANSA API帮助文档来获得各模块的详细使用说明。


  扫描下方二维码关注我的微信公众号 – CAE软件二次开发Lab,查看更多精彩文章!


本文链接:10分钟入门 ANSA API

转载声明:本站文章若无特别说明,皆为原创,转载请注明来源:CAECoder,谢谢!^^


发表评论