简体   繁体   English

GEKKO python 中的列表处理

[英]List handling in GEKKO python

i'm currently working on a model of a distillation flask for a university project, the phisical problem is described by a DAE system, and i'm trying to solve it using GEKKO.我目前正在为一个大学项目研究蒸馏 flask 的 model,DAE 系统描述了物理问题,我正在尝试使用 GEKKO 解决它。

I'm facing a problem with list handling: In this case i built a function that outputs the compressibility factor of a mixture, and it requires as inputs 3 gekko variables T1,x,y (x,y arrays) zv1 = m.Param(value=ZCALC(n,comps,R0,p,T1.value,x,y))我在处理列表时遇到了问题:在这种情况下,我构建了一个 function 来输出混合的压缩因子,它需要 3 个 gekko 变量 T1,x,y (x,y 数组) zv1 = m.Param(value=ZCALC(n,comps,R0,p,T1.value,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)

If i leave the 3 values as they are i recieve some errors like:如果我保留 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

The first error is biven by the fact that x and y are not list, but they are GEKKO arrays and the second error is due to T1 not being a float (t=T1)第一个错误是由于 x 和 y 未列出,但它们是 GEKKO arrays 而第二个错误是由于 T1 不是浮点数(t=T1)

I found out that by using T1.value i can avoid the second error but still i have the first error我发现通过使用 T1.value 我可以避免第二个错误,但我仍然有第一个错误

I have read the gekko documentation but i haven't been able to find a method to obtain a "standard" python list from a GEKKO array我已阅读 gekko 文档,但我无法找到从 GEKKO 数组中获取“标准”python 列表的方法

Thank you in advance for your help预先感谢您的帮助

There are two different methods for obtained the value of zv.有两种不同的方法来获得 zv 的值。

Option 1: Initialization Calculation选项 1:初始化计算

The first method is to use floating point numbers to obtain a single calculation that can be used for initialization of a parameter.第一种方法是使用浮点数来获得可用于参数初始化的单个计算。 This first method allows any type of functions such as np.roots() or np.sqrt() .第一种方法允许使用任何类型的函数,例如np.roots()np.sqrt() The function ZCALC() returns a floating point number. function ZCALC()返回一个浮点数。 Even though Gekko variables are used as an input, the floating point number is accessed from a scalar variable with T1.value or from an array variable with x[i].value .即使使用 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))

Option 2: Implicit Calculation选项 2:隐式计算

If the compressibility factor needs to change as T1 and x,y change then use Gekko variables so that the model is compiled with that dependency.如果压缩因子需要随着T1x,y的变化而变化,则使用 Gekko 变量,以便使用该依赖项编译 model。 The functions are only called during problem initialization.这些函数仅在问题初始化期间被调用。 Gekko needs the equations with specific Gekko functions to enable automatic differentiation to provide gradients to the solvers. 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)

Here is a script that shows the two methods:这是一个显示这两种方法的脚本:

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)

If the compressibility factor correlations can't be expressed as Gekko equations then try the cspline for 1D or bspline for 2D functions to create an approximation.如果压缩因子相关性不能表示为 Gekko 方程,则尝试使用 1D 的cspline或 2D 函数的bspline来创建近似值。 You may be able to use the bspline function if compressibility can depend on just 2 variables T and x (replace y with an explicit calculation of x ).如果可压缩性仅取决于 2 个变量Tx (将y替换为x的显式计算),则您可以使用bspline function。

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

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