エルボ配管内の流れ (流れ)

  • シミュレーション名: flow__in_a_curved_pipe_XYZ3D

シミュレーション体系

  • Navier-Stokes方程式

  • エルボの内径、外径はそれぞれ 160 mm, 200 mm ( 半径はそれぞれ 80 mm, 100 mm ).

  • エルボは直角 ( 90 deg )に、曲率半径は 1.0 m で曲がる.

  • 曲がり部分の両端に 1.0 m の直管部分がある.

  • 流入側の配管外側には、外径 300mm のヒーターを取り付けている(本問題には無関係).

メッシュ

  • メッシュ生成スクリプト ( mesh.py )

mesh.py ( flow__in_a_curved_pipe_XYZ3D )
import numpy as np
import os, sys
import gmsh

# ========================================================= #
# ===  make__geometry                                   === #
# ========================================================= #

def make__geometry( dimtags={} ):

    surfDim, voluDim = 2, 3
    
    # ------------------------------------------------- #
    # --- [1] parameter                             --- #
    # ------------------------------------------------- #
    radius_1    = 0.1
    radius_2    = 0.08
    radius_3    = 0.15
    heater_s    = 0.30
    heater_e    = 0.70
    angle       = 90.0 * np.pi/180.0
    
    # ------------------------------------------------- #
    # --- [2] design pipe1                          --- #
    # ------------------------------------------------- #
    cylinder_1s = gmsh.model.occ.addCylinder( 0,0,0, 1.0, 0,0, radius_1 )
    disk_1      = gmsh.model.occ.addDisk( 1,0,0, radius_1, radius_1 )
    rotate      = gmsh.model.occ.rotate( [(surfDim,disk_1)], 1,0,0, 0,1,0, angle )
    revolve_1   = gmsh.model.occ.revolve( [(surfDim,disk_1)],  1,1,0,  0,0,1,  angle )
    cylinder_1e = gmsh.model.occ.addCylinder( 2,1,0,  0,1,0,  radius_1 )
    object_1    = [ (dim,tag) for dim,tag in revolve_1 if ( dim == 3 ) ]
    tools_1     = [ (voluDim,cylinder_1s), (voluDim,cylinder_1e) ]
    gmsh.model.occ.synchronize()
    pipe1,maps  = gmsh.model.occ.fuse( object_1, tools_1, removeObject=True, removeTool=True )
    gmsh.model.occ.synchronize()

    # ------------------------------------------------- #
    # --- [3] design pipe2                          --- #
    # ------------------------------------------------- #
    cylinder_2s = gmsh.model.occ.addCylinder( 0,0,0, 1.0, 0,0, radius_2 )
    disk_2      = gmsh.model.occ.addDisk( 1,0,0, radius_2, radius_2 )
    rotate      = gmsh.model.occ.rotate( [(surfDim,disk_2)], 1,0,0, 0,1,0, angle )
    revolve_2   = gmsh.model.occ.revolve( [(surfDim,disk_2)],  1,1,0,  0,0,1,  angle )
    cylinder_2e = gmsh.model.occ.addCylinder( 2,1,0,  0,1,0,  radius_2 )
    object_2    = [ (dim,tag) for dim,tag in revolve_2 if ( dim == 3 ) ]
    tools_2     = [ (voluDim,cylinder_2s), (voluDim,cylinder_2e) ]
    gmsh.model.occ.synchronize()
    pipe2,maps  = gmsh.model.occ.fuse( object_2, tools_2, removeObject=True, removeTool=True  )
    gmsh.model.occ.synchronize()

    pipe1,maps  = gmsh.model.occ.cut ( pipe1, pipe2, removeObject=True, removeTool=False )
    gmsh.model.occ.synchronize()

    # ------------------------------------------------- #
    # --- [4] design heater                         --- #
    # ------------------------------------------------- #
    length      = heater_e - heater_s
    cylinder_3o = gmsh.model.occ.addCylinder( heater_s,0,0, length, 0,0, radius_3 )
    cylinder_3i = gmsh.model.occ.addCylinder( heater_s,0,0, length, 0,0, radius_1 )
    heater,maps = gmsh.model.occ.cut( [(voluDim,cylinder_3o)], [(voluDim,cylinder_3i)], \
                                      removeObject=True, removeTool=True )
    gmsh.model.occ.synchronize()
    
    # ------------------------------------------------- #
    # --- [3] register dimtags                      --- #
    # ------------------------------------------------- #
    dimtags["pipe"]           = pipe1
    dimtags["fluid"]          = pipe2
    dimtags["heater"]         = heater
    dimtags["inlet"]          = [(2,9)]
    dimtags["outlet"]         = [(2,10)]
    dimtags["inner_pipe"]     = [(2,6),(2,7),(2,8)]
    dimtags["outer_pipe"]     = [(2,23),(2,24),(2,25),(2,26)]
    dimtags["pipeEnd_inlet"]  = [(2,27)]
    dimtags["pipeEnd_outlet"] = [(2,28)]
    dimtags["heater_contact"] = [(2,19)]
    dimtags["heater_surface"] = [(2,20),(2,21),(2,22)]
    
    return( dimtags )


# ========================================================= #
# ===   実行部                                          === #
# ========================================================= #

if ( __name__=="__main__" ):

    # ------------------------------------------------- #
    # --- [1] initialization of the gmsh            --- #
    # ------------------------------------------------- #
    gmsh.initialize()
    gmsh.option.setNumber( "General.Terminal", 1 )
    gmsh.option.setNumber( "Mesh.Algorithm"  , 5 )
    gmsh.option.setNumber( "Mesh.Algorithm3D", 4 )
    gmsh.option.setNumber( "Mesh.SubdivisionAlgorithm", 0 )
    gmsh.model.add( "model" )
    
    # ------------------------------------------------- #
    # --- [2] Modeling                              --- #
    # ------------------------------------------------- #
    sample__model = "make"     #  -- [ "import" / "make" ] --  #

    if   ( sample__model == "import" ):
        dimtagsFile = None
        stpFile     = "msh/model.stp"
        import nkGmshRoutines.import__stepFile as isf
        dimtags     = isf.import__stepFile( inpFile=stpFile, dimtagsFile=dimtagsFile )
        
    elif ( sample__model == "make"   ):
        dimtags = {}
        dimtags = make__geometry( dimtags=dimtags )
        gmsh.model.occ.synchronize()
        gmsh.write( "msh/model.stp" )
    
    gmsh.model.occ.synchronize()
    gmsh.model.occ.removeAllDuplicates()
    gmsh.model.occ.synchronize()

    # ------------------------------------------------- #
    # --- [3] Mesh settings                         --- #
    # ------------------------------------------------- #
    mesh_from_config = True         # from nkGMshRoutines/test/mesh.conf, phys.conf
    uniform_size     = 0.05
    if ( mesh_from_config ):
        meshFile = "dat/mesh.conf"
        physFile = "dat/phys.conf"
        import nkGmshRoutines.assign__meshsize as ams
        meshes = ams.assign__meshsize( meshFile=meshFile, physFile=physFile, dimtags=dimtags )
    else:
        import nkGmshRoutines.assign__meshsize as ams
        meshes = ams.assign__meshsize( uniform=uniform_size, dimtags=dimtags )

    # ------------------------------------------------- #
    # --- [4] post process                          --- #
    # ------------------------------------------------- #
    gmsh.model.occ.synchronize()
    gmsh.model.mesh.generate(3)
    gmsh.write( "msh/model.msh" )
    gmsh.finalize()

  • phys.conf

phys.conf ( flow__in_a_curved_pipe_XYZ3D )
# <names> key	type		dimtags_keys			physNum
fluid		volu		[fluid]				301
pipe		volu		[pipe]				302
heater		volu		[heater]			303
inlet		surf		[inlet]				201
outlet		surf		[outlet]			202
inner_pipe	surf		[inner_pipe]			203
outer_pipe	surf		[outer_pipe]			204
pipeEnd_inlet	surf		[pipeEnd_inlet]			205
pipeEnd_outlet	surf		[pipeEnd_outlet]		206
heater_surface	surf		[heater_surface]		207
heater_contact	surf		[heater_contact]		208
  • mesh.conf

mesh.conf ( flow__in_a_curved_pipe_XYZ3D )
# <names> key	physNum	  meshType    resolution1	resolution2	evaluation
fluid	  	301	  constant    0.02		-		-
pipe		302	  constant    0.02		-		-
heater		303	  constant    0.03		-		-
inlet		201	  constant    0.0		-		-
outlet		202	  constant    0.0		-		-
inner_pipe	203	  constant    0.0		-		-
outer_pipe	204	  constant    0.0		-		-
pipeEnd_inlet	205	  constant    0.0		-		-
pipeEnd_outlet	206	  constant    0.0		-		-
heater_surface	207	  constant    0.0		-		-
heater_contact	208	  constant    0.0		-		-
  • 生成したメッシュを次に示す.

../../../_images/mesh2.png

Elmer シミュレーションファイル

  • シミュレーションファイル ( ns.sif )を以下に示す.

ns.sif ( flow__in_acurved_pipe_XYZ3D )

include "./msh/model/mesh.names"

Header
  CHECK KEYWORDS    Warn
  Mesh DB           "." "msh/model"
  Include Path      ""
  Results Directory "out/"
End


Simulation
  Max Output Level                         = 3
  Coordinate System                        = string "Cartesian"
  Coordinate Mapping(3)                    = 1 2 3

  Simulation Type                          = "Transient"
  TimeStepping Method                      = BDF
  BDF Order                                = 2
  Timestep sizes(1)                        = 0.1
  Timestep Intervals(1)                    = 50

  Steady State Max Iterations              = 1
  Post File                                = output.vtu
End

Constants
  Gravity(4)                               = 0 0 -1 9.82	!! m/s^2
End


Solver 1
  Equation                                 = Navier-Stokes

  Linear System Solver                     = Iterative
  Linear System Direct Method              = UMFPACK
  Linear System Iterative Method           = BiCGStab
  Linear System Convergence Tolerance      = 1.0e-6
  Linear System Max Iterations             = 5000
  Linear System Preconditioning            = ILUT

  Nonlinear System Convergence Tolerance   = Real 1.0e-7
  Nonlinear System Max Iterations          = Integer 1000
  Nonlinear System Relaxation Factor       = Real 1.0
  Nonlinear System Newton After Iterations = 15
  Nonlinear System Newton After Tolerance  = 1.0e-3

  Steady State Convergence Tolerance       = 1.0e-5

  stabilize                                = True
  Div Discretization                       = False
End


Body 1
  Name                                     = "fluid"
  Target Bodies(1)                         = $fluid
  Equation                                 = 1
  Material                                 = 1
End


Equation 1
  Name                                     = "Fluid"
  Active Solvers(1)                        = 1
  Navier-Stokes                            = True
End

Material 1
  Name                                     = "Air"
  Density                                  = 1.2e0      !! kg/m3
  Viscosity                                = 1.0e-3     !! 
End


Boundary Condition 1
  Name                                     = "inlet"
  Target Boundaries(1)                     = $inlet

  Velocity 1                               = 1.0
  Velocity 2                               = 0
  Velocity 3                               = 0
End

Boundary Condition 2
  Name                                     = "outlet"
  Target Boundaries(1)                     = $outlet
End

Boundary Condition 3
  Name                                     = "inner_pipe"
  Target Boundaries(1)                     = $inner_pipe
  !! Velocity 1                               = 0
  !! Velocity 2                               = 0
  !! Velocity 3                               = 0
End

シミュレーション結果

結果は以下の通り.

流入速度が進行に従い、減速しながら、パイプ中を進行していく.

../../../_images/flow_anime.gif