目的
研究で実装したFEMモデルの精度を保証する為,ANSYSのMAPDLでの結果と比較する必要があった.
そこで,MAPDLの計算をpythonでのパッケージpymapdlを用いて自動化させた.その時の技術を備忘録としてまとめていく.
参考文献
pymapdl
pymapdlは,ANSYSが提供するMAPDLを,pythonを用いて実行することが出来るパッケージ.
インストール方法
pipを利用する場合は以下の通り.
pip install ansys-mapdl-core
APDLの起動方法
ANSYSが既にインストールされているPCにおいて起動するにはlaunch_mapdlを利用する.
from ansys.mapdl.core import launch_mapdl
mapdl = launch_mapdl()
print(mapdl)
正常にインストール出来ているのであれば,ANSYSのパスなどは入力せずとも起動できる.
成功した場合,次のように返してくる.
Product: ANSYS Mechanical Enterprise
MAPDL Version: RELEASE 2020 R2 BUILD 20.2TEST UPDATE 20200601
ansys.mapdl.core Version: 0.57.0
もし,ANSYSのパスを正常に認識できていない場合,次のようにパスを指定することで起動できるようになる.
from ansys.mapdl import core as pymapdl
new_path = 'C:\\Program Files\\ANSYS Inc\\v211\\ANSYS\\bin\\winx64\\ansys211.exe'
pymapdl.change_default_ansys_path(new_path)
また,リモートPCにあるANSYSを利用する場合,次のように使用するポート,そして対象のIPアドレスを入力すれば出来るとのこと(これは試していない).
from ansys.mapdl.core import Mapdl
ip = '127.0.0.1'
mapdl = Mapdl(ip=ip, port=50052, request_instance=False)
print(mapdl)
基本的な使用方法
MAPDLにおけるコマンドを,pymapdlでは次のように二つの方法で利用する方法がある.
一つ目の方法はMAPDLのコマンドを*mapdl.run()*を使ってそのまま利用する方法だ.
mapdl.run('/PREP7')
mapdl.run('K, 1, 0, 0, 0')
mapdl.run('K, 2, 1, 0, 0')
mapdl.run('K, 3, 1, 1, 0')
mapdl.run('K, 4, 0, 1, 0')
mapdl.run('L, 1, 2')
mapdl.run('L, 2, 3')
mapdl.run('L, 3, 4')
mapdl.run('L, 4, 1')
mapdl.run('AL, 1, 2, 3, 4')
もう一つの方法は,mapdlに付属するモジュールを利用する方法だ.
mapdl.prep7()
# 節点部分の設定
mapdl.k(1, 0, 0)
mapdl.k(2, 5, 0)
mapdl.k(3, 5, 5)
# エッジ部分の設定
mapdl.l(1, 2, 1)
mapdl.l(2, 3, 1)
どちらでも良さそう.もしAPDLの方で既にコマンドを用意しているならば,一つ目の方法が楽そう.
終了方法
以下のコマンドを入力する.
mapdl.exit()
単純にmapdl.finish()やmapdl.clear()を利用した場合,裏のプロセスにおいてMAPDLが残り続ける.
この状態で,新しくlaunch_mapdlを利用した場合,ローカルの新しいポート番号に処理が割り当てられる(launch_apdlのドキュメント).
この状態を繰り返した場合,次のように開放済でないポート番号を利用してエラーを吐く恐れがある為,注意してほしい.
OSError: Unable to connect to MAPDL gRPC instance at 127.0.0.1:50062
条件を変えて解析を実行させるコード例
ベルヌーイ・オイラー梁を利用した解析を行う場合
#nodes_pos:節点のx,y位置(np.array,(n,2))
#edges_indices:梁の節点組み合わせ(np.array,(n,2))
#edges_thickness:梁の太さ(np.array,(n))
#frozen_nodes:固定ノード(list,(m))
#input_nodes:入力ノード(list,(z))
#input_vectors:入力x,yベクトル(np.array,(n,2))
for i in range(10):
nodes_pos, edges_indices, edges_thickness,\
input_nodes, input_vectors, frozen_nodes = \
make_random_fem_condition_with_continuous_graph() # カスタムのランダムFEM条件生成関数
# APDLの設定
mapdl = launch_mapdl()
mapdl.finish()
mapdl.clear()
mapdl.prep7()
# 材料物性値の設定
mapdl.et(1, 3)
mapdl.mp("ex", 1, 1) # ヤング率
mapdl.mp("prxy", 1, 0.3) # ポアソン比
mapdl.mat(1)
# 節点部分の設定
for i, node_pos in enumerate(nodes_pos):
mapdl.n(i + 1, node_pos[0], node_pos[1], 0)
# エッジ部分の設定
for i, edges_indice in enumerate(edges_indices):
h = edges_thickness[i]
mapdl.r(i + 1, h, (h * h**2) / 12, h, 0) # A,I,height=y_length,SHEARZ
mapdl.real(i + 1)
mapdl.e(edges_indice[0] + 1, edges_indice[1] + 1)
mapdl.finish()
mapdl.run('/solu')
# 解析条件設定
mapdl.antype('static')
# 固定ノード設定
for i in frozen_nodes:
mapdl.d(i + 1, "all", 0)
# 外力設定
for i, input_vector in enumerate(input_vectors):
mapdl.f(input_nodes[i] + 1, "FX", input_vector[0])
mapdl.f(input_nodes[i] + 1, "FY", input_vector[1])
# 解析開始
mapdl.solve()
mapdl.finish()
# 結果出力
x_disp = mapdl.post_processing.nodal_displacement('X')
y_disp = mapdl.post_processing.nodal_displacement('Y')
z_rot = mapdl.post_processing.nodal_rotation('Z')
ansys_disp = np.stack([x_disp, y_disp, z_rot]).T.flatten()
print(ansys_disp)
mapdl.exit() # ポート番号などをリセットするために必要