Note
You can download this example as a Jupyter notebook or start it in interactive mode.
Non-linear power flow after LOPF#
In this example, the dispatch of generators is optimised using the linear OPF, then a non-linear power flow is run on the resulting dispatch.
Data sources#
Grid: based on SciGRID Version 0.2 which is based on OpenStreetMap.
Load size and location: based on Landkreise (NUTS 3) GDP and population.
Load time series: from ENTSO-E hourly data, scaled up uniformly by factor 1.12 (a simplification of the methodology in Schumacher, Hirth (2015)).
Conventional power plant capacities and locations: BNetzA list.
Wind and solar capacities and locations: EEG Stammdaten, based on http://www.energymap.info/download.html, which represents capacities at the end of 2014. Units without PLZ are removed.
Wind and solar time series: REatlas, Andresen et al, “Validation of Danish wind time series from a new global renewable energy atlas for energy system analysis,” Energy 93 (2015) 1074 - 1088.
Where SciGRID nodes have been split into 220kV and 380kV substations, all load and generation is attached to the 220kV substation.
Warnings#
The data behind the notebook is no longer supported. See PyPSA/pypsa-eur for a newer model that covers the whole of Europe.
This dataset is ONLY intended to demonstrate the capabilities of PyPSA and is NOT (yet) accurate enough to be used for research purposes.
Known problems include:
Rough approximations have been made for missing grid data, e.g. 220kV-380kV transformers and connections between close sub-stations missing from OSM.
There appears to be some unexpected congestion in parts of the network, which may mean for example that the load attachment method (by Voronoi cell overlap with Landkreise) isn’t working, particularly in regions with a high density of substations.
Attaching power plants to the nearest high voltage substation may not reflect reality.
There is no proper n-1 security in the calculations - this can either be simulated with a blanket e.g. 70% reduction in thermal limits (as done here) or a proper security constrained OPF (see e.g. http://www.pypsa.org/examples/scigrid-sclopf.ipynb).
The borders and neighbouring countries are not represented.
Hydroelectric power stations are not modelled accurately.
The marginal costs are illustrative, not accurate.
Only the first day of 2011 is in the github dataset, which is not representative. The full year of 2011 can be downloaded at http://www.pypsa.org/examples/scigrid-with-load-gen-trafos-2011.zip.
The ENTSO-E total load for Germany may not be scaled correctly; it is scaled up uniformly by factor 1.12 (a simplification of the methodology in Schumacher, Hirth (2015), which suggests monthly factors).
Biomass from the EEG Stammdaten are not read in at the moment.
Power plant start up costs, ramping limits/costs, minimum loading rates are not considered.
[1]:
import pypsa
import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
[2]:
network = pypsa.examples.scigrid_de(from_master=True)
WARNING:pypsa.io:Importing network from PyPSA version v0.17.1 while current version is v0.25.1. Read the release notes at https://pypsa.readthedocs.io/en/latest/release_notes.html to prepare your network for import.
INFO:pypsa.io:Imported network scigrid-de.nc has buses, generators, lines, loads, storage_units, transformers
Plot the distribution of the load and of generating tech
[3]:
fig, ax = plt.subplots(
1, 1, subplot_kw={"projection": ccrs.EqualEarth()}, figsize=(8, 8)
)
load_distribution = (
network.loads_t.p_set.loc[network.snapshots[0]].groupby(network.loads.bus).sum()
)
network.plot(bus_sizes=1e-5 * load_distribution, ax=ax, title="Load distribution");
/home/docs/checkouts/readthedocs.org/user_builds/pypsa/conda/v0.25.1/lib/python3.11/site-packages/cartopy/mpl/style.py:76: UserWarning: facecolor will have no effect as it has been defined as "never".
warnings.warn('facecolor will have no effect as it has been '
[4]:
network.generators.groupby("carrier")["p_nom"].sum()
[4]:
carrier
Brown Coal 20879.500000
Gas 23913.130000
Geothermal 31.700000
Hard Coal 25312.600000
Multiple 152.700000
Nuclear 12068.000000
Oil 2710.200000
Other 3027.800000
Run of River 3999.100000
Solar 37041.524779
Storage Hydro 1445.000000
Waste 1645.900000
Wind Offshore 2973.500000
Wind Onshore 37339.895329
Name: p_nom, dtype: float64
[5]:
network.storage_units.groupby("carrier")["p_nom"].sum()
[5]:
carrier
Pumped Hydro 9179.5
Name: p_nom, dtype: float64
[6]:
techs = ["Gas", "Brown Coal", "Hard Coal", "Wind Offshore", "Wind Onshore", "Solar"]
n_graphs = len(techs)
n_cols = 3
if n_graphs % n_cols == 0:
n_rows = n_graphs // n_cols
else:
n_rows = n_graphs // n_cols + 1
fig, axes = plt.subplots(
nrows=n_rows, ncols=n_cols, subplot_kw={"projection": ccrs.EqualEarth()}
)
size = 6
fig.set_size_inches(size * n_cols, size * n_rows)
for i, tech in enumerate(techs):
i_row = i // n_cols
i_col = i % n_cols
ax = axes[i_row, i_col]
gens = network.generators[network.generators.carrier == tech]
gen_distribution = (
gens.groupby("bus").sum()["p_nom"].reindex(network.buses.index, fill_value=0.0)
)
network.plot(ax=ax, bus_sizes=2e-5 * gen_distribution)
ax.set_title(tech)
fig.tight_layout()
/home/docs/checkouts/readthedocs.org/user_builds/pypsa/conda/v0.25.1/lib/python3.11/site-packages/cartopy/mpl/style.py:76: UserWarning: facecolor will have no effect as it has been defined as "never".
warnings.warn('facecolor will have no effect as it has been '
Run Linear Optimal Power Flow on the first day of 2011.
To approximate n-1 security and allow room for reactive power flows, don’t allow any line to be loaded above 70% of their thermal rating
[7]:
contingency_factor = 0.7
network.lines.s_max_pu = contingency_factor
There are some infeasibilities without small extensions
[8]:
network.lines.loc[["316", "527", "602"], "s_nom"] = 1715
We performing a linear OPF for one day, 4 snapshots at a time.
[9]:
group_size = 4
network.storage_units.state_of_charge_initial = 0.0
for i in range(int(24 / group_size)):
# set the initial state of charge based on previous round
if i:
network.storage_units.state_of_charge_initial = (
network.storage_units_t.state_of_charge.loc[
network.snapshots[group_size * i - 1]
]
)
network.optimize(
network.snapshots[group_size * i : group_size * i + group_size],
solver_name="cbc",
)
WARNING:pypsa.components:The following transformers have zero r, which could break the linear load flow:
Index(['2', '5', '10', '12', '13', '15', '18', '20', '22', '24', '26', '30',
'32', '37', '42', '46', '52', '56', '61', '68', '69', '74', '78', '86',
'87', '94', '95', '96', '99', '100', '104', '105', '106', '107', '117',
'120', '123', '124', '125', '128', '129', '138', '143', '156', '157',
'159', '160', '165', '184', '191', '195', '201', '220', '231', '232',
'233', '236', '247', '248', '250', '251', '252', '261', '263', '264',
'267', '272', '279', '281', '282', '292', '303', '307', '308', '312',
'315', '317', '322', '332', '334', '336', '338', '351', '353', '360',
'362', '382', '384', '385', '391', '403', '404', '413', '421', '450',
'458'],
dtype='object', name='Transformer')
WARNING:pypsa.components:The following transformers have zero r, which could break the linear load flow:
Index(['2', '5', '10', '12', '13', '15', '18', '20', '22', '24', '26', '30',
'32', '37', '42', '46', '52', '56', '61', '68', '69', '74', '78', '86',
'87', '94', '95', '96', '99', '100', '104', '105', '106', '107', '117',
'120', '123', '124', '125', '128', '129', '138', '143', '156', '157',
'159', '160', '165', '184', '191', '195', '201', '220', '231', '232',
'233', '236', '247', '248', '250', '251', '252', '261', '263', '264',
'267', '272', '279', '281', '282', '292', '303', '307', '308', '312',
'315', '317', '322', '332', '334', '336', '338', '351', '353', '360',
'362', '382', '384', '385', '391', '403', '404', '413', '421', '450',
'458'],
dtype='object', name='Transformer')
INFO:linopy.model: Solve linear problem using Cbc solver
INFO:linopy.io:Writing objective.
Writing constraints.: 100%|██████████| 15/15 [00:00<00:00, 78.48it/s]
Writing continuous variables.: 100%|██████████| 7/7 [00:00<00:00, 250.50it/s]
INFO:linopy.io: Writing time: 0.23s
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 9940 primals, 23828 duals
Objective: 1.45e+06
Solver model: not available
Solver message: Optimal - objective value 1449687.25014697
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper, Line-fix-s-lower, Line-fix-s-upper, Transformer-fix-s-lower, Transformer-fix-s-upper, StorageUnit-fix-p_dispatch-lower, StorageUnit-fix-p_dispatch-upper, StorageUnit-fix-p_store-lower, StorageUnit-fix-p_store-upper, StorageUnit-fix-state_of_charge-lower, StorageUnit-fix-state_of_charge-upper, Kirchhoff-Voltage-Law, StorageUnit-energy_balance were not assigned to the network.
Welcome to the CBC MILP Solver
Version: 2.10.10
Build Date: Apr 19 2023
command line - cbc -printingOptions all -import /tmp/linopy-problem-cqv665cx.lp -solve -solu /tmp/linopy-solve-7brkwo9w.sol (default strategy 1)
Option for printingOptions changed from normal to all
Presolve 2396 (-21432) rows, 4338 (-5602) columns and 17225 (-28825) elements
Perturbing problem by 0.001% of 2327.2654 - largest nonzero change 0.00099751112 ( 0.017779791%) - largest zero change 0.00099725216
0 Obj 88150.3 Primal inf 6561637.9 (2191) Dual inf 574.70586 (4)
122 Obj 18798.986 Primal inf 3533540.2 (2138)
244 Obj 18798.986 Primal inf 3347990.9 (2084)
366 Obj 18799.233 Primal inf 3288071.4 (2052)
488 Obj 18799.55 Primal inf 2965523.6 (1982)
610 Obj 18801.755 Primal inf 3041883.8 (1949)
732 Obj 18808.073 Primal inf 2442282.4 (1855)
854 Obj 18809.966 Primal inf 4461839.1 (1826)
976 Obj 18810.776 Primal inf 3966631.1 (1759)
1098 Obj 18811.843 Primal inf 4848582.3 (1752)
1220 Obj 18813.338 Primal inf 5956633 (1689)
1342 Obj 18815.102 Primal inf 7122586.2 (1665)
1464 Obj 22632.85 Primal inf 12814617 (1530)
1586 Obj 22634.612 Primal inf 44752656 (1528)
1708 Obj 22637.095 Primal inf 12110012 (1487)
1830 Obj 22638.993 Primal inf 5316640.1 (1231)
1952 Obj 22642.546 Primal inf 6856722.3 (1185)
2074 Obj 56217.442 Primal inf 3820580.2 (1184)
2196 Obj 73809.885 Primal inf 2163606.4 (885)
2318 Obj 174061.57 Primal inf 2044603.5 (795)
2440 Obj 447675.03 Primal inf 1906557.2 (656)
2562 Obj 479474.4 Primal inf 2549636.3 (542)
2684 Obj 719428.6 Primal inf 102884.02 (390)
2806 Obj 976321.97 Primal inf 233452.77 (482)
2928 Obj 1332105.1 Primal inf 67307.555 (200)
3050 Obj 1427979.3 Primal inf 1543.1247 (78)
3172 Obj 1449452.1 Primal inf 54.277877 (15)
3191 Obj 1449691.9
3191 Obj 1449687.3 Dual inf 7.3445901e-06 (1)
3192 Obj 1449687.3
Optimal - objective value 1449687.3
After Postsolve, objective 1449687.3, infeasibilities - dual 215.9672 (7), primal 1.5133967e-06 (7)
Presolved model was optimal, full model needs cleaning up
0 Obj 1449687.3 Primal inf 1.2635423e-07 (1) Dual inf 1e+08 (8)
End of values pass after 12 iterations
12 Obj 1449687.3
Optimal - objective value 1449687.3
Optimal objective 1449687.25 - 3204 iterations time 0.392, Presolve 0.02
Total time (CPU seconds): 0.59 (Wallclock seconds): 0.57
WARNING:pypsa.components:The following transformers have zero r, which could break the linear load flow:
Index(['2', '5', '10', '12', '13', '15', '18', '20', '22', '24', '26', '30',
'32', '37', '42', '46', '52', '56', '61', '68', '69', '74', '78', '86',
'87', '94', '95', '96', '99', '100', '104', '105', '106', '107', '117',
'120', '123', '124', '125', '128', '129', '138', '143', '156', '157',
'159', '160', '165', '184', '191', '195', '201', '220', '231', '232',
'233', '236', '247', '248', '250', '251', '252', '261', '263', '264',
'267', '272', '279', '281', '282', '292', '303', '307', '308', '312',
'315', '317', '322', '332', '334', '336', '338', '351', '353', '360',
'362', '382', '384', '385', '391', '403', '404', '413', '421', '450',
'458'],
dtype='object', name='Transformer')
WARNING:pypsa.components:The following transformers have zero r, which could break the linear load flow:
Index(['2', '5', '10', '12', '13', '15', '18', '20', '22', '24', '26', '30',
'32', '37', '42', '46', '52', '56', '61', '68', '69', '74', '78', '86',
'87', '94', '95', '96', '99', '100', '104', '105', '106', '107', '117',
'120', '123', '124', '125', '128', '129', '138', '143', '156', '157',
'159', '160', '165', '184', '191', '195', '201', '220', '231', '232',
'233', '236', '247', '248', '250', '251', '252', '261', '263', '264',
'267', '272', '279', '281', '282', '292', '303', '307', '308', '312',
'315', '317', '322', '332', '334', '336', '338', '351', '353', '360',
'362', '382', '384', '385', '391', '403', '404', '413', '421', '450',
'458'],
dtype='object', name='Transformer')
INFO:linopy.model: Solve linear problem using Cbc solver
INFO:linopy.io:Writing objective.
Writing constraints.: 100%|██████████| 15/15 [00:00<00:00, 80.65it/s]
Writing continuous variables.: 100%|██████████| 7/7 [00:00<00:00, 255.80it/s]
INFO:linopy.io: Writing time: 0.23s
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 9940 primals, 23828 duals
Objective: 8.74e+05
Solver model: not available
Solver message: Optimal - objective value 873763.90232907
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper, Line-fix-s-lower, Line-fix-s-upper, Transformer-fix-s-lower, Transformer-fix-s-upper, StorageUnit-fix-p_dispatch-lower, StorageUnit-fix-p_dispatch-upper, StorageUnit-fix-p_store-lower, StorageUnit-fix-p_store-upper, StorageUnit-fix-state_of_charge-lower, StorageUnit-fix-state_of_charge-upper, Kirchhoff-Voltage-Law, StorageUnit-energy_balance were not assigned to the network.
Welcome to the CBC MILP Solver
Version: 2.10.10
Build Date: Apr 19 2023
command line - cbc -printingOptions all -import /tmp/linopy-problem-yqy0nijg.lp -solve -solu /tmp/linopy-solve-g4bh3ufi.sol (default strategy 1)
Option for printingOptions changed from normal to all
Presolve 2419 (-21409) rows, 4368 (-5572) columns and 17502 (-28548) elements
Perturbing problem by 0.001% of 3070.478 - largest nonzero change 0.00099526042 ( 0.019389923%) - largest zero change 0.00099451166
0 Obj 81193.865 Primal inf 5494255.5 (2219) Dual inf 1043.2235 (4)
123 Obj 11842.551 Primal inf 3830534.6 (2167)
246 Obj 11842.88 Primal inf 3043037.5 (2111)
369 Obj 11842.88 Primal inf 3000798.7 (2086)
492 Obj 11845.363 Primal inf 3243530.5 (2066)
615 Obj 11845.594 Primal inf 3116325.2 (1987)
738 Obj 11846.197 Primal inf 3106767.1 (1925)
861 Obj 11848.884 Primal inf 3550933.5 (1877)
984 Obj 11849.433 Primal inf 3956501 (1840)
1107 Obj 11850.964 Primal inf 2608199.3 (1722)
1230 Obj 11851.894 Primal inf 4413841.3 (1691)
1353 Obj 11853.518 Primal inf 6986413.9 (1658)
1476 Obj 11855.124 Primal inf 4771432 (1543)
1599 Obj 11857.272 Primal inf 17230040 (1528)
1722 Obj 11859.199 Primal inf 14911702 (1439)
1845 Obj 11861.172 Primal inf 7868857.1 (1346)
1968 Obj 11864.542 Primal inf 7633831.8 (1314)
2091 Obj 15366.27 Primal inf 7203194.1 (1206)
2214 Obj 21034.295 Primal inf 4788815.4 (967)
2337 Obj 29296.872 Primal inf 1090346.8 (717)
2460 Obj 115228.94 Primal inf 7471645.7 (818)
2583 Obj 294554.12 Primal inf 385292.79 (477)
2706 Obj 544453.14 Primal inf 170573.67 (432)
2829 Obj 722449.78 Primal inf 78653.084 (393)
2952 Obj 828889.96 Primal inf 10859.173 (140)
3075 Obj 857225.17 Primal inf 9904.9891 (111)
3198 Obj 873222.99 Primal inf 973.51594 (29)
3263 Obj 873767.79
Optimal - objective value 873763.9
After Postsolve, objective 873763.9, infeasibilities - dual 78.034695 (3), primal 9.155089e-07 (3)
Presolved model was optimal, full model needs cleaning up
0 Obj 873763.9 Dual inf 0.78034665 (3)
End of values pass after 3 iterations
3 Obj 873763.9
Optimal - objective value 873763.9
Optimal objective 873763.9023 - 3266 iterations time 0.422, Presolve 0.02
Total time (CPU seconds): 0.62 (Wallclock seconds): 0.59
WARNING:pypsa.components:The following transformers have zero r, which could break the linear load flow:
Index(['2', '5', '10', '12', '13', '15', '18', '20', '22', '24', '26', '30',
'32', '37', '42', '46', '52', '56', '61', '68', '69', '74', '78', '86',
'87', '94', '95', '96', '99', '100', '104', '105', '106', '107', '117',
'120', '123', '124', '125', '128', '129', '138', '143', '156', '157',
'159', '160', '165', '184', '191', '195', '201', '220', '231', '232',
'233', '236', '247', '248', '250', '251', '252', '261', '263', '264',
'267', '272', '279', '281', '282', '292', '303', '307', '308', '312',
'315', '317', '322', '332', '334', '336', '338', '351', '353', '360',
'362', '382', '384', '385', '391', '403', '404', '413', '421', '450',
'458'],
dtype='object', name='Transformer')
WARNING:pypsa.components:The following transformers have zero r, which could break the linear load flow:
Index(['2', '5', '10', '12', '13', '15', '18', '20', '22', '24', '26', '30',
'32', '37', '42', '46', '52', '56', '61', '68', '69', '74', '78', '86',
'87', '94', '95', '96', '99', '100', '104', '105', '106', '107', '117',
'120', '123', '124', '125', '128', '129', '138', '143', '156', '157',
'159', '160', '165', '184', '191', '195', '201', '220', '231', '232',
'233', '236', '247', '248', '250', '251', '252', '261', '263', '264',
'267', '272', '279', '281', '282', '292', '303', '307', '308', '312',
'315', '317', '322', '332', '334', '336', '338', '351', '353', '360',
'362', '382', '384', '385', '391', '403', '404', '413', '421', '450',
'458'],
dtype='object', name='Transformer')
INFO:linopy.model: Solve linear problem using Cbc solver
INFO:linopy.io:Writing objective.
Writing constraints.: 100%|██████████| 15/15 [00:00<00:00, 80.14it/s]
Writing continuous variables.: 100%|██████████| 7/7 [00:00<00:00, 251.53it/s]
INFO:linopy.io: Writing time: 0.23s
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 9940 primals, 23828 duals
Objective: 7.91e+05
Solver model: not available
Solver message: Optimal - objective value 790786.59488191
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper, Line-fix-s-lower, Line-fix-s-upper, Transformer-fix-s-lower, Transformer-fix-s-upper, StorageUnit-fix-p_dispatch-lower, StorageUnit-fix-p_dispatch-upper, StorageUnit-fix-p_store-lower, StorageUnit-fix-p_store-upper, StorageUnit-fix-state_of_charge-lower, StorageUnit-fix-state_of_charge-upper, Kirchhoff-Voltage-Law, StorageUnit-energy_balance were not assigned to the network.
Welcome to the CBC MILP Solver
Version: 2.10.10
Build Date: Apr 19 2023
command line - cbc -printingOptions all -import /tmp/linopy-problem-f7_bm3zp.lp -solve -solu /tmp/linopy-solve-etrw6amp.sol (default strategy 1)
Option for printingOptions changed from normal to all
Presolve 2482 (-21346) rows, 4437 (-5503) columns and 17760 (-28290) elements
Perturbing problem by 0.001% of 2327.2654 - largest nonzero change 0.00099940449 ( 0.0089548564%) - largest zero change 0.00099290601
0 Obj -35.947231 Primal inf 5817841 (2285)
124 Obj -35.947231 Primal inf 3617850.8 (2236)
248 Obj -35.947231 Primal inf 3215341.9 (2164)
372 Obj -35.947231 Primal inf 3006826.5 (2117)
496 Obj -29.01886 Primal inf 2708219.4 (2076)
620 Obj -28.673879 Primal inf 3891582.8 (2073)
744 Obj -26.704935 Primal inf 2745783.9 (1997)
868 Obj -24.891039 Primal inf 2846365.7 (1933)
992 Obj -23.690271 Primal inf 2804675.9 (1844)
1116 Obj -22.242021 Primal inf 5328384.7 (1843)
1240 Obj -20.756623 Primal inf 2388080.3 (1730)
1364 Obj -19.156596 Primal inf 10867715 (1734)
1488 Obj -17.052352 Primal inf 6881646.6 (1643)
1612 Obj -15.253495 Primal inf 5079510 (1467)
1736 Obj 7648.308 Primal inf 3919663.6 (1295)
1860 Obj 7651.097 Primal inf 1587548.8 (1214)
1984 Obj 7653.5283 Primal inf 1742262.8 (1093)
2108 Obj 7655.9015 Primal inf 17312403 (1290)
2232 Obj 7724.7418 Primal inf 1183320.8 (833)
2356 Obj 7728.3851 Primal inf 753564.38 (571)
2480 Obj 88058.258 Primal inf 500047.18 (438)
2604 Obj 298462.98 Primal inf 115223.05 (422)
2728 Obj 506800.66 Primal inf 143882.05 (475)
2852 Obj 619572.93 Primal inf 30741.362 (276)
2976 Obj 692808.13 Primal inf 26716.3 (206)
3100 Obj 769053.42 Primal inf 6375.2674 (125)
3224 Obj 790780.39 Primal inf 90.297361 (11)
3237 Obj 790794.5
Optimal - objective value 790786.59
After Postsolve, objective 790786.59, infeasibilities - dual 0 (0), primal 0 (0)
Optimal objective 790786.5949 - 3237 iterations time 0.362, Presolve 0.02
Total time (CPU seconds): 0.56 (Wallclock seconds): 0.53
WARNING:pypsa.components:The following transformers have zero r, which could break the linear load flow:
Index(['2', '5', '10', '12', '13', '15', '18', '20', '22', '24', '26', '30',
'32', '37', '42', '46', '52', '56', '61', '68', '69', '74', '78', '86',
'87', '94', '95', '96', '99', '100', '104', '105', '106', '107', '117',
'120', '123', '124', '125', '128', '129', '138', '143', '156', '157',
'159', '160', '165', '184', '191', '195', '201', '220', '231', '232',
'233', '236', '247', '248', '250', '251', '252', '261', '263', '264',
'267', '272', '279', '281', '282', '292', '303', '307', '308', '312',
'315', '317', '322', '332', '334', '336', '338', '351', '353', '360',
'362', '382', '384', '385', '391', '403', '404', '413', '421', '450',
'458'],
dtype='object', name='Transformer')
WARNING:pypsa.components:The following transformers have zero r, which could break the linear load flow:
Index(['2', '5', '10', '12', '13', '15', '18', '20', '22', '24', '26', '30',
'32', '37', '42', '46', '52', '56', '61', '68', '69', '74', '78', '86',
'87', '94', '95', '96', '99', '100', '104', '105', '106', '107', '117',
'120', '123', '124', '125', '128', '129', '138', '143', '156', '157',
'159', '160', '165', '184', '191', '195', '201', '220', '231', '232',
'233', '236', '247', '248', '250', '251', '252', '261', '263', '264',
'267', '272', '279', '281', '282', '292', '303', '307', '308', '312',
'315', '317', '322', '332', '334', '336', '338', '351', '353', '360',
'362', '382', '384', '385', '391', '403', '404', '413', '421', '450',
'458'],
dtype='object', name='Transformer')
INFO:linopy.model: Solve linear problem using Cbc solver
INFO:linopy.io:Writing objective.
Writing constraints.: 100%|██████████| 15/15 [00:00<00:00, 78.58it/s]
Writing continuous variables.: 100%|██████████| 7/7 [00:00<00:00, 256.72it/s]
INFO:linopy.io: Writing time: 0.23s
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 9940 primals, 23828 duals
Objective: 1.46e+06
Solver model: not available
Solver message: Optimal - objective value 1455232.67827293
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper, Line-fix-s-lower, Line-fix-s-upper, Transformer-fix-s-lower, Transformer-fix-s-upper, StorageUnit-fix-p_dispatch-lower, StorageUnit-fix-p_dispatch-upper, StorageUnit-fix-p_store-lower, StorageUnit-fix-p_store-upper, StorageUnit-fix-state_of_charge-lower, StorageUnit-fix-state_of_charge-upper, Kirchhoff-Voltage-Law, StorageUnit-energy_balance were not assigned to the network.
Welcome to the CBC MILP Solver
Version: 2.10.10
Build Date: Apr 19 2023
command line - cbc -printingOptions all -import /tmp/linopy-problem-r55yr3by.lp -solve -solu /tmp/linopy-solve-3siuuln9.sol (default strategy 1)
Option for printingOptions changed from normal to all
Presolve 2466 (-21362) rows, 4427 (-5513) columns and 17708 (-28342) elements
Perturbing problem by 0.001% of 2327.2654 - largest nonzero change 0.00099659414 ( 0.0084437175%) - largest zero change 0.00099290601
0 Obj 25318 Primal inf 5953235.3 (2283) Dual inf 257.04866 (1)
124 Obj 7980.1713 Primal inf 3678218.1 (2234)
248 Obj 7980.1713 Primal inf 3161230.9 (2154)
372 Obj 7980.1713 Primal inf 3159607.2 (2122)
496 Obj 7982.4593 Primal inf 3085333.4 (2087)
620 Obj 7984.9022 Primal inf 3765702.3 (2070)
744 Obj 7985.9546 Primal inf 11500073 (2026)
868 Obj 7989.4851 Primal inf 5994065.4 (1891)
992 Obj 7990.7625 Primal inf 2861796.1 (1806)
1116 Obj 7992.2846 Primal inf 9681223 (1816)
1240 Obj 7993.803 Primal inf 4222481.3 (1674)
1364 Obj 7995.6091 Primal inf 6182873.1 (1667)
1488 Obj 7997.6587 Primal inf 9164733.4 (1674)
1612 Obj 23733.32 Primal inf 8787498.2 (1554)
1736 Obj 23735.4 Primal inf 4137439.9 (1384)
1860 Obj 23737.272 Primal inf 1671432 (1195)
1984 Obj 32180.004 Primal inf 2642054.8 (1192)
2108 Obj 34252.04 Primal inf 534045.84 (736)
2232 Obj 61378.031 Primal inf 630584.17 (807)
2356 Obj 175374.62 Primal inf 700687.43 (751)
2480 Obj 394537.26 Primal inf 354882.56 (590)
2604 Obj 698709.87 Primal inf 110466.2 (415)
2728 Obj 1128187.8 Primal inf 42190.259 (327)
2852 Obj 1294953 Primal inf 24474.535 (226)
2976 Obj 1410172.6 Primal inf 12908.517 (128)
3100 Obj 1448466.5 Primal inf 3506.4167 (78)
3193 Obj 1455240
Optimal - objective value 1455232.7
After Postsolve, objective 1455232.7, infeasibilities - dual 24.259813 (1), primal 6.0436269e-07 (1)
Presolved model was optimal, full model needs cleaning up
0 Obj 1455232.7 Dual inf 0.28898438 (2)
End of values pass after 0 iterations
0 Obj 1455232.7 Dual inf 0.28898438 (2) w.o. free dual inf (1)
End of values pass after 1 iterations
1 Obj 1455232.7 Dual inf 0.046386348 (1) w.o. free dual inf (0)
2 Obj 1455232.7
Optimal - objective value 1455232.7
Optimal objective 1455232.678 - 3195 iterations time 0.402, Presolve 0.03
Total time (CPU seconds): 0.61 (Wallclock seconds): 0.57
WARNING:pypsa.components:The following transformers have zero r, which could break the linear load flow:
Index(['2', '5', '10', '12', '13', '15', '18', '20', '22', '24', '26', '30',
'32', '37', '42', '46', '52', '56', '61', '68', '69', '74', '78', '86',
'87', '94', '95', '96', '99', '100', '104', '105', '106', '107', '117',
'120', '123', '124', '125', '128', '129', '138', '143', '156', '157',
'159', '160', '165', '184', '191', '195', '201', '220', '231', '232',
'233', '236', '247', '248', '250', '251', '252', '261', '263', '264',
'267', '272', '279', '281', '282', '292', '303', '307', '308', '312',
'315', '317', '322', '332', '334', '336', '338', '351', '353', '360',
'362', '382', '384', '385', '391', '403', '404', '413', '421', '450',
'458'],
dtype='object', name='Transformer')
WARNING:pypsa.components:The following transformers have zero r, which could break the linear load flow:
Index(['2', '5', '10', '12', '13', '15', '18', '20', '22', '24', '26', '30',
'32', '37', '42', '46', '52', '56', '61', '68', '69', '74', '78', '86',
'87', '94', '95', '96', '99', '100', '104', '105', '106', '107', '117',
'120', '123', '124', '125', '128', '129', '138', '143', '156', '157',
'159', '160', '165', '184', '191', '195', '201', '220', '231', '232',
'233', '236', '247', '248', '250', '251', '252', '261', '263', '264',
'267', '272', '279', '281', '282', '292', '303', '307', '308', '312',
'315', '317', '322', '332', '334', '336', '338', '351', '353', '360',
'362', '382', '384', '385', '391', '403', '404', '413', '421', '450',
'458'],
dtype='object', name='Transformer')
INFO:linopy.model: Solve linear problem using Cbc solver
INFO:linopy.io:Writing objective.
Writing constraints.: 100%|██████████| 15/15 [00:00<00:00, 80.76it/s]
Writing continuous variables.: 100%|██████████| 7/7 [00:00<00:00, 246.60it/s]
INFO:linopy.io: Writing time: 0.23s
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 9940 primals, 23828 duals
Objective: 2.65e+06
Solver model: not available
Solver message: Optimal - objective value 2649026.44753696
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper, Line-fix-s-lower, Line-fix-s-upper, Transformer-fix-s-lower, Transformer-fix-s-upper, StorageUnit-fix-p_dispatch-lower, StorageUnit-fix-p_dispatch-upper, StorageUnit-fix-p_store-lower, StorageUnit-fix-p_store-upper, StorageUnit-fix-state_of_charge-lower, StorageUnit-fix-state_of_charge-upper, Kirchhoff-Voltage-Law, StorageUnit-energy_balance were not assigned to the network.
Welcome to the CBC MILP Solver
Version: 2.10.10
Build Date: Apr 19 2023
command line - cbc -printingOptions all -import /tmp/linopy-problem-k49vvuzj.lp -solve -solu /tmp/linopy-solve-zwb70h7x.sol (default strategy 1)
Option for printingOptions changed from normal to all
Presolve 2413 (-21415) rows, 4373 (-5567) columns and 17577 (-28473) elements
Perturbing problem by 0.001% of 2327.2654 - largest nonzero change 0.00099909145 ( 0.0082541046%) - largest zero change 0.00099876841
0 Obj 97183.555 Primal inf 6522465.4 (2248) Dual inf 1028.1946 (4)
123 Obj 28003.782 Primal inf 3713931.9 (2187)
246 Obj 28003.782 Primal inf 3443959.2 (2127)
369 Obj 28003.782 Primal inf 4098306.5 (2087)
492 Obj 28004.679 Primal inf 3403566.6 (2040)
615 Obj 28005.071 Primal inf 4309864.7 (2008)
738 Obj 28010.794 Primal inf 3240961.7 (1942)
861 Obj 28013.925 Primal inf 11770243 (1871)
984 Obj 28015.306 Primal inf 6287239.9 (1819)
1107 Obj 28016.582 Primal inf 3207929.1 (1725)
1230 Obj 28018.722 Primal inf 2963397.2 (1618)
1353 Obj 28021.1 Primal inf 19211549 (1568)
1476 Obj 59483.261 Primal inf 4440951.4 (1402)
1599 Obj 59485.129 Primal inf 2.7045896e+08 (1412)
1722 Obj 59489.804 Primal inf 90875714 (1361)
1845 Obj 59494.725 Primal inf 38184749 (1135)
1968 Obj 59504.152 Primal inf 916463.94 (915)
2091 Obj 130785.08 Primal inf 1206319.2 (903)
2214 Obj 344478.12 Primal inf 1.4278501e+08 (798)
2337 Obj 665395.07 Primal inf 2.0601155e+09 (792)
2460 Obj 1069728.2 Primal inf 1.4649021e+09 (798)
2583 Obj 1701403.9 Primal inf 59045004 (427)
2706 Obj 2141705.6 Primal inf 1.4640981e+08 (325)
2829 Obj 2401937.7 Primal inf 19895.418 (248)
2952 Obj 2591218.9 Primal inf 7624.9249 (149)
3075 Obj 2633322.5 Primal inf 16130.894 (156)
3198 Obj 2648504.4 Primal inf 38.482883 (41)
3233 Obj 2649041.8
Optimal - objective value 2649026.4
After Postsolve, objective 2649026.4, infeasibilities - dual 165.36547 (4), primal 1.0356107e-06 (4)
Presolved model was optimal, full model needs cleaning up
0 Obj 2649026.4 Dual inf 1.6536543 (4)
End of values pass after 14 iterations
14 Obj 2649026.4
Optimal - objective value 2649026.4
Optimal objective 2649026.448 - 3247 iterations time 0.382, Presolve 0.02
Total time (CPU seconds): 0.58 (Wallclock seconds): 0.56
WARNING:pypsa.components:The following transformers have zero r, which could break the linear load flow:
Index(['2', '5', '10', '12', '13', '15', '18', '20', '22', '24', '26', '30',
'32', '37', '42', '46', '52', '56', '61', '68', '69', '74', '78', '86',
'87', '94', '95', '96', '99', '100', '104', '105', '106', '107', '117',
'120', '123', '124', '125', '128', '129', '138', '143', '156', '157',
'159', '160', '165', '184', '191', '195', '201', '220', '231', '232',
'233', '236', '247', '248', '250', '251', '252', '261', '263', '264',
'267', '272', '279', '281', '282', '292', '303', '307', '308', '312',
'315', '317', '322', '332', '334', '336', '338', '351', '353', '360',
'362', '382', '384', '385', '391', '403', '404', '413', '421', '450',
'458'],
dtype='object', name='Transformer')
WARNING:pypsa.components:The following transformers have zero r, which could break the linear load flow:
Index(['2', '5', '10', '12', '13', '15', '18', '20', '22', '24', '26', '30',
'32', '37', '42', '46', '52', '56', '61', '68', '69', '74', '78', '86',
'87', '94', '95', '96', '99', '100', '104', '105', '106', '107', '117',
'120', '123', '124', '125', '128', '129', '138', '143', '156', '157',
'159', '160', '165', '184', '191', '195', '201', '220', '231', '232',
'233', '236', '247', '248', '250', '251', '252', '261', '263', '264',
'267', '272', '279', '281', '282', '292', '303', '307', '308', '312',
'315', '317', '322', '332', '334', '336', '338', '351', '353', '360',
'362', '382', '384', '385', '391', '403', '404', '413', '421', '450',
'458'],
dtype='object', name='Transformer')
INFO:linopy.model: Solve linear problem using Cbc solver
INFO:linopy.io:Writing objective.
Writing constraints.: 100%|██████████| 15/15 [00:00<00:00, 79.27it/s]
Writing continuous variables.: 100%|██████████| 7/7 [00:00<00:00, 253.75it/s]
INFO:linopy.io: Writing time: 0.23s
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 9940 primals, 23828 duals
Objective: 2.14e+06
Solver model: not available
Solver message: Optimal - objective value 2142956.88872811
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper, Line-fix-s-lower, Line-fix-s-upper, Transformer-fix-s-lower, Transformer-fix-s-upper, StorageUnit-fix-p_dispatch-lower, StorageUnit-fix-p_dispatch-upper, StorageUnit-fix-p_store-lower, StorageUnit-fix-p_store-upper, StorageUnit-fix-state_of_charge-lower, StorageUnit-fix-state_of_charge-upper, Kirchhoff-Voltage-Law, StorageUnit-energy_balance were not assigned to the network.
Welcome to the CBC MILP Solver
Version: 2.10.10
Build Date: Apr 19 2023
command line - cbc -printingOptions all -import /tmp/linopy-problem-k6kfcn14.lp -solve -solu /tmp/linopy-solve-obvr6v58.sol (default strategy 1)
Option for printingOptions changed from normal to all
Presolve 2419 (-21409) rows, 4370 (-5570) columns and 17602 (-28448) elements
Perturbing problem by 0.001% of 6880.5027 - largest nonzero change 0.00099919989 ( 0.0042006337%) - largest zero change 0.00099447956
0 Obj 92712.384 Primal inf 6319244.8 (2246) Dual inf 2421.7098 (4)
123 Obj 23361.441 Primal inf 4040192.4 (2206)
246 Obj 23361.441 Primal inf 3262836.9 (2154)
369 Obj 23361.441 Primal inf 2950810.8 (2079)
492 Obj 23362.526 Primal inf 3054064.2 (2052)
615 Obj 23363.285 Primal inf 2726340.5 (2002)
738 Obj 23364.506 Primal inf 2450128.5 (1918)
861 Obj 23365.55 Primal inf 3743974 (1873)
984 Obj 23366.807 Primal inf 3471253.9 (1820)
1107 Obj 23367.491 Primal inf 3430092.7 (1776)
1230 Obj 23368.564 Primal inf 3619425.4 (1668)
1353 Obj 23370.054 Primal inf 4148296 (1634)
1476 Obj 40820.437 Primal inf 3656378.9 (1460)
1599 Obj 40821.89 Primal inf 6246520.5 (1392)
1722 Obj 40823.744 Primal inf 13163866 (1275)
1845 Obj 40824.91 Primal inf 4691517.3 (1215)
1968 Obj 40827.697 Primal inf 25939416 (1116)
2091 Obj 60976.185 Primal inf 10484092 (990)
2214 Obj 185987.22 Primal inf 22073928 (890)
2337 Obj 343497.23 Primal inf 9168656.6 (789)
2460 Obj 806246.97 Primal inf 3719368.6 (599)
2583 Obj 1337036.3 Primal inf 141960.96 (425)
2706 Obj 1726216.5 Primal inf 28189.683 (295)
2829 Obj 1877231.4 Primal inf 14460.612 (250)
2952 Obj 2029306 Primal inf 26484.117 (311)
3075 Obj 2110041.7 Primal inf 2402.7327 (117)
3198 Obj 2135814.4 Primal inf 534.25763 (72)
3296 Obj 2142961.2
Optimal - objective value 2142956.9
After Postsolve, objective 2142956.9, infeasibilities - dual 137.65508 (4), primal 1.0570064e-06 (4)
Presolved model was optimal, full model needs cleaning up
0 Obj 2142956.9 Dual inf 1.3765504 (4)
End of values pass after 5 iterations
5 Obj 2142956.9
Optimal - objective value 2142956.9
Optimal objective 2142956.889 - 3301 iterations time 0.402, Presolve 0.02
Total time (CPU seconds): 0.59 (Wallclock seconds): 0.56
[10]:
p_by_carrier = network.generators_t.p.groupby(network.generators.carrier, axis=1).sum()
p_by_carrier.drop(
(p_by_carrier.max()[p_by_carrier.max() < 1700.0]).index, axis=1, inplace=True
)
p_by_carrier.columns
[10]:
Index(['Brown Coal', 'Gas', 'Hard Coal', 'Nuclear', 'Run of River', 'Solar',
'Wind Offshore', 'Wind Onshore'],
dtype='object', name='carrier')
[11]:
colors = {
"Brown Coal": "brown",
"Hard Coal": "k",
"Nuclear": "r",
"Run of River": "green",
"Wind Onshore": "blue",
"Solar": "yellow",
"Wind Offshore": "cyan",
"Waste": "orange",
"Gas": "orange",
}
# reorder
cols = [
"Nuclear",
"Run of River",
"Brown Coal",
"Hard Coal",
"Gas",
"Wind Offshore",
"Wind Onshore",
"Solar",
]
p_by_carrier = p_by_carrier[cols]
[12]:
c = [colors[col] for col in p_by_carrier.columns]
fig, ax = plt.subplots(figsize=(12, 6))
(p_by_carrier / 1e3).plot(kind="area", ax=ax, linewidth=4, color=c, alpha=0.7)
ax.legend(ncol=4, loc="upper left")
ax.set_ylabel("GW")
ax.set_xlabel("")
fig.tight_layout()
[13]:
fig, ax = plt.subplots(figsize=(12, 6))
p_storage = network.storage_units_t.p.sum(axis=1)
state_of_charge = network.storage_units_t.state_of_charge.sum(axis=1)
p_storage.plot(label="Pumped hydro dispatch", ax=ax, linewidth=3)
state_of_charge.plot(label="State of charge", ax=ax, linewidth=3)
ax.legend()
ax.grid()
ax.set_ylabel("MWh")
ax.set_xlabel("")
fig.tight_layout()
[14]:
now = network.snapshots[4]
With the linear load flow, there is the following per unit loading:
[15]:
loading = network.lines_t.p0.loc[now] / network.lines.s_nom
loading.describe()
[15]:
count 852.000000
mean -0.002892
std 0.258607
min -0.700000
25% -0.129689
50% 0.003084
75% 0.122643
max 0.700000
dtype: float64
[16]:
fig, ax = plt.subplots(subplot_kw={"projection": ccrs.EqualEarth()}, figsize=(9, 9))
network.plot(
ax=ax,
line_colors=abs(loading),
line_cmap=plt.cm.jet,
title="Line loading",
bus_sizes=1e-3,
bus_alpha=0.7,
)
fig.tight_layout();
/home/docs/checkouts/readthedocs.org/user_builds/pypsa/conda/v0.25.1/lib/python3.11/site-packages/cartopy/mpl/style.py:76: UserWarning: facecolor will have no effect as it has been defined as "never".
warnings.warn('facecolor will have no effect as it has been '
Let’s have a look at the marginal prices
[17]:
network.buses_t.marginal_price.loc[now].describe()
[17]:
count 585.000000
mean 15.737598
std 10.941995
min -10.397824
25% 6.992120
50% 15.841190
75% 25.048186
max 52.150120
Name: 2011-01-01 04:00:00, dtype: float64
[18]:
fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}, figsize=(8, 8))
plt.hexbin(
network.buses.x,
network.buses.y,
gridsize=20,
C=network.buses_t.marginal_price.loc[now],
cmap=plt.cm.jet,
zorder=3,
)
network.plot(ax=ax, line_widths=pd.Series(0.5, network.lines.index), bus_sizes=0)
cb = plt.colorbar(location="bottom")
cb.set_label("Locational Marginal Price (EUR/MWh)")
fig.tight_layout()
/home/docs/checkouts/readthedocs.org/user_builds/pypsa/conda/v0.25.1/lib/python3.11/site-packages/cartopy/mpl/style.py:76: UserWarning: facecolor will have no effect as it has been defined as "never".
warnings.warn('facecolor will have no effect as it has been '
Curtailment variable#
By considering how much power is available and how much is generated, you can see what share is curtailed:
[19]:
carrier = "Wind Onshore"
capacity = network.generators.groupby("carrier").sum().at[carrier, "p_nom"]
p_available = network.generators_t.p_max_pu.multiply(network.generators["p_nom"])
p_available_by_carrier = p_available.groupby(network.generators.carrier, axis=1).sum()
p_curtailed_by_carrier = p_available_by_carrier - p_by_carrier
[20]:
p_df = pd.DataFrame(
{
carrier + " available": p_available_by_carrier[carrier],
carrier + " dispatched": p_by_carrier[carrier],
carrier + " curtailed": p_curtailed_by_carrier[carrier],
}
)
p_df[carrier + " capacity"] = capacity
[21]:
p_df["Wind Onshore curtailed"][p_df["Wind Onshore curtailed"] < 0.0] = 0.0
[22]:
fig, ax = plt.subplots(figsize=(10, 4))
p_df[[carrier + " dispatched", carrier + " curtailed"]].plot(
kind="area", ax=ax, linewidth=3
)
p_df[[carrier + " available", carrier + " capacity"]].plot(ax=ax, linewidth=3)
ax.set_xlabel("")
ax.set_ylabel("Power [MW]")
ax.set_ylim([0, 40000])
ax.legend()
fig.tight_layout()
Non-Linear Power Flow#
Now perform a full Newton-Raphson power flow on the first hour. For the PF, set the P to the optimised P.
[23]:
network.generators_t.p_set = network.generators_t.p
network.storage_units_t.p_set = network.storage_units_t.p
Set all buses to PV, since we don’t know what Q set points are
[24]:
network.generators.control = "PV"
# Need some PQ buses so that Jacobian doesn't break
f = network.generators[network.generators.bus == "492"]
network.generators.loc[f.index, "control"] = "PQ"
Now, perform the non-linear PF.
[25]:
info = network.pf();
INFO:pypsa.pf:Performing non-linear load-flow on AC sub-network SubNetwork 0 for snapshots DatetimeIndex(['2011-01-01 00:00:00', '2011-01-01 01:00:00',
'2011-01-01 02:00:00', '2011-01-01 03:00:00',
'2011-01-01 04:00:00', '2011-01-01 05:00:00',
'2011-01-01 06:00:00', '2011-01-01 07:00:00',
'2011-01-01 08:00:00', '2011-01-01 09:00:00',
'2011-01-01 10:00:00', '2011-01-01 11:00:00',
'2011-01-01 12:00:00', '2011-01-01 13:00:00',
'2011-01-01 14:00:00', '2011-01-01 15:00:00',
'2011-01-01 16:00:00', '2011-01-01 17:00:00',
'2011-01-01 18:00:00', '2011-01-01 19:00:00',
'2011-01-01 20:00:00', '2011-01-01 21:00:00',
'2011-01-01 22:00:00', '2011-01-01 23:00:00'],
dtype='datetime64[ns]', name='snapshot', freq=None)
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.043731 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.044072 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.043288 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.044316 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.042980 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.044468 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.043098 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.043186 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.043176 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.042891 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.044288 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.044505 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.042956 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.042895 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.042972 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.043036 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.043306 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.043199 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.043259 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.042990 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.043490 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.043404 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.042988 seconds
INFO:pypsa.pf:Newton-Raphson solved in 4 iterations with error of 0.000000 in 0.043140 seconds
Any failed to converge?
[26]:
(~info.converged).any().any()
[26]:
False
With the non-linear load flow, there is the following per unit loading of the full thermal rating.
[27]:
(network.lines_t.p0.loc[now] / network.lines.s_nom).describe()
[27]:
count 852.000000
mean 0.000435
std 0.260958
min -0.813383
25% -0.125478
50% 0.003032
75% 0.126690
max 0.827203
dtype: float64
Let’s inspect the voltage angle differences across the lines have (in degrees)
[28]:
df = network.lines.copy()
for b in ["bus0", "bus1"]:
df = pd.merge(
df, network.buses_t.v_ang.loc[[now]].T, how="left", left_on=b, right_index=True
)
s = df[str(now) + "_x"] - df[str(now) + "_y"]
(s * 180 / np.pi).describe()
[28]:
count 852.000000
mean -0.022968
std 2.373833
min -12.158423
25% -0.462981
50% 0.001586
75% 0.537443
max 17.959258
dtype: float64
Plot the reactive power
[29]:
fig, ax = plt.subplots(subplot_kw={"projection": ccrs.EqualEarth()}, figsize=(9, 9))
q = network.buses_t.q.loc[now]
bus_colors = pd.Series("r", network.buses.index)
bus_colors[q < 0.0] = "b"
network.plot(
bus_sizes=1e-4 * abs(q),
ax=ax,
bus_colors=bus_colors,
title="Reactive power feed-in (red=+ve, blue=-ve)",
);
/home/docs/checkouts/readthedocs.org/user_builds/pypsa/conda/v0.25.1/lib/python3.11/site-packages/cartopy/mpl/style.py:76: UserWarning: facecolor will have no effect as it has been defined as "never".
warnings.warn('facecolor will have no effect as it has been '