1、在 abaqus中 生 成 voronoi多 面 体 的 方 法本 文 转 自 技 术 邻 张 磊这 篇 小 文 旨 在 介 绍 在 abaqus中 生 成 Voronoi凸 多 面 体 的 方 法 , 在 模 拟 晶 体 或 类似 结 构 时 , 经 常 需 要 生 成 许 多 相 互 连 接 的 Voronoi多 面 体 , 如 图 1所 示 。 通 常 方 法 是利 用 MATLAB或 是 其 他 软 件 生 成 多 面 体 的 空 间 结 构 , 然 后 导 入 abaqus进 一 步 处 理 。此 外 还 有 国 外 学 者 开 发 的 neper及 其 衍 生 软 件 可 以 使
2、用 , 不 过 该 软 件 目 前 仅 支 持 Linux操 作 系 统 , 而 且 往 往 需 要 用 户 做 进 一 步 的 开 发 才 能 满 足 该 用 户 特 定 的 需 求 , 对 于 使 用者 的 编 程 能 力 要 求 较 高 。图 1 Voronoi多 边 形 示 意 图其 实 生 成 Voronoi多 面 体 这 一 过 程 不 需 借 助 第 三 方 软 件 , 在 abaqus中 合 理 利 用脚 本 也 可 以 实 现 。 Abaqus常 用 的 脚 本 语 言 是 Python, Python是 一 种 简 单 易 学 的 编程 语 言 , 而 且 abaqus脚
3、本 学 习 起 来 也 很 轻 松 , 因 为 用 户 在 abaqus的 图 形 界 面 里 每 做一 个 操 作 , rpy文 件 就 会 记 录 下 对 应 的 脚 本 命 令 ( 一 些 特 殊 的 操 作 除 外 ) , 再 配 合 上 help文 档 的 详 细 说 明 , 很 多 新 手 也 可 以 在 短 时 间 内 运 用 脚 本 来 解 决 一 些 仿 真 中 比 较 繁 琐的 问 题 。Python库 Scipy提 供 了 现 成 的 Voronoi类 , 和 MATLAB里 的 函 数 一 样 , 可 以提 供 voronoi各 个 单 元 的 空 间 点 坐 标 ,
4、有 关 Voronoi类 的 调 用 , 所 需 变 量 及 其 属 性 ,可 参 考 如 下 , 其 中 属 性 部 分 我 用 中 文 做 了 介 绍 :scipy.spatial.Voronoi(points,furthest_site=False,incremental=False,qhull_options=None)Parameters : points : ndarray of floats, shape (npoints, ndim)Coordinates of points to construct a convex hull fromfurthest_site : bool
5、, optionalWhether to compute a furthest-site Voronoi diagram. Default: Falseincremental : bool, optionalAllow adding new points incrementally. This takes up some additional resources.Qhull_options : str, optionalAdditional options to pass to Qhull. See Qhull manual for details. (Default: “ Qbb Qc Qz
6、 Qx” for ndim 4 and “ Qbb Qc Qz” otherwise. Incremental mode omits “ Qz” .)注 : 对 于 一 般 用 户 , 只 需 要 注 意 points 参 数 即 可 , 代 表 voronoi 的 种 子 点 , 可 以 是 N 维 数 组 , 只 不 过 超 过 3 维 的 数 组 就 没 有 空间 上 的 意 义 了 。 ( 在 我 们 这 个 宇 宙 是 这 样 的 , 对 于 高 维 宇 宙 可 能 并 不 成 立 _)Attributes points (ndarray of double, shape (npoi
7、nts, ndim) Coordinates of input points.核 心 点 坐 标 , n行 2列 的 数 组vertices (ndarray of double, shape (nvertices, ndim) Coordinates of the Voronoi vertices.多 边 形 顶 点 的 坐 标 , n 行 2 列 的 数 组 , 只 标 出 有 限 的 顶 点 , 处 于 无 限 远 的 顶 点 不 会 标 出ridge_points (ndarray of ints, shape (nridges, 2) Indices of the points be
8、tween which eachVoronoi ridge lies.输 出 的 是 点 信 息 ,每 条 voronoi边 所 处 的 两 个 核 心 点 的 序 号ridge_vertices (list of list of ints, shape (nridges, *) Indices of the Voronoi vertices formingeach Voronoi ridge.多 边 形 每 条 边 的 端 点 序 号 , 如 果 端 点 是 无 限 远 , 那 么 序 号 就 是 -1regions (list of list of ints, shape (nregion
9、s, *) Indices of the Voronoi vertices forming each Voronoiregion. -1 indicates vertex outside the Voronoi diagram.给 出 了 每 个 多 边 形 的 端 点 信 息 , 如 果 端 点 是 无 限 远 , 那 么 序 号 就 是 -1, 有 多 个 无 限 远 端 点 的 , 都 只 用 一 个 -1point_region (list of ints, shape (npoints) Index of the Voronoi region for each input point
10、.If qhull option “ Qc” was not specified, the list will contain -1 for points that are not associated witha Voronoi region.对 于 每 一 个 输 入 点 , 给 出 其 对 应 的 region 序 号注 : ridge_vertices这 个 属 性 的 名 字 有 一 定 误 导 性 , 对 于 2维 voronoi来 说 , 这 个 属 性 指 的 是 边 上 的 顶 点 序 号 , 对 于 3维 voronoi来 说 , 这 个 变 量 实 际 上 指 的 是 面
11、 上 的 顶 点 序 号 , 对 于 N 维 voronoi而 言 , 这 个 变 量 指 的 是 N-1维 边 界 上 的 各 个 顶 点 。参 考 出 处 :http:/students.mimuw.edu.pl/pbechler/scipy_doc/generated/scipy.spatial.Voronoi.html#scipy.spatial.Voronoi介 绍 完 voronoi类 后 , 我 们 就 可 以 愉 快 地 使 用 它 了 , 在 使 用 之 前 , 首 先 需 要 生 成voronoi多 面 体 的 种 子 点 , 通 常 种 子 点 是 空 间 上 随 机 分
12、 布 的 点 , 不 过 如 果 我 们 对 种 子 点施 加 一 定 的 控 制 , 可 以 生 成 很 多 有 趣 的 空 间 形 状 , 比 如 蜂 窝 状 的 空 间 结 构 。 生 成 种 子 点后 , 将 种 子 点 坐 标 代 入 类 中 , 就 可 以 建 立 一 个 voronoi类 了 。 随 后 就 可 以 把 这 个 voronoi类 的 信 息 转 化 为 几 何 信 息 , 利 用 abaqus的 建 模 功 能 , 生 成 voronoi多 面 体 实 体 ( 也就 是 软 件 脚 本 语 言 中 的 cell对 象 ) 。Abaqus提 供 了 从 点 到 线
13、到 面 到 体 的 生 成 过 程 , 生 成 voronoi多 面 体 的 过 程 就 很好 地 体 现 了 这 一 点 :1. 通 过 ridge_vertices 属 性 , 可 以 获 知 一 个 面 上 的 顶 点 序 号 ( 贴 心 的 是 , 这 个 属性 提 供 的 点 是 按 照 点 的 相 连 顺 序 排 布 的 , 而 不 是 乱 序 , 这 一 点 非 常 重 要 ) , 而 通 过顶 点 序 号 , 就 能 从 vertices 属 性 中 获 知 该 点 的 坐 标 。2. 由 此 就 可 以 生 成 voronoi某 个 多 面 体 中 的 一 个 面 的 各 条
14、 边 : 使 用 脚 本 命 令 WirePolyLine将 该 面 的 各 点 顺 次 连 接 生 成 一 个 空 间 上 的 多 边 形 线 框 。3. 然 后 使 用 geometry edit的 cover edges功 能 将 线 框 围 住 的 区 域 生 成 1个 shell, 这 个 shell就 是 多 面 体 中 的 一 个 面 了 。4. 对 于 该 多 面 体 中 的 其 他 表 面 , 也 可 以 如 法 炮 制 , 直 到 生 成 这 个 多 面 体 的 全 部 外表 面 。 然 后 再 使 用 creat solidfrom shell功 能 ( 对 应 的 脚
15、本 方 法 为 AddCells) , 即 可 生 成 该 多 面 体 。 这 就 是 点 线 面 体 生 成 voronoi多 面 体 的 过 程 。下 面 我 用 一 个 配 图 例 子 来 说 明 一 下 以 上 过 程 :首 先 , 在 空 间 内 建 立 一 个 面 上 的 顶 点 边 线 关 系 , 为 了 尽 可 能 简 单 , 我 们 采 用 三角 形 线 框 来 构 成 一 个 面 , 生 成 三 角 形 线 框 步 骤 如 下 :1.使 用 creat wire功 能 , 输 入 各 个 点 的 坐 标 , 首 尾 相 连 ( 选 择 chained wires)形 成 一
16、 个 三 角 形 , 点 击 ok即 可 生 成 线 框 :图 2 由 点 生 成 线 框2.再 将 另 外 三 条 棱 边 输 入 , 获 得 四 面 体 的 各 条 棱 边 :图 3 补 全 四 面 体 的 全 部 棱 边3.使 用 Geometry edit工 具 中 的 Cover Edges功 能 , 依 次 封 闭 各 个 线 框 :图 4 封 闭 线 框 为 壳 体封 闭 后 的 壳 体 如 下 图 所 示 , 为 了 表 示 清 楚 , 这 里 做 了 一 个 剖 面 :图 5 壳 体 示 意 图4.使 用 create solid: from shell功 能 , 将 壳 体
17、 填 充 成 实 体 :图 6 由 壳 体 生 成 实 体填 充 后 的 实 体 如 下 图 所 示 , 为 了 显 示 方 便 , 下 图 依 旧 使 用 了 一 个 剖 切 面 :图 7 实 体 示 意 图至 此 , 由 点 坐 标 信 息 生 成 实 体 的 过 程 就 结 束 了 , 相 应 的 Python脚 本 请 见 附 件 ,将 该 脚 本 复 制 后 粘 贴 至 下 图 的 命 令 行 接 口 中 , 即 可 获 得 图 示 的 四 面 体 模 型 。 利 用 这 种 思路 , 我 们 可 以 在 空 间 中 生 成 任 意 的 凸 多 面 体 。 无 论 一 个 Voron
18、oi多 面 体 有 多 么 复 杂 ,利 用 脚 本 就 可 以 方 便 地 生 成 它 。在 生 成 过 程 中 , 可 以 利 用 脚 本 , 将 不 同 的 几 何 元 素 添 加 到 set之 中 , 方 便 后 续 赋予 材 料 属 性 , 添 加 约 束 或 者 接 触 , 撒 布 种 子 点 等 等 功 能 。 通 过 使 用 set, 从 理 论 上 说 ,使 用 者 可 以 对 每 一 个 点 , 每 一 条 边 , 每 一 个 面 和 体 进 行 控 制 , 这 是 neper做 不 到 的 。值 得 注 意 的 是 , voronoi类 的 属 性 提 供 了 三 种 类
19、 型 的 顶 点 : 1) 整 个 voronoi多 面体 的 全 部 顶 点 vertices; 2) 各 个 面 上 的 顶 点 ridge_vertices; 3) 各 个 体 上 的 顶 点 regions。 并 没 有 提 供 哪 些 面 是 属 于 哪 一 个 体 的 , 这 一 点 需 要 用 脚 本 对 坐 标 序 号 进 行 筛 选 判断 , 把 面 和 体 匹 配 起 来 , 才 能 实 现 上 述 功 能 。最 后 附 上 成 品 效 果 图 和 脚 本 , CAE附 件 :图 8 Voronoi示 意 图 , 图 中 两 种 不 同 的 颜 色 表 示 两 种 不 同
20、的 材 料图 9 对 图 8中 的 Voronoi多 面 体 进 行 网 格 划 分from abaqus import *from abaqusConstants import *session.Viewport(name=Viewport: 1 , origin=(0 .0 , 0 .0 ), width=2 8 2 .9 8 9 7 5 5 3 3 2 4 7 ,height=1 5 2 .0 8 4 6 3 9 6 9 8 2 6 7 )session.viewportsViewport: 1 .makeCurrent()session.viewportsViewport: 1 .ma
21、ximize()from caeModules import *from driverUtils import executeOnCaeStartupexecuteOnCaeStartup()Mdb()session.viewportsViewport: 1 .setValues(displayedObject=None)p = mdb.modelsModel-1 .Part(name=Part-1 , dimensionality=THREE_D,type=DEFORMABLE_BODY)p = mdb.modelsModel-1 .partsPart-1 session.viewports
22、Viewport: 1 .setValues(displayedObject=p)p.WirePolyLine(points=(0 .0 , 0 .0 , 0 .0 ), (5 .0 , 0 .0 , 0 .0 ), (0 .0 , 5 .0 , 0 .0 ), (0 .0 , 0 .0 , 0 .0 ), (5 .0 , 0 .0 , 0 .0 ), (0 .0 , 5 .0 , 0 .0 ), mergeWire=OFF,meshable=ON)e = p.edgesedges = e.getSequenceFromMask(mask=(#7 , ), )p.Set(edges=edges
23、, name=Wire-1 -Set-1 )p.WirePolyLine(points=(0 .0 , 0 .0 , 0 .0 ), (0 .0 , 0 .0 , 5 .0 ), ), mergeWire=OFF,meshable=ON)e = p.edgesedges = e.getSequenceFromMask(mask=(#1 , ), )p.Set(edges=edges, name=Wire-2 -Set-1 )v = p.verticesp.WirePolyLine(points=(v0 , v2 ), (v3 , v0 ), mergeWire=OFF, meshable=ON
24、)p = mdb.modelsModel-1 .partsPart-1 e = p.edgesedges = e.getSequenceFromMask(mask=(#3 , ), )p.Set(edges=edges, name=Wire-3 -Set-1 )e = p.edgesp.CoverEdges(edgeList = e0 :1 +e3 :5 , tryAnalytical=True)e1 = p.edgesp.CoverEdges(edgeList = e1 0 :1 +e1 2 :3 +e1 5 :6 , tryAnalytical=True)e = p.edgesp.CoverEdges(edgeList = e0 :1 +e3 :4 +e5 :6 , tryAnalytical=True)e1 = p.edgesp.CoverEdges(edgeList = e1 0 :1 +e1 3 :4 +e1 5 :6 , tryAnalytical=True)f = p.facesp.AddCells(faceList = f0 :4 )session.viewportsViewport: 1 .setValues(displayedObject=p)更 多 CAE 案 例 可 以 来 技 术 邻 关 注 作 者 。