Skip to content

Commit 964f50b

Browse files
Merge pull request #1105 from PowerGridModel/feature/refactor-y-bus-main-model
Clean-up main model: move y_bus related construction
2 parents 86ec472 + c2fe306 commit 964f50b

File tree

3 files changed

+186
-180
lines changed

3 files changed

+186
-180
lines changed

power_grid_model_c/power_grid_model/include/power_grid_model/main_core/math_state.hpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,25 @@ inline void clear(MathState& math_state) {
2323
math_state.y_bus_vec_asym.clear();
2424
}
2525

26+
template <symmetry_tag sym> std::vector<MathSolverProxy<sym>>& get_solvers(MathState& math_state) {
27+
if constexpr (is_symmetric_v<sym>) {
28+
return math_state.math_solvers_sym;
29+
} else {
30+
return math_state.math_solvers_asym;
31+
}
32+
}
33+
34+
template <symmetry_tag sym> inline auto& get_y_bus(MathState& math_state) {
35+
if constexpr (is_symmetric_v<sym>) {
36+
return math_state.y_bus_vec_sym;
37+
} else {
38+
return math_state.y_bus_vec_asym;
39+
}
40+
}
41+
2642
template <symmetry_tag sym>
2743
inline void update_y_bus(MathState& math_state, std::vector<MathModelParam<sym>> const& math_model_params) {
28-
auto& y_bus_vec = [&math_state]() -> auto& {
29-
if constexpr (is_symmetric_v<sym>) {
30-
return math_state.y_bus_vec_sym;
31-
} else {
32-
return math_state.y_bus_vec_asym;
33-
}
34-
}();
44+
auto& y_bus_vec = get_y_bus<sym>(math_state);
3545

3646
assert(y_bus_vec.size() == math_model_params.size());
3747

@@ -43,13 +53,7 @@ inline void update_y_bus(MathState& math_state, std::vector<MathModelParam<sym>>
4353
template <symmetry_tag sym>
4454
inline void update_y_bus(MathState& math_state, std::vector<MathModelParam<sym>> const& math_model_params,
4555
std::vector<MathModelParamIncrement> const& math_model_param_increments) {
46-
auto& y_bus_vec = [&math_state]() -> auto& {
47-
if constexpr (is_symmetric_v<sym>) {
48-
return math_state.y_bus_vec_sym;
49-
} else {
50-
return math_state.y_bus_vec_asym;
51-
}
52-
}();
56+
auto& y_bus_vec = get_y_bus<sym>(math_state);
5357

5458
assert(y_bus_vec.size() == math_model_params.size());
5559

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
// SPDX-FileCopyrightText: Contributors to the Power Grid Model project <[email protected]>
2+
//
3+
// SPDX-License-Identifier: MPL-2.0
4+
5+
#pragma once
6+
7+
namespace power_grid_model::main_core {
8+
9+
template <symmetry_tag sym, typename ComponentContainer, typename... ComponentType>
10+
void prepare_y_bus(MainModelState<ComponentContainer> const& state_, Idx n_math_solvers_, MathState& math_state_) {
11+
std::vector<YBus<sym>>& y_bus_vec = main_core::get_y_bus<sym>(math_state_);
12+
// also get the vector of other Y_bus (sym -> asym, or asym -> sym)
13+
std::vector<YBus<other_symmetry_t<sym>>>& other_y_bus_vec =
14+
main_core::get_y_bus<other_symmetry_t<sym>>(math_state_);
15+
// If no Ybus exists, build them
16+
if (y_bus_vec.empty()) {
17+
bool const other_y_bus_exist = (!other_y_bus_vec.empty());
18+
y_bus_vec.reserve(n_math_solvers_);
19+
auto math_params = get_math_param<sym>(state_, n_math_solvers_);
20+
21+
// Check the branch and shunt indices
22+
constexpr auto branch_param_in_seq_map =
23+
std::array{main_core::utils::index_of_component<Line, ComponentType...>,
24+
main_core::utils::index_of_component<Link, ComponentType...>,
25+
main_core::utils::index_of_component<Transformer, ComponentType...>};
26+
constexpr auto shunt_param_in_seq_map =
27+
std::array{main_core::utils::index_of_component<Shunt, ComponentType...>};
28+
29+
for (Idx i = 0; i != n_math_solvers_; ++i) {
30+
// construct from existing Y_bus structure if possible
31+
if (other_y_bus_exist) {
32+
y_bus_vec.emplace_back(state_.math_topology[i],
33+
std::make_shared<MathModelParam<sym> const>(std::move(math_params[i])),
34+
other_y_bus_vec[i].get_y_bus_structure());
35+
} else {
36+
y_bus_vec.emplace_back(state_.math_topology[i],
37+
std::make_shared<MathModelParam<sym> const>(std::move(math_params[i])));
38+
}
39+
40+
y_bus_vec.back().set_branch_param_idx(
41+
IdxVector{branch_param_in_seq_map.begin(), branch_param_in_seq_map.end()});
42+
y_bus_vec.back().set_shunt_param_idx(
43+
IdxVector{shunt_param_in_seq_map.begin(), shunt_param_in_seq_map.end()});
44+
}
45+
}
46+
}
47+
48+
template <symmetry_tag sym, typename ComponentContainer, typename... ComponentType>
49+
static std::vector<MathModelParamIncrement> get_math_param_increment(
50+
MainModelState<ComponentContainer> received_state, Idx n_math_solvers_,
51+
std::array<std::vector<Idx2D>, main_core::utils::n_types<ComponentType...>> const& parameter_changed_components_) {
52+
using AddToIncrement =
53+
void (*)(std::vector<MathModelParamIncrement>&, MainModelState<ComponentContainer> const&, Idx2D const&);
54+
55+
static constexpr std::array<AddToIncrement, main_core::utils::n_types<ComponentType...>> add_to_increments{
56+
[](std::vector<MathModelParamIncrement>& increments, MainModelState<ComponentContainer> const& state,
57+
Idx2D const& changed_component_idx) {
58+
if constexpr (std::derived_from<ComponentType, Branch>) {
59+
Idx2D const math_idx =
60+
state.topo_comp_coup
61+
->branch[main_core::get_component_sequence_idx<Branch>(state, changed_component_idx)];
62+
if (math_idx.group == isolated_component) {
63+
return;
64+
}
65+
// assign parameters
66+
increments[math_idx.group].branch_param_to_change.push_back(math_idx.pos);
67+
} else if constexpr (std::derived_from<ComponentType, Branch3>) {
68+
Idx2DBranch3 const math_idx =
69+
state.topo_comp_coup
70+
->branch3[main_core::get_component_sequence_idx<Branch3>(state, changed_component_idx)];
71+
if (math_idx.group == isolated_component) {
72+
return;
73+
}
74+
// assign parameters, branch3 param consists of three branch parameters
75+
for (size_t branch2 = 0; branch2 < 3; ++branch2) {
76+
increments[math_idx.group].branch_param_to_change.push_back(math_idx.pos[branch2]);
77+
}
78+
} else if constexpr (std::same_as<ComponentType, Shunt>) {
79+
Idx2D const math_idx =
80+
state.topo_comp_coup
81+
->shunt[main_core::get_component_sequence_idx<Shunt>(state, changed_component_idx)];
82+
if (math_idx.group == isolated_component) {
83+
return;
84+
}
85+
// assign parameters
86+
increments[math_idx.group].shunt_param_to_change.push_back(math_idx.pos);
87+
}
88+
}...};
89+
90+
std::vector<MathModelParamIncrement> math_param_increment(n_math_solvers_);
91+
92+
for (size_t i = 0; i < main_core::utils::n_types<ComponentType...>; ++i) {
93+
auto const& changed_type_components = parameter_changed_components_[i];
94+
auto const& add_type_to_increment = add_to_increments[i];
95+
for (auto const& changed_component : changed_type_components) {
96+
add_type_to_increment(math_param_increment, received_state, changed_component);
97+
}
98+
}
99+
100+
return math_param_increment;
101+
}
102+
103+
template <symmetry_tag sym>
104+
std::vector<MathModelParam<sym>> get_math_param(main_model_state_c auto const& state, Idx n_math_solvers) {
105+
std::vector<MathModelParam<sym>> math_param(n_math_solvers);
106+
for (Idx i = 0; i != n_math_solvers; ++i) {
107+
math_param[i].branch_param.resize(state.math_topology[i]->n_branch());
108+
math_param[i].shunt_param.resize(state.math_topology[i]->n_shunt());
109+
math_param[i].source_param.resize(state.math_topology[i]->n_source());
110+
}
111+
// loop all branch
112+
for (Idx i = 0; i != static_cast<Idx>(state.comp_topo->branch_node_idx.size()); ++i) {
113+
Idx2D const math_idx = state.topo_comp_coup->branch[i];
114+
if (math_idx.group == isolated_component) {
115+
continue;
116+
}
117+
// assign parameters
118+
math_param[math_idx.group].branch_param[math_idx.pos] =
119+
state.components.template get_item_by_seq<Branch>(i).template calc_param<sym>();
120+
}
121+
// loop all branch3
122+
for (Idx i = 0; i != static_cast<Idx>(state.comp_topo->branch3_node_idx.size()); ++i) {
123+
Idx2DBranch3 const math_idx = state.topo_comp_coup->branch3[i];
124+
if (math_idx.group == isolated_component) {
125+
continue;
126+
}
127+
// assign parameters, branch3 param consists of three branch parameters
128+
auto const branch3_param = state.components.template get_item_by_seq<Branch3>(i).template calc_param<sym>();
129+
for (size_t branch2 = 0; branch2 < 3; ++branch2) {
130+
math_param[math_idx.group].branch_param[math_idx.pos[branch2]] = branch3_param[branch2];
131+
}
132+
}
133+
// loop all shunt
134+
for (Idx i = 0; i != static_cast<Idx>(state.comp_topo->shunt_node_idx.size()); ++i) {
135+
Idx2D const math_idx = state.topo_comp_coup->shunt[i];
136+
if (math_idx.group == isolated_component) {
137+
continue;
138+
}
139+
// assign parameters
140+
math_param[math_idx.group].shunt_param[math_idx.pos] =
141+
state.components.template get_item_by_seq<Shunt>(i).template calc_param<sym>();
142+
}
143+
// loop all source
144+
for (Idx i = 0; i != static_cast<Idx>(state.comp_topo->source_node_idx.size()); ++i) {
145+
Idx2D const math_idx = state.topo_comp_coup->source[i];
146+
if (math_idx.group == isolated_component) {
147+
continue;
148+
}
149+
// assign parameters
150+
math_param[math_idx.group].source_param[math_idx.pos] =
151+
state.components.template get_item_by_seq<Source>(i).template math_param<sym>();
152+
}
153+
return math_param;
154+
}
155+
156+
} // namespace power_grid_model::main_core

0 commit comments

Comments
 (0)