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 pypsa
import pandas as pd
ERROR 1: PROJ: proj_create_from_database: Open of /home/docs/checkouts/readthedocs.org/user_builds/pypsa/conda/v0.26.0/share/proj failed
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()
INFO:linopy.model: Solve problem using Glpk solver
INFO:linopy.io: Writing time: 0.03s
WARNING:linopy.solvers:Dual values of MILP couldn't be parsed
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 32 primals, 0 duals
Objective: 3.56e+05
Solver model: not available
Solver message: integer optimal
INFO:pypsa.optimization.optimize:No shadow prices were assigned to the network.
GLPSOL--GLPK LP/MIP Solver 5.0
Parameter(s) specified in the command line:
--lp /tmp/linopy-problem-qn8jbces.lp --output /tmp/linopy-solve-231n_coo.sol
Reading problem data from '/tmp/linopy-problem-qn8jbces.lp'...
36 rows, 32 columns, 84 non-zeros
24 integer variables, all of which are binary
244 lines were read
GLPK Integer Optimizer 5.0
36 rows, 32 columns, 84 non-zeros
24 integer variables, all of which are binary
Preprocessing...
2 hidden packing inequaliti(es) were detected
18 rows, 15 columns, 37 non-zeros
9 integer variables, all of which are binary
Scaling...
A: min|aij| = 1.000e+00 max|aij| = 1.000e+03 ratio = 1.000e+03
GM: min|aij| = 5.623e-01 max|aij| = 1.778e+00 ratio = 3.162e+00
EQ: min|aij| = 3.162e-01 max|aij| = 1.000e+00 ratio = 3.162e+00
2N: min|aij| = 1.953e-01 max|aij| = 1.000e+00 ratio = 5.120e+00
Constructing initial basis...
Size of triangular part is 18
Solving LP relaxation...
GLPK Simplex Optimizer 5.0
18 rows, 15 columns, 37 non-zeros
0: obj = 5.060000000e+05 inf = 7.888e+01 (5)
5: obj = 5.060000000e+05 inf = 0.000e+00 (0)
* 11: obj = 3.560000000e+05 inf = 0.000e+00 (0)
OPTIMAL LP SOLUTION FOUND
Integer optimization begins...
Long-step dual simplex will be used
+ 11: mip = not found yet >= -inf (1; 0)
+ 11: >>>>> 3.560000000e+05 >= 3.560000000e+05 0.0% (1; 0)
+ 11: mip = 3.560000000e+05 >= tree is empty 0.0% (0; 1)
INTEGER OPTIMAL SOLUTION FOUND
Time used: 0.0 secs
Memory used: 0.1 Mb (78551 bytes)
Writing MIP solution to '/tmp/linopy-solve-231n_coo.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()
INFO:linopy.model: Solve problem using Glpk solver
INFO:linopy.io: Writing time: 0.03s
WARNING:linopy.solvers:Dual values of MILP couldn't be parsed
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 32 primals, 0 duals
Objective: 3.06e+05
Solver model: not available
Solver message: integer optimal
INFO:pypsa.optimization.optimize:No shadow prices were assigned to the network.
GLPSOL--GLPK LP/MIP Solver 5.0
Parameter(s) specified in the command line:
--lp /tmp/linopy-problem-tzxxlmeh.lp --output /tmp/linopy-solve-mga2enn0.sol
Reading problem data from '/tmp/linopy-problem-tzxxlmeh.lp'...
39 rows, 32 columns, 95 non-zeros
24 integer variables, all of which are binary
263 lines were read
GLPK Integer Optimizer 5.0
39 rows, 32 columns, 95 non-zeros
24 integer variables, all of which are binary
Preprocessing...
2 rows, 2 columns, 2 non-zeros
0 integer variables, none of which are binary
Scaling...
A: min|aij| = 1.000e+00 max|aij| = 1.000e+00 ratio = 1.000e+00
Problem data seem to be well scaled
Constructing initial basis...
Size of triangular part is 2
Solving LP relaxation...
GLPK Simplex Optimizer 5.0
2 rows, 2 columns, 2 non-zeros
* 0: obj = 3.960000000e+05 inf = 0.000e+00 (2)
* 2: obj = 3.060000000e+05 inf = 0.000e+00 (0)
OPTIMAL LP SOLUTION FOUND
Integer optimization begins...
Long-step dual simplex will be used
+ 2: mip = not found yet >= -inf (1; 0)
+ 2: >>>>> 3.060000000e+05 >= 3.060000000e+05 0.0% (1; 0)
+ 2: mip = 3.060000000e+05 >= tree is empty 0.0% (0; 1)
INTEGER OPTIMAL SOLUTION FOUND
Time used: 0.0 secs
Memory used: 0.1 Mb (68056 bytes)
Writing MIP solution to '/tmp/linopy-solve-mga2enn0.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.components: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.components: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 Glpk solver
INFO:linopy.io: Writing time: 0.04s
WARNING:linopy.solvers:Dual values of MILP couldn't be parsed
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 32 primals, 0 duals
Objective: 4.86e+05
Solver model: not available
Solver message: integer optimal
INFO:pypsa.optimization.optimize:No shadow prices were assigned to the network.
GLPSOL--GLPK LP/MIP Solver 5.0
Parameter(s) specified in the command line:
--lp /tmp/linopy-problem-9c9niqo1.lp --output /tmp/linopy-solve-g4os76_u.sol
Reading problem data from '/tmp/linopy-problem-9c9niqo1.lp'...
40 rows, 32 columns, 94 non-zeros
24 integer variables, all of which are binary
264 lines were read
GLPK Integer Optimizer 5.0
40 rows, 32 columns, 94 non-zeros
24 integer variables, all of which are binary
Preprocessing...
3 hidden packing inequaliti(es) were detected
1 constraint coefficient(s) were reduced
14 rows, 12 columns, 29 non-zeros
8 integer variables, all of which are binary
Scaling...
A: min|aij| = 1.000e+00 max|aij| = 4.000e+03 ratio = 4.000e+03
GM: min|aij| = 5.623e-01 max|aij| = 1.778e+00 ratio = 3.162e+00
EQ: min|aij| = 3.162e-01 max|aij| = 1.000e+00 ratio = 3.162e+00
2N: min|aij| = 1.953e-01 max|aij| = 1.000e+00 ratio = 5.120e+00
Constructing initial basis...
Size of triangular part is 14
Solving LP relaxation...
GLPK Simplex Optimizer 5.0
14 rows, 12 columns, 29 non-zeros
0: obj = 8.360000000e+05 inf = 1.062e+02 (4)
5: obj = 8.360000000e+05 inf = 0.000e+00 (0)
* 10: obj = 4.860000000e+05 inf = 0.000e+00 (0)
OPTIMAL LP SOLUTION FOUND
Integer optimization begins...
Long-step dual simplex will be used
+ 10: mip = not found yet >= -inf (1; 0)
+ 10: >>>>> 4.860000000e+05 >= 4.860000000e+05 0.0% (1; 0)
+ 10: mip = 4.860000000e+05 >= tree is empty 0.0% (0; 1)
INTEGER OPTIMAL SOLUTION FOUND
Time used: 0.0 secs
Memory used: 0.1 Mb (76022 bytes)
Writing MIP solution to '/tmp/linopy-solve-g4os76_u.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()
INFO:linopy.model: Solve problem using Glpk solver
INFO:linopy.io: Writing time: 0.03s
WARNING:linopy.solvers:Dual values of MILP couldn't be parsed
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 32 primals, 0 duals
Objective: 4.91e+05
Solver model: not available
Solver message: integer optimal
INFO:pypsa.optimization.optimize:No shadow prices were assigned to the network.
GLPSOL--GLPK LP/MIP Solver 5.0
Parameter(s) specified in the command line:
--lp /tmp/linopy-problem-rko0sj0b.lp --output /tmp/linopy-solve-siiflls0.sol
Reading problem data from '/tmp/linopy-problem-rko0sj0b.lp'...
39 rows, 32 columns, 93 non-zeros
24 integer variables, all of which are binary
269 lines were read
GLPK Integer Optimizer 5.0
39 rows, 32 columns, 93 non-zeros
24 integer variables, all of which are binary
Preprocessing...
7 hidden packing inequaliti(es) were detected
2 constraint coefficient(s) were reduced
25 rows, 20 columns, 51 non-zeros
14 integer variables, all of which are binary
Scaling...
A: min|aij| = 1.000e+00 max|aij| = 4.000e+03 ratio = 4.000e+03
GM: min|aij| = 5.623e-01 max|aij| = 1.778e+00 ratio = 3.162e+00
EQ: min|aij| = 3.162e-01 max|aij| = 1.000e+00 ratio = 3.162e+00
2N: min|aij| = 1.953e-01 max|aij| = 1.000e+00 ratio = 5.120e+00
Constructing initial basis...
Size of triangular part is 25
Solving LP relaxation...
GLPK Simplex Optimizer 5.0
25 rows, 20 columns, 51 non-zeros
0: obj = 8.360000000e+05 inf = 1.579e+02 (8)
9: obj = 8.410312500e+05 inf = 0.000e+00 (0)
* 25: obj = 4.910250000e+05 inf = 0.000e+00 (0)
OPTIMAL LP SOLUTION FOUND
Integer optimization begins...
Long-step dual simplex will be used
+ 25: mip = not found yet >= -inf (1; 0)
+ 26: >>>>> 4.910250000e+05 >= 4.910250000e+05 0.0% (2; 0)
+ 26: mip = 4.910250000e+05 >= tree is empty 0.0% (0; 3)
INTEGER OPTIMAL SOLUTION FOUND
Time used: 0.0 secs
Memory used: 0.1 Mb (94710 bytes)
Writing MIP solution to '/tmp/linopy-solve-siiflls0.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()
INFO:linopy.model: Solve problem using Glpk solver
INFO:linopy.io: Writing time: 0.02s
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 12 primals, 40 duals
Objective: 9.50e+05
Solver model: not 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.
GLPSOL--GLPK LP/MIP Solver 5.0
Parameter(s) specified in the command line:
--lp /tmp/linopy-problem-w0tbz3zi.lp --output /tmp/linopy-solve-ur7uwtuy.sol
Reading problem data from '/tmp/linopy-problem-w0tbz3zi.lp'...
40 rows, 12 columns, 56 non-zeros
208 lines were read
GLPK Simplex Optimizer 5.0
40 rows, 12 columns, 56 non-zeros
Preprocessing...
8 rows, 6 columns, 16 non-zeros
Scaling...
A: min|aij| = 1.000e+00 max|aij| = 1.000e+00 ratio = 1.000e+00
Problem data seem to be well scaled
Constructing initial basis...
Size of triangular part is 8
0: obj = 1.850000000e+06 inf = 3.000e+03 (2)
2: obj = 1.700000000e+06 inf = 0.000e+00 (0)
* 9: obj = 9.500000000e+05 inf = 0.000e+00 (0)
OPTIMAL LP SOLUTION FOUND
Time used: 0.0 secs
Memory used: 0.0 Mb (49911 bytes)
Writing basic solution to '/tmp/linopy-solve-ur7uwtuy.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()
INFO:linopy.model: Solve problem using Glpk solver
INFO:linopy.io: Writing time: 0.04s
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 13 primals, 41 duals
Objective: 1.68e+06
Solver model: not 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.
GLPSOL--GLPK LP/MIP Solver 5.0
Parameter(s) specified in the command line:
--lp /tmp/linopy-problem-8kb66jk9.lp --output /tmp/linopy-solve-ib8if6dc.sol
Reading problem data from '/tmp/linopy-problem-8kb66jk9.lp'...
41 rows, 13 columns, 73 non-zeros
227 lines were read
GLPK Simplex Optimizer 5.0
41 rows, 13 columns, 73 non-zeros
Preprocessing...
15 rows, 7 columns, 39 non-zeros
Scaling...
A: min|aij| = 1.000e-01 max|aij| = 1.000e+00 ratio = 1.000e+01
Problem data seem to be well scaled
Constructing initial basis...
Size of triangular part is 15
0: obj = 1.850000000e+06 inf = 1.800e+04 (6)
3: obj = 1.895000000e+06 inf = 0.000e+00 (0)
* 12: obj = 1.675000000e+06 inf = 6.821e-13 (0)
OPTIMAL LP SOLUTION FOUND
Time used: 0.0 secs
Memory used: 0.1 Mb (53519 bytes)
Writing basic solution to '/tmp/linopy-solve-ib8if6dc.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()
INFO:linopy.model: Solve problem using Glpk solver
INFO:linopy.io: Writing time: 0.04s
WARNING:linopy.solvers:Dual values of MILP couldn't be parsed
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 35 primals, 0 duals
Objective: 1.15e+06
Solver model: not available
Solver message: integer optimal
INFO:pypsa.optimization.optimize:No shadow prices were assigned to the network.
GLPSOL--GLPK LP/MIP Solver 5.0
Parameter(s) specified in the command line:
--lp /tmp/linopy-problem-zez7kt8y.lp --output /tmp/linopy-solve-0zz7qpu6.sol
Reading problem data from '/tmp/linopy-problem-zez7kt8y.lp'...
61 rows, 35 columns, 144 non-zeros
21 integer variables, all of which are binary
384 lines were read
GLPK Integer Optimizer 5.0
61 rows, 35 columns, 144 non-zeros
21 integer variables, all of which are binary
Preprocessing...
2 hidden packing inequaliti(es) were detected
5 constraint coefficient(s) were reduced
24 rows, 16 columns, 66 non-zeros
12 integer variables, all of which are binary
Scaling...
A: min|aij| = 1.000e+00 max|aij| = 5.000e+03 ratio = 5.000e+03
GM: min|aij| = 5.623e-01 max|aij| = 1.778e+00 ratio = 3.162e+00
EQ: min|aij| = 3.162e-01 max|aij| = 1.000e+00 ratio = 3.162e+00
2N: min|aij| = 2.441e-01 max|aij| = 1.465e+00 ratio = 6.000e+00
Constructing initial basis...
Size of triangular part is 24
Solving LP relaxation...
GLPK Simplex Optimizer 5.0
24 rows, 16 columns, 66 non-zeros
* 0: obj = 1.624000000e+06 inf = 0.000e+00 (4)
* 16: obj = 1.149000000e+06 inf = 1.782e-14 (0)
OPTIMAL LP SOLUTION FOUND
Integer optimization begins...
Long-step dual simplex will be used
+ 16: mip = not found yet >= -inf (1; 0)
+ 16: >>>>> 1.149000000e+06 >= 1.149000000e+06 0.0% (1; 0)
+ 16: mip = 1.149000000e+06 >= tree is empty 0.0% (0; 1)
INTEGER OPTIMAL SOLUTION FOUND
Time used: 0.0 secs
Memory used: 0.1 Mb (98846 bytes)
Writing MIP solution to '/tmp/linopy-solve-0zz7qpu6.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
n_mod 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])
INFO:linopy.model: Solve problem using Glpk solver
INFO:linopy.io: Writing time: 0.04s
WARNING:linopy.solvers:Dual values of MILP couldn't be parsed
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 56 primals, 0 duals
Objective: 5.55e+05
Solver model: not available
Solver message: integer optimal
INFO:pypsa.optimization.optimize:No shadow prices were assigned to the network.
GLPSOL--GLPK LP/MIP Solver 5.0
Parameter(s) specified in the command line:
--lp /tmp/linopy-problem-2h16l8m4.lp --output /tmp/linopy-solve-z2hcjsv6.sol
Reading problem data from '/tmp/linopy-problem-2h16l8m4.lp'...
96 rows, 56 columns, 253 non-zeros
42 integer variables, all of which are binary
646 lines were read
GLPK Integer Optimizer 5.0
96 rows, 56 columns, 253 non-zeros
42 integer variables, all of which are binary
Preprocessing...
3 hidden packing inequaliti(es) were detected
23 rows, 20 columns, 58 non-zeros
15 integer variables, all of which are binary
Scaling...
A: min|aij| = 1.000e+00 max|aij| = 1.000e+03 ratio = 1.000e+03
GM: min|aij| = 5.623e-01 max|aij| = 1.778e+00 ratio = 3.162e+00
EQ: min|aij| = 3.162e-01 max|aij| = 1.000e+00 ratio = 3.162e+00
2N: min|aij| = 1.953e-01 max|aij| = 1.000e+00 ratio = 5.120e+00
Constructing initial basis...
Size of triangular part is 23
Solving LP relaxation...
GLPK Simplex Optimizer 5.0
23 rows, 20 columns, 58 non-zeros
0: obj = 6.003500000e+05 inf = 4.762e+01 (4)
4: obj = 6.053700000e+05 inf = 0.000e+00 (0)
* 13: obj = 5.553700000e+05 inf = 0.000e+00 (0)
OPTIMAL LP SOLUTION FOUND
Integer optimization begins...
Long-step dual simplex will be used
+ 13: mip = not found yet >= -inf (1; 0)
+ 13: >>>>> 5.553700000e+05 >= 5.553700000e+05 0.0% (1; 0)
+ 13: mip = 5.553700000e+05 >= tree is empty 0.0% (0; 1)
INTEGER OPTIMAL SOLUTION FOUND
Time used: 0.0 secs
Memory used: 0.1 Mb (114764 bytes)
Writing MIP solution to '/tmp/linopy-solve-z2hcjsv6.sol'...
INFO:linopy.model: Solve problem using Glpk solver
INFO:linopy.io: Writing time: 0.04s
WARNING:linopy.solvers:Dual values of MILP couldn't be parsed
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 56 primals, 0 duals
Objective: 5.50e+05
Solver model: not available
Solver message: integer optimal
INFO:pypsa.optimization.optimize:No shadow prices were assigned to the network.
GLPSOL--GLPK LP/MIP Solver 5.0
Parameter(s) specified in the command line:
--lp /tmp/linopy-problem-9rr4zann.lp --output /tmp/linopy-solve-amws3tzn.sol
Reading problem data from '/tmp/linopy-problem-9rr4zann.lp'...
97 rows, 56 columns, 255 non-zeros
42 integer variables, all of which are binary
651 lines were read
GLPK Integer Optimizer 5.0
97 rows, 56 columns, 255 non-zeros
42 integer variables, all of which are binary
Preprocessing...
3 hidden packing inequaliti(es) were detected
27 rows, 22 columns, 68 non-zeros
16 integer variables, all of which are binary
Scaling...
A: min|aij| = 1.000e+00 max|aij| = 1.000e+03 ratio = 1.000e+03
GM: min|aij| = 5.623e-01 max|aij| = 1.778e+00 ratio = 3.162e+00
EQ: min|aij| = 3.162e-01 max|aij| = 1.000e+00 ratio = 3.162e+00
2N: min|aij| = 1.953e-01 max|aij| = 1.000e+00 ratio = 5.120e+00
Constructing initial basis...
Size of triangular part is 27
Solving LP relaxation...
GLPK Simplex Optimizer 5.0
27 rows, 22 columns, 68 non-zeros
0: obj = 5.953500000e+05 inf = 3.962e+01 (3)
3: obj = 5.954200000e+05 inf = 0.000e+00 (0)
* 13: obj = 5.504200000e+05 inf = 0.000e+00 (0)
OPTIMAL LP SOLUTION FOUND
Integer optimization begins...
Long-step dual simplex will be used
+ 13: mip = not found yet >= -inf (1; 0)
+ 13: >>>>> 5.504200000e+05 >= 5.504200000e+05 0.0% (1; 0)
+ 13: mip = 5.504200000e+05 >= tree is empty 0.0% (0; 1)
INTEGER OPTIMAL SOLUTION FOUND
Time used: 0.0 secs
Memory used: 0.1 Mb (117310 bytes)
Writing MIP solution to '/tmp/linopy-solve-amws3tzn.sol'...
INFO:linopy.model: Solve problem using Glpk solver
INFO:linopy.io: Writing time: 0.04s
WARNING:linopy.solvers:Dual values of MILP couldn't be parsed
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 56 primals, 0 duals
Objective: 5.50e+05
Solver model: not available
Solver message: integer optimal
INFO:pypsa.optimization.optimize:No shadow prices were assigned to the network.
GLPSOL--GLPK LP/MIP Solver 5.0
Parameter(s) specified in the command line:
--lp /tmp/linopy-problem-8f9nts3b.lp --output /tmp/linopy-solve-ra5m3xwy.sol
Reading problem data from '/tmp/linopy-problem-8f9nts3b.lp'...
97 rows, 56 columns, 255 non-zeros
42 integer variables, all of which are binary
651 lines were read
GLPK Integer Optimizer 5.0
97 rows, 56 columns, 255 non-zeros
42 integer variables, all of which are binary
Preprocessing...
3 hidden packing inequaliti(es) were detected
27 rows, 23 columns, 68 non-zeros
17 integer variables, all of which are binary
Scaling...
A: min|aij| = 1.000e+00 max|aij| = 1.000e+03 ratio = 1.000e+03
GM: min|aij| = 5.623e-01 max|aij| = 1.778e+00 ratio = 3.162e+00
EQ: min|aij| = 3.162e-01 max|aij| = 1.000e+00 ratio = 3.162e+00
2N: min|aij| = 1.953e-01 max|aij| = 1.000e+00 ratio = 5.120e+00
Constructing initial basis...
Size of triangular part is 27
Solving LP relaxation...
GLPK Simplex Optimizer 5.0
27 rows, 23 columns, 68 non-zeros
0: obj = 5.953500000e+05 inf = 4.762e+01 (4)
4: obj = 5.954400000e+05 inf = 0.000e+00 (0)
* 15: obj = 5.504400000e+05 inf = 0.000e+00 (0)
OPTIMAL LP SOLUTION FOUND
Integer optimization begins...
Long-step dual simplex will be used
+ 15: mip = not found yet >= -inf (1; 0)
+ 15: >>>>> 5.504400000e+05 >= 5.504400000e+05 0.0% (1; 0)
+ 15: mip = 5.504400000e+05 >= tree is empty 0.0% (0; 1)
INTEGER OPTIMAL SOLUTION FOUND
Time used: 0.0 secs
Memory used: 0.1 Mb (117479 bytes)
Writing MIP solution to '/tmp/linopy-solve-ra5m3xwy.sol'...
INFO:linopy.model: Solve problem using Glpk solver
INFO:linopy.io: Writing time: 0.04s
WARNING:linopy.solvers:Dual values of MILP couldn't be parsed
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 56 primals, 0 duals
Objective: 5.50e+05
Solver model: not available
Solver message: integer optimal
INFO:pypsa.optimization.optimize:No shadow prices were assigned to the network.
GLPSOL--GLPK LP/MIP Solver 5.0
Parameter(s) specified in the command line:
--lp /tmp/linopy-problem-mtdkf6tv.lp --output /tmp/linopy-solve-e2ehf0rg.sol
Reading problem data from '/tmp/linopy-problem-mtdkf6tv.lp'...
97 rows, 56 columns, 255 non-zeros
42 integer variables, all of which are binary
651 lines were read
GLPK Integer Optimizer 5.0
97 rows, 56 columns, 255 non-zeros
42 integer variables, all of which are binary
Preprocessing...
3 hidden packing inequaliti(es) were detected
27 rows, 23 columns, 68 non-zeros
17 integer variables, all of which are binary
Scaling...
A: min|aij| = 1.000e+00 max|aij| = 1.000e+03 ratio = 1.000e+03
GM: min|aij| = 5.623e-01 max|aij| = 1.778e+00 ratio = 3.162e+00
EQ: min|aij| = 3.162e-01 max|aij| = 1.000e+00 ratio = 3.162e+00
2N: min|aij| = 1.953e-01 max|aij| = 1.000e+00 ratio = 5.120e+00
Constructing initial basis...
Size of triangular part is 27
Solving LP relaxation...
GLPK Simplex Optimizer 5.0
27 rows, 23 columns, 68 non-zeros
0: obj = 5.953500000e+05 inf = 4.762e+01 (4)
4: obj = 5.954400000e+05 inf = 0.000e+00 (0)
* 15: obj = 5.504400000e+05 inf = 0.000e+00 (0)
OPTIMAL LP SOLUTION FOUND
Integer optimization begins...
Long-step dual simplex will be used
+ 15: mip = not found yet >= -inf (1; 0)
+ 15: >>>>> 5.504400000e+05 >= 5.504400000e+05 0.0% (1; 0)
+ 15: mip = 5.504400000e+05 >= tree is empty 0.0% (0; 1)
INTEGER OPTIMAL SOLUTION FOUND
Time used: 0.0 secs
Memory used: 0.1 Mb (117479 bytes)
Writing MIP solution to '/tmp/linopy-solve-e2ehf0rg.sol'...
INFO:linopy.model: Solve problem using Glpk solver
INFO:linopy.io: Writing time: 0.04s
WARNING:linopy.solvers:Dual values of MILP couldn't be parsed
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 56 primals, 0 duals
Objective: 5.50e+05
Solver model: not available
Solver message: integer optimal
INFO:pypsa.optimization.optimize:No shadow prices were assigned to the network.
GLPSOL--GLPK LP/MIP Solver 5.0
Parameter(s) specified in the command line:
--lp /tmp/linopy-problem-duv83smi.lp --output /tmp/linopy-solve-sldtva78.sol
Reading problem data from '/tmp/linopy-problem-duv83smi.lp'...
97 rows, 56 columns, 255 non-zeros
42 integer variables, all of which are binary
651 lines were read
GLPK Integer Optimizer 5.0
97 rows, 56 columns, 255 non-zeros
42 integer variables, all of which are binary
Preprocessing...
3 hidden packing inequaliti(es) were detected
27 rows, 23 columns, 68 non-zeros
17 integer variables, all of which are binary
Scaling...
A: min|aij| = 1.000e+00 max|aij| = 1.000e+03 ratio = 1.000e+03
GM: min|aij| = 5.623e-01 max|aij| = 1.778e+00 ratio = 3.162e+00
EQ: min|aij| = 3.162e-01 max|aij| = 1.000e+00 ratio = 3.162e+00
2N: min|aij| = 1.953e-01 max|aij| = 1.000e+00 ratio = 5.120e+00
Constructing initial basis...
Size of triangular part is 27
Solving LP relaxation...
GLPK Simplex Optimizer 5.0
27 rows, 23 columns, 68 non-zeros
0: obj = 5.953500000e+05 inf = 4.762e+01 (4)
4: obj = 5.954400000e+05 inf = 0.000e+00 (0)
* 15: obj = 5.504400000e+05 inf = 0.000e+00 (0)
OPTIMAL LP SOLUTION FOUND
Integer optimization begins...
Long-step dual simplex will be used
+ 15: mip = not found yet >= -inf (1; 0)
+ 15: >>>>> 5.504400000e+05 >= 5.504400000e+05 0.0% (1; 0)
+ 15: mip = 5.504400000e+05 >= tree is empty 0.0% (0; 1)
INTEGER OPTIMAL SOLUTION FOUND
Time used: 0.0 secs
Memory used: 0.1 Mb (117479 bytes)
Writing MIP solution to '/tmp/linopy-solve-sldtva78.sol'...
INFO:linopy.model: Solve problem using Glpk solver
INFO:linopy.io: Writing time: 0.04s
WARNING:linopy.solvers:Dual values of MILP couldn't be parsed
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 40 primals, 0 duals
Objective: 3.70e+05
Solver model: not available
Solver message: integer optimal
INFO:pypsa.optimization.optimize:No shadow prices were assigned to the network.
GLPSOL--GLPK LP/MIP Solver 5.0
Parameter(s) specified in the command line:
--lp /tmp/linopy-problem-vmtrgnip.lp --output /tmp/linopy-solve-d7jcbxyx.sol
Reading problem data from '/tmp/linopy-problem-vmtrgnip.lp'...
69 rows, 40 columns, 177 non-zeros
30 integer variables, all of which are binary
461 lines were read
GLPK Integer Optimizer 5.0
69 rows, 40 columns, 177 non-zeros
30 integer variables, all of which are binary
Preprocessing...
3 hidden packing inequaliti(es) were detected
17 rows, 15 columns, 40 non-zeros
11 integer variables, all of which are binary
Scaling...
A: min|aij| = 1.000e+00 max|aij| = 1.000e+03 ratio = 1.000e+03
GM: min|aij| = 5.623e-01 max|aij| = 1.778e+00 ratio = 3.162e+00
EQ: min|aij| = 3.162e-01 max|aij| = 1.000e+00 ratio = 3.162e+00
2N: min|aij| = 1.953e-01 max|aij| = 1.000e+00 ratio = 5.120e+00
Constructing initial basis...
Size of triangular part is 17
Solving LP relaxation...
GLPK Simplex Optimizer 5.0
17 rows, 15 columns, 40 non-zeros
0: obj = 4.153500000e+05 inf = 4.762e+01 (4)
3: obj = 4.154200000e+05 inf = 0.000e+00 (0)
* 11: obj = 3.704200000e+05 inf = 0.000e+00 (0)
OPTIMAL LP SOLUTION FOUND
Integer optimization begins...
Long-step dual simplex will be used
+ 11: mip = not found yet >= -inf (1; 0)
+ 11: >>>>> 3.704200000e+05 >= 3.704200000e+05 0.0% (1; 0)
+ 11: mip = 3.704200000e+05 >= tree is empty 0.0% (0; 1)
INTEGER OPTIMAL SOLUTION FOUND
Time used: 0.0 secs
Memory used: 0.1 Mb (86439 bytes)
Writing MIP solution to '/tmp/linopy-solve-d7jcbxyx.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 | False | 5000.0 | 0.0 |
12 | False | True | 0.0 | 700.0 |
13 | False | True | 0.0 | 800.0 |
14 | True | True | 3900.0 | 100.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 | False | 5000.0 | 0.0 |
22 | False | True | 0.0 | 700.0 |
23 | False | True | 0.0 | 800.0 |
24 | True | True | 3900.0 | 100.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 |