Skip to content

Commit 186a7d3

Browse files
committed
add toplevel arguments
1 parent 2db7f5f commit 186a7d3

File tree

2 files changed

+29
-25
lines changed

2 files changed

+29
-25
lines changed

src/systems/abstractsystem.jl

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,10 +1293,10 @@ Get the unknown variables of the system `sys` and its subsystems.
12931293
12941294
See also [`ModelingToolkit.get_unknowns`](@ref).
12951295
"""
1296-
function unknowns(sys::AbstractSystem)
1296+
function unknowns(sys::AbstractSystem; toplevel = false)
12971297
sts = get_unknowns(sys)
12981298
systems = get_systems(sys)
1299-
nonunique_unknowns = if isempty(systems)
1299+
nonunique_unknowns = if toplevel || isempty(systems)
13001300
sts
13011301
else
13021302
system_unknowns = reduce(vcat, namespace_variables.(systems))
@@ -1320,7 +1320,7 @@ Get the parameters of the system `sys` and its subsystems.
13201320
13211321
See also [`@parameters`](@ref) and [`ModelingToolkit.get_ps`](@ref).
13221322
"""
1323-
function parameters(sys::AbstractSystem; initial_parameters = false)
1323+
function parameters(sys::AbstractSystem; initial_parameters = false, toplevel = false)
13241324
ps = get_ps(sys)
13251325
if ps == SciMLBase.NullParameters()
13261326
return []
@@ -1329,8 +1329,8 @@ function parameters(sys::AbstractSystem; initial_parameters = false)
13291329
ps = first.(ps)
13301330
end
13311331
systems = get_systems(sys)
1332-
result = unique(isempty(systems) ? ps :
1333-
[ps; reduce(vcat, namespace_parameters.(systems))])
1332+
result = unique(toplevel || isempty(systems) ?
1333+
ps : [ps; reduce(vcat, namespace_parameters.(systems))])
13341334
if !initial_parameters
13351335
if is_time_dependent(sys)
13361336
# time-dependent systems have `Initial` parameters for all their
@@ -1490,8 +1490,9 @@ function controls(sys::AbstractSystem)
14901490
isempty(systems) ? ctrls : [ctrls; reduce(vcat, namespace_controls.(systems))]
14911491
end
14921492

1493-
function observed(sys::AbstractSystem)
1493+
function observed(sys::AbstractSystem; toplevel = false)
14941494
obs = get_observed(sys)
1495+
toplevel && return obs
14951496
systems = get_systems(sys)
14961497
[obs;
14971498
reduce(vcat,
@@ -1510,7 +1511,7 @@ If they are not explicitly provided, variables and parameters are initialized to
15101511
15111512
See also [`initialization_equations`](@ref), [`parameter_dependencies`](@ref) and [`ModelingToolkit.get_defaults`](@ref).
15121513
"""
1513-
function defaults(sys::AbstractSystem)
1514+
function defaults(sys::AbstractSystem; toplevel = false)
15141515
systems = get_systems(sys)
15151516
defs = get_defaults(sys)
15161517
# `mapfoldr` is really important!!! We should prefer the base model for
@@ -1519,7 +1520,8 @@ function defaults(sys::AbstractSystem)
15191520
# `compose(ODESystem(...; defaults=defs), ...)`
15201521
#
15211522
# Thus, right associativity is required and crucial for correctness.
1522-
isempty(systems) ? defs : mapfoldr(namespace_defaults, merge, systems; init = defs)
1523+
(toplevel ||isempty(systems)) ?
1524+
defs : mapfoldr(namespace_defaults, merge, systems; init = defs)
15231525
end
15241526

15251527
function defaults_and_guesses(sys::AbstractSystem)
@@ -1549,10 +1551,10 @@ It is often the most useful way to inspect the equations of a system.
15491551
15501552
See also [`full_equations`](@ref) and [`ModelingToolkit.get_eqs`](@ref).
15511553
"""
1552-
function equations(sys::AbstractSystem)
1554+
function equations(sys::AbstractSystem; toplevel = false)
15531555
eqs = get_eqs(sys)
15541556
systems = get_systems(sys)
1555-
if isempty(systems)
1557+
if toplevel || isempty(systems)
15561558
return eqs
15571559
else
15581560
eqs = Equation[eqs;

src/systems/callbacks.jl

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -94,17 +94,17 @@ A [`ContinuousCallback`](@ref SciMLBase.ContinuousCallback) specified symbolical
9494
as well as the positive-edge `affect` and negative-edge `affect_neg` that apply when *any* of `eq` are satisfied.
9595
By default `affect_neg = affect`; to only get rising edges specify `affect_neg = nothing`.
9696
97-
Assume without loss of generality that the equation is of the form `c(u,p,t) ~ 0`; we denote the integrator state as `i.u`.
97+
Assume without loss of generality that the equation is of the form `c(u,p,t) ~ 0`; we denote the integrator state as `i.u`.
9898
For compactness, we define `prev_sign = sign(c(u[t-1], p[t-1], t-1))` and `cur_sign = sign(c(u[t], p[t], t))`.
99-
A condition edge will be detected and the callback will be invoked iff `prev_sign * cur_sign <= 0`.
99+
A condition edge will be detected and the callback will be invoked iff `prev_sign * cur_sign <= 0`.
100100
The positive edge `affect` will be triggered iff an edge is detected and if `prev_sign < 0`; similarly, `affect_neg` will be
101-
triggered iff an edge is detected and `prev_sign > 0`.
101+
triggered iff an edge is detected and `prev_sign > 0`.
102102
103-
Inter-sample condition activation is not guaranteed; for example if we use the dirac delta function as `c` to insert a
103+
Inter-sample condition activation is not guaranteed; for example if we use the dirac delta function as `c` to insert a
104104
sharp discontinuity between integrator steps (which in this example would not normally be identified by adaptivity) then the condition is not
105105
guaranteed to be triggered.
106106
107-
Once detected the integrator will "wind back" through a root-finding process to identify the point when the condition became active; the method used
107+
Once detected the integrator will "wind back" through a root-finding process to identify the point when the condition became active; the method used
108108
is specified by `rootfind` from [`SciMLBase.RootfindOpt`](@ref). If we denote the time when the condition becomes active as `tc`,
109109
the value in the integrator after windback will be:
110110
* `u[tc-epsilon], p[tc-epsilon], tc` if `LeftRootFind` is used,
@@ -116,7 +116,7 @@ it passed through 0.
116116
117117
Multiple callbacks in the same system with different `rootfind` operations will be grouped
118118
by their `rootfind` value into separate VectorContinuousCallbacks in the enumeration order of `SciMLBase.RootfindOpt`. This may cause some callbacks to not fire if several become
119-
active at the same instant. See the `SciMLBase` documentation for more information on the semantic rules.
119+
active at the same instant. See the `SciMLBase` documentation for more information on the semantic rules.
120120
121121
Affects (i.e. `affect` and `affect_neg`) can be specified as either:
122122
* A list of equations that should be applied when the callback is triggered (e.g. `x ~ 3, y ~ 7`) which must be of the form `unknown ~ observed value` where each `unknown` appears only once. Equations will be applied in the order that they appear in the vector; parameters and state updates will become immediately visible to following equations.
@@ -327,14 +327,15 @@ The `SymbolicContinuousCallback`s in the returned vector are structs with two fi
327327
`affect` which correspond to the first and second elements of a `Pair` used to define an event, i.e.
328328
`eqs => affect`.
329329
"""
330-
function continuous_events(sys::AbstractSystem)
331-
obs = get_continuous_events(sys)
332-
filter(!isempty, obs)
330+
function continuous_events(sys::AbstractSystem; toplevel = false)
331+
cbs = get_continuous_events(sys)
332+
filter(!isempty, cbs)
333+
toplevel && return cbs
333334

334335
systems = get_systems(sys)
335-
cbs = [obs;
336+
cbs = [cbs;
336337
reduce(vcat,
337-
(map(o -> namespace_callback(o, s), continuous_events(s))
338+
(map(cb -> namespace_callback(cb, s), continuous_events(s))
338339
for s in systems),
339340
init = SymbolicContinuousCallback[])]
340341
filter(!isempty, cbs)
@@ -482,10 +483,11 @@ The `SymbolicDiscreteCallback`s in the returned vector are structs with two fiel
482483
`affect` which correspond to the first and second elements of a `Pair` used to define an event, i.e.
483484
`condition => affect`.
484485
"""
485-
function discrete_events(sys::AbstractSystem)
486-
obs = get_discrete_events(sys)
486+
function discrete_events(sys::AbstractSystem; toplevel = false)
487+
cbs = get_discrete_events(sys)
488+
toplevel && return cbs
487489
systems = get_systems(sys)
488-
cbs = [obs;
490+
cbs = [cbs;
489491
reduce(vcat,
490492
(map(o -> namespace_callback(o, s), discrete_events(s)) for s in systems),
491493
init = SymbolicDiscreteCallback[])]
@@ -688,7 +690,7 @@ function generate_rootfinding_callback(sys::AbstractTimeDependentSystem,
688690
generate_rootfinding_callback(cbs, sys, dvs, ps; kwargs...)
689691
end
690692
"""
691-
Generate a single rootfinding callback; this happens if there is only one equation in `cbs` passed to
693+
Generate a single rootfinding callback; this happens if there is only one equation in `cbs` passed to
692694
generate_rootfinding_callback and thus we can produce a ContinuousCallback instead of a VectorContinuousCallback.
693695
"""
694696
function generate_single_rootfinding_callback(

0 commit comments

Comments
 (0)