fluxopt.elements
¶
Classes:
| Name | Description |
|---|---|
Carrier |
Physical energy medium (electricity, heat, gas, …). |
Sizing |
Capacity optimization parameters. |
Investment |
Singular discrete build-timing optimization. |
Status |
Binary on/off behavior parameters. |
Flow |
A single energy flow on a carrier. |
Effect |
A tracked quantity across the optimization horizon (cost, CO₂, …). |
Storage |
Energy storage with level dynamics. |
PiecewiseConversion |
Piecewise-linear conversion linking N flows. |
Functions:
| Name | Description |
|---|---|
qualified_id |
Format a qualified flow id: |
node_id |
Format a carrier-node id: |
Carrier
dataclass
¶
Carrier(
id: str,
nodes: list[str] = list(),
unit: str = 'MWh',
color: str | None = None,
description: str = '',
)
Physical energy medium (electricity, heat, gas, …).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
Unique identifier used as xarray coordinate. |
required |
|
list[str]
|
Sub-nodes for multi-node balancing. Empty means single-node. |
list()
|
|
str
|
Energy unit label. |
'MWh'
|
|
str | None
|
Optional color for plotting. |
None
|
|
str
|
Human-readable description. |
''
|
Sizing
dataclass
¶
Sizing(
min_size: float,
max_size: float,
mandatory: bool = True,
effects_per_size: dict[str, Variate] = dict(),
effects_fixed: dict[str, Variate] = dict(),
)
Capacity optimization parameters.
The solver decides the optimal size within [min_size, max_size].
mandatory=True: continuous, size in [min, max], no binary.mandatory=False: binary indicator gates size: 0 or [min, max].min_size == max_sizewithmandatory=False: binary invest at exact size (yes/no).
See: docs/math/sizing.md
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
float
|
Minimum capacity if invested. |
required |
|
float
|
Maximum capacity. |
required |
|
bool
|
If True, must be built (no binary indicator). |
True
|
|
dict[str, Variate]
|
Effect cost per unit size (e.g. €/MW). |
dict()
|
|
dict[str, Variate]
|
Fixed effect cost if built (optional only). |
dict()
|
Investment
dataclass
¶
Investment(
min_size: float,
max_size: float,
mandatory: bool = True,
lifetime: int | None = None,
prior_size: float = 0.0,
effects_per_size_at_build: dict[str, Variate] = dict(),
effects_fixed_at_build: dict[str, Variate] = dict(),
effects_per_size_recurring: dict[str, Variate] = dict(),
effects_fixed_recurring: dict[str, Variate] = dict(),
)
Singular discrete build-timing optimization.
The solver decides WHEN to build (which period) and at what size.
Once built, capacity is available for lifetime periods.
Size is decided once — no growth or partial retirement.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
float
|
Minimum capacity if built. |
required |
|
float
|
Maximum capacity. |
required |
|
bool
|
If True, must build exactly once; if False, may build at most once. |
True
|
|
int | None
|
Periods active after build; None = forever. |
None
|
|
float
|
Pre-existing capacity available from period 0. |
0.0
|
|
dict[str, Variate]
|
One-time per-MW costs charged in the build period. |
dict()
|
|
dict[str, Variate]
|
One-time fixed costs charged in the build period. |
dict()
|
|
dict[str, Variate]
|
Recurring per-MW costs charged every active period. |
dict()
|
|
dict[str, Variate]
|
Recurring fixed costs charged every active period. |
dict()
|
Status
dataclass
¶
Status(
min_uptime: float | None = None,
max_uptime: float | None = None,
min_downtime: float | None = None,
max_downtime: float | None = None,
effects_per_running_hour: dict[str, Variate] = dict(),
effects_per_startup: dict[str, Variate] = dict(),
)
Binary on/off behavior parameters.
Together with relative bounds, gives semi-continuous behavior:
{0} U [min, max] * size.
See: docs/math/status.md
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
float | None
|
Minimum consecutive on-hours. |
None
|
|
float | None
|
Maximum consecutive on-hours. |
None
|
|
float | None
|
Minimum consecutive off-hours. |
None
|
|
float | None
|
Maximum consecutive off-hours. |
None
|
|
dict[str, Variate]
|
Effect cost per running hour. |
dict()
|
|
dict[str, Variate]
|
Effect cost per startup event. |
dict()
|
Flow
dataclass
¶
Flow(
carrier: str,
short_id: str = '',
node: str | None = None,
size: float | Sizing | Investment | None = None,
relative_minimum: Variate = 0.0,
relative_maximum: Variate = 1.0,
fixed_relative_profile: Variate | None = None,
effects_per_flow_hour: dict[str, Variate] = dict(),
status: Status | None = None,
prior_rates: list[float] | None = None,
)
A single energy flow on a carrier.
short_id defaults to carrier (or carrier:node when node
is set). Set explicitly to disambiguate multiple flows on the same
carrier::
Flow('elec') # short_id='elec'
Flow('heat', node='A') # short_id='heat:A'
Flow('elec', short_id='base') # short_id='base'
short_id must be unique within a component. Storage renames
colliding short_ids to charge / discharge before qualification.
id is the qualified form set by the parent component:
component(short_id).
See: docs/math/flows.md
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
Carrier this flow connects to. |
required |
|
str
|
Component-local identifier; defaults to |
''
|
|
str | None
|
Sub-node for multi-node carrier balancing. |
None
|
|
float | Sizing | Investment | None
|
Nominal capacity [MW], |
None
|
|
Variate
|
Lower bound as fraction of size. |
0.0
|
|
Variate
|
Upper bound as fraction of size. |
1.0
|
|
Variate | None
|
Fixed profile as fraction of size; sets both lower and upper bounds equal to the profile value. |
None
|
|
dict[str, Variate]
|
Effect coefficients per flow-hour (e.g. €/MWh). |
dict()
|
|
Status | None
|
On/off behavior (semi-continuous, startup costs, durations). |
None
|
|
list[float] | None
|
Flow rates [MW] before the horizon, used for status initial conditions. |
None
|
Methods:
| Name | Description |
|---|---|
__post_init__ |
Default short_id from carrier/node, set id = short_id. |
__post_init__
¶
Default short_id from carrier/node, set id = short_id.
Source code in src/fluxopt/elements.py
Effect
dataclass
¶
Effect(
id: str,
unit: str = '',
maximum: float | None = None,
minimum: float | None = None,
maximum_per_period: float | None = None,
minimum_per_period: float | None = None,
maximum_per_hour: Variate | None = None,
minimum_per_hour: Variate | None = None,
contribution_from: dict[str, Variate] = dict(),
period_weights: list[float] | None = None,
)
A tracked quantity across the optimization horizon (cost, CO₂, …).
One effect is designated as the objective to minimize via the
objective_effects argument of optimize(). Others can be bounded
to enforce budgets (e.g. emission caps).
Effects accumulate contributions from two domains:
- Temporal — per-timestep flow costs, running costs, startup costs.
- Lump — one-time sizing costs and fixed costs.
Cross-effect chains (e.g. CO₂ → cost) are supported via
contribution_from.
See: docs/math/effects.md
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
Unique identifier. |
required |
|
str
|
Unit label (e.g. |
''
|
|
float | None
|
Upper bound on weighted total across all periods. |
None
|
|
float | None
|
Lower bound on weighted total across all periods. |
None
|
|
float | None
|
Upper bound applied to each period independently. |
None
|
|
float | None
|
Lower bound applied to each period independently. |
None
|
|
Variate | None
|
Upper bound rate [unit/h], scaled by Δt. |
None
|
|
Variate | None
|
Lower bound rate [unit/h], scaled by Δt. |
None
|
|
dict[str, Variate]
|
Cross-effect factors |
dict()
|
|
list[float] | None
|
Per-period weights ω for total aggregation;
overrides global |
None
|
Storage
dataclass
¶
Storage(
id: str,
charging: Flow,
discharging: Flow,
capacity: float | Sizing | Investment | None = None,
eta_charge: Variate = 1.0,
eta_discharge: Variate = 1.0,
relative_loss_per_hour: Variate = 0.0,
prior_level: float | None = None,
cyclic: bool = True,
relative_minimum_level: Variate = 0.0,
relative_maximum_level: Variate = 1.0,
status: Status | None = None,
)
Energy storage with level dynamics.
Flow ids are qualified as storage(flow). When both flows connect
to the same carrier, they are renamed to charge / discharge::
Storage('bat', Flow('elec'), Flow('elec')) # bat(charge), bat(discharge)
Storage('bat', Flow('elec'), Flow('heat')) # bat(elec), bat(heat)
Level balance::
E_{s,t+1} = E_{s,t} (1 - δ)^Δt + P^c η^c Δt - P^d / η^d Δt
See: docs/math/storage.md
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
Storage identifier. |
required |
|
Flow
|
Charging flow. |
required |
|
Flow
|
Discharging flow. |
required |
|
float | Sizing | Investment | None
|
Maximum stored energy [MWh], |
None
|
|
Variate
|
Charging efficiency. |
1.0
|
|
Variate
|
Discharging efficiency. |
1.0
|
|
Variate
|
Self-discharge rate [1/h]. |
0.0
|
|
float | None
|
Initial energy level [MWh]; None = unconstrained. |
None
|
|
bool
|
If True, end level must equal start level. |
True
|
|
Variate
|
Min SOC as fraction of capacity. |
0.0
|
|
Variate
|
Max SOC as fraction of capacity. |
1.0
|
|
Status | None
|
Component-level on/off behavior gating both charging and
discharging. Forbids flow-level |
None
|
Methods:
| Name | Description |
|---|---|
__post_init__ |
Validate carrier match, rename colliding flow ids, and qualify. |
__post_init__
¶
Validate carrier match, rename colliding flow ids, and qualify.
Source code in src/fluxopt/elements.py
PiecewiseConversion
dataclass
¶
PiecewiseConversion(
points: dict[str, list[Variate]] | list[_CurveTuple],
method: PiecewiseMethod = 'auto',
status: Status | None = None,
availability: Variate = 1.0,
)
Piecewise-linear conversion linking N flows.
Wraps :func:linopy.piecewise.add_piecewise_formulation. All flows
share interpolation weights — every operating point lies on the same
piece of the curve.
Two input forms:
-
Dict — equality-only, terse for the common case::
PiecewiseConversion({'fuel': [0, 50, 100], 'Heat': [0, 45, 70]})
-
List of tuples — supports per-flow inequality bounds::
PiecewiseConversion( [ ('fuel', [0, 50, 100]), ('Heat', [0, 45, 70], '>='), ] )
See: docs/math/converters.md
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
dict[str, list[Variate]] | list[_CurveTuple]
|
Per-flow breakpoints. Either |
required |
|
PiecewiseMethod
|
Formulation. |
'auto'
|
|
Status | None
|
Component-level on/off behavior gating the curve. |
None
|
|
Variate
|
Time-varying scaling of the upper breakpoint. |
1.0
|
Methods:
| Name | Description |
|---|---|
__post_init__ |
Validate normalized breakpoints and bound combinations. |
__post_init__
¶
Validate normalized breakpoints and bound combinations.