首页
/ DeepXDE项目教程:一维泊松方程的Dirichlet/Periodic边界条件求解

DeepXDE项目教程:一维泊松方程的Dirichlet/Periodic边界条件求解

2025-07-09 07:59:44作者:沈韬淼Beryl

问题描述

本教程将介绍如何使用DeepXDE框架求解具有Dirichlet和Periodic边界条件的一维泊松方程。泊松方程是科学计算中常见的一类偏微分方程,广泛应用于电磁学、流体力学和热传导等领域。

我们考虑的具体方程形式为:

-∇²u = π²sin(πx), x ∈ [-1, 1]

边界条件设置如下:

  • 左边界(x=-1)处采用Dirichlet边界条件:u(-1)=0
  • 右边界(x=1)处采用Periodic边界条件:u(0)=u(1)

该问题的解析解为u(x) = sin(πx),我们将使用深度学习方法逼近这个解。

环境准备与导入

首先需要导入必要的Python模块:

import deepxde as dde
import numpy as np
from deepxde.backend import tf

这里我们导入了DeepXDE主模块、NumPy数值计算库以及TensorFlow后端接口。

计算几何定义

DeepXDE提供了方便的几何定义工具,对于一维问题,我们可以使用Interval类:

geom = dde.geometry.Interval(-1, 1)

这定义了一个从-1到1的一维区间,作为我们问题的求解域。

偏微分方程残差定义

接下来定义泊松方程的残差形式:

def pde(x, y):
    dy_xx = dde.grad.hessian(y, x)
    return -dy_xx - np.pi ** 2 * tf.sin(np.pi * x)

这里:

  • x是输入坐标
  • y是神经网络预测的解
  • dde.grad.hessian计算二阶导数
  • 返回值为PDE残差,理想情况下应为0

边界条件定义

Periodic边界条件

右边界(x=1)处的Periodic边界条件需要定义一个判断函数:

def boundary_r(x, on_boundary):
    return on_boundary and dde.utils.isclose(x[0], 1)

这个函数返回True当且仅当点在边界上且x坐标接近1。使用dde.utils.isclose是为了避免浮点数精度问题。

Dirichlet边界条件

左边界(x=-1)处的Dirichlet边界条件类似:

def boundary_l(x, on_boundary):
    return on_boundary and dde.utils.isclose(x[0], -1)

边界值函数

我们还需要定义边界上的值函数:

def func(x):
    return np.sin(np.pi * x)

这个函数实际上就是我们的解析解,用于Dirichlet边界条件的值设定和误差计算。

边界条件对象创建

基于上述定义,我们可以创建边界条件对象:

bc1 = dde.icbc.DirichletBC(geom, func, boundary_l)  # Dirichlet边界
bc2 = dde.icbc.PeriodicBC(geom, 0, boundary_r)      # Periodic边界

PDE问题定义

将几何、PDE残差和边界条件组合成完整的PDE问题:

data = dde.data.PDE(
    geom, 
    pde, 
    [bc1, bc2], 
    16,  # 内部训练点数
    2,   # 边界训练点数
    solution=func,  # 参考解
    num_test=100    # 测试点数
)

神经网络构建

我们使用全连接神经网络(FNN)作为求解器:

layer_size = [1] + [50] * 3 + [1]  # 1输入层,3个50神经元隐藏层,1输出层
activation = "tanh"                 # 激活函数
initializer = "Glorot uniform"      # 权重初始化
net = dde.nn.FNN(layer_size, activation, initializer)

这种结构对于一维问题通常能取得不错的效果,tanh激活函数适合处理光滑解。

模型训练

模型编译

model = dde.Model(data, net)
model.compile(
    "adam",                # 优化器
    lr=0.001,              # 学习率
    metrics=["l2 relative error"]  # 评估指标
)

训练过程

losshistory, train_state = model.train(iterations=10000)

训练10000次迭代,返回损失历史记录和训练状态。

结果分析

训练完成后,可以观察到L2相对误差通常会收敛到很小的值(1e-3量级或更低),表明神经网络成功学习了泊松方程的解。

完整代码

以下是完整的实现代码:

import deepxde as dde
import numpy as np
from deepxde.backend import tf

# 定义几何
geom = dde.geometry.Interval(-1, 1)

# 定义PDE
def pde(x, y):
    dy_xx = dde.grad.hessian(y, x)
    return -dy_xx - np.pi ** 2 * tf.sin(np.pi * x)

# 定义边界条件
def boundary_r(x, on_boundary):
    return on_boundary and dde.utils.isclose(x[0], 1)

def boundary_l(x, on_boundary):
    return on_boundary and dde.utils.isclose(x[0], -1)

def func(x):
    return np.sin(np.pi * x)

bc1 = dde.icbc.DirichletBC(geom, func, boundary_l)
bc2 = dde.icbc.PeriodicBC(geom, 0, boundary_r)

# 定义PDE问题
data = dde.data.PDE(geom, pde, [bc1, bc2], 16, 2, solution=func, num_test=100)

# 构建神经网络
layer_size = [1] + [50] * 3 + [1]
activation = "tanh"
initializer = "Glorot uniform"
net = dde.nn.FNN(layer_size, activation, initializer)

# 构建模型并训练
model = dde.Model(data, net)
model.compile("adam", lr=0.001, metrics=["l2 relative error"])
losshistory, train_state = model.train(iterations=10000)

总结

本教程展示了如何使用DeepXDE求解带混合边界条件的一维泊松方程。通过合理定义PDE残差和边界条件,配合适当的神经网络结构,我们可以有效求解这类微分方程问题。这种方法可以扩展到更高维度和更复杂的边界条件问题。