GEKKO 中的列表处理 python

List handling in GEKKO python

我目前正在为一个大学项目研究蒸馏瓶模型,物理问题由 DAE 系统描述,我正在尝试使用 GEKKO 解决它。

我遇到了列表处理问题: 在这种情况下,我构建了一个输出混合物压缩因子的函数,它需要 3 个gekko变量 T1,x,y(x,y 数组)作为输入 zv1 = m.Param(value=ZCALC(n,comps,R0,p,T1.value,x,y))

m = GEKKO()
y = m.Array(m.Var,n,value=0.)
x = m.Array(m.Var,n,value=0.)
for i in range(n):
    y[i].value = y0[i]
    x[i].value = x0[i]
T1 = m.Var(value=3.31513478e+02, lb=300, ub=900)

如果我保留这 3 个值,我会收到一些错误,例如:

  File "F:\Codice_GEKKO\D86_GEKKO.py", line 113, in <module>
    zv1 = m.Param(value=ZCALC(n,comps,R0,p,T1.value,x,y))
  File "F:\Codice_GEKKO\compressibilityfactor.py", line 48, in ZCALC
    zv=np.max(np.roots([1,-1,(Av-Bv-Bv**2),-Av*Bv]))
  File "<__array_function__ internals>", line 6, in roots
  File "C:\Users\verci\AppData\Local\Programs\Python\Python36\lib\site-packages\numpy\lib\polynomial.py", line 222, in roots
    non_zero = NX.nonzero(NX.ravel(p))[0]
  File "<__array_function__ internals>", line 6, in nonzero
  File "C:\Users\verci\AppData\Local\Programs\Python\Python36\lib\site-packages\numpy\core\fromnumeric.py", line 1908, in nonzero
    return _wrapfunc(a, 'nonzero')
  File "C:\Users\verci\AppData\Local\Programs\Python\Python36\lib\site-packages\numpy\core\fromnumeric.py", line 67, in _wrapfunc
    return _wrapit(obj, method, *args, **kwds)
  File "C:\Users\verci\AppData\Local\Programs\Python\Python36\lib\site-packages\numpy\core\fromnumeric.py", line 44, in _wrapit
    result = getattr(asarray(obj), method)(*args, **kwds)
  File "C:\Users\verci\AppData\Local\Programs\Python\Python36\lib\site-packages\gekko\gk_operators.py", line 25, in __len__
    return len(self.value)
  File "C:\Users\verci\AppData\Local\Programs\Python\Python36\lib\site-packages\gekko\gk_operators.py", line 144, in __len__
    return len(self.value)
TypeError: object of type 'int' has no len()```

Traceback (most recent call last):
  File "F:\Codice_GEKKO\D86_GEKKO.py", line 113, in <module>
    zv1 = m.Param(value=ZCALC(n,comps,R0,p,T1,x,y))
  File "F:\Codice_GEKKO\compressibilityfactor.py", line 27, in ZCALC
    (1-np.sqrt(t/tc[ii])))**2
TypeError: loop of ufunc does not support argument 0 of type GK_Operators which has no callable sqrt method

第一个错误是因为 x 和 y 不是列表,但它们是 GEKKO 数组,第二个错误是由于 T1 不是浮点数 (t=T1)

我发现通过使用 T1.value 我可以避免第二个错误,但我仍然遇到第一个错误

我已经阅读了 gekko 文档,但我一直无法找到从 GEKKO 数组中获取“标准”python 列表的方法

提前感谢您的帮助

zv的取值有两种不同的方法

选项一:初始化计算

第一种方法是使用浮点数获取可用于参数初始化的单个计算。第一种方法允许任何类型的函数,例如 np.roots()np.sqrt()。函数ZCALC() returns 一个浮点数。即使 Gekko 变量用作输入,浮点数也可以从标量变量 T1.value 或数组变量 x[i].value.

访问
def ZCALC(n,comps,R0,p,T1,x,y):
    # using the initialized values
    t = T1.value
    i = 0 # select values from x,y arrays
    x1 = x[i].value
    y1 = y[i].value
    print('t,x[0],y[0] initialized values')
    print(t,x1,y1)

    # include equations for compressibility factor
    w = (1-np.sqrt(t/300))**2
    z = np.max(np.roots([1,-1,x1**2,x1*y1]))
    # original equations from question
    #(1-np.sqrt(t/tc[ii])))**2
    #zv=np.max(np.roots([1,-1,(Av-Bv-Bv**2),-Av*Bv]))
    return z
zv1 = m.Param(value=ZCALC(n,comps,R0,p,T1,x,y))

选项 2:隐式计算

如果压缩因子需要随着 T1x,y 的变化而变化,则使用 Gekko 变量,以便使用该依赖项编译模型。这些函数仅在问题初始化期间调用。 Gekko 需要具有特定 Gekko 函数的方程来启用自动微分,从而为求解器提供梯度。

def ZCALC2(n,comps,R0,p,T1,x,y):
    # using gekko variables
    t = T1
    i = 0
    x1 = x[i] # use index to x array
    y1 = y[i] # use index to y array

    # use Gekko equations, not Numpy
    w = (x1/y1)*(1-m.sqrt(t/300))**2
    # set lower bound to get the maximum root
    zv = m.Var(value=ZCALC(n,comps,R0,p,T1,x,y),lb=10)
    # solve for roots of eq with gekko, not with np.roots
    eq = 1-zv+x1**2*zv+x1*y1*zv**3
    m.Equation(eq==0)
    return zv
zv2 = ZCALC2(n,comps,R0,p,T1,x,y)

这是一个显示这两种方法的脚本:

import numpy as np
m=GEKKO(remote=False)

def ZCALC(n,comps,R0,p,T1,x,y):
    # using the initialized values
    t = T1.value
    i = 0 # select values from x,y arrays
    x1 = x[i].value
    y1 = y[i].value
    print('t,x[0],y[0] initialized values')
    print(t,x1,y1)

    # include equations for compressibility factor
    w = (1-np.sqrt(t/300))**2
    z = np.max(np.roots([1,-1,x1**2,x1*y1]))
    # original equations from question
    #(1-np.sqrt(t/tc[ii])))**2
    #zv=np.max(np.roots([1,-1,(Av-Bv-Bv**2),-Av*Bv]))
    return z

def ZCALC2(n,comps,R0,p,T1,x,y):
    # using gekko variables
    t = T1
    i = 0
    x1 = x[i] # use index to x array
    y1 = y[i] # use index to y array

    # use Gekko equations, not Numpy
    w = (x1/y1)*(1-m.sqrt(t/300))**2
    # set lower bound to get the maximum root
    zv = m.Var(value=ZCALC(n,comps,R0,p,T1,x,y),lb=10)
    # solve for roots of eq with gekko, not with np.roots
    eq = 1-zv+x1**2*zv+x1*y1*zv**3
    m.Equation(eq==0)
    return zv

n = 3
y = m.Array(m.Var,n)
x = m.Array(m.Var,n)
x0 = [0.1,0.2,0.3]
y0 = [0.15,0.25,0.35]
for i in range(n):
    y[i].value = y0[i]
    x[i].value = x0[i]
T1 = m.Var(value=331, lb=300, ub=900)

comps = ['C2=','C3=','C2H8']; R0 = 8.314; p=10

# define Zv from initialized values (fixed parameter)
zv1 = m.Param(value=ZCALC(n,comps,R0,p,T1,x,y))

# define Zv from Gekko variables (updates with T1,x,y changes)
zv2 = ZCALC2(n,comps,R0,p,T1,x,y)

# initialized value of zv1 does not update with changes in T1,x,y
# initialized value of zv2 does update with changes in T1,x,y
print('initialized value of zv1, zv2')
print(zv1.value,zv2.value)

如果压缩因子相关性不能表示为 Gekko 方程,则尝试 cspline for 1D or bspline 二维函数来创建近似值。如果可压缩性仅取决于 2 个变量 Tx(将 y 替换为 x 的显式计算),则您可以使用 bspline 函数.