Scipy的solve_ivp报Cannot unpack non-iterable float错误如何解决
报错直接原因
solve_ivp要求传入的微分函数签名必须是**dSdt(t, S, *args)**,你写的dSdt(S,t,c_n, mp_n, q_n)把t和S的顺序写反了。调用时solve_ivp会先把当前时间(浮点型)传给函数的第一个参数,你把浮点型的t赋值给了S,后续执行vx, x, vy, y, vz, z = S时自然会报「无法解包非可迭代浮点对象」的错误。
其他需要修正的错误
- 你在
dSdt中调用dvx_dt_f等lambdify生成的数值函数时,传入的仍然是SymPy符号变量c/m/q/Ex/Ey/Ez/Bx/By/Bz,没有替换成实际数值,其中Ex/Ey/Ez/Bx/By/Bz你完全没有定义对应的数值实现,运行会继续报错。 - 定义热速度
vth_n时用到的温度变量T_n没有赋值,会触发NameError。 - SymPy的
solve方法参数是小写的simplify,你写的首字母大写Simplify不生效。
修正示例
首先调整微分函数的参数顺序,补充所有变量的数值定义:
# 1. 先定义温度,不然vth_n会报错 T_n = 1e6 # 可替换为你的实际温度值 vth_n = np.sqrt(kB_n*T_n/mp_n) # 2. 先实现E和B的数值函数,示例为均匀恒定场,可替换为你的实际场分布 def get_E(x,y,z,t): return np.array([0, 0, 0]) # 示例:零电场 def get_B(x,y,z,t): return np.array([0, 0, 1e4]) # 示例:z方向1万高斯磁场 # 3. 修正dSdt的参数顺序,替换所有符号变量为实际数值 def dSdt(t, S, c_n, mp_n, q_n): vx, x, vy, y, vz, z = S # 先获取当前位置的场数值 Ex, Ey, Ez = get_E(x,y,z,t) Bx, By, Bz = get_B(x,y,z,t) return [ dvx_dt_f(c_n, mp_n, q_n, x, y, z, vx, vy, vz, Ex, Ey, Ez, Bx, By, Bz), dx_dt_f(vx), dvy_dt_f(c_n, mp_n, q_n, x, y, z, vx, vy, vz, Ex, Ey, Ez, Bx, By, Bz), dy_dt_f(vy), dvz_dt_f(c_n, mp_n, q_n, x, y, z, vx, vy, vz, Ex, Ey, Ez, Bx, By, Bz), dz_dt_f(vz) ]
修正后再调用solve_ivp即可正常运行。
内容的提问来源于stack exchange,提问作者jokerp
相关产品推荐
相关产品推荐

