Note
You can download this example as a Jupyter notebook or start it in interactive mode.
Unit commitment#
This tutorial runs through examples of unit commitment for generators at a single bus. Examples of minimum part-load, minimum up time, minimum down time, start up costs, shut down costs and ramp rate restrictions are shown.
To enable unit commitment on a generator, set its attribute committable = True.
[1]:
import pandas as pd
import pypsa
Minimum part load demonstration#
In final hour load goes below part-load limit of coal gen (30%), forcing gas to commit.
[2]:
nu = pypsa.Network(snapshots=range(4))
nu.add("Bus", "bus")
nu.add(
"Generator",
"coal",
bus="bus",
committable=True,
p_min_pu=0.3,
marginal_cost=20,
p_nom=10000,
)
nu.add(
"Generator",
"gas",
bus="bus",
committable=True,
marginal_cost=70,
p_min_pu=0.1,
p_nom=1000,
)
nu.add("Load", "load", bus="bus", p_set=[4000, 6000, 5000, 800])
[3]:
nu.optimize()
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.03s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 32 primals, 36 duals
Objective: 3.56e+05
Solver model: available
Solver message: optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-status-min_up_time_must_stay_up were not assigned to the network.
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
Matrix [1e+00, 1e+04]
Cost [2e+01, 7e+01]
Bound [1e+00, 1e+00]
RHS [1e+00, 6e+03]
Presolving model
30 rows, 12 cols, 58 nonzeros 0s
0 rows, 3 cols, 0 nonzeros 0s
0 rows, 0 cols, 0 nonzeros 0s
Presolve: Optimal
Solving report
Status Optimal
Primal bound 356000
Dual bound 356000
Gap 0% (tolerance: 0.01%)
Solution status feasible
356000 (objective)
0 (bound viol.)
0 (int. viol.)
0 (row viol.)
Timing 0.00 (total)
0.00 (presolve)
0.00 (postsolve)
Nodes 0
LP iterations 0 (total)
0 (strong br.)
0 (separation)
0 (heuristics)
Writing the solution to /tmp/linopy-solve-4p6vqo4v.sol
[3]:
('ok', 'optimal')
[4]:
nu.generators_t.status
[4]:
| Generator-com | coal | gas |
|---|---|---|
| snapshot | ||
| 0 | 1.0 | 0.0 |
| 1 | 1.0 | 0.0 |
| 2 | 1.0 | 0.0 |
| 3 | 0.0 | 1.0 |
[5]:
nu.generators_t.p
[5]:
| Generator | coal | gas |
|---|---|---|
| snapshot | ||
| 0 | 4000.0 | 0.0 |
| 1 | 6000.0 | 0.0 |
| 2 | 5000.0 | 0.0 |
| 3 | 0.0 | 800.0 |
Minimum up time demonstration#
Gas has minimum up time, forcing it to be online longer
[6]:
nu = pypsa.Network(snapshots=range(4))
nu.add("Bus", "bus")
nu.add(
"Generator",
"coal",
bus="bus",
committable=True,
p_min_pu=0.3,
marginal_cost=20,
p_nom=10000,
)
nu.add(
"Generator",
"gas",
bus="bus",
committable=True,
marginal_cost=70,
p_min_pu=0.1,
up_time_before=0,
min_up_time=3,
p_nom=1000,
)
nu.add("Load", "load", bus="bus", p_set=[4000, 800, 5000, 3000])
[7]:
nu.optimize()
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.04s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 32 primals, 39 duals
Objective: 3.06e+05
Solver model: available
Solver message: optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-up-time, Generator-com-status-min_up_time_must_stay_up were not assigned to the network.
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
Matrix [1e+00, 1e+04]
Cost [2e+01, 7e+01]
Bound [1e+00, 1e+00]
RHS [1e+00, 5e+03]
Presolving model
33 rows, 16 cols, 73 nonzeros 0s
0 rows, 0 cols, 0 nonzeros 0s
Presolve: Optimal
Solving report
Status Optimal
Primal bound 306000
Dual bound 306000
Gap 0% (tolerance: 0.01%)
Solution status feasible
306000 (objective)
0 (bound viol.)
0 (int. viol.)
0 (row viol.)
Timing 0.00 (total)
0.00 (presolve)
0.00 (postsolve)
Nodes 0
LP iterations 0 (total)
0 (strong br.)
0 (separation)
0 (heuristics)
Writing the solution to /tmp/linopy-solve-dm28olvv.sol
[7]:
('ok', 'optimal')
[8]:
nu.generators_t.status
[8]:
| Generator-com | coal | gas |
|---|---|---|
| snapshot | ||
| 0 | 1.0 | 1.0 |
| 1 | 0.0 | 1.0 |
| 2 | 1.0 | 1.0 |
| 3 | 1.0 | 0.0 |
[9]:
nu.generators_t.p
[9]:
| Generator | coal | gas |
|---|---|---|
| snapshot | ||
| 0 | 3900.0 | 100.0 |
| 1 | 0.0 | 800.0 |
| 2 | 4900.0 | 100.0 |
| 3 | 3000.0 | -0.0 |
Minimum down time demonstration#
Coal has a minimum down time, forcing it to go off longer.
[10]:
nu = pypsa.Network(snapshots=range(4))
nu.add("Bus", "bus")
nu.add(
"Generator",
"coal",
bus="bus",
committable=True,
p_min_pu=0.3,
marginal_cost=20,
min_down_time=2,
down_time_before=1,
p_nom=10000,
)
nu.add(
"Generator",
"gas",
bus="bus",
committable=True,
marginal_cost=70,
p_min_pu=0.1,
p_nom=4000,
)
nu.add("Load", "load", bus="bus", p_set=[3000, 800, 3000, 8000])
[11]:
nu.optimize()
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following committable generators were both up and down before the simulation: Index(['coal'], dtype='object', name='Generator'). This could cause an infeasibility.
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following committable generators were both up and down before the simulation: Index(['coal'], dtype='object', name='Generator'). This could cause an infeasibility.
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.04s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 32 primals, 40 duals
Objective: 4.86e+05
Solver model: available
Solver message: optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-down-time, Generator-com-status-min_up_time_must_stay_up, Generator-com-status-min_down_time_must_stay_up were not assigned to the network.
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
Matrix [1e+00, 1e+04]
Cost [2e+01, 7e+01]
Bound [1e+00, 1e+00]
RHS [1e+00, 8e+03]
Presolving model
27 rows, 12 cols, 55 nonzeros 0s
4 rows, 4 cols, 8 nonzeros 0s
3 rows, 3 cols, 6 nonzeros 0s
2 rows, 2 cols, 4 nonzeros 0s
0 rows, 1 cols, 0 nonzeros 0s
0 rows, 0 cols, 0 nonzeros 0s
Presolve: Optimal
Solving report
Status Optimal
Primal bound 486000
Dual bound 486000
Gap 0% (tolerance: 0.01%)
Solution status feasible
486000 (objective)
0 (bound viol.)
0 (int. viol.)
0 (row viol.)
Timing 0.00 (total)
0.00 (presolve)
0.00 (postsolve)
Nodes 0
LP iterations 0 (total)
0 (strong br.)
0 (separation)
0 (heuristics)
Writing the solution to /tmp/linopy-solve-nowk1ot4.sol
[11]:
('ok', 'optimal')
[12]:
nu.objective
[12]:
486000.0
[13]:
nu.generators_t.status
[13]:
| Generator-com | coal | gas |
|---|---|---|
| snapshot | ||
| 0 | 0.0 | 1.0 |
| 1 | 0.0 | 1.0 |
| 2 | 1.0 | 0.0 |
| 3 | 1.0 | 0.0 |
[14]:
nu.generators_t.p
[14]:
| Generator | coal | gas |
|---|---|---|
| snapshot | ||
| 0 | 0.0 | 3000.0 |
| 1 | 0.0 | 800.0 |
| 2 | 3000.0 | 0.0 |
| 3 | 8000.0 | 0.0 |
Start up and shut down costs#
Now there are associated costs for shutting down, etc
[15]:
nu = pypsa.Network(snapshots=range(4))
nu.add("Bus", "bus")
nu.add(
"Generator",
"coal",
bus="bus",
committable=True,
p_min_pu=0.3,
marginal_cost=20,
min_down_time=2,
start_up_cost=5000,
p_nom=10000,
)
nu.add(
"Generator",
"gas",
bus="bus",
committable=True,
marginal_cost=70,
p_min_pu=0.1,
shut_down_cost=25,
p_nom=4000,
)
nu.add("Load", "load", bus="bus", p_set=[3000, 800, 3000, 8000])
[16]:
nu.optimize()
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.04s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 32 primals, 39 duals
Objective: 4.91e+05
Solver model: available
Solver message: optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-down-time, Generator-com-status-min_up_time_must_stay_up were not assigned to the network.
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
Matrix [1e+00, 1e+04]
Cost [2e+01, 5e+03]
Bound [1e+00, 1e+00]
RHS [1e+00, 8e+03]
Presolving model
33 rows, 23 cols, 78 nonzeros 0s
14 rows, 12 cols, 29 nonzeros 0s
10 rows, 10 cols, 21 nonzeros 0s
7 rows, 9 cols, 15 nonzeros 0s
6 rows, 7 cols, 12 nonzeros 0s
Objective function is integral with scale 0.04
Solving MIP model with:
6 rows
7 cols (7 binary, 0 integer, 0 implied int., 0 continuous)
12 nonzeros
Nodes | B&B Tree | Objective Bounds | Dynamic Constraints | Work
Proc. InQueue | Leaves Expl. | BestBound BestSol Gap | Cuts InLp Confl. | LpIters Time
0 0 0 0.00% 341050 inf inf 0 0 0 0 0.0s
Solving report
Status Optimal
Primal bound 491025
Dual bound 491025
Gap 0% (tolerance: 0.01%)
Solution status feasible
491025 (objective)
0 (bound viol.)
0 (int. viol.)
0 (row viol.)
Timing 0.00 (total)
0.00 (presolve)
0.00 (postsolve)
Nodes 1
LP iterations 0 (total)
0 (strong br.)
0 (separation)
0 (heuristics)
Writing the solution to /tmp/linopy-solve-4fjimtan.sol
[16]:
('ok', 'optimal')
[17]:
nu.objective
[17]:
491025.0
[18]:
nu.generators_t.status
[18]:
| Generator-com | coal | gas |
|---|---|---|
| snapshot | ||
| 0 | 0.0 | 1.0 |
| 1 | 0.0 | 1.0 |
| 2 | 1.0 | 0.0 |
| 3 | 1.0 | 0.0 |
[19]:
nu.generators_t.p
[19]:
| Generator | coal | gas |
|---|---|---|
| snapshot | ||
| 0 | 0.0 | 3000.0 |
| 1 | 0.0 | 800.0 |
| 2 | 3000.0 | 0.0 |
| 3 | 8000.0 | 0.0 |
Ramp rate limits#
[20]:
nu = pypsa.Network(snapshots=range(6))
nu.add("Bus", "bus")
nu.add(
"Generator",
"coal",
bus="bus",
marginal_cost=20,
ramp_limit_up=0.1,
ramp_limit_down=0.2,
p_nom=10000,
)
nu.add("Generator", "gas", bus="bus", marginal_cost=70, p_nom=4000)
nu.add("Load", "load", bus="bus", p_set=[4000, 7000, 7000, 7000, 7000, 3000])
[21]:
nu.optimize()
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.03s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 12 primals, 40 duals
Objective: 9.50e+05
Solver model: available
Solver message: optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper, Generator-fix-p-ramp_limit_up, Generator-fix-p-ramp_limit_down were not assigned to the network.
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
Matrix [1e+00, 1e+00]
Cost [2e+01, 7e+01]
Bound [0e+00, 0e+00]
RHS [1e+03, 1e+04]
Presolving model
10 rows, 6 cols, 20 nonzeros 0s
2 rows, 3 cols, 4 nonzeros 0s
2 rows, 3 cols, 4 nonzeros 0s
Presolve : Reductions: rows 2(-38); columns 3(-9); elements 4(-52)
Solving the presolved LP
Using EKK dual simplex solver - serial
Iteration Objective Infeasibilities num(sum)
0 0.0000000000e+00 Ph1: 0(0) 0s
0 9.5000000000e+05 Pr: 0(0) 0s
Solving the original LP from the solution after postsolve
Model status : Optimal
Objective value : 9.5000000000e+05
HiGHS run time : 0.00
Writing the solution to /tmp/linopy-solve-0aoj30y8.sol
[21]:
('ok', 'optimal')
[22]:
nu.generators_t.p
[22]:
| Generator | coal | gas |
|---|---|---|
| snapshot | ||
| 0 | 4000.0 | -0.0 |
| 1 | 5000.0 | 2000.0 |
| 2 | 6000.0 | 1000.0 |
| 3 | 7000.0 | -0.0 |
| 4 | 5000.0 | 2000.0 |
| 5 | 3000.0 | -0.0 |
[23]:
nu = pypsa.Network(snapshots=range(6))
nu.add("Bus", "bus")
nu.add(
"Generator",
"coal",
bus="bus",
marginal_cost=20,
ramp_limit_up=0.1,
ramp_limit_down=0.2,
p_nom_extendable=True,
capital_cost=1e2,
)
nu.add("Generator", "gas", bus="bus", marginal_cost=70, p_nom=4000)
nu.add("Load", "load", bus="bus", p_set=[4000, 7000, 7000, 7000, 7000, 3000])
[24]:
nu.optimize()
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.04s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 13 primals, 41 duals
Objective: 1.68e+06
Solver model: available
Solver message: optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper, Generator-ext-p-lower, Generator-ext-p-upper, Generator-ext-p-ramp_limit_up, Generator-ext-p-ramp_limit_down were not assigned to the network.
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
Matrix [1e-01, 1e+00]
Cost [2e+01, 1e+02]
Bound [0e+00, 0e+00]
RHS [3e+03, 7e+03]
Presolving model
16 rows, 7 cols, 42 nonzeros 0s
14 rows, 6 cols, 36 nonzeros 0s
Presolve : Reductions: rows 14(-27); columns 6(-7); elements 36(-37)
Solving the presolved LP
Using EKK dual simplex solver - serial
Iteration Objective Infeasibilities num(sum)
0 0.0000000000e+00 Ph1: 0(0) 0s
6 1.6750000000e+06 Pr: 0(0) 0s
Solving the original LP from the solution after postsolve
Model status : Optimal
Simplex iterations: 6
Objective value : 1.6750000000e+06
HiGHS run time : 0.00
Writing the solution to /tmp/linopy-solve-jofopmts.sol
[24]:
('ok', 'optimal')
[25]:
nu.generators.p_nom_opt
[25]:
Generator
coal 5000.0
gas 4000.0
Name: p_nom_opt, dtype: float64
[26]:
nu.generators_t.p
[26]:
| Generator | coal | gas |
|---|---|---|
| snapshot | ||
| 0 | 4000.0 | -0.0 |
| 1 | 4500.0 | 2500.0 |
| 2 | 5000.0 | 2000.0 |
| 3 | 5000.0 | 2000.0 |
| 4 | 4000.0 | 3000.0 |
| 5 | 3000.0 | -0.0 |
[27]:
nu = pypsa.Network(snapshots=range(7))
nu.add("Bus", "bus")
# Can get bad interactions if SU > RU and p_min_pu; similarly if SD > RD
nu.add(
"Generator",
"coal",
bus="bus",
marginal_cost=20,
committable=True,
p_min_pu=0.05,
initial_status=0,
ramp_limit_start_up=0.1,
ramp_limit_up=0.2,
ramp_limit_down=0.25,
ramp_limit_shut_down=0.15,
p_nom=10000.0,
)
nu.add("Generator", "gas", bus="bus", marginal_cost=70, p_nom=10000)
nu.add("Load", "load", bus="bus", p_set=[0.0, 200.0, 7000, 7000, 7000, 2000, 0])
WARNING:pypsa.components:Generator has no attribute initial_status, ignoring this passed value.
[28]:
nu.optimize()
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.05s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 35 primals, 61 duals
Objective: 1.15e+06
Solver model: available
Solver message: optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper, Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-status-min_up_time_must_stay_up, Generator-com-p-ramp_limit_up, Generator-com-p-ramp_limit_down were not assigned to the network.
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
Matrix [1e+00, 1e+04]
Cost [2e+01, 7e+01]
Bound [1e+00, 1e+00]
RHS [1e+00, 1e+04]
Presolving model
39 rows, 14 cols, 101 nonzeros 0s
14 rows, 8 cols, 40 nonzeros 0s
14 rows, 8 cols, 40 nonzeros 0s
Solving MIP model with:
14 rows
8 cols (4 binary, 0 integer, 0 implied int., 4 continuous)
40 nonzeros
Nodes | B&B Tree | Objective Bounds | Dynamic Constraints | Work
Proc. InQueue | Leaves Expl. | BestBound BestSol Gap | Cuts InLp Confl. | LpIters Time
0 0 0 0.00% 1124000 inf inf 0 0 0 0 0.0s
T 0 0 0 0.00% 1124000 1149000 2.18% 0 0 0 2 0.0s
Solving report
Status Optimal
Primal bound 1149000
Dual bound 1149000
Gap 0% (tolerance: 0.01%)
Solution status feasible
1149000 (objective)
0 (bound viol.)
0 (int. viol.)
0 (row viol.)
Timing 0.00 (total)
0.00 (presolve)
0.00 (postsolve)
Nodes 1
LP iterations 2 (total)
0 (strong br.)
0 (separation)
0 (heuristics)
Writing the solution to /tmp/linopy-solve-ws0yxfhy.sol
[28]:
('ok', 'optimal')
[29]:
nu.generators_t.p
[29]:
| Generator | coal | gas |
|---|---|---|
| snapshot | ||
| 0 | 0.0 | 0.0 |
| 1 | 0.0 | 200.0 |
| 2 | 1000.0 | 6000.0 |
| 3 | 3000.0 | 4000.0 |
| 4 | 4000.0 | 3000.0 |
| 5 | 1500.0 | 500.0 |
| 6 | 0.0 | 0.0 |
[30]:
nu.generators_t.status
[30]:
| Generator-com | coal |
|---|---|
| snapshot | |
| 0 | 0.0 |
| 1 | 0.0 |
| 2 | 1.0 |
| 3 | 1.0 |
| 4 | 1.0 |
| 5 | 1.0 |
| 6 | 0.0 |
[31]:
nu.generators.loc["coal"]
[31]:
attribute
bus bus
control PQ
type
p_nom 10000.0
p_nom_mod 0.0
p_nom_extendable False
p_nom_min 0.0
p_nom_max inf
p_min_pu 0.05
p_max_pu 1.0
p_set 0.0
q_set 0.0
sign 1.0
carrier
marginal_cost 20.0
marginal_cost_quadratic 0.0
build_year 0
lifetime inf
capital_cost 0.0
efficiency 1.0
committable True
start_up_cost 0.0
shut_down_cost 0.0
stand_by_cost 0.0
min_up_time 0
min_down_time 0
up_time_before 1
down_time_before 0
ramp_limit_up 0.2
ramp_limit_down 0.25
ramp_limit_start_up 0.1
ramp_limit_shut_down 0.15
weight 1.0
p_nom_opt 10000.0
Name: coal, dtype: object
Rolling horizon example#
This example solves sequentially in batches
[32]:
sets_of_snapshots = 6
p_set = [4000, 5000, 700, 800, 4000]
nu = pypsa.Network(snapshots=range(len(p_set) * sets_of_snapshots))
nu.add("Bus", "bus")
nu.add(
"Generator",
"coal",
bus="bus",
committable=True,
p_min_pu=0.3,
marginal_cost=20,
min_down_time=2,
min_up_time=3,
up_time_before=1,
ramp_limit_up=1,
ramp_limit_down=1,
ramp_limit_start_up=1,
ramp_limit_shut_down=1,
shut_down_cost=150,
start_up_cost=200,
p_nom=10000,
)
nu.add(
"Generator",
"gas",
bus="bus",
committable=True,
marginal_cost=70,
p_min_pu=0.1,
up_time_before=2,
min_up_time=3,
shut_down_cost=20,
start_up_cost=50,
p_nom=1000,
)
nu.add("Load", "load", bus="bus", p_set=p_set * sets_of_snapshots)
[33]:
overlap = 2
for i in range(sets_of_snapshots):
nu.optimize(nu.snapshots[i * len(p_set) : (i + 1) * len(p_set) + overlap])
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.05s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 56 primals, 96 duals
Objective: 5.55e+05
Solver model: available
Solver message: optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-up-time, Generator-com-down-time, Generator-com-status-min_up_time_must_stay_up, Generator-com-p-ramp_limit_up, Generator-com-p-ramp_limit_down were not assigned to the network.
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
Matrix [1e+00, 1e+04]
Cost [2e+01, 2e+02]
Bound [1e+00, 1e+00]
RHS [1e+00, 5e+03]
Presolving model
69 rows, 39 cols, 185 nonzeros 0s
55 rows, 35 cols, 150 nonzeros 0s
54 rows, 18 cols, 61 nonzeros 0s
9 rows, 10 cols, 23 nonzeros 0s
9 rows, 10 cols, 23 nonzeros 0s
Objective function is integral with scale 0.1
Solving MIP model with:
9 rows
10 cols (10 binary, 0 integer, 0 implied int., 0 continuous)
23 nonzeros
Nodes | B&B Tree | Objective Bounds | Dynamic Constraints | Work
Proc. InQueue | Leaves Expl. | BestBound BestSol Gap | Cuts InLp Confl. | LpIters Time
0 0 0 0.00% 550440 inf inf 0 0 0 0 0.0s
Solving report
Status Optimal
Primal bound 555370
Dual bound 555370
Gap 0% (tolerance: 0.01%)
Solution status feasible
555370 (objective)
0 (bound viol.)
0 (int. viol.)
0 (row viol.)
Timing 0.00 (total)
0.00 (presolve)
0.00 (postsolve)
Nodes 1
LP iterations 0 (total)
0 (strong br.)
0 (separation)
0 (heuristics)
Writing the solution to /tmp/linopy-solve-w62016ig.sol
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.05s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 56 primals, 97 duals
Objective: 5.50e+05
Solver model: available
Solver message: optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-up-time, Generator-com-down-time, Generator-com-status-min_up_time_must_stay_up, Generator-com-p-ramp_limit_up, Generator-com-p-ramp_limit_down were not assigned to the network.
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
Matrix [1e+00, 1e+04]
Cost [2e+01, 2e+02]
Bound [1e+00, 1e+00]
RHS [1e+00, 6e+03]
Presolving model
72 rows, 42 cols, 195 nonzeros 0s
57 rows, 37 cols, 160 nonzeros 0s
55 rows, 19 cols, 66 nonzeros 0s
12 rows, 12 cols, 32 nonzeros 0s
9 rows, 11 cols, 24 nonzeros 0s
8 rows, 9 cols, 21 nonzeros 0s
Objective function is integral with scale 0.1
Solving MIP model with:
8 rows
9 cols (9 binary, 0 integer, 0 implied int., 0 continuous)
21 nonzeros
Nodes | B&B Tree | Objective Bounds | Dynamic Constraints | Work
Proc. InQueue | Leaves Expl. | BestBound BestSol Gap | Cuts InLp Confl. | LpIters Time
0 0 0 0.00% 545420 inf inf 0 0 0 0 0.0s
Solving report
Status Optimal
Primal bound 550420
Dual bound 550420
Gap 0% (tolerance: 0.01%)
Solution status feasible
550420 (objective)
0 (bound viol.)
0 (int. viol.)
0 (row viol.)
Timing 0.00 (total)
0.00 (presolve)
0.00 (postsolve)
Nodes 1
LP iterations 1 (total)
0 (strong br.)
0 (separation)
0 (heuristics)
Writing the solution to /tmp/linopy-solve-3o9c0nva.sol
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.05s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 56 primals, 97 duals
Objective: 5.50e+05
Solver model: available
Solver message: optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-up-time, Generator-com-down-time, Generator-com-status-min_up_time_must_stay_up, Generator-com-p-ramp_limit_up, Generator-com-p-ramp_limit_down were not assigned to the network.
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
Matrix [1e+00, 1e+04]
Cost [2e+01, 2e+02]
Bound [1e+00, 1e+00]
RHS [1e+00, 6e+03]
Presolving model
72 rows, 42 cols, 193 nonzeros 0s
58 rows, 38 cols, 160 nonzeros 0s
57 rows, 21 cols, 71 nonzeros 0s
14 rows, 13 cols, 35 nonzeros 0s
12 rows, 13 cols, 31 nonzeros 0s
Objective function is integral with scale 0.1
Solving MIP model with:
12 rows
13 cols (13 binary, 0 integer, 0 implied int., 0 continuous)
31 nonzeros
Nodes | B&B Tree | Objective Bounds | Dynamic Constraints | Work
Proc. InQueue | Leaves Expl. | BestBound BestSol Gap | Cuts InLp Confl. | LpIters Time
0 0 0 0.00% 545440 inf inf 0 0 0 0 0.0s
T 0 0 0 0.00% 545440 550440 0.91% 0 0 0 3 0.0s
Solving report
Status Optimal
Primal bound 550440
Dual bound 550440
Gap 0% (tolerance: 0.01%)
Solution status feasible
550440 (objective)
0 (bound viol.)
0 (int. viol.)
0 (row viol.)
Timing 0.00 (total)
0.00 (presolve)
0.00 (postsolve)
Nodes 1
LP iterations 3 (total)
0 (strong br.)
0 (separation)
0 (heuristics)
Writing the solution to /tmp/linopy-solve-ohzhyhvn.sol
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.05s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 56 primals, 97 duals
Objective: 5.50e+05
Solver model: available
Solver message: optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-up-time, Generator-com-down-time, Generator-com-status-min_up_time_must_stay_up, Generator-com-p-ramp_limit_up, Generator-com-p-ramp_limit_down were not assigned to the network.
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
Matrix [1e+00, 1e+04]
Cost [2e+01, 2e+02]
Bound [1e+00, 1e+00]
RHS [1e+00, 6e+03]
Presolving model
72 rows, 42 cols, 195 nonzeros 0s
57 rows, 37 cols, 160 nonzeros 0s
55 rows, 19 cols, 66 nonzeros 0s
12 rows, 12 cols, 32 nonzeros 0s
9 rows, 11 cols, 24 nonzeros 0s
8 rows, 9 cols, 21 nonzeros 0s
Objective function is integral with scale 0.1
Solving MIP model with:
8 rows
9 cols (9 binary, 0 integer, 0 implied int., 0 continuous)
21 nonzeros
Nodes | B&B Tree | Objective Bounds | Dynamic Constraints | Work
Proc. InQueue | Leaves Expl. | BestBound BestSol Gap | Cuts InLp Confl. | LpIters Time
0 0 0 0.00% 545420 inf inf 0 0 0 0 0.0s
Solving report
Status Optimal
Primal bound 550420
Dual bound 550420
Gap 0% (tolerance: 0.01%)
Solution status feasible
550420 (objective)
0 (bound viol.)
0 (int. viol.)
0 (row viol.)
Timing 0.00 (total)
0.00 (presolve)
0.00 (postsolve)
Nodes 1
LP iterations 1 (total)
0 (strong br.)
0 (separation)
0 (heuristics)
Writing the solution to /tmp/linopy-solve-jec8plrm.sol
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.05s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 56 primals, 97 duals
Objective: 5.50e+05
Solver model: available
Solver message: optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-up-time, Generator-com-down-time, Generator-com-status-min_up_time_must_stay_up, Generator-com-p-ramp_limit_up, Generator-com-p-ramp_limit_down were not assigned to the network.
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
Matrix [1e+00, 1e+04]
Cost [2e+01, 2e+02]
Bound [1e+00, 1e+00]
RHS [1e+00, 6e+03]
Presolving model
72 rows, 42 cols, 193 nonzeros 0s
58 rows, 38 cols, 160 nonzeros 0s
57 rows, 21 cols, 71 nonzeros 0s
14 rows, 13 cols, 35 nonzeros 0s
12 rows, 13 cols, 31 nonzeros 0s
Objective function is integral with scale 0.1
Solving MIP model with:
12 rows
13 cols (13 binary, 0 integer, 0 implied int., 0 continuous)
31 nonzeros
Nodes | B&B Tree | Objective Bounds | Dynamic Constraints | Work
Proc. InQueue | Leaves Expl. | BestBound BestSol Gap | Cuts InLp Confl. | LpIters Time
0 0 0 0.00% 545440 inf inf 0 0 0 0 0.0s
T 0 0 0 0.00% 545440 550440 0.91% 0 0 0 3 0.0s
Solving report
Status Optimal
Primal bound 550440
Dual bound 550440
Gap 0% (tolerance: 0.01%)
Solution status feasible
550440 (objective)
0 (bound viol.)
0 (int. viol.)
0 (row viol.)
Timing 0.00 (total)
0.00 (presolve)
0.00 (postsolve)
Nodes 1
LP iterations 3 (total)
0 (strong br.)
0 (separation)
0 (heuristics)
Writing the solution to /tmp/linopy-solve-x81j3lbi.sol
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.05s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 40 primals, 69 duals
Objective: 3.70e+05
Solver model: available
Solver message: optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-up-time, Generator-com-down-time, Generator-com-status-min_up_time_must_stay_up, Generator-com-p-ramp_limit_up, Generator-com-p-ramp_limit_down were not assigned to the network.
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
Matrix [1e+00, 1e+04]
Cost [2e+01, 2e+02]
Bound [1e+00, 1e+00]
RHS [1e+00, 6e+03]
Presolving model
46 rows, 28 cols, 121 nonzeros 0s
34 rows, 23 cols, 93 nonzeros 0s
32 rows, 11 cols, 30 nonzeros 0s
6 rows, 6 cols, 15 nonzeros 0s
3 rows, 5 cols, 7 nonzeros 0s
2 rows, 3 cols, 4 nonzeros 0s
0 rows, 0 cols, 0 nonzeros 0s
Presolve: Optimal
Solving report
Status Optimal
Primal bound 370400
Dual bound 370400
Gap 0% (tolerance: 0.01%)
Solution status feasible
370400 (objective)
0 (bound viol.)
0 (int. viol.)
0 (row viol.)
Timing 0.00 (total)
0.00 (presolve)
0.00 (postsolve)
Nodes 0
LP iterations 0 (total)
0 (strong br.)
0 (separation)
0 (heuristics)
Writing the solution to /tmp/linopy-solve-5kk5258i.sol
[34]:
pd.concat(
{"Active": nu.generators_t.status.astype(bool), "Output": nu.generators_t.p}, axis=1
)
[34]:
| Active | Output | |||
|---|---|---|---|---|
| Generator-com | coal | gas | coal | gas |
| snapshot | ||||
| 0 | True | True | 3900.0 | 100.0 |
| 1 | True | True | 4900.0 | 100.0 |
| 2 | False | True | 0.0 | 700.0 |
| 3 | False | True | 0.0 | 800.0 |
| 4 | True | False | 4000.0 | 0.0 |
| 5 | True | False | 4000.0 | 0.0 |
| 6 | True | False | 5000.0 | 0.0 |
| 7 | False | True | 0.0 | 700.0 |
| 8 | False | True | 0.0 | 800.0 |
| 9 | True | True | 3900.0 | 100.0 |
| 10 | True | False | 4000.0 | 0.0 |
| 11 | True | True | 4900.0 | 100.0 |
| 12 | False | True | 0.0 | 700.0 |
| 13 | False | True | 0.0 | 800.0 |
| 14 | True | False | 4000.0 | 0.0 |
| 15 | True | False | 4000.0 | 0.0 |
| 16 | True | False | 5000.0 | 0.0 |
| 17 | False | True | 0.0 | 700.0 |
| 18 | False | True | 0.0 | 800.0 |
| 19 | True | True | 3900.0 | 100.0 |
| 20 | True | False | 4000.0 | 0.0 |
| 21 | True | True | 4900.0 | 100.0 |
| 22 | False | True | 0.0 | 700.0 |
| 23 | False | True | 0.0 | 800.0 |
| 24 | True | False | 4000.0 | 0.0 |
| 25 | True | False | 4000.0 | 0.0 |
| 26 | True | False | 5000.0 | 0.0 |
| 27 | False | True | 0.0 | 700.0 |
| 28 | False | True | 0.0 | 800.0 |
| 29 | True | True | 3900.0 | 100.0 |