I have a chemical reaction network including 65 reactions and 21 chemical species and I wanted to use GEKKO to model a simple plug flow reactor or to be more precise use GEKKO to solve the resulting DAE system.
The equations generally look like
dJi/dx = Ri or 0 = Ri
where Ji is the molar flux and Ri is the net reaction rate. Ri consist of multiple rates rj calculated from the reaction network which generally looks like
Ri = sum( nuij * rj ) with r = k * Can * Cbm
where C are my gas concentrations and also my unknowns I want to solve for. K, n and m are known from the reaction network and additional data files.
As the reaction network is too large and complicated to type every rate equation by hand, I wanted to use matrix and array operations like with numpy or write a "help function" to do intermediate calculations and formulate the final equations which I pass to the solver.
Normally with Scipy or comparable packages I would pass the following function to a solver:
P.L = ... # reactor length
P.C0 = ... # const. value for concentration
P.Jref= ... # reference molar flux
P.Rm =.. # given reaction matrix
k = ... # read rate constants from given additional data file
P.a = P.RM.copy() # additional matrix to simplify rate calculation
P.a[P.a >0] = 0.
P.a = P.a * -1.
#J0 dimensionless molar flux of species i at x=0 (value between 0 and 1)
J0 = np.zeros([21])
J0 [0] = ...
J0[1] = ...
...
def odefun(x,J):
# dimless molar flux to concentration
c = ( (J[:]) / np.sum(J[:])) * P.C0
C = np.tile(c,(np.shape(Para.Kin.RM)[0],1))
r = P.k[:] * np.prod(np.power(X,P.a),1) # reaction rate
R = np.transpose(P.RM) @ r # net rate of every chemical species
dJ_dx = P.L/P.J_ref * R[:] # ODE for every species
return dJ_dx
Is there an equivalent why for GEKKO or a simple way to implement such a large reaction network ?
Many matrix operations in
numpyare permitted withgekkoarrays. The qualification is thatnumpyfunctions must return a symbolic result. Here are a few examples of matrix operations:Matrix Operations with Numpy
np.prod()andnp.trace()Matrix Operations to Define Constraints and Objective with
m.sum()Here are related questions:
The Gekko underlying modeling language (APMonitor) has been used for other PDE systems such as a Solid Oxide Fuel Cells (SOFCs) with reaction kinetics, axial / radial spatial dependence, and time dependence. I recommend
IMODE=7to speed up the solution if you are only simulating and not optimizing. For the SOFC case, converting from Simulink to APMonitor (Gekko precursor) sped up the simulation significantly. We later applied the simulator in Model Predictive Control.One other strategy for large reaction networks is to focus on intialization strategies. Using
m.options.COLDSTART=2performs a decomposition of the problem to solve sub-sets of the model that can be successively solved independently. Additional details are provided here: