nVidia Modulus Tutorial – Lid Driven Cavity Flow讀後心得 === 學習目標 --- - 使用Modulus中Geometry module產生2D Geometry - 設定BC-Boundary Conditions - 設定待解之PDF( Flow Equation) - Loss function和network調教 - 使用Modulus作後處理 問題描述 --- ![Modulus-1](https://hackmd.io/_uploads/rkB2Xm-vT.png) 上邊界以1m/s速度朝x方向移動,其餘邊界皆為靜止。雷諾數(Reynold number)設定為10。 使用案例設定 --- ![Modulus-2](https://hackmd.io/_uploads/BJE6QX-DT.png) 以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)設定可獲得較快的收斂與避免在邊界的不連續性。 ![Modulus-3](https://hackmd.io/_uploads/H12RQ7Wvp.png) 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 ```