避免从 scipy.optimize 到 fsolve 的值错误

Avoiding value Error into fsolve from scipy.optimize

我正在尝试使用 scipy.optimze.fsolve 从 EES 实现中求解一长串方程。但是在这个等式块中有 CoolProp 调用具有一系列验证,有时它会产生 ValueError。我想知道是否有避免 ValueError 的策略,让 fsolve 尝试另一种猜测。

这是我的代码:

def block1(x):
    def cp_gas(Ti, Tj):
        return (1000/(Tj - Ti)*(x[6]*1.25 + x[1]*(0.45 *(((Tj + 273.15)/1000)
                -((Ti + 273.15)/1000)) + 1.67*(((Tj + 273.15)/1000)**2 - ((Ti + 273.15)/1000)**2)/2
                - 1.27*(((Tj + 273.15)/1000)**3 - ((Ti + 273.15)/1000)**3)/3 
                + 0.39*(((Tj + 273.15)/1000)**4 - ((Ti + 273.15)/1000)**4)/4) 
                + x[2]*(1.79 *(((Tj + 273.15)/1000) - ((Ti + 273.15)/1000)) 
                + 0.107*(((Tj + 273.15)/1000)**2 - ((Ti + 273.15)/1000)**2)/2 
                + 0.586*(((Tj + 273.15)/1000)**3 - ((Ti + 273.15)/1000)**3)/3 
                - 0.2*(((Tj + 273.15)/1000)**4 -((Ti + 273.15)/1000)**4)/4)
                + x[3]*(1.11*(((Tj + 273.15)/1000) - ((Ti + 273.15)/1000)) 
                - 0.48*(((Tj + 273.15)/1000)**2 - ((Ti + 273.15)/1000)**2)/2 
                + 0.96*(((Tj + 273.15)/1000)**3 - ((Ti + 273.15)/1000)**3)/3 
                - 0.42*(((Tj + 273.15)/1000)**4 - ((Ti + 273.15)/1000)**4)/4) 
                + x[4]*(0.88*(((Tj + 273.15)/1000) - ((Ti + 273.15)/1000)) 
                - 0.0001*(((Tj + 273.15)/1000)**2 - ((Ti + 273.15)/1000)**2)/2
                + 0.54*(((Tj + 273.15)/1000)**3 - ((Ti + 273.15)/1000)**3)/3
                - 0.33*(((Tj + 273.15)/1000)**4 - ((Ti + 273.15)/1000)**4)/4)
                + x[5]*(0.37*(((Tj + 273.15)/1000) - ((Ti + 273.15)/1000))
                + 1.05*(((Tj + 273.15)/1000)**2 - ((Ti + 273.15)/1000)**2)/2
                - 0.77*(((Tj + 273.15)/1000)**3 - ((Ti + 273.15)/1000)**3)/3
                + 0.21*(((Tj + 273.15)/1000)**4 - ((Ti + 273.15)/1000)**4)/4)))

    f = np.zeros(26)
    # x[24] = T_out_vent
    f[0] = x[0] - cp_gas(T0, Tgas5)
    f[1] = m_gas_teoria_conferindo*x[8] - x[9]*0.8 - x[7]
    f[2] = x[10] + x[8] - (x[7] + x[9]*0.8)
    f[3] = x[9] - x[8]*Z
    f[4] = x[12] + x[13] + x[14] + x[15] + x[16] + x[17] - x[11]
    f[5] = x[12] - M_CO2*x[8]/x[7]
    f[6] = x[13] - M_H2O*x[8]/x[7]
    f[7] = x[14] - M_N2*x[8]/x[7]
    f[8] = x[15] - M_O2*x[8]/x[7]
    f[9] = x[16] - M_SO2*x[8]/x[7]
    f[10] = x[17] - (M_Cz*x[8] - 0.8*x[9])/x[7]
    f[11] = x[18] - (e*a*((1-omega_ar) + 3.76*(1-omega_ar) + omega_ar)*(MM_ar_CBG)/(MM_CBG)*x[19])
    f[12] = x[1] - ((m_gas5-x[7])*FM_g_CO2+x[7]*x[12])/(x[7]*x[11]+(m_gas5-x[7])*FM_g)
    f[13] = x[2] - ((m_gas5-x[7])*FM_g_H2O+x[7]*x[13])/(x[7]*x[11]+(m_gas5-x[7])*FM_g) 
    f[14] = x[3] - ((m_gas5-x[7])*FM_g_N2+x[7]*x[14])/(x[7]*x[11]+(m_gas5-x[7])*FM_g)
    f[15] = x[4] - ((m_gas5-x[7])*FM_g_O2+x[7]*x[15])/(x[7]*x[11]+(m_gas5-x[7])*FM_g)
    f[16] = x[5] - (x[7]*x[16])/(x[7]*x[11]+(m_gas5-x[7])*FM_g) 
    f[17] = x[6] - (x[7]*x[17])/(x[7]*x[11]+(m_gas5-x[7])*FM_g)
    f[18] = x[20] - x[21]/rho_ar_in
    f[19] = (1/3600)*x[21] - (x[10]+x[18])
    f[20] = ((x[10]+x[18])*h_in_vent + x[22]) - (x[10] + x[18])*x[23]
    f[21] = x[23] - HAPropsSI('H', 'T', x[24] + 273.15, 'P', P_out_vent*1e3, 'W', omega_ar)/1e3
    f[22] = x[22] - (0.000012523*x[20] + 0.054570445)
    f[23] = x[25] - HAPropsSI('C', 'T', x[24] + 273.15, 'P', P_out_vent*1e3, 'W', omega_ar)/1e3
    f[24] = m_gas5 - (x[7]+x[19]+x[18])
    f[25] = eta_total - ((m_gas5*x[0]*(Tgas5-T0) - (x[10]+x[18])*x[25]*(x[24]-T0))
                       /(x[8]*PCI_RSU + x[19]*PCI_CBG))

    return f

x = fsolve(block1, np.ones(26))

代码根据先前定义的常量值产生 ValueError。

ValueError 示例:

ValueError: The output for key (8) with value (-nan) is outside the range of validity: (0) to (0.94145) :: inputs were:"H","T",1.3025950731911414e+02,"P",2.0132500000000000e+05,"W",1.0890000000000000e-02 

如果有人能帮助我,我将不胜感激。 提前致谢

你的函数 运行 不处理 NaN 值。

可以用try/except块来处理。 或者将 NaN 值更改为 0(或您选择的任何合适的数字)。

这是一个玩具示例,可帮助您修复代码。您必须决定什么应该是正确的行为,并使用建议的策略之一来处理 NaN。

import bumpy as np

def f(x):
    if np.isnan(x):
        raise ValueError('NaN is not supported')
    return x**x


test_cases = [1, 2, 3, 4, np.nan, 6, 7]

print('skip in case of error')
for x in test_cases:
    try:
        print(f(x))
    except ValueError:
        pass
    
print()
print('fix X in case of NaN')
for x in test_cases:
    if np.isnan(x):
        x = 0
    print(f(x))

输出:

skip in case of error
1
4
27
256
46656
823543

fix X in case of NaN
1
4
27
256
1
46656
823543