Skip to content

Commit 80b2549

Browse files
committed
add getters for noise, unit, connect, misc
1 parent 143d5c3 commit 80b2549

File tree

3 files changed

+128
-13
lines changed

3 files changed

+128
-13
lines changed

src/ModelingToolkit.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,9 @@ export initial_state, transition, activeState, entry, ticksInState, timeInState
246246
export @component, @mtkmodel, @mtkbuild
247247
export isinput, isoutput, getbounds, hasbounds, getguess, hasguess, isdisturbance,
248248
istunable, getdist, hasdist,
249-
tunable_parameters, isirreducible, getdescription, hasdescription
249+
tunable_parameters, isirreducible, getdescription, hasdescription,
250+
hasnoise, getnoise, hasunit, getunit, hasconnect, getconnect,
251+
hasmisc, getmisc
250252
export ode_order_lowering, dae_order_lowering, liouville_transform
251253
export PDESystem
252254
export Differential, expand_derivatives, @derivatives

src/variables.jl

Lines changed: 81 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ ModelingToolkit.dump_variable_metadata(p)
2929
"""
3030
function dump_variable_metadata(var)
3131
uvar = unwrap(var)
32-
vartype, name = get(uvar.metadata, VariableSource, (:unknown, :unknown))
32+
vartype, name = Symbolics.getmetadata(uvar, VariableSource, (:unknown, :unknown))
3333
type = symtype(uvar)
3434
if type <: AbstractArray
3535
shape = Symbolics.shape(var)
@@ -39,14 +39,14 @@ function dump_variable_metadata(var)
3939
else
4040
shape = nothing
4141
end
42-
unit = get(uvar.metadata, VariableUnit, nothing)
43-
connect = get(uvar.metadata, VariableConnectType, nothing)
44-
noise = get(uvar.metadata, VariableNoiseType, nothing)
42+
unit = getunit(uvar)
43+
connect = getconnect(uvar)
44+
noise = getnoise(uvar)
4545
input = isinput(uvar) || nothing
4646
output = isoutput(uvar) || nothing
47-
irreducible = get(uvar.metadata, VariableIrreducible, nothing)
48-
state_priority = get(uvar.metadata, VariableStatePriority, nothing)
49-
misc = get(uvar.metadata, VariableMisc, nothing)
47+
irreducible = isirreducible(var)
48+
state_priority = Symbolics.getmetadata(uvar, VariableStatePriority, nothing)
49+
misc = getmisc(uvar)
5050
bounds = hasbounds(uvar) ? getbounds(uvar) : nothing
5151
desc = getdescription(var)
5252
if desc == ""
@@ -57,12 +57,13 @@ function dump_variable_metadata(var)
5757
disturbance = isdisturbance(uvar) || nothing
5858
tunable = istunable(uvar, isparameter(uvar))
5959
dist = getdist(uvar)
60-
type = symtype(uvar)
60+
variable_type = getvariabletype(uvar)
6161

6262
meta = (
6363
var = var,
6464
vartype,
6565
name,
66+
variable_type,
6667
shape,
6768
unit,
6869
connect,
@@ -85,11 +86,28 @@ function dump_variable_metadata(var)
8586
return NamedTuple(k => v for (k, v) in pairs(meta) if v !== nothing)
8687
end
8788

89+
### Connect
8890
abstract type AbstractConnectType end
8991
struct Equality <: AbstractConnectType end # Equality connection
9092
struct Flow <: AbstractConnectType end # sum to 0
9193
struct Stream <: AbstractConnectType end # special stream connector
9294

95+
"""
96+
getconnect(x)
97+
98+
Get the connect type of x. See also [`hasconnect`](@ref).
99+
"""
100+
getconnect(x) = getconnect(unwrap(x))
101+
getconnect(x::Symbolic) = Symbolics.getmetadata(x, VariableConnectType, nothing)
102+
"""
103+
hasconnect(x)
104+
105+
Determine whether variable `x` has a connect type. See also [`getconnect`](@ref).
106+
"""
107+
hasconnect(x) = getconnect(x) !== nothing
108+
setconnect(x, t::Type{T}) where T <: AbstractConnectType = setmetadata(x, VariableConnectType, t)
109+
110+
### Input, Output, Irreducible
93111
isvarkind(m, x::Union{Num, Symbolics.Arr}) = isvarkind(m, value(x))
94112
function isvarkind(m, x)
95113
iskind = getmetadata(x, m, nothing)
@@ -98,15 +116,17 @@ function isvarkind(m, x)
98116
getmetadata(x, m, false)
99117
end
100118

101-
setinput(x, v) = setmetadata(x, VariableInput, v)
102-
setoutput(x, v) = setmetadata(x, VariableOutput, v)
103-
setio(x, i, o) = setoutput(setinput(x, i), o)
119+
setinput(x, v::Bool) = setmetadata(x, VariableInput, v)
120+
setoutput(x, v::Bool) = setmetadata(x, VariableOutput, v)
121+
setio(x, i::Bool, o::Bool) = setoutput(setinput(x, i), o)
122+
104123
isinput(x) = isvarkind(VariableInput, x)
105124
isoutput(x) = isvarkind(VariableOutput, x)
125+
106126
# Before the solvability check, we already have handled IO variables, so
107127
# irreducibility is independent from IO.
108128
isirreducible(x) = isvarkind(VariableIrreducible, x)
109-
setirreducible(x, v) = setmetadata(x, VariableIrreducible, v)
129+
setirreducible(x, v::Bool) = setmetadata(x, VariableIrreducible, v)
110130
state_priority(x) = convert(Float64, getmetadata(x, VariableStatePriority, 0.0))::Float64
111131

112132
function default_toterm(x)
@@ -545,3 +565,52 @@ function get_default_or_guess(x)
545565
return getguess(x)
546566
end
547567
end
568+
569+
## Miscellaneous metadata ======================================================================
570+
"""
571+
getmisc(x)
572+
573+
Fetch any miscellaneous data associated with symbolic variable `x`.
574+
See also [`hasmisc(x)`](@ref).
575+
"""
576+
getmisc(x) = getmisc(unwrap(x))
577+
getmisc(x::Symbolic) = Symbolics.getmetadata(x, VariableMisc, nothing)
578+
"""
579+
hasmisc(x)
580+
581+
Determine whether a symbolic variable `x` has misc
582+
metadata associated with it.
583+
584+
See also [`getmisc(x)`](@ref).
585+
"""
586+
hasmisc(x) = getmisc(x) !== nothing
587+
setmisc(x, miscdata) = setmetadata(x, VariableMisc, miscdata)
588+
589+
## Units ======================================================================
590+
"""
591+
getunit(x)
592+
593+
Alias for [`get_unit(x)`](@ref).
594+
"""
595+
getunit(x) = get_unit(x)
596+
"""
597+
hasunit(x)
598+
599+
Check if the variable `x` has a unit.
600+
"""
601+
hasunit(x) = getunit(x) !== nothing
602+
603+
## Noise ======================================================================
604+
"""
605+
getnoise(x)
606+
607+
Get the noise type of variable `x`.
608+
"""
609+
getnoise(x) = getnoise(unwrap(x))
610+
getnoise(x::Symbolic) = Symbolics.getmetadata(x, VariableNoiseType, nothing)
611+
"""
612+
hasnoise(x)
613+
614+
Determine if variable `x` has a noise type.
615+
"""
616+
hasnoise(x) = getnoise(x) !== nothing

test/test_variable_metadata.jl

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using ModelingToolkit
2+
using DynamicQuantities
23

34
# Bounds
45
@variables u [bounds = (-1, 1)]
@@ -185,3 +186,46 @@ params_meta = ModelingToolkit.dump_parameters(sys)
185186
params_meta = Dict([ModelingToolkit.getname(meta.var) => meta for meta in params_meta])
186187
@test params_meta[:p].default == 3.0
187188
@test isequal(params_meta[:q].dependency, 2p)
189+
190+
# Noise
191+
@variables x [noise = 1]
192+
@test hasnoise(x)
193+
@test getnoise(x) == 1
194+
@test ModelingToolkit.dump_variable_metadata(x).noise == 1
195+
196+
# Connect
197+
@variables x [connect = Flow]
198+
@test hasconnect(x)
199+
@test getconnect(x) == Flow
200+
@test ModelingToolkit.dump_variable_metadata(x).connect == Flow
201+
x = ModelingToolkit.setconnect(x, ModelingToolkit.Stream)
202+
@test getconnect(x) == ModelingToolkit.Stream
203+
204+
struct BadConnect end
205+
@test_throws Exception ModelingToolkit.setconnect(x, BadConnect)
206+
207+
# Unit
208+
@variables x [unit = u"s"]
209+
@test hasunit(x)
210+
@test getunit(x) == u"s"
211+
@test ModelingToolkit.dump_variable_metadata(x).unit == u"s"
212+
213+
# Misc data
214+
@variables x [misc = [:good]]
215+
@test hasmisc(x)
216+
@test getmisc(x) == [:good]
217+
x = ModelingToolkit.setmisc(x, "okay")
218+
@test getmisc(x) == "okay"
219+
220+
# Variable Type
221+
@variables x
222+
@test ModelingToolkit.getvariabletype(x) == ModelingToolkit.VARIABLE
223+
@test ModelingToolkit.dump_variable_metadata(x).variable_type == ModelingToolkit.VARIABLE
224+
x = ModelingToolkit.toparam(x)
225+
@test ModelingToolkit.getvariabletype(x) == ModelingToolkit.PARAMETER
226+
227+
@parameters y
228+
@test ModelingToolkit.getvariabletype(y) == ModelingToolkit.PARAMETER
229+
230+
@brownian z
231+
@test ModelingToolkit.getvariabletype(z) == ModelingToolkit.BROWNIAN

0 commit comments

Comments
 (0)