Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
平流方程中四阶Runge-Kutta的python程序设计_Python_Numerical Methods_Runge Kutta - Fatal编程技术网

平流方程中四阶Runge-Kutta的python程序设计

平流方程中四阶Runge-Kutta的python程序设计,python,numerical-methods,runge-kutta,Python,Numerical Methods,Runge Kutta,我想用Python编程一个对流方程(∂u/∂t) +c(∂u/∂x) =0。时间应采用龙格库塔四阶离散。空间离散化是二阶有限差分。当我运行我的代码时,我得到一条转换成正弦波的直线。但我给出的初始条件是正弦波。为什么它以直线开始?我想让正弦波向前移动。你知道如何使正弦波向前移动吗?我感谢你的帮助。提前谢谢 虽然表面上你的计算步骤与RK4方法有关,但它们偏离了RK4方法和正确的空间离散化,更不用说了 应用ODE积分方法的传统方法是使用函数导数(t,state,params),然后将其应用于计算Eul

我想用Python编程一个对流方程(∂u/∂t) +c(∂u/∂x) =0。时间应采用龙格库塔四阶离散。空间离散化是二阶有限差分。当我运行我的代码时,我得到一条转换成正弦波的直线。但我给出的初始条件是正弦波。为什么它以直线开始?我想让正弦波向前移动。你知道如何使正弦波向前移动吗?我感谢你的帮助。提前谢谢

虽然表面上你的计算步骤与RK4方法有关,但它们偏离了RK4方法和正确的空间离散化,更不用说了

应用ODE积分方法的传统方法是使用函数
导数(t,state,params)
,然后将其应用于计算Euler步长或RK4步长。在你的情况下是这样的

def衍生物(t、u、c、dx):
du=np.零(len(u));
p=c/(2*dx);
du[0]=p*(u[1]-u[-1]);
du[1:-1]=p*(u[2:-u[:-2]);
du[-1]=p*(u[0]-u[-2]);
返回du;
那你就可以了

X,dx=np.linspace(xmin,xmax,n+1,retstep=True);
X=X[:-1]#删除最后一点,因为u(X=1,t)=u(X=0,t)
m=500#时间步数
T=tmin+np.arange(m+1);
U=np.零((m+1,n),dtype=float)
U[0]=U=初始_(X);
对于范围内的k(m):
t=t[k];
k1=导数(t,u,c,dx)*dt;
k2=导数(t+0.5*dt,u+0.5*k1,c,dx)*dt;
k3=导数(t+0.5*dt,u+0.5*k2,c,dx)*dt;
k4=导数(t+dt,u+k3,c,dx)*dt;
U[k+1]=U=U+(k1+2*k2+2*k3+k4)/6;
这将使用时间步长中计算的
dt
作为主要变量,然后使用步长
dt
tmin
构造算术序列。其他方法也是可能的,但必须使
tmax
和时间步数兼容

至此为止的计算现在应该是成功的,并且可以在动画中使用。在我的理解中,你不会在每一帧中产生一个新的绘图,你只需要画一次图形,然后再改变线数据

#设置时间数据的动画
直线,=ax1.绘图(X,U[0],颜色为青色)
ax1.grid(真)
ax1.set_ylim([-2,2])
ax1.set_xlim([0,1])
定义动画(i):
line.set_ydata(U[i])
回程线,

等等。

虽然表面上你的计算步骤与RK4方法有关,但它们偏离了RK4方法和正确的空间离散化,更不用说了

应用ODE积分方法的传统方法是使用函数
导数(t,state,params)
,然后将其应用于计算Euler步长或RK4步长。在你的情况下是这样的

def衍生物(t、u、c、dx):
du=np.零(len(u));
p=c/(2*dx);
du[0]=p*(u[1]-u[-1]);
du[1:-1]=p*(u[2:-u[:-2]);
du[-1]=p*(u[0]-u[-2]);
返回du;
那你就可以了

X,dx=np.linspace(xmin,xmax,n+1,retstep=True);
X=X[:-1]#删除最后一点,因为u(X=1,t)=u(X=0,t)
m=500#时间步数
T=tmin+np.arange(m+1);
U=np.零((m+1,n),dtype=float)
U[0]=U=初始_(X);
对于范围内的k(m):
t=t[k];
k1=导数(t,u,c,dx)*dt;
k2=导数(t+0.5*dt,u+0.5*k1,c,dx)*dt;
k3=导数(t+0.5*dt,u+0.5*k2,c,dx)*dt;
k4=导数(t+dt,u+k3,c,dx)*dt;
U[k+1]=U=U+(k1+2*k2+2*k3+k4)/6;
这将使用时间步长中计算的
dt
作为主要变量,然后使用步长
dt
tmin
构造算术序列。其他方法也是可能的,但必须使
tmax
和时间步数兼容

至此为止的计算现在应该是成功的,并且可以在动画中使用。在我的理解中,你不会在每一帧中产生一个新的绘图,你只需要画一次图形,然后再改变线数据

#设置时间数据的动画
直线,=ax1.绘图(X,U[0],颜色为青色)
ax1.grid(真)
ax1.set_ylim([-2,2])
ax1.set_xlim([0,1])
定义动画(i):
line.set_ydata(U[i])
回程线,

等等。

首先,您需要使用较少的全局变量,尤其是
U
数组。作为参数传递更多。请注意,对于RK4,在非上次时间节点的Euler步长的状态下,需要进行3次导数求值。另外,
k
向量应该是导数函数的结果(此更改可能足以更正代码)。为了进一步简化代码,请考虑如何使用切片或卷积实现二阶导数。谢谢您的回答。在非上次时间节点的Euler步长的状态下进行3次导数求值到底是什么意思?你能澄清一下吗?稍后再读一遍,这与这里无关。您只是使用一种非常非常规的方法来获取阶段值。但是,之后的点仍然存在,函数
u
计算点/状态,而
k
向量应包含斜率/导数。我在k向量中包含导数函数。所以k值是用导数函数计算出来的。但我现在有很强的嗅觉。我编辑了我的代码。所以你可以看到它的新形式。你在用
(dx+deltax)
除法时做了一些非常奇怪的事情。通过它的使用,
deltax
应该是
deltat
,并且在任何时候它都不会被添加到
dx
。首先,您需要使用较少的全局变量,尤其是
U
数组。作为参数传递更多。请注意,对于RK4,在非上次时间节点的Euler步长的状态下,需要进行3次导数求值。另外,
k
向量应该是导数函数的结果(此更改可能足以更正代码)。为了进一步简化代码,请考虑如何使用切片或卷积实现二阶导数。谢谢您的回答。你到底是什么意思
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from math import pi

# wave speed
c = 1
# spatial domain
xmin = 0
xmax = 1
#time domain
m=500; # num of time steps 
tmin=0
T = tmin + np.arange(m+1);
tmax=500

n = 50 # num of grid points

# x grid of n points
X, dx = np.linspace(xmin, xmax, n+1, retstep=True);
X = X[:-1] # remove last point, as u(x=1,t)=u(x=0,t)

# for CFL of 0.1
CFL = 0.3
dt = CFL*dx/c


# initial conditions
def initial_u(x):
    return np.sin(2*pi*x)

# each value of the U array contains the solution for all x values at each timestep
U = np.zeros((m+1,n),dtype=float)
U[0] = u = initial_u(X);




def derivatives(t,u,c,dx):
    uvals = [] # u values for this time step
    for j in range(len(X)):
        if j == 0: # left boundary
            uvals.append((-c/(2*dx))*(u[j+1]-u[n-1]))
        elif j == n-1: # right boundary
            uvals.append((-c/(2*dx))*(u[0]-u[j-1]))
        else:
            uvals.append((-c/(2*dx))*(u[j+1]-u[j-1]))
    return np.asarray(uvals)


# solve for 500 time steps
for k in range(m):
    t = T[k];
    k1 = derivatives(t,u,c,dx)*dt;
    k2 = derivatives(t+0.5*dt,u+0.5*k1,c,dx)*dt;
    k3 = derivatives(t+0.5*dt,u+0.5*k2,c,dx)*dt;
    k4 = derivatives(t+dt,u+k3,c,dx)*dt;
    U[k+1] = u = u + (k1+2*k2+2*k3+k4)/6;

# plot solution
plt.style.use('dark_background')
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)

line, = ax1.plot(X,U[0],color='cyan')
ax1.grid(True)
ax1.set_ylim([-2,2])
ax1.set_xlim([0,1])
def animate(i):
    line.set_ydata(U[i])
    return line,