'22/05/21更新:複数のソリッド領域があって、それらが接合している場合に2重節点の防止を選択できるように雛形コードに追記した。
FEMなどのシミュレーションで使用するメッシュ生成ツールのひとつにオープンソースのアプリケーション「Netgen」があります。
本記事では、その「Netgen」のPythonライブラリ「ngsolve」を用いて、CADファイルの汎用形式(.step)に対してメッシュ分割するPythonの雛形コードを載せました。出力するメッシュ形式は、Gmshフォーマット(.msh)と市販のFEMソフトAbaqusフォーマット(.inp)です。WindowsとLinux(Ubuntu, RedHat)環境下で動作確認しています。
■ ライブラリのインストール方法
「Netgen」のPythonライブラリ「ngsolve」を次のようにpipで行います。
pip install ngsolve==6.2.2202
参考までに、本家のリンク先は下記です。アプリのNetgenを入れる場合には、注意が必要です。それは、netgen内のPythonと普段使用しているPythonが干渉しないようなパス設定に工夫が必要あり、個人的にはアプリのNetgenのインストールは推奨しません。
ngsolve.org
■以降で、本プログラムの実施例を示します
▼ CADファイル(.step)を準備する
下図は、CADソフト(オープンソースのFreeCAD)で作成した3次元構造です。4つの領域ソリッドで構成されたひとつのcomponent solidです。これを拡張子.stepのCADファイルで出力します。
▼ Netgenによるメッシュ分割
下図は、本プログラムを実行して、CADファイル(.step)からメッシュファイル(.inp, .msh)を生成した6つの例です。これらは、メッシュ設定が異なります。
■本プログラム
import os, glob
import time
from netgen.occ import *
from netgen.meshing import MeshingStep
cadfile_list = glob.glob(r'./CAD_stepfiles/*.step')
print('cadfile_list', cadfile_list)
out_dirpath = './FEM_inpfiles'
is_fragment = True
element_type_C3D10 = False
mesh_size_max_list = [3, 20]
grading = 0.15
segmentsperedge = 5
curvaturesafety = 3
mesh_quality_list = [
'moderate',
'very_fine',
'user_define1_grading',
'user_define2_segment',
]
for cadfile in cadfile_list:
file_name = os.path.basename(cadfile)
file_name, extension = os.path.splitext(file_name)
save_file_path = os.path.join(out_dirpath, file_name)
i = 0
for mesh_size_max in mesh_size_max_list:
geo = OCCGeometry(cadfile)
print('geo', geo)
if is_fragment:
geo.Glue()
for key in mesh_quality_list:
i += 1
print('processing ...', i, key)
if key == 'very_coarse':
mesh = geo.GenerateMesh(meshsize.moderate, maxh = mesh_size_max)
elif key == 'coarse':
mesh = geo.GenerateMesh(meshsize.coarse, maxh = mesh_size_max)
elif key == 'moderate':
mesh = geo.GenerateMesh(meshsize.moderate, maxh = mesh_size_max)
elif key == 'fine':
mesh = geo.GenerateMesh(meshsize.fine, maxh = mesh_size_max)
elif key == 'very_fine':
mesh = geo.GenerateMesh(meshsize.very_fine, maxh = mesh_size_max)
elif key == 'user_define1_grading':
mesh = geo.GenerateMesh(meshsize.coarse, maxh = mesh_size_max,
grading = grading)
elif key == 'user_define2_segment':
mesh = geo.GenerateMesh(meshsize.coarse, maxh = mesh_size_max,
segmentsperedge = segmentsperedge,
curvaturesafety = curvaturesafety)
elif key == 'user_define3_meshingstep':
mesh = geo.GenerateMesh(meshsize.coarse, maxh = mesh_size_max,
perfstepstart = MeshingStep.ANALYSE,
perfstepsend = MeshingStep.MESHVOLUME)
else:
print('check key of mesh_quality_dict')
if element_type_C3D10:
mesh.SecondOrder()
mesh.Export(f'{save_file_path}_{i}_{key}_hmax{mesh_size_max}.inp', "Abaqus Format")
mesh.Export(f'{save_file_path}_{i}_{key}_hmax{mesh_size_max}.msh', "Gmsh2 Format")
time.sleep(1)
del mesh
del geo
メッシングのパラメータ一覧は次の通りです。geo.GenerateMesh()内で指定します。その組み合わせを考えるとほぼ無限です。
Meshing parameters:
optimize3d = cmdmustm
optsteps3d = 3
optimize2d = smsmsmSmSmSm
optsteps2d = 3
opterrpow = 2
blockfill = 1
filldist = 0.1
safety = 5
relinnersafety = 3
uselocalh = 1
grading = 0.3
delaunay = 1
maxh = 1
meshsizefilename =
startinsurface = 0
checkoverlap = 1
checkchartboundary = 1
curvaturesafety = 2
segmentsperedge = 1
parthread = 0
elsizeweight = 0.2
giveuptol2d = 200
giveuptol = 10
maxoutersteps = 10
starshapeclass = 5
baseelnp = 0
sloppy = 1
badellimit = 175
secondorder = 0
elementorder = 1
quad = 0
inverttets = 0
inverttrigs = 0
以上
<広告>
リンク
リンク
リンク
リンク