Skip to content

flixopt.modeling

Attributes

Classes

ModelingUtilitiesAbstract

Utility functions for modeling calculations - 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 "off", returns 0.

Parameters:

Name Type Description Default
binary_values DataArray | ndarray | list[int, float]

Binary DataArray with values close to 0 (off) or 1 (on).

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 "on" period. Returns 0.0 if the

float

final state is "off".

Examples:

>>> arr = xr.DataArray([0, 0, 1, 1, 1, 0, 1, 1], dims=['time'])
>>> ModelingUtilitiesAbstract.count_consecutive_states(arr)
2.0
>>> arr = [0, 0, 1, 0, 1, 1, 1, 1]
>>> ModelingUtilitiesAbstract.count_consecutive_states(arr)
4.0

ModelingUtilities

Functions

compute_consecutive_hours_in_state staticmethod
compute_consecutive_hours_in_state(binary_values: TemporalData, hours_per_timestep: int | float, epsilon: float = None) -> float

Computes the final consecutive duration in state 'on' (=1) in hours.

Parameters:

Name Type Description Default
binary_values TemporalData

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 'on' 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 'off' 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 off duration in hours

get_most_recent_state staticmethod
get_most_recent_state(previous_values: DataArray | None) -> int

Get the most recent binary state from previous values.

Parameters:

Name Type Description Default
previous_values DataArray | None

DataArray with 'time' dimension

required

Returns:

Type Description
int

Most recent binary state (0 or 1)

ModelingPrimitives

Mathematical modeling primitives returning (variables, constraints) tuples

Functions

expression_tracking_variable staticmethod
expression_tracking_variable(model: Submodel, tracked_expression, name: str = None, short_name: str = None, bounds: tuple[TemporalData, TemporalData] = None, coords: str | list[str] | None = None) -> tuple[linopy.Variable, linopy.Constraint]

Creates variable that equals a given expression.

Mathematical formulation

tracker = expression lower ≤ tracker ≤ upper (if bounds provided)

Returns:

Name Type Description
variables Variable

{'tracker': tracker_var}

constraints Constraint

{'tracking': constraint}

consecutive_duration_tracking staticmethod
consecutive_duration_tracking(model: Submodel, state_variable: Variable, name: str = None, short_name: str = None, minimum_duration: TemporalData | None = None, maximum_duration: TemporalData | None = None, duration_dim: str = 'time', duration_per_step: int | float | TemporalData = None, previous_duration: TemporalData = 0) -> tuple[linopy.Variable, tuple[linopy.Constraint, linopy.Constraint, linopy.Constraint]]

Creates consecutive duration tracking for a binary state variable.

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

Parameters:

Name Type Description Default
name str

Name of the duration variable

None
state_variable Variable

Binary state variable to track duration for

required
minimum_duration TemporalData | None

Optional minimum consecutive duration

None
maximum_duration TemporalData | None

Optional maximum consecutive duration

None
previous_duration TemporalData

Duration from before first timestep

0

Returns:

Name Type Description
variables Variable

{'duration': duration_var}

constraints tuple[Constraint, Constraint, Constraint]

{'ub': constraint, 'forward': constraint, 'backward': constraint, ...}

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.

Mathematical formulation

Σ(binary_vars[i]) ≤ tolerance ∀t

Ensures at most one binary variable can be 1 at any time. Tolerance > 1.0 accounts for binary variable numerical precision.

Parameters:

Name Type Description Default
binary_variables list[Variable]

List of binary variables that should be mutually exclusive

required
tolerance float

Upper bound

1
short_name str

Short name of the constraint

'mutual_exclusivity'

Returns:

Name Type Description
variables Constraint

{} (no new variables created)

constraints 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[TemporalData, TemporalData], name: str = None) -> list[linopy.constraints.Constraint]

Create simple bounds. variable ∈ [lower_bound, upper_bound]

Mathematical Formulation

lower_bound ≤ variable ≤ upper_bound

Parameters:

Name Type Description Default
model Submodel

The optimization model instance

required
variable Variable

Variable to be bounded

required
bounds tuple[TemporalData, TemporalData]

Tuple of (lower_bound, upper_bound) absolute bounds

required

Returns:

Type Description
list[Constraint]

List containing lower_bound and upper_bound constraints

bounds_with_state staticmethod
bounds_with_state(model: Submodel, variable: Variable, bounds: tuple[TemporalData, TemporalData], variable_state: Variable, name: str = None) -> list[linopy.Constraint]

Constraint a variable to bounds, that can be escaped from to 0 by a binary variable. variable ∈ {0, [max(ε, lower_bound), upper_bound]}

Mathematical Formulation
  • variable_state * max(ε, lower_bound) ≤ variable ≤ variable_state * upper_bound
Use Cases
  • Investment decisions
  • Unit commitment (on/off states)

Parameters:

Name Type Description Default
model Submodel

The optimization model instance

required
variable Variable

Variable to be bounded

required
bounds tuple[TemporalData, TemporalData]

Tuple of (lower_bound, upper_bound) absolute bounds

required
variable_state Variable

Binary variable controlling the bounds

required

Returns:

Type Description
list[Constraint]

Tuple containing: - variables (Dict): Empty dict - constraints (Dict[str, linopy.Constraint]): 'ub', 'lb'

scaled_bounds staticmethod
scaled_bounds(model: Submodel, variable: Variable, scaling_variable: Variable, relative_bounds: tuple[TemporalData, TemporalData], name: str = None) -> list[linopy.Constraint]

Constraint a variable by scaling bounds, dependent on another variable. variable ∈ [lower_bound * scaling_variable, upper_bound * scaling_variable]

Mathematical Formulation

scaling_variable * lower_factor ≤ variable ≤ scaling_variable * upper_factor

Use Cases
  • Flow rates bounded by equipment capacity
  • Production levels scaled by plant size

Parameters:

Name Type Description Default
model Submodel

The optimization model instance

required
variable Variable

Variable to be bounded

required
scaling_variable Variable

Variable that scales the bound factors

required
relative_bounds tuple[TemporalData, TemporalData]

Tuple of (lower_factor, upper_factor) relative to scaling variable

required

Returns:

Type Description
list[Constraint]

Tuple containing: - variables (Dict): Empty dict - constraints (Dict[str, linopy.Constraint]): 'ub', 'lb'

scaled_bounds_with_state staticmethod
scaled_bounds_with_state(model: Submodel, variable: Variable, scaling_variable: Variable, relative_bounds: tuple[TemporalData, TemporalData], scaling_bounds: tuple[TemporalData, TemporalData], variable_state: Variable, name: str = None) -> list[linopy.Constraint]

Constraint a variable by scaling bounds with binary state control.

variable ∈ {0, [max(ε, lower_relative_bound) * scaling_variable, upper_relative_bound * scaling_variable]}

Mathematical Formulation (Big-M): (variable_state - 1) * M_misc + scaling_variable * rel_lower ≤ variable ≤ scaling_variable * rel_upper variable_state * big_m_lower ≤ variable ≤ 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 optimization model instance

required
variable Variable

Variable to be bounded

required
scaling_variable Variable

Variable that scales the bound factors

required
relative_bounds tuple[TemporalData, TemporalData]

Tuple of (lower_factor, upper_factor) relative to scaling variable

required
scaling_bounds tuple[TemporalData, TemporalData]

Tuple of (scaling_min, scaling_max) bounds of the scaling variable

required
variable_state Variable

Binary variable for on/off control

required
name str

Optional name prefix for constraints

None

Returns:

Type Description
list[Constraint]

List[linopy.Constraint]: List of constraint objects

state_transition_bounds staticmethod
state_transition_bounds(model: Submodel, state_variable: Variable, switch_on: Variable, switch_off: Variable, name: str, previous_state=0, coord: str = 'time') -> tuple[linopy.Constraint, linopy.Constraint, linopy.Constraint]

Creates switch-on/off variables with state transition logic.

Mathematical formulation

switch_on[t] - switch_off[t] = state[t] - state[t-1] ∀t > 0 switch_on[0] - switch_off[0] = state[0] - previous_state switch_on[t] + switch_off[t] ≤ 1 ∀t switch_on[t], switch_off[t] ∈ {0, 1}

Returns:

Name Type Description
variables Constraint

{'switch_on': binary_var, 'switch_off': binary_var}

constraints Constraint

{'transition': constraint, 'initial': constraint, 'mutex': constraint}

continuous_transition_bounds staticmethod
continuous_transition_bounds(model: Submodel, continuous_variable: Variable, switch_on: Variable, switch_off: 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 when switch variables are active.

Mathematical formulation

-max_change * (switch_on[t] + switch_off[t]) <= continuous[t] - continuous[t-1] <= max_change * (switch_on[t] + switch_off[t]) ∀t > 0 -max_change * (switch_on[0] + switch_off[0]) <= continuous[0] - previous_value <= max_change * (switch_on[0] + switch_off[0]) switch_on[t], switch_off[t] ∈ {0, 1}

This ensures the continuous variable can only change when switch_on or switch_off is 1. When both switches are 0, the variable must stay exactly constant.

Parameters:

Name Type Description Default
model Submodel

The submodel to add constraints to

required
continuous_variable Variable

The continuous variable to constrain

required
switch_on Variable

Binary variable indicating when changes are allowed (typically transitions to active state)

required
switch_off Variable

Binary variable indicating when changes are allowed (typically transitions to inactive state)

required
name str

Base name for the constraints

required
max_change float | DataArray

Maximum possible change in the continuous variable (Big-M value)

required
previous_value float | DataArray

Initial value of the continuous variable before first period

0.0
coord str

Coordinate name for time dimension

'time'

Returns:

Type Description
tuple[Constraint, Constraint, Constraint, Constraint]

Tuple of constraints: (transition_upper, transition_lower, initial_upper, initial_lower)

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)