【问题标题】:Solving system of des using method of lines - spatially discretised使用线法求解des的系统-空间离散
【发布时间】:2026-02-14 04:45:01
【问题描述】:

我正在尝试使 this example using the method of lines so solve a pde 适应 des 系统。这不是我要解决的系统,只是一个示例。

如何合并第二个 de?我尝试将odefunc 修改为

def odefunc(u,t):
    dudt = np.zeros(X.shape)
    dvdt = np.zeros(X.shape)

    dudt[0] = 0 # constant at boundary condition
    dudt[-1] = 0

    dvdt[0] = 0
    dvdt[-1] = 0


    # for the internal nodes
    for i in range (1, N-1):
        dudt[i] = k* (u[i+1] - 2*u[i] + u[i-1]) / h**2
        dvdt[i] = u[i]
    return [dudt,dvdt]

基于我发现的几个 odes 系统示例解决方案 - 但由于我已经有一个 dudt 数组,我怀疑这可能是我的问题。我也不知道我的初始条件现在应该是什么样子,所以它们是正确的尺寸等。

我得到的错误是 The array return by func must be one-dimensional, but got ndim=2. 在线sol = odeint(odefunc, init, tspan)

以单个 pde 为例

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt

plt.interactive(False) 

N = 5 # number of points to discretise
L = 1.0 # length of the rod
X = np.linspace(0,L,N)
h = L/ (N  - 1)

k = 0.02

def odefunc(u,t):
    dudt = np.zeros(X.shape)

    dudt[0] = 0 # constant at boundary condition
    dudt[-1] = 0


    # for the internal nodes
    for i in range (1, N-1):
        dudt[i] = k* (u[i+1] - 2*u[i] + u[i-1]) / h**2
    return dudt

init = 150.0 * np.ones(X.shape) # initial temperature
init[0] = 100.0 # boundary condition
init[-1] = 200.0 # boundary condition

tspan = np.linspace(0.0, 5.0, 100)
sol = odeint(odefunc, init, tspan)

for i in range(0, len(tspan), 5):
    plt.plot(X,sol[i], label = 't={0:1.2f}'.format(tspan[i]))

# legend outside the figure
plt.legend(loc='center left', bbox_to_anchor=(1,0.5))
plt.xlabel('X position')
plt.ylabel('Temperature')

# adjust figure edges so the legend is in the figure
plt.subplots_adjust(top=0.89, right = 0.77)
plt.show()

【问题讨论】:

    标签: python scipy pde


    【解决方案1】:

    从 ode 函数的 odeint documentation 将 y 定义为一个向量,但您将它定义为一个向量列表。

    解决一阶odes的刚性或非刚性系统的初始值问题:

    dy/dt = func(y, t, ...) [or func(t, y, ...)]

    其中 y 可以是一个向量。

    您可以简单地使用ravel 函数从向量列表中创建一个向量。这是您的代码中的一个示例:

    import numpy as np
    from scipy.integrate import odeint
    import matplotlib.pyplot as plt
    plt.interactive(False) 
    N = 5 # number of points to discretise
    L = 1.0 # length of the rod
    X = np.linspace(0,L,N)
    h = L/ (N  - 1)
    k = 0.02
    def odefunc2(y,t):
        
        u = y[:N]
        v = y[N:]
        
        dudt = np.zeros_like(u)
        dvdt = np.zeros_like(v)    
    
        dudt[0] = 0 # constant at boundary condition
        dudt[-1] = 0
        
        dvdt[0] = 0
        dvdt[-1] = 0
        # for the internal nodes
        for i in range (1, N-1):
            dudt[i] = k* (u[i+1] - 2*u[i] + u[i-1]) / h**2
            dvdt[i] = u[i]
        return np.ravel([dudt, dvdt])
    
    initu = 150.0 * np.ones(X.shape) # initial temperature
    initu[0] = 100.0 # boundary condition
    initu[-1] = 200.0 # boundary condition
    
    initv = np.zeros(X.shape) # initial v
    
    init = np.ravel([initu, initv])
    
    tspan = np.linspace(0.0, 5.0, 100)
    sol = odeint(odefunc2, init, tspan)
    
    fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2)
    
    for i in range(0, len(tspan)):
        ax1.plot(X, sol[i, :N], label = 't={0:1.2f}'.format(tspan[i]))
        ax2.plot(X, sol[i, N:], label = 't={0:1.2f}'.format(tspan[i]))
    
    plt.show()
    
    

    【讨论】: