Nonlinear.VariableLimiter
Limit the range of a signal with variable limits.
The Limiter block passes its input signal as output signal as long as the input is within the upper and lower limits specified by the two additional inputs limit1 and limit2. If this is not the case, the corresponding limit is passed as output.
Deviations from the Modelica Standard Library
MSL defines the output (default strict = false, homotopyType = Linear) as y = homotopy(actual = smooth(0, if u > limit1 then limit1 else if u < limit2 then limit2 else u), simplified = u) and, when strict = true, wraps the piecewise expression in noEvent(...). Three constructs are involved that this implementation does not reproduce:
noEvent(...)— used only in thestrict = truebranch to suppress state events at the clamp boundaries. Dyad currently has nonoEvent-style operator, so thestrict = truepath cannot be expressed.strictis therefore afinal structural parameterfixed tofalse; only the non-strict behavior is implemented. Support can be added later without changing the default behavior.smooth(0, ...)— declares C0-continuity of the piecewise expression to the integrator. Omitted here (the plainifelseis used instead); behavior is equivalent.homotopy(..., simplified = u)— supplies a simplified linear form used during homotopy-based initialization. Omitted here.
This component extends from BlockComponents.Interfaces.SISO
Usage
BlockComponents.Nonlinear.VariableLimiter()
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
strict | = true, if strict limits with noEvent(..). Only false is implemented (see docstring) | – | false |
Connectors
u- This connector represents a real signal as an input to a component (RealInput)y- This connector represents a real signal as an output from a component (RealOutput)limit1- This connector represents a real signal as an input to a component (RealInput)limit2- This connector represents a real signal as an input to a component (RealInput)
Behavior
Source
"""
Limit the range of a signal with variable limits.
The Limiter block passes its input signal as output signal as long as
the input is within the upper and lower limits specified by the two
additional inputs `limit1` and `limit2`. If this is not the case,
the corresponding limit is passed as output.
```math
y = \\begin{cases}
\\text{limit1} & \\text{if } u > \\text{limit1} \\\\
\\text{limit2} & \\text{if } u < \\text{limit2} \\\\
u & \\text{otherwise}
\\end{cases}
```
## Deviations from the Modelica Standard Library
MSL defines the output (default `strict = false`, `homotopyType = Linear`) as
`y = homotopy(actual = smooth(0, if u > limit1 then limit1 else if u < limit2 then limit2 else u), simplified = u)`
and, when `strict = true`, wraps the piecewise expression in `noEvent(...)`.
Three constructs are involved that this implementation does not reproduce:
- `noEvent(...)` — used **only** in the `strict = true` branch to suppress state
events at the clamp boundaries. Dyad currently has no `noEvent`-style operator,
so the `strict = true` path cannot be expressed. `strict` is therefore a
`final structural parameter` fixed to `false`; only the non-strict behavior is
implemented. Support can be added later without changing the default behavior.
- `smooth(0, ...)` — declares C0-continuity of the piecewise expression to the
integrator. Omitted here (the plain `ifelse` is used instead); behavior is
equivalent.
- `homotopy(..., simplified = u)` — supplies a simplified linear form used during
homotopy-based initialization. Omitted here.
"""
component VariableLimiter
extends BlockComponents.Interfaces.SISO
"Connector of Real input signal used as maximum of input u"
limit1 = RealInput() {
"Dyad": {
"placement": {
"icon": {"iconName": "input", "x1": -100, "y1": 150, "x2": 0, "y2": 250, "rot": 0},
"diagram": {"iconName": "input", "x1": -100, "y1": 150, "x2": 0, "y2": 250, "rot": 0}
},
"tags": []
}
}
"Connector of Real input signal used as minimum of input u"
limit2 = RealInput() {
"Dyad": {
"placement": {
"icon": {"iconName": "input", "x1": -100, "y1": 750, "x2": 0, "y2": 850, "rot": 0},
"diagram": {"iconName": "input", "x1": -100, "y1": 750, "x2": 0, "y2": 850, "rot": 0}
},
"tags": []
}
}
"= true, if strict limits with noEvent(..). Only false is implemented (see docstring)"
final structural parameter strict::Boolean = false
relations
assert(limit1 >= limit2, "VariableLimiter: Input signals are not consistent: limit1 < limit2")
if strict
else
# strict = true is not implemented: MSL uses
# y = smooth(0, noEvent(if u > limit1 then limit1 else if u < limit2 then limit2 else u))
# which requires a `noEvent`-style operator that Dyad does not currently
# provide. `strict` is fixed to `false`, so this branch is never selected.
# Populate this branch once a noEvent operator becomes available.
y = ifelse(u > limit1, limit1, ifelse(u < limit2, limit2, u))
end
metadata {
"Dyad": {
"labels": [{"label": "$(instance)", "x": 500, "y": 1100, "rot": 0}],
"icons": {"default": "dyad://BlockComponents/VarLimiter.svg"}
}
}
endFlattened Source
"""
Limit the range of a signal with variable limits.
The Limiter block passes its input signal as output signal as long as
the input is within the upper and lower limits specified by the two
additional inputs `limit1` and `limit2`. If this is not the case,
the corresponding limit is passed as output.
```math
y = \\begin{cases}
\\text{limit1} & \\text{if } u > \\text{limit1} \\\\
\\text{limit2} & \\text{if } u < \\text{limit2} \\\\
u & \\text{otherwise}
\\end{cases}
```
## Deviations from the Modelica Standard Library
MSL defines the output (default `strict = false`, `homotopyType = Linear`) as
`y = homotopy(actual = smooth(0, if u > limit1 then limit1 else if u < limit2 then limit2 else u), simplified = u)`
and, when `strict = true`, wraps the piecewise expression in `noEvent(...)`.
Three constructs are involved that this implementation does not reproduce:
- `noEvent(...)` — used **only** in the `strict = true` branch to suppress state
events at the clamp boundaries. Dyad currently has no `noEvent`-style operator,
so the `strict = true` path cannot be expressed. `strict` is therefore a
`final structural parameter` fixed to `false`; only the non-strict behavior is
implemented. Support can be added later without changing the default behavior.
- `smooth(0, ...)` — declares C0-continuity of the piecewise expression to the
integrator. Omitted here (the plain `ifelse` is used instead); behavior is
equivalent.
- `homotopy(..., simplified = u)` — supplies a simplified linear form used during
homotopy-based initialization. Omitted here.
"""
component VariableLimiter
"Input signal port"
u = RealInput() {
"Dyad": {
"placement": {
"icon": {"iconName": "input", "x1": -100, "y1": 450, "x2": 0, "y2": 550, "rot": 0},
"diagram": {"iconName": "input", "x1": -100, "y1": 450, "x2": 0, "y2": 550, "rot": 0}
}
}
}
"Output signal port"
y = RealOutput() {
"Dyad": {
"placement": {
"icon": {"iconName": "output", "x1": 1000, "y1": 450, "x2": 1100, "y2": 550, "rot": 0},
"diagram": {"iconName": "output", "x1": 1000, "y1": 450, "x2": 1100, "y2": 550, "rot": 0}
}
}
}
"Connector of Real input signal used as maximum of input u"
limit1 = RealInput() {
"Dyad": {
"placement": {
"icon": {"iconName": "input", "x1": -100, "y1": 150, "x2": 0, "y2": 250, "rot": 0},
"diagram": {"iconName": "input", "x1": -100, "y1": 150, "x2": 0, "y2": 250, "rot": 0}
},
"tags": []
}
}
"Connector of Real input signal used as minimum of input u"
limit2 = RealInput() {
"Dyad": {
"placement": {
"icon": {"iconName": "input", "x1": -100, "y1": 750, "x2": 0, "y2": 850, "rot": 0},
"diagram": {"iconName": "input", "x1": -100, "y1": 750, "x2": 0, "y2": 850, "rot": 0}
},
"tags": []
}
}
"= true, if strict limits with noEvent(..). Only false is implemented (see docstring)"
final structural parameter strict::Boolean = false
relations
assert(limit1 >= limit2, "VariableLimiter: Input signals are not consistent: limit1 < limit2")
if strict
else
# strict = true is not implemented: MSL uses
# y = smooth(0, noEvent(if u > limit1 then limit1 else if u < limit2 then limit2 else u))
# which requires a `noEvent`-style operator that Dyad does not currently
# provide. `strict` is fixed to `false`, so this branch is never selected.
# Populate this branch once a noEvent operator becomes available.
y = ifelse(u > limit1, limit1, ifelse(u < limit2, limit2, u))
end
metadata {
"Dyad": {
"labels": [{"label": "$(instance)", "x": 500, "y": 1100, "rot": 0}],
"icons": {"default": "dyad://BlockComponents/VarLimiter.svg"}
}
}
endTest Cases
No test cases defined.
Related
Examples
Experiments
Analyses
Tests