Python 複数のCADファイル(.step)をメッシュファイルへCUIで自動生成する「Netgen」

'22/05/21更新:複数のソリッド領域があって、それらが接合している場合に2重節点の防止を選択できるように雛形コードに追記した。
 FEMなどのシミュレーションで使用するメッシュ生成ツールのひとつにオープンソースのアプリケーション「Netgen」があります。
 本記事では、その「Netgen」のPythonライブラリ「ngsolve」を用いて、CADファイルの汎用形式(.step)に対してメッシュ分割するPythonの雛形コードを載せました。出力するメッシュ形式は、Gmshフォーマット(.msh)と市販のFEMソフトAbaqusフォーマット(.inp)です。WindowsLinuxUbuntu, 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

# CADファイル(.step)のあるフォルダをリストで抽出
cadfile_list = glob.glob(r'./CAD_stepfiles/*.step')
print('cadfile_list', cadfile_list)

# 出力先フォルダ
out_dirpath = './FEM_inpfiles'

# 領域間の重複する線や面を削除する場合:True しない場合:False
is_fragment = True

# 1次要素(C3D4)の場合はFalse。2次要素(C3D10)の場合はTrue
element_type_C3D10 = False

# メッシュ分割のパラメータ変数
mesh_size_max_list = [3, 20]
grading = 0.15
segmentsperedge = 5
curvaturesafety = 3

# メッシュ分割の設定をリストで設定
mesh_quality_list = [
#'very_coarse',
#'coarse',
'moderate',
#'fine',
'very_fine',
'user_define1_grading',
'user_define2_segment',
#'user_define3_meshingstep',
]

# CADファイルからメッシュファイルを生成する
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:
        # CADファイル(.step)を読み込み
        geo = OCCGeometry(cadfile)
        print('geo', geo)
        
        # 異種材料界面を接着する(2重節点を防止したい場合)
        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')
                

            # 10節点四面体要素にしたい場合
            if element_type_C3D10:
                mesh.SecondOrder()

            # メッシュファイルをAbaqusとgmshフォーマット(書式)で出力
            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

以上

<広告>