Skip to content

Commit c82f7fb

Browse files
authored
Merge pull request #1237 from SciML/species_diffeq_error
Error when having differentials w.r.t. species
2 parents 98c066b + bd6fede commit c82f7fb

File tree

3 files changed

+44
-27
lines changed

3 files changed

+44
-27
lines changed

src/reactionsystem.jl

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,13 @@ struct ReactionSystem{V <: NetworkProperties} <:
367367
end
368368
end
369369

370+
# Checks that no (non-reaction) equation contains a differential w.r.t. a species.
371+
for eq in eqs
372+
(eq isa Reaction) && continue
373+
(hasnode(is_species_diff, eq.lhs) || hasnode(is_species_diff, eq.rhs)) &&
374+
error("An equation ($eq) contains a differential with respect to a species. This is currently not supported. If this is a functionality you require, please raise an issue on the Catalyst GitHub page and we can consider the best way to implement it.")
375+
end
376+
370377
rs = new{typeof(nps)}(
371378
eqs, rxs, iv, sivs, unknowns, spcs, ps, var_to_name, observed,
372379
name, systems, defaults, connection_type, nps, cls, cevs,
@@ -376,6 +383,13 @@ struct ReactionSystem{V <: NetworkProperties} <:
376383
end
377384
end
378385

386+
# Checks if a symbolic expression constains a differential with respect to a species (either directly
387+
# or somehwere within the differential expression).
388+
function is_species_diff(expr)
389+
Symbolics.is_derivative(expr) || return false
390+
return hasnode(ex -> (ex isa Symbolics.BasicSymbolic) && isspecies(ex) && !isbc(ex), expr)
391+
end
392+
379393
# Four-argument constructor. Permits additional inputs as optional arguments.
380394
# Calls the full constructor.
381395
function ReactionSystem(eqs, iv, unknowns, ps;
@@ -482,7 +496,7 @@ function ReactionSystem(rxs::Vector, iv = Catalyst.DEFAULT_IV; kwargs...)
482496
make_ReactionSystem_internal(rxs, iv, [], []; kwargs...)
483497
end
484498

485-
# One-argument constructor. Creates an emtoy `ReactionSystem` from a time independent variable only.
499+
# One-argument constructor. Creates an empty `ReactionSystem` from a time independent variable only.
486500
function ReactionSystem(iv; kwargs...)
487501
ReactionSystem(Reaction[], iv, [], []; kwargs...)
488502
end

test/reactionsystem_core/coupled_equation_crn_systems.jl

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -978,17 +978,6 @@ let
978978
@variables V1(t)
979979
@species S1(t) S2(t)
980980

981-
# Coupled system with additional differential equation for species.
982-
eqs = [
983-
Reaction(p1, [S1], [S2]),
984-
D(S1) ~ p2 - S1
985-
]
986-
@named rs = ReactionSystem(eqs, t)
987-
rs = complete(rs)
988-
u0 = [S1 => 1.0, S2 => 2.0]
989-
ps = [p1 => 2.0, p2 => 3.0]
990-
@test_throws Exception ODEProblem(rs, u0, (0.0, 1.0), ps; structural_simplify = true)
991-
992981
# Coupled system overconstrained due to additional algebraic equations (without variables).
993982
eqs = [
994983
Reaction(p1, [S1], [S2]),
@@ -1012,3 +1001,32 @@ let
10121001
ps = [p1 => 2.0, p2 => 3.0]
10131002
@test_throws Exception ODEProblem(rs, u0, (0.0, 1.0), ps; structural_simplify = true)
10141003
end
1004+
1005+
# Checks that equations cannot contain differentials with respect to species.
1006+
let
1007+
# Basic case.
1008+
@test_throws Exception @eval @reaction_network begin
1009+
@equations D(X) ~ 1.0
1010+
d, X --> 0
1011+
end
1012+
1013+
# Complicated differential.
1014+
@test_throws Exception @eval @reaction_network begin
1015+
@equations V + X^2 ~ 1.0 - D(V + log(1 + X))
1016+
d, X --> 0
1017+
end
1018+
1019+
# Case where the species is declared, but not part of a reaction.
1020+
@test_throws Exception @eval @reaction_network begin
1021+
@species Y(t)
1022+
@equations D(Y) ~ 1.0
1023+
d, X --> 0
1024+
end
1025+
1026+
# Case where the equation also declares a new non-species variable.
1027+
# At some point something like this could be supported, however, not right now.
1028+
@test_throws Exception @eval @reaction_network begin
1029+
@equations D(V) ~ 1.0 + D(X)
1030+
d, X --> 0
1031+
end
1032+
end

test/reactionsystem_core/reactionsystem.jl

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -770,21 +770,6 @@ let
770770
end
771771

772772
# Fix for SBML test 305.
773-
let
774-
@parameters k1 k2 S2 [isconstantspecies = true]
775-
@species S1(t) S3(t)
776-
rx = Reaction(k2, [S1], nothing)
777-
∂ₜ = default_time_deriv()
778-
eq = ∂ₜ(S3) ~ k1 * S2
779-
@mtkbuild osys = ODESystem([eq], t)
780-
@named rs = ReactionSystem([rx, eq], t)
781-
rs = complete(rs)
782-
@test issetequal(unknowns(rs), [S1, S3])
783-
@test issetequal(parameters(rs), [S2, k1, k2])
784-
osys = convert(ODESystem, rs)
785-
@test issetequal(unknowns(osys), [S1, S3])
786-
@test issetequal(parameters(osys), [S2, k1, k2])
787-
end
788773
let
789774
@parameters k1 k2 S2 [isconstantspecies = true]
790775
@species S1(t) S3(t) [isbcspecies = true]

0 commit comments

Comments
 (0)