在尝试使用 RK4 求解以下方程组后,即使我使用 Cash-Karp 方法结合了自适应时间步长,输出似乎也具有大而快的振荡。我现在正在寻找具有更复杂工具(例如 BDF 方法)的现有求解器来求解 PDE,并且遇到了我希望能够工作的odespy 。
这是问题所在:
odespy 的教程相当详细。虽然有帮助,但缺少如何实现具有时间和空间导数的 PDE 系统的示例,我想知道 odespy 是否真的可以解决这样的问题。我主要是好奇,因为使用线的方法将这种情况减少到解决 ODE 系统的系统。到目前为止,这是我的代码:
import odespy
import matplotlib
matplotlib.use('pdf')
import os
import matplotlib.pyplot as plt
from pylab import *
import numpy as np
c = 3.*(10.**8.)
N = 500
zmax = 1000.
z = np.linspace(0.,zmax,N+1)
f_kwargs = dict(L=zmax, z=z)
y_1 = np.zeros((N+1),dtype=np.complex_) #should be [Nz x Nt] array
y_2 = np.zeros((N+1),dtype=np.complex_)
y_3 = np.zeros((N+1),dtype=np.complex_)
y_4 = np.zeros((N+1),dtype=np.complex_)
u = y_1,y_2,y_3,y_4
U_0 = np.zeros((4,N+1),dtype=np.complex_)
U_0[0][:] = np.cos(0.01)*(np.e**(z[:]/c))
U_0[1][:] = np.sin(0.01)*(np.e**(z[:]/c))
U_0[2][:] = 0.
U_0[3][:] = 0.
def rhs(u, t, L=None, beta=None, z=None):
N = len((u[0])[:]) - 1 #the PDE example specifies end condition, uses -1
dz = z[1] - z[0]
for i in range(0, N):
if i == 0:
OUT = [np.cos(0.01)*np.e**(-t),
np.sin(0.01)*np.e**(-t),
0.,
0.]
else:
OUT = [(y_2[i]*np.conj(y_3[i]) - y_1[i]),
(np.conj(y_3[i]*y_1[i]) - y_2[i]),
y_4[i],
(y_4[i] - ((y_3[i])**2.)*(1./dz)*np.conj(y_2[i+1] - y_2[i]))]
return OUT
solver = odespy.ForwardEuler(rhs, f_kwargs=f_kwargs,complex_valued=True)
solver.set_initial_condition(U_0)#solver.set_initial_condition(U_0)
dz = z[1] - z[0]
time_points = np.linspace(0.,600.,600) #t' = t/TR
dt = time_points[1] - time_points[0]
u, t = solver.solve(time_points)
此代码不起作用,我主要担心的是:
1) 无法以 odespy 可以处理我的 PDE(第 4 个方程)中的时间导数的方式正确制定方程,并且第 3 和第 4 个方程是 z 中的导数,而不是 t(这是第一个的导数)两个方程)。
2) 无法向 odespy 提供输入,使其可以采用 PDE 系统,然后应用此处概述的线方法。例如,一个已经可见的错误是我的初始/边界条件实现。我为我的输出和初始/边界条件使用了一个 4 x (N+1) 数组,但求解器并不期望从我收集的内容中得到这样的输入。
我仍在阅读文档,但想知道是否有人对上述内容有任何意见?任何关于如何解决上述问题的建议以及对 PDE 系统使用 odespy/数值方法的评论都将不胜感激。

