1. 方程背景与物理意义
1.1 一维热传导方程
一维热传导方程是描述热量在一维空间中传播的基本偏微分方程:
其中:
-
: 温度分布函数 -
: 时间变量 -
: 空间位置变量 -
: 热扩散系数
1.2 边界条件和初始条件
完整的热传导问题需要指定:
初始条件 (Initial Condition, IC):
边界条件 (Boundary Conditions, BC):
-
Dirichlet边界条件: , -
Neumann边界条件: ,
1.3 解析解
对于特定的初始和边界条件,热传导方程有解析解。本教程使用的测试解为:
其中 和 是控制衰减速度和空间频率的参数。当 很大时,这成为一个高频问题,对数值方法构成挑战。
2. 实际应用场景
2.1 工程应用
-
热传导分析: 建筑材料、电子器件散热设计 -
材料科学: 金属热处理过程建模 -
能源工程: 热交换器设计优化 -
地球物理: 地下温度场分析
2.2 多尺度挑战
在实际应用中,热传导问题经常涉及多个时间和空间尺度:
-
时间尺度: 从微秒级的瞬态响应到小时级的稳态过程 -
空间尺度: 从微米级的微观结构到米级的宏观系统 -
频率尺度: 从低频的缓慢变化到高频的快速振荡
3. PINNs核心数学原理
3.1 物理信息神经网络基本思想
PINNs通过将物理定律直接嵌入到神经网络的损失函数中,实现数据驱动与物理约束的融合。
神经网络近似:
其中 是神经网络参数。
3.2 损失函数构成
PINNs的总损失函数由三部分组成:
1. PDE残差损失 (Physics Loss):
2. 初始条件损失:
3. 边界条件损失:
3.3 自动微分
PINNs利用自动微分计算偏导数:
# 时间导数
u_t = torch.autograd.grad(u, t, grad_outputs=torch.ones_like(u), create_graph=True)[0]
# 空间一阶导数
u_x = torch.autograd.grad(u, x, grad_outputs=torch.ones_like(u), create_graph=True)[0]
# 空间二阶导数
u_xx = torch.autograd.grad(u_x, x, grad_outputs=torch.ones_like(u_x), create_graph=True)[0]
4. 时空多尺度网络数学原理
4.1 频谱偏置问题
标准神经网络存在**频谱偏置(Spectral Bias)**现象,即优先学习低频函数,难以拟合高频细节。对于热传导方程中的高频模式 ( 很大),这是一个严重问题。
4.2 傅里叶特征编码
Random Fourier Features (RFF) 通过随机频率编码解决频谱偏置:
其中:
-
是输入坐标 -
是随机频率矩阵, -
控制频率分布的标准差
数学原理:根据Bochner定理,任何平移不变的核函数都可以表示为傅里叶变换:
4.3 时空多尺度傅里叶网络
对于时空问题,我们可以分别处理时间和空间维度:
时间编码:
空间编码:
网络架构:
优势:
-
参数分离: 时间和空间特征分别学习,减少参数耦合 -
频率调节: 可针对时间和空间维度设置不同的频率参数 -
计算效率: 分离架构可能提高计算效率
4.4 多尺度数学分析
频率响应分析:对于输入频率 ,网络的频率响应由傅里叶特征的频率分布决定:
参数选择策略:
-
低频问题: -
高频问题: 问题特征频率 -
多尺度问题: 多个 值的组合
5. 代码架构解析
5.1 整体架构
torch_heat1D.py
├── Sampler 类 # 数据采样器
├── heat1D_NN 类 # 标准MLP网络
├── heat1D_FF 类 # 傅里叶特征网络
├── heat1D_ST_FF 类 # 时空分离网络
└── 主程序 # 模型训练和对比
5.2 类层次结构
每个PINN模型类都继承自 nn.Module,包含以下核心方法:
-
__init__(): 初始化网络架构和参数 -
forward(): 前向传播 -
net_u(): 预测函数值 -
net_r(): 计算PDE残差 -
train_model(): 训练循环 -
predict_u(): 预测新样本
6. 核心代码解读
6.1 Sampler类 - 数据采样
class Sampler:
def __init__(self, dim, coords, func, name=None):
self.dim = dim # 维度 (2D: 时间+空间)
self.coords = coords # 采样区域边界
self.func = func # 目标函数
self.name = name # 采样器名称
def sample(self, N):
# 在指定区域内均匀随机采样
x = self.coords[0:1, :] + (self.coords[1:2, :] - self.coords[0:1, :]) * np.random.rand(N, self.dim)
y = self.func(x) # 计算函数值
return x, y
设计思想:
-
统一接口处理不同类型的边界条件 -
支持任意维度的采样区域 -
灵活的函数评估机制
6.2 标准MLP网络 (heat1D_NN)
class heat1D_NN(nn.Module):
def _build_network(self, layers):
"""构建标准全连接网络"""
network_layers = []
for i in range(len(layers) - 1):
linear = nn.Linear(layers[i], layers[i + 1])
# Xavier初始化 - 重要!
nn.init.xavier_normal_(linear.weight)
nn.init.zeros_(linear.bias)
network_layers.append(linear)
# 除最后一层外使用tanh激活函数
if i < len(layers) - 2:
network_layers.append(nn.Tanh())
return nn.Sequential(*network_layers).to(self.device)
关键设计:
-
Xavier初始化: 防止梯度消失/爆炸 -
Tanh激活函数: 相比ReLU,tanh在PINNs中通常表现更好 -
深度架构: 多层结构增强非线性拟合能力
6.3 傅里叶特征编码 (heat1D_FF)
def fourier_feature_encoding(self, inputs):
"""傅里叶特征编码的核心实现"""
# inputs: [batch_size, 2] (t, x)
# self.W: [2, num_features] 随机频率矩阵
projected = torch.matmul(inputs, self.W) # [batch_size, num_features]
# 生成正弦和余弦特征
return torch.cat([torch.sin(projected), torch.cos(projected)], dim=1)
数学实现:
参数初始化:
# 关键参数:随机频率矩阵
self.W = torch.randn(2, layers[0] // 2, device=device) * sigma
self.W.requires_grad = False # 固定不训练
6.4 时空分离网络 (heat1D_ST_FF)
设计亮点:
-
分离编码: 时间和空间使用不同的频率参数 -
并行处理: 时空分支可以并行计算
6.5 PDE残差计算
def operator(u, t, x, k, sigma_t=1.0, sigma_x=1.0):
"""热传导方程的微分算子"""
# 计算时间导数
u_t = torch.autograd.grad(u, t, grad_outputs=torch.ones_like(u),
create_graph=True)[0] / sigma_t
# 计算空间一阶导数
u_x = torch.autograd.grad(u, x, grad_outputs=torch.ones_like(u),
create_graph=True)[0] / sigma_x
# 计算空间二阶导数
u_xx = torch.autograd.grad(u_x, x, grad_outputs=torch.ones_like(u_x),
create_graph=True)[0] / sigma_x
# PDE残差: u_t - k*u_xx = 0
residual = u_t - k * u_xx
return residual
技术细节:
-
create_graph=True: 启用高阶导数计算 -
归一化处理: sigma_t, sigma_x 用于数值稳定性 -
自动微分: PyTorch自动计算梯度图
6.6 训练循环
def train_model(self, nIter=10000, batch_size=128, lr=1e-3):
"""完整的训练循环"""
optimizer = optim.Adam(self.parameters(), lr=lr)
scheduler = optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.9)
for it in range(nIter):
optimizer.zero_grad()
# 1. 批量采样
X_ics_batch, u_ics_batch = self.fetch_minibatch(self.ics_sampler, batch_size)
X_bc1_batch, u_bc1_batch = self.fetch_minibatch(self.bcs_sampler[0], batch_size)
X_bc2_batch, u_bc2_batch = self.fetch_minibatch(self.bcs_sampler[1], batch_size)
X_res_batch, _ = self.fetch_minibatch(self.res_sampler, batch_size)
# 2. 前向传播
u_ics_pred = self.net_u(X_ics_batch[:, 0:1], X_ics_batch[:, 1:2])
u_bc1_pred = self.net_u(X_bc1_batch[:, 0:1], X_bc1_batch[:, 1:2])
u_bc2_pred = self.net_u(X_bc2_batch[:, 0:1], X_bc2_batch[:, 1:2])
r_pred = self.net_r(X_res_batch[:, 0:1], X_res_batch[:, 1:2])
# 3. 损失计算
loss_ic = torch.mean((u_ics_batch - u_ics_pred) ** 2)
loss_bc1 = torch.mean(u_bc1_pred ** 2) # 齐次边界条件
loss_bc2 = torch.mean(u_bc2_pred ** 2)
loss_res = torch.mean(r_pred ** 2) # PDE残差
total_loss = loss_res + (loss_bc1 + loss_bc2) + loss_ic
# 4. 反向传播和优化
total_loss.backward()
optimizer.step()
训练策略:
-
随机采样: 每个epoch重新采样训练点 -
多损失平衡: IC, BC, PDE损失同等重要 -
学习率调度: 指数衰减提高收敛稳定性
7. 实验结果分析
7.1 高频问题挑战
代码中设置 b = 500,创建高频测试问题:
这个函数在空间上有500个周期,对神经网络来说是极大的挑战。
7.2 三种方法性能对比
预期结果:
-
Plain MLP: 在高频问题上表现最差,难以捕捉快速振荡 -
Fourier Features: 显著改善,能够学习高频模式 -
Spatial-Temporal FF: 在复杂时空耦合问题上可能最优
评估指标:
-
L2相对误差: -
训练时间: 收敛到给定精度的时间 -
参数效率: 精度与参数量的权衡
7.3 可视化分析
代码生成多种对比图:
-
解场对比: 精确解 vs 三种方法预测 -
误差分布: 绝对误差的空间分布 -
收敛曲线: 各损失函数的训练过程 -
性能统计: 定量指标对比
主要结果
时空多尺度网络的测试误差为6e-3,
MLP误差超过1,
比MLP精度提升2-3个数量级。
-
训练损失和测试误差
-
网络模型和结果对比
总结
本教程展示了PINNs在求解热传导方程中的应用,重点分析了时空多尺度网络的设计原理。关键要点:
-
物理约束: PINNs通过损失函数直接嵌入物理定律 -
频谱偏置: 傅里叶特征有效解决神经网络的高频学习困难 -
架构创新: 时空分离设计提供了处理复杂偏微分方程的新思路 -
工程实用: 代码提供了完整的训练、评估和可视化框架
这种方法在科学计算、工程仿真等领域有广阔的应用前景,特别是在处理多尺度、高频、复杂边界条件的偏微分方程问题上显示出独特优势。
【完整教程+代码+结果绘图,留言:ST-code(有偿),往期代码教程留言】

