From 9c7624ff9192b8645b2048e5d83d296b5b8cdb2f Mon Sep 17 00:00:00 2001 From: cchenyang Date: Sat, 28 Sep 2024 14:30:36 +0800 Subject: [PATCH] nsfnet001 --- .../applications/research/nsf_nets/README.md | 165 ++++++++++++++++++ .../research/nsf_nets/README_CN.md | 162 +++++++++++++++++ .../research/nsf_nets/__init__.py | 20 +++ .../research/nsf_nets/config.yaml | 18 ++ .../applications/research/nsf_nets/eval.py | 55 ++++++ .../research/nsf_nets/src/__init__.py | 14 ++ .../research/nsf_nets/src/dataset.py | 55 ++++++ .../research/nsf_nets/src/network.py | 111 ++++++++++++ .../research/nsf_nets/src/process.py | 28 +++ .../applications/research/nsf_nets/train.py | 61 +++++++ 10 files changed, 689 insertions(+) create mode 100644 MindFlow/applications/research/nsf_nets/README.md create mode 100644 MindFlow/applications/research/nsf_nets/README_CN.md create mode 100644 MindFlow/applications/research/nsf_nets/__init__.py create mode 100644 MindFlow/applications/research/nsf_nets/config.yaml create mode 100644 MindFlow/applications/research/nsf_nets/eval.py create mode 100644 MindFlow/applications/research/nsf_nets/src/__init__.py create mode 100644 MindFlow/applications/research/nsf_nets/src/dataset.py create mode 100644 MindFlow/applications/research/nsf_nets/src/network.py create mode 100644 MindFlow/applications/research/nsf_nets/src/process.py create mode 100644 MindFlow/applications/research/nsf_nets/train.py diff --git a/MindFlow/applications/research/nsf_nets/README.md b/MindFlow/applications/research/nsf_nets/README.md new file mode 100644 index 000000000..0a2bde220 --- /dev/null +++ b/MindFlow/applications/research/nsf_nets/README.md @@ -0,0 +1,165 @@ +ENGLISH | [简体中文](README_CN.md) + +# Contents + +- [Navier-Stokes Flow Nets Description](#navier-stokes-flow-nets-description) +- [Dataset](#dataset) +- [Environment Requirements](#environment-requirements) +- [Quick Start](#quick-start) +- [Script Description](#script-description) + - [Script and Sample Code](#script-and-sample-code) + - [Script Parameters](#script-parameters) + - [Training Process](#training-process) + - [Evaluation Process](#evaluation-process) + +## [Navier-Stokes Flow Nets Description](#contents) + +"Navier-Stokes flow nets(NSFNets)" solves the vorticity-velocity(VV) and velocity-pressure(VP) formulations of the +Navier-Stokes equations by training neural networks. +The training process of the model is unsupervised learning, which means no labeled data are fed into the net during +training. +The loss are defined by the residual of equations governing VP and VV formulation, and also the boundary conditions. +The results obtained by NSFNet performs better than CFD solvers in the ill-posed or inverse problems. + +> [paper](https://www.sciencedirect.com/science/article/pii/S0021999120307257): Xiaowei Jin, Shengze Cai, Hui Li, George +> Em Karniadakis, NSFnets (Navier-Stokes flow nets): Physics-informed neural networks for the incompressible +> Navier-Stokes equations, Journal of Computational Physics, Volume 426, 2021, 109951, ISSN 0021-9991. + +Example details: the code to simulate Kovasznay flow (2-dimension without time). + +## [Dataset](#contents) + +The dataset is generated randomly during runtime. +The size of dataset is controlled by parameter `n_train` for domain and `n_bound` for boundary in `config.yaml`, +and by default are 2601 and 100, respectively. + +The pretrained checkpoint files will be downloaded automatically at the first launch. +If you need to download the checkpoint files manually, +please visit [this link](https://download.mindspore.cn/mindscience/SciAI/sciai/model/nsf_nets/). + +## [Environment Requirements](#contents) + +- Hardware(Ascend/GPU) + - Prepare hardware environment with Ascend or GPU processor. +- Framework + - [MindSpore](https://www.mindspore.cn/install/en) +- For more information, please check the resources below: + - [MindSpore Tutorials](https://www.mindspore.cn/tutorials/en/master/index.html) + - [MindSpore Python API](https://www.mindspore.cn/docs/en/master/index.html) + +## [Quick Start](#contents) + +After installing MindSpore via the official website, you can start training and evaluation as follows: + +- running on Ascend or on GPU + +Default: + +```bash +python train.py +``` + +Full command: + +```bash +python train.py \ + --layers 2 50 50 50 50 3 \ + --save_ckpt true \ + --load_ckpt false \ + --save_ckpt_path ./checkpoints \ + --load_ckpt_path ./checkpoints/model_final_float32.ckpt \ + --log_path ./logs \ + --print_interval 10 \ + --n_train 2601 \ + --n_bound 100 \ + --lr 1e-3 1e-4 1e-5 1e-6 \ + --epochs 5000 5000 50000 50000 \ + --download_data nsf_nets \ + --force_download false \ + --amp_level O2 \ + --device_id 0 \ + --mode 0 +``` + +## [Script Description](#contents) + +### [Script and Sample Code](#contents) + +```text +├── nsf_nets +│ ├── checkpoints # checkpoints files +│ ├── data # data files +│ ├── figures # plot figures +│ ├── logs # log files +│ ├── src # source codes +│ │ ├──network.py # network architecture +│ │ └──dataset.py # to generate datasets +│ ├── config.yaml # hyper-parameters configuration +│ ├── README.md # English model descriptions +│ ├── README_CN.md # Chinese model description +│ ├── train.py # python training script +│ └── eval.py # python evaluation script +``` + +### [Script Parameters](#contents) + +Important parameters in `train.py` are as follows: + +| parameter | description | default value | +|----------------|----------------------------------------------|----------------------------------------| +| layers | layer structure | 2 50 50 50 50 3 | +| save_ckpt | whether save checkpoint or not | true | +| load_ckpt | whether load checkpoint or not | false | +| save_ckpt_path | checkpoint saving path | ./checkpoints | +| load_ckpt_path | checkpoint loading path | ./checkpoints/model_final_float32.ckpt | +| log_path | log saving path | ./logs | +| print_interval | time and loss print interval | 10 | +| n_train | sampling numbers inside domain | 2601 | +| n_bound | sampling numbers on boundary | 100 | +| lr | learning rate | 1e-3 1e-4 1e-5 1e-6 | +| epochs | number of epochs | 5000 5000 50000 50000 | +| download_data | necessary dataset and/or checkpoints | nsf_nets | +| force_download | whether download the dataset or not by force | false | +| amp_level | MindSpore auto mixed precision level | O2 | +| device_id | device id to set | None | +| mode | MindSpore Graph mode(0) or Pynative mode(1) | 0 | + +### [Training Process](#contents) + +- running on GPU/Ascend + + ```bash + python train.py + ``` + + The loss values during training will be printed in the console, which can also be inspected after training in log + file. + + ```bash + # grep "loss:" log + step: 0, loss: 3.0267472, interval: 10.88703203201294s, total: 10.88703203201294s + step: 10, loss: 1.9014359, interval: 0.2849254608154297s, total: 11.1719574928283697s + step: 20, loss: 0.9572897, interval: 0.24947023391723633s, total: 11.42142772674560603s + step: 30, loss: 0.6608443, interval: 0.24956488609313965s, total: 11.67099261283874568s + step: 40, loss: 0.61762005, interval: 0.2589101791381836s, total: 11.92990279197692928s + step: 50, loss: 0.61856925, interval: 0.2607557773590088s, total: 12.19065856933593808s + ... + ``` + +- After training, you can still review the training process through the log file saved in `log_path`, `./logs` directory + by default. + +- The model checkpoint will be saved in `save_ckpt_path`, `./checkpoint` directory by default. + +### [Evaluation Process](#contents) + +Before running the command below, please check the checkpoint loading path `load_ckpt_path` specified +in `config.yaml` for evaluation. + +- running on GPU/Ascend + + ```bash + python eval.py + ``` + + You can view the process and results through the `log_path`, `./logs` by default. \ No newline at end of file diff --git a/MindFlow/applications/research/nsf_nets/README_CN.md b/MindFlow/applications/research/nsf_nets/README_CN.md new file mode 100644 index 000000000..ad669dc11 --- /dev/null +++ b/MindFlow/applications/research/nsf_nets/README_CN.md @@ -0,0 +1,162 @@ +[ENGLISH](README.md) | 简体中文 + +# 目录 + +- [Navier-Stokes Flow Nets 描述](#navier-stokes-flow-nets-描述) +- [数据集](#数据集) +- [环境要求](#环境要求) +- [快速开始](#快速开始) +- [脚本说明](#脚本说明) + - [脚本和示例代码](#脚本和示例代码) + - [脚本参数](#脚本参数) + - [训练流程](#训练流程) + - [推理流程](#推理流程) + +## [Navier-Stokes Flow Nets 描述](#目录) + +Navier-Stokes Flow Net(NSFNets)通过训练神经网络求解维纳-斯托克斯方程中涡度-速度(VV)公式和速度-压力(VP)公式。 +该模型的训练流程是无监督学习,训练的损失由涡度-速度公式或速度-压力公式的残差以及边界条件得出。 +在问题条件缺失或是求解反问题的情况下,使用PINNs比传统计算流体力学方法能够得到更优的解。 + +> [论文](https://www.sciencedirect.com/science/article/pii/S0021999120307257): Xiaowei Jin, Shengze Cai, Hui Li, George +> Em Karniadakis, NSFnets (Navier-Stokes flow nets): Physics-informed neural networks for the incompressible +> Navier-Stokes equations, Journal of Computational Physics, Volume 426, 2021, 109951, ISSN 0021-9991. + +案例详情: 空间域二维Kovasnay流仿真。 + +## [数据集](#目录) + +训练数据集在运行时随机生成。 +数据集的大小由`config.yaml`中的问题域内采样参数`n_train`和问题边界采样参数`n_bound`控制, +默认值分别为2601和50。 + +预训练checkpoints文件将会在首次启动时自动下载。 +您如果需要手动下载checkpoints文件, +请访问[此链接](https://download.mindspore.cn/mindscience/SciAI/sciai/model/nsf_nets/)。 + +## [环境要求](#目录) + +- 硬件(Ascend/GPU) + - 使用 Ascend 或 GPU 处理器准备硬件环境。 +- 框架 + - [MindSpore](https://www.mindspore.cn/install) +- 欲了解更多信息,请查看以下资源: + - [MindSpore教程](https://www.mindspore.cn/tutorials/zh-CN/master/index.html) + - [MindSpore Python API](https://www.mindspore.cn/docs/zh-CN/master/index.html) + +## [快速开始](#目录) + +通过官网安装好MindSpore后,就可以开始训练和验证如下: + +- 在 Ascend 或 GPU 上运行 + +默认: + +```bash +python train.py +``` + +完整命令: + +```bash +python train.py \ + --layers 2 50 50 50 50 3 \ + --save_ckpt true \ + --load_ckpt false \ + --save_ckpt_path ./checkpoints \ + --load_ckpt_path ./checkpoints/model_final_float32.ckpt \ + --log_path ./logs \ + --print_interval 10 \ + --n_train 2601 \ + --n_bound 100 \ + --lr 1e-3 1e-4 1e-5 1e-6 \ + --epochs 5000 5000 50000 50000 \ + --download_data nsf_nets \ + --force_download false \ + --amp_level O2 \ + --device_id 0 \ + --mode 0 +``` + +## [脚本说明](#目录) + +### [脚本和示例代码](#目录) + +文件结构如下: + +```text +├── nsf_nets +│ ├── checkpoints # checkpoint文件 +│ ├── data # 数据文件 +│ ├── figures # 结果图片 +│ ├── logs # 日志文件 +│ ├── src # 源代码 +│ │ ├── network.py # 网络架构 +│ │ └── process.py # 数据处理 +│ ├── config.yaml # 超参数配置 +│ ├── README.md # 英文模型说明 +│ ├── README_CN.md # 中文模型说明 +│ ├── train.py # python训练脚本 +│ └── eval.py # python评估脚本 +``` + +### [脚本参数](#目录) + +train.py中的重要参数如下: + +| 参数 | 描述 | 默认值 | +|----------------|----------------------------|----------------------------------------| +| layers | 神经网络结构 | 2 50 50 50 50 3 | +| save_ckpt | 是否保存checkpoint | true | +| load_ckpt | 是否加载checkpoint | false | +| save_ckpt_path | checkpoint保存路径 | ./checkpoints | +| load_ckpt_path | checkpoint加载路径 | ./checkpoints/model_final_float32.ckpt | +| log_path | 日志保存路径 | ./logs | +| print_interval | 时间与loss打印间隔 | 10 | +| n_train | 问题域内数据集采样数 | 2601 | +| n_bound | 问题边界数据集采样数 | 100 | +| lr | 学习率 | 1e-3 1e-4 1e-5 1e-6 | +| epochs | 时期(迭代次数) | 5000 5000 50000 50000 | +| download_data | 模型所需数据集与(或)checkpoints | nsf_nets | +| force_download | 是否强制下载数据 | false | +| amp_level | MindSpore自动混合精度等级 | O2 | +| device_id | 需要设置的设备号 | None | +| mode | MindSpore静态图模式(0)或动态图模式(1) | 0 | + +### [训练流程](#目录) + +- 在 GPU/Ascend 上运行 + + ```bash + python train.py + ``` + + 训练期间的损失值将打印在控制台中, 也可以训练后在日志文件中查看。 + + ```bash + # grep "loss:" log + step: 0, loss: 3.0267472, interval: 10.88703203201294s, total: 10.88703203201294s + step: 10, loss: 1.9014359, interval: 0.2849254608154297s, total: 11.1719574928283697s + step: 20, loss: 0.9572897, interval: 0.24947023391723633s, total: 11.42142772674560603s + step: 30, loss: 0.6608443, interval: 0.24956488609313965s, total: 11.67099261283874568s + step: 40, loss: 0.61762005, interval: 0.2589101791381836s, total: 11.92990279197692928s + step: 50, loss: 0.61856925, interval: 0.2607557773590088s, total: 12.19065856933593808s + ... + ``` + +- 训练结束后,您仍然可以通过保存在`log_path`下面的日志文件回顾训练过程,默认为`./logs`目录中。 + +- 模型checkpoint将保存在 `save_ckpt_path`中,默认为`./checkpoints` 目录中。 + +### [推理流程](#目录) + +在运行下面的命令之前,请检查使用的`config.yaml` 中的checkpoint加载路径`load_ckpt_path` +进行推理。 + +- 在 GPU/Ascend 上运行 + + ```bash + python eval.py + ``` + + 您可以通过日志文件`log_path`查看过程与结果,默认位于`./logs` 。 \ No newline at end of file diff --git a/MindFlow/applications/research/nsf_nets/__init__.py b/MindFlow/applications/research/nsf_nets/__init__.py new file mode 100644 index 000000000..5dfb9a6e8 --- /dev/null +++ b/MindFlow/applications/research/nsf_nets/__init__.py @@ -0,0 +1,20 @@ +# Copyright 2023 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +"""init for nsf_nets""" +from train import main as main_train +from eval import main as main_eval +from src.process import prepare + +__all__ = ["main_train", "main_eval", "prepare"] diff --git a/MindFlow/applications/research/nsf_nets/config.yaml b/MindFlow/applications/research/nsf_nets/config.yaml new file mode 100644 index 000000000..426ed7a9f --- /dev/null +++ b/MindFlow/applications/research/nsf_nets/config.yaml @@ -0,0 +1,18 @@ +model_name: nsf_nets +description: nsf_nets +case: "Navier\u9225\u63DDtokes" +layers: [2, 50, 50, 50, 50, 3] +save_ckpt: true +load_ckpt: false +save_ckpt_path: ./checkpoints +load_ckpt_path: ./checkpoints/model_final_float32.ckpt +log_path: ./logs +print_interval: 10 +n_train: 2601 +n_bound: 200 +lr: [0.001, 0.0001, 1.0e-05, 1.0e-06] +epochs: [5000, 5000, 50000, 50000] +download_data: nsf_nets +force_download: false +amp_level: O2 +mode: 0 diff --git a/MindFlow/applications/research/nsf_nets/eval.py b/MindFlow/applications/research/nsf_nets/eval.py new file mode 100644 index 000000000..3c9d9597b --- /dev/null +++ b/MindFlow/applications/research/nsf_nets/eval.py @@ -0,0 +1,55 @@ +# Copyright 2023 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +"""nsf nets eval""" +import numpy as np +import mindspore as ms + +from sciai.context import init_project +from sciai.utils import print_log, amp2datatype +from sciai.utils.python_utils import print_time +from src.dataset import generate_data, generate_test_data +from src.network import VPNSFnet +from src.process import prepare + + +def evaluate(lam, net): + """evaluate""" + # Test Data + p_star, u_star, v_star, x_star, y_star = generate_test_data(lam) + u_pred, v_pred, p_pred = net.neural_net(x_star, y_star) + # Error + error_u = np.linalg.norm(u_star - u_pred.asnumpy(), 2) / np.linalg.norm(u_star, 2) + error_v = np.linalg.norm(v_star - v_pred.asnumpy(), 2) / np.linalg.norm(v_star, 2) + error_p = np.linalg.norm(p_star - p_pred.asnumpy(), 2) / np.linalg.norm(p_star, 2) + print_log('Error u: ' + str(error_u)) + print_log('Error v: ' + str(error_v)) + print_log('Error p: ' + str(error_p)) + + +@print_time("eval") +def main(args): + dtype = amp2datatype(args.amp_level) + lam, ub_train, vb_train, x_train, xb_train, y_train, yb_train = generate_data(args, dtype) + net = VPNSFnet(xb_train, yb_train, ub_train, vb_train, x_train, y_train, args.layers) + if dtype == ms.float16: + net.to_float(ms.float16) + ms.load_checkpoint(args.load_ckpt_path, net) + evaluate(lam, net) + + +if __name__ == "__main__": + args_ = prepare() + init_project(args=args_[0]) + main(*args_) diff --git a/MindFlow/applications/research/nsf_nets/src/__init__.py b/MindFlow/applications/research/nsf_nets/src/__init__.py new file mode 100644 index 000000000..14331ea3d --- /dev/null +++ b/MindFlow/applications/research/nsf_nets/src/__init__.py @@ -0,0 +1,14 @@ +# Copyright 2023 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ diff --git a/MindFlow/applications/research/nsf_nets/src/dataset.py b/MindFlow/applications/research/nsf_nets/src/dataset.py new file mode 100644 index 000000000..33ef6c7c8 --- /dev/null +++ b/MindFlow/applications/research/nsf_nets/src/dataset.py @@ -0,0 +1,55 @@ +# Copyright 2023 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +"""nsf_net dataset""" +import numpy as np +import mindspore as ms +from sciai.utils.ms_utils import to_tensor + + +def generate_data(args, dtype): + """generate data""" + n_train = args.n_train + n_bound = args.n_bound + # Load Data + re = 40 + lam = 0.5 * re - np.sqrt(0.25 * (re ** 2) + 4 * (np.pi ** 2)) + x = np.linspace(-0.5, 1.0, n_bound + 1) + y = np.linspace(-0.5, 1.5, n_bound + 1) + yb1 = np.array([-0.5] * n_bound) + yb2 = np.array([1] * n_bound) + xb1 = np.array([-0.5] * n_bound) + xb2 = np.array([1.5] * n_bound) + y_train1 = np.concatenate([y[1:n_bound + 1], y[0:n_bound], xb1, xb2], 0) + x_train1 = np.concatenate([yb1, yb2, x[0:n_bound], x[1:n_bound + 1]], 0) + xb_train = x_train1.reshape(x_train1.shape[0], 1) + yb_train = y_train1.reshape(y_train1.shape[0], 1) + ub_train = 1 - np.exp(lam * xb_train) * np.cos(2 * np.pi * yb_train) + vb_train = lam / (2 * np.pi) * np.exp(lam * xb_train) * np.sin(2 * np.pi * yb_train) + x_train = (np.random.rand(n_train, 1) - 1 / 3) * 3 / 2 + y_train = (np.random.rand(n_train, 1) - 1 / 4) * 2 + xb_train, yb_train, ub_train, vb_train, x_train, y_train = to_tensor( + (xb_train, yb_train, ub_train, vb_train, x_train, y_train), dtype=dtype) + return lam, ub_train, vb_train, x_train, xb_train, y_train, yb_train + + +def generate_test_data(lam): + x_star = (np.random.rand(1000, 1) - 1 / 3) * 3 / 2 + y_star = (np.random.rand(1000, 1) - 1 / 4) * 2 + u_star = 1 - np.exp(lam * x_star) * np.cos(2 * np.pi * y_star) + v_star = (lam / (2 * np.pi)) * np.exp(lam * x_star) * np.sin(2 * np.pi * y_star) + p_star = 0.5 * (1 - np.exp(2 * lam * x_star)) + # Prediction + x_star, y_star = to_tensor((x_star, y_star), dtype=ms.float32) + return p_star, u_star, v_star, x_star, y_star diff --git a/MindFlow/applications/research/nsf_nets/src/network.py b/MindFlow/applications/research/nsf_nets/src/network.py new file mode 100644 index 000000000..59590250a --- /dev/null +++ b/MindFlow/applications/research/nsf_nets/src/network.py @@ -0,0 +1,111 @@ +# Copyright 2023 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +"""Network definitions""" +import mindspore as ms +from mindspore import nn, ops + +from sciai.architecture import MLP, MSE +from sciai.common.initializer import XavierTruncNormal +from sciai.operators import grad + + +class VPNSFnet(nn.Cell): + """VPNSF network""" + def __init__(self, xb, yb, ub, vb, x, y, layers): + super().__init__() + # remove the second bracket + xb_list = ops.concat([xb, yb], 1) + x_list = ops.concat([x, y], 1) + + self.xb_list = xb_list + self.x_list = x_list + + self.xb = xb + self.yb = yb + self.x = x + self.y = y + + self.ub = ub + self.vb = vb + + self.layers = layers + self.alpha = ms.Tensor(1, dtype=ms.float32) + self.grad = ops.GradOperation(get_all=True) + + # Initialize NN + self.neural_net = Net(layers, xb_list.min(0), xb_list.max(0)) + self.net_f_ns = NetFNS(self.neural_net) + self.mse = MSE() + + def construct(self, *inputs): + """Network forward pass""" + xb, yb, ub, vb, x, y = inputs + u_boundary_pred, v_boundary_pred, _ = self.neural_net(xb, yb) + _, _, _, f_u_pred, f_v_pred, f_e_pred = self.net_f_ns(x, y) + + # set loss function + loss = self.alpha * self.mse(ub - u_boundary_pred) + self.alpha * self.mse(vb - v_boundary_pred) + \ + self.mse(f_u_pred) + self.mse(f_v_pred) + self.mse(f_e_pred) + return loss + + +class NetFNS(nn.Cell): + """FNS network""" + def __init__(self, neural_net): + super().__init__() + self.neural_net = neural_net + self.net_grad_u = grad(self.neural_net, 0, (0, 1)) # du/dx, du/dy + self.net_grad_v = grad(self.neural_net, 1, (0, 1)) # dv/dx, dv/dy + self.net_grad_p = grad(self.neural_net, 2, (0, 1)) # dp/dx, dp/dy + self.ops_ux2 = grad(self.net_grad_u, 0, (0, 1)) # du2/dx2, du2/dxdy + self.ops_uy2 = grad(self.net_grad_u, 1, (0, 1)) # du2/dydx, du2/dy2 + self.ops_vx2 = grad(self.net_grad_v, 0, (0, 1)) # dv2/dx2, dv2/dxdy + self.ops_vy2 = grad(self.net_grad_v, 1, (0, 1)) # dv2/dydx, dv2/dy2 + + def construct(self, x, y): + """Network forward pass""" + u, v, p = self.neural_net(x, y) + + u_x, u_y = self.net_grad_u(x, y) + u_xx, _ = self.ops_ux2(x, y) + _, u_yy = self.ops_uy2(x, y) + + v_x, v_y = self.net_grad_v(x, y) + v_xx, _ = self.ops_vx2(x, y) + _, v_yy = self.ops_vy2(x, y) + + p_x, p_y = self.net_grad_p(x, y) + + f_u = (u * u_x + v * u_y) + p_x - (1.0 / 40) * (u_xx + u_yy) + f_v = (u * v_x + v * v_y) + p_y - (1.0 / 40) * (v_xx + v_yy) + f_e = u_x + v_y + + return u, v, p, f_u, f_v, f_e + + +class Net(nn.Cell): + """MLP network""" + def __init__(self, layers, lowb, upb): + super().__init__() + self.lowb, self.upb = lowb, upb + self.mlp = MLP(layers=layers, weight_init=XavierTruncNormal(), bias_init="zeros", + activation="tanh") + + def construct(self, x, y): + """Network forward pass""" + out = ops.concat([x, y], 1) + out = 2.0 * (out - self.lowb) / (self.upb - self.lowb) - 1.0 + out = self.mlp(out) + return ops.split(out, split_size_or_sections=1, axis=1) diff --git a/MindFlow/applications/research/nsf_nets/src/process.py b/MindFlow/applications/research/nsf_nets/src/process.py new file mode 100644 index 000000000..20bd7782f --- /dev/null +++ b/MindFlow/applications/research/nsf_nets/src/process.py @@ -0,0 +1,28 @@ +# Copyright 2023 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +"""process for nsf_nets""" +import os + +import yaml + +from sciai.utils import parse_arg + + +def prepare(): + abs_dir = os.path.abspath(os.path.dirname(__file__)) + with open(f"{abs_dir}/../config.yaml") as f: + config_dict = yaml.safe_load(f) + args_ = parse_arg(config_dict) + return (args_,) diff --git a/MindFlow/applications/research/nsf_nets/train.py b/MindFlow/applications/research/nsf_nets/train.py new file mode 100644 index 000000000..785447db6 --- /dev/null +++ b/MindFlow/applications/research/nsf_nets/train.py @@ -0,0 +1,61 @@ +# Copyright 2023 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +"""nsf nets train""" +import os + +import mindspore as ms +from mindspore import nn + +from eval import evaluate +from sciai.common import TrainCellWithCallBack +from sciai.context import init_project +from sciai.utils import amp2datatype, calc_ckpt_name +from sciai.utils.python_utils import print_time +from src.dataset import generate_data +from src.network import VPNSFnet +from src.process import prepare + + +def train(n_iter, learning_rate, net, args, *data): + """train""" + optim = nn.optim.Adam(net.trainable_params(), learning_rate) + ckpt_interval = 1000 if args.save_ckpt else 0 + train_cell = TrainCellWithCallBack(net, optim, + time_interval=args.print_interval, loss_interval=args.print_interval, + ckpt_interval=ckpt_interval, ckpt_dir=args.save_ckpt_path, + amp_level=args.amp_level, model_name=args.model_name) + for _ in range(n_iter): + train_cell(*data) + + +@print_time("train") +def main(args): + dtype = amp2datatype(args.amp_level) + lam, ub_train, vb_train, x_train, xb_train, y_train, yb_train = generate_data(args, dtype) + net = VPNSFnet(xb_train, yb_train, ub_train, vb_train, x_train, y_train, args.layers) + if args.load_ckpt: + ms.load_checkpoint(args.load_ckpt_path, net) + for single_lr, epoch_num in zip(args.lr, args.epochs): + train(epoch_num, single_lr, net, args, xb_train, yb_train, ub_train, vb_train, + x_train, y_train) + evaluate(lam, net) + if args.save_ckpt: + ms.save_checkpoint(net, os.path.join(args.save_ckpt_path, calc_ckpt_name(args))) + + +if __name__ == "__main__": + args_ = prepare() + init_project(args=args_[0]) + main(*args_) -- Gitee