2. Python语言核心速成

Abaqus的Python脚本并不是“另一门语言”,它运行在CPython解释器上,只是额外挂载了abaqus、abaqusConstants、odbAccess等模块。因此,写脚本时真正需要掌握的是Python的最小知识集:用什么容器装数据、用什么语句控制流程、用什么函数封装重复逻辑、怎么导入Abaqus模块、出错时怎么让脚本可控地停下来。本节围绕这五件事展开,并给出可直接在Abaqus/CAE的File→Run Script中试跑的最小示例。

一、数据类型:脚本里到底在装什么

Abaqus脚本中最高频的容器是元组(tuple)、列表(list)和字典(dict)。元组用圆括号,创建后不可改,适合表示坐标、集合名、固定参数组,例如point = (0.0, 0.0, 0.0);列表用方括号,可增删改,适合批量管理几何边、单元集合、载荷步,例如edges = e.getEdges()返回的就是一个边对象序列;字典用花括号,以键值对存储,Abaqus的很多API返回值就是字典,例如odb.steps['Step-1'].frames[-1].fieldOutputs['S']这类访问链中,steps和fieldOutputs都表现为可按名字索引的映射结构。

数值类型方面,Abaqus API大量使用float表示长度、模量、时间;int表示编号、增量步;bool表示开关,如True/False。需要特别注意的是,Abaqus的很多布尔参数要求传入ON或OFF常量(来自abaqusConstants),而不是Python的True/False,例如mdb.models['Model-1'].ConstrainedSketch(name='__profile__', sheetSize=200.0)中的sheetSize是浮点数,而Part(...)的dimensionality则要用THREE_D这类常量。写脚本时若把常量写成字符串'THREE_D',Abaqus通常会报类型错误,这是新手最常见的坑之一。

字符串用于命名,如部件名、集合名、步骤名。Abaqus对象名区分大小写,且不能包含空格和特殊字符,脚本中建议用f'Set-{i}'这类格式化字符串批量生成集合名,既简洁又不易冲突。

二、流程控制:让脚本按条件与循环工作

条件判断用if/elif/else。在Abaqus脚本中,它常用于根据几何类型或分析结果分支处理,例如判断某条边是直线还是圆弧,再决定是否加密种子。循环用for和while。for最常用于遍历Abaqus返回的对象序列,例如遍历所有单元、所有节点、所有分析步;while则适合“满足条件就继续”的场景,比如反复调整网格尺寸直到单元数量落入目标区间。

下面这段示例演示了“按目标单元数自动调整全局种子”的循环逻辑,参数为教学假设值,实际运行需根据模型尺寸调整:

from abaqus import *
from abaqusConstants import *
import mesh

target = 8000          # 目标单元数(示例值)
size = 5.0             # 初始种子尺寸(示例值)
p = mdb.models['Model-1'].parts['Part-1']

for i in range(20):
    p.seedPart(size=size, deviationFactor=0.1, minSizeFactor=0.1)
    p.generateMesh()
    n = len(p.elements)
    if abs(n - target) / float(target) < 0.05:
        break
    size = size * (float(n) / target) ** 0.5

print('final seed = %.3f, elements = %d' % (size, n))

这段代码体现了三个关键点:range(20)限制最大迭代次数,防止死循环;break在达到5%误差时提前退出;种子尺寸按单元数比例的平方根修正,是因为二维网格单元数大致与种子尺寸的平方成反比。运行后可在CAE的Mesh模块中查看网格,并核对消息区打印的单元数。

三、函数:把重复操作封装成可复用单元

函数用def定义。Abaqus脚本中,函数最常见的用途是封装“建一个部件”“加一个分析步”“提取一条曲线”这类重复动作。函数参数建议给出默认值,便于在不同模型中复用。例如:

def create_block(name, length, height, depth):
    s = mdb.models['Model-1'].ConstrainedSketch(name=name+'-sk', sheetSize=200.0)
    s.rectangle(point1=(0.0, 0.0), point2=(length, height))
    p = mdb.models['Model-1'].Part(name=name, dimensionality=THREE_D,
                                   type=DEFORMABLE_BODY)
    p.BaseSolidExtrude(sketch=s, depth=depth)
    return p

调用create_block('Block-A', 100.0, 50.0, 20.0)即可生成一个长方体部件。函数返回值让后续脚本能继续对该部件操作,这是脚本模块化的基础。

四、模块导入:Abaqus脚本的入口

Abaqus脚本开头通常需要导入以下模块:from abaqus import *提供mdb、session等核心对象;from abaqusConstants import *提供THREE_D、ON、OFF等常量;import mesh、import part、import step等提供各模块的辅助函数;后处理时用from odbAccess import *打开ODB。若脚本在CAE外以abaqus python运行,还需import sys处理路径。导入顺序建议先Abaqus核心,再标准库,最后自定义模块,便于排查。

五、异常处理:让脚本出错时可控

Abaqus API在参数非法、对象不存在、几何操作失败时会抛出异常。用try/except可以捕获并给出可读提示,而不是让整个脚本崩溃。例如批量创建集合时,某个集合名可能已存在:

try:
    p.Set(name='Set-1', edges=p.edges[0:4])
except Exception as e:
    print('create Set-1 failed: %s' % e)

更稳妥的做法是先用if 'Set-1' in p.sets:判断,再决定是否创建。异常处理不是掩盖错误,而是让脚本在批量任务中“跳过失败项、继续处理剩余项”,这对处理几十个部件的自动化脚本尤其重要。

Abaqus脚本最小知识集:数据 → 控制 → 封装 → 导入 → 容错 数据类型 tuple 坐标/固定组 list 边/集合/步 dict 按名索引 常量 THREE_D / ON 流程控制 if / elif / else for 遍历对象序列 while 迭代调参 break 防死循环 函数封装 def 定义可复用块 默认参数便于复用 return 返回部件对象 封装建部件/加步 模块导入 from abaqus import * abaqusConstants 常量 mesh / part / step odbAccess 后处理 异常 try except 跳过失败项 继续批量 打印原因 示例:按目标单元数自动调整全局种子(教学假设值) 输入 target=8000, size=5.0 循环处理 seedPart → generateMesh 判断 |n-target|/target < 5% 修正 size *= (n/target)^0.5 输出 seed/elem 未达标则继续迭代,最多20次;达标或超限后打印最终种子与单元数

六、把五件事串起来:一个可运行的最小脚本骨架

综合以上内容,一个面向Abaqus的脚本骨架可以写成:先导入模块,再用函数封装建模动作,用循环批量创建对象,用条件判断控制流程,用异常处理保证批量任务不中断。下面给出一个“批量创建三个长方体部件并统计单元数”的示例,参数为教学假设值:

from abaqus import *
from abaqusConstants import *

def create_block(name, L, H, D):
    s = mdb.models['Model-1'].ConstrainedSketch(name=name+'-sk', sheetSize=200.0)
    s.rectangle(point1=(0.0, 0.0), point2=(L, H))
    p = mdb.models['Model-1'].Part(name=name, dimensionality=THREE_D,
                                   type=DEFORMABLE_BODY)
    p.BaseSolidExtrude(sketch=s, depth=D)
    return p

sizes = [(80.0, 40.0, 10.0), (100.0, 50.0, 12.0), (120.0, 60.0, 15.0)]
for i, (L, H, D) in enumerate(sizes, start=1):
    try:
        p = create_block('Block-%d' % i, L, H, D)
        p.seedPart(size=5.0, deviationFactor=0.1, minSizeFactor=0.1)
        p.generateMesh()
        print('Block-%d: elements = %d' % (i, len(p.elements)))
    except Exception as e:
        print('Block-%d failed: %s' % (i, e))

运行后,模型树中会出现Block-1、Block-2、Block-3三个部件,消息区打印每个部件的单元数。若某个部件因尺寸或草图问题失败,脚本会打印原因并继续处理下一个,而不是整体中断。这就是“最小知识集”在Abaqus脚本中的实际价值:数据类型决定你能装什么,流程控制决定你能批量做什么,函数决定你能复用多少,模块导入决定你能调用哪些Abaqus能力,异常处理决定脚本在真实工程中是否可靠。

建议在CAE中先用File→Run Script运行上述骨架,观察模型树和消息区输出;确认无误后,再把sizes替换为实际尺寸列表,把seedPart参数替换为你的网格控制参数。所有示例数值均为教学假设值,实际使用需按模型单位制与精度要求调整。