NetworkDynamics v1.0.0
Breaking
ModelingToolkitv10 → v11 (#344).
MTK v11 split intoModelingToolkitBase(MIT) andModelingToolkit(AGPL);
NetworkDynamics now only depends on the MIT half, so the AGPL dependency is gone.
(This does not make the package copyleft-free: theSparseArraysstdlib still pulls in
SuiteSparse, whose UMFPACK/CHOLMOD/SPQR binaries are GPL-2.0-or-later. That is the
weaker, non-network-clause copyleft that large parts of the Julia ecosystem already carry.)
Along with it:SymbolicUtils≥4,Symbolics≥7.- MTK models are no longer simplified by
mtkcompile(#344).
A built-in pipeline (alias/linear-state elimination, algebraic and nonlinear loop
breaking, simple DAE index reduction) took its place, sincemtkcompilelives in the
AGPL half. Passmtkcompile=truefor the old behavior,mtkcompile=:compareto print
both side by side, or set the global default withNetworkDynamics.set_mtkcompile!.
Models containing discrete variables now warn (still unsupported). - Symbolic expressions as a
guess, or bound to an unknown, now error
(#378)
(the@variables x(t) = <symbolic expr> [guess=<symbolic expr>]pattern).
They used to be substituted once, at build time, and frozen into a number — so they silently went stale
when the values they referenced changed, and an expression that could not be resolved was
quietly dropped, leaving the variable free. Since formulas are now tracked properly, write
@variables x(t) [initf = <expr>](or[guessf = <expr>]) instead; the error message
names the rewrite. Symbolic values on@parametersdo not error: since MTKv11 those create
a so-called parameter binding, the bound parameter on the lhs is moved to observed thus a
permanent runtime dependency is injected. This is in contrast toinitf, which sets the
parameter's numeric value once at init time. set_mtk_defaults!→set_mtk_defaults, non-mutating
(#378): rebind the
result,sys = set_mtk_defaults(sys, ...). A symbolic value now becomes a parameter
binding (as if written@parameters K = K_e) rather than a default; numeric values
are unchanged.SciMLBasev3 /OrdinaryDiffEqv7
(#374). Upstream changed
the defaultinitializealgto check inconsistent initial conditions rather than
reinitialize them, soODEProblem(nw, ...)now passesinitializealg=BrownFullBasicInit()
to keep the previous behavior. Override withinitializealg=....
We deliberately chose to deviate from the DiffEq default here because for the kind of systems
simulated with ND you mostly want DAE reinit at events and sim start.VectorContinuousComponentCallbacklostaffect_neg!
(#374), matching DiffEq's
VectorContinuousCallback. The affect now receives anevent_signsvector (per output:
+1upcrossing,-1downcrossing,0none) and resolves the direction itself.find_fixpointtakes anNWState
(#344). TheVector,
NWParameterand(NWState, NWParameter)forms are deprecated but still work.
Initialization
- Aliased names are interchangeable
(#378): it no longer
matters which of several aliased symbols you attach metadata to.:busbar.uand
:terminal.uare the same state, so defaults, guesses, bounds and formulas written
against either are routed to the canonical one. - Backward-flow initialization
(#378): anInitFormula
may now write an observable, "pinning" it as a value downstream formulas read as
input. This lets you write purely component-local formulas — a parent states what a
child's output must be, the child's formula inverts its own equation — and have them
chain end to end, the way power system models are usually initialized.GuessFormula
pins are hints: they seed the solver but are never consistency-checked, so an entire
backward chain can be spelled as guesses. - New
initf/guessfmetadata
(#378):
@variables x(t) [initf = <expr>]declares an initialization equation,
[guessf = <expr>]a guess. Both also work on@parameters, and there they do something
a binding cannot: the parameter stays a real, free parameter that the dynamics can use,
it is merely given its value at initialization. (A binding would eliminate it into an
observed equation instead.) That is what a setpoint back-computed from the operating point
needs. A scalarguess=0and aguessf=<expr>can now coexist on one variable.
set_initf(sys, target => expr, ...)andset_guessfattach the same thing at system
level, for targets inside a subsystem (non-mutating, rebind the result). - More robust on badly scaled models
(#344,
#378): a failed init
solve is retried on a rescaled problem, and thetol/nwtolresidual check falls back
to a Jacobian-scaled residual before giving up. Stiff equations — e.g. a shunt
capacitor'sDt(V_C) = (ω0/C)·Δi— no longer fail on a roundoff-level mismatch. The
fallback can only relax the check, never tighten it. NWStategainsguess,apply_formulasandverbosekeywords. Withdefault=true
values are filled in order: defaults/inits →InitFormulas → guesses (ifguess=true)
→GuessFormulas.find_fixpoint's default start state now usesguess=true.initialize_component/initialize_componentwisegainwarn=falseto silence
initialization warnings.
Merged pull requests:
- MTK(Base) v11 Compat (#344) (@hexaeder)
- Bump julia-actions/cache to v3, remove cache-save workaround (#346) (@hexaeder)
- fix init macros (#351) (@hexaeder)
- CompatHelper: bump compat for NetworkDynamics to 0.10 for package NetworkDynamicsInspector, (keep existing compat) (#366) (@github-actions[bot])
- Update Buildkite pipeline for the new JuliaGPU cluster (#368) (@maleadt)
- Hw/fix formula handling (#372) (@hexaeder)
- bump sciml versions (#374) (@hexaeder)
- add copy(::Network) and improve metadata dealiasing (#376) (@hexaeder)
- CompatHelper: bump compat for LinearSolve to 5, (keep existing compat) (#377) (@github-actions[bot])
- improve init routine around Formulas (#378) (@hexaeder)
- CompatHelper: bump compat for TimerOutputs to 1, (keep existing compat) (#379) (@github-actions[bot])