GmshでCompound Surfaceを使う

Gmsh 2.5.0の新機能、 Compound Surfaceを使う方法についてのメモです。

Compound Surfaceとは

Compound Surfaceを直訳すると「合成表面」といった感じでしょうか。 複数の面をmesh作成時に大きな1枚の面として扱うという機能です。

例がないとピンとこないと思いますので、下のnutの図で説明します。 左がCompound Surfaceなしの場合で、 大抵のFEM mesherではこの様な振る舞いが一般的です。 面の境界(図の青線)に要素境界が来るように分割され、 面と面をまたぐような要素は作られません。
それに対して右のCompound Surfaceを使った場合は、 要素境界は必ずしも面の構成とは一致せず、 面をまたぐ要素が作成されます。 Compound Surfaceあり/なしの差は側面がわかりやすく、 小さなfilletに対して要素が作成されなくなります。 また、上面もよく見ると元の面構成と異なる要素分割が行われています。
最初に述べたように、Compound Surfaceを使うと大きな 1枚の面として扱われるため、個々の面の境界は無視されます。

見ての通り、Compound Surfaceを使うと形状再現は悪くなります。 しかし、Filletなどの細かな形状に対して要素を作らなくなりますので、 要素数、節点数を削減することができます。 注目する部分ではなく大雑把にmeshを作れれば良いという場合には便利な機能です。

[Without Compound] [With Compound]
(左: Compound Surfaceなし / 右: Compound Surfaceあり)

使い方

使い方は単純で、Compound Surfaceでまとめたい面を指定するだけです。 上の図をclickするとGmshの入力fileを見れますので、Compoud Surface あり/なしで比較すると割とすぐに理解できると思います(違いは最後の数行だけです)。
図のnutの例では、上面の6枚の面をCompound Surface(60)に、 下面をCompound Surface(61)に、側面をfillet共々Compound Surface(61)に まとめています。 Volumeを作成する時に、個別の面を指定する代わりに Compound Surfaceを指定するようにすれば上図のような要素が作成されます。

...
Compound Surface(60) = { 12:17 }; // top face
Compound Surface(61) = { 18:23 }; // bottom face
Compound Surface(62) = { 24:59 }; // side with fillets
Surface Loop(1) = { 6:11, 60, 61, 62 };
Volume(1) = {1};
Physical Volume("all") = {1};

注意1 - 面番号

Compound Surfaceの面番号は、Compound Surfaceを構成する個々の面の番号よりも 大きな値にしないとうまく動かないようです。例えば以下のような例はNGになります。 (もしかしたら2.5.0のbugでそのうち改善されるかもしれませんが。)

...
Ruled Surface(10) = {10};
Ruled Surface(11) = {11};
Plane Surface(12) = {12};
Compound Surface(1) = { 10, 11, 12 }; // これはNG
// Compound Surface(13) = { 10, 11, 12 }; // これならok

注意2 - Physical Surface | Volume

Compound Surfaceを作成した場合は、元のバラバラな複数の面と Compound Surfaceの両方が存在する状態になります。 このままmesh作成すると、両方の面に対してそれぞれ要素が作成されてしまい 要素が二重にできてしまいます。
これを防ぐために、必ずCompound Surfaceに対してPhysical Surfaceか Physical Volumeの指定を行ってください。 Pyshicalを指定すると、指定したものだけが出力されるようになり、 元のバラバラな複数の面に対する要素は出力されなくなります。

STL Remesh

Compound Surfaceの便利な使い方として、STL Remeshへの適用があります。
STLは三角形の面だけで三次元形状を表す形式です。 IGESやSTEPなどのCAD用形式と比べると非常に簡単なため、 自作programから3D形状を出力する場合に便利です。 簡単な形式なのでとりあえずSTLで形状を作って、 そこからFEM modelを作成するということをやりたくなるわけですが、 実際にやろうとすると意外とうまくいかないものです。 うまくいかない原因としていろいろありますが、大きくは以下の2点でしょう。

要するに、STLの三角形分割を無視して要素を作ってくれれば良いわけで、 GmshのCompound Surfaceでなんとかできそうです。

実際の例 (STL形式の地形→FEM mesh)

実際にSTLからCompound Surfaceを使って要素作成した例を図示します。 国土地理院の標高データからSTL形式の地表面を作成し、 それをGmshでFEM用にの要素へと再分割しています。

[Island STL] [Island tetra mesh]
(左: STLによる地形 / 右: Gmshで作成した要素)
元のSTLは island.zip (1MB)。新潟県佐渡です。

右の画をclickするとGmshの入力を見ることができます。 要素の粗密をつけるためにFieldなどを使っていますが、 STL Remeshに関する部分は以下になります。

Mesh.RemeshParametrization=0;
Mesh.RemeshAlgorithm=1;

Merge "island_top.stl";
Merge "island_side.stl";
Merge "island_gnd.stl";
CreateTopology;

Compound Surface(4) = {1}; // All faces in island_top.stl
Compound Surface(5) = {2}; // All faces in island_side.stl
Compound Surface(6) = {3}; // All faces in island_gnd.stl

Surface Loop(7) = {4,5,6};
Volume(8) = {7};

Physical Surface ("top")  = {4};
Physical Surface ("side") = {5};
Physical Surface ("gnd")  = {6};
Physical Volume  ("all")  = {8};

RemeshAlgorithm=1 → Merge → CreateTopology → Compound Surface の順にやれば目的とするFEM用の要素を作ることができます。 順番を変えると動きませんのでこの通りにやってください。
3つのSTLに分割してあるのは個別に境界条件をつけるためです。 それぞれにPhysical Surfaceを指定してやれば、 ちゃんと要素が識別された状態で出力されます。 そのような必要がなければ、全部の面を1つのSTLに入れた状態でもremeshできます。 この場合、CreateTopology は不要のようです。


ご意見、ご感想は、花房 真広 <webmaster@hanabusa.net>まで。メールする前にtop pageの注意書を読んでください。