You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
for both continuous and discrete events (though only the latter are supported
12
-
when converting to `JumpSystem`s currently).
11
+
for both continuous and discrete events.
13
12
14
-
In this tutorial we'll illustrate how to make use of constraint equations and
15
-
events. Let's consider a model of a cell with volume $V(t)$ that grows at a rate
16
-
$\lambda$. For now we'll assume the cell can grow indefinitely. We'll also keep
17
-
track of one protein $P(t)$, which is produced at a rate proportional $V$ and
18
-
can be degraded.
13
+
In this tutorial we'll illustrate how to make use of coupled constraint (i.e.
14
+
ODE/algebraic) equations and events. Let's consider a model of a cell with
15
+
volume $V(t)$ that grows at a rate $\lambda$. For now we'll assume the cell can
16
+
grow indefinitely. We'll also keep track of one protein $P(t)$, which is
17
+
produced at a rate proportional $V$ and can be degraded.
19
18
20
-
## [Coupling ODE constraints via extending a system](@id constraint_equations_coupling_constraints)
19
+
## [Coupling ODE constraints via the DSL](@id constraint_equations_dsl)
20
+
The easiest way to include ODEs and algebraic equations is to just include them
21
+
when using the DSL to specify a model. Here we include an ODE for $V(t)$ along
22
+
with degradation and production reactions for $P(t)$:
23
+
```@example ceq1
24
+
using Catalyst, OrdinaryDiffEqTsit5, Plots
25
+
26
+
rn = @reaction_network growing_cell begin
27
+
# the growth rate
28
+
@parameters λ = 1.0
21
29
22
-
There are several ways we can create our Catalyst model with the two reactions
23
-
and ODE for $V(t)$. One approach is to use compositional modeling, create
24
-
separate `ReactionSystem`s and `ODESystem`s with their respective components,
25
-
and then extend the `ReactionSystem` with the `ODESystem`. Let's begin by
26
-
creating these two systems.
30
+
# assume there is no protein initially
31
+
@species P(t) = 0.0
32
+
33
+
# set the initial volume to 1.0
34
+
@variables V(t) = 1.0
27
35
28
-
Here, to create differentials with respect to time (for our differential equations), we must import the time differential operator from Catalyst. We do this through `D = default_time_deriv()`. Here, `D(V)` denotes the differential of the variable `V` with respect to time.
36
+
# the reactions
37
+
V, 0 --> P
38
+
1.0, P --> 0
29
39
40
+
# the coupled ODE for V(t)
41
+
@equations begin
42
+
D(V) ~ λ * V
43
+
end
44
+
end
45
+
```
46
+
We can now create an `ODEProblem` from our model and solve it to see how $V(t)$
47
+
and $P(t)$ evolve in time:
30
48
```@example ceq1
49
+
oprob = ODEProblem(rn, [], (0.0, 1.0))
50
+
sol = solve(oprob, Tsit5())
51
+
plot(sol)
52
+
```
53
+
54
+
## Coupling ODE constraints via directly building a `ReactionSystem`
55
+
As an alternative to the previous approach, we could have also constructed our
56
+
`ReactionSystem` all at once using the symbolic interface:
We can also model discrete events. Similar to our example with continuous events, we start by creating reaction equations, parameters, variables, and unknowns.
253
+
We can again also model discrete events. Similar to our example with continuous
254
+
events, we start by creating reaction equations, parameters, variables, and
255
+
unknowns.
139
256
```@example ceq3
140
257
t = default_t()
141
258
@parameters k_on switch_time k_off
@@ -157,22 +274,7 @@ Simulating our model,
157
274
rs2 = complete(rs2)
158
275
159
276
oprob = ODEProblem(rs2, u0, tspan, p)
160
-
sol = solve(oprob, Tsit5(); tstops = 2.0)
161
-
plot(sol)
162
-
```
163
-
Note that for discrete events we need to set a stop time via `tstops` so that
164
-
the ODE solver can step exactly to the specific time of our event. In the
165
-
previous example we just manually set the numeric value of the parameter in the
166
-
`tstops` kwarg to `solve`, however, it can often be convenient to instead get
167
-
the value of the parameter from `oprob` and pass this numeric value. This helps
168
-
ensure consistency between the value passed via `p` and/or symbolic defaults and
169
-
what we pass as a `tstop` to `solve`. We can do this as
170
-
```julia
171
277
switch_time_val = oprob.ps[:switch_time]
172
278
sol = solve(oprob, Tsit5(); tstops = switch_time_val)
173
279
plot(sol)
174
280
```
175
-
For a detailed discussion on how to directly use the lower-level but more
176
-
flexible DifferentialEquations.jl event/callback interface, see the
0 commit comments