nVidia Modulus Tutorial – Lid Driven Cavity Flow讀後心得
===
學習目標
---
- 使用Modulus中Geometry module產生2D Geometry
- 設定BC-Boundary Conditions
- 設定待解之PDF( Flow Equation)
- Loss function和network調教
- 使用Modulus作後處理
問題描述
---

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

以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)設定可獲得較快的收斂與避免在邊界的不連續性。

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 = {ρVD\over u} = {νD\over \gamma} = {1.0 \times 0.1\over 0.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
```