Skip to content
LIBRARY
Nonlinear.VariableLimiter.md

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.

Misplaced &

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.

This component extends from BlockComponents.Interfaces.SISO

Usage

BlockComponents.Nonlinear.VariableLimiter()

Parameters:

NameDescriptionUnitsDefault 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

dyad
"""
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"}
  }
}
end
Flattened Source
dyad
"""
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"}
  }
}
end


Test Cases

No test cases defined.