论文理解:“Gradient-enhanced physics-informed neural networks for forwardand inverse PDE problems“

译:梯度增强物理信息神经网络用于正向和反向偏微分方程问题

-- Computer methods in applied mechanics engineering -- 2022


目录

一、引言

二、方法

2.1、PINN

2.2、gPINNs

2.3、基于残差自适应细化(RAR)的gPINN算法

三、实验

3.1、函数逼近

3.2、PDE正问题

3.3、PDE逆问题

3.4、通过RAR增强gPINN

3.5、gPINN的计算成本


一、引言

        物理信息神经网络(PINNs)通过使用自动微分将PDE嵌入神经网络的损失中来求解PDE,而且解决反PDE问题就像解决正向问题一样容易。但是提高PINN的精度和效率是一个有待解决的问题。

        PINN使用PDE残差作为每个PDE的相应损失,尚未注意到PDE的其他类型的损失。作者想到如果PDE残差为零,PDE残差的梯度也应该为零

        因此作者提出了梯度增强的PINN (gPINN),它利用一种新型的损失函数,利用PDE残差的梯度信息来提高PINN的精度。

二、方法

2.1、PINN

        首先回忆一下PINN怎么解决正向和逆向问题。

考虑由定义域Ω上定义的参数λ参数化的解u(x, t)的下列偏微分方程:

边界条件:

简单来说就是用神经网络近似u(x)优化下列损失即可解决正向问题:

其中:

(2)式使用的是定义域内部的点,(3)式是边界点。

而对于逆问题,λ就未知了,同时又多了对u的已知量,因此损失变成:

即多了一项:

对于怎样获取参数λ:解决正问题时,优化损失得到网络参数即可。但是解决逆问题时,要把pde的参数λ也设置成变量去更新,即优化逆问题的损失同时得到网络参数和pde的参数λ。

2.2、gPINNs

        引言中提到f的导数也是零。即:

损失在PINN的基础上变为:

其中:

注意,本文的\mathcal{T}_{gi}\mathcal{T}_f是一样的,但可以不一样。

通过后面的实验结果能发现,gPINN提高了u的预测解的精度,并且需要更少的训练点。gPINN的一个动机是PINN的PDE残差通常在零附近波动,惩罚残差的斜率可以减少波动,使残差更接近零。

2.3、基于残差自适应细化(RAR)的gPINN算法

具体算法如下:

三、实验

        下面是基于本文的网络做的各种实验,只选取部分实验做参考。

原文代码:https://github.com/lu-group/gpinn

3.1、函数逼近

        作者首先用一个函数逼近的例子来证明添加梯度信息的有效性。考虑下面的函数

 训练点均匀采样,损失如下:

还考虑以下带有额外梯度的损失函数:

结果如下:

3.2、PDE正问题

        下面将gPINN应用于偏微分方程的求解,以扩散反应方程为例,方程如下:

式中,u为溶质浓度,D = 1为扩散系数,R为化学反应

初始条件和边界条件如下:

解析解为:

作者选择合适的解代理来自动满足初始条件和边界条件(损失函数就不用考虑这两项了):

其中N(x)是神经网络。这里有两个梯度的损失项(对x和对t的导数损失),总的损失函数是

结果如下:

3.3、PDE逆问题

        这里考虑Brinkman-Forchheimer模型的有效粘度和渗透率。Brinkman-Forchheimer模型可以看作是扩展的达西定律,用于描述有壁边界的多孔介质流动:

其中,解u为流体速度,g为外力,v为流体的运动粘度,ε为多孔介质的孔隙率,K为渗透率。有效粘度v_e与孔隙结构有关,难以确定。设无滑移边界条件,即u(0) = u(1) = 0。这个问题的解析解是

其中r=\sqrt{\frac{v \epsilon}{v_e K}}。 

明确来说,这个例子的目标是推断v_e,同时优化网络的参数和v_e的值。作者只在5个传感器位置收集了速度u的数据测量。

结果如下:

接下来,作者将高斯噪声(均值0和标准差0.05)添加到观测值中,并使用12次u的测量值推断v_e和K。结果如下:

:不同于这个例子,如果PDE逆问题要求的方程参数是一个函数而不是一个常数的话,可以用另外一个网络去近似这个参数。具体参考原文PDE逆问题第二个例子。

3.4、通过RAR增强gPINN

        为了进一步提高gPINN求解刚性PDEs的精度和训练效率,在训练过程中应用RAR自适应地改善残差点的分布。

结果如下:

3.5、gPINN的计算成本

        gPINN相对于PINN的相对计算代价(下表中第二行的值)为gPINN的训练时间除以PINN的训练时间。

注:3.4和3.5的方程相同,没有表示出来。

最后,再附上原文代码:https://github.com/lu-group/gpinn

  • 2
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是用 PINN 求解二阶 Diffusion 方程的 PyTorch 代码: ```python import torch import numpy as np import matplotlib.pyplot as plt # 定义求解区域的左右边界 x_left = 0.0 x_right = 1.0 # 定义时间和空间步长 delta_t = 0.001 delta_x = 0.05 # 定义神经网络的输入维度和隐藏层维度 input_dim = 2 hidden_dim = 10 # 定义神经网络的输出维度 output_dim = 1 # 定义 Diffusion 方程的初始条件和边界条件 def u_init(x): return np.sin(np.pi * x) def u_left(t): return 0.0 def u_right(t): return 0.0 # 定义神经网络模型 class PINN(torch.nn.Module): def __init__(self): super(PINN, self).__init__() self.fc1 = torch.nn.Linear(input_dim, hidden_dim) self.fc2 = torch.nn.Linear(hidden_dim, hidden_dim) self.fc3 = torch.nn.Linear(hidden_dim, output_dim) def forward(self, x, t): # 拼接时间和空间坐标作为神经网络的输入 xt = torch.cat([x, t], dim=1) h1 = torch.tanh(self.fc1(xt)) h2 = torch.tanh(self.fc2(h1)) out = self.fc3(h2) return out # 定义 PINN 的损失函数 def pinn_loss(model, x_left, x_right, delta_t, delta_x): # 定义空间和时间的网格 x = torch.linspace(x_left, x_right, int((x_right - x_left) / delta_x) + 1).unsqueeze(1) t = torch.linspace(0, 1, int(1 / delta_t) + 1).unsqueeze(1) # 计算模型在内部网格点上的预测值 x_internal = x[1:-1] t_internal = t[1:-1] u_internal = model(x_internal, t_internal) # 计算模型在左右边界上的预测值 u_left_boundary = model(x_left, t_internal) u_right_boundary = model(x_right, t_internal) # 计算初始条件和边界条件的损失 init_loss = torch.mean((model(x, torch.zeros_like(x)) - u_init(x)) ** 2) left_boundary_loss = torch.mean((u_left_boundary - u_left(t_internal)) ** 2) right_boundary_loss = torch.mean((u_right_boundary - u_right(t_internal)) ** 2) # 计算 Diffusion 方程的残差 u_x = torch.autograd.grad(u_internal, x_internal, grad_outputs=torch.ones_like(u_internal), create_graph=True)[0] u_xx = torch.autograd.grad(u_x, x_internal, grad_outputs=torch.ones_like(u_x), create_graph=True)[0] f = u_xx - (1 / delta_t) * (u_internal - u_init(x_internal)) # 计算残差的损失 residual_loss = torch.mean(f ** 2) # 计算总的损失 loss = init_loss + left_boundary_loss + right_boundary_loss + residual_loss return loss # 初始化神经网络模型和优化器 model = PINN() optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # 训练神经网络模型 for i in range(10000): optimizer.zero_grad() loss = pinn_loss(model, x_left, x_right, delta_t, delta_x) loss.backward() optimizer.step() if i % 1000 == 0: print("Iteration {}, Loss = {}".format(i, loss.item())) # 使用训练好的神经网络模型进行预测 x_test = torch.linspace(x_left, x_right, 101).unsqueeze(1) t_test = torch.linspace(0, 1, 1001).unsqueeze(1) u_test = model(x_test, t_test).detach().numpy() # 绘制预测结果 X, T = np.meshgrid(x_test, t_test) plt.pcolormesh(X, T, u_test, cmap='coolwarm') plt.colorbar() plt.xlabel("x") plt.ylabel("t") plt.title("PINN Solution to Diffusion Equation") plt.show() ``` 这段代码中,首先定义了求解区域的左右边界、时间和空间步长等参数,然后定义了 Diffusion 方程的初始条件和边界条件,以及神经网络模型和损失函数。在训练神经网络模型时,使用了 Adam 优化器,最后使用训练好的模型进行预测,并绘制了预测结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值