如果你的工作涉及到"有限元",不妨加个关注,总有对你有用的东西。
点击下面名片快速关注。
很多人在刚开始读 Abaqus 的 .inp 文件时,最容易把注意力放在 *Node、*Element、*Material、*Step 这些关键词上。因为它们看起来最“实在”:节点、单元、材料、载荷、边界条件,都是有限元分析中直接要用的内容。
但如果你打开一个由 Abaqus/CAE 导出的 inp 文件,通常会发现中间有一大段这样的内容:
*Assembly, name=Assembly
...
*End Assembly
这一段就是本文要讲的 Assembly 部分。
简单来说,Assembly 不是单纯的“注释段”或“模型排版段”,而是 Abaqus 用来组织零件、实例、集 合、接触区域和约束关系的核心结构。理解 Assembly,很多 inp 文件里的引用关系、集 合命名、边界条件为什么写成某种格式,就会一下子清楚很多。
在 Abaqus 中,Part 可以理解为“零件定义”。
一个 Part 里面通常会定义:
*Part, name=Part-1
*Node
...
*Element
...
*Elset
...
*Nset
...
*Solid Section
...
*End Part
但是,Part 本身只是一个零件模板。它还没有真正被放到整个有限元模型的全局空间中。
真正进入模型装配关系的是 Instance,也就是零件实例。
Assembly 的核心作用,就是把一个或多个 Part 通过 Instance 的方式放到同一个全局坐标系下,形成完整模型。
一个典型结构如下:
*Part, name=Block
...
*End Part
*Assembly, name=Assembly
*Instance, name=Block-1, part=Block
*End Instance
*End Assembly
这里可以这样理解:
Block 是一个零件定义;Block-1 是 Block 这个零件在模型中的一个实例;Assembly 是装配体,负责管理这个实例在整体模型中的位置和引用关系。如果把 Part 比作“零件图纸”,那么 Instance 就是“把这张图纸做成一个实物并放到总装里”,Assembly 就是“总装环境”。
这是很多初学者第一次读 inp 文件时的困惑。
既然节点、单元都已经在 Part 中定义了,为什么还要再写一遍 Instance?
原因很简单:同一个 Part 可以被实例化多次。
例如,一个螺栓、一个垫片、一个连接块,几何和网格可能完全一样,但在模型中出现的位置不同。如果没有 Instance,每出现一次就要重新写一套节点和单元;有了 Instance,就可以复用 Part。
例如:
*Part, name=Bolt
...
*End Part
*Assembly, name=Assembly
*Instance, name=Bolt-1, part=Bolt
*End Instance
*Instance, name=Bolt-2, part=Bolt
50., 0., 0.
*End Instance
*End Assembly
这里 Bolt-1 和 Bolt-2 都来自同一个 Part:Bolt。
区别在于,Bolt-2 后面多了一行:
50., 0., 0.
这表示把这个实例在全局坐标系中平移一段距离。
所以,Instance 解决的不是“这个零件长什么样”的问题,而是“这个零件放在哪里、叫做什么、如何被引用”的问题。
Assembly 部分最基本的写法如下:
*Assembly, name=Assembly
*Instance, name=Part-1-1, part=Part-1
*End Instance
*End Assembly
其中:
*Assembly, name=Assembly
表示开始定义装配体,name=Assembly 是装配体名称。Abaqus/CAE 默认经常使用 Assembly 这个名字。
*Instance, name=Part-1-1, part=Part-1
表示创建一个零件实例:
name=Part-1-1:实例名称;part=Part-1:该实例来自哪个 Part。*End Instance
表示该实例定义结束。
*End Assembly
表示整个装配体定义结束。
在实际 inp 文件中,Assembly 内部不仅可以有 Instance,还可能包含:
*Nset
*Elset
*Surface
*Rigid Body
*Coupling
*Equation
*Connector Section
这些内容是否应该放在 Assembly 中,取决于它们作用的对象是单个 Part,还是整个装配体中的多个实例。
Instance 不只是“引用一个 Part”,它还可以定义该 Part 在装配体中的位置。
*Instance, name=Block-2, part=Block
10., 0., 0.
*End Instance
这表示将 Block 这个 Part 生成一个名为 Block-2 的实例,并在 X 方向平移 10 个单位。
注意:Abaqus 本身没有固定单位制,10 是毫米、米还是其他单位,取决于你的整体单位体系。
*Instance, name=Plate-2, part=Plate
0., 0., 0.
0., 0., 0., 0., 0., 1., 90.
*End Instance
这里第一行:
0., 0., 0.
表示平移量为 0。
第二行:
0., 0., 0., 0., 0., 1., 90.
表示绕一条旋转轴旋转 90 度。
这 7 个数字可以理解为:
轴上一点 a 的坐标:x1, y1, z1
轴上另一点 b 的坐标:x2, y2, z2
旋转角度:angle
也就是说:
0., 0., 0., 0., 0., 1., 90.
表示绕通过 (0,0,0) 和 (0,0,1) 的轴,也就是全局 Z 轴,旋转 90 度。
Assembly 部分最重要、也最容易出错的地方,是名称引用。
在 Part 内部,节点编号和单元编号可以很简单:
*Nset, nset=Fixed
1, 2, 3, 4
但当这个 Part 被实例化以后,Abaqus 需要知道你说的 Fixed 到底属于哪个实例。
例如:
*Part, name=Bracket
*Nset, nset=Fixed
1, 2, 3, 4
*End Part
如果在 Assembly 中有两个实例:
*Assembly, name=Assembly
*Instance, name=Bracket-1, part=Bracket
*End Instance
*Instance, name=Bracket-2, part=Bracket
*End Instance
*End Assembly
那么 Bracket-1.Fixed 和 Bracket-2.Fixed 是两个不同的集 合。
这就是为什么在 inp 文件中经常看到类似这样的写法:
*Boundary
Assembly.Bracket-1.Fixed, 1, 3
这句话的意思是:对装配体 Assembly 中,实例 Bracket-1 里的节点集 Fixed,约束 1 到 3 号自由度。
这种用点号连接的方式,本质上是在说明层级路径:
Assembly.实例名.集 合名
也可以类比为文件路径:
总装 / 某个零件实例 / 某个集 合
读 inp 文件时,经常会看到 *Nset、*Elset 出现在不同位置。它们的位置不同,含义也不同。
定义在 *Part 和 *End Part 之间:
*Part, name=PartA
*Nset, nset=Top
1, 2, 3
*End Part
这类集 合属于 Part。这个 Part 被实例化之后,每个实例都会继承这个集 合。
如果有两个实例:
*Instance, name=PartA-1, part=PartA
*End Instance
*Instance, name=PartA-2, part=PartA
*End Instance
那么会有:
PartA-1.Top
PartA-2.Top
它们名称相似,但属于不同实例。
定义在某个 *Instance 内部:
*Assembly, name=Assembly
*Instance, name=PartA-1, part=PartA
*Nset, nset=LocalSet
10, 20, 30
*End Instance
*End Assembly
这类集 合只属于该实例。
如果你只想给某一个实例额外定义集 合,而不影响同一个 Part 的其他实例,这种写法就很有用。
定义在 Assembly 层级:
*Assembly, name=Assembly
*Instance, name=PartA-1, part=PartA
*End Instance
*Instance, name=PartA-2, part=PartA
*End Instance
*Nset, nset=LoadNodes
PartA-1.101, PartA-1.102, PartA-2.201, PartA-2.202
*End Assembly
这类集 合属于整个装配体,可以跨多个实例。
这在定义载荷、输出、接触、耦合区域时非常常见。
当 Assembly-level set 包含很多节点或单元时,如果每个编号前面都写实例名,会非常冗长:
*Nset, nset=LoadNodes
PartA-1.101, PartA-1.102, PartA-1.103
PartA-2.201, PartA-2.202, PartA-2.203
这时可以使用 instance= 参数简化写法:
*Nset, nset=LoadNodes, instance=PartA-1
101, 102, 103
*Nset, nset=LoadNodes, instance=PartA-2
201, 202, 203
这里两次使用了同一个集 合名 LoadNodes,Abaqus 会把后面定义的成员继续追加到同一个 Assembly-level set 中。
对于 *Elset 也类似:
*Elset, elset=ContactElems, instance=PartA-1
1, 2, 3
*Elset, elset=ContactElems, instance=PartA-2
10, 11, 12
这种写法在手动修改 inp 文件时非常实用,尤其是需要把多个实例中的节点或单元合并成一个集 合时。
在 Abaqus 中,接触、压力、耦合等操作经常依赖 *Surface。
Surface 也可以定义在不同层级:
例如,Part 中可以定义一个表面:
*Surface, type=ELEMENT, name=Surf-Top
TopElems, S1
当这个 Part 被实例化以后,不同实例会继承这个表面:
PartA-1.Surf-Top
PartA-2.Surf-Top
如果某个接触关系发生在两个实例之间,那么在后续定义 contact pair、tie、coupling 等内容时,就需要准确引用对应实例下的 surface。
这也是 Assembly 部分的重要价值:它把“几何/网格本身”和“装配后的相互关系”区分开了。
手动修改 inp 文件时,Assembly 部分最常见的问题不是语法拼写,而是层级放错。
如果网格定义在 Part 里,那么截面属性通常也要在 Part 层级定义。你不能因为某个实例材料不同,就随手在 Assembly 里重写 section。
如果确实希望同一个几何的不同实例使用不同材料或不同单元类型,往往需要把网格或属性定义放到更合适的层级,或者创建不同 Part,而不是简单复 制粘贴关键词。
例如:
*Boundary
Fixed, 1, 3
如果 Fixed 不是 Assembly-level set,而是某个 Part 或 Instance 下的集 合,这种写法就可能无法 正确定位。
更稳妥的写法是使用完整路径,例如:
*Boundary
Assembly.PartA-1.Fixed, 1, 3
由于点号 . 在 Abaqus 的完整名称中有特殊含义,建议不要在普通 set、surface、instance 名称里使用点号。
比如不建议写:
*Elset, elset=Set.1
更推荐:
*Elset, elset=Set_1
或者:
*Elset, elset=Set-1
这样后续引用时更清晰,也不容易和层级路径混淆。
下面用一个非常简化的例子,把 Part、Assembly、Instance、Set 和 Boundary 串起来看:
*Heading
Simple assembly example
*Part, name=Block
*Node
1, 0., 0., 0.
2, 1., 0., 0.
3, 1., 1., 0.
4, 0., 1., 0.
*Nset, nset=Left
1, 4
*Nset, nset=Right
2, 3
*End Part
*Assembly, name=Assembly
*Instance, name=Block-1, part=Block
*End Instance
*Instance, name=Block-2, part=Block
2., 0., 0.
*End Instance
*Nset, nset=AllRightNodes
Block-1.Right, Block-2.Right
*End Assembly
*Step, name=Step-1
*Static
*Boundary
Assembly.Block-1.Left, 1, 3
*Cload
Assembly.AllRightNodes, 1, 100.
*End Step
这个例子表达了几个关键点:
Block 是 Part;Block-1 和 Block-2 是两个实例;Block-2 相对原始 Part 平移了 2 个单位;Block-1.Left 是实例 Block-1 中继承来的节点集;AllRightNodes 是 Assembly-level set,它把两个实例的 Right 节点集 合并到一起;如果你拿到一个复杂 inp 文件,不建议一上来就逐行硬啃。可以按下面顺序读:
搜索:
*Part
看看模型中有哪些零件。
搜索:
*Instance
确认每个实例来自哪个 Part,以及有没有平移或旋转。
重点看:
*Nset
*Elset
*Surface
尤其是定义在 *Assembly 和 *End Assembly 之间的集 合与表面。
在 *Boundary、*Cload、*Dload、*Contact Pair、*Tie、*Coupling 等关键词中,看看它们引用的是哪个实例、哪个集 合、哪个表面。
这样读下来,你就能从“零件定义”逐步过渡到“整体模型行为”,而不是被一堆名称绕晕。
Abaqus 的 inp 文件并不是简单地把节点、单元、材料和载荷堆在一起。对于由 Part 和 Instance 组织的模型来说,Assembly 是连接零件定义和整体分析的关键层级。
它回答了几个核心问题:
理解了 Assembly,再去读 Abaqus 的 inp 文件,就不再只是看关键词,而是在看一个有限元模型如何从“零件”一步步变成“装配体”,再进入实际分析。
对于需要二次开发、批量建模、Python 生成 inp 文件、手动修改边界条件和接触关系的工程师来说,Assembly 部分绝对是必须掌握的一块基础内容。