104
104
105
105
上式中 $f$ 即为 MLP 模型本身,用 PaddleScience 代码表示如下
106
106
107
- ``` py linenums="32 "
107
+ ``` py linenums="33 "
108
108
-- 8 < --
109
- examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:32 : 35
109
+ examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:33 : 36
110
110
-- 8 < --
111
111
```
112
112
@@ -118,9 +118,9 @@ examples/cylinder/2d_unsteady/cylinder2d_unsteady_Re100.py:32:35
118
118
119
119
由于 2D-Cylinder 使用的是 Navier-Stokes 方程的2维瞬态形式,因此可以直接使用 PaddleScience 内置的 ` NavierStokes ` 。
120
120
121
- ``` py linenums="36 "
121
+ ``` py linenums="37 "
122
122
-- 8 < --
123
- examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:36 : 37
123
+ examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:37 : 38
124
124
-- 8 < --
125
125
```
126
126
@@ -130,7 +130,7 @@ examples/cylinder/2d_unsteady/cylinder2d_unsteady_Re100.py:36:37
130
130
131
131
本文中 2D-Cylinder 的计算域由 CSV 文件储存的点云构成,因此可以直接使用 PaddleScience 内置的点云几何 ` PointCloud ` 和时间域 ` TimeDomain ` ,组合成时间-空间的 ` TimeXGeometry ` 计算域。
132
132
133
- ``` py linenums="39 "
133
+ ``` py linenums="40 "
134
134
# set timestamps
135
135
TIME_START , TIME_END = 1 , 50
136
136
NUM_TIMESTAMPS = 50
@@ -159,15 +159,20 @@ geom = {
159
159
timestamps = np.concatenate((t0, train_timestamps), axis = 0 ),
160
160
),
161
161
ppsci.geometry.PointCloud(
162
- " ./datasets/domain_train.csv" ,
163
- (" Points:0" , " Points:1" ),
164
- alias_dict = {" Points:0" : " x" , " Points:1" : " y" },
162
+ reader.load_csv_file(
163
+ " ./datasets/domain_train.csv" ,
164
+ (" x" , " y" ),
165
+ alias_dict = {" x" : " Points:0" , " y" : " Points:1" },
166
+ ),
167
+ (" x" , " y" ),
165
168
),
166
169
),
167
- " time_rect_eval" : ppsci.geometry.PointCloud( # (1)
168
- " ./datasets/domain_eval.csv" ,
170
+ " time_rect_eval" : ppsci.geometry.PointCloud(
171
+ reader.load_csv_file(
172
+ " ./datasets/domain_eval.csv" ,
173
+ (" t" , " x" , " y" ),
174
+ ),
169
175
(" t" , " x" , " y" ),
170
- alias_dict = {},
171
176
),
172
177
}
173
178
```
@@ -232,19 +237,19 @@ geom = {
232
237
233
238
在定义约束之前,需要给每一种约束指定采样点个数,表示每一种约束在其对应计算域内采样数据的数量,以及通用的采样配置。
234
239
235
- ``` py linenums="79 "
240
+ ``` py linenums="85 "
236
241
-- 8 < --
237
- examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:79 : 86
242
+ examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:85 : 92
238
243
-- 8 < --
239
244
```
240
245
241
246
#### 3.4.1 内部点约束
242
247
243
248
以作用在流体域内部点上的 ` InteriorConstraint ` 为例,代码如下:
244
249
245
- ``` py linenums="88 "
250
+ ``` py linenums="94 "
246
251
-- 8 < --
247
- examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:88 : 100
252
+ examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:94 : 106
248
253
-- 8 < --
249
254
```
250
255
@@ -262,87 +267,91 @@ examples/cylinder/2d_unsteady/cylinder2d_unsteady_Re100.py:88:100
262
267
263
268
#### 3.4.2 边界约束
264
269
265
- 同理,我们还需要构建流体域的流入边界、流出边界、圆周边界共三个边界的 Dirichlet 边界约束。以 ` bc_inlet_cylinder ` 边界约束为例,由于作用区域是边界且边界上的数据由 CSV 文件记录,因此我们使用 ` SupervisedConstraint ` 类,并指定第一个参数为 CSV 文件的路径 ` ./datasets/domain_inlet_cylinder.csv ` ;
270
+ 同理,我们还需要构建流体域的流入边界、流出边界、圆周边界共三个边界的 Dirichlet 边界约束。以 ` bc_inlet_cylinder ` 边界约束为例,由于作用区域是边界且边界上的数据由 CSV 文件记录,因此我们使用 ` SupervisedConstraint ` 类,并按照如下规则指定第一个参数 ` dataloader_cfg ` 配置字典:
271
+
272
+ - 该配置字典的第一个参数为包含 CSV 文件的路径 ` ./datasets/domain_inlet_cylinder.csv ` 在内的配置字典;
273
+
274
+ - 该配置字典的第一个参数指定数据加载方式,此处我们使用 ` IterableCSVDataset ` 作为全量数据加载器;
266
275
267
- 第二个参数指定数据输入 $x$ 和 $y$ 在 CSV 文件中的字段名,分别为 ` "Points:0" ` 和 ` "Points:1" ` ;
276
+ - 该配置字典的第二个参数指定数据的加载路径,此处填写 ` ./datasets/domain_inlet_cylinder.csv ` ;
268
277
269
- 第三个参数指定约束目标值 $u$ 和 $v$ 在 CSV 文件中的字段名,分别为 ` "U:0" ` 和 ` "U:1" ` ;
278
+ - 该配置字典的第三个参数指定要从文件中读取的输入列,对应转换后关键字,此处填写为 ` ("x", "y") ` ;
270
279
271
- 考虑到同一个变量在不同 CSV 文件中可能具有不同的字段名,而且有的字段名过长在编写代码时容易写错,因此第四个参数用于指定字段别名,此处为 ` {"Points:0": "x", "Points:1": "y", "U:0": " u", "U:1": "v"} ` ,表示读取数据后,将 ` "Points:0" ` 关键字重新命名为 ` "x" ` ,将 ` "Points:1" ` 关键字重新命名为 ` "y" ` ,将 ` "U:0" ` 关键字重新命名为 ` "u" ` ,将 ` "U:1" ` 关键字重新命名为 ` "v" ` ;
280
+ - 该配置字典的第四个参数指定要从文件中读取的标签列,对应转换后关键字,此处填写为 ` (" u", "v") ` ;
272
281
273
- 第五个参数是在计算域上的采样配置,此处我们使用全量数据点训练,因此 ` dataset ` 字段设置为 "IterableNamedArrayDataset" 且 ` iters_per_epoch ` 也设置为 1,采样点数 ` batch_size ` 设为 161 * 30(表示一个时刻产生 161 个数据点,共有 30 个时刻) ;
282
+ - 考虑到同一个变量在不同 CSV 文件中可能具有不同的字段名,而且有的字段名过长在编写代码时容易写错,因此该配置字典的第五个参数用于指定字段列的别名,此处填写为 ` {"x": "Points:0", "y": "Points:1", "u": "U:0", "v": "U:1"} ` ;
274
283
275
- 第六个参数是损失函数,此处我们选用常用的MSE函数,且 ` reduction ` 设置为 ` "mean" ` ,即我们会将参与计算的所有数据点产生的损失项求和取平均 ;
284
+ - 该配置字典的第六个参数指定每个标签在计算损失时的权重,此处我们放大 "u" 和 "v" 的权重至 10,填写 ` {"u": 10, "v": 10} ` ;
276
285
277
- 第七个参数是权重系数,该配置可以精确调整每一个变量参与损失计算时的权重 ;
286
+ - 该配置字典的第七个参数指定数据读取是否涉及时间信息,此处我们设定为训练时间戳,即填写 ` train_timestamps ` ;
278
287
279
- 第八个参数是指定 CSV 文件的时刻信息,此处我们传入表示训练 30 个时刻的 ` train_timestamps ` ;
288
+ 第二个参数是损失函数,此处我们选用常用的MSE函数,且 ` reduction ` 设置为 ` "mean" ` ,即我们会将参与计算的所有数据点产生的损失项求和取平均 ;
280
289
281
- 第九个参数是约束条件的名字 ,我们需要给每一个约束条件命名,方便后续对其索引。此处我们命名为 "BC_inlet_cylinder" 即可。
290
+ 第三个参数是约束条件的名字 ,我们需要给每一个约束条件命名,方便后续对其索引。此处我们命名为 "BC_inlet_cylinder" 即可。
282
291
283
292
剩下的 ` bc_outlet ` 按照相同原理构建,代码如下所示:
284
293
285
- ``` py linenums="101 "
294
+ ``` py linenums="107 "
286
295
-- 8 < --
287
- examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:101 : 129
296
+ examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:107 : 135
288
297
-- 8 < --
289
298
```
290
299
291
300
#### 3.4.3 初值约束
292
301
293
302
对于 $t=t_0$ 时刻的流体域内的点,我们还需要对 $u$, $v$, $p$ 施加初值约束,代码如下:
294
303
295
- ``` py linenums="130 "
304
+ ``` py linenums="136 "
296
305
-- 8 < --
297
- examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:130 : 144
306
+ examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:136 : 150
298
307
-- 8 < --
299
308
```
300
309
301
310
#### 3.4.4 监督约束
302
311
303
312
本案例在流体域内部加入了一定数量的监督点来保证模型最终的收敛情况,因此最后还需要加入一个监督约束,数据同样来自 CSV 文件,代码如下:
304
313
305
- ``` py linenums="145 "
314
+ ``` py linenums="151 "
306
315
-- 8 < --
307
- examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:145 : 159
316
+ examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:151 : 165
308
317
-- 8 < --
309
318
```
310
319
311
320
在微分方程约束、边界约束、初值约束、监督约束构建完毕之后,以我们刚才的命名为关键字,封装到一个字典中,方便后续访问。
312
321
313
- ``` py linenums="160 "
322
+ ``` py linenums="166 "
314
323
-- 8 < --
315
- examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:160 : 167
324
+ examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:166 : 173
316
325
-- 8 < --
317
326
```
318
327
319
328
### 3.5 超参数设定
320
329
321
330
接下来我们需要指定训练轮数和学习率,此处我们按实验经验,使用两万轮训练轮数,评估间隔为四百轮,学习率设为 0.001。
322
331
323
- ``` py linenums="169 "
332
+ ``` py linenums="175 "
324
333
-- 8 < --
325
- examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:169 : 171
334
+ examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:175 : 177
326
335
-- 8 < --
327
336
```
328
337
329
338
### 3.6 优化器构建
330
339
331
340
训练过程会调用优化器来更新模型参数,此处选择较为常用的 ` Adam ` 优化器。
332
341
333
- ``` py linenums="173 "
342
+ ``` py linenums="179 "
334
343
-- 8 < --
335
- examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:173 : 174
344
+ examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:179 : 180
336
345
-- 8 < --
337
346
```
338
347
339
348
### 3.7 评估器构建
340
349
341
350
在训练过程中通常会按一定轮数间隔,用验证集(测试集)评估当前模型的训练情况,因此使用 ` ppsci.validate.GeometryValidator ` 构建评估器。
342
351
343
- ``` py linenums="176 "
352
+ ``` py linenums="182 "
344
353
-- 8 < --
345
- examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:176 : 192
354
+ examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:182 : 198
346
355
-- 8 < --
347
356
```
348
357
@@ -364,19 +373,19 @@ examples/cylinder/2d_unsteady/cylinder2d_unsteady_Re100.py:176:192
364
373
365
374
本文中的输出数据是一个区域内的二维点集,每个时刻 $t$ 的坐标是 $(x^t_i, y^t_i)$,对应值是 $(u^t_i, v^t_i, p^t_i)$,因此我们只需要将评估的输出数据按时刻保存成 50 个 ** vtu格式** 文件,最后用可视化软件打开查看即可。代码如下:
366
375
367
- ``` py linenums="194 "
376
+ ``` py linenums="200 "
368
377
-- 8 < --
369
- examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:194 : 205
378
+ examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:200 : 212
370
379
-- 8 < --
371
380
```
372
381
373
382
### 3.9 模型训练、评估与可视化
374
383
375
384
完成上述设置之后,只需要将上述实例化的对象按顺序传递给 ` ppsci.solver.Solver ` ,然后启动训练、评估、可视化。
376
385
377
- ``` py linenums="207 "
386
+ ``` py linenums="214 "
378
387
-- 8 < --
379
- examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:207 :
388
+ examples/ cylinder/ 2d_unsteady / cylinder2d_unsteady_Re100.py:214 :
380
389
-- 8 < --
381
390
```
382
391
0 commit comments