Skip to content

Commit 5518c89

Browse files
committed
add ismassaction and get rid of some temp arrays
1 parent bca57d1 commit 5518c89

File tree

2 files changed

+38
-29
lines changed

2 files changed

+38
-29
lines changed

src/ModelingToolkit.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ export JumpProblem, DiscreteProblem
116116
export NonlinearSystem, OptimizationSystem
117117
export ode_order_lowering
118118
export PDESystem
119-
export Reaction, ReactionSystem
119+
export Reaction, ReactionSystem, ismassaction
120120
export Differential, expand_derivatives, @derivatives
121121
export IntervalDomain, ProductDomain, , CircleDomain
122122
export Equation, ConstrainedEquation

src/systems/reaction/reactionsystem.jl

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ function get_netstoich(subs, prods, sstoich, pstoich)
5252
ns
5353
end
5454

55-
5655
struct ReactionSystem <: AbstractSystem
5756
eqs::Vector{Reaction}
5857
iv::Variable
@@ -121,46 +120,56 @@ function assemble_diffusion(rs)
121120
eqs
122121
end
123122

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}())
144125
end
145126

146127
# Calculate the Jump rate law (like ODE, but uses X instead of X(t).
147128
# 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))
149130
@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))
153134
end
154135
if !only_use_rate
155136
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])
157138
end
158139
end
159140
rl
160141
end
161142

162-
function var2op(var)
163-
Operation(var,Vector{Expression}())
143+
# if haveivdep=true 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((isequal(state,convert(Variable,rxv)) for state in states(rs), 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 = map(p -> Pair(var2op(p[1]),p[2]), 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
164173
end
165174

166175
function Base.convert(::Type{<:ODESystem},rs::ReactionSystem)

0 commit comments

Comments
 (0)