Skip to content

Commit

Permalink
adressing #50 and some improvments
Browse files Browse the repository at this point in the history
  • Loading branch information
BDonnot committed Oct 4, 2023
1 parent c82bce9 commit 679bb65
Show file tree
Hide file tree
Showing 22 changed files with 353 additions and 102 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@ Change Log
- [ADDED] possibility to initialize a powergrid based on pypowsybl
- [ADDED] some more algorithm to perform powerflow: Fast Decoupled Powerflow (in BX and XB variant)
see https://github.com/BDonnot/lightsim2grid/issues/63
- [ADDED] build lightsim2grid for python 3.12
- [ADDED] support for non distributed slack but multiple slack buses
see https://github.com/BDonnot/lightsim2grid/issues/50 (ONLY FOR AC powerflow)
- [IMPROVED] now shipping `src` and `eigen` directory in the source of
lightsim2grid to allow their installation if wheels are not provided.
- [IMPROVED] in the underlying cpp GridModel powerlines can now have 2
different values for the `h` parameters (`h_or` and `h_ex`).
- [IMPROVED] now lightsim2grid is able to load a pandapower network with non
contiguous non starting at 0 bus index

[0.7.3/4] 2023-08-24
--------------------
Expand Down
8 changes: 5 additions & 3 deletions lightsim2grid/gridmodel/_aux_add_dc_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
# you can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
# This file is part of LightSim2grid, LightSim2grid implements a c++ backend targeting the Grid2Op platform.

import warnings

import numpy as np
from ._aux_add_sgen import SOME_KIND_OF_INF_FOR_PMIN_PMAX
from ._pp_bus_to_ls_bus import pp_bus_to_ls


def _aux_add_dc_line(model, pp_net):
def _aux_add_dc_line(model, pp_net, pp_to_ls):
"""
Add the transformers of the pp_net into the lightsim2grid "model"
Expand All @@ -33,8 +35,8 @@ def _aux_add_dc_line(model, pp_net):
# nothing to do if no dc line
return

branch_from_id = pp_net.dcline["from_bus"].values
branch_to_id = pp_net.dcline["to_bus"].values
branch_from_id = pp_bus_to_ls(pp_net.dcline["from_bus"].values, pp_to_ls)
branch_to_id = pp_bus_to_ls(pp_net.dcline["to_bus"].values, pp_to_ls)
p_mw = -pp_net.dcline["p_mw"].values
if np.any(~np.isfinite(p_mw)):
warnings.warn("Some non finite values are found for p_mw, they have been replaced by 0.")
Expand Down
8 changes: 5 additions & 3 deletions lightsim2grid/gridmodel/_aux_add_gen.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
# Copyright (c) 2020, RTE (https://www.rte-france.com)
# Copyright (c) 2020-2023, RTE (https://www.rte-france.com)
# See AUTHORS.txt
# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0.
# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file,
# you can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
# This file is part of LightSim2grid, LightSim2grid implements a c++ backend targeting the Grid2Op platform.

import numpy as np
from ._pp_bus_to_ls_bus import pp_bus_to_ls


def _aux_add_gen(model, pp_net):
def _aux_add_gen(model, pp_net, pp_to_ls):
"""
Add the generators of the pp_net into the lightsim2grid "model"
Expand All @@ -26,7 +28,7 @@ def _aux_add_gen(model, pp_net):
pp_net.gen["vm_pu"].values,
pp_net.gen["min_q_mvar"].values,
pp_net.gen["max_q_mvar"].values,
pp_net.gen["bus"].values
pp_bus_to_ls(pp_net.gen["bus"].values, pp_to_ls)
)
for gen_id, is_connected in enumerate(pp_net.gen["in_service"].values):
if not is_connected:
Expand Down
17 changes: 9 additions & 8 deletions lightsim2grid/gridmodel/_aux_add_line.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# Copyright (c) 2020, RTE (https://www.rte-france.com)
# Copyright (c) 2020-2023, RTE (https://www.rte-france.com)
# See AUTHORS.txt
# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0.
# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file,
# you can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
# This file is part of LightSim2grid, LightSim2grid implements a c++ backend targeting the Grid2Op platform.
import warnings

import numpy as np

from ._pp_bus_to_ls_bus import pp_bus_to_ls

def _aux_add_line(converter, model, pp_net):
def _aux_add_line(converter, model, pp_net, pp_to_ls=None):
"""
Add the lines of the pp_net into the lightsim2grid "model"
Expand All @@ -34,14 +35,14 @@ def _aux_add_line(converter, model, pp_net):
pp_net.line["x_ohm_per_km"].values * pp_net.line["length_km"].values,
pp_net.line["c_nf_per_km"].values * pp_net.line["length_km"].values,
pp_net.line["g_us_per_km"].values * pp_net.line["length_km"].values,
pp_net.bus.loc[pp_net.line["from_bus"]]["vn_kv"],
pp_net.bus.loc[pp_net.line["to_bus"]]["vn_kv"]
)
pp_net.bus.loc[pp_net.line["from_bus"]]["vn_kv"],
pp_net.bus.loc[pp_net.line["to_bus"]]["vn_kv"],
)

### add them to the grid
model.init_powerlines(line_r, line_x, line_h,
pp_net.line["from_bus"].values,
pp_net.line["to_bus"].values
pp_bus_to_ls(pp_net.line["from_bus"].values, pp_to_ls),
pp_bus_to_ls(pp_net.line["to_bus"].values, pp_to_ls)
)
for line_id, is_connected in enumerate(pp_net.line["in_service"].values):
if not is_connected:
Expand Down
17 changes: 12 additions & 5 deletions lightsim2grid/gridmodel/_aux_add_load.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
# Copyright (c) 2020, RTE (https://www.rte-france.com)
# Copyright (c) 2020-2023, RTE (https://www.rte-france.com)
# See AUTHORS.txt
# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0.
# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file,
# you can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
# This file is part of LightSim2grid, LightSim2grid implements a c++ backend targeting the Grid2Op platform.

import numpy as np

from ._pp_bus_to_ls_bus import pp_bus_to_ls

def _aux_add_load(model, pp_net):
def _aux_add_load(model, pp_net, pp_to_ls):
"""
Add the load of the pp_net into the lightsim2grid "model"
Expand All @@ -25,9 +27,14 @@ def _aux_add_load(model, pp_net):
raise RuntimeError("Cannot handle 'parallel' load columns. Please duplicate the rows if that is the case. "
"Some pp_net.load[\"parallel\"] != 1 it is not handled by lightsim yet.")

model.init_loads(pp_net.load["p_mw"].values,
pp_net.load["q_mvar"].values,
pp_net.load["bus"].values
ratio = 1.0
if "scaling" in pp_net.load:
ratio = pp_net.load["scaling"].values
ratio[~np.isfinite(ratio)] = 1.0

model.init_loads(pp_net.load["p_mw"].values * ratio,
pp_net.load["q_mvar"].values * ratio,
pp_bus_to_ls(pp_net.load["bus"].values, pp_to_ls)
)
for load_id, is_connected in enumerate(pp_net.load["in_service"].values):
if not is_connected:
Expand Down
17 changes: 12 additions & 5 deletions lightsim2grid/gridmodel/_aux_add_sgen.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
# Copyright (c) 2020, RTE (https://www.rte-france.com)
# Copyright (c) 2020-2023, RTE (https://www.rte-france.com)
# See AUTHORS.txt
# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0.
# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file,
# you can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
# This file is part of LightSim2grid, LightSim2grid implements a c++ backend targeting the Grid2Op platform.

import warnings
import numpy as np
from ._pp_bus_to_ls_bus import pp_bus_to_ls

SOME_KIND_OF_INF_FOR_PMIN_PMAX = 99999.


def _aux_add_sgen(model, pp_net):
def _aux_add_sgen(model, pp_net, pp_to_ls):
"""
Add the static generators (=PQ generators) of the pp_net into the lightsim2grid "model"
Expand Down Expand Up @@ -64,13 +66,18 @@ def _aux_add_sgen(model, pp_net):
warnings.warn("There were some Nan in the pp_net.sgen[\"max_q_mvar\"], they have been replaced by 0")
max_q_mvar[~np.isfinite(max_q_mvar)] = 0.

model.init_sgens(pp_net.sgen["p_mw"].values,
pp_net.sgen["q_mvar"].values,
ratio = 1.0
if "scaling" in pp_net.sgen:
ratio = pp_net.sgen["scaling"].values
ratio[~np.isfinite(ratio)] = 1.0

model.init_sgens(pp_net.sgen["p_mw"].values * ratio,
pp_net.sgen["q_mvar"].values * ratio,
min_p_mw,
max_p_mw,
min_q_mvar,
max_q_mvar,
pp_net.sgen["bus"].values
pp_bus_to_ls(pp_net.sgen["bus"].values, pp_to_ls)
)
for sgen_id, is_connected in enumerate(pp_net.sgen["in_service"].values):
if not is_connected:
Expand Down
6 changes: 4 additions & 2 deletions lightsim2grid/gridmodel/_aux_add_shunt.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
# you can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
# This file is part of LightSim2grid, LightSim2grid implements a c++ backend targeting the Grid2Op platform.

import numpy as np
from ._pp_bus_to_ls_bus import pp_bus_to_ls


def _aux_add_shunt(model, pp_net):
def _aux_add_shunt(model, pp_net, pp_to_ls):
"""
Add the shunts of the pp_net into the lightsim2grid "model"
Expand All @@ -31,7 +33,7 @@ def _aux_add_shunt(model, pp_net):

model.init_shunt(pp_net.shunt["p_mw"].values,
pp_net.shunt["q_mvar"].values,
pp_net.shunt["bus"].values
pp_bus_to_ls(pp_net.shunt["bus"].values, pp_to_ls)
)
for sh_id, is_connected in enumerate(pp_net.shunt["in_service"].values):
if not is_connected:
Expand Down
16 changes: 9 additions & 7 deletions lightsim2grid/gridmodel/_aux_add_slack.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
# Copyright (c) 2020, RTE (https://www.rte-france.com)
# Copyright (c) 2020-2023, RTE (https://www.rte-france.com)
# See AUTHORS.txt
# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0.
# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file,
# you can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
# This file is part of LightSim2grid, LightSim2grid implements a c++ backend targeting the Grid2Op platform.

import warnings
import numpy as np
from ._pp_bus_to_ls_bus import pp_bus_to_ls


def _aux_add_slack(model, pp_net):
def _aux_add_slack(model, pp_net, pp_to_ls):
"""
add the slack bus(es) to the lightsim2grid "model" based on the information in the pandapower network.
Expand Down Expand Up @@ -49,7 +51,7 @@ def _aux_add_slack(model, pp_net):

# in this case the ext grid is not taken into account, i raise a warning if
# there is one
slack_bus_ids = pp_net.ext_grid["bus"].values
slack_bus_ids = pp_bus_to_ls(pp_net.ext_grid["bus"].values, pp_to_ls)
if pp_net.ext_grid.shape[0] >= 1:
warnings.warn("LightSim will not consider the pandapower \"ext_grid\" as there "
"are already generators tagged as slack bus")
Expand All @@ -59,15 +61,15 @@ def _aux_add_slack(model, pp_net):
"I will attempt to add some from the ext_grid.")
# first i try to see if a generator is connected to a slack bus
# TODO SLACK: deactivate warnings (will be done at the end when more tests will be done)
slack_bus_ids = pp_net.ext_grid["bus"].values
slack_bus_ids = pp_bus_to_ls(pp_net.ext_grid["bus"].values, pp_to_ls)
# if pp_net.ext_grid.shape[0] >= 2:
# warnings.warn("LightSim cannot handle multiple slack bus at the moment. Only the first "
# "slack bus of pandapower will be used.")

if np.all(np.isin(slack_bus_ids, pp_net.gen["bus"].values)):
if np.all(np.isin(slack_bus_ids, pp_bus_to_ls(pp_net.gen["bus"].values, pp_to_ls))):
# all slack buses have a generator connected to them
# so i assume it was just a computation artifact, and assign these generators as slack buses
slack_gen_ids = np.isin(pp_net.gen["bus"].values, slack_bus_ids) # id of generators connected to slack bus
slack_gen_ids = np.isin(pp_bus_to_ls(pp_net.gen["bus"].values, pp_to_ls), slack_bus_ids) # id of generators connected to slack bus
slack_gen_ids = np.where(slack_gen_ids)[0] # keep only the id of the generators
if "slack_weight" in pp_net.gen:
slack_coeff = pp_net.gen["slack_weight"].values[slack_gen_ids]
Expand Down Expand Up @@ -100,7 +102,7 @@ def _aux_add_slack(model, pp_net):
vm_pu = 1.0 * pp_net.ext_grid["vm_pu"].values
gen_p = np.concatenate((pp_net.gen["p_mw"].values, slack_contrib))
gen_v = np.concatenate((pp_net.gen["vm_pu"].values, vm_pu))
gen_bus = np.concatenate((pp_net.gen["bus"].values, slack_bus_ids))
gen_bus = np.concatenate((pp_bus_to_ls(pp_net.gen["bus"].values, pp_to_ls), slack_bus_ids))
gen_min_q = np.concatenate((pp_net.gen["min_q_mvar"].values, [-999999.]))
gen_max_q = np.concatenate((pp_net.gen["max_q_mvar"].values, [+99999.]))
model.init_generators(gen_p, gen_v, gen_min_q, gen_max_q, gen_bus)
Expand Down
8 changes: 5 additions & 3 deletions lightsim2grid/gridmodel/_aux_add_storage.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
# Copyright (c) 2020, RTE (https://www.rte-france.com)
# Copyright (c) 2020-2023, RTE (https://www.rte-france.com)
# See AUTHORS.txt
# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0.
# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file,
# you can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
# This file is part of LightSim2grid, LightSim2grid implements a c++ backend targeting the Grid2Op platform.

import numpy as np
from ._pp_bus_to_ls_bus import pp_bus_to_ls


def _aux_add_storage(model, pp_net):
def _aux_add_storage(model, pp_net, pp_to_ls):
"""
Add the storages of the pp_net into the lightsim2grid "model"
Expand All @@ -28,7 +30,7 @@ def _aux_add_storage(model, pp_net):

model.init_storages(pp_net.storage["p_mw"].values,
pp_net.storage["q_mvar"].values,
pp_net.storage["bus"].values
pp_bus_to_ls(pp_net.storage["bus"].values, pp_to_ls)
)
for stor_id, is_connected in enumerate(pp_net.storage["in_service"].values):
if not is_connected:
Expand Down
10 changes: 6 additions & 4 deletions lightsim2grid/gridmodel/_aux_add_trafo.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
# Copyright (c) 2020, RTE (https://www.rte-france.com)
# Copyright (c) 2020-2023, RTE (https://www.rte-france.com)
# See AUTHORS.txt
# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0.
# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file,
# you can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
# This file is part of LightSim2grid, LightSim2grid implements a c++ backend targeting the Grid2Op platform.

import warnings
import numpy as np
from ._pp_bus_to_ls_bus import pp_bus_to_ls


def _aux_add_trafo(converter, model, pp_net):
def _aux_add_trafo(converter, model, pp_net, pp_to_ls):
"""
Add the transformers of the pp_net into the lightsim2grid "model"
Expand Down Expand Up @@ -89,8 +91,8 @@ def _aux_add_trafo(converter, model, pp_net):
tap_pos,
shift_,
is_tap_hv_side,
pp_net.trafo["hv_bus"].values,
pp_net.trafo["lv_bus"].values)
pp_bus_to_ls(pp_net.trafo["hv_bus"].values, pp_to_ls),
pp_bus_to_ls(pp_net.trafo["lv_bus"].values, pp_to_ls))

for tr_id, is_connected in enumerate(pp_net.trafo["in_service"].values):
if not is_connected:
Expand Down
11 changes: 6 additions & 5 deletions lightsim2grid/gridmodel/_aux_check_legit.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# Copyright (c) 2020, RTE (https://www.rte-france.com)
# Copyright (c) 2020-2023, RTE (https://www.rte-france.com)
# See AUTHORS.txt
# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0.
# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file,
# you can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
# This file is part of LightSim2grid, LightSim2grid implements a c++ backend targeting the Grid2Op platform.

import warnings
import numpy as np

Expand Down Expand Up @@ -47,10 +48,10 @@ def _aux_check_legit(pp_net):
# "in pandapower network")

# bus indexes should start at 0 and be contiguous
if np.any(np.sort(pp_net.bus.index) != np.arange(pp_net.bus.shape[0])):
raise RuntimeError("In order to work, pandapower bus indexes should start at 0 and be contiguous. "
"Make sure that `pp_net.bus.index` have this property. You can write a github "
"issue if you want improvment on this regard.")
# if np.any(np.sort(pp_net.bus.index) != np.arange(pp_net.bus.shape[0])):
# raise RuntimeError("In order to work, pandapower bus indexes should start at 0 and be contiguous. "
# "Make sure that `pp_net.bus.index` have this property. You can write a github "
# "issue if you want improvment on this regard.")

if "_options" in pp_net and \
"trafo_model" in pp_net["_options"] and \
Expand Down
16 changes: 16 additions & 0 deletions lightsim2grid/gridmodel/_pp_bus_to_ls_bus.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright (c) 2023, RTE (https://www.rte-france.com)
# See AUTHORS.txt
# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0.
# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file,
# you can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
# This file is part of LightSim2grid, LightSim2grid implements a c++ backend targeting the Grid2Op platform.

import numpy as np

def pp_bus_to_ls(pp_bus_id, pp_to_ls_converter):
if pp_to_ls_converter is None:
res = pp_bus_id
else:
res = np.array([pp_to_ls_converter[pp_id] for pp_id in pp_bus_id])
return res
Loading

0 comments on commit 679bb65

Please sign in to comment.