Skip to content

Commit ebc744e

Browse files
Merge pull request #378 from isaacsas/expand-sys-docs
add ReactionSystem docs
2 parents 8bf2adc + dc704d2 commit ebc744e

File tree

2 files changed

+167
-1
lines changed

2 files changed

+167
-1
lines changed

docs/src/systems/ReactionSystem.md

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,59 @@
11
# ReactionSystem
22

3-
`ReactionSystem` is still a work in progress.
3+
A `ReactionSystem` represents a system of chemical reactions. Conversions are provided to generate corresponding chemical reaction ODE models, chemical Langevin equation SDE models, and stochastic chemical kinetics jump process models. As a simple example, the code below creates a SIR model, and solves the corresponding ODE, SDE and jump process models.
4+
5+
```julia
6+
using ModelingToolkit, OrdinaryDiffEq, StochasticDiffEq, DiffEqJump
7+
@parameters β γ t
8+
@variables S(t) I(t) R(t)
9+
10+
rxs = [Reaction(β, [S,I], [I], [1,1], [2])
11+
Reaction(γ, [I], [R])]
12+
rs = ReactionSystem(rxs, t, [S,I,R], [β,γ])
13+
14+
u₀map = [S => 999.0, I => 1.0, R => 0.0]
15+
parammap ==> 1/10000, γ => 0.01]
16+
tspan = (0.0, 250.0)
17+
18+
# solve as ODEs
19+
odesys = convert(ODESystem, rs)
20+
oprob = ODEProblem(odesys, u₀map, tspan, parammap)
21+
sol = solve(oprob, Tsit5())
22+
23+
# solve as SDEs
24+
sdesys = convert(SDESystem, rs)
25+
sprob = SDEProblem(sdesys, u₀map, tspan, parammap)
26+
sol = solve(sprob, EM(), dt=.01)
27+
28+
# solve as jump process
29+
jumpsys = convert(JumpSystem, rs)
30+
u₀map = [S => 999, I => 1, R => 0]
31+
dprob = DiscreteProblem(jumpsys, u₀map, tspan, parammap)
32+
jprob = JumpProblem(jumpsys, dprob, Direct())
33+
sol = solve(jprob, SSAStepper())
34+
```
35+
36+
## System Constructors
37+
38+
```@docs
39+
Reaction
40+
ReactionSystem
41+
```
42+
43+
## Composition and Accessor Functions
44+
45+
- `sys.eqs` or `equations(sys)`: The reactions that define the system.
46+
- `sys.states` or `states(sys)`: The set of chemical species in the system.
47+
- `sys.parameters` or `parameters(sys)`: The parameters of the system.
48+
- `sys.iv` or `independent_variable(sys)`: The independent variable of the reaction system, usually time.
49+
50+
## Query Functions
51+
```@docs
52+
ismassaction
53+
```
54+
55+
## Transformations
56+
57+
```@docs
58+
Base.convert
59+
```

src/systems/reaction/reactionsystem.jl

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,64 @@
1+
2+
"""
3+
$(TYPEDEF)
4+
5+
One chemical reaction.
6+
7+
# Fields
8+
$(FIELDS)
9+
10+
# Examples
11+
12+
```
13+
using ModelingToolkit
14+
@parameters t k[1:20]
15+
@variables A(t) B(t) C(t) D(t)
16+
rxs = [Reaction(k[1], nothing, [A]), # 0 -> A
17+
Reaction(k[2], [B], nothing), # B -> 0
18+
Reaction(k[3],[A],[C]), # A -> C
19+
Reaction(k[4], [C], [A,B]), # C -> A + B
20+
Reaction(k[5], [C], [A], [1], [2]), # C -> A + A
21+
Reaction(k[6], [A,B], [C]), # A + B -> C
22+
Reaction(k[7], [B], [A], [2], [1]), # 2B -> A
23+
Reaction(k[8], [A,B], [A,C]), # A + B -> A + C
24+
Reaction(k[9], [A,B], [C,D]), # A + B -> C + D
25+
Reaction(k[10], [A], [C,D], [2], [1,1]), # 2A -> C + D
26+
Reaction(k[11], [A], [A,B], [2], [1,1]), # 2A -> A + B
27+
Reaction(k[12], [A,B,C], [C,D], [1,3,4], [2, 3]), # A+3B+4C -> 2C + 3D
28+
Reaction(k[13], [A,B], nothing, [3,1], nothing), # 3A+B -> 0
29+
Reaction(k[14], nothing, [A], nothing, [2]), # 0 -> 2A
30+
Reaction(k[15]*A/(2+A), [A], nothing; only_use_rate=true), # A -> 0 with custom rate
31+
Reaction(k[16], [A], [B]; only_use_rate=true), # A -> B with custom rate.
32+
Reaction(k[17]*A*exp(B), [C], [D], [2], [1]), # 2C -> D with non constant rate.
33+
Reaction(k[18]*B, nothing, [B], nothing, [2]), # 0 -> 2B with non constant rate.
34+
Reaction(k[19]*t, [A], [B]), # A -> B with non constant rate.
35+
Reaction(k[20]*t*A, [B,C], [D],[2,1],[2]) # 2A +B -> 2C with non constant rate.
36+
]
37+
```
38+
39+
Notes:
40+
- `nothing` can be used to indicate a reaction that has no reactants or no products.
41+
In this case the corresponding stoichiometry vector should also be set to `nothing`.
42+
- The three-argument form assumes all reactant and product stoichiometric coefficients
43+
are one.
44+
"""
145
struct Reaction{S <: Variable, T <: Number}
46+
"""The rate function (excluding mass action terms)."""
247
rate
48+
"""Reaction substrates."""
349
substrates::Vector{Operation}
50+
"""Reaction products."""
451
products::Vector{Operation}
52+
"""The stoichiometric coefficients of the reactants."""
553
substoich::Vector{T}
54+
"""The stoichiometric coefficients of the products."""
655
prodstoich::Vector{T}
56+
"""The net stoichiometric coefficients of all species changed by the reaction."""
757
netstoich::Vector{Pair{S,T}}
58+
"""
59+
`false` (default) if `rate` should be multiplied by mass action terms to give the rate law.
60+
`true` if `rate` represents the full reaction rate law.
61+
"""
862
only_use_rate::Bool
963
end
1064

@@ -52,12 +106,32 @@ function get_netstoich(subs, prods, sstoich, pstoich)
52106
ns
53107
end
54108

109+
"""
110+
$(TYPEDEF)
111+
112+
A system of chemical reactions.
113+
114+
# Fields
115+
$(FIELDS)
116+
117+
# Example
118+
Continuing from the example in the [`Reaction`](@ref) definition:
119+
```
120+
rs = ReactionSystem(rxs, t, [A,B,C,D], k)
121+
```
122+
"""
55123
struct ReactionSystem <: AbstractSystem
124+
"""The reactions defining the system."""
56125
eqs::Vector{Reaction}
126+
"""Independent variable (usually time)."""
57127
iv::Variable
128+
"""Dependent (state) variables representing amount of each species."""
58129
states::Vector{Variable}
130+
"""Parameter variables."""
59131
ps::Vector{Variable}
132+
"""The name of the system"""
60133
name::Symbol
134+
"""systems: The internal systems"""
61135
systems::Vector{ReactionSystem}
62136
end
63137

@@ -141,6 +215,22 @@ function jumpratelaw(rx; rxvars=get_variables(rx.rate))
141215
end
142216

143217
# if haveivdep=false then time dependent rates will still be classified as mass action
218+
"""
219+
```julia
220+
ismassaction(rx, rs; rxvars = get_variables(rx.rate),
221+
haveivdep = any(var -> isequal(rs.iv,convert(Variable,var)), rxvars))
222+
```
223+
224+
True if a given reaction is of mass action form, i.e. `rx.rate` does not depend
225+
on any chemical species that correspond to states of the system, and does not depend
226+
explicitly on the independent variable (usually time).
227+
228+
# Arguments
229+
- `rx`, the [`Reaction`](@ref).
230+
- `rs`, a [`ReactionSystem`](@ref) containing the reaction.
231+
- Optional: `rxvars`, the `Variable`s the `rx` depends on.
232+
- Optional: `haveivdep`, `true` if the [`Reaction`](@ref) `rate` field explicitly depends on the independent variable.
233+
"""
144234
function ismassaction(rx, rs; rxvars = get_variables(rx.rate),
145235
haveivdep = any(var -> isequal(rs.iv,convert(Variable,var)), rxvars))
146236
return !(haveivdep || rx.only_use_rate || any(convert(Variable,rxv) in states(rs) for rxv in rxvars))
@@ -172,19 +262,39 @@ function assemble_jumps(rs)
172262
eqs
173263
end
174264

265+
"""
266+
```julia
267+
Base.convert(::Type{<:ODESystem},rs::ReactionSystem)
268+
```
269+
Convert a ReactionSystem to an ODESystem.
270+
"""
175271
function Base.convert(::Type{<:ODESystem},rs::ReactionSystem)
176272
eqs = assemble_drift(rs)
177273
ODESystem(eqs,rs.iv,rs.states,rs.ps,name=rs.name,
178274
systems=convert.(ODESystem,rs.systems))
179275
end
180276

277+
"""
278+
```julia
279+
Base.convert(::Type{<:SDESystem},rs::ReactionSystem)
280+
```
281+
282+
Convert a ReactionSystem to a SDESystem.
283+
"""
181284
function Base.convert(::Type{<:SDESystem},rs::ReactionSystem)
182285
eqs = assemble_drift(rs)
183286
noiseeqs = assemble_diffusion(rs)
184287
SDESystem(eqs,noiseeqs,rs.iv,rs.states,rs.ps,
185288
name=rs.name,systems=convert.(SDESystem,rs.systems))
186289
end
187290

291+
"""
292+
```julia
293+
Base.convert(::Type{<:JumpSystem},rs::ReactionSystem)
294+
```
295+
296+
Convert a ReactionSystem to a JumpSystem.
297+
"""
188298
function Base.convert(::Type{<:JumpSystem},rs::ReactionSystem)
189299
eqs = assemble_jumps(rs)
190300
JumpSystem(eqs,rs.iv,rs.states,rs.ps,name=rs.name,

0 commit comments

Comments
 (0)