在 python 中使用带有 GEKKO 的 ODE 系统中的数组变量
Using array variables in system of ODEs with GEKKO in python
我之前 post 回答过有关在参数估计领域使用 GEKKO 的问题。 这个问题对于理解 GEKKO 的一些工作原理非常有用,但我没有利用的一个方面是数组变量的使用。在重新审视这个问题时,我意识到我的 'measured' 数据是错误的,因为我将初始(和未测量)条件作为我测量变量的一部分作为数组的第一个元素。 (很抱歉,我不确定如何使 python 语法高亮显示)
#Experimental data
times = np.array([0.0, 0.071875, 0.143750, 0.215625, 0.287500, 0.359375, 0.431250,
0.503125, 0.575000, 0.646875, 0.718750, 0.790625, 0.862500,
0.934375, 1.006250, 1.078125, 1.150000])
A_obs = np.array([1.0, 0.552208, 0.300598, 0.196879, 0.101175, 0.065684, 0.045096,
0.028880, 0.018433, 0.011509, 0.006215, 0.004278, 0.002698,
0.001944, 0.001116, 0.000732, 0.000426])
C_obs = np.array([0.0, 0.187768, 0.262406, 0.350412, 0.325110, 0.367181, 0.348264,
0.325085, 0.355673, 0.361805, 0.363117, 0.327266, 0.330211,
0.385798, 0.358132, 0.380497, 0.383051])
P_obs = np.array([0.0, 0.117684, 0.175074, 0.236679, 0.234442, 0.270303, 0.272637,
0.274075, 0.278981, 0.297151, 0.297797, 0.298722, 0.326645,
0.303198, 0.277822, 0.284194, 0.301471])
在重新审视这方面时,我 运行 遇到了一个问题,我必须向 GEKKO 指定一个积分周期,其中必须包括时间 = 0。模拟时间跨度与测量时间跨度的这种变化由于术语长度不同,数据导致我的 objective 函数无法正常工作:
m.Minimize((A-Am)**2) #Array A has 17 elements, array Am has 16
m.Minimize((P-Pm)**2)
m.Minimize((C-Cm)**2)
为了解决这个问题,我想我需要用 m.Array() 来实现我的变量,这样我就可以按元素对它们进行索引,以期设置表单的 objective 函数:
m.Obj(np.sum([(A[i+1]-Am[i])**2 for i in range(len(Am))]))
完整的代码显示在 post 的末尾,但我的问题似乎在于设置系统的 m.Equations()。目前,我不使用索引来引用变量的各个元素:
m.Equation(r1 == k1 * A )
m.Equation(r2 == k2 * A * B )
m.Equation(r3 == k3 * C * B )
m.Equation(r4 == k4 * A )
m.Equation(r5 == k5 * A )
m.Equation(r6 == k6 * A * B )
#mass balance diff eqs, function calls rxn function
m.Equation(A.dt() == - r1 - r2 - r4 - r5 - r6 )
m.Equation(B.dt() == r1 - r2 - r3 - r6 )
m.Equation(C.dt() == r2 - r3 + r4)
m.Equation(P.dt() == r3 + r5 + r6)
程序在使用这种形式的方程时出错:
m.Equation(A.dt() == - r1 - r2 - r4 - r5 - r6 )
AttributeError: 'numpy.ndarray' object has no attribute 'dt'
当我尝试将它们设置为数组时,python 冻结了,因为我认为我一定是生成了太多的方程式或其他一些内存问题。也许它试图分别区分索引中的每个方程,这也是不正确的:
m.Equation([r1[k] == k1 * A[k] for k in range(len(r1))])
m.Equation([r2[k] == k2 * A[k] * B[k] for k in range(len(r2))])
m.Equation([r3[k] == k3 * C[k] * B[k] for k in range(len(r3))])
m.Equation([r4[k] == k4 * A[k] for k in range(len(r4))])
m.Equation([r5[k] == k5 * A[k] for k in range(len(r5))])
m.Equation([r6[k] == k6 * A[k] * B[k] for k in range(len(r6))])
#mass balance diff eqs, function calls rxn function
m.Equation([A[j].dt() == - r1[j] - r2[j] - r4[j] - r5[j] - r6[j] for j in range(len(A))] )
m.Equation([B[j].dt() == r1[j] - r2[j] - r3[j] - r6[j] for j in range(len(B))] )
m.Equation([C[j].dt() == r2[j] - r3[j] + r4[j] for j in range(len(C))])
m.Equation([P[j].dt() == r3[j] + r5[j] + r6[j] for j in range(len(P)) ])
如果有人能解释如何在方程中使用数组变量,特别是 ODE,将不胜感激,因为我找不到任何示例,其中数组变量是 ODE 系统的一部分(我一定错过了许多例子)。此外,如果有另一种可能更简单的方法来编写我的 objective 具有不同长度变量的函数(并且不必像我最初那样将它们指定为数组变量),那也很好知道。
完整脚本如下:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from gekko import GEKKO
data = {'times':[0.071875, 0.143750, 0.215625, 0.287500, 0.359375, 0.431250,
0.503125, 0.575000, 0.646875, 0.718750, 0.790625, 0.862500,
0.934375, 1.006250, 1.078125, 1.150000],
'A_obs':[0.552208, 0.300598, 0.196879, 0.101175, 0.065684, 0.045096,
0.028880, 0.018433, 0.011509, 0.006215, 0.004278, 0.002698,
0.001944, 0.001116, 0.000732, 0.000426],
'C_obs':[0.187768, 0.262406, 0.350412, 0.325110, 0.367181, 0.348264,
0.325085, 0.355673, 0.361805, 0.363117, 0.327266, 0.330211,
0.385798, 0.358132, 0.380497, 0.383051],
'P_obs':[0.117684, 0.175074, 0.236679, 0.234442, 0.270303, 0.272637,
0.274075, 0.278981, 0.297151, 0.297797, 0.298722, 0.326645,
0.303198, 0.277822, 0.284194, 0.301471]}
df = pd.DataFrame(data)
df.set_index('times',inplace = True)
m = GEKKO(remote=False)
time_obs = df.index
t = m.time = np.append(0,time_obs) #adding a time = 0 start value to time discretization for integration
Am= m.Array(m.Param,(len(time_obs)))
Cm= m.Array(m.Param,(len(time_obs)))
Pm= m.Array(m.Param,(len(time_obs)))
for i in range(len(time_obs)):
Am[i].value = df.iloc[i]['A_obs']
Cm[i].value = df.iloc[i]['C_obs']
Pm[i].value = df.iloc[i]['P_obs']
A = m.Array(m.Var,(len(t)),lb=0,value=0.0)
A[0].value=1.0
B = m.Array(m.Var,(len(t)),lb=0,value=0.0)
C = m.Array(m.Var,(len(t)),lb=0,value=0.0)
P = m.Array(m.Var,(len(t)),lb=0,value=0.0)
k = m.Array(m.FV,6,value=1,lb=0)
for ki in k:
ki.STATUS = 1
k1,k2,k3,k4,k5,k6 = k
r1 = m.Array(m.Var,(len(t)),lb=0,value=0.0)
r2 = m.Array(m.Var,(len(t)),lb=0,value=0.0)
r3 = m.Array(m.Var,(len(t)),lb=0,value=0.0)
r4 = m.Array(m.Var,(len(t)),lb=0,value=0.0)
r5 = m.Array(m.Var,(len(t)),lb=0,value=0.0)
r6 = m.Array(m.Var,(len(t)),lb=0,value=0.0)
m.Equation(r1 == k1 * A )
m.Equation(r2 == k2 * A * B )
m.Equation(r3 == k3 * C * B )
m.Equation(r4 == k4 * A )
m.Equation(r5 == k5 * A )
m.Equation(r6 == k6 * A * B )
#mass balance diff eqs, function calls rxn function
m.Equation(A.dt() == - r1 - r2 - r4 - r5 - r6 )
m.Equation(B.dt() == r1 - r2 - r3 - r6 )
m.Equation(C.dt() == r2 - r3 + r4)
m.Equation(P.dt() == r3 + r5 + r6)
'''
m.Equation([r1[k] == k1 * A[k] for k in range(len(r1))])
m.Equation([r2[k] == k2 * A[k] * B[k] for k in range(len(r2))])
m.Equation([r3[k] == k3 * C[k] * B[k] for k in range(len(r3))])
m.Equation([r4[k] == k4 * A[k] for k in range(len(r4))])
m.Equation([r5[k] == k5 * A[k] for k in range(len(r5))])
m.Equation([r6[k] == k6 * A[k] * B[k] for k in range(len(r6))])
#mass balance diff eqs, function calls rxn function
m.Equation([A[j].dt() == - r1[j] - r2[j] - r4[j] - r5[j] - r6[j] for j in range(len(A))] )
m.Equation([B[j].dt() == r1[j] - r2[j] - r3[j] - r6[j] for j in range(len(B))] )
m.Equation([C[j].dt() == r2[j] - r3[j] + r4[j] for j in range(len(C))])
m.Equation([P[j].dt() == r3[j] + r5[j] + r6[j] for j in range(len(P)) ])
'''
m.Obj(np.sum([(A[i+1]-Am[i])**2 for i in range(len(Am))]))
m.Obj(np.sum([(C[i+1]-Cm[i])**2 for i in range(len(Cm))]))
m.Obj(np.sum([(P[i+1]-Pm[i])**2 for i in range(len(Pm))]))
m.options.IMODE = 5
m.options.SOLVER = 3 #IPOPT optimizer
m.options.RTOL = 1E-6
m.options.OTOL = 1E-6
m.options.NODES = 6
m.options.DIAGLEVEL = 10
#m.open_folder()
m.solve()
使用数组变量没有问题,但这需要 collocation equations 的自定义实现以将导数与变量相关联。为缺失的测量值放置一个占位符并创建一个新参数 mobj
以忽略某些测量值(例如初始测量值)要容易得多。
# ignore first measurement
tobj = np.ones(len(t))
tobj[0] = 0
mobj = m.Param(tobj)
数组对于压缩代码很有用,例如变量的定义。
A,B,C,P = m.Array(m.Var,4,lb=0,fixed_initial=False)
解决方法如下:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from gekko import GEKKO
data = {'times':[0,0.071875, 0.143750, 0.215625, 0.287500, 0.359375, 0.431250,
0.503125, 0.575000, 0.646875, 0.718750, 0.790625, 0.862500,
0.934375, 1.006250, 1.078125, 1.150000],
'A_obs':[0,0.552208, 0.300598, 0.196879, 0.101175, 0.065684, 0.045096,
0.028880, 0.018433, 0.011509, 0.006215, 0.004278, 0.002698,
0.001944, 0.001116, 0.000732, 0.000426],
'C_obs':[0,0.187768, 0.262406, 0.350412, 0.325110, 0.367181, 0.348264,
0.325085, 0.355673, 0.361805, 0.363117, 0.327266, 0.330211,
0.385798, 0.358132, 0.380497, 0.383051],
'P_obs':[0,0.117684, 0.175074, 0.236679, 0.234442, 0.270303, 0.272637,
0.274075, 0.278981, 0.297151, 0.297797, 0.298722, 0.326645,
0.303198, 0.277822, 0.284194, 0.301471]}
df = pd.DataFrame(data)
df.set_index('times',inplace = True)
m = GEKKO(remote=False)
time_obs = df.index
t = m.time = time_obs
# ignore first measurement
tobj = np.ones(len(t))
tobj[0] = 0
mobj = m.Param(tobj)
Am= m.Param(df['A_obs'].values)
Cm= m.Param(df['C_obs'].values)
Pm= m.Param(df['P_obs'].values)
A,B,C,P = m.Array(m.Var,4,lb=0,fixed_initial=False)
k = m.Array(m.FV,6,value=1,lb=0)
for ki in k:
ki.STATUS = 1
k1,k2,k3,k4,k5,k6 = k
r = m.Array(m.Var,6,lb=0,value=0.0)
r1,r2,r3,r4,r5,r6 = r
m.Equation(r1 == k1 * A )
m.Equation(r2 == k2 * A * B )
m.Equation(r3 == k3 * C * B )
m.Equation(r4 == k4 * A )
m.Equation(r5 == k5 * A )
m.Equation(r6 == k6 * A * B )
#mass balance diff eqs, function calls rxn function
m.Equation(A.dt() == - r1 - r2 - r4 - r5 - r6 )
m.Equation(B.dt() == r1 - r2 - r3 - r6 )
m.Equation(C.dt() == r2 - r3 + r4)
m.Equation(P.dt() == r3 + r5 + r6)
m.Minimize(mobj*(A-Am)**2)
m.Minimize(mobj*(C-Cm)**2)
m.Minimize(mobj*(P-Pm)**2)
m.options.IMODE = 5
m.options.SOLVER = 3 #IPOPT optimizer
m.options.RTOL = 1E-6
m.options.OTOL = 1E-6
m.options.NODES = 3
m.options.DIAGLEVEL = 0
#m.open_folder()
m.solve()
import matplotlib.pyplot as plt
plt.plot(m.time,Am.value,'ro')
plt.plot(m.time,A.value,'r-',label='A')
plt.plot(m.time,Cm.value,'bo')
plt.plot(m.time,C.value,'b-',label='C')
plt.plot(m.time,Pm.value,'go')
plt.plot(m.time,P.value,'g-',label='P')
plt.xlabel('Time')
plt.legend()
plt.show()
我之前 post 回答过有关在参数估计领域使用 GEKKO 的问题。
#Experimental data
times = np.array([0.0, 0.071875, 0.143750, 0.215625, 0.287500, 0.359375, 0.431250,
0.503125, 0.575000, 0.646875, 0.718750, 0.790625, 0.862500,
0.934375, 1.006250, 1.078125, 1.150000])
A_obs = np.array([1.0, 0.552208, 0.300598, 0.196879, 0.101175, 0.065684, 0.045096,
0.028880, 0.018433, 0.011509, 0.006215, 0.004278, 0.002698,
0.001944, 0.001116, 0.000732, 0.000426])
C_obs = np.array([0.0, 0.187768, 0.262406, 0.350412, 0.325110, 0.367181, 0.348264,
0.325085, 0.355673, 0.361805, 0.363117, 0.327266, 0.330211,
0.385798, 0.358132, 0.380497, 0.383051])
P_obs = np.array([0.0, 0.117684, 0.175074, 0.236679, 0.234442, 0.270303, 0.272637,
0.274075, 0.278981, 0.297151, 0.297797, 0.298722, 0.326645,
0.303198, 0.277822, 0.284194, 0.301471])
在重新审视这方面时,我 运行 遇到了一个问题,我必须向 GEKKO 指定一个积分周期,其中必须包括时间 = 0。模拟时间跨度与测量时间跨度的这种变化由于术语长度不同,数据导致我的 objective 函数无法正常工作:
m.Minimize((A-Am)**2) #Array A has 17 elements, array Am has 16
m.Minimize((P-Pm)**2)
m.Minimize((C-Cm)**2)
为了解决这个问题,我想我需要用 m.Array() 来实现我的变量,这样我就可以按元素对它们进行索引,以期设置表单的 objective 函数:
m.Obj(np.sum([(A[i+1]-Am[i])**2 for i in range(len(Am))]))
完整的代码显示在 post 的末尾,但我的问题似乎在于设置系统的 m.Equations()。目前,我不使用索引来引用变量的各个元素:
m.Equation(r1 == k1 * A )
m.Equation(r2 == k2 * A * B )
m.Equation(r3 == k3 * C * B )
m.Equation(r4 == k4 * A )
m.Equation(r5 == k5 * A )
m.Equation(r6 == k6 * A * B )
#mass balance diff eqs, function calls rxn function
m.Equation(A.dt() == - r1 - r2 - r4 - r5 - r6 )
m.Equation(B.dt() == r1 - r2 - r3 - r6 )
m.Equation(C.dt() == r2 - r3 + r4)
m.Equation(P.dt() == r3 + r5 + r6)
程序在使用这种形式的方程时出错:
m.Equation(A.dt() == - r1 - r2 - r4 - r5 - r6 )
AttributeError: 'numpy.ndarray' object has no attribute 'dt'
当我尝试将它们设置为数组时,python 冻结了,因为我认为我一定是生成了太多的方程式或其他一些内存问题。也许它试图分别区分索引中的每个方程,这也是不正确的:
m.Equation([r1[k] == k1 * A[k] for k in range(len(r1))])
m.Equation([r2[k] == k2 * A[k] * B[k] for k in range(len(r2))])
m.Equation([r3[k] == k3 * C[k] * B[k] for k in range(len(r3))])
m.Equation([r4[k] == k4 * A[k] for k in range(len(r4))])
m.Equation([r5[k] == k5 * A[k] for k in range(len(r5))])
m.Equation([r6[k] == k6 * A[k] * B[k] for k in range(len(r6))])
#mass balance diff eqs, function calls rxn function
m.Equation([A[j].dt() == - r1[j] - r2[j] - r4[j] - r5[j] - r6[j] for j in range(len(A))] )
m.Equation([B[j].dt() == r1[j] - r2[j] - r3[j] - r6[j] for j in range(len(B))] )
m.Equation([C[j].dt() == r2[j] - r3[j] + r4[j] for j in range(len(C))])
m.Equation([P[j].dt() == r3[j] + r5[j] + r6[j] for j in range(len(P)) ])
如果有人能解释如何在方程中使用数组变量,特别是 ODE,将不胜感激,因为我找不到任何示例,其中数组变量是 ODE 系统的一部分(我一定错过了许多例子)。此外,如果有另一种可能更简单的方法来编写我的 objective 具有不同长度变量的函数(并且不必像我最初那样将它们指定为数组变量),那也很好知道。
完整脚本如下:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from gekko import GEKKO
data = {'times':[0.071875, 0.143750, 0.215625, 0.287500, 0.359375, 0.431250,
0.503125, 0.575000, 0.646875, 0.718750, 0.790625, 0.862500,
0.934375, 1.006250, 1.078125, 1.150000],
'A_obs':[0.552208, 0.300598, 0.196879, 0.101175, 0.065684, 0.045096,
0.028880, 0.018433, 0.011509, 0.006215, 0.004278, 0.002698,
0.001944, 0.001116, 0.000732, 0.000426],
'C_obs':[0.187768, 0.262406, 0.350412, 0.325110, 0.367181, 0.348264,
0.325085, 0.355673, 0.361805, 0.363117, 0.327266, 0.330211,
0.385798, 0.358132, 0.380497, 0.383051],
'P_obs':[0.117684, 0.175074, 0.236679, 0.234442, 0.270303, 0.272637,
0.274075, 0.278981, 0.297151, 0.297797, 0.298722, 0.326645,
0.303198, 0.277822, 0.284194, 0.301471]}
df = pd.DataFrame(data)
df.set_index('times',inplace = True)
m = GEKKO(remote=False)
time_obs = df.index
t = m.time = np.append(0,time_obs) #adding a time = 0 start value to time discretization for integration
Am= m.Array(m.Param,(len(time_obs)))
Cm= m.Array(m.Param,(len(time_obs)))
Pm= m.Array(m.Param,(len(time_obs)))
for i in range(len(time_obs)):
Am[i].value = df.iloc[i]['A_obs']
Cm[i].value = df.iloc[i]['C_obs']
Pm[i].value = df.iloc[i]['P_obs']
A = m.Array(m.Var,(len(t)),lb=0,value=0.0)
A[0].value=1.0
B = m.Array(m.Var,(len(t)),lb=0,value=0.0)
C = m.Array(m.Var,(len(t)),lb=0,value=0.0)
P = m.Array(m.Var,(len(t)),lb=0,value=0.0)
k = m.Array(m.FV,6,value=1,lb=0)
for ki in k:
ki.STATUS = 1
k1,k2,k3,k4,k5,k6 = k
r1 = m.Array(m.Var,(len(t)),lb=0,value=0.0)
r2 = m.Array(m.Var,(len(t)),lb=0,value=0.0)
r3 = m.Array(m.Var,(len(t)),lb=0,value=0.0)
r4 = m.Array(m.Var,(len(t)),lb=0,value=0.0)
r5 = m.Array(m.Var,(len(t)),lb=0,value=0.0)
r6 = m.Array(m.Var,(len(t)),lb=0,value=0.0)
m.Equation(r1 == k1 * A )
m.Equation(r2 == k2 * A * B )
m.Equation(r3 == k3 * C * B )
m.Equation(r4 == k4 * A )
m.Equation(r5 == k5 * A )
m.Equation(r6 == k6 * A * B )
#mass balance diff eqs, function calls rxn function
m.Equation(A.dt() == - r1 - r2 - r4 - r5 - r6 )
m.Equation(B.dt() == r1 - r2 - r3 - r6 )
m.Equation(C.dt() == r2 - r3 + r4)
m.Equation(P.dt() == r3 + r5 + r6)
'''
m.Equation([r1[k] == k1 * A[k] for k in range(len(r1))])
m.Equation([r2[k] == k2 * A[k] * B[k] for k in range(len(r2))])
m.Equation([r3[k] == k3 * C[k] * B[k] for k in range(len(r3))])
m.Equation([r4[k] == k4 * A[k] for k in range(len(r4))])
m.Equation([r5[k] == k5 * A[k] for k in range(len(r5))])
m.Equation([r6[k] == k6 * A[k] * B[k] for k in range(len(r6))])
#mass balance diff eqs, function calls rxn function
m.Equation([A[j].dt() == - r1[j] - r2[j] - r4[j] - r5[j] - r6[j] for j in range(len(A))] )
m.Equation([B[j].dt() == r1[j] - r2[j] - r3[j] - r6[j] for j in range(len(B))] )
m.Equation([C[j].dt() == r2[j] - r3[j] + r4[j] for j in range(len(C))])
m.Equation([P[j].dt() == r3[j] + r5[j] + r6[j] for j in range(len(P)) ])
'''
m.Obj(np.sum([(A[i+1]-Am[i])**2 for i in range(len(Am))]))
m.Obj(np.sum([(C[i+1]-Cm[i])**2 for i in range(len(Cm))]))
m.Obj(np.sum([(P[i+1]-Pm[i])**2 for i in range(len(Pm))]))
m.options.IMODE = 5
m.options.SOLVER = 3 #IPOPT optimizer
m.options.RTOL = 1E-6
m.options.OTOL = 1E-6
m.options.NODES = 6
m.options.DIAGLEVEL = 10
#m.open_folder()
m.solve()
使用数组变量没有问题,但这需要 collocation equations 的自定义实现以将导数与变量相关联。为缺失的测量值放置一个占位符并创建一个新参数 mobj
以忽略某些测量值(例如初始测量值)要容易得多。
# ignore first measurement
tobj = np.ones(len(t))
tobj[0] = 0
mobj = m.Param(tobj)
数组对于压缩代码很有用,例如变量的定义。
A,B,C,P = m.Array(m.Var,4,lb=0,fixed_initial=False)
解决方法如下:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from gekko import GEKKO
data = {'times':[0,0.071875, 0.143750, 0.215625, 0.287500, 0.359375, 0.431250,
0.503125, 0.575000, 0.646875, 0.718750, 0.790625, 0.862500,
0.934375, 1.006250, 1.078125, 1.150000],
'A_obs':[0,0.552208, 0.300598, 0.196879, 0.101175, 0.065684, 0.045096,
0.028880, 0.018433, 0.011509, 0.006215, 0.004278, 0.002698,
0.001944, 0.001116, 0.000732, 0.000426],
'C_obs':[0,0.187768, 0.262406, 0.350412, 0.325110, 0.367181, 0.348264,
0.325085, 0.355673, 0.361805, 0.363117, 0.327266, 0.330211,
0.385798, 0.358132, 0.380497, 0.383051],
'P_obs':[0,0.117684, 0.175074, 0.236679, 0.234442, 0.270303, 0.272637,
0.274075, 0.278981, 0.297151, 0.297797, 0.298722, 0.326645,
0.303198, 0.277822, 0.284194, 0.301471]}
df = pd.DataFrame(data)
df.set_index('times',inplace = True)
m = GEKKO(remote=False)
time_obs = df.index
t = m.time = time_obs
# ignore first measurement
tobj = np.ones(len(t))
tobj[0] = 0
mobj = m.Param(tobj)
Am= m.Param(df['A_obs'].values)
Cm= m.Param(df['C_obs'].values)
Pm= m.Param(df['P_obs'].values)
A,B,C,P = m.Array(m.Var,4,lb=0,fixed_initial=False)
k = m.Array(m.FV,6,value=1,lb=0)
for ki in k:
ki.STATUS = 1
k1,k2,k3,k4,k5,k6 = k
r = m.Array(m.Var,6,lb=0,value=0.0)
r1,r2,r3,r4,r5,r6 = r
m.Equation(r1 == k1 * A )
m.Equation(r2 == k2 * A * B )
m.Equation(r3 == k3 * C * B )
m.Equation(r4 == k4 * A )
m.Equation(r5 == k5 * A )
m.Equation(r6 == k6 * A * B )
#mass balance diff eqs, function calls rxn function
m.Equation(A.dt() == - r1 - r2 - r4 - r5 - r6 )
m.Equation(B.dt() == r1 - r2 - r3 - r6 )
m.Equation(C.dt() == r2 - r3 + r4)
m.Equation(P.dt() == r3 + r5 + r6)
m.Minimize(mobj*(A-Am)**2)
m.Minimize(mobj*(C-Cm)**2)
m.Minimize(mobj*(P-Pm)**2)
m.options.IMODE = 5
m.options.SOLVER = 3 #IPOPT optimizer
m.options.RTOL = 1E-6
m.options.OTOL = 1E-6
m.options.NODES = 3
m.options.DIAGLEVEL = 0
#m.open_folder()
m.solve()
import matplotlib.pyplot as plt
plt.plot(m.time,Am.value,'ro')
plt.plot(m.time,A.value,'r-',label='A')
plt.plot(m.time,Cm.value,'bo')
plt.plot(m.time,C.value,'b-',label='C')
plt.plot(m.time,Pm.value,'go')
plt.plot(m.time,P.value,'g-',label='P')
plt.xlabel('Time')
plt.legend()
plt.show()