Skip to content
TriangularTest.md

TriangularTest ​

A test component that integrates a triangular signal over time.

This component connects a triangular wave generator to an integrator to demonstrate signal processing and integration. The triangular signal has amplitude 1, frequency 2 Hz, starts at time 0.5 seconds with an offset of 0.7. The output of the integrator represents the accumulated area under the triangular wave over time. The test case validates the behavior by checking both the initial signal value and the final integrated value after 5 seconds of simulation.

Usage ​

BlockComponents.TriangularTest()

Behavior ​

julia
using BlockComponents #hide
using ModelingToolkit #hide
@named sys = BlockComponents.TriangularTest() #hide
full_equations(sys) #hide
<< @example-block not executed in draft mode >>

Source ​

dyad
"""
A test component that integrates a triangular signal over time.

This component connects a triangular wave generator to an integrator to demonstrate signal
processing and integration. The triangular signal has amplitude 1, frequency 2 Hz, starts at
time 0.5 seconds with an offset of 0.7. The output of the integrator represents the accumulated
area under the triangular wave over time. The test case validates the behavior by checking both
the initial signal value and the final integrated value after 5 seconds of simulation.
"""
test component TriangularTest
  "Integrator component that accumulates the input signal"
  integrator = Integrator() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 160, "y1": 20, "x2": 260, "y2": 120, "rot": 0}
      }
    }
  }
  "Triangular waveform generator with configurable parameters"
  signal = Triangular(amplitude = 1, frequency = 2, start_time = 0.5, offset = 0.7) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 20, "y1": 20, "x2": 120, "y2": 120, "rot": 0}
      }
    }
  }
relations
  "Connects the triangular signal output to the integrator input"
  connect(signal.y, integrator.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
metadata {
  "Dyad": {
    "icons": {"default": "dyad://BlockComponents/Example.svg"},
    "tests": {
      "case1": {
        "stop": 5,
        "atol": {"integrator.x": 0.001},
        "expect": {
          "initial": {"signal.y": 0.7},
          "signals": ["signal.y", "integrator.x"],
          "final": {"signal.y": 0.7, "integrator.x": 3.5}
        }
      }
    }
  }
}
end
Flattened Source
dyad
"""
A test component that integrates a triangular signal over time.

This component connects a triangular wave generator to an integrator to demonstrate signal
processing and integration. The triangular signal has amplitude 1, frequency 2 Hz, starts at
time 0.5 seconds with an offset of 0.7. The output of the integrator represents the accumulated
area under the triangular wave over time. The test case validates the behavior by checking both
the initial signal value and the final integrated value after 5 seconds of simulation.
"""
test component TriangularTest
  "Integrator component that accumulates the input signal"
  integrator = Integrator() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 160, "y1": 20, "x2": 260, "y2": 120, "rot": 0}
      }
    }
  }
  "Triangular waveform generator with configurable parameters"
  signal = Triangular(amplitude = 1, frequency = 2, start_time = 0.5, offset = 0.7) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 20, "y1": 20, "x2": 120, "y2": 120, "rot": 0}
      }
    }
  }
relations
  "Connects the triangular signal output to the integrator input"
  connect(signal.y, integrator.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
metadata {
  "Dyad": {
    "icons": {"default": "dyad://BlockComponents/Example.svg"},
    "tests": {
      "case1": {
        "stop": 5,
        "atol": {"integrator.x": 0.001},
        "expect": {
          "initial": {"signal.y": 0.7},
          "signals": ["signal.y", "integrator.x"],
          "final": {"signal.y": 0.7, "integrator.x": 3.5}
        }
      }
    }
  }
}
end


Test Cases ​

julia
using BlockComponents
using DyadInterface: TransientAnalysis, rebuild_sol
using ModelingToolkit: toggle_namespacing, get_defaults, @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 = TriangularTest()
model_case1 = toggle_namespacing(model_case1, false)

model_case1 = toggle_namespacing(model_case1, true)
result_case1 = TransientAnalysis(; model = model_case1, alg = "auto", start = 0e+0, stop = 5e+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.signal.y])
dfr_case1 = try CSV.read(joinpath(snapshotsdir, "TriangularTest_case1_sig0.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_case1, idxs=[model_case1.signal.y], width=2, label="Actual value of signal.y")
if !isnothing(dfr_case1)
  scatter!(plt, dfr_case1.t, dfr_case1.expected, mc=:red, ms=3, label="Expected value of signal.y")
end
scatter!(plt, [df_case1.t[1]], [0.7], label="Initial Condition for `signal.y`")
scatter!(plt, [df_case1.t[end]], [0.7], label="Final Condition for `signal.y`")
<< @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.integrator.x])
dfr_case1 = try CSV.read(joinpath(snapshotsdir, "TriangularTest_case1_sig1.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_case1, idxs=[model_case1.integrator.x], width=2, label="Actual value of integrator.x")
if !isnothing(dfr_case1)
  scatter!(plt, dfr_case1.t, dfr_case1.expected, mc=:red, ms=3, label="Expected value of integrator.x")
end
scatter!(plt, [df_case1.t[end]], [3.5], label="Final Condition for `integrator.x`")
<< @setup-block not executed in draft mode >>
julia
plt
<< @example-block not executed in draft mode >>