【问题标题】:Python vestigial parameter and uncallable functionPython残留参数和不可调用函数
【发布时间】:2020-03-15 00:03:34
【问题描述】:
import numpy as np
from scipy.optimize import fsolve
from scipy.integrate import quad
import matplotlib.pyplot as plt

Rgas = 8.31446261815324 #Pa*m**3/mol*K

def Peng_Robinson_EOS(P,V,T,Tc,Pc,ω):
    a = (1+(0.37464+1.54226*ω-0.26992*ω**2)*(1-(T/Tc)**(1/2)))**2*Rgas**2*Tc**2/Pc #Pa*m**3
    b = 0.07780 * Rgas*Tc/Pc
    return P + a/((V+(1-np.sqrt(2))*b)*(V+(1+np.sqrt(2)))) - Rgas*T/(V-b)

def PR_Psat(T,Tc,Pc,ω,V,Pguess = 100000):
    def integral_diff (Pguess,T,Tc,Pc,ω,V):
        def Psat_integrand (V,Pguess,T,Tc,Pc,ω):
            integrand1 = fsolve(Peng_Robinson_EOS(Pguess,V,T,Tc,Pc,ω),Pguess)
            integrand2 = Pguess
            integrand  = integrand1-integrand2
            return integrand
        Vl         = fsolve(Psat_integrand(V,Pguess,T,Tc,Pc,ω),0)

        Vv_guess   = Rgas*T/Pguess
        Vv         = fsolve(Psat_integrand(V,Pguess,T,Tc,Pc,ω),Vv_guess)

        Vinf_guess = (Vl + Vv)/2
        Vinf       = fsolve(Psat_integrand(V,Pguess,T,Tc,Pc,ω),Vinf_guess)

        left       = quad(Psat_integrand(V,Pguess,T,Tc,Pc,ω),Vl,Vinf)[0]
        right      = quad(Psat_integrand(V,Pguess,T,Tc,Pc,ω),Vinf,Vv)[0]
        diff       = left + right
        return diff
    Psat = fsolve(integral_diff(Pguess,T,Tc,Pc,ω,V),Pguess)
    return Psat

这段代码有两个问题。

1:理论上,PR_Psat 不应该依赖于V,因为计算中使用的所有V 的值都是通过fsolve 找到的。但是,因为Peng_Robinson_EOS 依赖于V,Python 不会让它在封闭函数中被忽略。有没有办法消除“指定”V 的需要?

从较早的版本(之前 V 是所有函数的参数),来演示:

runfile('...', wdir='...')
Traceback (most recent call last):

  File "<ipython-input-4-0875bc6411e8>", line 1, in <module>
    runfile('...', wdir='...')

  File "...\lib\site-packages\spyder\utils\site\sitecustomize.py", line 705, in runfile
    execfile(filename, namespace)

  File "...\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "...", line 40, in <module>
    print(PR_Psat(300,647.1,22055000,0.345))

  File "...", line 37, in PR_Psat
    Psat = fsolve(integral_diff(Pguess,T,Tc,Pc,ω),Pguess)

  File "...", line 25, in integral_diff
    Vl         = fsolve(Psat_integrand(V,Pguess,T,Tc,Pc,ω),0)

NameError: name 'V' is not defined

2:Peng_Robinson 似乎没有被视为可调用函数,而是被视为浮点数。我不确定是什么原因造成的。

runfile('...', wdir='...')
Traceback (most recent call last):

  File "<ipython-input-13-0875bc6411e8>", line 1, in <module>
    runfile('...', wdir='...')

  File "C:\Users\Spencer\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 705, in runfile
    execfile(filename, namespace)

  File "...\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "...", line 42, in <module>
    print(PR_Psat(300,647.1,22055000,0.345,1))

  File "...", line 39, in PR_Psat
    Psat = fsolve(integral_diff(Pguess,T,Tc,Pc,ω,V),Pguess)

  File "...", line 27, in integral_diff
    Vl         = fsolve(Psat_integrand(V,Pguess,T,Tc,Pc,ω),0)

  File "...", line 23, in Psat_integrand
    integrand1 = fsolve(Peng_Robinson_EOS(Pguess,V,T,Tc,Pc,ω),Pguess)

  File "...\lib\site-packages\scipy\optimize\minpack.py", line 148, in fsolve
    res = _root_hybr(func, x0, args, jac=fprime, **options)

  File "...\lib\site-packages\scipy\optimize\minpack.py", line 214, in _root_hybr
    shape, dtype = _check_func('fsolve', 'func', func, x0, args, n, (n,))

  File "...\lib\site-packages\scipy\optimize\minpack.py", line 27, in _check_func
    res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))

TypeError: 'numpy.float64' object is not callable

理论上,如果P(V) 与常数T 一起绘制,Peng_Robinson_EOS 应该会产生三次回归。 PR_Psat 的目标是找到 P 的值,P 和三次回归之间的积分取消。 (因此,integral_diff 被插入到 fsolve

总结问题,

1) 有没有办法消除 VPR_Psat 中的需要?

2) 为什么Peng_Robinson_EOS 被标记为不可调用的 numpy.float64 对象?

【问题讨论】:

  • 我已投票结束您的问题,因为“需要更多关注”,因为我实际上无法在您发布的内容中看到明确的问题。

标签: python dtype


【解决方案1】:

问题是语法错误。 fsolve 和 quad 的参数放置错误。为了解决这两个问题,我将 args 移到了后面。例如,

不正确:

Vv         = fsolve(Psat_integrand(V,Pguess,T,Tc,Pc,ω),Vv_guess)

正确:

Vv         = fsolve(Psat_integrand,Vv_guess,args=(Pguess,T,Tc,Pc,ω))

Peng_Robinson_EOS 被称为numpy.float64 的原因是,根据问题中代码的语法,程序在传递给求解器之前会被评估。

此外,使用正确的语法,V 不再是问题。

def PR_Psat(T,Tc,Pc,ω,Pguess = 1000):
    def integral_diff (Pguess,T,Tc,Pc,ω):
        def Psat_integrand (V,Pguess,T,Tc,Pc,ω):
            integrand1 = fsolve(Peng_Robinson_EOS,Pguess,args=(V,T,Tc,Pc,ω))
            integrand2 = Pguess
            integrand  = integrand1-integrand2
            return integrand
        Vl         = fsolve(Psat_integrand,0,args=(Pguess,T,Tc,Pc,ω))

        Vv_guess   = Rgas*T/Pguess
        Vv         = fsolve(Psat_integrand,Vv_guess,args=(Pguess,T,Tc,Pc,ω))

        Vinf_guess = (Vl + Vv)/2
        Vinf       = fsolve(Psat_integrand,Vinf_guess,args=(Pguess,T,Tc,Pc,ω))

        left       = quad(Psat_integrand,Vl,Vinf,args=(Pguess,T,Tc,Pc,ω))[0]
        right      = quad(Psat_integrand,Vinf,Vv,args=(Pguess,T,Tc,Pc,ω))[0]
        diff       = left + right
        return diff
    Psat = fsolve(integral_diff,Pguess,args=(T,Tc,Pc,ω))
    return Psat

【讨论】:

    猜你喜欢
    • 2016-08-23
    • 2015-06-28
    • 1970-01-01
    • 2012-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多