使用scipy.solve_ivp求解二维超音速绕翼型问题时的初始条件维度匹配困惑
scipy.solve_ivp求解二维超音速绕翼型问题时的初始条件维度匹配困惑
嗨,我来帮你理清楚这个问题~咱们一步步拆解:
首先解决初始条件的维度矛盾
scipy的solve_ivp有个明确的要求:初始条件必须是一维数组,不管你有多少组状态变量,都得把它们排成一条“长队”,而不是二维矩阵。你遇到的问题就是因为初始条件是(2,100)的二维数组,但函数里又需要按行访问phix和phiy,解决方法很简单:
- 把初始条件扁平化为一维数组
- 在ODE函数内部,把输入的扁平状态变量重新恢复成
(2,100)的形状进行计算,最后再把结果扁平返回
给你修改后的可运行代码示例:
import numpy as np import matplotlib.pyplot as plt from scipy.integrate import solve_ivp ## General Variables N=100 r = np.linspace(0, 1, N) s = np.linspace(-1, 1, N*2) R, S = np.meshgrid(r, s) y_max = 1 y_min = -1 y_upper = 0.1*r-0.1*r**2 y_lower = -0.1*r+0.1*r**2 Mach = 2 #given in problem ## Equation to solve def def SSonicFlowFun(t, P): # 把扁平的状态变量恢复成(2, N)的形状,方便按行访问phix和phiy P_reshaped = P.reshape(2, N) phix = P_reshaped[0, :] phiy = P_reshaped[1, :] # 保持元素级运算,y_upper是长度为N的数组,计算会自动广播 dpxdt = (y_max/(y_max - y_upper)) / (1 - Mach**2) * phiy dpydt = (y_max/(y_max - y_upper)) * phix # 把导数结果扁平化为一维返回,符合solve_ivp的要求 return np.concatenate([dpxdt, dpydt]) t_span = (0, 1) # 初始条件扁平化为一维数组,shape变为(200,) Phi0 = np.zeros((2, 100)).flatten() print(Phi0.shape) ## Solving ODE sol= solve_ivp(SSonicFlowFun, t_span, Phi0)
关于有限差分和时间积分的误区
你提到“solve_ivp是解决空间 too it should theoretically give same answer right?” 这里得纠正一下:
MIT课程里的思路是把空间维度用有限差分离散化,将PDE转化为大规模ODE系统——每个空间节点的phix和phiy都是ODE的状态变量,然后用ODE求解器在时间维度积分。你现在去掉了有限差分,相当于完全忽略了空间上的导数项,模型本身是不完整的,所以就算维度问题解决了,结果也和课程要求的不符。
等你搞定维度问题后,得把空间的有限差分矩阵加回去:比如你需要计算phix的二阶空间导数(或者其他空间导数项),用有限差分方法把这些导数转化为状态变量的线性组合,然后放到ODE的右端项(也就是dpxdt和dpydt的表达式里)。
为什么单个ODE(形状1,100)能运行?
因为当你用(1,100)的初始条件时,扁平后是(100,)的一维数组,函数里直接取P[0]其实是取第一个元素,但你误打误撞让逻辑跑通了,但本质上和多组状态变量的处理逻辑是一致的——只是少了一组变量而已。
备注:内容来源于stack exchange,提问作者Ricardo
相关产品推荐
相关产品推荐

