Skip to content

Commit

Permalink
fix a bug in the detection of the main component
Browse files Browse the repository at this point in the history
  • Loading branch information
BDonnot committed Dec 4, 2023
1 parent 54422ae commit d0840af
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 17 deletions.
22 changes: 11 additions & 11 deletions lightsim2grid/gridmodel/from_pypowsybl.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def init(net : pypo.network,
slack_bus_id: int = None,
sn_mva = 100.,
sort_index=True,
f_hz = 50.,
f_hz = 50., # unused
only_main_component=True):
model = GridModel()
# model.set_f_hz(f_hz)
Expand Down Expand Up @@ -89,8 +89,8 @@ def init(net : pypo.network,
for gen_id, is_disco in enumerate(gen_disco):
if is_disco:
model.deactivate_gen(gen_id)
model.set_gen_names(df_gen.index)
model.set_gen_names(df_gen.index)

# for loads
if sort_index:
df_load = net.get_loads().sort_index()
Expand All @@ -104,7 +104,7 @@ def init(net : pypo.network,
for load_id, is_disco in enumerate(load_disco):
if is_disco:
model.deactivate_load(load_id)
model.set_load_names(df_load.index)
model.set_load_names(df_load.index)

# for lines
if sort_index:
Expand Down Expand Up @@ -148,7 +148,7 @@ def init(net : pypo.network,
for line_id, (is_or_disc, is_ex_disc) in enumerate(zip(lor_disco, lex_disco)):
if is_or_disc or is_ex_disc:
model.deactivate_powerline(line_id)
model.set_line_names(df_line.index)
model.set_line_names(df_line.index)

# for trafo
if sort_index:
Expand Down Expand Up @@ -184,7 +184,7 @@ def init(net : pypo.network,
for t_id, (is_or_disc, is_ex_disc) in enumerate(zip(tor_disco, tex_disco)):
if is_or_disc or is_ex_disc:
model.deactivate_trafo(t_id)
model.set_trafo_names(df_trafo.index)
model.set_trafo_names(df_trafo.index)

# for shunt
if sort_index:
Expand All @@ -201,7 +201,7 @@ def init(net : pypo.network,
for shunt_id, disco in enumerate(sh_disco):
if disco:
model.deactivate_shunt(shunt_id)
model.set_shunt_names(df_trafo.index)
model.set_shunt_names(df_trafo.index)

# for hvdc (TODO not tested yet)
df_dc = net.get_hvdc_lines().sort_index()
Expand All @@ -228,7 +228,7 @@ def init(net : pypo.network,
for hvdc_id, (is_or_disc, is_ex_disc) in enumerate(zip(hvdc_from_disco, hvdc_to_disco)):
if is_or_disc or is_ex_disc:
model.deactivate_hvdc(hvdc_id)
model.set_dcline_names(df_sations.index)
model.set_dcline_names(df_sations.index)

# storage units (TODO not tested yet)
if sort_index:
Expand All @@ -243,7 +243,7 @@ def init(net : pypo.network,
for batt_id, disco in enumerate(batt_disco):
if disco:
model.deactivate_storage(batt_id)
model.set_storage_names(df_batt.index)
model.set_storage_names(df_batt.index)

# TODO dist slack
if gen_slack_id is None and slack_bus_id is None:
Expand All @@ -262,8 +262,8 @@ def init(net : pypo.network,
raise RuntimeError(f"There is no generator connected to bus {slack_bus_id}. It cannot be the slack")
for gen_id, is_slack in enumerate(gen_is_conn_slack):
if is_slack:
model.add_gen_slackbus(gen_id, 1. / nb_conn)
model.add_gen_slackbus(gen_id, 1. / nb_conn)

# TODO
# sgen => regular gen (from net.get_generators()) with voltage_regulator off TODO

Expand Down
1 change: 0 additions & 1 deletion lightsim2grid/lightSimBackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,6 @@ def make_complete_path(path, filename):
raise Grid2OpException('There is no powergrid at "{}"'.format(full_path))
return full_path
full_path = make_complete_path(path, filename)

grid_tmp = pypow_net.load(full_path)
gen_slack_id = None
if "gen_slack_id" in loader_kwargs:
Expand Down
3 changes: 2 additions & 1 deletion lightsim2grid/tests/test_backend_pypowsybl.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ def test_init(self):
grid.ac_pf(np.ones(14, dtype=np.complex128), 10, 1e-6)

def test_runpf(self):
backend = LightSimBackend(loader_method="pypowsybl", loader_kwargs=_aux_get_loader_kwargs())
backend = LightSimBackend(loader_method="pypowsybl",
loader_kwargs=_aux_get_loader_kwargs())
self._aux_prep_backend(backend)
# AC powerflow
conv, exc_ = backend.runpf()
Expand Down
10 changes: 7 additions & 3 deletions src/GridModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1002,20 +1002,25 @@ void GridModel::consider_only_main_component(){
// TODO copy paste from SecurityAnalysis
std::queue<Eigen::Index> neighborhood;
for(const auto & el : slack_buses_id) neighborhood.push(el);
if(neighborhood.empty()){
throw std::runtime_error("There is no slack buses defined in your grid. You cannot isolate the main component.");
}
std::vector<bool> visited(nb_busbars, false);
std::vector<bool> already_added(nb_busbars, false);
while (true)
{
const Eigen::Index col_id = neighborhood.front();
neighborhood.pop();
visited[col_id] = true;
for (Eigen::SparseMatrix<real_type>::InnerIterator it(graph, col_id); it; ++it)
{
// add in the queue all my neighbor (if the coefficient is big enough)
if(!visited[it.row()] ){ // && abs(it.value()) > 1e-8
if(!visited[it.row()] && !already_added[it.row()]){ // && abs(it.value()) > 1e-8
neighborhood.push(it.row());
already_added[it.row()] = true;
}
}
if(neighborhood.empty()) break;
neighborhood.pop();
}

// disconnected elements not in main component
Expand All @@ -1027,7 +1032,6 @@ void GridModel::consider_only_main_component(){
storages_.disconnect_if_not_in_main_component(visited);
generators_.disconnect_if_not_in_main_component(visited);
dc_lines_.disconnect_if_not_in_main_component(visited);

// and finally deal with the buses
init_bus_status();
}
4 changes: 3 additions & 1 deletion src/SecurityAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

bool SecurityAnalysis::check_invertible(const Eigen::SparseMatrix<cplx_type> & Ybus) const{
std::vector<bool> visited(Ybus.cols(), false);
std::vector<bool> already_added(Ybus.cols(), false);
std::queue<Eigen::Index> neighborhood;
Eigen::Index col_id = 0; // start by node 0, why not
while (true)
Expand All @@ -20,8 +21,9 @@ bool SecurityAnalysis::check_invertible(const Eigen::SparseMatrix<cplx_type> & Y
for (Eigen::SparseMatrix<cplx_type>::InnerIterator it(Ybus, col_id); it; ++it)
{
// add in the queue all my neighbor (if the coefficient is big enough)
if(!visited[it.row()] && abs(it.value()) > 1e-8){
if(!visited[it.row()] && !already_added[it.row()] && abs(it.value()) > 1e-8){
neighborhood.push(it.row());
already_added[it.row()] = true;
}
}
if(neighborhood.empty()) break;
Expand Down

0 comments on commit d0840af

Please sign in to comment.