PyGEM
- Python Geometrical Morphing.
- 1400万格子でも大丈夫!らしい
- MITライセンス
- ちょっとしたGUIもある
pip show PyGEM
Name: pygem
Version: 0.2
Summary: Tools to apply FFD.
Home-page: https://github.com/mathLab/PyGeM
Author: Filippo Salmoiraghi, Marco Tezzele
Author-email: filippo.salmoiraghi@gmail.com, marcotez@gmail.com
License: MIT
Location: /home/ubuntu/.pyenv/versions/anaconda3-4.3.1/envs/py35/lib/python3.5/site-packages
Requires: numpy, numpy-stl, scipy, matplotlib, enum34, Sphinx, sphinx-rtd-theme
Python3系利用する場合は2to3を使う
メッシュモーフィングの準備
OpenFOAMのCavityケースでメッシュモーフィングを行う
blockMeshコマンドを実行後、boundingBoxを見る
blockMesh| grep boundingBox
boundingBox: (0 0 0) (0.1 0.1 0.01)
格子点データをコピーしておく。
import shutil
from PyFoam.IPythonHelpers.Case import Case
case = Case("../cavity")
org_points_path = case.sol.polyMeshDir()+"/points_org"
points_path = case.sol.polyMeshDir()+"/points"
shutil.move(points_path, org_points_path)
boundingBoxを定義する
格子点が完全にコントロールボックス内に入るように少し大きめのコントロールボックスにする。
import numpy as np
import pygem as pg
import pygem.affine as at
params = pg.params.FFDParameters()
e = 1.0e-6
params.rot_angle = np.array([0,0,0])
params.lenght_box =np.array([0.1,0.1,0.01]) + e
params.origin_box = np.array([0.,0.,0.]) -e
params.rotation_matrix = at.angles2matrix(
params.rot_angle[2] * np.pi / 180,
params.rot_angle[1] * np.pi / 180,
params.rot_angle[0] * np.pi / 180)
params.position_vertex_0 = params.origin_box
params.position_vertex_1 = params.position_vertex_0 + np.dot(params.rotation_matrix, [params.lenght_box[0], 0, 0])
params.position_vertex_2 = params.position_vertex_0 + np.dot(params.rotation_matrix, [0, params.lenght_box[1], 0])
params.position_vertex_3 = params.position_vertex_0 + np.dot(params.rotation_matrix, [0, 0, params.lenght_box[2]])
params.psi_mapping = np.diag(1. / params.lenght_box)
params.inv_psi_mapping = np.diag(params.lenght_box)
ワカメに変形するように設定する
- 正方形をy方向に均等に延ばす
- y方向高さに応じてx方向にコントロールポイントを移動
コントロールポイントと変形量をparamsに追加する
params.n_control_points=np.array([2,5,2])
params.array_mu_x = np.zeros(params.n_control_points.cumprod()[-1]).reshape(params.n_control_points)
params.array_mu_y = np.zeros(params.n_control_points.cumprod()[-1]).reshape(params.n_control_points)
params.array_mu_z = np.zeros(params.n_control_points.cumprod()[-1]).reshape(params.n_control_points)
params.array_mu_y[:,0,:] = 0
params.array_mu_y[:,1,:] = 1
params.array_mu_y[:,2,:] = 2
params.array_mu_y[:,3,:] = 3
params.array_mu_y[:,4,:] = 4
params.array_mu_x[:,0,:] = 0.
params.array_mu_x[:,1,:] = -1.
params.array_mu_x[:,2,:] = 0.
params.array_mu_x[:,3,:] = 1.
params.array_mu_x[:,4,:] = 0.
ワカメにする
格子点を書きこむ(元のファイルを上書きするような破壊的な使い方はできない)
of_handler = pg.openfhandler.OpenFoamHandler()
points = of_handler.parse(org_points_path)
free_form = pg.freeform.FFD(params, points)
free_form.perform()
new_points = free_form.modified_mesh_points
of_handler.write(new_points, points_path)