如何在PyTorch中对用于PINN的一维热方程进行无量纲化?
一维热方程PINN的无量纲化实现(PyTorch)
一、无量纲化推导
原热方程:
$$\frac{\partial u}{\partial t} = \alpha \frac{\partial^2 u}{\partial x^2}$$
针对你的场景(杆长$L=1\ \text{m}$,时长$T=86400\ \text{s}$),定义无量纲变量:
- 无量纲空间:$\xi = \frac{x}{L}$(范围$[0,1]$)
- 无量纲时间:$\tau = \frac{t}{T}$(范围$[0,1]$)
- 无量纲温度:$u' = \frac{u}{U}$($U$为特征温度,比如初始与边界的温度差,若无需温度缩放可直接取$u'=u$)
代入原方程推导得无量纲形式:
$$\frac{\partial u'}{\partial \tau} = Fo \cdot \frac{\partial^2 u'}{\partial \xi^2}$$
其中$Fo = \frac{\alpha T}{L^2}$是傅里叶数(无量纲参数),由你的$\alpha$、$T$、$L$计算得到。
二、PyTorch中的实现修改
需要修改以下三个核心部分:
1. 输入数据的无量纲化预处理
在生成或加载训练数据(包括PDE采样点、初始/边界条件点)时,先将原始的$x$(单位m)和$t$(单位s)转换为无量纲变量:
# 定义常量 L = 1.0 # 杆长,单位m T = 86400.0 # 总时长,单位s alpha = 你的alpha值 # 单位m²/s Fo = alpha * T / (L ** 2) # 计算傅里叶数 # 对输入数据x(空间)、t(时间)做无量纲化 def normalize_input(x, t): xi = x / L tau = t / T # 组合成网络输入(形状:[N, 2],第一列ξ,第二列τ) return torch.cat([xi, tau], dim=1)
后续所有输入网络的数据(包括x_PDE、初始条件点、边界条件点)都要经过这个函数处理。
2. 修改PDE残差损失函数
原代码基于有量纲变量计算导数,现在适配无量纲方程。修改后的损失函数如下:
def lossPDE(self, x_PDE_normalized): # x_PDE_normalized是无量纲输入,形状[N,2],列分别是ξ和τ g = x_PDE_normalized.clone() g.requires_grad = True f = self.forward(g) # f对应无量纲温度u' # 计算一阶导数:∂u'/∂ξ 和 ∂u'/∂τ f_xi_tau = torch.autograd.grad( f, g, torch.ones([g.shape[0], 1]).to(device), retain_graph=True, create_graph=True )[0] f_tau = f_xi_tau[:, [1]] # ∂u'/∂τ # 计算二阶导数:∂²u'/∂ξ² f_xi2_tau2 = torch.autograd.grad( f_xi_tau, g, torch.ones(g.shape).to(device), create_graph=True )[0] f_xi2 = f_xi2_tau2[:, [0]] # ∂²u'/∂ξ² # 无量纲PDE残差:∂u'/∂τ - Fo * ∂²u'/∂ξ² pde_residual = f_tau - self.Fo * f_xi2 return self.loss_function(pde_residual, self.f_hat)
注意:需要在类中添加Fo属性,初始化时传入计算好的傅里叶数。
3. 初始/边界条件的适配
如果初始条件或边界条件涉及有量纲的温度值,也要同步做无量纲化(比如初始温度$u_0(x)$转换为$u_0'(x) = u_0(x)/U$),确保网络输出的无量纲温度和标签匹配。
三、关键说明
- 无量纲化后,输入变量$\xi$和$\tau$都在$[0,1]$范围内,能有效缓解PINN训练中因变量尺度差异导致的梯度不稳定问题。
- 傅里叶数$Fo$是唯一的无量纲参数,若后续调整场景(比如杆长、时长),只需重新计算$Fo$即可,无需大幅修改网络结构。
内容的提问来源于stack exchange,提问作者Link_tester
相关产品推荐
相关产品推荐

