pytorch PINN求解分段初边值条件不为sin(pi*x)的Burger方程的间断问题的预测解和真实解以及误差等值线图的代码
时间: 2024-02-13 17:05:12 浏览: 120
以下是求解分段初边值条件不为sin(pi*x)的Burger方程的间断问题的预测解和真实解以及误差等值线图的代码:
```python
import torch
import numpy as np
import matplotlib.pyplot as plt
# 设置随机数种子,以便结果可重现
torch.manual_seed(1234)
np.random.seed(1234)
# 定义Burger方程
def f(u, v, x):
u_x = torch.autograd.grad(u, x, grad_outputs=torch.ones_like(u), create_graph=True)[0]
v_x = torch.autograd.grad(v, x, grad_outputs=torch.ones_like(v), create_graph=True)[0]
return u*v_x + 0.01*torch.autograd.grad(v_x, x, grad_outputs=torch.ones_like(v_x), create_graph=True)[0] - 0.1*u_x
# 定义边界条件
def g_left(t):
return 0.5*(torch.tanh(20*(0.25-t)) + 1)
def g_right(t):
return 0.5*(torch.tanh(20*(0.75-t)) + 1)
def h(u):
return u
# 定义PINN模型
class PINN(torch.nn.Module):
def __init__(self):
super(PINN, self).__init__()
self.fc1 = torch.nn.Linear(1, 50)
self.fc2 = torch.nn.Linear(50, 50)
self.fc3 = torch.nn.Linear(50, 50)
self.fc4 = torch.nn.Linear(50, 1)
def forward(self, x):
h = x
h = torch.nn.functional.relu(self.fc1(h))
h = torch.nn.functional.relu(self.fc2(h))
h = torch.nn.functional.relu(self.fc3(h))
h = self.fc4(h)
return h
# 定义训练函数
def train(model, x_left, x_right, x_inner, y_left, y_right, optimizer, epochs):
losses = []
for epoch in range(epochs):
optimizer.zero_grad()
# 计算边界损失
y_pred_left = model(x_left)
y_pred_right = model(x_right)
loss_boundary = torch.mean((g_left(0) - y_pred_left)**2) + torch.mean((g_right(0) - y_pred_right)**2)
# 计算内部损失
u = x_inner[:, 0]
t = x_inner[:, 1]
u.requires_grad = True
t.requires_grad = True
v = model(u)
f_pred = f(u, v, t)
loss_interior = torch.mean((f_pred)**2)
# 计算总损失
loss = loss_boundary + loss_interior
# 反向传播和优化
loss.backward()
optimizer.step()
# 记录损失
losses.append(loss.item())
# 打印中间结果
if epoch % 1000 == 0:
print("Epoch {}: Loss {}".format(epoch, loss.item()))
return losses
# 生成训练数据
n_left = 50
n_right = 50
n_inner = 2000
x_left = torch.linspace(0, 0.25, n_left)[:, None]
x_right = torch.linspace(0.75, 1, n_right)[:, None]
x_inner = torch.rand(n_inner, 2)
x_inner[:, 0] = x_inner[:, 0]*0.5 + 0.25
x_inner[:, 1] = x_inner[:, 1]*2
y_left = g_left(0)
y_right = g_right(0)
# 训练模型
model = PINN()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
losses = train(model, x_left, x_right, x_inner, y_left, y_right, optimizer, epochs=10000)
# 绘制真实解和预测解的等值线图
x = torch.linspace(0, 1, 100)[:, None]
t = torch.linspace(0, 2, 100)[:, None]
u_true = torch.zeros(100, 100)
u_pred = torch.zeros(100, 100)
for i in range(100):
for j in range(100):
u_true[i, j] = h(g_left(t[j])*(x[i] <= 0.25) + g_right(t[j])*(x[i] >= 0.75) + (1 - x[i])*(x[i] > 0.25)*(x[i] < 0.5)*(t[j] <= 1) + x[i]*(x[i] > 0.5)*(x[i] < 0.75)*(t[j] <= 1) + (1 - x[i])*(x[i] > 0.25)*(x[i] < 0.5)*(t[j] > 1) + (1 - x[i])*(x[i] > 0.5)*(x[i] < 0.75)*(t[j] > 1))
u_pred[i, j] = model(torch.cat([x[i, None], t[j, None]], dim=1)).item()
fig, axs = plt.subplots(1, 3, figsize=(12, 4))
axs[0].contourf(x, t, u_true, levels=100, cmap="rainbow")
axs[0].set_xlabel("x")
axs[0].set_ylabel("t")
axs[0].set_title("True Solution")
axs[1].contourf(x, t, u_pred, levels=100, cmap="rainbow")
axs[1].set_xlabel("x")
axs[1].set_ylabel("t")
axs[1].set_title("Predicted Solution")
axs[2].contourf(x, t, u_true - u_pred, levels=100, cmap="rainbow")
axs[2].set_xlabel("x")
axs[2].set_ylabel("t")
axs[2].set_title("Error")
plt.show()
```
请注意,这段代码假设你已经安装了PyTorch和Matplotlib。
阅读全文