diff --git a/docs/src/basics/AbstractSystem.md b/docs/src/basics/AbstractSystem.md index 2161613353..e68a7bb94e 100644 --- a/docs/src/basics/AbstractSystem.md +++ b/docs/src/basics/AbstractSystem.md @@ -63,6 +63,7 @@ Optionally, a system could have: - `get_defaults(sys)`: A `Dict` that maps variables into their default values for the current-level system. - `get_noiseeqs(sys)`: Noise equations of the current-level system. + - `get_description(sys)`: A string that describes what a system represents. - `get_metadata(sys)`: Any metadata about the system or its origin to be used by downstream packages. Note that if you know a system is an `AbstractTimeDependentSystem` you could use `get_iv` to get the diff --git a/src/ModelingToolkit.jl b/src/ModelingToolkit.jl index 2f57bb1765..7687122a61 100644 --- a/src/ModelingToolkit.jl +++ b/src/ModelingToolkit.jl @@ -243,7 +243,7 @@ export Equation, ConstrainedEquation export Term, Sym export SymScope, LocalScope, ParentScope, DelayParentScope, GlobalScope export independent_variable, equations, controls, observed, full_equations -export initialization_equations, guesses, defaults, parameter_dependencies +export initialization_equations, guesses, defaults, parameter_dependencies, hierarchy export structural_simplify, expand_connections, linearize, linearization_function export calculate_jacobian, generate_jacobian, generate_function, generate_custom_function diff --git a/src/systems/abstractsystem.jl b/src/systems/abstractsystem.jl index b6e2a79c3e..226c4ff55d 100644 --- a/src/systems/abstractsystem.jl +++ b/src/systems/abstractsystem.jl @@ -498,6 +498,7 @@ end Substitutions(subs, deps) = Substitutions(subs, deps, nothing) Base.nameof(sys::AbstractSystem) = getfield(sys, :name) +description(sys::AbstractSystem) = has_description(sys) ? get_description(sys) : "" #Deprecated function independent_variable(sys::AbstractSystem) @@ -986,6 +987,7 @@ for prop in [:eqs :ps :tspan :name + :description :var_to_name :ctrls :defaults @@ -1855,8 +1857,14 @@ function get_or_construct_tearing_state(sys) state end -# TODO: what about inputs? -function n_extra_equations(sys::AbstractSystem) +""" + n_expanded_connection_equations(sys::AbstractSystem) + +Returns the number of equations that the connections in `sys` expands to. +Equivalent to `length(equations(expand_connections(sys))) - length(filter(eq -> !(eq.lhs isa Connection), equations(sys)))`. +""" +function n_expanded_connection_equations(sys::AbstractSystem) + # TODO: what about inputs? isconnector(sys) && return length(get_unknowns(sys)) sys, (csets, _) = generate_connection_set(sys) ceqs, instream_csets = generate_connection_equations_and_stream_connections(csets) @@ -1883,84 +1891,89 @@ function n_extra_equations(sys::AbstractSystem) nextras = n_outer_stream_variables + length(ceqs) end -function Base.show(io::IO, mime::MIME"text/plain", sys::AbstractSystem) - eqs = equations(sys) - vars = unknowns(sys) - nvars = length(vars) - if eqs isa AbstractArray && eltype(eqs) <: Equation - neqs = count(eq -> !(eq.lhs isa Connection), eqs) - Base.printstyled(io, "Model $(nameof(sys)) with $neqs "; bold = true) - nextras = n_extra_equations(sys) - if nextras > 0 - Base.printstyled(io, "("; bold = true) - Base.printstyled(io, neqs + nextras; bold = true, color = :magenta) - Base.printstyled(io, ") "; bold = true) - end - Base.printstyled(io, "equations\n"; bold = true) - else - Base.printstyled(io, "Model $(nameof(sys))\n"; bold = true) - end - # The reduced equations are usually very long. It's not that useful to print - # them. - #Base.print_matrix(io, eqs) - #println(io) +function Base.show( + io::IO, mime::MIME"text/plain", sys::AbstractSystem; hint = true, bold = true) + limit = get(io, :limit, false) # if output should be limited, + rows = first(displaysize(io)) ÷ 5 # then allocate ≈1/5 of display height to each list - rows = first(displaysize(io)) ÷ 5 - limit = get(io, :limit, false) + # Print name and description + desc = description(sys) + printstyled(io, "Model ", nameof(sys), ":"; bold) + !isempty(desc) && print(io, " ", desc) - Base.printstyled(io, "Unknowns ($nvars):"; bold = true) - nrows = min(nvars, limit ? rows : nvars) - limited = nrows < length(vars) - defs = has_defaults(sys) ? defaults(sys) : nothing + # Print subsystems + subs = get_systems(sys) + nsubs = length(subs) + nrows = min(nsubs, limit ? rows : nsubs) + nrows > 0 && printstyled(io, "\nSubsystems ($(nsubs)):"; bold) + nrows > 0 && hint && print(io, " see hierarchy(sys)") for i in 1:nrows - s = vars[i] - print(io, "\n ", s) - - if defs !== nothing - val = get(defs, s, nothing) - if val !== nothing - print(io, " [defaults to ") - show( - IOContext(io, :compact => true, :limit => true, - :displaysize => (1, displaysize(io)[2])), - val) - print(io, "]") - end - description = getdescription(s) - if description !== nothing && description != "" - print(io, ": ", description) + sub = subs[i] + name = String(nameof(sub)) + print(io, "\n ", name) + desc = description(sub) + if !isempty(desc) + maxlen = displaysize(io)[2] - length(name) - 6 # remaining length of line + if limit && length(desc) > maxlen + desc = chop(desc, tail = length(desc) - maxlen) * "…" # too long end + print(io, ": ", desc) end end - limited && print(io, "\n⋮") - println(io) + limited = nrows < nsubs + limited && print(io, "\n ⋮") # too many to print - vars = parameters(sys) - nvars = length(vars) - Base.printstyled(io, "Parameters ($nvars):"; bold = true) - nrows = min(nvars, limit ? rows : nvars) - limited = nrows < length(vars) - for i in 1:nrows - s = vars[i] - print(io, "\n ", s) - - if defs !== nothing - val = get(defs, s, nothing) - if val !== nothing - print(io, " [defaults to ") - show( - IOContext(io, :compact => true, :limit => true, - :displaysize => (1, displaysize(io)[2])), - val) - print(io, "]") + # Print equations + eqs = equations(sys) + if eqs isa AbstractArray && eltype(eqs) <: Equation + neqs = count(eq -> !(eq.lhs isa Connection), eqs) + next = n_expanded_connection_equations(sys) + ntot = neqs + next + ntot > 0 && printstyled(io, "\nEquations ($ntot):"; bold) + neqs > 0 && print(io, "\n $neqs standard", hint ? ": see equations(sys)" : "") + next > 0 && print(io, "\n $next connecting", + hint ? ": see equations(expand_connections(sys))" : "") + #Base.print_matrix(io, eqs) # usually too long and not useful to print all equations + end + + # Print variables + for varfunc in [unknowns, parameters] + vars = varfunc(sys) + nvars = length(vars) + nvars == 0 && continue # skip + header = titlecase(String(nameof(varfunc))) # e.g. "Unknowns" + printstyled(io, "\n$header ($nvars):"; bold) + hint && print(io, " see $(nameof(varfunc))(sys)") + nrows = min(nvars, limit ? rows : nvars) + defs = has_defaults(sys) ? defaults(sys) : nothing + for i in 1:nrows + s = vars[i] + print(io, "\n ", s) + if !isnothing(defs) + val = get(defs, s, nothing) + if !isnothing(val) + print(io, " [defaults to ") + show( + IOContext(io, :compact => true, :limit => true, + :displaysize => (1, displaysize(io)[2])), + val) + print(io, "]") + end + desc = getdescription(s) end - description = getdescription(s) - if description !== nothing && description != "" - print(io, ": ", description) + if !isnothing(desc) && desc != "" + print(io, ": ", desc) end end + limited = nrows < nvars + limited && printstyled(io, "\n ⋮") # too many variables to print end - limited && print(io, "\n⋮") + + # Print observed + nobs = has_observed(sys) ? length(observed(sys)) : 0 + nobs > 0 && printstyled(io, "\nObserved ($nobs):"; bold) + nobs > 0 && hint && print(io, " see observed(sys)") + return nothing end @@ -2900,12 +2913,23 @@ function Base.showerror(io::IO, e::HybridSystemNotSupportedException) print(io, "HybridSystemNotSupportedException: ", e.msg) end -function AbstractTrees.children(sys::ModelingToolkit.AbstractSystem) +function AbstractTrees.children(sys::AbstractSystem) ModelingToolkit.get_systems(sys) end -function AbstractTrees.printnode(io::IO, sys::ModelingToolkit.AbstractSystem) - print(io, nameof(sys)) +function AbstractTrees.printnode( + io::IO, sys::AbstractSystem; describe = false, bold = false) + printstyled(io, nameof(sys); bold) + describe && !isempty(description(sys)) && print(io, ": ", description(sys)) end +""" + hierarchy(sys::AbstractSystem; describe = false, bold = describe, kwargs...) + +Print a tree of a system's hierarchy of subsystems. +""" +function hierarchy(sys::AbstractSystem; describe = false, bold = describe, kwargs...) + print_tree(sys; printnode_kw = (describe = describe, bold = bold), kwargs...) +end + function Base.IteratorEltype(::Type{<:TreeIterator{ModelingToolkit.AbstractSystem}}) Base.HasEltype() end @@ -2988,12 +3012,13 @@ function extend(sys::AbstractSystem, basesys::AbstractSystem; name::Symbol = nam cevs = union(get_continuous_events(basesys), get_continuous_events(sys)) devs = union(get_discrete_events(basesys), get_discrete_events(sys)) defs = merge(get_defaults(basesys), get_defaults(sys)) # prefer `sys` + desc = join(filter(desc -> !isempty(desc), description.([sys, basesys])), " ") # concatenate non-empty descriptions with space meta = union_nothing(get_metadata(basesys), get_metadata(sys)) syss = union(get_systems(basesys), get_systems(sys)) args = length(ivs) == 0 ? (eqs, sts, ps) : (eqs, ivs[1], sts, ps) kwargs = (parameter_dependencies = dep_ps, observed = obs, continuous_events = cevs, discrete_events = devs, defaults = defs, systems = syss, metadata = meta, - name = name, gui_metadata = gui_metadata) + name = name, description = desc, gui_metadata = gui_metadata) # collect fields specific to some system types if basesys isa ODESystem diff --git a/src/systems/diffeqs/odesystem.jl b/src/systems/diffeqs/odesystem.jl index ec2c5f8157..2176e53d55 100644 --- a/src/systems/diffeqs/odesystem.jl +++ b/src/systems/diffeqs/odesystem.jl @@ -79,6 +79,10 @@ struct ODESystem <: AbstractODESystem """ name::Symbol """ + A description of the system. + """ + description::String + """ The internal systems. These are required to have unique names. """ systems::Vector{ODESystem} @@ -178,7 +182,7 @@ struct ODESystem <: AbstractODESystem parent::Any function ODESystem(tag, deqs, iv, dvs, ps, tspan, var_to_name, ctrls, observed, tgrad, - jac, ctrl_jac, Wfact, Wfact_t, name, systems, defaults, guesses, + jac, ctrl_jac, Wfact, Wfact_t, name, description, systems, defaults, guesses, torn_matching, initializesystem, initialization_eqs, schedule, connector_type, preface, cevents, devents, parameter_dependencies, @@ -199,7 +203,7 @@ struct ODESystem <: AbstractODESystem check_units(u, deqs) end new(tag, deqs, iv, dvs, ps, tspan, var_to_name, ctrls, observed, tgrad, jac, - ctrl_jac, Wfact, Wfact_t, name, systems, defaults, guesses, torn_matching, + ctrl_jac, Wfact, Wfact_t, name, description, systems, defaults, guesses, torn_matching, initializesystem, initialization_eqs, schedule, connector_type, preface, cevents, devents, parameter_dependencies, metadata, gui_metadata, is_dde, tearing_state, substitutions, complete, index_cache, @@ -213,6 +217,7 @@ function ODESystem(deqs::AbstractVector{<:Equation}, iv, dvs, ps; systems = ODESystem[], tspan = nothing, name = nothing, + description = "", default_u0 = Dict(), default_p = Dict(), defaults = _merge(Dict(default_u0), Dict(default_p)), @@ -290,7 +295,8 @@ function ODESystem(deqs::AbstractVector{<:Equation}, iv, dvs, ps; end ODESystem(Threads.atomic_add!(SYSTEM_COUNT, UInt(1)), deqs, iv′, dvs′, ps′, tspan, var_to_name, ctrl′, observed, tgrad, jac, - ctrl_jac, Wfact, Wfact_t, name, systems, defaults, guesses, nothing, initializesystem, + ctrl_jac, Wfact, Wfact_t, name, description, systems, + defaults, guesses, nothing, initializesystem, initialization_eqs, schedule, connector_type, preface, cont_callbacks, disc_callbacks, parameter_dependencies, metadata, gui_metadata, is_dde, checks = checks) @@ -393,6 +399,7 @@ function flatten(sys::ODESystem, noeqs = false) discrete_events = discrete_events(sys), defaults = defaults(sys), name = nameof(sys), + description = description(sys), initialization_eqs = initialization_equations(sys), is_dde = is_dde(sys), checks = false) @@ -697,3 +704,16 @@ function add_accumulations(sys::ODESystem, vars::Vector{<:Pair}) @set! sys.unknowns = [get_unknowns(sys); avars] @set! sys.defaults = merge(get_defaults(sys), Dict(a => 0.0 for a in avars)) end + +function Base.show(io::IO, mime::MIME"text/plain", sys::ODESystem; hint = true, bold = true) + # Print general AbstractSystem information + invoke(Base.show, Tuple{typeof(io), typeof(mime), AbstractSystem}, + io, mime, sys; hint, bold) + + # Print initialization equations (unique to ODESystems) + nini = length(initialization_equations(sys)) + nini > 0 && printstyled(io, "\nInitialization equations ($nini):"; bold) + nini > 0 && hint && print(io, " see initialization_equations(sys)") + + return nothing +end diff --git a/src/systems/diffeqs/sdesystem.jl b/src/systems/diffeqs/sdesystem.jl index 0d73aaf313..9f3814774f 100644 --- a/src/systems/diffeqs/sdesystem.jl +++ b/src/systems/diffeqs/sdesystem.jl @@ -80,6 +80,10 @@ struct SDESystem <: AbstractODESystem """ name::Symbol """ + A description of the system. + """ + description::String + """ The internal systems. These are required to have unique names. """ systems::Vector{SDESystem} @@ -142,7 +146,7 @@ struct SDESystem <: AbstractODESystem function SDESystem(tag, deqs, neqs, iv, dvs, ps, tspan, var_to_name, ctrls, observed, tgrad, jac, - ctrl_jac, Wfact, Wfact_t, name, systems, defaults, connector_type, + ctrl_jac, Wfact, Wfact_t, name, description, systems, defaults, connector_type, cevents, devents, parameter_dependencies, metadata = nothing, gui_metadata = nothing, complete = false, index_cache = nothing, parent = nothing, is_scalar_noise = false, is_dde = false, @@ -168,7 +172,8 @@ struct SDESystem <: AbstractODESystem end new(tag, deqs, neqs, iv, dvs, ps, tspan, var_to_name, ctrls, observed, tgrad, jac, ctrl_jac, - Wfact, Wfact_t, name, systems, defaults, connector_type, cevents, devents, + Wfact, Wfact_t, name, description, systems, + defaults, connector_type, cevents, devents, parameter_dependencies, metadata, gui_metadata, complete, index_cache, parent, is_scalar_noise, is_dde, isscheduled) end @@ -183,6 +188,7 @@ function SDESystem(deqs::AbstractVector{<:Equation}, neqs::AbstractArray, iv, dv default_p = Dict(), defaults = _merge(Dict(default_u0), Dict(default_p)), name = nothing, + description = "", connector_type = nothing, checks = true, continuous_events = nothing, @@ -234,7 +240,7 @@ function SDESystem(deqs::AbstractVector{<:Equation}, neqs::AbstractArray, iv, dv end SDESystem(Threads.atomic_add!(SYSTEM_COUNT, UInt(1)), deqs, neqs, iv′, dvs′, ps′, tspan, var_to_name, ctrl′, observed, tgrad, jac, - ctrl_jac, Wfact, Wfact_t, name, systems, defaults, connector_type, + ctrl_jac, Wfact, Wfact_t, name, description, systems, defaults, connector_type, cont_callbacks, disc_callbacks, parameter_dependencies, metadata, gui_metadata, complete, index_cache, parent, is_scalar_noise, is_dde; checks = checks) end @@ -349,7 +355,8 @@ function stochastic_integral_transform(sys::SDESystem, correction_factor) end SDESystem(deqs, get_noiseeqs(sys), get_iv(sys), unknowns(sys), parameters(sys), - name = name, parameter_dependencies = parameter_dependencies(sys), checks = false) + name = name, description = description(sys), + parameter_dependencies = parameter_dependencies(sys), checks = false) end """ @@ -457,7 +464,8 @@ function Girsanov_transform(sys::SDESystem, u; θ0 = 1.0) # return modified SDE System SDESystem(deqs, noiseeqs, get_iv(sys), unknown_vars, parameters(sys); defaults = Dict(θ => θ0), observed = [weight ~ θ / θ0], - name = name, parameter_dependencies = parameter_dependencies(sys), + name = name, description = description(sys), + parameter_dependencies = parameter_dependencies(sys), checks = false) end diff --git a/src/systems/discrete_system/discrete_system.jl b/src/systems/discrete_system/discrete_system.jl index b09ecf5c4c..3e220998cb 100644 --- a/src/systems/discrete_system/discrete_system.jl +++ b/src/systems/discrete_system/discrete_system.jl @@ -42,6 +42,10 @@ struct DiscreteSystem <: AbstractTimeDependentSystem """ name::Symbol """ + A description of the system. + """ + description::String + """ The internal systems. These are required to have unique names. """ systems::Vector{DiscreteSystem} @@ -95,7 +99,7 @@ struct DiscreteSystem <: AbstractTimeDependentSystem function DiscreteSystem(tag, discreteEqs, iv, dvs, ps, tspan, var_to_name, observed, - name, + name, description, systems, defaults, preface, connector_type, parameter_dependencies = Equation[], metadata = nothing, gui_metadata = nothing, tearing_state = nothing, substitutions = nothing, @@ -111,7 +115,7 @@ struct DiscreteSystem <: AbstractTimeDependentSystem u = __get_unit_type(dvs, ps, iv) check_units(u, discreteEqs) end - new(tag, discreteEqs, iv, dvs, ps, tspan, var_to_name, observed, name, + new(tag, discreteEqs, iv, dvs, ps, tspan, var_to_name, observed, name, description, systems, defaults, preface, connector_type, parameter_dependencies, metadata, gui_metadata, @@ -128,6 +132,7 @@ function DiscreteSystem(eqs::AbstractVector{<:Equation}, iv, dvs, ps; systems = DiscreteSystem[], tspan = nothing, name = nothing, + description = "", default_u0 = Dict(), default_p = Dict(), defaults = _merge(Dict(default_u0), Dict(default_p)), @@ -164,7 +169,7 @@ function DiscreteSystem(eqs::AbstractVector{<:Equation}, iv, dvs, ps; throw(ArgumentError("System names must be unique.")) end DiscreteSystem(Threads.atomic_add!(SYSTEM_COUNT, UInt(1)), - eqs, iv′, dvs′, ps′, tspan, var_to_name, observed, name, systems, + eqs, iv′, dvs′, ps′, tspan, var_to_name, observed, name, description, systems, defaults, preface, connector_type, parameter_dependencies, metadata, gui_metadata, kwargs...) end @@ -221,6 +226,7 @@ function flatten(sys::DiscreteSystem, noeqs = false) observed = observed(sys), defaults = defaults(sys), name = nameof(sys), + description = description(sys), checks = false) end end diff --git a/src/systems/jumps/jumpsystem.jl b/src/systems/jumps/jumpsystem.jl index a714d4b364..6409609a10 100644 --- a/src/systems/jumps/jumpsystem.jl +++ b/src/systems/jumps/jumpsystem.jl @@ -74,6 +74,8 @@ struct JumpSystem{U <: ArrayPartition} <: AbstractTimeDependentSystem observed::Vector{Equation} """The name of the system.""" name::Symbol + """A description of the system.""" + description::String """The internal systems. These are required to have unique names.""" systems::Vector{JumpSystem} """ @@ -116,7 +118,8 @@ struct JumpSystem{U <: ArrayPartition} <: AbstractTimeDependentSystem index_cache::Union{Nothing, IndexCache} isscheduled::Bool - function JumpSystem{U}(tag, ap::U, iv, unknowns, ps, var_to_name, observed, name, + function JumpSystem{U}( + tag, ap::U, iv, unknowns, ps, var_to_name, observed, name, description, systems, defaults, connector_type, devents, parameter_dependencies, metadata = nothing, gui_metadata = nothing, @@ -131,7 +134,8 @@ struct JumpSystem{U <: ArrayPartition} <: AbstractTimeDependentSystem u = __get_unit_type(unknowns, ps, iv) check_units(u, ap, iv) end - new{U}(tag, ap, iv, unknowns, ps, var_to_name, observed, name, systems, defaults, + new{U}(tag, ap, iv, unknowns, ps, var_to_name, + observed, name, description, systems, defaults, connector_type, devents, parameter_dependencies, metadata, gui_metadata, complete, index_cache, isscheduled) end @@ -147,6 +151,7 @@ function JumpSystem(eqs, iv, unknowns, ps; default_p = Dict(), defaults = _merge(Dict(default_u0), Dict(default_p)), name = nothing, + description = "", connector_type = nothing, checks = true, continuous_events = nothing, @@ -193,7 +198,7 @@ function JumpSystem(eqs, iv, unknowns, ps; disc_callbacks = SymbolicDiscreteCallbacks(discrete_events) parameter_dependencies, ps = process_parameter_dependencies(parameter_dependencies, ps) JumpSystem{typeof(ap)}(Threads.atomic_add!(SYSTEM_COUNT, UInt(1)), - ap, value(iv), unknowns, ps, var_to_name, observed, name, systems, + ap, value(iv), unknowns, ps, var_to_name, observed, name, description, systems, defaults, connector_type, disc_callbacks, parameter_dependencies, metadata, gui_metadata, checks = checks) end diff --git a/src/systems/nonlinear/nonlinearsystem.jl b/src/systems/nonlinear/nonlinearsystem.jl index d9ad826a2c..3b0e4b7e92 100644 --- a/src/systems/nonlinear/nonlinearsystem.jl +++ b/src/systems/nonlinear/nonlinearsystem.jl @@ -44,6 +44,10 @@ struct NonlinearSystem <: AbstractTimeIndependentSystem """ name::Symbol """ + A description of the system. + """ + description::String + """ The internal systems. These are required to have unique names. """ systems::Vector{NonlinearSystem} @@ -91,7 +95,8 @@ struct NonlinearSystem <: AbstractTimeIndependentSystem parent::Any isscheduled::Bool - function NonlinearSystem(tag, eqs, unknowns, ps, var_to_name, observed, jac, name, + function NonlinearSystem( + tag, eqs, unknowns, ps, var_to_name, observed, jac, name, description, systems, defaults, connector_type, parameter_dependencies = Equation[], metadata = nothing, gui_metadata = nothing, @@ -102,7 +107,8 @@ struct NonlinearSystem <: AbstractTimeIndependentSystem u = __get_unit_type(unknowns, ps) check_units(u, eqs) end - new(tag, eqs, unknowns, ps, var_to_name, observed, jac, name, systems, defaults, + new(tag, eqs, unknowns, ps, var_to_name, observed, + jac, name, description, systems, defaults, connector_type, parameter_dependencies, metadata, gui_metadata, tearing_state, substitutions, complete, index_cache, parent, isscheduled) end @@ -111,6 +117,7 @@ end function NonlinearSystem(eqs, unknowns, ps; observed = [], name = nothing, + description = "", default_u0 = Dict(), default_p = Dict(), defaults = _merge(Dict(default_u0), Dict(default_p)), @@ -157,7 +164,7 @@ function NonlinearSystem(eqs, unknowns, ps; parameter_dependencies, ps = process_parameter_dependencies( parameter_dependencies, ps) NonlinearSystem(Threads.atomic_add!(SYSTEM_COUNT, UInt(1)), - eqs, unknowns, ps, var_to_name, observed, jac, name, systems, defaults, + eqs, unknowns, ps, var_to_name, observed, jac, name, description, systems, defaults, connector_type, parameter_dependencies, metadata, gui_metadata, checks = checks) end @@ -554,6 +561,7 @@ function flatten(sys::NonlinearSystem, noeqs = false) observed = observed(sys), defaults = defaults(sys), name = nameof(sys), + description = description(sys), checks = false) end end diff --git a/src/systems/optimization/constraints_system.jl b/src/systems/optimization/constraints_system.jl index f9176df3a2..a2756994ac 100644 --- a/src/systems/optimization/constraints_system.jl +++ b/src/systems/optimization/constraints_system.jl @@ -45,6 +45,10 @@ struct ConstraintsSystem <: AbstractTimeIndependentSystem """ name::Symbol """ + A description of the system. + """ + description::String + """ The internal systems. These are required to have unique names. """ systems::Vector{ConstraintsSystem} @@ -79,7 +83,7 @@ struct ConstraintsSystem <: AbstractTimeIndependentSystem index_cache::Union{Nothing, IndexCache} function ConstraintsSystem(tag, constraints, unknowns, ps, var_to_name, observed, jac, - name, + name, description, systems, defaults, connector_type, metadata = nothing, tearing_state = nothing, substitutions = nothing, @@ -89,7 +93,8 @@ struct ConstraintsSystem <: AbstractTimeIndependentSystem u = __get_unit_type(unknowns, ps) check_units(u, constraints) end - new(tag, constraints, unknowns, ps, var_to_name, observed, jac, name, systems, + new(tag, constraints, unknowns, ps, var_to_name, + observed, jac, name, description, systems, defaults, connector_type, metadata, tearing_state, substitutions, complete, index_cache) end @@ -100,6 +105,7 @@ equations(sys::ConstraintsSystem) = constraints(sys) # needed for Base.show function ConstraintsSystem(constraints, unknowns, ps; observed = [], name = nothing, + description = "", default_u0 = Dict(), default_p = Dict(), defaults = _merge(Dict(default_u0), Dict(default_p)), @@ -142,7 +148,7 @@ function ConstraintsSystem(constraints, unknowns, ps; isempty(observed) || collect_var_to_name!(var_to_name, (eq.lhs for eq in observed)) ConstraintsSystem(Threads.atomic_add!(SYSTEM_COUNT, UInt(1)), - cstr, unknowns, ps, var_to_name, observed, jac, name, systems, + cstr, unknowns, ps, var_to_name, observed, jac, name, description, systems, defaults, connector_type, metadata, checks = checks) end diff --git a/src/systems/optimization/optimizationsystem.jl b/src/systems/optimization/optimizationsystem.jl index 22488e8bad..1f543dc8d1 100644 --- a/src/systems/optimization/optimizationsystem.jl +++ b/src/systems/optimization/optimizationsystem.jl @@ -37,6 +37,8 @@ struct OptimizationSystem <: AbstractOptimizationSystem constraints::Vector{Union{Equation, Inequality}} """The name of the system.""" name::Symbol + """A description of the system.""" + description::String """The internal systems. These are required to have unique names.""" systems::Vector{OptimizationSystem} """ @@ -67,7 +69,7 @@ struct OptimizationSystem <: AbstractOptimizationSystem isscheduled::Bool function OptimizationSystem(tag, op, unknowns, ps, var_to_name, observed, - constraints, name, systems, defaults, metadata = nothing, + constraints, name, description, systems, defaults, metadata = nothing, gui_metadata = nothing, complete = false, index_cache = nothing, parent = nothing, isscheduled = false; checks::Union{Bool, Int} = true) @@ -78,7 +80,7 @@ struct OptimizationSystem <: AbstractOptimizationSystem check_units(u, constraints) end new(tag, op, unknowns, ps, var_to_name, observed, - constraints, name, systems, defaults, metadata, gui_metadata, complete, + constraints, name, description, systems, defaults, metadata, gui_metadata, complete, index_cache, parent, isscheduled) end end @@ -92,6 +94,7 @@ function OptimizationSystem(op, unknowns, ps; default_p = Dict(), defaults = _merge(Dict(default_u0), Dict(default_p)), name = nothing, + description = "", systems = OptimizationSystem[], checks = true, metadata = nothing, @@ -125,7 +128,7 @@ function OptimizationSystem(op, unknowns, ps; op′, unknowns′, ps′, var_to_name, observed, constraints, - name, systems, defaults, metadata, gui_metadata; + name, description, systems, defaults, metadata, gui_metadata; checks = checks) end diff --git a/src/systems/pde/pdesystem.jl b/src/systems/pde/pdesystem.jl index 7aa3f29191..eac540e401 100644 --- a/src/systems/pde/pdesystem.jl +++ b/src/systems/pde/pdesystem.jl @@ -78,6 +78,10 @@ struct PDESystem <: ModelingToolkit.AbstractMultivariateSystem """ name::Symbol """ + A description of the system. + """ + description::String + """ Metadata for the system, to be used by downstream packages. """ metadata::Any @@ -96,6 +100,7 @@ struct PDESystem <: ModelingToolkit.AbstractMultivariateSystem gui_metadata = nothing, eval_module = @__MODULE__, checks::Union{Bool, Int} = true, + description = "", name) if checks == true || (checks & CheckUnits) > 0 u = __get_unit_type(dvs, ivs, ps) @@ -127,7 +132,7 @@ struct PDESystem <: ModelingToolkit.AbstractMultivariateSystem end new(eqs, bcs, domain, ivs, dvs, ps, defaults, connector_type, systems, analytic, - analytic_func, name, metadata, gui_metadata) + analytic_func, name, description, metadata, gui_metadata) end end diff --git a/test/components.jl b/test/components.jl index 965578e0c5..ea63e3e758 100644 --- a/test/components.jl +++ b/test/components.jl @@ -41,7 +41,7 @@ end completed_rc_model = complete(rc_model) @test isequal(completed_rc_model.resistor.n.i, resistor.n.i) -@test ModelingToolkit.n_extra_equations(capacitor) == 2 +@test ModelingToolkit.n_expanded_connection_equations(capacitor) == 2 @test length(equations(structural_simplify(rc_model, allow_parameter = false))) == 2 sys = structural_simplify(rc_model) @test_throws ModelingToolkit.RepeatedStructuralSimplificationError structural_simplify(sys)