LIBRARY
Math.Tests.Max
Computes the maximum of constant and time-varying inputs.
Connects constant sources with values 3 and 7 to a Max block and verifies that max(3, 7) = 7. A second Max block is driven by two sine waves of different frequencies so the selected (larger) input alternates over time.
Usage
BlockComponents.Math.Tests.Max()
Behavior
julia
using BlockComponents #hide
using ModelingToolkit #hide
@named sys = BlockComponents.Math.Tests.Max() #hide
let eqs = full_equations(sys); Base.length(eqs) > 25 ? nothing : eqs end #hide<< @example-block not executed in draft mode >>Source
dyad
"""
Computes the maximum of constant and time-varying inputs.
Connects constant sources with values 3 and 7 to a Max block and verifies
that max(3, 7) = 7. A second Max block is driven by two sine waves of
different frequencies so the selected (larger) input alternates over time.
"""
test component Max
"Constant source providing the first input"
c1 = BlockComponents.Sources.Constant(k = 3) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 20, "y1": 20, "x2": 120, "y2": 120, "rot": 0}
},
"tags": []
}
}
"Constant source providing the second input"
c2 = BlockComponents.Sources.Constant(k = 7) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 20, "y1": 140, "x2": 120, "y2": 240, "rot": 0}
},
"tags": []
}
}
"Max block under test"
max_block = BlockComponents.Math.Max() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 160, "y1": 50, "x2": 260, "y2": 150, "rot": 0}
},
"tags": []
}
}
"Sine source for the first input of the second block"
sine1 = BlockComponents.Sources.Sine(amplitude = 5, frequency = 1) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 290, "y1": 20, "x2": 390, "y2": 120, "rot": 0}
},
"tags": []
}
}
"Sine source for the second input of the second block"
sine2 = BlockComponents.Sources.Sine(amplitude = 5, frequency = 2) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 290, "y1": 140, "x2": 390, "y2": 240, "rot": 0}
},
"tags": []
}
}
"Second Max block driven by the sine sources"
max_block_2 = BlockComponents.Math.Max() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 440, "y1": 50, "x2": 540, "y2": 150, "rot": 0}
},
"tags": []
}
}
relations
connect(c1.y, max_block.u1) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(c2.y, max_block.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 190}, {"x": 140, "y": 130}], "E": 2}],
"renderStyle": "standard"
}
}
connect(sine1.y, max_block_2.u1) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(sine2.y, max_block_2.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 410, "y": 190}, {"x": 410, "y": 130}], "E": 2}],
"renderStyle": "standard"
}
}
metadata {
"Dyad": {
"icons": {"default": "dyad://BlockComponents/Example.svg"},
"tests": {
"case1": {
"stop": 1,
"expect": {"signals": ["max_block.y", "max_block_2.y", "sine1.y", "sine2.y"]}
}
}
}
}
endFlattened Source
dyad
"""
Computes the maximum of constant and time-varying inputs.
Connects constant sources with values 3 and 7 to a Max block and verifies
that max(3, 7) = 7. A second Max block is driven by two sine waves of
different frequencies so the selected (larger) input alternates over time.
"""
test component Max
"Constant source providing the first input"
c1 = BlockComponents.Sources.Constant(k = 3) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 20, "y1": 20, "x2": 120, "y2": 120, "rot": 0}
},
"tags": []
}
}
"Constant source providing the second input"
c2 = BlockComponents.Sources.Constant(k = 7) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 20, "y1": 140, "x2": 120, "y2": 240, "rot": 0}
},
"tags": []
}
}
"Max block under test"
max_block = BlockComponents.Math.Max() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 160, "y1": 50, "x2": 260, "y2": 150, "rot": 0}
},
"tags": []
}
}
"Sine source for the first input of the second block"
sine1 = BlockComponents.Sources.Sine(amplitude = 5, frequency = 1) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 290, "y1": 20, "x2": 390, "y2": 120, "rot": 0}
},
"tags": []
}
}
"Sine source for the second input of the second block"
sine2 = BlockComponents.Sources.Sine(amplitude = 5, frequency = 2) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 290, "y1": 140, "x2": 390, "y2": 240, "rot": 0}
},
"tags": []
}
}
"Second Max block driven by the sine sources"
max_block_2 = BlockComponents.Math.Max() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 440, "y1": 50, "x2": 540, "y2": 150, "rot": 0}
},
"tags": []
}
}
relations
connect(c1.y, max_block.u1) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(c2.y, max_block.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 190}, {"x": 140, "y": 130}], "E": 2}],
"renderStyle": "standard"
}
}
connect(sine1.y, max_block_2.u1) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(sine2.y, max_block_2.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 410, "y": 190}, {"x": 410, "y": 130}], "E": 2}],
"renderStyle": "standard"
}
}
metadata {
"Dyad": {
"icons": {"default": "dyad://BlockComponents/Example.svg"},
"tests": {
"case1": {
"stop": 1,
"expect": {"signals": ["max_block.y", "max_block_2.y", "sine1.y", "sine2.y"]}
}
}
}
}
endTest Cases
julia
using BlockComponents
using DyadInterface: TransientAnalysis, rebuild_sol, ODEAlg
using ModelingToolkit: toggle_namespacing, get_initial_conditions, @named
using CSV, DataFrames, Plots
snapshotsdir = joinpath(dirname(dirname(pathof(BlockComponents))), "test", "snapshots")<< @setup-block not executed in draft mode >>Test Case case1
julia
@named model_case1 = BlockComponents.Math.Tests.Max()
model_case1 = toggle_namespacing(model_case1, false)
model_case1 = toggle_namespacing(model_case1, true)
result_case1 = TransientAnalysis(; model = model_case1, alg = ODEAlg.Auto(), start = 0e+0, stop = 1e+0, abstol=1e-6, reltol=1e-6)
sol_case1 = rebuild_sol(result_case1)<< @setup-block not executed in draft mode >>julia
df_case1 = DataFrame(:t => sol_case1[:t], :actual => sol_case1[model_case1.max_block.y])
dfr_case1 = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Math.Tests.Max_case1_sig0.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_case1, idxs=[model_case1.max_block.y], width=2, label="Actual value of max_block.y")
if !isnothing(dfr_case1)
scatter!(plt, dfr_case1.t, dfr_case1.expected, mc=:red, ms=3, label="Expected value of max_block.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_case1 = DataFrame(:t => sol_case1[:t], :actual => sol_case1[model_case1.max_block_2.y])
dfr_case1 = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Math.Tests.Max_case1_sig1.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_case1, idxs=[model_case1.max_block_2.y], width=2, label="Actual value of max_block_2.y")
if !isnothing(dfr_case1)
scatter!(plt, dfr_case1.t, dfr_case1.expected, mc=:red, ms=3, label="Expected value of max_block_2.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_case1 = DataFrame(:t => sol_case1[:t], :actual => sol_case1[model_case1.sine1.y])
dfr_case1 = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Math.Tests.Max_case1_sig2.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_case1, idxs=[model_case1.sine1.y], width=2, label="Actual value of sine1.y")
if !isnothing(dfr_case1)
scatter!(plt, dfr_case1.t, dfr_case1.expected, mc=:red, ms=3, label="Expected value of sine1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_case1 = DataFrame(:t => sol_case1[:t], :actual => sol_case1[model_case1.sine2.y])
dfr_case1 = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Math.Tests.Max_case1_sig3.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_case1, idxs=[model_case1.sine2.y], width=2, label="Actual value of sine2.y")
if !isnothing(dfr_case1)
scatter!(plt, dfr_case1.t, dfr_case1.expected, mc=:red, ms=3, label="Expected value of sine2.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>Related
Examples
Experiments
Analyses
Tests