ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Gmsh网格转Exodus II:打通Peridigm前处理链路的转换工具

Gmsh网格转Exodus II:打通Peridigm前处理链路的转换工具 简介这是一份将Gmsh网格转换为Exodus II格式的Python转换工具面向Peridigm等仿真软件的前处理场景适合从事近场动力学、计算力学及ParaView后处理的工程师和研究人员可减少手工转换带来的格式错误提升前处理效率。压缩包共25个文件、约861KB包含Python转换脚本、msh/geo示例网格、png结果预览图、配置文件以及安装与许可文档目录结构清晰可按模块直接取用。已有561人学习下载。工具支持通过convert.py命令行完成input.msh到output.g的转换也可借助meshio-convert命令替代目前可处理二维网格中的三节点三角形与四节点四边形单元并明确提示VTK版本与Ubuntu环境下的python-vtk安装要点帮助规避python-vtk6的段错误缺陷。包内附带三维立方体、圆柱等典型算例及转换效果图同时提供安装脚本、依赖清单与代码检查配置便于快速验证转换质量、复现环境并接入Peridigm、ParaView等工具链。 做近场动力学仿真绕不开 Peridigm而 Peridigm 读网格只认 Exodus II 这套格式。很多用 Gmsh 建好模型、切好网格的人第一步就卡在 .msh 转 .e 上gmsh-exodus-converter 这个转换器就是专门来填这个坑的。它读入 Gmsh 生成的网格文件解析节点、单元、物理组信息再按 Exodus II 的数据库结构输出成 Peridigm 能直接加载的文件。这篇文章从格式差异讲到转换原理再带你把工具编译出来、实际转一个模型最后列出我踩过的坑和排查思路适合刚接触 Peridigm、准备用 Gmsh 做前处理的人参考。更直白地说如果你已经习惯用 Gmsh 的脚本化建模、带 OCC 内核切几何那你缺的不是网格生成能力而是一座从 Gmsh 数据模型到 Peridigm 输入数据的桥。gmsh-exodus-converter 就是这座桥而且它还能帮你把物理组、边界条件这些信息一起带过去省掉手动写节点集合的重复劳动。1. 这个转换器到底在解决什么问题1.1 为什么 Peridigm 偏偏认 Exodus IIPeridigm 是美国 Sandia 国家实验室开源的近场动力学求解器它的前处理和结果输出都深度绑定了 SEACAS 工具链而 SEACAS 的网格数据库标准就是 Exodus II。这个格式不是简单的文本网格而是基于 NetCDF 的二进制数据库里面可以同时存节点坐标、单元连接、单元块、节点集、侧集、时间序列等一系列信息。对 Peridigm 来说节点坐标和单元连接只是最底层的数据。真正决定材料分布和边界条件的是 block 和 nodeset哪个区域用哪种材料哪个节点集合施加载荷哪个节点集合固定都要通过 Exodus 的单元块和节点集来标识。这就是为什么不能只给 Peridigm 一份裸节点坐标必须把拓扑和集合信息完整地放进 Exodus II 文件里。Exodus II 的另一个优势是面向大规模并行仿真设计支持分块写入和增量输出。近场动力学计算经常要跑几十万个节点结果文件写入频率也高用 NetCDF 这种自描述格式会稳很多。所以 Peridigm 选择 Exodus II 不是拍脑袋而是整个工具链延续下来的技术选型。1.2 Gmsh 网格和 Exodus II 之间的鸿沟Gmsh 的优势在几何建模和网格生成它的 .msh 格式完全围绕网格生成器本身设计。节点段、单元段、物理组各自分开单元类型用整数代码表示文件既可以是 ASCII 也可以是二进制版本还有 2.2、4.0、4.1 之分。这种格式灵活、易读但跟 Exodus II 的数据模型差别很大。最明显的一道坎是“集合”的表达方式不同。Gmsh 里用 Physical Volume、Physical Surface、Physical Curve 把单元和边界聚合成逻辑组而在 Exodus II 里对应的是 element block 和 nodeset。转换器必须把物理组变成 Exodus 能识别的块和集合同时还要处理单元类型映射、节点编号连续化、删除孤立节点这些额外工作。另一个鸿沟是坐标系和单位。Gmsh 只存坐标数值不记录单位Exodus II 也有一个单位系统字段但 Peridigm 并不会自动换算单位。转换器没有单位转换的职责它只是原样搬运坐标数值这就意味着你在 Gmsh 里用毫米建模型到了 Peridigm 里依然是毫米前后必须保持一致否则材料参数和损伤模型全都会错位。1.3 转换器的职责边界gmsh-exodus-converter 这个名字听起来很专一实际做的事比想象中多。它至少包含四条链路解析 .msh 节点段和单元段把 Gmsh 单元类型翻译成 Exodus 单元类型保留尽可能多的物理组信息最后按 Exodus 的 NetCDF 结构写输出。它不会帮你生成网格不会帮你修复破损几何也不会替你调试 Peridigm 参数。它只解决一个核心问题让同一个网格模型能在 Gmsh 和 Peridigm 之间无缝流转。理解这个职责边界很重要后面遇到问题你就知道该去哪一环排查是在 Gmsh 侧、转换器侧还是 Peridigm 侧。2. 转换链路里的关键设计2.1 从 MSH 文件里抓哪些信息MSH 2.2 的节点段以$Nodes开头每行是“节点编号 x y z”单元段以$Elements开头每行是“单元编号 类型 物理组个数 物理组编号 几何组编号 节点列表”。转换器第一步就是把这张表原样读进来建立节点编号到坐标的映射以及单元编号到类型和节点的映射。MSH 4 以上的格式结构差异很大节点和单元段会按块组织还多了$Entities和$PhysicalNames。我的建议是尽量在 Gmsh 里把Mesh.MshFileVersion设成 2.2很多第三方转换器对 2.2 的支持最成熟。在 Gmsh 命令行里可以加-format msh2或者在 GUI 的 Toolbox 里设置。物理组是 Peridigm 最需要的东西这些信息在 Gmsh 里通过单元标签传入。每个单元可能带上物理组编号多个单元共用一个物理组就形成了一个逻辑集合。转换器保留这些集合后才能在写 Exodus 文件时生成对应的 block 和 nodeset。如果 Gmsh 里没有定义任何 Physical Volume转换器就只能把整个网格当成一个默认块后续材料分配就很麻烦。2.2 Exodus II 文件核心结构速览用 NetCDF 格式呈现的 Exodus II 文件顶层有一堆尺寸变量例如num_nodes表示节点总数num_elem表示单元总数num_el_blk表示单元块数量num_ns表示节点集数量num_ss表示侧集数量。每个单元块的连接表储存在connect1、connect2这样的变量里坐标储存在coordx、coordy、coordz。Peridigm 通过 SEACAS 库读取这些变量所以在转换器里写输出时节点坐标数组、每个块对应的连接表、块属性、节点集列表都必须严格按顺序写入。这里有一个经典坑Exodus 文件内部节点编号通常从 1 开始而 C/C 数组从 0 开始。转换器如果没处理好编号偏移生成的连接表就会差 1Peridigm 加载后所有单元的顶点都指向错误节点。节点集和侧集在 Exodus 里分别是ns_node_conn和ss_elem_conn这样的变量。一个节点集就是一个节点编号数组Peridigm 用 YAML 配置里加载边界条件时会直接引用这个集合的名字。所以转换器最好把 Gmsh 的 Physical Surface 映射为节点集把 Physical Curve 也合并进去尽量减少用户在 Peridigm 输入文件里手写节点列表的负担。2.3 单元类型映射从 MSH 整数代码到 Exodus 单元名Gmsh 用整数代码标识单元类型Exodus 用字符串名标识单元类型。转换器内部必须维护一张映射表。近场动力学里最常遇到的是一阶体单元对应关系可以参考下表Gmsh 单元类型代码Gmsh 单元名Exodus 单元名说明4四面体 4 节点TET4最常见的四面体网格5六面体 8 节点HEX8结构化区域常用6三棱柱 6 节点WEDGE6扫掠网格产物7金字塔 5 节点PYRAMID5过渡单元Peridigm 支持有限2三角形 3 节点TRI3面单元可转换为侧集或节点集3四边形 4 节点QUAD4面单元可转换为侧集或节点集二阶单元不是不能转但对 Peridigm 意义不大因为它做近场动力学计算时主要用节点坐标和节点间距离并不依赖单元插值函数。如果你在 Gmsh 里生成了二阶网格转换器要么降阶处理要么直接报错。我的习惯是在 Gmsh 里强制Mesh.ElementOrder1既减小文件体积也避免后续兼容性问题。面单元的处理要特别留意。Peridigm 的边界载荷通常通过节点集实现所以转换器把三角形、四边形面单元转成节点集是比较常见的做法。如果是把面单元转成 Exodus 的表面单元块Peridigm 能不能用还得看它的版本和配置。建议先查看转换器 README 里有没有专门的“surface to nodeset”选项。2.4 编号重排与孤立节点处理Gmsh 输出的节点编号一般是一条条实体自带编号在多个实体拼在一起时可能存在重复节点或者编号不连续。Exodus 要求节点编号尽量连续紧凑转换器需要在写输出前做一次全局拓扑重建。具体做法通常是建立一个“旧节点编号到新节点编号”的映射表遍历所有单元把所有出现过的节点收集起来按照在单元里出现的先后顺序重新编号。单元连接表里引用的旧编号全部替换成新编号。从来没有被任何单元引用的孤立节点直接删除不写入输出文件。还有一个容易忽视的点是容差合并。如果 Gmsh 里有两个实体共用同一个边界但因为建模精度不同产生了微小偏差边界上的节点坐标非常接近但不是完全相等。转换器可以提供一个合并容差参数比如--merge-tolerance 1e-8距离小于容差的节点视为同一个节点。这个功能对 Peridigm 特别有用因为近场动力学邻居搜索对初始构型的一致性要求很高重复节点会让一个位置出现两个相互可见的粒子影响损伤判断。3. 一步步编译并完成一次转换3.1 准备依赖NetCDF、HDF5 与 Exodus 库gmsh-exodus-converter 这类工具通常用 C/C 编写写 Exodus 文件时依赖 NetCDF-C 库和 SEACAS 的 exodus 库。编译前先确认系统里有没有这些库。Ubuntu/Debian 上可以安装libnetcdf-dev、libhdf5-dev而 SEACAS 库可能需要自己编译或者通过 conda 环境安装。如果你不想折腾系统级依赖我建议用 conda 建一个隔离环境直接安装exodus或seacas相关包然后在 CMake 里指定CMAKE_PREFIX_PATH指向这个环境。这样可以避免和系统自带的 NetCDF 版本冲突。编译前先跑一次cmake ..如果报找不到头文件通常不是代码问题而是CMAKE_PREFIX_PATH没指对。也有实现比较巧妙的转换器不走 Exodus 库而是直接用 NetCDF API 手写 Exodus 文件。这种工具依赖更少但功能可能不完整比如不写结果变量历史记录。如果只是网格转换够用了如果希望保留 Peridigm 必需的全部变量字段还是建议用标准 SEACAS 库。3.2 编译源码和典型调用方式假设你已经把仓库 clone 到本地在源码目录下执行mkdir build cd build cmake .. -DCMAKE_BUILD_TYPERelease -DCMAKE_PREFIX_PATH/path/to/seacas make -j$(nproc)编译成功后一般会生成一个可执行文件名字大概率与项目同名。先运行./gmsh-exodus-converter -h看一下支持的选项不同仓库的差异很大。典型的调用格式是./gmsh-exodus-converter input.msh output.e更复杂一点可能支持这些参数./gmsh-exodus-converter --merge-tolerance 1e-8 \ --surface-as-nodeset \ --block-prefixpart_ \ input.msh output.e--surface-as-nodeset是我比较推荐的选项它会把所有边界单元提取出来生成 Peridigm 可以直接用的节点集。--block-prefix则是给单元块加了前缀名方便你在 Peridigm 输入文件里区分不同块。具体名称以你手头仓库为准关键是养成看-h输出的习惯。3.3 用 ncdump 和 ParaView 验证转换结果转换完成后千万不要直接扔给 Peridigm先做快速验证。第一种方式是使用 NetCDF 自带的ncdump -h output.e检查文件里的维度数量和变量名是否合理。你会看到num_nodes、num_elem、num_el_blk等变量确认其数值跟 Gmsh 里的模型对应得上。第二种方式是用 ParaView 打开 .e 文件。ParaView 自带 Exodus II 读取器加载后选择几何浏览器里能看到多个 block。用鼠标旋转查看网格是否完整有没有空洞或错位的单元。这一步能直观发现节点编号错乱、坐标轴反了、表面节点集位置不对等问题。第三种方式是直接用一个极短的 Peridigm 输入文件试跑。把模拟时间设到很小的值比如0.0001秒跑一个时间步后看日志里是否正常加载了块和节点集。只要没有崩溃且输出结果文件有内容说明这次转换在 Peridigm 侧的兼容性基本合格。4. 转换实战中的高频坑4.1 单元类型不支持或映射错误最常见的报错是Unsupported element type或者Element type mismatch。原因一般是 Gmsh 生成了一阶或二阶单元里的稀有类型比如金字塔单元而转换器没实现对应的输出。解决办法是在 Gmsh 里尽量把网格统一成四面体或六面体。如果转换器把单元类型映射错了Peridigm 加载时不会立刻报错但后续计算时单元体积或者邻居搜索会产生非常离谱的结果。我遇到过一次把棱柱单元映射成六面体单元的事故表面网格看着正常Peridigm 跑出来的应变场却像噪声。排查方法是用 ParaView 显示每个 block 的类型再和 Gmsh 里的单元类型逐一核对。4.2 物理组丢失导致材料区域错乱Gmsh 里定义了 Physical Volume但转换后 Peridigm 只看到一个 block所有单元都是同一种材料这种情况十有八九是转换器没有解析物理组标签。你可以在终端里跑转换器时加上-v或--verbose参数看它是否打印每个 block 的单元数量。解决思路是在 Gmsh 中为每个材料区域单独建立 Physical Volume最好用整数编号区分。例如Physical Volume(steel) {1};和Physical Volume(copper) {2};转换器就会在 Exodus 文件里生成两个 block。Peridigm 的 YAML 配置里对应写两个 block 条目分别指定材料问题就解决大半。4.3 重复节点和孤立节点让 Peridigm 直接卡住有些 Gmsh 几何来自 CAD 装配体每个零件独立划分网格零件接触面上节点编号不共享。这种情况下生成的节点坐标里会有大量位置重合但编号不同的重复节点。Peridigm 做邻居搜索时会把同一坐标的两个粒子都算进去最直接的表现是内存暴涨或求解发散。应对方法就是在转换时开启节点合并功能设置合适的容差。一般取网格最小尺寸的千分之一就够了太大的容差会把真正靠近的几何特征错误合并。合并之后再用ncdump确认节点数明显减少和 Gmsh 里的物理节点数对得上。4.4 单位不统一的小坑Gmsh 里画几何时你可能按毫米建模材料参数按兆帕和吨力制式写也可能导入的 STEP 文件本身就是米制。转换器只是原样搬运坐标不会加任何单位信息。Exodus 文件里的坐标数值是什么Peridigm 就认为是什么。所以每次转换前先确认单位的统一性这是很土但很关键的一步。我也见过有人在 Gmsh 里用的毫米Peridigm 里的 horizon 和弹性参数却按米制换算导致损伤区域范围完全不对。建议在项目里固定一套单位体系并在 Gmsh 的几何脚本注释里写清楚。4.5 大模型转换时的内存问题几十万节点的网格转换对现代电脑不算大但如果你做的是上百万节点的近场动力学模型转换器在建立连接表和重排编号时会占掉不少内存。有些转换器会在内存里保留所有节点和单元转换时进程可能跑到十几个 GB。优化手段不复杂一是把 Gmsh 输出设为二进制模式减少解析开销二是尽量用 Release 编译选项三是如果转换器支持分批写 NetCDF别把整个连接表一次性塞进内存。实在内存不够就分区域转换然后在 Peridigm 里用多个 block 拼起来。5. 让网格在 Peridigm 里稳定跑起来5.1 Peridigm 输入文件里如何引用块和节点集转换完成后Peridigm 输入文件的核心是 YAML 里的 blocks 和 boundary_conditions。一个典型的 blocks 片段长这样blocks: - name: specimen material: my_material element_block: part_1 boundary_conditions: - name: fixed_end type: displacement nodeset: boundary_fixed value: [0.0, 0.0, 0.0]这里的element_block名字必须和 Exodus 文件里的 block 名字对应nodeset名字也要和转换器生成的节点集名字对应。如果对不上Peridigm 会提示找不到 block这时候回头检查转换器是否把物理组输出成了预期名字。我通常会在转换后用ncdump -v eb_names output.e查看单元块名称再用ncdump -v ns_names output.e查看节点集名称确认后直接复制到 YAML 里避免手拼字符串打错字。5.2 最小复现流程从建模到求解把整套流程固定成脚本是提高效率的关键。我自己的习惯是建一个run_all.sh里面依次执行 Gmsh 建模、mesh 转换、Peridigm 求解三个命令gmsh model.geo -3 -format msh2 -o model.msh ./gmsh-exodus-converter --surface-as-nodeset model.msh model.e peridigm input.yaml这样做的好处是每次改几何参数后一条命令就能重新生成全部中间产物不会出现昨天转的网格和今天改的几何对不上的情况。模型有几十个版本迭代的时候这个脚本就是救命稻草。Peridigm 跑完以后结果也是 Exodus 格式你可以继续用 ParaView 打开结果文件观察损伤云图。这样就形成了一个完整的闭环Gmsh 建模、转换器搭桥、Peridigm 求解、ParaView 后处理。5.3 我的建模习惯与最后一点建议最后再分享一个我踩过多次坑后养成的习惯在 Gmsh 脚本里把所有需要施加载荷或约束的边界都显式定义为 Physical Surface哪怕这个面暂时用不到边界条件。转换器会把这些面转成节点集Peridigm 里要用时直接引用就行省得以后要加边界条件时重新建模再转换。另一个习惯是转换前先在 Gmsh 里用gmsh model.geo -3 -o model.msh -check跑一遍自检确认网格没有负体积单元。负体积单元转换器一般不会报错但进入 Peridigm 后会出现局部异常损伤或无法求解。多花十秒做检查省下的是几天排查时间。gmsh-exodus-converter 这种工具看起来很小但它刚好处在 Gmsh 生态和 Peridigm 生态的接缝处。把这条链路跑通以后你就会发现近场动力学以前最麻烦的前处理环节其实也可以做到像普通有限元一样流畅。本文还有配套的精品资源点击获取
返回列表