pythonOCC による OpenFOAM 用モデルの作成

2011年4月29日

はじめに

pythonOCC で OpenFOAM 用モデルを作成する。

使用バージョン

pythonOCC 0.5/Python 2.6 Windows 版、OpenFOAM 1.7.x Windows 64 bit 版。

作成するモデル

ミキシングエルボー

スクリプト

# create mixing elbow model

from OCC.Display.SimpleGui import *
from OCC.BRepPrimAPI import *
from OCC.gp import *
from OCC.BRepBuilderAPI import *
from OCC.BRepSweep import *
from OCC.BRepAlgoAPI import *
from OCC.Utils.DataExchange.STL import *
from math import *


# window
display, start_display, add_menu, add_function_to_menu = init_display()


# origin
origin = BRepBuilderAPI_MakeVertex(gp_Pnt(0., 0., 0.)).Vertex()


#
# left cylinder
#

# create a cylinder
cylinder1 = BRepPrimAPI_MakeCylinder(5., 30.).Shape()

trsf = gp_Trsf()

# rotate the cylinder
ax = gp_Ax1(gp_Pnt(0., 0., 0.), gp_Dir(gp_Vec(0., 1., 0.)))
trsf.SetRotation(ax, 90./180.*pi)
cylinder1 = BRepBuilderAPI_Transform(cylinder1, trsf).Shape()


#
# elbow
#

# create a face from a circle
ax = gp_Ax2(gp_Pnt(30., 0., 0.), gp_Dir(gp_Vec(1., 0., 0.)))
circle = gp_Circ(ax, 5.)
circle = BRepBuilderAPI_MakeEdge(circle).Edge()
circle = BRepBuilderAPI_MakeWire(circle).Wire()
circle = BRepBuilderAPI_MakeFace(circle).Face()

# create a volume to revolve the face
ax = gp_Ax1(gp_Pnt(30., 0., 15.), gp_Dir(gp_Vec(0., -1., 0.)))
elbow = BRepSweep_Revol(circle, ax, 90./180.*pi).Shape()


#
# right cylinder
#

# create a cylinder
cylinder2 = BRepPrimAPI_MakeCylinder(5., 30.).Shape()

# translate the cylinder
trsf.SetTranslation(gp_Vec(45., 0., 15.))
cylinder2 = BRepBuilderAPI_Transform(cylinder2, trsf).Shape()


#
# small cylinder
#
cylinder3 = BRepPrimAPI_MakeCylinder(2.5, 15.).Shape()

# rotate the cylinder to adjust it's direction
ax = gp_Ax1(gp_Pnt(0., 0., 7.5), gp_Dir(gp_Vec(0., -1., 0.)))
trsf.SetRotation(ax, 45./180.*pi)
cylinder3 = BRepBuilderAPI_Transform(cylinder3, trsf).Shape()

# translate the cylinder
trsf.SetTranslation(gp_Vec(50., 0., 15. - 10.))
cylinder3 = BRepBuilderAPI_Transform(cylinder3, trsf).Shape()

# rotate the cylinder
ax = gp_Ax1(gp_Pnt(30., 0., 15.), gp_Dir(gp_Vec(0., -1., 0.)))
trsf.SetRotation(ax, -45./180.*pi)
cylinder3 = BRepBuilderAPI_Transform(cylinder3, trsf).Shape()


# unite
shape = BRepAlgoAPI_Fuse(cylinder1, elbow).Shape()
shape = BRepAlgoAPI_Fuse(shape, cylinder2).Shape()
shape = BRepAlgoAPI_Fuse(shape, cylinder3).Shape()


# export STL file
filename = 'mixing_elbow.stl'
fp = open(filename, 'w')
fp.close()

e = STLExporter(filename=filename)
e.set_shape(shape)
e.write_file()


# set display shapes
display.DisplayShape(origin)
display.DisplayShape(shape)

# display the window
start_display()

実行結果

ParaView による STL ファイルの表示

解説

ミキシングエルボー形状を作成し、STL ファイルを書き出す。形状の作成は、円筒部分と曲がり部分をそれぞれ作り、最後に合体させる。

# window
display, start_display, add_menu, add_function_to_menu = init_display()

ウインドウの作成。

# origin
origin = BRepBuilderAPI_MakeVertex(gp_Pnt(0., 0., 0.)).Vertex()

参考のために原点を作成。

#
# left cylinder
#

# create a cylinder
cylinder1 = BRepPrimAPI_MakeCylinder(5., 30.).Shape()

trsf = gp_Trsf()

# rotate the cylinder
ax = gp_Ax1(gp_Pnt(0., 0., 0.), gp_Dir(gp_Vec(0., 1., 0.)))
trsf.SetRotation(ax, 90./180.*pi)
cylinder1 = BRepBuilderAPI_Transform(cylinder1, trsf).Shape()

左の円筒。BRepPrimAPI_MakeCylinder() で円筒を作り、それを gp_Trsf の SetRotation() で回転設定、BRepBuilderAPI_Transform() でその回転を実行している。円筒は縦にできるので、それを横に寝せている。

#
# elbow
#

# create a face from a circle
ax = gp_Ax2(gp_Pnt(30., 0., 0.), gp_Dir(gp_Vec(1., 0., 0.)))
circle = gp_Circ(ax, 5.)
circle = BRepBuilderAPI_MakeEdge(circle).Edge()
circle = BRepBuilderAPI_MakeWire(circle).Wire()
circle = BRepBuilderAPI_MakeFace(circle).Face()

# create a volume to revolve the face
ax = gp_Ax1(gp_Pnt(30., 0., 15.), gp_Dir(gp_Vec(0., -1., 0.)))
elbow = BRepSweep_Revol(circle, ax, 90./180.*pi).Shape()

曲がり部分。gp_Circ() で円を作り、BRepBuilderAPI_MakeEdge() でエッジ、BRepBuilderAPI_MakeWire() でワイヤー、BRepBuilderAPI_MakeFace() で面を作っている。その面を BRepSweep_Revol() で回転させてボリュームを作る。

#
# right cylinder
#

# create a cylinder
cylinder2 = BRepPrimAPI_MakeCylinder(5., 30.).Shape()

# translate the cylinder
trsf.SetTranslation(gp_Vec(45., 0., 15.))
cylinder2 = BRepBuilderAPI_Transform(cylinder2, trsf).Shape()

右上の円筒。円筒を作り、それを平行移動させている。

#
# small cylinder
#
cylinder3 = BRepPrimAPI_MakeCylinder(2.5, 15.).Shape()

# rotate the cylinder to adjust it's direction
ax = gp_Ax1(gp_Pnt(0., 0., 7.5), gp_Dir(gp_Vec(0., -1., 0.)))
trsf.SetRotation(ax, 45./180.*pi)
cylinder3 = BRepBuilderAPI_Transform(cylinder3, trsf).Shape()

# translate the cylinder
trsf.SetTranslation(gp_Vec(50., 0., 15. - 10.))
cylinder3 = BRepBuilderAPI_Transform(cylinder3, trsf).Shape()

# rotate the cylinder
ax = gp_Ax1(gp_Pnt(30., 0., 15.), gp_Dir(gp_Vec(0., -1., 0.)))
trsf.SetRotation(ax, -45./180.*pi)
cylinder3 = BRepBuilderAPI_Transform(cylinder3, trsf).Shape()

下の細い円筒。円筒を曲がりの右上に位置させて回転させるのだが、それだと向きが変わるので、前もって逆回転させている。

# unite
shape = BRepAlgoAPI_Fuse(cylinder1, elbow).Shape()
shape = BRepAlgoAPI_Fuse(shape, cylinder2).Shape()
shape = BRepAlgoAPI_Fuse(shape, cylinder3).Shape()

合体。

# export STL file
filename = 'mixing_elbow.stl'
fp = open(filename, 'w')
fp.close()

e = STLExporter(filename=filename)
e.set_shape(shape)
e.write_file()

STL ファイルのエクスポート。あらかじめファイルがないと書き込めないようで、はじめに空ファイルを作っている。

# set display shapes
display.DisplayShape(origin)
display.DisplayShape(shape)

# display the window
start_display()

表示させる形状の指定と、ウインドウの表示。

メッシュの作成

Netgen でメッシュを作成。

計算

icoFoam で計算確認。