InvestParameters
InvestParameters
model investment decisions in optimization problems, enabling both binary (invest/don't invest) and continuous sizing choices with comprehensive cost modeling.
Investment Decision Types
FlixOpt supports two main types of investment decisions:
Binary Investment
Fixed-size investment creating a yes/no decision (e.g., install a 100 kW generator):
With: - \(v_\text{invest}\) being the resulting investment size - \(s_\text{invest} \in \{0, 1\}\) being the binary investment decision - \(\text{size}_\text{fixed}\) being the predefined component size
Behavior: - \(s_\text{invest} = 0\): no investment (\(v_\text{invest} = 0\)) - \(s_\text{invest} = 1\): invest at fixed size (\(v_\text{invest} = \text{size}_\text{fixed}\))
Continuous Sizing
Variable-size investment with bounds (e.g., battery capacity from 10-1000 kWh):
With: - \(v_\text{invest}\) being the investment size variable (continuous) - \(s_\text{invest} \in \{0, 1\}\) being the binary investment decision - \(\text{size}_\text{min}\) being the minimum investment size (if investing) - \(\text{size}_\text{max}\) being the maximum investment size
Behavior: - \(s_\text{invest} = 0\): no investment (\(v_\text{invest} = 0\)) - \(s_\text{invest} = 1\): invest with size in \([\text{size}_\text{min}, \text{size}_\text{max}]\)
This uses the bounds with state pattern described in Bounds and States.
Optional vs. Mandatory Investment
The mandatory
parameter controls whether investment is required:
Optional Investment (mandatory=False
, default):
$$\label{eq:invest_optional}
s_\text{invest} \in {0, 1}
$$
The optimization can freely choose to invest or not.
Mandatory Investment (mandatory=True
):
$$\label{eq:invest_mandatory}
s_\text{invest} = 1
$$
The investment must occur (useful for mandatory upgrades or replacements).
Effect Modeling
Investment effects (costs, emissions, etc.) are modeled using three components:
Fixed Effects
One-time effects incurred if investment is made, independent of size:
With: - \(E_{e,\text{fix}}\) being the fixed contribution to effect \(e\) - \(\text{fix}_e\) being the fixed effect value (e.g., fixed installation cost)
Examples: - Fixed installation costs (permits, grid connection) - One-time environmental impacts (land preparation) - Fixed labor or administrative costs
Specific Effects
Effects proportional to investment size (per-unit costs):
With: - \(E_{e,\text{spec}}\) being the size-dependent contribution to effect \(e\) - \(\text{spec}_e\) being the specific effect value per unit size (e.g., €/kW)
Examples: - Equipment costs (€/kW) - Material requirements (kg steel/kW) - Recurring costs (€/kW/year maintenance)
Piecewise Effects
Non-linear effect relationships using piecewise linear approximations:
Subject to: $$ v_\text{invest} = \sum_{k=1}^{K} \lambda_k \cdot v_k $$
With: - \(E_{e,\text{pw}}\) being the piecewise contribution to effect \(e\) - \(\lambda_k\) being the piecewise lambda variables (see Piecewise) - \(r_{e,k}\) being the effect rate at piece \(k\) - \(v_k\) being the size points defining the pieces
Use cases: - Economies of scale (bulk discounts) - Technology learning curves - Threshold effects (capacity tiers with different costs)
See Piecewise for detailed mathematical formulation.
Retirement Effects
Effects incurred if investment is NOT made (when retiring/not replacing existing equipment):
With: - \(E_{e,\text{retirement}}\) being the retirement contribution to effect \(e\) - \(\text{retirement}_e\) being the retirement effect value
Behavior: - \(s_\text{invest} = 0\): retirement effects are incurred - \(s_\text{invest} = 1\): no retirement effects
Examples: - Demolition or disposal costs - Decommissioning expenses - Contractual penalties for not investing - Opportunity costs or lost revenues
Total Investment Effects
The total contribution to effect \(e\) from an investment is:
Effects integrate into the overall system effects as described in Effects, Penalty & Objective.
Integration with Components
Investment parameters modify component sizing:
Without Investment
Component size is a fixed parameter: $$ \text{size} = \text{size}_\text{nominal} $$
With Investment
Component size becomes a variable: $$ \text{size} = v_\text{invest} $$
This size variable then appears in component constraints. For example, flow rate bounds become:
Using the scaled bounds pattern from Bounds and States.
Cost Annualization
Important: All investment cost values must be properly weighted to match the optimization model's time horizon.
For long-term investments, costs should be annualized:
With: - \(\text{cost}_\text{capital}\) being the upfront investment cost - \(r\) being the discount rate - \(n\) being the equipment lifetime in years
Example: €1,000,000 equipment with 20-year life and 5% discount rate $$ \text{cost}_\text{annual} = \frac{1{,}000{,}000 \cdot 0.05}{1 - (1.05)^{-20}} \approx €80{,}243/\text{year} $$
Implementation
Python Class: InvestParameters
Key Parameters:
- fixed_size
: For binary investments (mutually exclusive with continuous sizing)
- minimum_size
, maximum_size
: For continuous sizing
- mandatory
: Whether investment is required (default: False
)
- effects_of_investment
: Fixed effects incurred when investing (replaces deprecated fix_effects
)
- effects_of_investment_per_size
: Per-unit effects proportional to size (replaces deprecated specific_effects
)
- piecewise_effects_of_investment
: Non-linear effect modeling (replaces deprecated piecewise_effects
)
- effects_of_retirement
: Effects for not investing (replaces deprecated divest_effects
)
See the InvestParameters
API documentation for complete parameter list and usage examples.
Used in:
- Flow
- Flexible capacity decisions
- Storage
- Storage sizing optimization
- LinearConverter
- Converter capacity planning
- All components supporting investment decisions
Examples
Binary Investment (Solar Panels)
solar_investment = InvestParameters(
fixed_size=100, # 100 kW system
mandatory=False, # Optional investment (default)
effects_of_investment={'cost': 25000}, # Installation costs
effects_of_investment_per_size={'cost': 1200}, # €1200/kW
)
Continuous Sizing (Battery)
battery_investment = InvestParameters(
minimum_size=10, # kWh
maximum_size=1000,
mandatory=False, # Optional investment (default)
effects_of_investment={'cost': 5000}, # Grid connection
effects_of_investment_per_size={'cost': 600}, # €600/kWh
)
With Retirement Costs (Replacement)
boiler_replacement = InvestParameters(
minimum_size=50, # kW
maximum_size=200,
mandatory=False, # Optional investment (default)
effects_of_investment={'cost': 15000},
effects_of_investment_per_size={'cost': 400},
effects_of_retirement={'cost': 8000}, # Demolition if not replaced
)
Economies of Scale (Piecewise)
battery_investment = InvestParameters(
minimum_size=10,
maximum_size=1000,
piecewise_effects_of_investment=PiecewiseEffects(
piecewise_origin=Piecewise([
Piece(0, 100), # Small
Piece(100, 500), # Medium
Piece(500, 1000), # Large
]),
piecewise_shares={
'cost': Piecewise([
Piece(800, 750), # €800-750/kWh
Piece(750, 600), # €750-600/kWh
Piece(600, 500), # €600-500/kWh (bulk discount)
])
},
),
)