Bounds and States
This document describes the mathematical formulations for variable bounding patterns used throughout FlixOpt. These patterns define how optimization variables are constrained, both with and without state control.
Basic Bounds
The simplest bounding pattern constrains a variable between lower and upper bounds.
With: - \(v\) being the optimization variable - \(\text{lower}\) being the lower bound (constant or time-dependent) - \(\text{upper}\) being the upper bound (constant or time-dependent)
Implementation: BoundingPatterns.basic_bounds()
Used in: - Storage charge state bounds (see Storage) - Flow rate absolute bounds
Bounds with State
When a variable should only be non-zero if a binary state variable is active (e.g., on/off operation, investment decisions), the bounds are controlled by the state:
With: - \(v\) being the optimization variable - \(s \in \{0, 1\}\) being the binary state variable - \(\text{lower}\) being the lower bound when active - \(\text{upper}\) being the upper bound when active - \(\varepsilon\) being a small positive number to ensure numerical stability
Behavior: - When \(s = 0\): variable is forced to zero (\(0 \leq v \leq 0\)) - When \(s = 1\): variable can take values in \([\text{lower}, \text{upper}]\)
Implementation: BoundingPatterns.bounds_with_state()
Used in: - Flow rates with on/off operation (see OnOffParameters) - Investment size decisions (see InvestParameters)
Scaled Bounds
When a variable's bounds depend on another variable (e.g., flow rate scaled by component size), scaled bounds are used:
With: - \(v\) being the optimization variable (e.g., flow rate) - \(v_\text{scale}\) being the scaling variable (e.g., component size) - \(\text{rel}_\text{lower}\) being the relative lower bound factor (typically 0) - \(\text{rel}_\text{upper}\) being the relative upper bound factor (typically 1)
Example: Flow rate bounds - If \(v_\text{scale} = P\) (flow size) and \(\text{rel}_\text{upper} = 1\) - Then: \(0 \leq p(t_i) \leq P\) (see Flow)
Implementation: BoundingPatterns.scaled_bounds()
Used in: - Flow rate constraints (see Flow equation 1) - Storage charge state constraints (see Storage equation 1)
Scaled Bounds with State
Combining scaled bounds with binary state control requires a Big-M formulation to handle both the scaling and the on/off behavior:
With: - \(v\) being the optimization variable - \(v_\text{scale}\) being the scaling variable - \(s \in \{0, 1\}\) being the binary state variable - \(\text{rel}_\text{lower}\) being the relative lower bound factor - \(\text{rel}_\text{upper}\) being the relative upper bound factor - \(M_\text{misc} = v_\text{scale,max} \cdot \text{rel}_\text{lower}\) - \(M_\text{upper} = v_\text{scale,max} \cdot \text{rel}_\text{upper}\) - \(M_\text{lower} = \max(\varepsilon, v_\text{scale,min} \cdot \text{rel}_\text{lower})\)
Where \(v_\text{scale,max}\) and \(v_\text{scale,min}\) are the maximum and minimum possible values of the scaling variable.
Behavior: - When \(s = 0\): variable is forced to zero - When \(s = 1\): variable follows scaled bounds \(v_\text{scale} \cdot \text{rel}_\text{lower} \leq v \leq v_\text{scale} \cdot \text{rel}_\text{upper}\)
Implementation: BoundingPatterns.scaled_bounds_with_state()
Used in: - Flow rates with on/off operation and investment sizing - Components combining OnOffParameters and InvestParameters
Expression Tracking
Sometimes it's necessary to create an auxiliary variable that equals an expression:
With optional bounds:
With: - \(v_\text{tracker}\) being the auxiliary tracking variable - \(\text{expression}\) being a linear expression of other variables - \(\text{lower}, \text{upper}\) being optional bounds on the tracker
Use cases: - Creating named variables for complex expressions - Bounding intermediate results - Simplifying constraint formulations
Implementation: ModelingPrimitives.expression_tracking_variable()
Mutual Exclusivity
When multiple binary variables should not be active simultaneously (at most one can be 1):
With: - \(s_i(t) \in \{0, 1\}\) being binary state variables - \(\text{tolerance}\) being the maximum number of simultaneously active states (typically 1) - \(t\) being the time index
Use cases: - Ensuring only one operating mode is active - Mutual exclusion of operation and maintenance states - Enforcing single-choice decisions
Implementation: ModelingPrimitives.mutual_exclusivity_constraint()
Used in: - Operating mode selection - Piecewise linear function segments (see Piecewise)