# 使用gmsh对3D造型软件导出的装配体进行多区域网格划分 # 问题 [gmsh](http://www.gmsh.info/)是个好东西,开源免费跨平台,容易上手同时功能强大。所有操作都能通过脚本完成,故易于自动化——脚本化到了GUI上某些功能不全的程度。 `gmsh`自带了一个不算简陋的造型系统,不过我还是习惯用`Creo`这类软件画图,导出成`*.step`格式(`*igs`格式在网格软件中的兼容性相当捉鸡),然后用`gmsh`的`Open CASCADE`模块导入之,再继续在`gmsh`中操作。这样做在做单个零件网格划分的时候是没问题的,但做多物理体仿真的时候,这么搞有可能出现零件界面上网格点不对齐的问题,尤其是在具有复杂形状的零件界面上。 两周之前我就遇到了这个问题,纠结了一整天。开始时以为`gmsh`不过是在界面上用了两个*位置重合*的网格点来分别表示两个零件,还试图自己写网格导入器去重复来着。后来去重复功能写成了,但是只在部分区域有用,因为其他位置的网格点实在是完全没有对齐。 无奈之下,只好去官方的邮件列表里面提问,运气很好,当试有高手很闲,直接就给详细回复了,解决了问题。昨晚发现又有人在提问同样的问题,看来这个问题对于新手实在不是很友好,有必要把这个贴子专门记录一下。 > 我当时以为官方邮件列表是不能贴图的,所以邮件列表提问的同时在`stackoverflow`贴图提问了。下面直接把[`stackoverflow`的帖子](https://stackoverflow.com/questions/47095493/any-way-to-make-gmsh-to-use-the-same-vertex-set-on-both-sides-of-a-material-boun)贴下来。 # Any way to make gmsh to use the same vertex set on both sides of a material boundary? I am trying to mesh a complex geometry composed of 3 kinds of materials, like below: {{:ordinarysoftware:gmsh:a_sample_part.png?direct&600|你们猜这个是什么零件}} The geometry is imported from a *.stp file. I defined several physical surfaces and 3 physical domains in the geo file: ``` Physical Surface("air-case", 1) = {50, 42, 41, 40, 48}; Physical Surface("case-thermal", 2) = {32, 15, 22, 21, 25}; Physical Surface("thermal-grain", 3) = {2, 7, 6}; Physical Surface("thermal-fluid", 4) = {30, 27}; Physical Surface("burning", 5) = {3, 4, 5, 10, 13, 9, 11, 12}; Physical Surface("case-sym", 11) = {49, 51, 34, 43, 44, 47}; Physical Surface("thermal-sym", 12) = {24, 28, 14, 23, 29, 33}; Physical Surface("grain-sym", 13) = {8, 1}; Physical Volume("case", 1) = {6, 5, 7}; Physical Volume("thermal", 2) = {2, 3, 4}; Physical Volume("grain",3)={1}; ``` The picture looks ok at first glance. The vertices near material boundaries are well aligned, see enlarged views below: {{:ordinarysoftware:gmsh:a_sample_part_good_region.png?direct&600|好的区域}} However, inside the geometry (actually, near the middle of the cylinder part), you can find the vertice are not aligned: {{:ordinarysoftware:gmsh:a_sample_part_bad_region.png?direct&600|坏的区域}} It is weird because, on the boundary of the green and yellow material, all the vertice are aligned. Even though the output mesh contains duplicated points, I can easily remove duplicated ones according to the coordinate. I think this means gmsh does have the ability to ensure this. However, near the yellow/blue interface, vertice just randomly distributes on two sides, it is then impossible to connect the vertices without modifying the coordinates. I think there must be some way to ensure gmsh to use the same vertex on both sides of the interface, but I didn't find relevant information in the document. Any suggestions? # Answer OK, I've got the solution somewhere else. I am posting it here to help others who encountered the same issue. The problem is resulted by my modelling procedure. I modelled the geometry using Creo in separated parts and then exported the assembly. As a result, the *.stp file contains several geometries which are not topologically connected. To solve this, we need to merge the duplicated surfaces. There are two options: > You can use the new CAD features in Gmsh to remove these duplicate internal surfaces. With the stable release, you can do ``` SetFactory("OpenCASCADE"); v() = ShapeFromFile("file.step"); BooleanFragments{ Volume{v()}; Delete; }{} ``` > With the latest development snapshots, you can use the "Coherence" shortcut (which does exactly the same thing): ``` SetFactory("OpenCASCADE"); Merge "file.step"; Coherence; ``` The `Coherence` didn't work for my model, but `BooleanFragments` worked perfectly. Thank professor Geuzaine for offering help. # 总结 问题的原因出在`Creo`导出的装配体上(我相信其他CAD软件也是一样的,没时间测)。虽然画图的时候,几个零件的接触面是在一起的,但由于他们是不同的零件,所以导出时`Creo`并不会把这些贴在一起的面做合并——奇怪的是,`gmsh`的交互式选择GUI界面中并未区分这两个贴在一起的面,所以开始时我以为`Creo`或者`gmsh`做了自动合并。 所以,非常合乎逻辑地,`gmsh`把他俩当成了毫无关联的两个零件,给你对齐是情分,不给你对齐也完全合理。 希望官方赶紧把`Coherence`开发好吧,现在(2017年11月24日)这玩意儿还标着`实验性功能`呢,无效的话就只能先拿老办法顶着。 > PS:最近还发现了一个小问题:如果要使用`gmsh`中的`netgen`功能,系统`PATH`必须是可以访问到你安装的`netgen`可执行文件了,否则可能使得(起码在windows下是)`gmsh`会不报错直接崩溃。