-
Notifications
You must be signed in to change notification settings - Fork 204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Linopy transition #796
Linopy transition #796
Changes from all commits
08c4643
28e1168
23dcbc4
4bb5327
3dd5078
f2945c4
7ca9ee5
bf4c5ab
f11d5da
4c2d346
97b24e6
004a850
f19c69c
3d72eee
f94362b
6b302f8
28877d3
060b973
e953d5a
5fd8060
f86da66
0e7d145
a2a48f7
2be7fe1
70b6d04
377455e
a01f188
644c2ea
d210ce1
c4016e2
5669f31
5991ca7
32674db
87ff6dd
7026712
c444005
a7db9bb
ac4e5a5
2074e18
5998973
f932c6a
be6905d
fef6951
a6ee0a5
577464c
417bf62
6b060d0
cfb251f
26849ab
60faf63
f54d1f6
cbea30e
6a7e770
e7bd8bb
0e50477
d014acc
56ce52e
c1155c3
a3cbd04
671dbb5
78ca7d0
564fd05
0ea2125
b62ed10
194ff0e
e907991
6ec28f1
f0c95cb
4b5d8da
1affa86
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -513,6 +513,18 @@ def base_network( | |
|
||
if hvdc_as_lines_config: | ||
lines = pd.concat([lines_ac, lines_dc]) | ||
lines.drop( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Generally, I'd recommend to do the converse: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Absolutely agree that explicit definition would work better there. Moreover, the updated PyPSA version is not very stable in what relates to the data structures. Custom columns are not forbidden explicitly, but can lead to some weird issues. So, I'd be very careful in dealing with them. In a dedicated PR, have moved the definition of lines columns in the previous script. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great! What would be your idea here, merge this and then 1065, merge 1065 here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have created a PR on top of #1065 which enables linopy in addition to the upgrade of PyPSA version |
||
labels=[ | ||
"bus0_lon", | ||
"bus0_lat", | ||
"bus1_lon", | ||
"bus1_lat", | ||
"bus_0_coors", | ||
"bus_1_coors", | ||
], | ||
axis=1, | ||
inplace=True, | ||
) | ||
n.import_components_from_dataframe(lines, "Line") | ||
else: | ||
lines_dc = _set_electrical_parameters_links(links_config, lines_dc) | ||
|
@@ -522,6 +534,18 @@ def base_network( | |
axis=1, | ||
result_type="reduce", | ||
) | ||
lines_ac.drop( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in #1065: no need for the drop in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great! What would be your idea here, merge this and then 1065, merge 1065 here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Have created a PR on top of #1065 which enables linopy in addition to the upgrade of PyPSA version |
||
labels=[ | ||
"bus0_lon", | ||
"bus0_lat", | ||
"bus1_lon", | ||
"bus1_lat", | ||
"bus_0_coors", | ||
"bus_1_coors", | ||
], | ||
axis=1, | ||
inplace=True, | ||
) | ||
n.import_components_from_dataframe(lines_ac, "Line") | ||
# The columns which names starts with "bus" are mixed up with the third-bus specification | ||
# when executing additional_linkports() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -125,15 +125,14 @@ | |
from functools import reduce | ||
|
||
import geopandas as gpd | ||
import linopy | ||
import numpy as np | ||
import pandas as pd | ||
import pyomo.environ as po | ||
import pypsa | ||
from _helpers import ( | ||
REGION_COLS, | ||
configure_logging, | ||
create_logger, | ||
get_aggregation_strategies, | ||
sets_path_to_root, | ||
update_p_nom_max, | ||
) | ||
|
@@ -336,47 +335,22 @@ def distribute_clusters( | |
distribution_factor.sum(), 1.0, rtol=1e-3 | ||
), f"Country weights L must sum up to 1.0 when distributing clusters. Is {distribution_factor.sum()}." | ||
|
||
m = po.ConcreteModel() | ||
|
||
def n_bounds(model, *n_id): | ||
""" | ||
Create a function that makes a bound pair for pyomo. | ||
|
||
Use n_bounds(model, n_id) if N is Single-Index | ||
Use n_bounds(model, *n_id) if N is Multi-Index | ||
Example: https://pyomo.readthedocs.io/en/stable/pyomo_modeling_components/Variables.html | ||
|
||
Returns | ||
------- | ||
bounds = A function (or Python object) that gives a (lower,upper) bound pair i.e.(1,10) for the variable | ||
""" | ||
return (1, N[n_id]) | ||
|
||
m.n = po.Var(list(distribution_factor.index), bounds=n_bounds, domain=po.Integers) | ||
m.tot = po.Constraint(expr=(po.summation(m.n) == n_clusters)) | ||
m.objective = po.Objective( | ||
expr=sum( | ||
(m.n[i] - distribution_factor.loc[i] * n_clusters) ** 2 | ||
for i in distribution_factor.index | ||
), | ||
sense=po.minimize, | ||
m = linopy.Model() | ||
clusters = m.add_variables( | ||
lower=1, upper=N, coords=[L.index], name="n", integer=True | ||
) | ||
|
||
opt = po.SolverFactory(solver_name) | ||
if not opt.has_capability("quadratic_objective"): | ||
logger.warning( | ||
f"The configured solver `{solver_name}` does not support quadratic objectives. Falling back to `ipopt`." | ||
m.add_constraints(clusters.sum() == n_clusters, name="tot") | ||
# leave out constant in objective (L * n_clusters) ** 2 | ||
m.objective = (clusters * clusters - 2 * clusters * L * n_clusters).sum() | ||
if solver_name == "gurobi": | ||
logging.getLogger("gurobipy").propagate = False | ||
elif solver_name != "scip": | ||
logger.info( | ||
f"The configured solver `{solver_name}` does not support quadratic objectives. Falling back to `scip`." | ||
) | ||
opt = po.SolverFactory("ipopt") | ||
|
||
results = opt.solve(m) | ||
assert ( | ||
results["Solver"][0]["Status"] == "ok" | ||
), f"Solver returned non-optimally: {results}" | ||
|
||
return ( | ||
pd.Series(m.n.get_values(), index=distribution_factor.index).round().astype(int) | ||
) | ||
solver_name = "scip" | ||
m.solve(solver_name=solver_name) | ||
return m.solution["n"].to_series().astype(int) | ||
|
||
|
||
def busmap_for_gadm_clusters(inputs, n, gadm_level, geo_crs, country_list): | ||
|
@@ -577,9 +551,10 @@ def clustering_for_n_clusters( | |
extended_link_costs=0, | ||
focus_weights=None, | ||
): | ||
bus_strategies, generator_strategies = get_aggregation_strategies( | ||
aggregation_strategies | ||
) | ||
line_strategies = aggregation_strategies.get("lines", dict()) | ||
line_strategies.update({"geometry": "first", "bounds": "first"}) | ||
generator_strategies = aggregation_strategies.get("generators", dict()) | ||
one_port_strategies = aggregation_strategies.get("one_ports", dict()) | ||
|
||
if not isinstance(custom_busmap, pd.Series): | ||
if alternative_clustering: | ||
|
@@ -605,12 +580,20 @@ def clustering_for_n_clusters( | |
clustering = get_clustering_from_busmap( | ||
n, | ||
busmap, | ||
bus_strategies=bus_strategies, | ||
aggregate_generators_weighted=True, | ||
aggregate_generators_carriers=aggregate_carriers, | ||
aggregate_one_ports=["Load", "StorageUnit"], | ||
line_length_factor=line_length_factor, | ||
line_strategies=line_strategies, | ||
generator_strategies=generator_strategies, | ||
bus_strategies={ | ||
"lat": "mean", | ||
"lon": "mean", | ||
"tag_substation": "first", | ||
"tag_area": "first", | ||
"country": "first", | ||
}, | ||
Comment on lines
+589
to
+595
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a bit widely duplicated across scripts. v_nom is also not here, may this be somewhat linked to the issue by Emmanuel? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree that the duplication should be fixed. Implemented in #1065 as an update of the aggregation strategies outside the clustering functions. Yeah, it looks like transparence is much desired in working with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good! What would be your idea here, merge this and then 1065, merge 1065 here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think it could make sense to have a stacked PR: a PR on top of #1065 which enables linopy in addition to the upgrade of PyPSA version |
||
one_port_strategies=one_port_strategies, | ||
scale_link_capital_costs=False, | ||
) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add >=0.2X in agreement to the expected version; it is not backcompatible unfortunately
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in #1065