diff --git a/docs/src/API/System.md b/docs/src/API/System.md index 379e7fa19b..c7cf3cdd9b 100644 --- a/docs/src/API/System.md +++ b/docs/src/API/System.md @@ -7,6 +7,7 @@ optimizations). ```@docs System +ModelingToolkit.AbstractSystem ``` ## Utility constructors @@ -185,3 +186,41 @@ ModelingToolkit.is_bound ```@docs debug_system ``` + +## Input validation + +The following values can be passed to the `check` keyword of `System` to toggle validation +of input. Flags can be combined with bitwise `|` and `&`. + +```@docs +ModelingToolkit.CheckAll +ModelingToolkit.CheckNone +ModelingToolkit.CheckComponents +ModelingToolkit.CheckUnits +``` + +These can also be used by custom `AbstractSystem` subtypes. + +## Utility functions + +These utility functions can be useful when manipulating systems, especially when building +custom `AbstractSystem` subtypes. + +```@docs +ModelingToolkit.collect_scoped_vars! +ModelingToolkit.collect_var_to_name! +ModelingToolkit.collect_vars! +ModelingToolkit.eqtype_supports_collect_vars +ModelingToolkit.modified_unknowns! +``` + +## Namepsace manipulation + +ModelingToolkit namespaces variables from subsystems when using them in a parent system to +disambiguate from identically named variables in other subsystems or the parent system. The +following functions are useful for manipulating namespacing functionality. + +```@docs +ModelingToolkit.renamespace +ModelingToolkit.namespace_equations +``` diff --git a/docs/src/API/model_building.md b/docs/src/API/model_building.md index cbdf72edae..28069b535e 100644 --- a/docs/src/API/model_building.md +++ b/docs/src/API/model_building.md @@ -3,6 +3,29 @@ This page lists functionality and utilities related to building hierarchical models. It is recommended to read the page on the [`System`](@ref System_type) before this. +## Common definitions of `t` and `D` + +ModelingToolkit provides common definitions for the independent variable `t` (time) and the +derivative with respect to it `D`. + +```@docs +ModelingToolkit.t_nounits +ModelingToolkit.D_nounits +ModelingToolkit.t +ModelingToolkit.D +ModelingToolkit.t_unitful +ModelingToolkit.D_unitful +``` + +Users are recommended to use the appropriate common definition in their models. The required +definitions can be imported with convenient aliased names. For example: + +```julia +using ModelingToolkit: t_nounits as t, D_nounits as D +``` + +Allows using `t` and `D` to refer to `t_nounits` and `D_nounits` respectively. + ## Hierarchical model composition The `System` data structure can represent a tree-like hierarchy of systems for building models diff --git a/docs/src/API/variables.md b/docs/src/API/variables.md index 4c11d900c9..99fd53372c 100644 --- a/docs/src/API/variables.md +++ b/docs/src/API/variables.md @@ -18,6 +18,17 @@ Symbolic variables can have metadata attached to them. The defaults and guesses at variable construction time are examples of this metadata. ModelingToolkit also defines additional types of metadata. +## Variable defaults + +Variables can be assigned default values to avoid having to specify defaults to the +[`System`](@ref) constructor. + +```@docs +ModelingToolkit.hasdefault +ModelingToolkit.getdefault +ModelingToolkit.setdefault +``` + ## Variable descriptions Descriptive strings can be attached to variables using the `[description = "descriptive string"]` syntax: @@ -56,6 +67,7 @@ help?> u ```@docs hasdescription getdescription +ModelingToolkit.VariableDescription ``` ## Connect @@ -83,6 +95,7 @@ getconnect(k) ```@docs hasconnect getconnect +ModelingToolkit.VariableConnectType ``` ```@docs; canonical=false @@ -112,6 +125,8 @@ isinput isoutput ModelingToolkit.setinput ModelingToolkit.setoutput +ModelingToolkit.VariableInput +ModelingToolkit.VariableOutput ``` ## Bounds @@ -144,6 +159,7 @@ hasbounds(x[2]) ```@docs hasbounds getbounds +ModelingToolkit.VariableBounds ``` ## Guess @@ -232,6 +248,7 @@ isirreducible(important_value) ```@docs isirreducible +ModelingToolkit.VariableIrreducible ``` ## State Priority @@ -245,6 +262,7 @@ state_priority(important_dof) ```@docs state_priority +ModelingToolkit.VariableStatePriority ``` ## Units @@ -261,6 +279,17 @@ getunit(speed) ```@docs hasunit getunit +ModelingToolkit.VariableUnit +``` + +## Variable type + +This metadata is used by the [`System`](@ref) constructor for automatically identifying the different types of variables in a system. + +```@docs +ModelingToolkit.VariableType +ModelingToolkit.MTKVariableTypeCtx +ModelingToolkit.isparameter ``` ## Miscellaneous metadata @@ -277,6 +306,7 @@ getmisc(y) ```@docs hasmisc getmisc +ModelingToolkit.VariableMisc ``` ## Dumping metadata diff --git a/src/ModelingToolkit.jl b/src/ModelingToolkit.jl index 1dbf9d37dd..26efc0c7a9 100644 --- a/src/ModelingToolkit.jl +++ b/src/ModelingToolkit.jl @@ -134,7 +134,7 @@ in a non-breaking release. Usage of these arguments is not advised. """ $(TYPEDEF) -TODO +Abstract supertype of all system types. Any custom system types must subtype this. """ abstract type AbstractSystem end # Solely so that `ODESystem` can be deprecated and still act as a valid type. @@ -336,6 +336,15 @@ export DynamicOptSolution @public is_diff_equation, Equality, linearize_symbolic, reorder_unknowns @public similarity_transform, inputs, outputs, bound_inputs, unbound_inputs, bound_outputs @public unbound_outputs, is_bound +@public AbstractSystem, CheckAll, CheckNone, CheckComponents, CheckUnits +@public t, D, t_nounits, D_nounits, t_unitful, D_unitful +@public SymbolicContinuousCallback, SymbolicDiscreteCallback +@public VariableType, MTKVariableTypeCtx, VariableBounds, VariableConnectType +@public VariableDescription, VariableInput, VariableIrreducible, VariableMisc +@public VariableOutput, VariableStatePriority, VariableUnit, collect_scoped_vars! +@public collect_var_to_name!, collect_vars!, eqtype_supports_collect_vars, hasdefault +@public getdefault, setdefault, iscomplete, isparameter, modified_unknowns! +@public renamespace, namespace_equations for prop in [SYS_PROPS; [:continuous_events, :discrete_events]] getter = Symbol(:get_, prop) diff --git a/src/parameters.jl b/src/parameters.jl index de7a722af3..7633d8c1b7 100644 --- a/src/parameters.jl +++ b/src/parameters.jl @@ -1,9 +1,27 @@ import SymbolicUtils: symtype, term, hasmetadata, issym + +""" + @enum VariableType + +The type of the declared variable, used for automatic identification of +variables/parameters/brownians/etc. by the `System` constructor. +""" @enum VariableType VARIABLE PARAMETER BROWNIAN + +""" + $TYPEDEF + +The symbolic metadata key for storing the `VariableType`. +""" struct MTKVariableTypeCtx end getvariabletype(x, def = VARIABLE) = getmetadata(unwrap(x), MTKVariableTypeCtx, def) +""" + $TYPEDEF + +Check if the variable contains the metadata identifying it as a parameter. +""" function isparameter(x) x = unwrap(x) diff --git a/src/problems/jumpproblem.jl b/src/problems/jumpproblem.jl index 3bc0e11f61..32aa25182f 100644 --- a/src/problems/jumpproblem.jl +++ b/src/problems/jumpproblem.jl @@ -210,6 +210,13 @@ function get_variables!(dep, jump::MassActionJump, variables) end ### Functions to determine which unknowns are modified by a given jump + +""" + $(TYPEDSIGNATURES) + +Push to `munknowns` the variables modified by jump `jump`. `sts` is the list of unknowns of +the system. Return the modified `munknowns`. +""" function modified_unknowns!(munknowns, jump::Union{ConstantRateJump, VariableRateJump}, sts) for eq in jump.affect! st = eq.lhs diff --git a/src/systems/abstractsystem.jl b/src/systems/abstractsystem.jl index 3fe04936d3..f9d9a196b4 100644 --- a/src/systems/abstractsystem.jl +++ b/src/systems/abstractsystem.jl @@ -1095,6 +1095,12 @@ end renamespace(sys, eq::Equation) = namespace_equation(eq, sys) renamespace(names::AbstractVector, x) = foldr(renamespace, names, init = x) + +""" + $(TYPEDSIGNATURES) + +Namespace `x` with the name of `sys`. +""" function renamespace(sys, x) sys === nothing && return x x = unwrap(x) @@ -1141,6 +1147,11 @@ function namespace_guesses(sys) Dict(unknowns(sys, k) => namespace_expr(v, sys) for (k, v) in guess) end +""" + $(TYPEDSIGNATURES) + +Return `equations(sys)`, namespaced by the name of `sys`. +""" function namespace_equations(sys::AbstractSystem, ivs = independent_variables(sys)) eqs = equations(sys) isempty(eqs) && return Equation[] @@ -1162,6 +1173,11 @@ function namespace_tstops(sys::AbstractSystem) end end +""" + $(TYPEDSIGNATURES) + +Namespace the given equation with the name of the given system `sys`. +""" function namespace_equation(eq::Equation, sys, n = nameof(sys); diff --git a/src/systems/model_parsing.jl b/src/systems/model_parsing.jl index c24c063ee0..61edc394b2 100644 --- a/src/systems/model_parsing.jl +++ b/src/systems/model_parsing.jl @@ -186,7 +186,6 @@ function update_readable_metadata!(varclass_dict, meta::Dict, varname) (:description, VariableDescription), (:unit, VariableUnit), (:bounds, VariableBounds), - (:noise, VariableNoiseType), (:input, VariableInput), (:output, VariableOutput), (:irreducible, VariableIrreducible), diff --git a/src/utils.jl b/src/utils.jl index d028d4ed18..c6f3777c2b 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -88,9 +88,31 @@ function readable_code(expr) end # System validation enums +""" + const CheckNone + +Value that can be provided to the `check` keyword of `System` to disable checking of input. +""" const CheckNone = 0 +""" + const CheckAll + +Value that can be provided to the `check` keyword of `System` to enable all input +validation. +""" const CheckAll = 1 << 0 +""" + const CheckComponents + +Value that can be provided to the `check` keyword of `System` to only enable checking of +basic components of the system, such as equations, variables, etc. +""" const CheckComponents = 1 << 1 +""" + const CheckUnits + +Value that can be provided to the `check` keyword of `System` to enable checking of units. +""" const CheckUnits = 1 << 2 function check_independent_variables(ivs) @@ -228,8 +250,23 @@ function iv_from_nested_derivative(x, op = Differential) end end +""" + $(TYPEDSIGNATURES) + +Check if the symbolic variable `v` has a default value. +""" hasdefault(v) = hasmetadata(v, Symbolics.VariableDefaultValue) +""" + $(TYPEDSIGNATURES) + +Return the default value of symbolic variable `v`. +""" getdefault(v) = value(Symbolics.getdefaultval(v)) +""" + $(TYPEDSIGNATURES) + +Set the default value of symbolic variable `v` to `val`. +""" function setdefault(v, val) val === nothing ? v : wrap(setdefaultval(unwrap(v), value(val))) end diff --git a/src/variables.jl b/src/variables.jl index b61298eca2..46c9c95bc6 100644 --- a/src/variables.jl +++ b/src/variables.jl @@ -1,10 +1,45 @@ +""" + $TYPEDEF + +Symbolic metadata key for storing the unit associated with a symbolic variable. +""" struct VariableUnit end +""" + $TYPEDEF + +Symbolic metadata key for storing the type of connector that a variable is. +""" struct VariableConnectType end -struct VariableNoiseType end +""" + $TYPEDEF + +Symbolic metadata key for storing whether a symbolic variable is an input or not. +""" struct VariableInput end +""" + $TYPEDEF + +Symbolic metadata key for storing whether a symbolic variable is an output or not. +""" struct VariableOutput end +""" + $TYPEDEF + +Symbolic metadata key for storing whether a symbolic variable is irreducible or not. +""" struct VariableIrreducible end +""" + $TYPEDEF + +Symbolic metadata key for storing the priority a variable has for being selected during +state selection. +""" struct VariableStatePriority end +""" + $TYPEDEF + +Symbolic metadata key for storing miscellaneous information about a symbolic variable. +""" struct VariableMisc end # Metadata for renamed shift variables xₜ₋₁ struct VariableUnshifted end @@ -227,6 +262,11 @@ function default_toterm(x) end ## Bounds ====================================================================== +""" + $TYPEDEF + +Symbolic metadata key for specifying the bounds of a symbolic variable. +""" struct VariableBounds end Symbolics.option_to_metadata_type(::Val{:bounds}) = VariableBounds @@ -436,6 +476,11 @@ function getbounds(p::AbstractVector) end ## Description ================================================================= +""" + $TYPEDEF + +Symbolic metadata key for storing the description of a symbolic variable. +""" struct VariableDescription end Symbolics.option_to_metadata_type(::Val{:description}) = VariableDescription