Try   HackMD

nVidia Modulus Tutorial – Lid Driven Cavity Flow讀後心得

學習目標

  • 使用Modulus中Geometry module產生2D Geometry
  • 設定BC-Boundary Conditions
  • 設定待解之PDF( Flow Equation)
  • Loss function和network調教
  • 使用Modulus作後處理

問題描述

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

上邊界以1m/s速度朝x方向移動,其餘邊界皆為靜止。雷諾數(Reynold number)設定為10。

使用案例設定

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

以PINNs為基礎求解PDE的步驟:設定幾何形狀設定物理現象所對應之PDE產生neural network solver。如果對應到Modulus,所使用的module與class分別為:CSG/STL(產生point cloud)、TrainDomain class與Solver class。問題與Modulus的對應如上圖所示。

使用Modulus解決LDC包含以下幾個步驟:
Step 1:Importing the required packages

from sympy import Symbol, Eq, Abs

from modulus.solver import Solver
from modulus.dataset import TrainDomain, ValidationDomain
from modulus.data import Validation
from modulus.sympy_utils.geometry_2d import Rectangle
from modulus.csv_utils.csv_rw import csv_to_dict
from modulus.PDES import NaviewStokes
from modulus.controller impotr ModulusController

Step 2:產生幾何形狀

# make geometry
height = 0.1
width = 0.1
vel = 1.0

# define geometry
rec = Rectangle((-width / 2, -height / 2), (width / 2, height / 2))
geo = rec

可使用sample_boundary產生sample point,並使用var_to_vtk產生Paraview可顯示之.vtu檔。

samples = geo.sample_boundary(1000)
var_to_vtk(samples, './geo')

Step 3:定義邊界條件與設定LDC所對應之PDE

# define sympy varaibles to parametize domain curves
x, y = Symbol("x"), Symbol("y")

class LDCTrain(TRainDomain):
  define __init__(self, **config)
  super(LDCTrain, self)._init_()
  
  #top wall
  topwall = geo.boundary_bc(outvar_sympy={'u': vel, 'v': 0},
                        batch_size_per_area=10000,
                        lambda_sympy={'lambda_u': 1.0 -20 * Abs(x), # weight edges to be zero
                                      'lambda_v': 1.0},
                        criteria=Eq(y, height / 2))
   self.add(topwall, name="Topwall")
   
   # no slip
   bottomwall = geo.boundary_bc(outvar_sympy={'u': 0, 'v': 0},
                                batch_size_per_area=10000,
                                criteria-y < height / 2)
   self. add(bottomwall, name="NoSlip")

   # interior
   interior = geo.interior_bc(outvar_sympy={'continuity': 0, 'momentum_x': 0, 'momentum_y': 0},
                              bounds={x: (-width / 2, width / 2),
                                      y: (-height i 2, height 1'2)},
                              lambda_sympy={'lambda_continuity': geo.sdf,
                                            'lambda_momentum_x': geo.sdf,
                                            'lambda_momentum_y': geo.sdf},
                              batch_size_per_area=400000)
    self.add(interior, name="Interior")

Modulus solver的training data的來源為系統之BC與PDE,可由TrainDomain定義。另外,使用solver求解必須定義相關的loss function。
Boundary Condition:使用boundary_bc函數設定。
Equations to solve:考慮2D LDC,我們必須求解continuity equation與x,y方向的momentum equation。初始值為零表示不存在forcing/source項目。
Lambda_sympy表示loss function weighting。下圖可知在左上角與右上角有最大的不連續性,利用SDF(Signed Distance Field)設定可獲得較快的收斂與避免在邊界的不連續性。

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Step 4:產生驗證資料

# validation data
mapping = {'Points:0': 'x', 'Points:1': 'y', 'U:0': 'u', 'U:1': 'v', 'p': 'p'}
openfoam_var = csv_to_dict('openfoam/cavity_uniformVe10.csv, mapping)
openfoam_var['x'] t= -width / 2 # center OpenFoam data
openfoam_var['y'] t= -height / 2 # center OpenFoam data
openfoam_invar_numpy = {key: value for key, value in openfoam_var.items() if key in ['x', 'y']}
openfoam_outvar_numpy = {key: value for key, value in openfoam_var.items() if key in ['u', 'v']}
class LDCVal (ValidationDomain):
  def_init_(self, **config):
  super(LDCVal, self).__init_
  val = Validation. from_numpy(openfoam_invar_numpy, openfoam_outvar_numpy)
  self.add(val, name='Val')

Modulus solver唯一基於物理條件之neural network solver,因此並不需要training data,但我們可以將CFD或其他solver的結果匯入為validating data。我們將OpenFOAM的計算結果以.csv方式匯入,視為solver的validation domain。

Step 5:建立Neural Network Solver

class LDCSolver (Solver):
  train_domain = LDCTrain
  val_domain = LDCVal

  def _init_(self, **config):
    super (LDCSolver, self).__init__(**config)
    self.equations = NavierStokes(nu=0.01, rho=1.0, dim=2,
                                  time=False).make_node()
    flow_net = self.arch.make_node(name='flow_net',
                                   inputs=['x', 'y'],
                                   outputs=['u', 'v', 'p'])
    self.nets = [flow_net]

    @classmethod
    def update_defaults(cls, defaults):
      defaults.update ({
          'network_dir': './network_checkpoint_ldc_2d',
          'decay_steps': 4000,
          max_steps':400000
      })
      
if __name__ == '__main__':
  ctr = ModulusController(LDCSolver)
  ctr.run()

solver繼承Modulus內建的Solver Class,需要設定train_domain與val_domain。
LDC所遵循的PDE為Navier-Stokes方程式,Modulus已有內建,需要給定的參數為:dim=2(2D)、ν(kinematic viscosity)=0.01 m2/sec與ρ(密度)=1.0kg/m31.

Re=ρVDu=νDγ=1.0×0.10.01=10

Modulus預設的network包含6個hidden layer,每一個layer包含512個node。指定network的輸入為(x,y),輸出為(u,v,p)

Step 6:執行Neural Network Solver

python ldc_2d.py