The System type
ModelingToolkit.jl uses System to symbolically represent all types of numerical problems. Users create Systems representing the problem they want to solve and mtkcompile transforms them into a format ModelingToolkit.jl can generate code for (alongside performing other optimizations).
ModelingToolkitBase.System — Type
struct System <: ModelingToolkitBase.IntermediateDeprecationSystemA symbolic representation of a numerical system to be solved. This is a recursive tree-like data structure - each system can contain additional subsystems. As such, it implements the AbstractTrees.jl interface to enable exploring the hierarchical structure.
Fields
tag::UInt64: This field is internal API. It may be removed or changed without notice in a non-breaking release. Usage of this field is not advised.A unique integer tag for the system.
eqs::Vector{Equation}: The equations of the system.
noise_eqs::Union{Nothing, VecOrMat{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}}: The noise terms for each equation of the system. This field is only used for flattened systems. To represent noise in a hierarchical system, use brownians. In a system withNequations andKindependent brownian variables, this should be anN x Kmatrix. In the special case whereN == Kand each equation has independent noise, this noise matrix is diagonal. Diagonal noise can be specified by providing anNlength vector. If this field isnothing, the system does not have noise.
jumps::Vector{Union{JumpProcesses.ConstantRateJump, JumpProcesses.MassActionJump, JumpProcesses.VariableRateJump}}: Jumps associated with the system. Each jump can be aVariableRateJump,ConstantRateJumporMassActionJump. SeeJumpProcesses.jlfor more information.MassActionJumps must usescale_rates = false(pre-scaled rate expressions); seeSymbolicMassActionJump.
constraints::Vector{Union{Equation, Inequality}}: The constraints of the system. This can be used to represent the constraints in an optimal-control problem or boundary-value differential equation, or the constraints in a constrained optimization.
costs::Vector{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}: The costs of the system. This can be the cost in an optimal-control problem, or the loss of an optimization problem. Scalar loss values must also be provided as a single- element vector.
consolidate::Any: A function which combines costs into a scalar value. This should take two arguments, thecostsof this system and the consolidated costs of all subsystems in the order they are present in thesystemsfield. It should return a scalar cost that combines all of the individual values. This defaults to a function that simply sums all cost values.
unknowns::Vector{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}: The variables being solved for by this system. For example, in a differential equation system, this contains the dependent variables.
ps::Vector{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}: The parameters of the system. Parameters can either be variables that parameterize the problem being solved for (e.g. the spring constant of a mass-spring system) or additional unknowns not part of the main dynamics of the system (e.g. discrete/clocked variables in a hybrid ODE).
brownians::Vector{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}: The brownian variables of the system, created via@brownians. Each brownian variable represents an independent noise. A system with brownians cannot be simulated directly. It needs to be compiled usingmtkcompileintonoise_eqs.
poissonians::Vector{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}: The poissonian variables of the system, created via@poissonians. Each poissonian variable represents an independent Poisson counting process with an associated rate. A system with poissonians cannot be simulated directly. It needs to be compiled usingmtkcompilewhich converts poissonians into jump equations.
iv::Union{Nothing, SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}: The independent variable for a time-dependent system, ornothingfor a time-independent system.
observed::Vector{Equation}: Equations that compute variables of a system that have been eliminated from the set of unknowns bymtkcompile. More generally, this contains all variables that can be computed from the unknowns and parameters and do not need to be solved for. Such variables are termed as "observables". Each equation must be of the formobservable ~ expressionand observables cannot appear on the LHS of multiple equations. Equations must be sorted such that every observable appears on the left hand side of an equation before it appears on the right hand side of any other equation.
var_to_name::Dict{Symbol, SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}: This field is internal API. It may be removed or changed without notice in a non-breaking release. Usage of this field is not advised.A mapping from the name of a variable to the actual symbolic variable in the system. This is used to enable
getpropertysyntax to access variables of a system.
name::Symbol: The name of the system.
description::String: An optional description for the system.
bindings::ReadOnlyDicts.ReadOnlyDict{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, ModelingToolkitBase.AtomicArrayDict{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, Dict{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}}}: Binding relations for variables/parameters. The bound variable (key) is completely determined by the binding (value). Providing an initial condition for a bound variable is an error. Bindings for variables (ones created via@variablesand@discretes) are treated as initial conditions.
initial_conditions::ModelingToolkitBase.AtomicArrayDict{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, Dict{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}}: Initial conditions for variables (unknowns/observables/parameters) which can be changed/overridden. When constructing a numerical problem from the system.
guesses::ModelingToolkitBase.AtomicArrayDict{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, Dict{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}}: Guess values for variables of a system that are solved for during initialization.
systems::Vector{System}: A list of subsystems of this system. Used for hierarchically building models.
initialization_eqs::Vector{Equation}: Equations that must be satisfied during initialization of the numerical problem created from this system. For time-dependent systems, these equations are not valid after the initial time.
continuous_events::Vector{ModelingToolkitBase.SymbolicContinuousCallback}: Symbolic representation of continuous events in a dynamical system. SeeSymbolicContinuousCallback.
discrete_events::Vector{ModelingToolkitBase.SymbolicDiscreteCallback}: Symbolic representation of discrete events in a dynamica system. SeeSymbolicDiscreteCallback.
connector_type::Any: This field is internal API. It may be removed or changed without notice in a non-breaking release. Usage of this field is not advised.If this system is a connector, the type of connector it is.
assertions::Dict{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, String}: A map from expressions that must be through throughout the solution process to an associated error message. By default these assertions cause the generated code to outputNaNs if violated, but can be made to error usingdebug_system.
metadata::Base.ImmutableDict{DataType, Any}: The metadata associated with this system, as aBase.ImmutableDict. This follows the same interface as SymbolicUtils.jl. Metadata can be queried and updated usingSymbolicUtils.getmetadataandSymbolicUtils.setmetadatarespectively.
gui_metadata::Any: This field is internal API. It may be removed or changed without notice in a non-breaking release. Usage of this field is not advised.Metadata added by the
@mtkmodelmacro.
is_dde::Bool: Whether the system contains delay terms. This is inferred from the equations, but can also be provided explicitly.
tstops::Vector{Any}: Extra time points for the integrator to stop at. These can be numeric values, or expressions of parameters and time.
tspan::Union{Nothing, Tuple}: The(t0, t1)timespan of the system, ornothingif it does not have one. Time-dependent problem constructors use it as thetspanwhen the caller does not pass one. Only the timespan of the top-level system is used; those of subsystems are ignored.
inputs::OrderedCollections.OrderedSet{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}: This field is internal API. It may be removed or changed without notice in a non-breaking release. Usage of this field is not advised.The list of input variables of the system.
outputs::OrderedCollections.OrderedSet{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}: This field is internal API. It may be removed or changed without notice in a non-breaking release. Usage of this field is not advised.The list of output variables of the system.
tearing_state::Any: TheTearingStateof the system post-simplification withmtkcompile.
namespacing::Bool: Whether the system namespaces variables accessed viagetproperty.completed systems do not namespace, but this flag can be toggled independently ofcompleteusingtoggle_namespacing.
complete::Bool: Whether the system is marked as "complete". Completed systems cannot be used as subsystems.
index_cache::Union{Nothing, ModelingToolkitBase.IndexCache}: This field is internal API. It may be removed or changed without notice in a non-breaking release. Usage of this field is not advised.For systems simplified or completed with
split = true(the default) this contains anIndexCachewhich aids in symbolic indexing. If this field isnothing, the system is either not completed, or completed withsplit = false.
parameter_bindings_graph::Union{Nothing, ModelingToolkitBase.ParameterBindingsGraph}: This field is internal API. It may be removed or changed without notice in a non-breaking release. Usage of this field is not advised.Contains the dependency graph of bound parameters to avoid excessive duplicated work during code generation.
ignored_connections::Union{Nothing, Vector{Connection}}: This field is internal API. It may be removed or changed without notice in a non-breaking release. Usage of this field is not advised.Connections that should be ignored because they were removed by an analysis point transformation. The first element of the tuple contains all such "standard" connections (ones between connector systems) and the second contains all such causal variable connections.
preface::Any:SymbolicUtils.Code.Assignments to prepend to all code generated from this system.
parent::Union{Nothing, System}: After simplification withmtkcompile, this field contains the unsimplified system with the hierarchical structure. There may be multiple levels ofparents. The root parent is used for accessing variables viagetpropertysyntax.
initializesystem::Union{Nothing, System}: A custom initialization system to use if no initial conditions are provided for the unknowns or observables of this system.
is_initializesystem::Bool: Whether the current system is an initialization system.
is_discrete::Boolstate_priorities::ModelingToolkitBase.AtomicArrayDict{Int64, Dict{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, Int64}}: State priorities for variables. Used in structural simplification algorithms.
irreducibles::ModelingToolkitBase.AtomicArraySet{Dict{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, Nothing}}: Variables marked as irreducible for simplification.
maybe_zeros::ModelingToolkitBase.AtomicArraySet{Dict{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, Nothing}}: Expressions which may be zero and should be given special consideration during simplification.
irstructure_tlv::TaskLocalValues.TaskLocalValue{IRStructure{SymReal}}: This field is internal API. It may be removed or changed without notice in a non-breaking release. Usage of this field is not advised.The
IRStructureused for efficient symbolic manipulation, stored in aTaskLocalValue.
isscheduled::Bool: This field is internal API. It may be removed or changed without notice in a non-breaking release. Usage of this field is not advised.Whether the system has been simplified by
mtkcompile.
schedule::Union{Nothing, ModelingToolkitBase.Schedule}: This field is internal API. It may be removed or changed without notice in a non-breaking release. Usage of this field is not advised.The
Schedulecontaining additional information about the simplified system.
analytically_integrated::Dict{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}: Keys are variables thatmtkcompilemanaged to integrate analytically. The analytically integrated expression is present as an observed equation. Despite being observed, these variables require initial conditions, typically to solve for auxililar parameters. For example,D(x) ~ 0may be analytically solved asx ~ x0, in which case the new parameterx0requires a value. Initialization solves for this value given an initial condition forx. Currently, setting this field is only valid for flattened systems.The values correspond to the introduced parameter for the constant of integration. This must be solvable (have a binding of
missing) and is allowed to be modified by callbacks as a proxy for updating the analytically integrated variable.
ModelingToolkitBase.AbstractSystem — Type
abstract type AbstractSystemAbstract supertype of all system types.
Custom system types must subtype AbstractSystem and implement the required structural interface:
nameof(sys)::Symbolmust identify the system within its parent's subsystem list.get_systems(sys)::Vector{<:AbstractSystem}must return the direct, finite, acyclic subsystem hierarchy.
Both requirements default to fields named name and systems, respectively. Additional system data is optional. Generic code must use the public has_x/get_x accessors described in the AbstractSystem interface, rather than depending on the fields of System or another concrete subtype. A custom type may extend the documented generic accessors, including independent_variable, when its storage does not match those defaults; it should not extend internal compilation or problem-construction functions.
Examples
A minimal custom system can participate in generic hierarchy traversal without implementing any methods:
struct CustomSystem <: AbstractSystem
name::Symbol
systems::Vector{AbstractSystem}
end
leaf = CustomSystem(:leaf, AbstractSystem[])
root = CustomSystem(:root, AbstractSystem[leaf])
nameof(root)
get_systems(root)The rules that hold for every AbstractSystem, and the generic functions available on any subtype, are stated in The AbstractSystem Interface.
Utility constructors
Several utility constructors also exist to easily construct alternative system formulations. NonlinearSystem, ODESystem, DiscreteSystem and ImplicitDiscreteSystem are deprecated aliases for System kept for compatibility with ModelingToolkit v9; they emit a deprecation warning and are documented here so that the warning has a target to look up.
ModelingToolkitBase.NonlinearSystem — Function
NonlinearSystem(sys::System) -> System
Given a time-dependent system sys of ODEs, convert it to a time-independent system of nonlinear equations that solve for the steady-state of the unknowns. This is done by replacing every derivative D(x) of an unknown x with zero. Note that this process does not retain noise equations, brownian terms, jumps or costs associated with sys. All other information such as initial conditions, bindings, guesses, observed and initialization equations are retained. The independent variable of sys becomes a parameter of the returned system.
If sys is hierarchical (it contains subsystems) this transformation will be applied recursively to all subsystems. The output system will be marked as complete if and only if the input system is also complete. This also retains the split flag passed to complete.
See also: complete.
NonlinearSystem(args...; kwargs...)Deprecated alias constructor for System. Use System(args...; kwargs...) in new code.
ModelingToolkitBase.SDESystem — Function
SDESystem(eqs::Vector{Equation}, noise, iv; is_scalar_noise = false, kwargs...)Construct a system of equations with associated noise terms. Instead of specifying noise using @brownians variables, it is specified using a noise matrix noise. iv is the independent variable of the system.
In the general case, noise should be a N x M matrix where N is the number of equations (length(eqs)) and M is the number of independent random variables. noise[i, j] is the diffusion term for equation i and random variable j. If the noise is diagonal (N == M and noise[i, j] == 0 for all i != j) it can be specified as a Vector of length N corresponding to the diagonal of the noise matrix. As a special case, if all equations have the same noise then all rows of noise are identical. This is known as "scalar noise". In this case, noise can be a Vector corresponding to the repeated row and is_scalar_noise must be true.
Note that systems created in this manner cannot be used hierarchically. This should only be used to construct flattened systems. To use such a system hierarchically, it must be converted to use brownian variables using noise_to_brownians. mtkcompile will automatically perform this conversion.
All keyword arguments are the same as those of the System constructor.
SDESystem(eqs::Vector{Equation}, noise, iv, dvs, ps; is_scalar_noise = false, kwargs...)Identical to the 3-argument SDESystem constructor, but uses the explicitly provided dvs and ps for unknowns and parameters of the system.
SDESystem(sys::System, noise; kwargs...) -> System
Attach the given noise matrix noise to the system sys.
ModelingToolkitBase.JumpSystem — Function
JumpSystem(jumps, iv; kwargs...) -> Any
Construct a System to solve a system of jump equations. jumps is an array of jumps, expressed using JumpProcesses.ConstantRateJump, JumpProcesses.VariableRateJump, and JumpProcesses.MassActionJump. It can also include standard equations to simulate jump-diffusion processes. iv should be the independent variable of the system.
MassActionJumps must be constructed with scale_rates = false (pre-scaled rate expressions). Use SymbolicMassActionJump for convenience, which handles this automatically. JumpProcesses will not re-apply factorial scaling on parameter updates for jumps constructed through the MTK pipeline.
All keyword arguments are the same as those of the System constructor.
JumpSystem(jumps, iv, dvs, ps; kwargs...) -> Any
Identical to the 2-argument JumpSystem constructor, but uses the explicitly provided dvs and ps for unknowns and parameters of the system.
See the 2-argument JumpSystem for details on MassActionJump requirements.
ModelingToolkitBase.OptimizationSystem — Function
OptimizationSystem(cost; kwargs...)
Construct a time-independent System for optimizing the specified scalar cost. The system will have no equations.
Unknowns and parameters of the system are inferred from the cost and other values (such as initial conditions) passed to it.
All keyword arguments are the same as those of the System constructor.
OptimizationSystem(cost, dvs, ps; kwargs...)
Identical to the corresponding single-argument OptimizationSystem constructor, except the unknowns and parameters are specified by passing arrays of symbolic variables to dvs and ps respectively.
OptimizationSystem(cost::Array; kwargs...)
Construct a time-independent System for optimizing the specified multi-objective cost. The cost will be reduced to a scalar using the consolidate function. This defaults to summing the specified cost and that of all subsystems. The system will have no equations.
Unknowns and parameters of the system are inferred from the cost and other values (such as initial conditions) passed to it.
All keyword arguments are the same as those of the System constructor.
OptimizationSystem(cost::Array, dvs, ps; kwargs...)
Identical to the corresponding single-argument OptimizationSystem constructor, except the unknowns and parameters are specified by passing arrays of symbolic variables to dvs and ps respectively.
ModelingToolkitBase.ODESystem — Type
ODESystem(args...; kwargs...)Deprecated alias for System.
Use System(args...; kwargs...) in new code.
ModelingToolkitBase.DiscreteSystem — Function
DiscreteSystem(args...; kwargs...)Deprecated alias constructor for System. Use System(args...; kwargs...) in new code.
ModelingToolkitBase.ImplicitDiscreteSystem — Function
ImplicitDiscreteSystem(args...; kwargs...)Deprecated alias constructor for System. Use System(args...; kwargs...) in new code.
getproperty syntax
ModelingToolkit allows obtaining in a system using getproperty. For a system sys with a subcomponent inner containing variable var, sys.inner.var will obtain the appropriately namespaced version of var. Note that this can also be used to access subsystems (sys.inner) or analysis points.
By default, top-level systems not marked as complete will apply their namespace. Systems marked as complete will not do this namespacing. This namespacing behavior can be toggled independently of whether the system is completed using toggle_namespacing and the current namespacing behavior can be queried via ModelingToolkit.does_namespacing.
Base.getproperty — Method
Base.getproperty(sys::AbstractSystem, name::Symbol)Access the subsystem, variable or analysis point of sys named name. To check if sys will namespace the returned value, use ModelingToolkitBase.does_namespacing(sys).
See also: ModelingToolkitBase.does_namespacing.
Functions for querying system equations
ModelingToolkitBase.has_diff_eqs — Function
has_diff_eqs(sys::AbstractSystem)Return true if a system contains at least one differential equation (i.e. an equation with a differential term). Note that this does not consider subsystems, and only takes into account equations in the top-level system.
Example:
using ModelingToolkitBase
using ModelingToolkitBase: t_nounits as t, D_nounits as D
@parameters p d
@variables X(t)
eq1 = D(X) ~ p - d*X
eq2 = 0 ~ p - d*X
@named osys1 = tem([eq1], t)
@named osys2 = tem([eq2], t)
osys12 = compose(osys1, [osys2])
osys21 = compose(osys2, [osys1])
has_diff_eqs(osys12) # returns `true`.
has_diff_eqs(osys21) # returns `false`.ModelingToolkitBase.has_alg_eqs — Function
has_alg_eqs(sys::AbstractSystem)For a system, returns true if it contain at least one algebraic equation (i.e. that does not contain any differentials) in its top-level system.
Example:
using ModelingToolkitBase
using ModelingToolkitBase: t_nounits as t, D_nounits as D
@parameters p d
@variables X(t)
eq1 = D(X) ~ p - d*X
eq2 = 0 ~ p - d*X
@named osys1 = System([eq1], t)
@named osys2 = System([eq2], t)
osys12 = compose(osys1, [osys2])
osys21 = compose(osys2, [osys1])
has_alg_eqs(osys12) # returns `false`.
has_alg_eqs(osys21) # returns `true`.ModelingToolkitBase.get_diff_eqs — Function
get_diff_eqs(sys::AbstractSystem)For a system, returns a vector of all differential equations (i.e. that does contain a differential) in its top-level system.
Example:
using ModelingToolkitBase
using ModelingToolkitBase: t_nounits as t, D_nounits as D
@parameters p d
@variables X(t)
eq1 = D(X) ~ p - d*X
eq2 = 0 ~ p - d*X
@named osys1 = tem([eq1], t)
@named osys2 = tem([eq2], t)
osys12 = compose(osys1, [osys2])
osys21 = compose(osys2, [osys1])
get_diff_eqs(osys12) # returns `[Differential(t)(X(t)) ~ p - d*X(t)]`.
get_diff_eqs(osys21) # returns `Equation[]``.ModelingToolkitBase.get_alg_eqs — Function
get_alg_eqs(sys::AbstractSystem)For a system, returns a vector of all algebraic equations (i.e. that does not contain any differentials) in its top-level system.
Example:
using ModelingToolkitBase
using ModelingToolkitBase: t_nounits as t, D_nounits as D
@parameters p d
@variables X(t)
eq1 = D(X) ~ p - d*X
eq2 = 0 ~ p - d*X
@named osys1 = ([eq1], t)
@named osys2 = ([eq2], t)
osys12 = compose(sys1, [osys2])
osys21 = compose(osys2, [osys1])
get_alg_eqs(osys12) # returns `Equation[]`.
get_alg_eqs(osys21) # returns `[0 ~ p - d*X(t)]`.ModelingToolkitBase.has_diff_equations — Function
has_diff_equations(sys::AbstractSystem)For a system, returns true if it contain at least one differential equation (i.e. that contain a differential).
Example:
using ModelingToolkitBase
using ModelingToolkitBase: t_nounits as t, D_nounits as D
@parameters p d
@variables X(t)
eq1 = D(X) ~ p - d*X
eq2 = 0 ~ p - d*X
@named osys1 = System([eq1], t)
@named osys2 = System([eq2], t)
has_diff_equations(osys1) # returns `true`.
has_diff_equations(osys2) # returns `false`.ModelingToolkitBase.has_alg_equations — Function
has_alg_equations(sys::AbstractSystem)For a system, returns true if it contain at least one algebraic equation (i.e. that does not contain any differentials).
Example:
using ModelingToolkitBase
using ModelingToolkitBase: t_nounits as t, D_nounits as D
@parameters p d
@variables X(t)
eq1 = D(X) ~ p - d*X
eq2 = 0 ~ p - d*X
@named osys1 = System([eq1], t)
@named osys2 = System([eq2], t)
has_alg_equations(osys1) # returns `false`.
has_alg_equations(osys2) # returns `true`.ModelingToolkitBase.diff_equations — Function
diff_equations(sys::AbstractSystem)For a system, returns a vector of all its differential equations (i.e. that does contain a differential).
Example:
using ModelingToolkitBase
using ModelingToolkitBase: t_nounits as t, D_nounits as D
@parameters p d
@variables X(t)
eq1 = D(X) ~ p - d*X
eq2 = 0 ~ p - d*X
@named osys = System([eq1, eq2], t)
diff_equations(osys) # returns `[Differential(t)(X(t)) ~ p - d*X(t)]`.ModelingToolkitBase.alg_equations — Function
alg_equations(sys::AbstractSystem)For a system, returns a vector of all its algebraic equations (i.e. that does not contain any differentials).
Example:
using ModelingToolkitBase
using ModelingToolkitBase: t_nounits as t, D_nounits as D
@parameters p d
@variables X(t)
eq1 = D(X) ~ p - d*X
eq2 = 0 ~ p - d*X
@named osys = System([eq1, eq2], t)
alg_equations(osys) # returns `[0 ~ p - d*X(t)]`.ModelingToolkitBase.is_alg_equation — Function
is_alg_equation(eq)Return true if the input is an algebraic equation, i.e. an equation that does not contain any differentials.
Example:
using ModelingToolkitBase
using ModelingToolkitBase: t_nounits as t, D_nounits as D
@parameters p d
@variables X(t)
eq1 = D(X) ~ p - d*X
eq2 = 0 ~ p - d*X
is_alg_equation(eq1) # false
is_alg_equation(eq2) # trueModelingToolkitBase.is_diff_equation — Function
is_diff_equation(eq)Return true if the input is a differential equation, i.e. an equation that contains a differential term.
Example:
using ModelingToolkitBase
using ModelingToolkitBase: t_nounits as t, D_nounits as D
@parameters p d
@variables X(t)
eq1 = D(X) ~ p - d*X
eq2 = 0 ~ p - d*X
is_diff_equation(eq1) # true
is_diff_equation(eq2) # falseString parsing
ModelingToolkit can parse system variables from strings.
ModelingToolkitBase.parse_variable — Function
parse_variable(
sys::ModelingToolkitBase.AbstractSystem,
str::AbstractString
) -> Any
Return the variable in sys referred to by its string representation str. Roughly supports the following CFG:
varname = "D(" varname ")" | "Differential(" iv ")(" varname ")" | arrvar | maybe_dummy_var
arrvar = maybe_dummy_var "[idxs...]"
idxs = int | int "," idxs
maybe_dummy_var = namespacedvar | namespacedvar "(" iv ")" |
namespacedvar "(" iv ")" "ˍ" ts | namespacedvar "ˍ" ts |
namespacedvar "ˍ" ts "(" iv ")"
ts = iv | iv ts
namespacedvar = ident "₊" namespacedvar | ident "." namespacedvar | identWhere iv is the independent variable, int is an integer and ident is an identifier.
Dumping system data
ModelingToolkitBase.dump_unknowns — Function
dump_unknowns(sys::AbstractSystem)Return an array of NamedTuples containing the metadata associated with each unknown in sys. Also includes the default value of the unknown, if provided.
using ModelingToolkitBase
using DynamicQuantities
using ModelingToolkitBase: t, D
@parameters p = 1.0, [description = "My parameter", tunable = false] q = 2.0, [description = "Other parameter"]
@variables x(t) = 3.0 [unit = u"m"]
@named sys = System(Equation[], t, [x], [p, q])
ModelingToolkitBase.dump_unknowns(sys)See also: ModelingToolkitBase.dump_variable_metadata, ModelingToolkitBase.dump_parameters
ModelingToolkitBase.dump_parameters — Function
dump_parameters(sys::AbstractSystem)Return an array of NamedTuples containing the metadata associated with each parameter in sys. Also includes the default value of the parameter, if provided.
using ModelingToolkitBase
using DynamicQuantities
using ModelingToolkitBase: t, D
@parameters p = 1.0, [description = "My parameter", tunable = false] q = 2.0, [description = "Other parameter"]
@variables x(t) = 3.0 [unit = u"m"]
@named sys = System(Equation[], t, [x], [p, q])
ModelingToolkitBase.dump_parameters(sys)See also: ModelingToolkitBase.dump_variable_metadata, ModelingToolkitBase.dump_unknowns
ModelingToolkitBase.dump_variable_metadata — Function
dump_variable_metadata(var)Return all the metadata associated with symbolic variable var as a NamedTuple.
using ModelingToolkitBase
@parameters p::Int [description = "My description", bounds = (0.5, 1.5)]
ModelingToolkitBase.dump_variable_metadata(p)Inputs and outputs
ModelingToolkitBase.has_inputs — Function
has_inputs(sys::ModelingToolkitBase.AbstractSystem) -> Bool
Returns whether the system sys has the internal field inputs.
See also get_inputs.
ModelingToolkitBase.get_inputs — Function
get_inputs(sys::ModelingToolkitBase.AbstractSystem) -> Any
Get the internal field inputs of a system sys. It only includes inputs local to sys; not those of its subsystems, like unknowns(sys), parameters(sys) and equations(sys) does.
See also has_inputs.
ModelingToolkitBase.inputs — Function
inputs(sys)Return all variables that mare marked as inputs. See also unbound_inputs See also bound_inputs, unbound_inputs
ModelingToolkitBase.has_outputs — Function
has_outputs(sys::ModelingToolkitBase.AbstractSystem) -> Bool
Returns whether the system sys has the internal field outputs.
See also get_outputs.
ModelingToolkitBase.get_outputs — Function
get_outputs(sys::ModelingToolkitBase.AbstractSystem) -> Any
Get the internal field outputs of a system sys. It only includes outputs local to sys; not those of its subsystems, like unknowns(sys), parameters(sys) and equations(sys) does.
See also has_outputs.
ModelingToolkitBase.outputs — Function
outputs(sys)Return all variables that mare marked as outputs. See also unbound_outputs See also bound_outputs, unbound_outputs
ModelingToolkitBase.bound_inputs — Function
bound_inputs(sys)Return inputs that are bound within the system, i.e., internal inputs See also bound_inputs, unbound_inputs, bound_outputs, unbound_outputs
ModelingToolkitBase.unbound_inputs — Function
unbound_inputs(sys)Return inputs that are not bound within the system, i.e., external inputs See also bound_inputs, unbound_inputs, bound_outputs, unbound_outputs
ModelingToolkitBase.bound_outputs — Function
bound_outputs(sys)Return outputs that are bound within the system, i.e., internal outputs See also bound_inputs, unbound_inputs, bound_outputs, unbound_outputs
ModelingToolkitBase.unbound_outputs — Function
unbound_outputs(sys)Return outputs that are not bound within the system, i.e., external outputs See also bound_inputs, unbound_inputs, bound_outputs, unbound_outputs
ModelingToolkitBase.is_bound — Function
is_bound(sys, u)Determine whether input/output variable u is "bound" within the system, i.e., if it's to be considered internal to sys. A variable/signal is considered bound if it appears in an equation together with variables from other subsystems. The typical usecase for this function is to determine whether the input to an IO component is connected to another component, or if it remains an external input that the user has to supply before simulating the system.
See also bound_inputs, unbound_inputs, bound_outputs, unbound_outputs
Debugging utilities
ModelingToolkitBase.debug_system — Function
debug_system(sys::AbstractSystem; functions = [log, sqrt, (^), /, inv, asin, acos], error_nonfinite = true)Wrap functions in sys so any error thrown in them shows helpful symbolic-numeric information about its input. If error_nonfinite, functions that output nonfinite values (like Inf or NaN) also display errors, even though the raw function itself does not throw an exception (like 1/0). For example:
julia> sys = debug_system(complete(sys))
julia> prob = ODEProblem(sys, [0.0, 2.0], (0.0, 1.0))
julia> prob.f(prob.u0, prob.p, 0.0)
ERROR: Function /(1, sin(P(t))) output non-finite value Inf with input
1 => 1
sin(P(t)) => 0.0Additionally, all assertions in the system are optionally logged when they fail. A new parameter is also added to the system which controls whether the message associated with each assertion will be logged when the assertion fails. This parameter defaults to true and can be toggled by symbolic indexing with ModelingToolkitBase.ASSERTION_LOG_VARIABLE. For example, prob.ps[ModelingToolkitBase.ASSERTION_LOG_VARIABLE] = false will disable logging.
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 &.
ModelingToolkitBase.CheckAll — Constant
const CheckAllValue that can be provided to the check keyword of System to enable all input validation.
ModelingToolkitBase.CheckNone — Constant
const CheckNoneValue that can be provided to the check keyword of System to disable checking of input.
ModelingToolkitBase.CheckComponents — Constant
const CheckComponentsValue 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.
ModelingToolkitBase.CheckUnits — Constant
const CheckUnitsValue that can be provided to the check keyword of System to enable checking of units.
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.
ModelingToolkitBase.collect_scoped_vars! — Function
collect_scoped_vars!(
unknowns::OrderedCollections.OrderedSet{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}},
parameters::OrderedCollections.OrderedSet{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}},
sys::ModelingToolkitBase.AbstractSystem,
iv::Union{Nothing, SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}};
...
)
collect_scoped_vars!(
unknowns::OrderedCollections.OrderedSet{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}},
parameters::OrderedCollections.OrderedSet{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}},
sys::ModelingToolkitBase.AbstractSystem,
iv::Union{Nothing, SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}},
::Type{op};
depth
)
Search through equations and parameter dependencies of sys, where sys is at a depth of depth from the root system, looking for variables scoped to the root system. Also recursively searches through all subsystems of sys, increasing the depth if it is not -1. A depth of -1 indicates searching for variables with GlobalScope.
ModelingToolkitBase.collect_var_to_name! — Function
collect_var_to_name!(vars::Dict{Symbol, SymbolicT}, xs::Vector{SymbolicT})Populate vars with mappings from symbolic variable names to variables.
Arguments
vars: dictionary updated in place.xs: symbolic variables to inspect.
Returns
nothing. Throws ArgumentError if two distinct variables have the same name.
ModelingToolkitBase.collect_vars! — Function
collect_vars!(
unknowns::OrderedCollections.OrderedSet{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}},
parameters::OrderedCollections.OrderedSet{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}},
expr::SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal},
iv::Union{Nothing, SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}};
...
)
collect_vars!(
unknowns::OrderedCollections.OrderedSet{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}},
parameters::OrderedCollections.OrderedSet{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}},
expr::SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal},
iv::Union{Nothing, SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}},
::Type{op};
depth
)
Search through expr for all symbolic variables present in it. Populate dvs with unknowns and ps with parameters present. iv should be the independent variable of the system or nothing for time-independent systems. Expressions where the operator isa op go through validate_operator.
depth is a keyword argument which indicates how many levels down expr is from the root of the system hierarchy. This is used to resolve scoping operators. The scope of a variable can be checked using check_scope_depth.
This function should return nothing.
ModelingToolkitBase.eqtype_supports_collect_vars — Function
eqtype_supports_collect_vars(eq) -> Bool
Indicate whether the given equation type (Equation, Pair, etc) supports collect_vars!. Can be dispatched by higher-level libraries to indicate support.
ModelingToolkitBase.modified_unknowns! — Function
modified_unknowns!(
munknowns,
jump::Union{JumpProcesses.ConstantRateJump, JumpProcesses.VariableRateJump},
sts
) -> Any
Push to munknowns the variables modified by jump jump. sts is the list of unknowns of the system. Return the modified munknowns.
ModelingToolkitBase.convert_bindings_for_time_independent_system — Function
convert_bindings_for_time_independent_system(
sys::ModelingToolkitBase.AbstractSystem
) -> Tuple{Any, Any}
Given a time-dependent AbstractSystem, move bindings of variables to initial conditions as required to convert sys to a time-independent system. Does not modify sys, and returns the new initial conditions and bindings respectively.
Namespace 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.
ModelingToolkitBase.renamespace — Function
renamespace(
sys,
x::SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}
) -> Any
Namespace x with the name of sys.
renamespace(sys, ap::AnalysisPoint) -> Any
Namespace an AnalysisPoint by namespacing the involved systems and the name of the point.
ModelingToolkitBase.namespace_equations — Function
namespace_equations(sys::AbstractSystem)Return equations(sys), namespaced by the name of sys.
ModelingToolkitBase.@nonamespace — Macro
Rewrite @nonamespace a.b.c to getvar(getvar(a, :b; namespace = false), :c; namespace = false).
This is the default behavior of getvar. This should be used when inheriting unknowns from a model.
ModelingToolkitBase.@namespace — Macro
Rewrite @namespace a.b.c to getvar(getvar(a, :b; namespace = true), :c; namespace = true).
Linearization and Analysis
Functions for linearization and analysis of systems.
ModelingToolkitBase.AnalysisPoint — Type
struct AnalysisPointAnalysisPoint(input, name::Symbol, outputs::Vector)Create an AnalysisPoint for linear analysis. Analysis points can be created by calling
connect(out, :ap_name, in...)Where out is the output being connected to the inputs in.... All involved connectors (input and outputs) are required to either have an unknown named u or a single unknown, all of which should have the same size.
See also get_sensitivity, get_comp_sensitivity, get_looptransfer, and open_loop.
Fields
input::Any: The input to the connection. In the context of ModelingToolkitStandardLibrary.jl, this is aRealOutputconnector.
name::Symbol: The name of the analysis point.
outputs::Union{Nothing, Vector{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}, Vector{System}}: The outputs of the connection. In the context of ModelingToolkitStandardLibrary.jl, these are allRealInputconnectors.
Example
using ModelingToolkitBase
using ModelingToolkitStandardLibrary.Blocks
using ModelingToolkitBase: t_nounits as t
@named P = FirstOrder(k = 1, T = 1)
@named C = Gain(; k = -1)
t = ModelingToolkitBase.get_iv(P)
eqs = [connect(P.output, C.input)
connect(C.output, :plant_input, P.input)]
sys = System(eqs, t, systems = [P, C], name = :feedback_system)
matrices_S, _ = get_sensitivity(sys, :plant_input) # Compute the matrices of a state-space representation of the (input) sensitivity function.
matrices_T, _ = get_comp_sensitivity(sys, :plant_input)Continued linear analysis and design can be performed using ControlSystemsBase.jl. Create ControlSystemsBase.StateSpace objects using
using ControlSystemsBase, Plots
S = ss(matrices_S...)
T = ss(matrices_T...)
bodeplot([S, T], lab = ["S" "T"])The sensitivity functions obtained this way should be equivalent to the ones obtained with the code below
using ControlSystemsBase
P = tf(1.0, [1, 1])
C = 1 # Negative feedback assumed in ControlSystems
S = sensitivity(P, C) # or feedback(1, P*C)
T = comp_sensitivity(P, C) # or feedback(P*C)ModelingToolkit.linearization_ap_transform — Function
sys, input_vars, output_vars =linearization_ap_transform(
sys,
inputs::Union{Vector{Symbol}, Vector{AnalysisPoint}, Symbol, AnalysisPoint},
outputs,
loop_openings
) -> Tuple{Any, Vector{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}, Vector{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}, Vector{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}}
Apply analysis-point transformations to prepare a system for linearization.
Returns
sys: The transformed system.input_vars: A vector of input variables corresponding to the input analysis points.output_vars: A vector of output variables corresponding to the output analysis points.loop_opening_params: A vector of the variables that were turned into parameters by theloop_openings(their operating-point values must be supplied when linearizing).
ModelingToolkit.get_sensitivity_function — Function
get_sensitivity_function(
sys::ModelingToolkitBase.AbstractSystem,
aps;
kwargs...
) -> Tuple{ModelingToolkit.LinearizationFunction{_A, P, H, _B, J1, J2, J3, J4, IA, @NamedTuple{abstol::Float64, reltol::Float64, nlsolve_alg::Nothing}} where {_A, P<:ODEProblem, H<:FunctionWrappersWrappers.FunctionWrappersWrapper, _B, J1<:Union{Nothing, ModelingToolkit.PreparedJacobian{true, DifferentiationInterfaceForwardDiffExt.ForwardDiffTwoArgJacobianPrep{Nothing, C, Tuple{Nothing, Nothing}}, ModelingToolkit.UFFun{F}, _A, ADTypes.AutoForwardDiff{nothing, Nothing}} where {C<:(ForwardDiff.JacobianConfig{T, _A, _B, <:Tuple{Any, Any}} where {T<:(ForwardDiff.Tag{F} where F<:ModelingToolkit.UFFun), _A, _B}), F, _A}}, J2<:Union{Nothing, ModelingToolkit.PreparedJacobian{true, DifferentiationInterfaceForwardDiffExt.ForwardDiffTwoArgJacobianPrep{Nothing, C, Tuple{Nothing, Nothing}}, FunctionWrappersWrappers.FunctionWrappersWrapper{FW, P, CS}, _A, ADTypes.AutoForwardDiff{nothing, Nothing}} where {C<:(ForwardDiff.JacobianConfig{T, _A, _B, <:Tuple{Any, Any}} where {T<:(ForwardDiff.Tag{F} where F<:FunctionWrappersWrappers.FunctionWrappersWrapper), _A, _B}), FW, P, CS, _A}}, J3<:Union{Nothing, ModelingToolkit.PreparedJacobian{true, DifferentiationInterfaceForwardDiffExt.ForwardDiffTwoArgJacobianPrep{Nothing, C, Tuple{Nothing, Nothing, Nothing}}, ModelingToolkit.PFFun{_A, S}, _A1, ADTypes.AutoForwardDiff{nothing, Nothing}} where {C<:(ForwardDiff.JacobianConfig{T, _A, _B, <:Tuple{Any, Vector{T} where T<:(ForwardDiff.Dual{T, _A, _B} where {_B, _A, T})}} where {T<:(ForwardDiff.Tag{F} where F<:(ModelingToolkit.PFFun{_A, S} where {_A, S<:(SymbolicIndexingInterface.OOPSetter{_A, System} where _A)})), _A, _B}), _A, S<:(SymbolicIndexingInterface.OOPSetter{_A, System} where _A), _A1}}, J4<:(ModelingToolkit.PreparedJacobian{true, DifferentiationInterfaceForwardDiffExt.ForwardDiffTwoArgJacobianPrep{Nothing, C, Tuple{Nothing, Nothing, Nothing}}, ModelingToolkit.HPFun{F, S}, _A, ADTypes.AutoForwardDiff{nothing, Nothing}} where {C<:(ForwardDiff.JacobianConfig{T, _A, _B, <:Tuple{Any, Vector{T} where T<:(ForwardDiff.Dual{T, _A, _B} where {_B, _A, T<:(ForwardDiff.Tag{F} where F<:(ModelingToolkit.HPFun{F, S} where {F<:FunctionWrappersWrappers.FunctionWrappersWrapper, S<:(SymbolicIndexingInterface.OOPSetter{_A, System} where _A)}))})}} where {T<:(ForwardDiff.Tag{F} where F<:(ModelingToolkit.HPFun{F, S} where {F<:FunctionWrappersWrappers.FunctionWrappersWrapper, S<:(SymbolicIndexingInterface.OOPSetter{_A, System} where _A)})), _A, _B}), F<:FunctionWrappersWrappers.FunctionWrappersWrapper, S<:(SymbolicIndexingInterface.OOPSetter{_A, System} where _A), _A}), IA<:Union{SciMLBase.NoInit, SciMLBase.OverrideInit{Nothing, Nothing, Nothing}}}, System}
Return the sensitivity function for the analysis point(s) aps, and the modified system simplified with the appropriate inputs and outputs.
Keyword Arguments
loop_openings: A list of analysis points whose connections should be removed and the outputs set to the input as a part of the linear analysis.system_modifier: A function taking the transformed system and applying any additional transformations, returning the modified system. The modified system is passed tolinearization_function.
All other keyword arguments are forwarded to linearization_function.
ModelingToolkit.get_comp_sensitivity_function — Function
get_comp_sensitivity_function(
sys::ModelingToolkitBase.AbstractSystem,
aps;
kwargs...
) -> Tuple{ModelingToolkit.LinearizationFunction{_A, P, H, _B, J1, J2, J3, J4, IA, @NamedTuple{abstol::Float64, reltol::Float64, nlsolve_alg::Nothing}} where {_A, P<:ODEProblem, H<:FunctionWrappersWrappers.FunctionWrappersWrapper, _B, J1<:Union{Nothing, ModelingToolkit.PreparedJacobian{true, DifferentiationInterfaceForwardDiffExt.ForwardDiffTwoArgJacobianPrep{Nothing, C, Tuple{Nothing, Nothing}}, ModelingToolkit.UFFun{F}, _A, ADTypes.AutoForwardDiff{nothing, Nothing}} where {C<:(ForwardDiff.JacobianConfig{T, _A, _B, <:Tuple{Any, Any}} where {T<:(ForwardDiff.Tag{F} where F<:ModelingToolkit.UFFun), _A, _B}), F, _A}}, J2<:Union{Nothing, ModelingToolkit.PreparedJacobian{true, DifferentiationInterfaceForwardDiffExt.ForwardDiffTwoArgJacobianPrep{Nothing, C, Tuple{Nothing, Nothing}}, FunctionWrappersWrappers.FunctionWrappersWrapper{FW, P, CS}, _A, ADTypes.AutoForwardDiff{nothing, Nothing}} where {C<:(ForwardDiff.JacobianConfig{T, _A, _B, <:Tuple{Any, Any}} where {T<:(ForwardDiff.Tag{F} where F<:FunctionWrappersWrappers.FunctionWrappersWrapper), _A, _B}), FW, P, CS, _A}}, J3<:Union{Nothing, ModelingToolkit.PreparedJacobian{true, DifferentiationInterfaceForwardDiffExt.ForwardDiffTwoArgJacobianPrep{Nothing, C, Tuple{Nothing, Nothing, Nothing}}, ModelingToolkit.PFFun{_A, S}, _A1, ADTypes.AutoForwardDiff{nothing, Nothing}} where {C<:(ForwardDiff.JacobianConfig{T, _A, _B, <:Tuple{Any, Vector{T} where T<:(ForwardDiff.Dual{T, _A, _B} where {_B, _A, T})}} where {T<:(ForwardDiff.Tag{F} where F<:(ModelingToolkit.PFFun{_A, S} where {_A, S<:(SymbolicIndexingInterface.OOPSetter{_A, System} where _A)})), _A, _B}), _A, S<:(SymbolicIndexingInterface.OOPSetter{_A, System} where _A), _A1}}, J4<:(ModelingToolkit.PreparedJacobian{true, DifferentiationInterfaceForwardDiffExt.ForwardDiffTwoArgJacobianPrep{Nothing, C, Tuple{Nothing, Nothing, Nothing}}, ModelingToolkit.HPFun{F, S}, _A, ADTypes.AutoForwardDiff{nothing, Nothing}} where {C<:(ForwardDiff.JacobianConfig{T, _A, _B, <:Tuple{Any, Vector{T} where T<:(ForwardDiff.Dual{T, _A, _B} where {_B, _A, T<:(ForwardDiff.Tag{F} where F<:(ModelingToolkit.HPFun{F, S} where {F<:FunctionWrappersWrappers.FunctionWrappersWrapper, S<:(SymbolicIndexingInterface.OOPSetter{_A, System} where _A)}))})}} where {T<:(ForwardDiff.Tag{F} where F<:(ModelingToolkit.HPFun{F, S} where {F<:FunctionWrappersWrappers.FunctionWrappersWrapper, S<:(SymbolicIndexingInterface.OOPSetter{_A, System} where _A)})), _A, _B}), F<:FunctionWrappersWrappers.FunctionWrappersWrapper, S<:(SymbolicIndexingInterface.OOPSetter{_A, System} where _A), _A}), IA<:Union{SciMLBase.NoInit, SciMLBase.OverrideInit{Nothing, Nothing, Nothing}}}, System}
Return the complementary sensitivity function for the analysis point(s) aps, and the modified system simplified with the appropriate inputs and outputs.
Keyword Arguments
loop_openings: A list of analysis points whose connections should be removed and the outputs set to the input as a part of the linear analysis.system_modifier: A function taking the transformed system and applying any additional transformations, returning the modified system. The modified system is passed tolinearization_function.
All other keyword arguments are forwarded to linearization_function.
ModelingToolkit.get_looptransfer_function — Function
get_looptransfer_function(
sys::ModelingToolkitBase.AbstractSystem,
aps;
kwargs...
) -> Tuple{ModelingToolkit.LinearizationFunction{_A, P, H, _B, J1, J2, J3, J4, IA, @NamedTuple{abstol::Float64, reltol::Float64, nlsolve_alg::Nothing}} where {_A, P<:ODEProblem, H<:FunctionWrappersWrappers.FunctionWrappersWrapper, _B, J1<:Union{Nothing, ModelingToolkit.PreparedJacobian{true, DifferentiationInterfaceForwardDiffExt.ForwardDiffTwoArgJacobianPrep{Nothing, C, Tuple{Nothing, Nothing}}, ModelingToolkit.UFFun{F}, _A, ADTypes.AutoForwardDiff{nothing, Nothing}} where {C<:(ForwardDiff.JacobianConfig{T, _A, _B, <:Tuple{Any, Any}} where {T<:(ForwardDiff.Tag{F} where F<:ModelingToolkit.UFFun), _A, _B}), F, _A}}, J2<:Union{Nothing, ModelingToolkit.PreparedJacobian{true, DifferentiationInterfaceForwardDiffExt.ForwardDiffTwoArgJacobianPrep{Nothing, C, Tuple{Nothing, Nothing}}, FunctionWrappersWrappers.FunctionWrappersWrapper{FW, P, CS}, _A, ADTypes.AutoForwardDiff{nothing, Nothing}} where {C<:(ForwardDiff.JacobianConfig{T, _A, _B, <:Tuple{Any, Any}} where {T<:(ForwardDiff.Tag{F} where F<:FunctionWrappersWrappers.FunctionWrappersWrapper), _A, _B}), FW, P, CS, _A}}, J3<:Union{Nothing, ModelingToolkit.PreparedJacobian{true, DifferentiationInterfaceForwardDiffExt.ForwardDiffTwoArgJacobianPrep{Nothing, C, Tuple{Nothing, Nothing, Nothing}}, ModelingToolkit.PFFun{_A, S}, _A1, ADTypes.AutoForwardDiff{nothing, Nothing}} where {C<:(ForwardDiff.JacobianConfig{T, _A, _B, <:Tuple{Any, Vector{T} where T<:(ForwardDiff.Dual{T, _A, _B} where {_B, _A, T})}} where {T<:(ForwardDiff.Tag{F} where F<:(ModelingToolkit.PFFun{_A, S} where {_A, S<:(SymbolicIndexingInterface.OOPSetter{_A, System} where _A)})), _A, _B}), _A, S<:(SymbolicIndexingInterface.OOPSetter{_A, System} where _A), _A1}}, J4<:(ModelingToolkit.PreparedJacobian{true, DifferentiationInterfaceForwardDiffExt.ForwardDiffTwoArgJacobianPrep{Nothing, C, Tuple{Nothing, Nothing, Nothing}}, ModelingToolkit.HPFun{F, S}, _A, ADTypes.AutoForwardDiff{nothing, Nothing}} where {C<:(ForwardDiff.JacobianConfig{T, _A, _B, <:Tuple{Any, Vector{T} where T<:(ForwardDiff.Dual{T, _A, _B} where {_B, _A, T<:(ForwardDiff.Tag{F} where F<:(ModelingToolkit.HPFun{F, S} where {F<:FunctionWrappersWrappers.FunctionWrappersWrapper, S<:(SymbolicIndexingInterface.OOPSetter{_A, System} where _A)}))})}} where {T<:(ForwardDiff.Tag{F} where F<:(ModelingToolkit.HPFun{F, S} where {F<:FunctionWrappersWrappers.FunctionWrappersWrapper, S<:(SymbolicIndexingInterface.OOPSetter{_A, System} where _A)})), _A, _B}), F<:FunctionWrappersWrappers.FunctionWrappersWrapper, S<:(SymbolicIndexingInterface.OOPSetter{_A, System} where _A), _A}), IA<:Union{SciMLBase.NoInit, SciMLBase.OverrideInit{Nothing, Nothing, Nothing}}}, System}
Return the loop-transfer function for the analysis point(s) aps, and the modified system simplified with the appropriate inputs and outputs.
Keyword Arguments
loop_openings: A list of analysis points whose connections should be removed and the outputs set to the input as a part of the linear analysis.system_modifier: A function taking the transformed system and applying any additional transformations, returning the modified system. The modified system is passed tolinearization_function.
All other keyword arguments are forwarded to linearization_function.
ModelingToolkit.get_sensitivity — Function
get_sensitivity(sys, ap; loop_openings = [], system_modifier = identity, op = Dict(), kwargs...)Compute the sensitivity transfer matrices at analysis point ap and return (matrices, simplified_system, extras). This introduces an infinitesimal perturbation at the input of ap, linearizes the system, and computes the transfer function from the perturbation to the output of ap.
Arguments
sys: system containing the analysis point.ap: anAnalysisPointor its symbolic name.
Keyword Arguments
loop_openings: connections to open before linearization.system_modifier: transformation applied before linearization.op: operating-point values passed tolinearize.allow_input_derivatives: allow derivatives of input variables in the linearization.t: time at which to evaluate the linearization.kwargs...: forwarded toget_sensitivity_function.
See also get_comp_sensitivity and get_looptransfer.
ModelingToolkit.get_comp_sensitivity — Function
get_comp_sensitivity(sys, ap; loop_openings = [], system_modifier = identity, op = Dict(), kwargs...)Compute the complementary-sensitivity transfer matrices at analysis point ap and return (matrices, simplified_system, extras). This introduces an infinitesimal perturbation at the output of ap, linearizes the system, and computes the transfer function from the perturbation to the input of ap.
Keyword arguments match get_sensitivity, with kwargs... forwarded to get_comp_sensitivity_function.
See also get_sensitivity and get_looptransfer.
ModelingToolkit.get_looptransfer — Function
get_looptransfer(sys, ap; loop_openings = [], system_modifier = identity, op = Dict(), kwargs...)Compute the loop-transfer matrices at analysis point ap and return (matrices, simplified_system, extras). The transfer is from ap.out to ap.in.
Keyword arguments match get_sensitivity, with kwargs... forwarded to get_looptransfer_function.
The computed loop transfer includes negative feedback. Negate the result when using an analysis tool that expects a loop-transfer function without the negative gain.
See also get_sensitivity, get_comp_sensitivity, and open_loop.
ModelingToolkitBase.open_loop — Function
open_loop(
sys,
ap::Union{Symbol, AnalysisPoint};
system_modifier
) -> Tuple{Any, Tuple{Any, Any}}
Apply LoopTransferTransform to the analysis point ap and return the result of apply_transformation.
Keyword Arguments
system_modifier: a function which takes the modified system and returns a new system with any required further modifications performed.
ModelingToolkit.isolate_subsystem — Function
sys, input_vars, output_vars = isolate_subsystem(sys, input_aps, output_aps)Isolate the part of the unsimplified, hierarchical system sys bounded by the input analysis points input_aps and the output analysis points output_aps. The returned sys contains only the subsystems between the boundary analysis points at every level of the hierarchy; all upstream and downstream components, and all equations involving them, are removed.
Boundary analysis points may reside at any level of the hierarchy and in different branches of the subsystem tree.
Returns:
sys: The system with only the isolated subsystems and their internal connections.input_vars: Variables at the inside face of each input analysis point.output_vars: Variables at the inside face of each output analysis point.
isolate_subsystem extracts the plant from an unsimplified feedback system using analysis points as boundaries.
using ModelingToolkit
using ModelingToolkitStandardLibrary.Blocks
using ModelingToolkit: t_nounits as t
@named plant = FirstOrder(k = 1, T = 1)
@named controller = Gain(k = -1)
eqs = [
connect(controller.output, :plant_input, plant.input)
connect(plant.output, :plant_output, controller.input)
]
@named closed_loop = System(eqs, t, systems = [plant, controller])
isolated, input_vars, output_vars =
isolate_subsystem(closed_loop, :plant_input, :plant_output)
isequal(only(input_vars), plant.input.u), isequal(only(output_vars), plant.output.u)(true, true)