@@ -52,7 +52,6 @@ function get_netstoich(subs, prods, sstoich, pstoich)
52
52
ns
53
53
end
54
54
55
-
56
55
struct ReactionSystem <: AbstractSystem
57
56
eqs:: Vector{Reaction}
58
57
iv:: Variable
@@ -121,46 +120,56 @@ function assemble_diffusion(rs)
121
120
eqs
122
121
end
123
122
124
- function assemble_jumps (rs)
125
- eqs = Vector {Union{ConstantRateJump, MassActionJump, VariableRateJump}} ()
126
-
127
- for rx in rs. eqs
128
- rl = jumpratelaw (rx)
129
- affect = Vector {Equation} ()
130
- for (spec,stoich) in rx. netstoich
131
- push! (affect,var2op (spec) ~ var2op (spec) + stoich)
132
- end
133
- if any (isequal .(var2op (rs. iv),get_variables (rx. rate)))
134
- push! (eqs,VariableRateJump (rl,affect))
135
- elseif rx. only_use_rate || any ([isequal (state,r_op) for state in rs. states, r_op in getfield .(get_variables (rx. rate),:op )])
136
- push! (eqs,ConstantRateJump (rl,affect))
137
- else
138
- reactant_stoch = isempty (rx. substoich) ? [0 => 1 ] : Pair .(var2op .(getfield .(rx. substrates,:op )),rx. substoich)
139
- net_stoch = map (p -> Pair (var2op (p[1 ]),p[2 ]),rx. netstoich)
140
- push! (eqs,MassActionJump (rx. rate, reactant_stoch, net_stoch))
141
- end
142
- end
143
- eqs
123
+ function var2op (var)
124
+ Operation (var,Vector {Expression} ())
144
125
end
145
126
146
127
# Calculate the Jump rate law (like ODE, but uses X instead of X(t).
147
128
# The former generates a "MethodError: objects of type Int64 are not callable" when trying to solve the problem.
148
- function jumpratelaw (rx)
129
+ function jumpratelaw (rx; rxvars = get_variables (rx . rate) )
149
130
@unpack rate, substrates, substoich, only_use_rate = rx
150
- rl = deepcopy ( rate)
151
- for op in get_variables (rx . rate)
152
- rl = substitute (rl,op => var2op (op. op))
131
+ rl = rate
132
+ for op in rxvars
133
+ rl = substitute (rl, op => var2op (op. op))
153
134
end
154
135
if ! only_use_rate
155
136
for (i,stoich) in enumerate (substoich)
156
- rl *= isone (stoich) ? var2op (substrates[i]. op) : Operation (binomial,[var2op (substrates[i]. op),stoich])
137
+ rl *= isone (stoich) ? var2op (substrates[i]. op) : Operation (binomial,[var2op (substrates[i]. op),stoich])
157
138
end
158
139
end
159
140
rl
160
141
end
161
142
162
- function var2op (var)
163
- Operation (var,Vector {Expression} ())
143
+ # if haveivdep=false then time dependent rates will still be classified as mass action
144
+ function ismassaction (rx, rs; rxvars = get_variables (rx. rate),
145
+ haveivdep = any (var -> isequal (rs. iv,convert (Variable,var)), rxvars))
146
+ return ! (haveivdep || rx. only_use_rate || any (convert (Variable,rxv) in states (rs) for rxv in rxvars))
147
+ end
148
+
149
+ function assemble_jumps (rs)
150
+ eqs = Vector {Union{ConstantRateJump, MassActionJump, VariableRateJump}} ()
151
+
152
+ for rx in equations (rs)
153
+ rxvars = get_variables (rx. rate)
154
+ haveivdep = any (var -> isequal (rs. iv,convert (Variable,var)), rxvars)
155
+ if ismassaction (rx, rs; rxvars= rxvars, haveivdep= haveivdep)
156
+ reactant_stoch = isempty (rx. substoich) ? [0 => 1 ] : [var2op (sub. op) => stoich for (sub,stoich) in zip (rx. substrates,rx. substoich)]
157
+ net_stoch = [Pair (var2op (p[1 ]),p[2 ]) for p in rx. netstoich]
158
+ push! (eqs, MassActionJump (rx. rate, reactant_stoch, net_stoch))
159
+ else
160
+ rl = jumpratelaw (rx, rxvars= rxvars)
161
+ affect = Vector {Equation} ()
162
+ for (spec,stoich) in rx. netstoich
163
+ push! (affect, var2op (spec) ~ var2op (spec) + stoich)
164
+ end
165
+ if haveivdep
166
+ push! (eqs, VariableRateJump (rl,affect))
167
+ else
168
+ push! (eqs, ConstantRateJump (rl,affect))
169
+ end
170
+ end
171
+ end
172
+ eqs
164
173
end
165
174
166
175
function Base. convert (:: Type{<:ODESystem} ,rs:: ReactionSystem )
0 commit comments