diff --git a/src/systems/unit_check.jl b/src/systems/unit_check.jl index acf7451065..1a6e00c33f 100644 --- a/src/systems/unit_check.jl +++ b/src/systems/unit_check.jl @@ -213,6 +213,17 @@ function _validate(terms::Vector, labels::Vector{String}; info::String = "") valid end +function _validate(ap::AnalysisPoint; info::String = "") + is_valid = false + if (ap.outputs == nothing) + is_valid = true + else + conn_eq = connect(ap.input, ap.outputs...) + is_valid = _validate(conn_eq.rhs, info=info) + end + return is_valid +end + function _validate(conn::Connection; info::String = "") valid = true syss = get_systems(conn) @@ -277,7 +288,7 @@ function validate(jumps::Vector{JumpType}, t::Symbolic) end function validate(eq::Union{Inequality, Equation}; info::String = "") - if typeof(eq.lhs) == Connection + if typeof(eq.lhs) <: Union{Connection, AnalysisPoint} _validate(eq.rhs; info) else _validate([eq.lhs, eq.rhs], ["left", "right"]; info) diff --git a/src/systems/validation.jl b/src/systems/validation.jl index d416a02ea2..6372be1100 100644 --- a/src/systems/validation.jl +++ b/src/systems/validation.jl @@ -2,7 +2,7 @@ module UnitfulUnitCheck using ..ModelingToolkit, Symbolics, SciMLBase, Unitful, RecursiveArrayTools using ..ModelingToolkit: ValidationError, - ModelingToolkit, Connection, instream, JumpType, VariableUnit, + ModelingToolkit, Connection, instream, JumpType, VariableUnit, AnalysisPoint, get_systems, Conditional, Comparison using JumpProcesses: MassActionJump, ConstantRateJump, VariableRateJump @@ -182,6 +182,17 @@ function _validate(terms::Vector, labels::Vector{String}; info::String = "") valid end +function _validate(ap::AnalysisPoint; info::String = "") + is_valid = false + if (ap.outputs == nothing) + is_valid = true + else + conn_eq = connect(ap.input, ap.outputs...) + is_valid = _validate(conn_eq.rhs, info=info) + end + return is_valid +end + function _validate(conn::Connection; info::String = "") valid = true syss = get_systems(conn) @@ -242,7 +253,7 @@ function validate(jumps::Vector{JumpType}, t::Symbolic) end function validate(eq::MT.Equation; info::String = "") - if typeof(eq.lhs) == Connection + if typeof(eq.lhs) <: Union{AnalysisPoint, Connection} _validate(eq.rhs; info) else _validate([eq.lhs, eq.rhs], ["left", "right"]; info) diff --git a/test/analysis_points.jl b/test/analysis_points.jl index f718e7bc59..3d0387bfd7 100644 --- a/test/analysis_points.jl +++ b/test/analysis_points.jl @@ -7,6 +7,88 @@ using ModelingToolkit: t_nounits as t, D_nounits as D, AnalysisPoint, AbstractSy import ModelingToolkit as MTK import ControlSystemsBase as CS using Symbolics: NAMESPACE_SEPARATOR +using Unitful + +@testset "AnalysisPoint is ignored when verifying units" begin + # no units first + @mtkmodel FirstOrderTest begin + @components begin + in = Blocks.Step() + fb = Blocks.Feedback() + fo = Blocks.SecondOrder(k = 1, w = 1, d = 0.1) + end + @equations begin + connect(in.output, :u, fb.input1) + connect(fb.output, :e, fo.input) + connect(fo.output, :y, fb.input2) + end + end + @named model = FirstOrderTest() + @test model isa System + + @connector function UnitfulOutput(; name) + vars = @variables begin + u(t), [unit=u"m", output=true] + end + return System(Equation[], t, vars, []; name) + end + @connector function UnitfulInput(; name) + vars = @variables begin + u(t), [unit=u"m", input=true] + end + return System(Equation[], t, vars, []; name) + end + @component function UnitfulBlock(; name) + pars = @parameters begin + offset, [unit=u"m"] + start_time + height, [unit=u"m"] + duration + end + systems = @named begin + output = UnitfulOutput() + end + eqs = [ + output.u ~ offset + height*(0.5 + (1/pi)*atan(1e5*(t - start_time))) + ] + return System(eqs, t, [], pars; systems, name) + end + @mtkmodel TestAPAroundUnits begin + @components begin + input = UnitfulInput() + end + @variables begin + output(t), [output=true, unit=u"m^2"] + end + @components begin + ub = UnitfulBlock() + end + @equations begin + connect(ub.output, :ap, input) + output ~ input.u^2 + end + end + @named sys = TestAPAroundUnits() + @test sys isa System + + @mtkmodel TestAPWithNoOutputs begin + @components begin + input = UnitfulInput() + end + @variables begin + output(t), [output=true, unit=u"m^2"] + end + @components begin + ub = UnitfulBlock() + end + @equations begin + connect(ub.output, :ap, input) + output ~ input.u^2 + end + end + @named sys2 = TestAPWithNoOutputs() + @test sys2 isa System +end @testset "AnalysisPoint is lowered to `connect`" begin @named P = FirstOrder(k = 1, T = 1)