Skip to content

Latest commit

 

History

History
420 lines (379 loc) · 32.7 KB

File metadata and controls

420 lines (379 loc) · 32.7 KB

NetworkDynamics Release Notes

v1.4.0 Changelog

  • Component callbacks take a single symbol list. ComponentCondition(f, syms) with f(u, t) and ComponentAffect(f, syms) with f(u, ctx); the list may name states, parameters, inputs, outputs and observed alike, all reachable through u. In an affect the states and parameters are writable, everything else is read only, so affects can now react to observed values directly. The values are a snapshot taken when the affect fires. The old (f, sym, psym) forms with f(u, p, t) and f(u, p, ctx) still work but warn once.
  • Affects can opt out of the automatic step-size reset with ctx.dt_reset[] = false, meant for bookkeeping changes which do not introduce a discontinuity. If several affects fire at the same time, one asking for the reset is enough; parameter changes are saved either way.
  • Batched affects fill their observed buffer once per event instead of once per member.
  • save_parameters! no longer stores a full copy of the parameter vector. The solution keeps the initial parameters plus a list of the values which changed, which makes frequent parameter changes in large networks much cheaper in memory.
  • Observed functions only evaluate what is needed. MTK components now know which observables depend on which, and which of them read the component inputs. SII.observed only evaluates the observables that were asked for and what they depend on. More importantly, it only runs the full network RHS to fill the input buffers if a requested observable actually reads an input. This mostly helps callbacks, which may read an observable at every interpolation point.
  • Aliases of states and parameters resolve directly to their slot. If terminal.u ~ u for a state u, reading terminal.u no longer goes through the observed function. The alias map is now a regular field of the component models, set with the aliasmap constructor keyword; set_aliasmap!, delete_aliasmap! and has_aliasmap are removed.
  • improvements to the simplification pipeline around removing algebraic states
  • Outputs fed forward from an input become algebraic states. When a vertex output depends algebraically on the input, the ND-native MTK simplification now keeps that output as state and the input equation as residual, e.g. the bus voltage and the current balance. The observables of such components no longer read the input, so callback conditions on them don't need the network buffers. The algebraic states of MTK components may change, e.g. PSS/E machines now keep busbar₊u_r, busbar₊u_i instead of the stator currents. If making the outputs states would cost more states than the old tear, the old tear is kept.
  • Parallel edges. Several edge models may now connect the same pair of vertices. The graphless constructor builds a NetworkDynamics.ComponentGraph in that case and keeps the edge models in input order. Inputs without parallel edges still produce a SimpleGraph or SimpleDiGraph as before, unless legacy_graph=false is passed. EIndex(src => dst) throws if it matches more than one edge.
  • chk_component reports allocations in f or g function of model
  • chk_component(c; ad=true) also calls f and g with ForwardDiff Duals and reports if they error or allocate only for Duals. Construction runs the check without this Dual pass.
  • New chk_network(nw) checks the network rhs for allocations with Float64 and Duals and lists the component batches which allocate.
  • Fix: calling the network with Duals allocated on every call, due to the unspecialized element type in the cache getters.
  • ODEProblem(nw, ...) uses FullSpecialize by default. SciML's AutoSpecialize limits ForwardDiff to chunk size 1, so a sparse Jacobian took one RHS pass per color. On IEEE39 the solve gets about 40 % faster. specialize=SciMLBase.AutoSpecialize restores the old behavior.
  • A new network reuses the compiled solver. The Network type no longer carries the component functions; the RHS reaches them through a function barrier (30–40 ns per call). On IEEE39 the first solve of a second network dropped from 17 s to 0.4 s. Reuse needs the same graph type, mass matrix type and float type. Network(...; fullytyped=true) restores the fully typed network.
  • DAE (re)initialization starts with Newton also without a jac_prototype. The default initializealg of ODEProblem(nw, ...) now always uses the Jacobian-based polyalg (NewtonRaphson, then TrustRegion and LevenbergMarquardt) instead of the upstream default, which opens with Broyden. After an event Broyden could take hundreds of iterations and, on last-bit floating point differences, land on a different root than Newton. The internal default_dae_init_alg is removed.
  • OrdinaryDiffEqNonlinearSolve is now a weak dependency, only to require at least v2.9.4 whenever it is loaded. Older versions broke ForwardDiff in the DAE initialization of networks with a jac_prototype.
  • Fix: MTK models may carry several differing initf for one target (e.g. two weak, optional recipes recovering a state from either its input or its output). Previously this errored at VertexModel construction; now initialization decides which one fires and reports a disagreement. A weak initf is also no longer dropped next to an optional strong one.
  • Networks without edges can be built by passing an empty edge list, e.g. Network(g, vm, []) or Network(vms, []).
  • Faster MTK components. Integer powers like x^2 in generated code now go through Base.literal_pow (plain multiplication) instead of the generic, much slower integer power. MTK edges also write their src and dst outputs through one contiguous view. Together this made the RHS of a large PowerDynamics network about 4× faster, with identical results.

v1.3.0 Changelog

  • Initialization values now travel across a two-term algebraic constraint. An equation 0 ~ a*x + b*y with numeric coefficients determines either symbol from the other, so both directions join the resolution graph next to the observed and output equations — this is how a provided interface current reaches an injector through the KCL of a bus. Wider constraints are left alone. Where such a rule determines a settable state, that state is no longer handed to the nonlinear solver.
  • find_fixpoint accepts a solve that stalls just short of convergence. NonlinearSolve terminates at ≈3e-13, tight enough that a larger network can miss it on cancellation noise and report Stalled with a perfectly good residual. A non-success return code is now only an error if the residual also misses the new tol=1e-10 keyword. The solver's own tolerances are untouched, so it still converges as far as it can.
  • find_fixpoint and DAE initialization now select a sparsity-aware nonlinear solver when the network carries a jac_prototype, via NetworkDynamics.default_fixpoint_alg and NetworkDynamics.default_dae_init_alg; find_fixpoint's alg defaults to nothing meaning "let NetworkDynamics decide", and an explicit alg still overrides. This also makes SparseMatrixColorings a dependency, since NonlinearSolve only enables sparse-AD coloring when it is loaded somewhere in the process.
  • set_jac_prototype! now stores a pattern with a full diagonal, whether it computed the pattern itself or was handed one. Solvers size the iteration matrix W = M/γ - J from the prototype, and W has a diagonal whatever the mass matrix looks like. Without those entries the sparse W silently grows on first use, which breaks a GPU sparse solver that has already factorized the prototype symbolically. get_jac_prototype still reports the detected pattern unchanged, structural zeros on the diagonal included.
  • SparseConnectivityTracer is now a regular dependency instead of a weak one, and the sparsity detection moved from ext/NetworkDynamicsSparsityExt.jl into src/sparsity.jl. get_jac_prototype and set_jac_prototype! work without loading anything extra.
  • Network(...; sparse=true) detects the Jacobian sparsity pattern and stores it right away, equivalent to calling set_jac_prototype! on the finished network. The default stays false; a future :auto may change that.
  • Nested conditionals no longer defeat the sparsity detection. The if/else rewrite works on conditionals in value position and runs bottom-up, so nested ifelse and elseif chains collapse instead of pushing the whole component onto the dense fallback.

v1.2.0 Changelog

Initialization-time formula resolution is now a single dependency graph (#387). Init formulas, guess formulas, observed equations and output equations all describe the same thing — out = f(in…) — so they go into one bucket of rules and the execution order falls out of which symbols are already known. This replaces the old approach of expanding observables into the formulas that read them.

  • Optional InitFormulas (kwarg optional=true, set_initf(…; optional=true), or the [initf_optional = <expr>] variable option): a formula whose inputs never become known is skipped instead of failing the initialization. Where weak yields on the target (a value is already there), optional yields on the inputs. The two are independent and combinable.
  • An observable reached through a scaled alias (y ~ -x) is now resolved by the graph in both directions instead of being folded into the aliasmap, so which way the scaling applies is decided per query. A value written on y still reaches the state x, on the init path and on the NWState path alike.
  • bounds written on a scaled alias no longer move onto the underlying state. That is a theoretical breakage from v1.1 but i am sure nothing depends on it.

v1.1.0 Changelog

Cross-component initialization metadata for per-unit / base-value handling: three separate features that resolve at three different times.

Added

  • Weak InitFormulas: a formula declared weak (kwarg weak=true, macro @initformula weak=true …, set_initf(…; weak=true), or the [initf_weak = <expr>] variable option) yields to a value the user already set — it is dropped at init when its single target already carries a default or is written by a strong formula. This is the right precedence for defaulting (a value that follows another unless pinned), the inverse of a plain initf, which always overwrites.
  • bound_to parameter metadata: @parameters S_b [bound_to = :busbar₊S_b] declares a parameter as a structural alias of another symbol in the same component. It is realized as a real MTK binding before compilation, so the bound parameter leaves psym and reappears as an observable of its target — one true parameter for the quantity, nothing can desync. An explicit default on a bound parameter, or an unresolvable target, is an error.
  • default_from parameter metadata: @parameters S_b [default_from = (:src, :busbar₊S_b)] weakly copies a parameter's default from a neighboring component — the src/dst vertex of an edge (:src/:dst), or the hub an injector node hangs off (:hub). The value is resolved at network init and baked into a weak InitFormula, so it follows the source but stays independently settable (contrast bound_to, which eliminates the parameter). Unlike bound_to, the source lives in a different component, resolvable only once the graph exists.

v1.0.0 Changelog

Three themes: ModelingToolkit v11 support (which drops the AGPL dependency), a reworked initialization pipeline, and the SciML v3 stack.

Breaking

  • ModelingToolkit v10 → v11 (#344). MTK v11 split into ModelingToolkitBase (MIT) and ModelingToolkit (AGPL); NetworkDynamics now only depends on the MIT half, so the AGPL dependency is gone. (This does not make the package copyleft-free: the SparseArrays stdlib 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, since mtkcompile lives in the AGPL half. Pass mtkcompile=true for the old behavior, mtkcompile=:compare to print both side by side, or set the global default with NetworkDynamics.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 @parameters do 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 to initf, 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.
  • SciMLBase v3 / OrdinaryDiffEq v7 (#374). Upstream changed the default initializealg to check inconsistent initial conditions rather than reinitialize them, so ODEProblem(nw, ...) now passes initializealg=BrownFullBasicInit() to keep the previous behavior. Override with initializealg=.... 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.
  • VectorContinuousComponentCallback lost affect_neg! (#374), matching DiffEq's VectorContinuousCallback. The affect now receives an event_signs vector (per output: +1 upcrossing, -1 downcrossing, 0 none) and resolves the direction itself.
  • find_fixpoint takes an NWState (#344). The Vector, NWParameter and (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.u and :terminal.u are the same state, so defaults, guesses, bounds and formulas written against either are routed to the canonical one.
  • Backward-flow initialization (#378): an InitFormula 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 / guessf metadata (#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 scalar guess=0 and a guessf=<expr> can now coexist on one variable. set_initf(sys, target => expr, ...) and set_guessf attach 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 the tol/nwtol residual check falls back to a Jacobian-scaled residual before giving up. Stiff equations — e.g. a shunt capacitor's Dt(V_C) = (ω0/C)·Δi — no longer fail on a roundoff-level mismatch. The fallback can only relax the check, never tighten it.
  • NWState gains guess, apply_formulas and verbose keywords. With default=true values are filled in order: defaults/inits → InitFormulas → guesses (if guess=true) → GuessFormulas. find_fixpoint's default start state now uses guess=true.
  • initialize_component / initialize_componentwise gain warn=false to silence initialization warnings.

Other

  • New copy(::Network) (#376), much cheaper than deepcopy.
  • doctor now smoketests each component's observable function.

v0.10.17 Changelog

  • Open-loop linearization (#341):
    • New open_loop_linearization(s0) decomposes the network into open-loop subsystems (Ynw, Zbus, Yinj) for bus/injector node analysis
    • New linearize_component for linearizing individual vertex/edge models in isolation
    • LTI algebra on NetworkDescriptorSystem: append, feedback, * (series/gain/matrix), + (parallel), - (subtraction/negation)
    • Injector node helpers: injector_vidxs, is_injector, has_injector_nodes
    • Type parameter change (soft-breaking): NetworkDescriptorSystem now has 8 type parameters (added ST for sym) instead of 7
  • #342 default initialization problem solver chooses compatible autodiff_vjp now to prevent Enzyme errors in some nonlinear solve algorithms

v0.10.16 Changelog

  • Linear analysis overhaul (#340): Renamed linear_stability.jl to linear_analysis.jl and significantly expanded linear analysis capabilities:
    • New NetworkDescriptorSystem type for descriptor system representation (M ẋ = Ax + Bu, y = Cx + Du) with callable transfer function evaluation
    • New linearize_network(s0; in, out) for full ABCD state-space linearization with perturbation channel classification (vertex/edge inputs/outputs, parameters)
    • New reduce_dae to eliminate algebraic constraints from descriptor systems
    • New participation_factors and show_participation_factors for eigenmode participation analysis
    • New eigenvalue_sensitivity and show_eigenvalue_sensitivity for parameter sensitivity of eigenvalues via nested ForwardDiff
    • API change (soft-breaking): isfixpoint, jacobian_eigenvals, is_linear_stable now take s0::NWState directly instead of (nw, s0). Old signatures are deprecated with warnings.
  • New set_mtk_defaults! helper for forwarding keyword defaults in @component definitions
  • initialize_component: add alg_kwargs keyword, default autodiff=AutoForwardDiff() in solver
  • New dependency: ADTypes
  • Base.copy methods for NWState and NWParameter
  • NWState constructor now validates uflat length
  • PrettyTables v3 compatibility for benchmark code
  • Coreloop: added perturb/perturb_maps kwargs for perturbation-based linearization

v0.10.15 Changelog

  • small fixes, mainly for PowerDynamics tests (#339)

v0.10.14 Changelog

  • Add assume_io_coupling parameter to MTK VertexModel and EdgeModel constructors (#332)
    • New optional parameter forces MTK to consider direct dependency chains from outputs to inputs
    • Helps resolve cases where MTK simplification results in derivatives of input variables
  • Improved error handling for RHS differentials with new RHSDifferentialsError exception type that provides helpful guidance
  • fix performance bottleneck in MTK model "compilation"
  • much improved sparsity tracing #334: no more manual dense/replaced_conditions keywords. Algorithm goes through network batch by batch (not component by component) and replaced incompatible component functions with fixed RGF or dense equivalent automatically.
  • Add LoopbackConnection edge model for injector node pattern (#334)
    • New special edge type enables direct connection of "injector nodes" (vertices with flipped input-output scheme) to hub nodes
    • Injector nodes take potential as input and output flow, allowing modular decomposition of complex vertex models
    • Particularly useful for large networks where splitting vertex models into smaller components improves performance and reduces compilation time
  • Add experimental with_mtk_model_cache function (#334) to prevent repeated simplification and code gen for identical models.

v0.10.13 Changelog

Multiple new features from #331:

  • Parallel component initialization: Add experimental parallel=false keyword to initialize_componentwise for multithreaded component initialization with visual progress indicators
  • Better initialization defaults: Change default solver to FastShortcutNLLSPolyalg(linsolve=QRFactorization()) for better handling of ill-conditioned initialization problems
  • Handle duplicate symbols: Support initialization of components with duplicate state/output symbols (shadowing), with automatic validation that duplicates resolve to same values
  • GPU compatibility for MTK models: MTK-generated models can now run on GPU via enhanced CUDA extension with proper handling of RuntimeGeneratedFunctions and function wrappers
  • Network copy constructor enhancement: Network(nw) now preserves JAC prototype when network structure is unchanged, improving performance for repeated network construction
  • Callback improvements: Support passing vectors/tuples of callbacks for a single component in wrap_component_callbacks

v0.10.12 Changelog

Implemented in #326:

  • Add ComponentPostprocessing metadata mechanism for MTK models to attach postprocessing functions (like callbacks) at subcomponent level
  • Enhance initialization system:
    • Add alg and solve_kwargs parameters to initialize_component and initialize_componentwise for better control over nonlinear solvers
    • Deprecate passing raw kwargs to initialization functions - use alg and solve_kwargs instead (old behavior still works with warning)
    • Support passing solver options as dictionaries mapping VIndex/EIndex to component-specific settings
    • Better error reporting for duplicate edge graphelements with detailed information about which edges conflict
    • Add warning when MTK models use vector variables/parameters (unsupported feature)

v0.10.11 Changelog

  • #324: Add custom ODEProblem constructor which takes a NWState object rather than flat arrays. Also always generate Network callbacks automatically. If you've previously passed callback=get_callbacks(nw), you'll get a deprecation note. For any other usage of the callback keyword on ODEProblem Constructor you'll get an error.

v0.10.10 Changelog

  • #323 Add GuessFormula system for improving initial guesses in component initialization:
    • New GuessFormula type and @guessformula macro for defining guess refinement formulas
    • GuessFormulas operate after InitFormulas in the initialization pipeline
    • Unlike InitFormulas (which set defaults), GuessFormulas refine initial guesses for free variables
    • Add has_guessformula, get_guessformulas, set_guessformula!, add_guessformula!, delete_guessformulas! metadata functions
    • Add additional_guessformula keyword to initialize_component, initialize_component!, and initialize_componentwise functions
    • Improved initialization documentation with execution order details

v0.10.9 Changelog

  • #317 Enhanced callback system with negative affect support and runtime callback injection:
    • Add affect_neg! parameter to ContinuousComponentCallback and VectorContinuousComponentCallback for handling downcrossing events
    • Add ability to inject additional callbacks at runtime via get_callbacks(nw, additional_callbacks) without storing them in component metadata
    • Add NetworkDynamics.pretty_f() debugging utility for pretty-printing MTK-generated functions
    • Improve MTK integration warnings for nested event systems
    • Better initialization error messages with specific variable information when NaN values are detected
  • #314 Consolidate deprecated functionality: all deprecated functionality moved to dedicated src/deprecated.jl file for easier maintenance

v0.10.8 Changelog

  • #313 Fix FilteringProxy issues and improvements:
    • Fix bug with empty getindex operations on FilteringProxy
    • Add pattern highlighting in FilteringProxy display (matches shown in light red)
    • Fix method ambiguity issues in symbolic indexing
    • Improve callback error handling with early validation for wrong signatures
    • Allow name clash reconstruction when it was previously allowed

v0.10.7 Changelog (PR #312)

  • #312 Major rework of symbolic indexing system:
    • New index types: Added ParamIdx and StateIdx for explicit parameter vs state numeric indexing
    • Enhanced proxy system: Replaced internal VProxy/EProxy with new FilteringProxy system that provides more powerful interactive filtering and inspection capabilities
    • Improved display system: Major enhancements to show methods with compact printing and matched name highlighting
    • New exports: ParamIdx, StateIdx, generate_indices, FilteringProxy
    • All user-facing API remains backward compatible - .v and .e properties work as before but are now more powerful

v0.10.6 Changelog

  • #309 improve error handling in initialization system:
    • Add custom exception types: NetworkInitError and ComponentInitError with detailed error messages
    • Enhanced error detection for NaN values, time-dependent systems, and RHS evaluation failures
    • Improved find_fixpoint function with better input validation and time handling support (fixes #308)
    • Add equality (==) and approximate equality (isapprox) methods for NWState and NWParameter
    • Minor documentation fixes and spelling corrections
    • fix #310 (allow VPIndex(i) to index into network objects)
    • implement #307, allow nw[VIndex(:)], nw[[VIndex(1),VIndex(2)]]

v0.10.4 Changelog

  • #303 update for ModelingToolkit.jl v10 compatibility:
    • rename all ODESystem -> System (follows MTK v10 API)
    • MTK extension now uses mtkcompile instead of structural_simplify internally
    • Add new implicit_output function to handle fully implicit output variables in MTK models
    • Add documentation for handling fully implicit outputs in MTK integration
    • Update minimum ModelingToolkit.jl requirement from v9.67 to v10

v0.10.3 Changelog

  • #301 improve callback system performance and flexibility:
    • Add callback batching for better DiscreteComponentCallback performance
    • Allow EIndex(1=>2) as standalone edge index with relaxed type constraints
    • Optimize CallbackSet construction to prevent performance bottlenecks
    • Add important documentation warning about parameter array copying in callbacks
    • Fixed spelling: ContinousComponentCallback → ContinuousComponentCallback and VectorContinousComponentCallback → VectorContinuousComponentCallback (old names maintained as deprecated aliases for backward compatibility)

v0.10.2 Changelog

  • #299 enhance metadata system with pattern matching and utility functions:
    • Add String/Regex pattern matching for all metadata functions (has_metadata, get_metadata, set_metadata!, etc.)
    • Add strip_*! functions to remove all metadata of a specific type from components
    • Add free_u() and free_p() functions to identify variables/parameters without default values
    • Support removing metadata by passing nothing or missing to set_*! functions

v0.10.1 Changelog

  • #294 add linear stability analysis functions: isfixpoint, jacobian_eigenvals, and is_linear_stable with support for both ODE and DAE systems
  • #283 add automatic sparsity detection using get_jac_prototype and set_jac_prototype!
  • #285 rename delete_initconstraint! -> delete_initconstaints! and delete_initformula! -> delete_initformulas!

v0.10 Changelog

  • BREAKING: the interface initialization of components has changed: it is now split up in two versions, mutating and non mutating version. Also it errors now if the tolerance bounds are violated. See docs on initialization for more details.

  • new get_graph(::Network) method to extract graph object from nw

  • improved Initialization System: Added comprehensive initialization formulas and constraints system:

    • added @initformula to add explicit algebraic init equations for specific variables
    • added @initconstraint to add additional constraints for the component initialization
  • allow access edges via Pairs, i.e. EIndex(1=>2,:a) references variable :a in edge from vertex 1 to 2. Works also with unique names of vertices like EIndex(:a=>:b) #281.

v0.9 Changelog

Main changes in this release

NetworkDynamics v0.9 is a complete overhaul of the previous releases of NetworkDynamics. Users of the package should probably read the new documentation carefully.

The most important changes are:

  • Explicit split in f and g function: There is no split into ODE and Static components anymore, everything is unified in component models with internal function f and output function g.
  • Parameters handling: Parameters are allways stored in a flat array. The Symbolic Indexing Interfaces helps to set and retrieve parameters.
  • Automatic aggregation: vertices no longer receive a list of all connected edges. This lead to inhomogeneous call signatures and was a performance bottleneck. Now, each Network has a aggregation function attached to it. The backaned will perform a reduction over all connected edges to calculate the input for a certain vertex. In practice, for typical flow networks you'll allways receive the sum of all flows rather than the individual flows.
  • Symbolic Indexing: the order of the states in the state vector changed in non-trivial ways. But the old idx_containing and syms_containing functions have been replaced with a much more capable symbolic indexing framework.

Limitations

  • We dropped support for delay differential equations. If you've been using that feature please reach out to us.
  • Due to the built aggregation, the vertices cannot explicitly handle the inputs from edges differently anymore. If you've been relying on those features reach out to us.