@@ -22,9 +22,10 @@ Notes:
22
22
`combinatoric_ratelaw=false` then the ratelaw is `k*S^2`, i.e. the scaling
23
23
factor is ignored.
24
24
"""
25
- function oderatelaw (rx; combinatoric_ratelaw = true )
25
+ function oderatelaw (rx; combinatoric_ratelaw = true , expand_catalyst_funs = true )
26
26
@unpack rate, substrates, substoich, only_use_rate = rx
27
27
rl = rate
28
+ expand_catalyst_funs && (rl = expand_registered_functions (rl))
28
29
29
30
# if the stoichiometric coefficients are not integers error if asking to scale rates
30
31
! all (s -> s isa Union{Integer, Symbolic}, substoich) &&
47
48
drop_dynamics (s) = isconstant (s) || isbc (s) || (! isspecies (s))
48
49
49
50
function assemble_oderhs (rs, ispcs; combinatoric_ratelaws = true , remove_conserved = false ,
50
- physical_scales = nothing )
51
+ physical_scales = nothing , expand_catalyst_funs = true )
51
52
nps = get_networkproperties (rs)
52
53
species_to_idx = Dict (x => i for (i, x) in enumerate (ispcs))
53
54
rhsvec = Any[0 for _ in ispcs]
@@ -62,7 +63,8 @@ function assemble_oderhs(rs, ispcs; combinatoric_ratelaws = true, remove_conserv
62
63
! ((physical_scales === nothing ) ||
63
64
(physical_scales[rxidx] == PhysicalScale. ODE)) && continue
64
65
65
- rl = oderatelaw (rx; combinatoric_ratelaw = combinatoric_ratelaws)
66
+ rl = oderatelaw (rx; combinatoric_ratelaw = combinatoric_ratelaws,
67
+ expand_catalyst_funs)
66
68
remove_conserved && (rl = substitute (rl, depspec_submap))
67
69
for (spec, stoich) in rx. netstoich
68
70
# dependent species don't get an ODE, so are skipped
@@ -95,10 +97,10 @@ function assemble_oderhs(rs, ispcs; combinatoric_ratelaws = true, remove_conserv
95
97
end
96
98
97
99
function assemble_drift (rs, ispcs; combinatoric_ratelaws = true , as_odes = true ,
98
- include_zero_odes = true , remove_conserved = false , physical_scales = nothing )
99
-
100
+ include_zero_odes = true , remove_conserved = false , physical_scales = nothing ,
101
+ expand_catalyst_funs = true )
100
102
rhsvec = assemble_oderhs (rs, ispcs; combinatoric_ratelaws, remove_conserved,
101
- physical_scales)
103
+ physical_scales, expand_catalyst_funs )
102
104
if as_odes
103
105
D = Differential (get_iv (rs))
104
106
eqs = [Equation (D (x), rhs)
111
113
112
114
# this doesn't work with constraint equations currently
113
115
function assemble_diffusion (rs, sts, ispcs; combinatoric_ratelaws = true ,
114
- remove_conserved = false )
116
+ remove_conserved = falsem , expand_catalyst_funs = true )
115
117
# as BC species should ultimately get an equation, we include them in the noise matrix
116
118
num_bcsts = count (isbc, get_unknowns (rs))
117
119
@@ -127,7 +129,9 @@ function assemble_diffusion(rs, sts, ispcs; combinatoric_ratelaws = true,
127
129
end
128
130
129
131
for (j, rx) in enumerate (get_rxs (rs))
130
- rlsqrt = sqrt (abs (oderatelaw (rx; combinatoric_ratelaw = combinatoric_ratelaws)))
132
+ rl = oderatelaw (rx; combinatoric_ratelaw = combinatoric_ratelaws,
133
+ expand_catalyst_funs)
134
+ rlsqrt = sqrt (abs (rl))
131
135
hasnoisescaling (rx) && (rlsqrt *= getnoisescaling (rx))
132
136
remove_conserved && (rlsqrt = substitute (rlsqrt, depspec_submap))
133
137
@@ -176,9 +180,12 @@ Notes:
176
180
the ratelaw is `k*S*(S-1)`, i.e. the rate law is not normalized by the scaling
177
181
factor.
178
182
"""
179
- function jumpratelaw (rx; combinatoric_ratelaw = true )
183
+ function jumpratelaw (rx; combinatoric_ratelaw = true , expand_catalyst_funs = true )
180
184
@unpack rate, substrates, substoich, only_use_rate = rx
185
+
181
186
rl = rate
187
+ expand_catalyst_funs && (rl = expand_registered_functions (rl))
188
+
182
189
if ! only_use_rate
183
190
coef = eltype (substoich) <: Number ? one (eltype (substoich)) : 1
184
191
for (i, stoich) in enumerate (substoich)
@@ -360,7 +367,8 @@ function classify_vrjs(rs, physcales)
360
367
isvrjvec
361
368
end
362
369
363
- function assemble_jumps (rs; combinatoric_ratelaws = true , physical_scales = nothing )
370
+ function assemble_jumps (rs; combinatoric_ratelaws = true , physical_scales = nothing ,
371
+ expand_catalyst_funs = true )
364
372
meqs = MassActionJump[]
365
373
ceqs = ConstantRateJump[]
366
374
veqs = VariableRateJump[]
@@ -389,7 +397,8 @@ function assemble_jumps(rs; combinatoric_ratelaws = true, physical_scales = noth
389
397
if (! isvrj) && ismassaction (rx, rs; rxvars, haveivdep = false , unknownset)
390
398
push! (meqs, makemajump (rx; combinatoric_ratelaw = combinatoric_ratelaws))
391
399
else
392
- rl = jumpratelaw (rx; combinatoric_ratelaw = combinatoric_ratelaws)
400
+ rl = jumpratelaw (rx; combinatoric_ratelaw = combinatoric_ratelaws,
401
+ expand_catalyst_funs)
393
402
affect = Vector {Equation} ()
394
403
for (spec, stoich) in rx. netstoich
395
404
# don't change species that are constant or BCs
@@ -409,46 +418,58 @@ end
409
418
410
419
# merge constraint components with the ReactionSystem components
411
420
# also handles removing BC and constant species
412
- function addconstraints! (eqs, rs:: ReactionSystem , ists, ispcs; remove_conserved = false )
421
+ function addconstraints! (eqs, rs:: ReactionSystem , ists, ispcs; remove_conserved = false ,
422
+ treat_conserved_as_eqs = false )
413
423
# if there are BC species, put them after the independent species
414
424
rssts = get_unknowns (rs)
415
425
sts = any (isbc, rssts) ? vcat (ists, filter (isbc, rssts)) : ists
416
426
ps = get_ps (rs)
417
-
427
+ initeqs = Equation[]
428
+ defs = MT. defaults (rs)
429
+ obs = MT. observed (rs)
430
+
418
431
# make dependent species observables and add conservation constants as parameters
419
432
if remove_conserved
420
433
nps = get_networkproperties (rs)
421
434
422
435
# add the conservation constants as parameters and set their values
423
- ps = vcat (ps, collect (eq. lhs for eq in nps. constantdefs))
424
- defs = copy (MT. defaults (rs))
425
- for eq in nps. constantdefs
426
- defs[eq. lhs] = eq. rhs
427
- end
436
+ ps = copy (ps)
437
+ push! (ps, nps. conservedconst)
428
438
429
- # add the dependent species as observed
430
- obs = copy (MT. observed (rs))
431
- append! (obs, nps. conservedeqs)
432
- else
433
- defs = MT. defaults (rs)
434
- obs = MT. observed (rs)
439
+ if treat_conserved_as_eqs
440
+ # add back previously removed dependent species
441
+ sts = union (sts, nps. depspecs)
442
+
443
+ # treat conserved eqs as normal eqs
444
+ append! (eqs, conservedequations (rs))
445
+
446
+ # add initialization equations for conserved parameters
447
+ initialmap = Dict (u => Initial (u) for u in species (rs))
448
+ conseqs = conservationlaw_constants (rs)
449
+ initeqs = [Symbolics. substitute (conseq, initialmap) for conseq in conseqs]
450
+ else
451
+ # add the dependent species as observed
452
+ obs = copy (obs)
453
+ append! (obs, conservedequations (rs))
454
+ end
435
455
end
436
456
437
457
ceqs = Equation[eq for eq in get_eqs (rs) if eq isa Equation]
438
458
if ! isempty (ceqs)
439
459
if remove_conserved
440
460
@info """
441
- Be careful mixing constraints and elimination of conservation laws.
442
- Catalyst does not check that the conserved equations still hold for the
443
- final coupled system of equations. Consider using `remove_conserved =
444
- false` and instead calling ModelingToolkit.structural_simplify to simplify
445
- any generated ODESystem or NonlinearSystem.
461
+ Be careful mixing ODEs or algebraic equations and elimination of
462
+ conservation laws. Catalyst does not check that the conserved equations
463
+ still hold for the final coupled system of equations. Consider using
464
+ `remove_conserved = false` and instead calling
465
+ ModelingToolkit.structural_simplify to simplify any generated ODESystem or
466
+ NonlinearSystem.
446
467
"""
447
468
end
448
469
append! (eqs, ceqs)
449
470
end
450
471
451
- eqs, sts, ps, obs, defs
472
+ eqs, sts, ps, obs, defs, initeqs
452
473
end
453
474
454
475
# used by flattened systems that don't support constraint equations currently
0 commit comments