flixopt.modeling ¶
Classes¶
ModelingUtilitiesAbstract ¶
Utility functions for modeling - leveraging xarray for temporal data
Functions¶
to_binary staticmethod ¶
to_binary(values: DataArray, epsilon: float | None = None, dims: str | list[str] | None = None) -> xr.DataArray
Converts a DataArray to binary {0, 1} values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
values | DataArray | Input DataArray to convert to binary | required |
epsilon | float | None | Tolerance for zero detection (uses CONFIG.Modeling.epsilon if None) | None |
dims | str | list[str] | None | Dims to keep. Other dimensions are collapsed using .any() -> If any value is 1, all are 1. | None |
Returns:
| Type | Description |
|---|---|
DataArray | Binary DataArray with same shape (or collapsed if collapse_non_time=True) |
count_consecutive_states staticmethod ¶
count_consecutive_states(binary_values: DataArray | ndarray | list[int, float], dim: str = 'time', epsilon: float | None = None) -> float
Count consecutive steps in the final active state of a binary time series.
This function counts how many consecutive time steps the series remains "on" (non-zero) at the end of the time series. If the final state is "inactive", returns 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
binary_values | DataArray | ndarray | list[int, float] | Binary DataArray with values close to 0 (inactive) or 1 (active). | required |
dim | str | Dimension along which to count consecutive states. | 'time' |
epsilon | float | None | Tolerance for zero detection. Uses CONFIG.Modeling.epsilon if None. | None |
Returns:
| Type | Description |
|---|---|
float | Sum of values in the final consecutive "active" period. Returns 0.0 if the |
float | final state is "inactive". |
Examples:
ModelingUtilities ¶
Functions¶
compute_consecutive_hours_in_state staticmethod ¶
compute_consecutive_hours_in_state(binary_values: DataArray, hours_per_timestep: int | float, epsilon: float = None) -> float
Computes the final consecutive duration in state 'active' (=1) in hours.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
binary_values | DataArray | Binary DataArray with 'time' dim, or scalar/array | required |
hours_per_timestep | int | float | Duration of each timestep in hours | required |
epsilon | float | Tolerance for zero detection (uses CONFIG.Modeling.epsilon if None) | None |
Returns:
| Type | Description |
|---|---|
float | The duration of the final consecutive 'active' period in hours |
compute_previous_off_duration staticmethod ¶
compute_previous_off_duration(previous_values: DataArray, hours_per_step: DataArray | float | int) -> float
Compute previous consecutive 'inactive' duration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
previous_values | DataArray | DataArray with 'time' dimension | required |
hours_per_step | DataArray | float | int | Duration of each timestep in hours | required |
Returns:
| Type | Description |
|---|---|
float | Previous consecutive inactive duration in hours |
ModelingPrimitives ¶
Mathematical modeling primitives returning (variables, constraints) tuples
Functions¶
expression_tracking_variable staticmethod ¶
expression_tracking_variable(model: Submodel, tracked_expression: LinearExpression | Variable, name: str = None, short_name: str = None, bounds: tuple[DataArray, DataArray] = None, coords: str | list[str] | None = None) -> tuple[linopy.Variable, linopy.Constraint]
Creates a variable constrained to equal a given expression.
Mathematical formulation
tracker = expression lower ≤ tracker ≤ upper (if bounds provided)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model | Submodel | The submodel to add variables and constraints to | required |
tracked_expression | LinearExpression | Variable | Expression that the tracker variable must equal | required |
name | str | Full name for the variable and constraint | None |
short_name | str | Short name for display purposes | None |
bounds | tuple[DataArray, DataArray] | Optional (lower_bound, upper_bound) tuple for the tracker variable | None |
coords | str | list[str] | None | Coordinate dimensions for the variable (None uses all model coords) | None |
Returns:
| Type | Description |
|---|---|
tuple[Variable, Constraint] | Tuple of (tracker_variable, tracking_constraint) |
consecutive_duration_tracking staticmethod ¶
consecutive_duration_tracking(model: Submodel, state: Variable, name: str = None, short_name: str = None, minimum_duration: DataArray | None = None, maximum_duration: DataArray | None = None, duration_dim: str = 'time', duration_per_step: int | float | DataArray = None, previous_duration: DataArray = 0) -> tuple[dict[str, linopy.Variable], dict[str, linopy.Constraint]]
Creates consecutive duration tracking for a binary state variable.
Tracks how long a binary state has been continuously active (=1). Duration resets to 0 when state becomes inactive (=0).
Mathematical formulation
duration[t] ≤ state[t] · M ∀t duration[t+1] ≤ duration[t] + duration_per_step[t] ∀t duration[t+1] ≥ duration[t] + duration_per_step[t] + (state[t+1] - 1) · M ∀t duration[0] = (duration_per_step[0] + previous_duration) · state[0]
If minimum_duration provided: duration[t] ≥ (state[t-1] - state[t]) · minimum_duration[t-1] ∀t > 0
Where M is a big-M value (sum of all duration_per_step + previous_duration).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model | Submodel | The submodel to add variables and constraints to | required |
state | Variable | Binary state variable (1=active, 0=inactive) to track duration for | required |
name | str | Full name for the duration variable | None |
short_name | str | Short name for display purposes | None |
minimum_duration | DataArray | None | Optional minimum consecutive duration (enforced at state transitions) | None |
maximum_duration | DataArray | None | Optional maximum consecutive duration (upper bound on duration variable) | None |
duration_dim | str | Dimension name to track duration along (default 'time') | 'time' |
duration_per_step | int | float | DataArray | Time increment per step in duration_dim | None |
previous_duration | DataArray | Initial duration value before first timestep (default 0) | 0 |
Returns:
| Type | Description |
|---|---|
dict[str, Variable] | Tuple of (duration_variable, constraints_dict) |
dict[str, Constraint] | where constraints_dict contains: 'ub', 'forward', 'backward', 'initial', and optionally 'lb', 'initial_lb' |
mutual_exclusivity_constraint staticmethod ¶
mutual_exclusivity_constraint(model: Submodel, binary_variables: list[Variable], tolerance: float = 1, short_name: str = 'mutual_exclusivity') -> linopy.Constraint
Creates mutual exclusivity constraint for binary variables.
Ensures at most one binary variable can be active (=1) at any time.
Mathematical formulation
Σᵢ binary_vars[i] ≤ tolerance ∀t
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model | Submodel | The submodel to add the constraint to | required |
binary_variables | list[Variable] | List of binary variables that should be mutually exclusive | required |
tolerance | float | Upper bound on the sum (default 1, allows slight numerical tolerance) | 1 |
short_name | str | Short name for the constraint | 'mutual_exclusivity' |
Returns:
| Type | Description |
|---|---|
Constraint | Mutual exclusivity constraint |
Raises:
| Type | Description |
|---|---|
AssertionError | If fewer than 2 variables provided or variables aren't binary |
BoundingPatterns ¶
High-level patterns that compose primitives and return (variables, constraints) tuples
Functions¶
basic_bounds staticmethod ¶
basic_bounds(model: Submodel, variable: Variable, bounds: tuple[DataArray, DataArray], name: str = None) -> list[linopy.constraints.Constraint]
Creates simple lower and upper bounds for a variable.
Mathematical formulation
lower_bound ≤ variable ≤ upper_bound
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model | Submodel | The submodel to add constraints to | required |
variable | Variable | Variable to be bounded | required |
bounds | tuple[DataArray, DataArray] | Tuple of (lower_bound, upper_bound) absolute bounds | required |
name | str | Optional name prefix for constraints | None |
Returns:
| Type | Description |
|---|---|
list[Constraint] | List of [lower_constraint, upper_constraint] |
bounds_with_state staticmethod ¶
bounds_with_state(model: Submodel, variable: Variable, bounds: tuple[DataArray, DataArray], state: Variable, name: str = None) -> list[linopy.Constraint]
Creates bounds controlled by a binary state variable.
Variable is forced to 0 when state=0, bounded when state=1.
Mathematical formulation
state · max(ε, lower_bound) ≤ variable ≤ state · upper_bound
Where ε is a small positive number (CONFIG.Modeling.epsilon) ensuring numerical stability when lower_bound is 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model | Submodel | The submodel to add constraints to | required |
variable | Variable | Variable to be bounded | required |
bounds | tuple[DataArray, DataArray] | Tuple of (lower_bound, upper_bound) absolute bounds when state=1 | required |
state | Variable | Binary variable (0=force variable to 0, 1=allow bounds) | required |
name | str | Optional name prefix for constraints | None |
Returns:
| Type | Description |
|---|---|
list[Constraint] | List of [lower_constraint, upper_constraint] (or [fix_constraint] if lower=upper) |
scaled_bounds staticmethod ¶
scaled_bounds(model: Submodel, variable: Variable, scaling_variable: Variable, relative_bounds: tuple[DataArray, DataArray], name: str = None) -> list[linopy.Constraint]
Creates bounds scaled by another variable.
Variable is bounded relative to a scaling variable (e.g., flow rate relative to size).
Mathematical formulation
scaling_variable · lower_factor ≤ variable ≤ scaling_variable · upper_factor
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model | Submodel | The submodel to add constraints to | required |
variable | Variable | Variable to be bounded | required |
scaling_variable | Variable | Variable that scales the bound factors (e.g., equipment size) | required |
relative_bounds | tuple[DataArray, DataArray] | Tuple of (lower_factor, upper_factor) relative to scaling_variable | required |
name | str | Optional name prefix for constraints | None |
Returns:
| Type | Description |
|---|---|
list[Constraint] | List of [lower_constraint, upper_constraint] (or [fix_constraint] if lower=upper) |
scaled_bounds_with_state staticmethod ¶
scaled_bounds_with_state(model: Submodel, variable: Variable, scaling_variable: Variable, relative_bounds: tuple[DataArray, DataArray], scaling_bounds: tuple[DataArray, DataArray], state: Variable, name: str = None) -> list[linopy.Constraint]
Creates bounds scaled by a variable and controlled by a binary state.
Variable is forced to 0 when state=0, bounded relative to scaling_variable when state=1.
Mathematical formulation (Big-M): (state - 1) · M_misc + scaling_variable · rel_lower ≤ variable ≤ scaling_variable · rel_upper state · big_m_lower ≤ variable ≤ state · big_m_upper
Where
M_misc = scaling_max · rel_lower big_m_upper = scaling_max · rel_upper big_m_lower = max(ε, scaling_min · rel_lower)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model | Submodel | The submodel to add constraints to | required |
variable | Variable | Variable to be bounded | required |
scaling_variable | Variable | Variable that scales the bound factors (e.g., equipment size) | required |
relative_bounds | tuple[DataArray, DataArray] | Tuple of (lower_factor, upper_factor) relative to scaling_variable | required |
scaling_bounds | tuple[DataArray, DataArray] | Tuple of (scaling_min, scaling_max) bounds of the scaling_variable | required |
state | Variable | Binary variable (0=force variable to 0, 1=allow scaled bounds) | required |
name | str | Optional name prefix for constraints | None |
Returns:
| Type | Description |
|---|---|
list[Constraint] | List of [scaling_lower, scaling_upper, binary_lower, binary_upper] constraints |
state_transition_bounds staticmethod ¶
state_transition_bounds(model: Submodel, state: Variable, activate: Variable, deactivate: Variable, name: str, previous_state: float | DataArray = 0, coord: str = 'time') -> tuple[linopy.Constraint, linopy.Constraint, linopy.Constraint]
Creates state transition constraints for binary state variables.
Tracks transitions between active (1) and inactive (0) states using separate binary variables for activation and deactivation events.
Mathematical formulation
activate[t] - deactivate[t] = state[t] - state[t-1] ∀t > 0 activate[0] - deactivate[0] = state[0] - previous_state activate[t] + deactivate[t] ≤ 1 ∀t activate[t], deactivate[t] ∈ {0, 1}
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model | Submodel | The submodel to add constraints to | required |
state | Variable | Binary state variable (0=inactive, 1=active) | required |
activate | Variable | Binary variable for transitions from inactive to active (0→1) | required |
deactivate | Variable | Binary variable for transitions from active to inactive (1→0) | required |
name | str | Base name for constraints | required |
previous_state | float | DataArray | State value before first timestep (default 0) | 0 |
coord | str | Time dimension name (default 'time') | 'time' |
Returns:
| Type | Description |
|---|---|
tuple[Constraint, Constraint, Constraint] | Tuple of (transition_constraint, initial_constraint, mutex_constraint) |
continuous_transition_bounds staticmethod ¶
continuous_transition_bounds(model: Submodel, continuous_variable: Variable, activate: Variable, deactivate: Variable, name: str, max_change: float | DataArray, previous_value: float | DataArray = 0.0, coord: str = 'time') -> tuple[linopy.Constraint, linopy.Constraint, linopy.Constraint, linopy.Constraint]
Constrains a continuous variable to only change during state transitions.
Ensures a continuous variable remains constant unless a transition event occurs. Uses Big-M formulation to enforce change bounds.
Mathematical formulation
-max_change · (activate[t] + deactivate[t]) ≤ continuous[t] - continuous[t-1] ≤ max_change · (activate[t] + deactivate[t]) ∀t > 0 -max_change · (activate[0] + deactivate[0]) ≤ continuous[0] - previous_value ≤ max_change · (activate[0] + deactivate[0]) activate[t], deactivate[t] ∈ {0, 1}
Behavior
- When activate=0 and deactivate=0: variable must stay constant
- When activate=1 or deactivate=1: variable can change within ±max_change
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model | Submodel | The submodel to add constraints to | required |
continuous_variable | Variable | Continuous variable to constrain | required |
activate | Variable | Binary variable for transitions from inactive to active (0→1) | required |
deactivate | Variable | Binary variable for transitions from active to inactive (1→0) | required |
name | str | Base name for constraints | required |
max_change | float | DataArray | Maximum allowed change (Big-M value, should be ≥ actual max change) | required |
previous_value | float | DataArray | Initial value before first timestep (default 0.0) | 0.0 |
coord | str | Time dimension name (default 'time') | 'time' |
Returns:
| Type | Description |
|---|---|
tuple[Constraint, Constraint, Constraint, Constraint] | Tuple of (transition_upper, transition_lower, initial_upper, initial_lower) constraints |
link_changes_to_level_with_binaries staticmethod ¶
link_changes_to_level_with_binaries(model: Submodel, level_variable: Variable, increase_variable: Variable, decrease_variable: Variable, increase_binary: Variable, decrease_binary: Variable, name: str, max_change: float | DataArray, initial_level: float | DataArray = 0.0, coord: str = 'period') -> tuple[linopy.Constraint, linopy.Constraint, linopy.Constraint, linopy.Constraint, linopy.Constraint]
Link changes to level evolution with binary control and mutual exclusivity.
Creates the complete constraint system for ALL time periods: 1. level[0] = initial_level + increase[0] - decrease[0] 2. level[t] = level[t-1] + increase[t] - decrease[t] ∀t > 0 3. increase[t] <= max_change * increase_binary[t] ∀t 4. decrease[t] <= max_change * decrease_binary[t] ∀t 5. increase_binary[t] + decrease_binary[t] <= 1 ∀t
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model | Submodel | The submodel to add constraints to | required |
increase_variable | Variable | Incremental additions for ALL periods (>= 0) | required |
decrease_variable | Variable | Incremental reductions for ALL periods (>= 0) | required |
increase_binary | Variable | Binary indicators for increases for ALL periods | required |
decrease_binary | Variable | Binary indicators for decreases for ALL periods | required |
level_variable | Variable | Level variable for ALL periods | required |
name | str | Base name for constraints | required |
max_change | float | DataArray | Maximum change per period | required |
initial_level | float | DataArray | Starting level before first period | 0.0 |
coord | str | Time coordinate name | 'period' |
Returns:
| Type | Description |
|---|---|
tuple[Constraint, Constraint, Constraint, Constraint, Constraint] | Tuple of (initial_constraint, transition_constraints, increase_bounds, decrease_bounds, mutual_exclusion) |