Skip to content
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

Optional ID structural refactor #828

Merged
merged 38 commits into from
Nov 25, 2024
Merged
Changes from 5 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
9810322
Removed hardoded -1s
figueroa1395 Nov 11, 2024
56534a8
Nipick renaming
figueroa1395 Nov 11, 2024
e7e734c
refactor check_components_independence
figueroa1395 Nov 11, 2024
1bc81f6
Merge branch 'feature/refactor-optional-id' into feature/optional-id-…
figueroa1395 Nov 11, 2024
4640a90
make MSVC happy
figueroa1395 Nov 11, 2024
9cdb0d6
minor update_component refactor
figueroa1395 Nov 12, 2024
a118af8
main model utils introduced
figueroa1395 Nov 12, 2024
ba0a0b8
moved check_id_na
figueroa1395 Nov 12, 2024
7688198
moved UpdateCompProperties and process_buffer_span
figueroa1395 Nov 12, 2024
15a62c9
moved check_component_independence
figueroa1395 Nov 12, 2024
e01c16e
Merge branch 'feature/refactor-optional-id' into feature/optional-id-…
figueroa1395 Nov 12, 2024
954e933
clang tidy
figueroa1395 Nov 13, 2024
104c9fe
moved validate_update_independence and corrected namespace name
figueroa1395 Nov 13, 2024
e6fddf2
Merge branch 'feature/refactor-optional-id' into feature/optional-id-…
figueroa1395 Nov 13, 2024
5f94b0c
actually solve merge conflicts
figueroa1395 Nov 13, 2024
c509044
refactored is_update_independent
figueroa1395 Nov 13, 2024
366b424
removed string lookup
figueroa1395 Nov 13, 2024
44b4233
moved get_component_sequence
figueroa1395 Nov 14, 2024
e4bf1a3
move get_sequence_idx_map
figueroa1395 Nov 14, 2024
c4eb684
Fix tests
figueroa1395 Nov 15, 2024
2143cba
fixed bug - finally
figueroa1395 Nov 15, 2024
cc76897
re-organize
figueroa1395 Nov 15, 2024
1a89659
Merge branch 'main' into feature/optional-id-refactor-part2
figueroa1395 Nov 15, 2024
e474644
address comments
figueroa1395 Nov 18, 2024
67929c5
addressed comments
figueroa1395 Nov 18, 2024
5767a9a
Merge branch 'main' into feature/optional-id-refactor-part2
figueroa1395 Nov 18, 2024
f7c64c9
minor
figueroa1395 Nov 19, 2024
297d2d7
rename get_comp_seq in state_queries
figueroa1395 Nov 19, 2024
8cabc92
Merge pull request #836 from PowerGridModel/get_component_sequence-re…
Jerry-Jinfeng-Guo Nov 19, 2024
4022bac
addess comments
figueroa1395 Nov 20, 2024
b6c4f4d
minor
figueroa1395 Nov 20, 2024
acf5c96
address comments
figueroa1395 Nov 21, 2024
979b9f8
address comments
figueroa1395 Nov 22, 2024
f5134f9
Merge branch 'main' into feature/optional-id-refactor-part2
figueroa1395 Nov 22, 2024
2a9bc41
removed redundant usings
figueroa1395 Nov 22, 2024
c56adb2
final refactor attempt
figueroa1395 Nov 22, 2024
520c174
Revert "final refactor attempt"
figueroa1395 Nov 25, 2024
1f5bb5f
Merge branch 'main' into feature/optional-id-refactor-part2
mgovers Nov 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,12 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
using ComponentFlags = std::array<bool, n_types>;
using ComponentCountInBase = std::pair<std::string, Idx>;
figueroa1395 marked this conversation as resolved.
Show resolved Hide resolved

// TODO: (figueroa1395) probably move to common.hpp or somewhere else
figueroa1395 marked this conversation as resolved.
Show resolved Hide resolved
static constexpr Idx ignore_output{-1};
static constexpr Idx invalid_index{-1};
static constexpr Idx isolated_component{-1};
static constexpr Idx not_connected{-1};
static constexpr Idx sequential{-1};
figueroa1395 marked this conversation as resolved.
Show resolved Hide resolved

protected:
// run functors with all component types
Expand Down Expand Up @@ -435,7 +439,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
if (!std::get<index_of_component<CT>>(to_store)) {
return std::vector<Idx2D>{};
}
auto const independence = check_components_independence<CT>(update_data);
auto const independence = check_component_independence<CT>(update_data);
validate_update_data_independence(independence);
return get_component_sequence<CT>(update_data, scenario_idx, independence);
});
Expand Down Expand Up @@ -552,7 +556,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
template <typename Calculate>
requires std::invocable<std::remove_cvref_t<Calculate>, MainModelImpl&, MutableDataset const&, Idx>
BatchParameter batch_calculation_(Calculate&& calculation_fn, MutableDataset const& result_data,
ConstDataset const& update_data, Idx threading = -1) {
ConstDataset const& update_data, Idx threading = sequential) {
figueroa1395 marked this conversation as resolved.
Show resolved Hide resolved
// if the update dataset is empty without any component
// execute one power flow in the current instance, no batch calculation is needed
if (update_data.empty()) {
Expand Down Expand Up @@ -703,21 +707,22 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
}

static auto scenario_update_restore(MainModelImpl& model, ConstDataset const& update_data,
ComponentFlags const& is_independent, SequenceIdx const& all_scenario_sequence,
ComponentFlags const& independence_flags,
SequenceIdx const& all_scenario_sequence,
SequenceIdx& current_scenario_sequence_cache,
std::vector<CalculationInfo>& infos) noexcept {
auto do_update_cache = [&is_independent] {
auto do_update_cache = [&independence_flags] {
ComponentFlags result;
std::ranges::transform(is_independent, result.begin(), std::logical_not<>{});
std::ranges::transform(independence_flags, result.begin(), std::logical_not<>{});
return result;
}();

auto const scenario_sequence = [&all_scenario_sequence, &current_scenario_sequence_cache,
&is_independent]() -> SequenceIdxView {
&independence_flags]() -> SequenceIdxView {
return run_functor_with_all_types_return_array(
[&all_scenario_sequence, &current_scenario_sequence_cache, &is_independent]<typename CT>() {
[&all_scenario_sequence, &current_scenario_sequence_cache, &independence_flags]<typename CT>() {
constexpr auto comp_idx = index_of_component<CT>;
if (std::get<comp_idx>(is_independent)) {
if (std::get<comp_idx>(independence_flags)) {
return std::span<Idx2D const>{std::get<comp_idx>(all_scenario_sequence)};
}
return std::span<Idx2D const>{std::get<comp_idx>(current_scenario_sequence_cache)};
Expand Down Expand Up @@ -778,79 +783,76 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
public:
template <class Component> using UpdateType = typename Component::UpdateType;

template <class CompType>
UpdateCompProperties check_components_independence(ConstDataset const& update_data) const {
auto const comp_count_in_base = this->component_count<CompType>();

auto const check_id_na = [](auto const& obj) -> bool {
if constexpr (requires { obj.id; }) {
return is_nan(obj.id);
} else if constexpr (requires { obj.get().id; }) {
return is_nan(obj.get().id);
} else {
throw UnreachableHit{"check_components_independence", "Only components with id are supported"};
}
};

auto const process_buffer_span = [check_id_na](auto const& all_spans, UpdateCompProperties& result) {
result.ids_all_na = std::ranges::all_of(
all_spans, [&check_id_na](auto const& vec) { return std::ranges::all_of(vec, check_id_na); });
result.ids_part_na =
std::ranges::any_of(
all_spans, [&check_id_na](auto const& vec) { return std::ranges::any_of(vec, check_id_na); }) &&
!result.ids_all_na;
template <typename T> bool check_id_na(T const& obj) const {
if constexpr (requires { obj.id; }) {
return is_nan(obj.id);
} else if constexpr (requires { obj.get().id; }) {
return is_nan(obj.get().id);
} else {
throw UnreachableHit{"check_component_independence", "Only components with id are supported"};
}
}

if (all_spans.empty()) {
result.update_ids_match = true;
} else {
// Remember the begin iterator of the first scenario, then loop over the remaining scenarios and
// check the ids
auto const first_span = all_spans[0];
// check the subsequent scenarios
// only return true if all scenarios match the ids of the first batch
result.update_ids_match = std::ranges::all_of(
all_spans.cbegin() + 1, all_spans.cend(), [&first_span](auto const& current_span) {
return std::ranges::equal(current_span, first_span,
[](UpdateType<CompType> const& obj,
UpdateType<CompType> const& first) { return obj.id == first.id; });
});
}
};
template <typename CompType>
void process_buffer_span(auto const& all_spans, UpdateCompProperties& properties) const {
properties.ids_all_na = std::ranges::all_of(all_spans, [this](auto const& vec) {
return std::ranges::all_of(vec, [this](auto const& item) { return this->check_id_na(item); });
});
properties.ids_part_na = std::ranges::any_of(all_spans,
[this](auto const& vec) {
return std::ranges::any_of(vec, [this](auto const& item) {
return this->check_id_na(item);
});
}) &&
!properties.ids_all_na;

if (all_spans.empty()) {
properties.update_ids_match = true;
} else {
// Remember the begin iterator of the first scenario, then loop over the remaining scenarios and
// check the ids
auto const first_span = all_spans[0];
// check the subsequent scenarios
// only return true if all scenarios match the ids of the first batch
properties.update_ids_match =
std::ranges::all_of(all_spans.cbegin() + 1, all_spans.cend(), [&first_span](auto const& current_span) {
return std::ranges::equal(current_span, first_span,
[](UpdateType<CompType> const& obj, UpdateType<CompType> const& first) {
return obj.id == first.id;
});
});
}
}

auto const check_each_component = [&update_data, &process_buffer_span,
&comp_count_in_base]() -> UpdateCompProperties {
// get span of all the update data
auto const comp_index = update_data.find_component(CompType::name, false);
UpdateCompProperties result;
result.name = CompType::name;
result.is_columnar = update_data.is_columnar(result.name);
result.dense = update_data.is_dense(result.name);
result.uniform = update_data.is_uniform(result.name);
result.has_any_elements =
comp_index != invalid_index && update_data.get_component_info(comp_index).total_elements > 0;

result.elements_ps_in_update =
result.uniform ? update_data.uniform_elements_per_scenario(result.name) : invalid_index;

result.elements_in_base = comp_count_in_base;

if (result.is_columnar) {
process_buffer_span(
update_data.get_columnar_buffer_span_all_scenarios<meta_data::update_getter_s, CompType>(), result);
} else {
process_buffer_span(update_data.get_buffer_span_all_scenarios<meta_data::update_getter_s, CompType>(),
result);
}
return result;
};
template <class CompType> UpdateCompProperties check_component_independence(ConstDataset const& update_data) const {
UpdateCompProperties properties;
properties.name = CompType::name;
auto const component_idx = update_data.find_component(properties.name, false);
properties.is_columnar = update_data.is_columnar(properties.name);
properties.dense = update_data.is_dense(properties.name);
properties.uniform = update_data.is_uniform(properties.name);
properties.has_any_elements =
component_idx != invalid_index && update_data.get_component_info(component_idx).total_elements > 0;
properties.elements_ps_in_update =
properties.uniform ? update_data.uniform_elements_per_scenario(properties.name) : invalid_index;
properties.elements_in_base = this->component_count<CompType>();

if (properties.is_columnar) {
process_buffer_span<CompType>(
update_data.template get_columnar_buffer_span_all_scenarios<meta_data::update_getter_s, CompType>(),
properties);
} else {
process_buffer_span<CompType>(
update_data.template get_buffer_span_all_scenarios<meta_data::update_getter_s, CompType>(), properties);
}

return check_each_component();
return properties;
}

UpdateCompIndependence check_components_independence(ConstDataset const& update_data) const {
// check and return indenpendence of all components
return run_functor_with_all_types_return_array(
[this, &update_data]<typename CT>() { return this->check_components_independence<CT>(update_data); });
[this, &update_data]<typename CT>() { return this->check_component_independence<CT>(update_data); });
}

ComponentFlags is_update_independent(ConstDataset const& update_data) {
Expand Down Expand Up @@ -1080,7 +1082,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
// loop all branch
for (Idx i = 0; i != static_cast<Idx>(state_.comp_topo->branch_node_idx.size()); ++i) {
Idx2D const math_idx = state_.topo_comp_coup->branch[i];
if (math_idx.group == -1) {
if (math_idx.group == isolated_component) {
figueroa1395 marked this conversation as resolved.
Show resolved Hide resolved
continue;
}
// assign parameters
Expand All @@ -1090,7 +1092,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
// loop all branch3
for (Idx i = 0; i != static_cast<Idx>(state_.comp_topo->branch3_node_idx.size()); ++i) {
Idx2DBranch3 const math_idx = state_.topo_comp_coup->branch3[i];
if (math_idx.group == -1) {
if (math_idx.group == isolated_component) {
continue;
}
// assign parameters, branch3 param consists of three branch parameters
Expand All @@ -1103,7 +1105,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
// loop all shunt
for (Idx i = 0; i != static_cast<Idx>(state_.comp_topo->shunt_node_idx.size()); ++i) {
Idx2D const math_idx = state_.topo_comp_coup->shunt[i];
if (math_idx.group == -1) {
if (math_idx.group == isolated_component) {
continue;
}
// assign parameters
Expand All @@ -1113,7 +1115,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
// loop all source
for (Idx i = 0; i != static_cast<Idx>(state_.comp_topo->source_node_idx.size()); ++i) {
Idx2D const math_idx = state_.topo_comp_coup->source[i];
if (math_idx.group == -1) {
if (math_idx.group == isolated_component) {
continue;
}
// assign parameters
Expand All @@ -1132,7 +1134,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
Idx2D const math_idx =
state.topo_comp_coup
->branch[main_core::get_component_sequence<Branch>(state, changed_component_idx)];
if (math_idx.group == -1) {
if (math_idx.group == isolated_component) {
return;
}
// assign parameters
Expand All @@ -1141,7 +1143,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
Idx2DBranch3 const math_idx =
state.topo_comp_coup
->branch3[main_core::get_component_sequence<Branch3>(state, changed_component_idx)];
if (math_idx.group == -1) {
if (math_idx.group == isolated_component) {
return;
}
// assign parameters, branch3 param consists of three branch parameters
Expand All @@ -1154,7 +1156,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
Idx2D const math_idx =
state.topo_comp_coup
->shunt[main_core::get_component_sequence<Shunt>(state, changed_component_idx)];
if (math_idx.group == -1) {
if (math_idx.group == isolated_component) {
return;
}
// assign parameters
Expand Down Expand Up @@ -1236,7 +1238,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
for (Idx i = 0, n = narrow_cast<Idx>(components.size()); i != n; ++i) {
if (include(i)) {
Idx2D const math_idx = components[i];
if (math_idx.group != -1) {
if (math_idx.group != isolated_component) {
auto const& component = get_component_by_sequence<ComponentIn>(state, i);
CalcStructOut& math_model_input = calc_input[math_idx.group];
std::vector<CalcParamOut>& math_model_input_vect = math_model_input.*comp_vect;
Expand All @@ -1256,7 +1258,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
for (Idx i = 0, n = narrow_cast<Idx>(components.size()); i != n; ++i) {
if (include(i)) {
Idx2D const math_idx = components[i];
if (math_idx.group != -1) {
if (math_idx.group != isolated_component) {
auto const& component = get_component_by_sequence<ComponentIn>(state, i);
CalcStructOut& math_model_input = calc_input[math_idx.group];
std::vector<CalcParamOut>& math_model_input_vect = math_model_input.*comp_vect;
Expand All @@ -1267,30 +1269,12 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
}
}

template <calculation_input_type CalcInputType>
static auto calculate_param(auto const& c, auto const&... extra_args)
requires requires {
{ c.calc_param(extra_args...) };
}
{
return c.calc_param(extra_args...);
}

template <calculation_input_type CalcInputType>
static auto calculate_param(auto const& c, auto const&... extra_args)
requires requires {
{ c.template calc_param<typename CalcInputType::sym>(extra_args...) };
}
{
return c.template calc_param<typename CalcInputType::sym>(extra_args...);
}

template <symmetry_tag sym, IntSVector(StateEstimationInput<sym>::*component), class Component>
static void prepare_input_status(MainModelState const& state, std::vector<Idx2D> const& objects,
std::vector<StateEstimationInput<sym>>& input) {
for (Idx i = 0, n = narrow_cast<Idx>(objects.size()); i != n; ++i) {
Idx2D const math_idx = objects[i];
if (math_idx.group == -1) {
if (math_idx.group == isolated_component) {
continue;
}
(input[math_idx.group].*component)[math_idx.pos] =
Expand Down Expand Up @@ -1398,7 +1382,8 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
}
}

auto fault_coup = std::vector<Idx2D>(state_.components.template size<Fault>(), Idx2D{-1, -1});
auto fault_coup =
std::vector<Idx2D>(state_.components.template size<Fault>(), Idx2D{isolated_component, not_connected});
std::vector<ShortCircuitInput> sc_input(n_math_solvers_);

for (Idx i = 0; i != n_math_solvers_; ++i) {
Expand Down Expand Up @@ -1498,4 +1483,22 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
}
};

template <calculation_input_type CalcInputType>
static auto calculate_param(auto const& c, auto const&... extra_args)
requires requires {
{ c.calc_param(extra_args...) };
}
{
return c.calc_param(extra_args...);
}

template <calculation_input_type CalcInputType>
static auto calculate_param(auto const& c, auto const&... extra_args)
requires requires {
{ c.template calc_param<typename CalcInputType::sym>(extra_args...) };
}
{
return c.template calc_param<typename CalcInputType::sym>(extra_args...);
}
figueroa1395 marked this conversation as resolved.
Show resolved Hide resolved

} // namespace power_grid_model
Loading