[英]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.如果压缩因子需要随着T1
和x,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 个变量T
和x
(将y
替换为x
的显式计算),则您可以使用bspline
function。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.