Effects & Dimensions¶
Effects track metrics (costs, CO₂, energy). Dimensions define the structure over which effects aggregate.
Defining Effects¶
costs = fx.Effect(label='costs', unit='€', is_objective=True)
co2 = fx.Effect(label='co2', unit='kg')
flow_system.add_elements(costs, co2)
One effect is the objective (minimized). Others are tracked or constrained.
Effect Types¶
Accumulated over timesteps — operational costs, emissions, energy:
- Per flow hour: \(E(t) = p(t) \cdot c \cdot \Delta t\)
- Per event (startup): \(E(t) = s^{start}(t) \cdot c\)
Time-independent — investment costs, fixed fees:
\(E_{per} = P \cdot c_{inv}\)
Sum of periodic and temporal components.
Where Effects Are Contributed¶
Dimensions¶
The model operates across three dimensions:
The basic time resolution — always required:
All variables and constraints are indexed by time. Temporal effects sum over timesteps.
Represent uncertainty (weather, prices). Operations vary per scenario, investments are shared:
flow_system = fx.FlowSystem(
timesteps=pd.date_range('2024-01-01', periods=8760, freq='h'),
scenarios=pd.Index(['sunny_year', 'cloudy_year']),
scenario_weights=[0.7, 0.3],
)
Scenarios are independent — no energy or information exchange between them.
Objective Function¶
The objective aggregates effects across all dimensions with weights:
Single period, no scenarios:
Investment decided once, operations weighted by probability:
- \(w_s\) — scenario weight (probability)
Multi-year planning with discounting:
- \(w_y\) — period weight (duration or discount factor)
Periods × Scenarios:
The penalty effect is always included: \(\min \quad E_{objective} + E_{penalty}\)
Weights¶
Provided explicitly — typically probabilities:
Default: equal weights, normalized to sum to 1.
Computed automatically from period index (interval sizes):
When both present:
\(w_{y,s} = w_y \cdot w_s\)
Constraints on Effects¶
Bound on aggregated effect (temporal + periodic) per period:
Cross-Effects¶
Effects can contribute to each other (e.g., carbon pricing):
co2 = fx.Effect(label='co2', unit='kg')
costs = fx.Effect(
label='costs', unit='€', is_objective=True,
share_from_temporal={'co2': 0.08}, # €80/tonne
)
Penalty Effect¶
A built-in Penalty effect enables soft constraints and prevents infeasibility:
fx.StatusParameters(effects_per_startup={'Penalty': 1})
fx.Bus(label='heat', excess_penalty_per_flow_hour=1e5)
Penalty is weighted identically to the objective effect across all dimensions.
Shared vs Independent Decisions¶
By default, investment decisions are shared across scenarios within a period:
- Build capacity once → operate differently per scenario
- Reflects real-world investment under uncertainty
By default, operational decisions are independent per scenario:
Use Cases¶
Limit total CO₂ emissions across all years:
Cap annual investment spending:
Track and limit peak power:
Add CO₂ cost to objective automatically:
Limit total land area for installations:
Reference¶
| Symbol | Type | Description |
|---|---|---|
| \(E_{temp}(t)\) | \(\mathbb{R}\) | Temporal effect at timestep \(t\) |
| \(E_{per}\) | \(\mathbb{R}\) | Periodic effect (per period) |
| \(E\) | \(\mathbb{R}\) | Total effect (\(E_{per} + \sum_t E_{temp}(t)\)) |
| \(w_s\) | \(\mathbb{R}_{\geq 0}\) | Scenario weight (probability) |
| \(w_y\) | \(\mathbb{R}_{> 0}\) | Period weight (duration/discount) |
| \(p(t)\) | \(\mathbb{R}_{\geq 0}\) | Flow rate at timestep \(t\) |
| \(s^{start}(t)\) | \(\{0, 1\}\) | Startup indicator |
| \(P\) | \(\mathbb{R}_{\geq 0}\) | Investment size |
| \(c\) | \(\mathbb{R}\) | Effect coefficient |
| \(\Delta t\) | \(\mathbb{R}_{> 0}\) | Timestep duration (hours) |
| Constraint | Python | Scope |
|---|---|---|
| Total limit | maximum_total | Per period |
| Timestep limit | maximum_per_hour | Each timestep |
| Periodic limit | maximum_periodic | Per period (periodic only) |
| Temporal limit | maximum_temporal | Per period (temporal only) |
| Global limit | maximum_over_periods | Across all periods |
Classes: Effect, EffectCollection