メッシュ生成ソフトウェアGmshの使い方

Gmsh

更新

  • 2022/07/14, 下記の例題のgeoファイルの修正と、画面キャプチャや説明の追加を行いました。

Gmshとは

  • フリーのメッシュ生成ソフトウェア
  • Gmshのホームページ, https://gmsh.info/

準備

Windowsの場合

  • gmshダウンロードページからWindows版をダウンロードして解凍すればGUIで使える。
  • WSL(Windows Subsystem for Linux)を入れればLinux同様CUIでも使える。

Macの場合

Linuxの場合

  • gmshダウンロードページからLinux版をダウンロードして解凍すればGUIで使える。
  • 以下のコマンドでインストールし、CUIで使える。
$ sudo apt update
$ sudo apt install gmsh

今回GUIで使用したバージョンは以下の画像の通り。 png

使い方

  • 基本的にGUIで操作をし、大規模なメッシュを切る場合だけメモリの関係で重くなるのでメッシュを切る計算をCUIで行うのがおすすめ。
  • GUIで操作をするとスクリプトに自動的に操作が書き込まれていく。
  • 似たような操作や細かい変更はスクリプトを直接書き換えるのが楽。
  • スクリプトはプログラムのように変数を定義できる。

コマンド

  • Point : {x座標, y座標, z座標, 点付近のメッシュサイズ}
  • Line : {点番号, 点番号}
  • Loop : {点番号, …} Surfaceを作るのに必要
  • Surface : {Loop番号}
  • Loop : {Surface番号, …} Volumeを作るのに必要
  • Volume : {Loop番号}
  • Transinite : 一辺のメッシュサイズを決める
  • Physical : LineやVolumeに名前を付ける. 境界条件の設定に役立つ

スクリプトの例

例1. 2次元の正方領域を構造格子で切る

len = 1.0;
Point(1) = {0, 0, 0, 1.0};
Point(2) = {len, 0, 0, 1.0};
Point(3) = {len, len, 0, 1.0};
Point(4) = {0, len, 0, 1.0};
Line(1) = {1, 2};
Line(2) = {2, 3};
Line(3) = {3, 4};
Line(4) = {4, 1};
Curve Loop(1) = {1, 2, 3, 4};
Surface(1) = {1};
Transfinite Line "*" = 21 Using Bump 1.0;
Transfinite Surface "*";
Physical Curve("movingWall") = {3};
Physical Curve("wall") = {4, 1, 2};
Physical Surface("fluid") = {1};
  • 最後の三行のPhysical CurveとPhysical SurfaceはCurve(=Line)とSurfaceに対して("")内の名前のラベルを付ける。これによってメッシュをmshファイルで出力した場合にも辺や面に名前が付いており、識別して変換しやすくなる。

操作手順

  1. 上記のスクリプトをファイルに書き込む(File>Newで拡張子が.geoの新しいファイルを作成し、Modules>Geometry>Edit Scriptで編集できる。もしくは別でファイルを用意し、File>Openで読み込む。)
  2. Modules>Geometry>Reload script
  3. 以下の2点をOptions>Meshから変更する
    1. “Recombine all triangular meshs"にチェックを入れる
    2. “Subdivision Algorithm"を"All Quads"にする
  4. Modules>Mesh>Define>2D

上記手順で以下のメッシュが作成される。 png

  • 上記の手順3がない状態で2Dを押すと以下のように三角形で分割される png

例2. 2次元の円を四辺形要素で綺麗に切る

Point(1) = {7.14644660941, 3.64644660941, 0, 1.0};
Point(2) = {7.14644660941, 4.35355339059, 0, 1.0};
Point(3) = {7.85355339059, 4.35355339059, 0, 1.0};
Point(4) = {7.85355339059, 3.64644660941, 0, 1.0};
Point(5) = {7.35, 3.85, 0, 1.0};
Point(6) = {7.35, 4.15, 0, 1.0};
Point(7) = {7.65, 4.15, 0, 1.0};
Point(8) = {7.65, 3.85, 0, 1.0};
Point(9) = {7.5, 4.0, 0, 1.0};
Line(1) = {6, 7};
Line(2) = {7, 8};
Line(3) = {8, 5};
Line(4) = {5, 6};
Circle(5) = {2, 9, 3};
Circle(6) = {3, 9, 4};
Circle(7) = {4, 9, 1};
Circle(8) = {1, 9, 2};
Line(9) = {2, 6};
Line(10) = {3, 7};
Line(11) = {4, 8};
Line(12) = {1, 5};
Recursive Delete {
  Point{9}; 
}//+
Curve Loop(1) = {3, 4, 1, 2};
Plane Surface(1) = {1};
Curve Loop(2) = {4, -9, -8, 12};
Plane Surface(2) = {2};
Curve Loop(3) = {1, -10, -5, 9};
Plane Surface(3) = {3};
Curve Loop(4) = {2, -11, -6, 10};
Plane Surface(4) = {4};
Curve Loop(5) = {3, -12, -7, 11};
Plane Surface(5) = {5};
Transfinite Surface {1} = {5, 8, 7, 6};
Transfinite Surface {2} = {1, 5, 6, 2};
Transfinite Surface {3} = {6, 7, 3, 2};
Transfinite Surface {4} = {7, 8, 4, 3};
Transfinite Surface {5} = {8, 5, 1, 4};
Transfinite Curve {8, 9, 12, 4, 5, 10, 1, 6, 11, 2, 3, 7} = 25 Using Progression 1;
Recombine Surface {2, 3, 4, 5, 1};

操作手順

  1. 上記のスクリプトをファイルに書き込む(File>Newで拡張子が.geoの新しいファイルを作成し、Modules>Geometry>Edit Scriptで編集できる。もしくは別でファイルを用意し、File>Openで読み込む。)
  2. Modules>Geometry>Reload script
  3. Modules>Mesh>Define>2D

上記手順で以下のメッシュが作成される。

※今回は、最後の行に"Recombine Surface"が入っているため、Optionの"Recombine all triangular meshs"へのチェックと、Subdivision Algorithmが"All Quads"になっていなくても四辺形要素で作られる。

png

例3. 3次元の立方体領域を構造格子で切る

Point(1) = {0, 0, 0, 1.0};
Point(2) = {1, 0, 0, 1.0};
Point(3) = {1, 1, 0, 1.0};
Point(4) = {0, 1, 0, 1.0};
Point(5) = {0, 0, 1, 1.0};
Point(6) = {1, 0, 1, 1.0};
Point(7) = {1, 1, 1, 1.0};
Point(8) = {0, 1, 1, 1.0};
Point(9) = {1, 1, 1, 1.0};
Line(1) = {1, 2};
Line(2) = {2, 3};
Line(3) = {3, 4};
Line(4) = {4, 1};
Line(5) = {1, 5};
Line(6) = {2, 6};
Line(7) = {3, 7};
Line(8) = {4, 8};
Line(9) = {8, 7};
Line(10) = {7, 6};
Line(11) = {6, 5};
Line(12) = {5, 8};
Line Loop(1) = {1, 2, 3, 4};
Surface(1) = {1};
Line Loop(3) = {3, 8, 9, -7};
Surface(2) = {3};
Line Loop(5) = {4, 5, 12, -8};
Surface(3) = {5};
Line Loop(7) = {7, 10, -6, 2};
Surface(4) = {7};
Line Loop(9) = {1, 6, 11, -5};
Surface(5) = {9};
Line Loop(11) = {9, 10, 11, 12};
Surface(6) = {11};
Surface Loop(1) = {6, 2, 4, 5, 1, 3};
Volume(1) = {1};
Transfinite Line "*" = 21 Using Bump 1.0;
Transfinite Surface "*";
Transfinite Volume "*";
Physical Surface("movingWall") = {6};
Physical Surface("wall") = {1, 2, 3, 4, 5};
Physical Volume("fluid") = {1};

操作手順

  1. 上記のスクリプトをファイルに書き込む(File>Newで拡張子が.geoの新しいファイルを作成し、Modules>Geometry>Edit Scriptで編集できる。もしくは別でファイルを用意し、File>Openで読み込む。)
  2. Modules>Geometry>Reload script
  3. 以下をOptions>Meshから変更する
    1. “Recombine all triangular meshs"にチェックを入れる(六面体の場合) / チェックを外す(四面体の場合)
  4. Modules>Mesh>Define>3D

上記手順で以下のメッシュが作成される。 png png

例4. 3次元の球

rad = 1.0;
Point(1) = {0, 0, 0, 1};
Point(2) = {rad, 0, 0, 1};
Point(3) = {-rad, 0, 0, 1};
Point(4) = {0, rad, 0, 1};
Point(5) = {0, -rad, 0, 1};
Point(6) = {0, 0, rad, 1};
Point(7) = {0, 0, -rad, 1};
Circle(1) = {2, 1, 4};
Circle(2) = {4, 1, 3};
Circle(3) = {3, 1, 5};
Circle(4) = {5, 1, 2};
Circle(5) = {2, 1, 6};
Circle(6) = {6, 1, 3};
Circle(7) = {3, 1, 7};
Circle(8) = {7, 1, 2};
Circle(9) = {4, 1, 6};
Circle(10) = {6, 1, 5};
Circle(11) = {5, 1, 7};
Circle(12) = {7, 1, 4};
Line Loop(14) = {2, 7, 12};
Ruled Surface(14) = {14};
Line Loop(16) = {2, -6, -9};
Ruled Surface(16) = {16};
Line Loop(18) = {3, -10, 6};
Ruled Surface(18) = {18};
Line Loop(20) = {3, 11, -7};
Ruled Surface(20) = {20};
Line Loop(22) = {4, -8, -11};
Ruled Surface(22) = {22};
Line Loop(24) = {4, 5, 10};
Ruled Surface(24) = {24};
Line Loop(26) = {1, 9, -5};
Ruled Surface(26) = {26};
Line Loop(28) = {1, -12, 8};
Ruled Surface(28) = {28};
Surface Loop(30) = {14, 16, 18, 20, 22, 24, 26, 28};
Volume(30) = {30};//+
Translate {0, 0, 12.75} {
  Line{4}; Point{6}; Point{4}; Point{2}; Point{1}; Point{3}; Point{5}; Point{7}; Line{9}; Line{1}; Line{5}; Line{2}; Line{6}; Line{10}; Line{3}; Line{12}; Line{8}; Line{7}; Line{11}; Surface{26}; Surface{24}; Surface{16}; Surface{18}; Surface{28}; Surface{14}; Surface{20}; Surface{22}; Volume{30}; 
}

操作手順

  1. 上記のスクリプトをファイルに書き込む(File>Newで拡張子が.geoの新しいファイルを作成し、Modules>Geometry>Edit Scriptで編集できる。もしくは別でファイルを用意し、File>Openで読み込む。)
  2. Modules>Geometry>Reload script
  3. 以下をOptions>Meshから変更する
    1. “Recombine all triangular meshs"のチェックを外す
  4. Modules>Mesh>Define>3D

上記手順で以下のメッシュが作成される。 ※OptionのMin Max Element Sizeを書き換えている png

おまけ:ハートを切る

import math

f = open("heart.geo", "w")
f.write("SetFactory(\"OpenCASCADE\");\n")
idx = 1

for i in range(50):
  t = 2 * math.pi * i / 50
  x = 16 * math.sin(t) * math.sin(t) * math.sin(t)
  y = 13 * math.cos(t) - 5 * math.cos(2*t) - 2 * math.cos(3*t) - math.cos(4*t)
  f.write("Point("+str(idx)+") = {"+str(x)+", "+str(y)+", 0, 1.0};\n")
  idx += 1

for i in range(49):
  f.write("Line("+str(i+1)+") = {"+str(i+1)+", "+str(i+2)+"};\n")
f.write("Line("+str(50)+") = {"+str(50)+", "+str(1)+"};\n")
f.write("Curve Loop(1) = {")
for i in range(50):
  f.write(str(i+1))
  if i != 49:
    f.write(", ")
f.write("};\n")
f.write("Plane Surface(1) = {1};\n")
f.close()

操作手順

  1. 上記のpythonスクリプトでheart.geoを出力する
  2. geoファイルからメッシュを切る

上記手順で以下のメッシュが作成される。 png

メッシュファイルの出力

GUIの場合

  • Modules>Mesh>2D/3Dでメッシュを分割した後、File>exportでファイル出力する。出力形式は.mshがおすすめ。

CUIの場合

  • $ gmsh -3 hoge.geo -format msh2 -o fuga.mshのコマンドで.mshファイルが生成される。

mshファイルをソルバーの入力ファイル形式に合わせる

mshファイルの読み方は[1]を参考にし、変換プログラムを自作してソルバーの入力ファイルの形式に合わせる。

注意点

  • GUIの最新バージョンgmsh ver4にあるCurve LoopはCUIのgmsh ver3にはないため、Line Loopに書き換える必要がある
  • 構造格子と非構造格子を組み合わせて切るのがうまくいかない場合がある
    • バージョン4では切れない場合にエラーが出ないで誤ったmshを出力する場合がある。バージョン3では切れない場合にアルゴリズムをfrontal等に変更することを提案するメッセージが出るがどっちにしてもうまく切れない。

参考文献

[1] Qiita記事 自作ソルバにGmshを! 日本語で詳しく書かれている

[2] Mesh refinementの動画 https://www.youtube.com/watch?v=kpWVNNHHdd8 メッシュの一部を細かく切る方法

[3] Transfiniteの動画 https://www.youtube.com/watch?v=O1FyiBBuN98&t=253s メッシュのサイズを指定する方法

[4] Hopscotch Building hexagonal meshes with Gmsh

川上幸亮
川上幸亮

エンジニアとして働いています。