教程

备注

abqpy 基于 Python 3 进行开发,但 Abaqus 的 Python 解释器是 Python 2,所以你必须编写 Python 2 和 Python 3 相互兼容的代码。

欲了解更多示例,请查看 Examples 。

通常,在 Abaqus,我们有几件事要做:

  • 构建模型

  • 提交和监视任务

  • 获取输出数据并可视化

建立 Abaqus 模型

建立 Abaqus 模型的最方便的方法是在 Abaqus CAE 中进行。 当我们使用 Abaqus/CAE 图形用户界面 (GUI) 创建模型并可视化结果时, 每次操作后由 Abaqus/CAE 内部发布命令。 这些命令反映了您创建的几何形状以及您从每个对话框中选择的选项和设置。

因此,我们可以使用 Python 脚本构建我们的 Abaqus 模型。 我们可以完全使用 Python 脚本构建我们的 Abak 模型,尽管它不是一个有效的方法。 通常,我们在 Abaqus/CAE 中做一些事情,并在 reply (.rpy) 文件中检查 Python 脚本。然后将其复制到我们的脚本文件,这样做没有任何问题,但并不是很方便。

但是,如果在 Abaqus 的 Python 脚本中提供类型提示,事情就会变得更容易了,这就是 abqpy 所做的事情。

下面描述的示例很简单,有一个正方形结构,底部的垂直位移是固定的, 表面有垂直压力,Abaqus 模型如下所示:

_images/model.png

脚本的导入部分

通常,当我们使用 Python 脚本构建模型时,我们需要导入以下模块:

from abaqus import *
from abaqusConstants import *
from driverUtils import *

模块 abaqus 包含两个最重要的变量 mdb 和 session 用于控制模型。 模块 abaqusConstants 包含用于建模的常量字符串,例如,当我们使用以下代码定义部件时:

mdb.models['Model-1'].Part(name='part', dimensionality=THREE_D, type=DEFORMABLE_BODY)

THREE_D 表示该部件是三维的,DEFORMABLE_BODY 表示该部件是可变形的。

模块 driverUtils 包含一个重要函数 executeOnCaeStartup , 当我们打开 Abaqus 时都会执行此功能,所以我们需要在我们的 Python 脚本中调用此函数。 现在,我们的 Python 脚本就像:

from abaqus import *
from abaqusConstants import *
from driverUtils import *

executeOnCaeStartup()

创建部件

首先,我们需要创建一个用于创建部件的草图,我们需要使用 ConstrainedSketch() 来创建草图:

model = mdb.models['Model-1']
sketch = model.ConstrainedSketch(name='sketch', sheetSize=1.0)
sketch.rectangle((0, 0), (1, 1))

在该代码中,我们绘制了一个正方形。现在我们可以使用这个草图创建一个部件:

part = model.Part(name='part', dimensionality=THREE_D, type=DEFORMABLE_BODY)
part.BaseSolidExtrude(sketch=sketch, depth=1)

第一行代码创建了一个三维可变形的部件。然后我们使用 BaseSolidExtrude() 方法并利用草图赋予部件几何特征。

为边界条件和荷载创建一些集合

与在 Abaqus/CAE 中构建模型不同的是,在 Abaqus/CAE 中我们可以点击节点 / 面来创建集合, 当我们使用 Python 脚本来构建模型时,我们需要使用坐标来找到我们需要的节点 / 面。

我们可以使用 Set() 和 Surface() 来创建集合和表面:

part.Set(name='set-all', cells=part.cells.findAt(coordinates=((0.5, 0.5, 0.5), )))
part.Set(name='set-bottom', faces=part.faces.findAt(coordinates=((0.5, 0.5, 0.0), )))
part.Set(name='set-top', faces=part.faces.findAt(coordinates=((0.5, 0.5, 1.0), )))
part.Surface(name='surface-top',
             side1Faces=part.faces.findAt(coordinates=((0.5, 0.5, 1.0), )))

将部件合并到装配集

我们可以使用 Instance() 方法创建装配实例:

model.rootAssembly.Instance(name='instance', part=part, dependent=ON)

创建材料和截面,并将材料分配给部件

首先,我们使用 Material() 方法创建一个材料对象:

material = model.Material(name='material')

然后我们给材料分配一些属性,例如 Elastic() 和 Density():

material.Elastic(table=((1000, 0.2), ))
material.Density(table=((2500, ), ))

然后我们创建一个 AlimenousSolidSection() 截面并将该截面分配给部件 (SectionAssignment()):

model.HomogeneousSolidSection(name='section', material='material', thickness=None)
part.SectionAssignment(region=part.sets['set-all'], sectionName='section')

创建分析步

可以使用 StaticStep() 创建一个简单的静力分析步:

step = model.StaticStep(name='Step-1', previous='Initial', description='',
                        timePeriod=1.0, timeIncrementationMethod=AUTOMATIC,
                        maxNumInc=100, initialInc=0.01, minInc=0.001, maxInc=0.1)

指定输出变量

我们可以使用 FieldOutputRequest() 和 HistoryOutPutRequest() 来指定场变量输出和历史变量输出信息。

field = model.FieldOutputRequest('F-Output-1', createStepName='Step-1',
                                 variables=('S', 'E', 'U'))

创建边界条件

我们可以使用 DisplacementBC() 来创建一个位移边界条件:

bottom_instance = model.rootAssembly.instances['instance'].sets['set-bottom']
bc = model.DisplacementBC(name='BC-1', createStepName='Initial',
                          region=bottom_instance, u3=SET)

应当指出,指定边界条件的几何区域需为实例而不是部件的几何区域,由于定义在部件的集合会被自动复制到实例,因此我们可以使用上面我们定义在部件的集合。

创建荷载

我们可以使用 Pressure() 方法来创建压力:

top_instance = model.rootAssembly.instances['instance'].surfaces['surface-top']
pressure = model.Pressure('pressure', createStepName='Step-1', region=top_instance,
                          magnitude=100)

网格

为了给模型划分网格,我们必须指定单元类型 ElemType,可用单元类型在 mesh 模块中定义,因此我们需要导入 mesh 模块:

import mesh

elem1 = mesh.ElemType(elemCode=C3D8R)
elem2 = mesh.ElemType(elemCode=C3D6)
elem3 = mesh.ElemType(elemCode=C3D4)
part.setElementType(regions=(part.cells, ), elemTypes=(elem1, elem2, elem3))
part.seedPart(size=0.1)
part.generateMesh()

创建作业

我们可以使用 Job() 方法来创建作业:

job = mdb.Job(name='Job-1', model='Model-1')

然后我们可以将模型写入一个 inp 文件(.inp):

job.writeInput()

然后我们就可以提交创建好的作业:

job.submit()
job.waitForCompletion()

将 Abaqus 模型保存到 .cae 文件

我们可以使用 SaveAs 方法保存 Abaqus 模型到一个 .cae 文件:

mdb.saveAs('compression.cae')

完整的脚本

此示例的完整脚本如下:

列表 1 compression.py
from abaqus import *
from abaqusConstants import *
from caeModules import *
from driverUtils import *

executeOnCaeStartup()

# Model
model = mdb.models['Model-1']

# Part
sketch = model.ConstrainedSketch(name='sketch', sheetSize=1.0)
sketch.rectangle((0, 0), (1, 1))
part = model.Part(name='part', dimensionality=THREE_D, type=DEFORMABLE_BODY)
part.BaseSolidExtrude(sketch=sketch, depth=1)

# Create sets
part.Set(name='set-all', cells=part.cells.findAt(coordinates=((0.5, 0.5, 0.5), )))
part.Set(name='set-bottom', faces=part.faces.findAt(coordinates=((0.5, 0.5, 0.0), )))
part.Set(name='set-top', faces=part.faces.findAt(coordinates=((0.5, 0.5, 1.0), )))
part.Surface(name='surface-top',
             side1Faces=part.faces.findAt(coordinates=((0.5, 0.5, 1.0), )))

# Assembly
model.rootAssembly.DatumCsysByDefault(CARTESIAN)
model.rootAssembly.Instance(name='instance', part=part, dependent=ON)

# Material
material = model.Material(name='material')
material.Elastic(table=((1000, 0.2), ))
material.Density(table=((2500, ), ))

# Section
model.HomogeneousSolidSection(name='section', material='material', thickness=None)
part.SectionAssignment(region=part.sets['set-all'], sectionName='section')

# Step
step = model.StaticStep(name='Step-1', previous='Initial', description='',
                        timePeriod=1.0, timeIncrementationMethod=AUTOMATIC,
                        maxNumInc=100, initialInc=0.01, minInc=0.001, maxInc=0.1)

# Output request
field = model.FieldOutputRequest('F-Output-1', createStepName='Step-1',
                                 variables=('S', 'E', 'U'))

# Boundary condition
bottom_instance = model.rootAssembly.instances['instance'].sets['set-bottom']
bc = model.DisplacementBC(name='BC-1', createStepName='Initial',
                          region=bottom_instance, u3=SET)

# Load
top_instance = model.rootAssembly.instances['instance'].surfaces['surface-top']
pressure = model.Pressure('pressure', createStepName='Step-1', region=top_instance,
                          magnitude=100)

# Mesh
elem1 = mesh.ElemType(elemCode=C3D8R)
elem2 = mesh.ElemType(elemCode=C3D6)
elem3 = mesh.ElemType(elemCode=C3D4)
part.setElementType(regions=(part.cells, ), elemTypes=(elem1, elem2, elem3))
part.seedPart(size=0.1)
part.generateMesh()

# Job
job = mdb.Job(name='Job-1', model='Model-1')
job.writeInput()

# Submit the job
# job.submit()
# job.waitForCompletion()

# Save abaqus model
mdb.saveAs('compression.cae')

提取输出数据

如果我们想要提取输出数据,我们必须写一个输出脚本。

脚本的导入部分

同样,我们必须导入一些模块:

from abaqus import *
from abaqusConstants import *
from driverUtils import *

executeOnCaeStartup()

打开输出数据库

我们可以使用 openOdb() 方法打开输出数据库:

import visualization
odb = session.openOdb('Job-1.odb')
session.viewports['Viewport: 1'].setValues(displayedObject=odb)

提取输出数据

我们可以使用 xyDataListFromField() 方法提取输出数据:

dataList = session.xyDataListFromField(odb=odb, outputPosition=NODAL,
                                       variable=(('U', NODAL, ((COMPONENT, 'U3'),)),),
                                       nodeSets=('INSTANCE.SET-TOP', ))

dataList 是一个 XYData 对象列表。 XYData 是在 Abaqus 中定义的数据类型。 数据存储在元组中,因此我们可以使用 numpy (numpy 已安装在 Abaqus Python 解释器中)简单地将其保存到一个文件。

import numpy as np

data = np.array(dataList[0])
np.savetxt('data.csv', data, header='time,U3', delimiter=',', comments='')

以上示例的结果

上述模型的 U3 的分布如下:

_images/output.png

上表面某点的竖直位移的分布如图所示:

_images/compression.png

完整输出脚本

此示例的完整脚本如下:

列表 2 compression-output.py
from abaqus import *
from abaqusConstants import *
from driverUtils import *
import visualization
import numpy as np

executeOnCaeStartup()

# Open output database
odb = session.openOdb('Job-1.odb')
session.viewports['Viewport: 1'].setValues(displayedObject=odb)

# Extract output data
dataList = session.xyDataListFromField(odb=odb, outputPosition=NODAL,
                                       variable=(('U', NODAL, ((COMPONENT, 'U3'),)),),
                                       nodeSets=('INSTANCE.SET-TOP', ))
data = np.array(dataList[0])
np.savetxt('data.csv', data, header='time,U3', delimiter=',', comments='')

评论