Skip to content

Commit f8b1e40

Browse files
committed
Some usability improvements
1 parent 1712ac2 commit f8b1e40

File tree

4 files changed

+25
-26
lines changed

4 files changed

+25
-26
lines changed

docs/src/tutorials/acausal_components.md

+16-19
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,11 @@ rc_eqs = [
9595
connect(capacitor.n, source.n, ground.g)
9696
]
9797

98-
@named rc_model = ODESystem(rc_eqs, t,
99-
systems=[resistor, capacitor, source, ground])
98+
@named rc_model = compose(ODESystem(rc_eqs, t),
99+
[resistor, capacitor, source, ground])
100100
sys = structural_simplify(rc_model)
101101
u0 = [
102102
capacitor.v => 0.0
103-
capacitor.p.i => 0.0
104103
]
105104
prob = ODAEProblem(sys, u0, (0, 10.0))
106105
sol = solve(prob, Tsit5())
@@ -289,15 +288,15 @@ rc_eqs = [
289288
Finally we build our four component model with these connection rules:
290289
291290
```julia
292-
@named rc_model = ODESystem(rc_eqs, t,
293-
systems=[resistor, capacitor, source, ground])
291+
@named rc_model = compose(ODESystem(rc_eqs, t)
292+
[resistor, capacitor, source, ground])
294293
```
295294
296-
Notice that this model is acasual because we have not specified anything about
297-
the causality of the model. We have simply specified what is true about each
298-
of the variables. This forms a system of differential-algebraic equations
299-
(DAEs) which define the evolution of each state of the system. The
300-
equations are:
295+
Note that we can also specify the subsystems in a vector. This model is acasual
296+
because we have not specified anything about the causality of the model. We have
297+
simply specified what is true about each of the variables. This forms a system
298+
of differential-algebraic equations (DAEs) which define the evolution of each
299+
state of the system. The equations are:
301300
302301
```julia
303302
equations(rc_model)
@@ -369,9 +368,10 @@ parameters(rc_model)
369368
This system could be solved directly as a DAE using [one of the DAE solvers
370369
from DifferentialEquations.jl](https://diffeq.sciml.ai/stable/solvers/dae_solve/).
371370
However, let's take a second to symbolically simplify the system before doing the
372-
solve. The function `structural_simplify` looks for all of the equalities and
373-
eliminates unnecessary variables to build the leanest numerical representation
374-
of the system. Let's see what it does here:
371+
solve. Although we can use ODE solvers that handles mass matrices to solve the
372+
above system directly, we want to run the `structural_simplify` function first,
373+
as it eliminates many unnecessary variables to build the leanest numerical
374+
representation of the system. Let's see what it does here:
375375
376376
```julia
377377
sys = structural_simplify(rc_model)
@@ -410,16 +410,13 @@ plot(sol)
410410
411411
![](https://user-images.githubusercontent.com/1814174/109416295-55184100-798b-11eb-96d1-5bb7e40135ba.png)
412412
413-
However, we can also choose to use the "torn nonlinear system" to remove all
414-
of the algebraic variables from the solution of the system. Note that this
415-
requires having done `structural_simplify`. MTK can numerically solve all
416-
the unreduced algebraic equations numerically. This is done by using
417-
`ODAEProblem` like:
413+
Since we have run `structural_simplify`, MTK can numerically solve all the
414+
unreduced algebraic equations numerically using the `ODAEProblem` (note the
415+
letter `A`):
418416
419417
```julia
420418
u0 = [
421419
capacitor.v => 0.0
422-
capacitor.p.i => 0.0
423420
]
424421
prob = ODAEProblem(sys, u0, (0, 10.0))
425422
sol = solve(prob, Rodas4())

examples/rc_model.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ rc_eqs = [
1414
connect(capacitor.n, source.n, ground.g)
1515
]
1616

17-
@named rc_model = compose(ODESystem(rc_eqs, t), resistor, capacitor, source, ground)
17+
@named rc_model = compose(ODESystem(rc_eqs, t), [resistor, capacitor, source, ground])

src/systems/abstractsystem.jl

+5-6
Original file line numberDiff line numberDiff line change
@@ -849,15 +849,14 @@ Base.:(&)(sys::AbstractSystem, basesys::AbstractSystem; name::Symbol=nameof(sys)
849849
compose multiple systems together. The resulting system would inherit the first
850850
system's name.
851851
"""
852-
compose(syss::AbstractSystem...; name=nameof(first(syss))) = compose(collect(syss); name=name)
853-
function compose(syss::AbstractArray{<:AbstractSystem}; name=nameof(first(syss)))
854-
nsys = length(syss)
855-
nsys >= 2 || throw(ArgumentError("There must be at least 2 systems. Got $nsys systems."))
856-
sys = first(syss)
852+
function compose(sys::AbstractSystem, systems::AbstractArray{<:AbstractSystem}; name=nameof(first(syss)))
853+
nsys = length(systems)
854+
nsys >= 1 || throw(ArgumentError("There must be at least 1 subsystem. Got $nsys subsystems."))
857855
@set! sys.name = name
858-
@set! sys.systems = syss[2:end]
856+
@set! sys.systems = systems
859857
return sys
860858
end
859+
compose(syss::AbstractSystem...; name=nameof(first(syss))) = compose(first(syss), collect(syss[2:end]); name=name)
861860
Base.:()(sys1::AbstractSystem, sys2::AbstractSystem) = compose(sys1, sys2)
862861

863862
UnPack.unpack(sys::ModelingToolkit.AbstractSystem, ::Val{p}) where p = getproperty(sys, p; namespace=false)

test/components.jl

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ sol = solve(prob, Rodas4())
2020
@test iszero(sol[ground.g.v])
2121
@test sol[resistor.v] == sol[source.p.v] - sol[capacitor.p.v]
2222

23+
u0 = [
24+
capacitor.v => 0.0
25+
]
2326
prob = ODAEProblem(sys, u0, (0, 10.0))
2427
sol = solve(prob, Tsit5())
2528

0 commit comments

Comments
 (0)