Skip to content

Commit f624106

Browse files
authored
Merge pull request #644 from SciML/lattice_reaction_system_may_2023
Spatial Reaction Network Implementation
2 parents 5b6efd3 + 5e220f7 commit f624106

15 files changed

+2178
-84
lines changed

HISTORY.md

+24-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,32 @@
11
# Breaking updates and feature summaries across releases
22

33
## Catalyst unreleased (master branch)
4+
- Simulation of spatial ODEs now supported. For full details, please see https://github.com/SciML/Catalyst.jl/pull/644 and upcoming documentation. Note that these methods are currently considered alpha, with the interface and approach changing even in non-breaking Catalyst releases.
5+
- LatticeReactionSystem structure represents a spatial reaction network:
6+
```julia
7+
rn = @reaction_network begin
8+
(p,d), 0 <--> X
9+
end
10+
tr = @transport_reaction D X
11+
lattice = Graphs.grid([5, 5])
12+
lrs = LatticeReactionSystem(rn, [tr], lattice)
13+
```
14+
- Here, if a `u0` or `p` vector is given with scalar values:
15+
```julia
16+
u0 = [:X => 1.0]
17+
p = [:p => 1.0, :d => 0.5, :D => 0.1]
18+
```
19+
this value will be used across the entire system. If their values are instead vectors, different values are used across the spatial system. Here
20+
```julia
21+
X0 = zeros(25)
22+
X0[1] = 1.0
23+
u0 = [:X => X0]
24+
```
25+
X's value will be `1.0` in the first vertex, but `0.0` in the remaining one (the system have 25 vertexes in total). SInce th parameters `p` and `d` are part of the non-spatial reaction network, their values are tied to vertexes. However, if the `D` parameter (which governs diffusion between vertexes) is given several values, these will instead correspond to the specific edges (and transportation along those edges.)
26+
427

528
## Catalyst 13.5
6-
- Added a CatalystHomotopyContinuationExtension extension, which exports the `hc_steady_state` function if HomotopyContinuation is exported. `hc_steady_state` finds the steady states of a reactin system using the homotopy continuation method. This feature is only available for julia versions 1.9+. Example:
29+
- Added a CatalystHomotopyContinuationExtension extension, which exports the `hc_steady_state` function if HomotopyContinuation is exported. `hc_steady_state` finds the steady states of a reaction system using the homotopy continuation method. This feature is only available for julia versions 1.9+. Example:
730
```julia
831
wilhelm_2009_model = @reaction_network begin
932
k1, Y --> 2X

Project.toml

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78"
1616
Parameters = "d96e819e-fc66-5662-9728-84c9c7592b0a"
1717
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
1818
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
19+
RuntimeGeneratedFunctions = "7e49a35a-f44a-4d26-94aa-eba1b4ca6b47"
1920
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
2021
SymbolicUtils = "d1185830-fcd6-423d-90d6-eec64667417b"
2122
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"
@@ -40,6 +41,7 @@ ModelingToolkit = "8.66"
4041
Parameters = "0.12"
4142
Reexport = "0.2, 1.0"
4243
Requires = "1.0"
44+
RuntimeGeneratedFunctions = "0.5.12"
4345
SymbolicUtils = "1.0.3"
4446
Symbolics = "5.0.3"
4547
Unitful = "1.12.4"

src/Catalyst.jl

+23
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ const MT = ModelingToolkit
1616
using Unitful
1717
@reexport using ModelingToolkit
1818
using Symbolics
19+
20+
using RuntimeGeneratedFunctions
21+
RuntimeGeneratedFunctions.init(@__MODULE__)
22+
1923
import Symbolics: BasicSymbolic
2024
import SymbolicUtils
2125
using ModelingToolkit: Symbolic, value, istree, get_states, get_ps, get_iv, get_systems,
@@ -33,6 +37,7 @@ import ModelingToolkit: check_variables,
3337

3438
import Base: (==), hash, size, getindex, setindex, isless, Sort.defalg, length, show
3539
import MacroTools, Graphs
40+
import Graphs: DiGraph, SimpleGraph, SimpleDiGraph, vertices, edges, add_vertices!, nv, ne
3641
import DataStructures: OrderedDict, OrderedSet
3742
import Parameters: @with_kw_noshow
3843

@@ -107,4 +112,22 @@ export balance_reaction
107112
function hc_steady_states end
108113
export hc_steady_states
109114

115+
### Spatial Reaction Networks ###
116+
117+
# spatial reactions
118+
include("spatial_reaction_systems/spatial_reactions.jl")
119+
export TransportReaction, TransportReactions, @transport_reaction
120+
export isedgeparameter
121+
122+
# lattice reaction systems
123+
include("spatial_reaction_systems/lattice_reaction_systems.jl")
124+
export LatticeReactionSystem
125+
export spatial_species, vertex_parameters, edge_parameters
126+
127+
# variosu utility functions
128+
include("spatial_reaction_systems/utility.jl")
129+
130+
# spatial lattice ode systems.
131+
include("spatial_reaction_systems/spatial_ODE_systems.jl")
132+
110133
end # module
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
### Lattice Reaction Network Structure ###
2+
# Describes a spatial reaction network over a graph.
3+
# Adding the "<: MT.AbstractTimeDependentSystem" part messes up show, disabling me from creating LRSs.
4+
struct LatticeReactionSystem{S,T} # <: MT.AbstractTimeDependentSystem
5+
# Input values.
6+
"""The reaction system within each compartment."""
7+
rs::ReactionSystem{S}
8+
"""The spatial reactions defined between individual nodes."""
9+
spatial_reactions::Vector{T}
10+
"""The graph on which the lattice is defined."""
11+
lattice::SimpleDiGraph{Int64}
12+
13+
# Derived values.
14+
"""The number of compartments."""
15+
num_verts::Int64
16+
"""The number of edges."""
17+
num_edges::Int64
18+
"""The number of species."""
19+
num_species::Int64
20+
"""Whenever the initial input was a digraph."""
21+
init_digraph::Bool
22+
"""Species that may move spatially."""
23+
spat_species::Vector{BasicSymbolic{Real}}
24+
"""
25+
All parameters related to the lattice reaction system
26+
(both with spatial and non-spatial effects).
27+
"""
28+
parameters::Vector{BasicSymbolic{Real}}
29+
"""
30+
Parameters which values are tied to vertexes (adjacencies),
31+
e.g. (possibly) have a unique value at each vertex of the system.
32+
"""
33+
vertex_parameters::Vector{BasicSymbolic{Real}}
34+
"""
35+
Parameters which values are tied to edges (adjacencies),
36+
e.g. (possibly) have a unique value at each edge of the system.
37+
"""
38+
edge_parameters::Vector{BasicSymbolic{Real}}
39+
40+
function LatticeReactionSystem(rs::ReactionSystem{S}, spatial_reactions::Vector{T},
41+
lattice::DiGraph; init_digraph = true) where {S, T}
42+
# There probably some better way to ascertain that T has that type. Not sure how.
43+
if !(T <: AbstractSpatialReaction)
44+
error("The second argument must be a vector of AbstractSpatialReaction subtypes.")
45+
end
46+
47+
if isempty(spatial_reactions)
48+
spat_species = Vector{BasicSymbolic{Real}}[]
49+
else
50+
spat_species = unique(reduce(vcat, [spatial_species(sr) for sr in spatial_reactions]))
51+
end
52+
num_species = length(unique([species(rs); spat_species]))
53+
rs_edge_parameters = filter(isedgeparameter, parameters(rs))
54+
if isempty(spatial_reactions)
55+
srs_edge_parameters = Vector{BasicSymbolic{Real}}[]
56+
else
57+
srs_edge_parameters = setdiff(reduce(vcat, [parameters(sr) for sr in spatial_reactions]), parameters(rs))
58+
end
59+
edge_parameters = unique([rs_edge_parameters; srs_edge_parameters])
60+
vertex_parameters = filter(!isedgeparameter, parameters(rs))
61+
# Ensures the parameter order begins similarly to in the non-spatial ReactionSystem.
62+
ps = [parameters(rs); setdiff([edge_parameters; vertex_parameters], parameters(rs))]
63+
64+
foreach(sr -> check_spatial_reaction_validity(rs, sr; edge_parameters=edge_parameters), spatial_reactions)
65+
return new{S,T}(rs, spatial_reactions, lattice, nv(lattice), ne(lattice), num_species,
66+
init_digraph, spat_species, ps, vertex_parameters, edge_parameters)
67+
end
68+
end
69+
function LatticeReactionSystem(rs, srs, lat::SimpleGraph)
70+
return LatticeReactionSystem(rs, srs, DiGraph(lat); init_digraph = false)
71+
end
72+
73+
### Lattice ReactionSystem Getters ###
74+
75+
# Get all species.
76+
species(lrs::LatticeReactionSystem) = unique([species(lrs.rs); lrs.spat_species])
77+
# Get all species that may be transported.
78+
spatial_species(lrs::LatticeReactionSystem) = lrs.spat_species
79+
80+
# Get all parameters.
81+
ModelingToolkit.parameters(lrs::LatticeReactionSystem) = lrs.parameters
82+
# Get all parameters which values are tied to vertexes (compartments).
83+
vertex_parameters(lrs::LatticeReactionSystem) = lrs.vertex_parameters
84+
# Get all parameters which values are tied to edges (adjacencies).
85+
edge_parameters(lrs::LatticeReactionSystem) = lrs.edge_parameters
86+
87+
# Gets the lrs name (same as rs name).
88+
ModelingToolkit.nameof(lrs::LatticeReactionSystem) = nameof(lrs.rs)
89+
90+
# Checks if a lattice reaction system is a pure (linear) transport reaction system.
91+
is_transport_system(lrs::LatticeReactionSystem) = all(sr -> sr isa TransportReaction, lrs.spatial_reactions)

0 commit comments

Comments
 (0)