繁体   English   中英

ValueError:操作数无法与形状一起广播 (3,5) (3,)

[英]ValueError: operands could not be broadcast together with shapes (3,5) (3,)

我有 15 个 ode 方程需要同时求解,我想使用 solve_ivp 求解它们。

T、co2 和 q 各有 5 个状态。 初始条件为 T=20, co2 = 0, q=0

我试图将它们分成 3 个列表,一个用于 T,一个用于 co2,一个用于 q。

我不知道如何解决这个错误并且已经研究了几个小时。 非常感谢您的帮助!

import math
from scipy.integrate import solve_ivp
from bokeh.core.property.instance import Instance
from bokeh.io import save
from bokeh.layouts import column
from bokeh.model import Model
from bokeh.models import CustomJS, Slider, Callback
from bokeh.plotting import ColumnDataSource, figure, show
import numpy as np

# three plots , co2 as y and z as x

###############    User generated - Slider initial value   ############### 
V= 100.0 # volume
r = 5.0
T = 20.0
c_co2_0 = 5.0 # concentration
episl_r = 0.3 # void
v0 = 2.0 # initial vilocity

###############  ---          Static Parameters        ---  ############### 
b0 = 93.0 * (10**(-5))
deltH_0 = 95.3 # calculate b
Tw = -5.0 # room temperature
T0 = 353.15 # temeperature 
t0 = .37 # heterogeneity constant, in paper is denoted as t_h0
alpha = 0.33
chi = 0.0 
q_s0 = 3.40
R = 8.314
kT = 3.5*(10**3) #calculate rA
ρs = 880.0
deltH_co2 = 75.0 # calculate temeprature change 

# ------------------ For Equation 4 : Enegergy Ballance  --------------
ρg = 1.87 # ?
h = 13.8
Cp_g = 37.55 # J/molK
Cp_s = 1580.0 # J/molK

###############   -----  Parameters depend on input  -----  ############### 
L = V / (math.pi * r**2)
deltZ = L / 5.0 # 5 boxes in total
p_co2 = R * T * c_co2_0
a_s = deltZ / r
theta = (1-episl_r) * ρs * Cp_s +  episl_r * ρg * Cp_g

# Equations are calclulated in order 
def b(T):
    b = ( b0 ** ( (deltH_0/ (R * T0) ) * (T0/T - 1) ) )
    return b

def t_h(T):
    return ( t0 + alpha * (1 - T0 / T) )

def q_s(T):
    return ( q_s0 ** ( chi * (1 - T / T0)) )

# Calculate rco2_n (not ode)
# change it to q
def R_co2(T, c_co2, q): 
    b_var = b(T)
    t_var = t_h(T)
    qs_var = q_s(T)
    # print(qs_var)
    r_co2 =  kT * ( R * T * c_co2 * ( (1- ( (q / qs_var)**t_var) )**(1/t_var) ) - q / (b_var*qs_var) ) 
    # print(r_co2)
    return r_co2
# ODE Part 
# Repetitive shortcut

# Equation 2
ener_balan_part1 = v0  * ρg* Cp_g 
def ener_balan(theta, deltZ): # replace v0  * ρg* Cp_g / (theta * deltZ) 
    return(ener_balan_part1/ (theta*deltZ) )
def ener_balan2(episl_r):
    return( (1-episl_r) * ρs * deltH_co2)
def ener_balan3(a_s, Tw, T0):
    return (a_s * h *(Tw-T0))

# Equation 1 Mass Balance : find co2_n

def mass_balan(episl_r, deltZ):
    return ( v0/ (episl_r * deltZ) )
def masss_balan2(episl_r, ρs):
    return( (1-episl_r ) * ρs )
def deriv(t, y):
    T_n, co2_n, q_n = y
    # rco2_ first, rate of generation 
    T1 = -ener_balan(theta, deltZ) * T_n + ener_balan(theta, deltZ) * T0 + ener_balan2(episl_r)* (R_co2(T_n, co2_n, q_n))+ ener_balan3(a_s, Tw, T0)
    co2_1 = -mass_balan(episl_r, deltZ) * co2_n + mass_balan(episl_r, deltZ) * c_co2_0 - (R_co2(T_n, co2_n, q_n)) * masss_balan2(episl_r, ρs)
    q_1 = R_co2(T_n, co2_n, q_n)

    T2 = -ener_balan(theta, deltZ) * T_n + ener_balan(theta, deltZ) * T0 + ener_balan2(episl_r)* (R_co2(T_n, co2_n, q_n))+ ener_balan3(a_s, Tw, T0)
    co2_2 = -mass_balan(episl_r, deltZ) * co2_n + mass_balan(episl_r, deltZ) * c_co2_0 - (R_co2(T_n, co2_n, q_n)) * masss_balan2(episl_r, ρs)
    q_2 = R_co2(T_n, co2_n, q_n)

    T3 = -ener_balan(theta, deltZ) * T_n + ener_balan(theta, deltZ) * T0 + ener_balan2(episl_r)* (R_co2(T_n, co2_n, q_n))+ ener_balan3(a_s, Tw, T0)
    co2_3 = -mass_balan(episl_r, deltZ) * co2_n + mass_balan(episl_r, deltZ) * c_co2_0 - (R_co2(T_n, co2_n, q_n)) * masss_balan2(episl_r, ρs)
    q_3 = R_co2(T_n, co2_n, q_n)

    T4 = -ener_balan(theta, deltZ) * T_n + ener_balan(theta, deltZ) * T0 + ener_balan2(episl_r)* (R_co2(T_n, co2_n, q_n))+ ener_balan3(a_s, Tw, T0)
    co2_4 = -mass_balan(episl_r, deltZ) * co2_n + mass_balan(episl_r, deltZ) * c_co2_0 - (R_co2(T_n, co2_n, q_n)) * masss_balan2(episl_r, ρs)
    q_4 = R_co2(T_n, co2_n, q_n)

    T5 = -ener_balan(theta, deltZ) * T_n + ener_balan(theta, deltZ) * T0 + ener_balan2(episl_r)* (R_co2(T_n, co2_n, q_n))+ ener_balan3(a_s, Tw, T0)
    co2_5 = -mass_balan(episl_r, deltZ) * co2_n + mass_balan(episl_r, deltZ) * c_co2_0 - (R_co2(T_n, co2_n, q_n)) * masss_balan2(episl_r, ρs)
    q_5 = R_co2(T_n, co2_n, q_n)

    T_ls = np.array([T1, T2, T3, T4, T5])
    co2_ls = np.array([co2_1, co2_2, co2_3, co2_4, co2_5])
    q_ls = np.array([q_1, q_2, q_3, q_4, q_5])

    return T_ls, co2_ls, q_ls
    
t0, tf = 0, 10
############# initial condition 
T_initial = 20
c_co2_0 = 0
q0 = 0
init_cond = np.array([20, 0, 0])
N=5
soln = solve_ivp(deriv, (t0, tf), init_cond)

这是错误消息

helper.py:293: RuntimeWarning: divide by zero encountered in double_scalars
  r_co2 =  kT * ( R * T * c_co2 * ( (1- ( (q / qs_var)**t_var) )**(1/t_var) ) - q / (b_var*qs_var) )
Traceback (most recent call last):
  File "helper.py", line 350, in <module>
    soln = solve_ivp(deriv, (t0, tf), init_cond)
  File "/Users/cocochen/.local/share/virtualenvs/py-HkKPxrQC/lib/python3.8/site-packages/scipy/integrate/_ivp/ivp.py", line 546, in solve_ivp
    solver = method(fun, t0, y0, tf, vectorized=vectorized, **options)
  File "/Users/cocochen/.local/share/virtualenvs/py-HkKPxrQC/lib/python3.8/site-packages/scipy/integrate/_ivp/rk.py", line 96, in __init__
    self.h_abs = select_initial_step(
  File "/Users/cocochen/.local/share/virtualenvs/py-HkKPxrQC/lib/python3.8/site-packages/scipy/integrate/_ivp/common.py", line 104, in select_initial_step
    d1 = norm(f0 / scale)
ValueError: operands could not be broadcast together with shapes (3,5) (3,) 

当我重新创建确切的错误消息时,我给出了一个基于示例的答案。 所以这里的问题是你没有遵循Numpy 广播规则 这基本上说如果数组的尺寸相同等于 1 ,则可以广播数组(给定某些操作)。

让我们看一个带有错误和解决方案的示例:

 import numpy as np array_1 = np.arange(15).reshape(3,5) array_2 = np.arange(3)

array_1的形状为(3, 5) array_2的形状为(3,)

如果您尝试使用以下代码添加它们(在内部将被广播)

array_1 + array_2

这将是错误

ValueError: operands could not be broadcast together with shapes (3,5) (3,) 

由于我们没有遵循上述规则。 为了解决这个问题,我们需要像这样重塑 array_2

array_2 = array_2.reshape(-1,1)

现在,如果您检查,array_2 形状是

(3, 1)

现在如果我们尝试添加两个数组

array_1 + array_2

它将起作用,因为现在满足两个规则,两个数组都具有维度或维度值为 1(array_2 形状(3,1))

https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html

solve_ivpfun参数指定为

The calling signature is fun(t, y). Here t is a scalar, and there are two options for the ndarray y: 
It can either have shape (n,); then fun must return array_like with shape (n,).

yinit_cond = np.array([20, 0, 0]) ,形状 (3,)

这意味着deriv必须返回 (3,) 结果。 什么是

 deriv(0, init_cond)

我不会下载并运行你的代码,但deriv的结尾是

T_ls = np.array([T1, T2, T3, T4, T5])
co2_ls = np.array([co2_1, co2_2, co2_3, co2_4, co2_5])
q_ls = np.array([q_1, q_2, q_3, q_4, q_5])
return T_ls, co2_ls, q_ls

这将创建 3 个形状 (5,) 数组,并将它们作为元组返回。 这形成了一个 (3,5) 数组。

我的猜测是错误点

norm(f0 / scale)

f0来自试验func运行,因此是 (3,5),而scale是 (3,) 从init_cond派生的。

未能阅读或遵循规范是这些scipy求解功能(也是优化和集成)出现问题的常见原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM