From 103c11c42668e7702a912bb41a6cabfd9c57516d Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Fri, 14 Aug 2026 10:25:56 +0200 Subject: [PATCH] Revert "Merge links on nodes: create user node output from topo node output" Signed-off-by: Martijn Govers --- .../calculation_parameters.hpp | 19 +- .../power_grid_model/common/common.hpp | 15 -- .../power_grid_model/common/statistics.hpp | 5 +- .../include/power_grid_model/link_solver.hpp | 47 ++-- .../main_core/math_output_queries.hpp | 46 ---- .../power_grid_model/main_core/output.hpp | 137 +++++++--- .../main_core/state_queries.hpp | 90 +------ .../main_core/topological_node_output.hpp | 118 --------- .../power_grid_model/main_model_impl.hpp | 16 +- .../optimizer/base_optimizer.hpp | 2 +- .../optimizer/tap_position_optimizer.hpp | 5 +- tests/cpp_unit_tests/common/test_common.cpp | 35 --- tests/cpp_unit_tests/main_core/CMakeLists.txt | 1 - .../main_core/test_main_core_output.cpp | 14 +- .../test_topological_node_output.cpp | 244 ------------------ .../math_solver/test_math_solver_pf.hpp | 2 +- .../math_solver/test_math_solver_se.hpp | 2 +- .../optimizer/test_optimizer.hpp | 8 - .../optimizer/test_tap_position_optimizer.cpp | 2 +- .../power_flow/dummy-test/sym_output.json | 2 +- .../distribution-case/sym_output_batch.json | 40 +-- 21 files changed, 160 insertions(+), 690 deletions(-) delete mode 100644 power_grid_model_c/power_grid_model/include/power_grid_model/main_core/math_output_queries.hpp delete mode 100644 power_grid_model_c/power_grid_model/include/power_grid_model/main_core/topological_node_output.hpp delete mode 100644 tests/cpp_unit_tests/main_core/test_topological_node_output.cpp diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/calculation_parameters.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/calculation_parameters.hpp index 778743f508..2438a96ffd 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/calculation_parameters.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/calculation_parameters.hpp @@ -340,7 +340,7 @@ template struct SolverOutput { using sym = sym_type; std::vector> u; - std::vector> bus_injection; // TODO(mgovers): remove this for v2 + std::vector> bus_injection; std::vector bus; std::vector> branch; std::vector> source; @@ -405,28 +405,11 @@ struct OptimizerOutput { TransformerTapPositionOutput transformer_tap_positions; }; -template struct SupernodeOutput; - -template struct SupernodeOutput { - using sym = decode_symmetry_v; - - ComplexValueVector bus_injection; // user bus output - BranchSolverOutput branch; // user link -}; -template struct SupernodeOutput { - using sym = decode_symmetry_v; - - BranchShortCircuitSolverOutput branch; // user link -}; - template struct MathOutput { using SolverOutputType = T; - using UnderlyingSolverOutputType = underlying_value_t; - using sym = decode_symmetry_v; SolverOutputType solver_output; OptimizerOutput optimizer_output; - std::vector> supernode_output; }; // component indices at physical model side diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/common/common.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/common/common.hpp index 9f84a39e09..f80b5a4584 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/common/common.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/common/common.hpp @@ -44,17 +44,6 @@ struct Idx2DHash { } }; -namespace detail { -template struct underlying_value { - using type = T; -}; -template struct underlying_value { - using type = underlying_value>::type; -}; -} // namespace detail - -template using underlying_value_t = detail::underlying_value>::type; - struct symmetric_t {}; struct asymmetric_t {}; @@ -66,10 +55,6 @@ template constexpr bool is_asymmetric_v = std::derived_from using other_symmetry_t = std::conditional_t, asymmetric_t, symmetric_t>; -template - requires symmetry_tag::sym> -using decode_symmetry_v = underlying_value_t::sym; - // math constant using namespace std::complex_literals; using DoubleComplex = std::complex; diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/common/statistics.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/common/statistics.hpp index 634e1f1506..30868217cf 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/common/statistics.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/common/statistics.hpp @@ -349,8 +349,7 @@ template requires std::same_as, DecomposedComplexRandVar::sym>> constexpr auto combine(RandVarsView rand_vars) { - using sym = decode_symmetry_v; - static_assert(symmetry_tag); + using sym = std::ranges::range_value_t::sym; DecomposedComplexRandVar result{ .real_component = @@ -378,7 +377,7 @@ template requires std::same_as, UniformComplexRandVar::sym>> constexpr auto combine_magnitude(RandVarsView rand_vars) { - using sym = decode_symmetry_v; + using sym = std::ranges::range_value_t::sym; auto const weighted_average_magnitude_measurement = statistics::combine(rand_vars | std::views::transform([](auto const& measurement) { diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/link_solver.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/link_solver.hpp index 4a9f27ea7a..ea5dc3137b 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/link_solver.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/link_solver.hpp @@ -9,7 +9,6 @@ #include "common/counting_iterator.hpp" #include "common/typing.hpp" -#include #include #include #include @@ -212,14 +211,12 @@ inline void backward_substitution(ReducedEchelonForm& elimination_result) { // only iterate over free columns to the right of the pivot column // as these are the only ones that can be affected by the backward substitution for (auto const backward_col_idx : backward_substitution_free_right_cols(free_col_indices, pivot_col_idx)) { - std::ignore = - elimination_result.matrix.get_value(pivot_row_idx, backward_col_idx) - .transform([&elimination_result, multiplier_value, row_idx, - backward_col_idx](IntS pivot_value) { - elimination_result.matrix.add_to_value(static_cast(-multiplier_value * pivot_value), - row_idx, backward_col_idx); - return pivot_value; - }); + elimination_result.matrix.get_value(pivot_row_idx, backward_col_idx) + .transform([&elimination_result, multiplier_value, row_idx, backward_col_idx](IntS pivot_value) { + elimination_result.matrix.add_to_value(static_cast(-multiplier_value * pivot_value), + row_idx, backward_col_idx); + return pivot_value; + }); } elimination_result.rhs[row_idx] -= static_cast(multiplier_value) * elimination_result.rhs[pivot_row_idx]; @@ -271,11 +268,11 @@ inline SolutionSet set_solution_system(ReducedEchelonForm& result) { auto const pivot_edge_idx = result.pivot_edge_indices[matrix_row]; for (auto dfs_matrix_col : std::views::iota(Idx{}, free_indices_size)) { Idx const free_edge_idx = result.free_edge_indices[dfs_matrix_col]; - std::ignore = result.matrix.get_value(matrix_row, free_edge_idx) - .transform([&dfs_matrix, pivot_edge_idx, dfs_matrix_col](IntS matrix_element) { - dfs_matrix.set_value(matrix_element, pivot_edge_idx, dfs_matrix_col); - return matrix_element; - }); + result.matrix.get_value(matrix_row, free_edge_idx) + .transform([&dfs_matrix, pivot_edge_idx, dfs_matrix_col](IntS matrix_element) { + dfs_matrix.set_value(matrix_element, pivot_edge_idx, dfs_matrix_col); + return matrix_element; + }); } extended_rhs[pivot_edge_idx] = result.rhs[matrix_row]; } @@ -297,13 +294,12 @@ inline std::vector> set_projection_system(Idx free_in for (Idx dfs_matrix_col = 0; dfs_matrix_col < free_indices_number; dfs_matrix_col++) { auto dot_product_rhs = DoubleComplex{}; for (Idx dfs_matrix_row = 0; dfs_matrix_row < total_indices_number; dfs_matrix_row++) { - std::ignore = solution_set.dfs_matrix.get_value(dfs_matrix_row, dfs_matrix_col) - .transform([&dot_product_rhs, &extended_rhs_ = solution_set.extended_rhs, - &dfs_matrix_row](IntS first_value) { - dot_product_rhs += - static_cast(first_value) * extended_rhs_[dfs_matrix_row]; - return first_value; - }); + solution_set.dfs_matrix.get_value(dfs_matrix_row, dfs_matrix_col) + .transform( + [&dot_product_rhs, &extended_rhs_ = solution_set.extended_rhs, &dfs_matrix_row](IntS first_value) { + dot_product_rhs += static_cast(first_value) * extended_rhs_[dfs_matrix_row]; + return first_value; + }); } auto& projection_system_row = projection_system[dfs_matrix_col]; projection_system_row[free_indices_number] = dot_product_rhs; @@ -369,11 +365,10 @@ inline std::vector compute_internal_loads(SolutionSet const& solu internal_loads[row] = solution_set.extended_rhs[row]; auto sum_value = DoubleComplex{}; for (auto const column : IdxRange{number_of_columns}) { - std::ignore = - solution_set.dfs_matrix.get_value(row, column).transform([&sum_value, &system, column](IntS value) { - sum_value += static_cast(value) * system[column].back(); - return value; - }); + solution_set.dfs_matrix.get_value(row, column).transform([&sum_value, &system, column](IntS value) { + sum_value += static_cast(value) * system[column].back(); + return value; + }); } internal_loads[row] -= sum_value; } diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/math_output_queries.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/math_output_queries.hpp deleted file mode 100644 index 2115731b40..0000000000 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/math_output_queries.hpp +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-FileCopyrightText: Contributors to the Power Grid Model project -// -// SPDX-License-Identifier: MPL-2.0 - -#pragma once - -#include -#include -#include - -#include "../calculation_parameters.hpp" -#include "../common/common.hpp" -#include "../component/branch.hpp" -#include "../component/branch3.hpp" -#include "../component/fault.hpp" -#include "../component/load_gen.hpp" -#include "../component/shunt.hpp" -#include "../component/source.hpp" - -namespace power_grid_model::main_core { - -template -constexpr auto get_component_output(MathOutput> const& math_output, - Idx2D const& math_id) { - auto const& solver_output = math_output.solver_output[math_id.group]; - - auto const& component_type_output = [&solver_output] { - if constexpr (std::derived_from || std::derived_from) { - return solver_output.branch; - } else if constexpr (std::same_as && requires { solver_output.source; }) { - return solver_output.source; - } else if constexpr (std::same_as && requires { solver_output.shunt; }) { - return solver_output.shunt; - } else if constexpr (std::derived_from && requires { solver_output.load_gen; }) { - return solver_output.load_gen; - } else if constexpr (std::same_as && requires { solver_output.fault; }) { - return solver_output.fault; - } else { - static_assert(false, "Unsupported component type for output retrieval"); - } - }(); - - return component_type_output[math_id.pos]; -} - -} // namespace power_grid_model::main_core diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/output.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/output.hpp index 34b33cc13f..8f96f774f4 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/output.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/output.hpp @@ -39,6 +39,84 @@ namespace detail { template concept assignable_to = std::assignable_from; +template Component, class ComponentContainer> + requires model_component_state_c +constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { + return state.topo_comp_coup->node.cbegin(); +} + +template Component, class ComponentContainer> + requires model_component_state_c +constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { + return state.topo_comp_coup->branch.cbegin() + get_component_sequence_offset(state.components); +} + +template Component, class ComponentContainer> + requires model_component_state_c +constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { + return state.topo_comp_coup->branch3.cbegin() + get_component_sequence_offset(state.components); +} + +template Component, class ComponentContainer> + requires model_component_state_c +constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { + return state.topo_comp_coup->source.cbegin(); +} + +template Component, class ComponentContainer> + requires model_component_state_c +constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { + return state.topo_comp_coup->load_gen.cbegin() + + get_component_sequence_offset(state.components); +} + +template Component, class ComponentContainer> + requires model_component_state_c +constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { + return state.topo_comp_coup->shunt.cbegin(); +} + +template Component, class ComponentContainer> + requires model_component_state_c +constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { + return state.comp_topo->voltage_sensor_node_idx.cbegin() + + get_component_sequence_offset(state.components); +} + +template Component, class ComponentContainer> + requires model_component_state_c +constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { + return state.comp_topo->power_sensor_object_idx.cbegin() + + get_component_sequence_offset(state.components); +} + +template Component, class ComponentContainer> + requires model_component_state_c +constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { + return state.comp_topo->current_sensor_object_idx.cbegin() + + get_component_sequence_offset(state.components); +} + +template Component, class ComponentContainer> + requires model_component_state_c +constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { + return state.comp_coup.fault.cbegin(); +} + +template Component, class ComponentContainer> + requires model_component_state_c +constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { + return state.comp_topo->regulated_object_idx.cbegin() + + get_component_sequence_offset(state.components); +} + +template Component, class ComponentContainer> + requires model_component_state_c +constexpr auto comp_base_sequence(MainModelState const& state) { + auto const start = comp_base_sequence_cbegin(state); + return std::ranges::subrange{start, start + get_component_size(state.components)}; +} + template requires model_component_state_c && @@ -55,40 +133,29 @@ constexpr void produce_output(MainModelState const& state, C } // namespace detail // output node -template Component, class ComponentContainer, steady_state_solver_output_type SolverOutputType> - requires model_component_state_c -constexpr auto output_result(Component const& node, MainModelState const& state, - MathOutput> const& math_output, Idx2D const& topo_id) { - using sym = decode_symmetry_v; - - auto const& math_id = get_math_id(state, topo_id.group); +template Component, steady_state_solver_output_type SolverOutputType> +constexpr auto output_result(Component const& node, std::vector const& solver_output, Idx2D math_id) { + using sym = SolverOutputType::sym; if (math_id.group == disconnected) { return node.template get_null_output(); } - - return node.template get_output(math_output.solver_output[math_id.group].u[math_id.pos], - math_output.supernode_output[topo_id.group].bus_injection[topo_id.pos]); + return node.template get_output(solver_output[math_id.group].u[math_id.pos], + solver_output[math_id.group].bus_injection[math_id.pos]); } -template Component, class ComponentContainer, - short_circuit_solver_output_type SolverOutputType> - requires model_component_state_c -constexpr auto output_result(Component const& node, MainModelState const& state, - MathOutput> const& math_output, Idx2D const& topo_id) { - auto const& math_id = get_math_id(state, topo_id.group); - +template Component, short_circuit_solver_output_type SolverOutputType> +inline auto output_result(Component const& node, std::vector const& solver_output, Idx2D math_id) { if (math_id.group == disconnected) { return node.get_null_sc_output(); } - - return node.get_sc_output(math_output.solver_output[math_id.group].u_bus[math_id.pos]); + return node.get_sc_output(solver_output[math_id.group].u_bus[math_id.pos]); } // output branch template Component, steady_state_solver_output_type SolverOutputType> constexpr auto output_result(Component const& branch, std::vector const& solver_output, Idx2D math_id) { - using sym = decode_symmetry_v; + using sym = SolverOutputType::sym; if (math_id.group == disconnected) { return branch.template get_null_output(); @@ -107,7 +174,7 @@ inline auto output_result(Component const& branch, std::vector template Component, steady_state_solver_output_type SolverOutputType> constexpr auto output_result(Component const& branch3, std::vector const& solver_output, Idx2DBranch3 const& math_id) { - using sym = decode_symmetry_v; + using sym = SolverOutputType::sym; if (math_id.group == disconnected) { return branch3.template get_null_output(); @@ -132,7 +199,7 @@ inline auto output_result(Component const& branch3, std::vector Component, steady_state_solver_output_type SolverOutputType> constexpr auto output_result(Component const& source, std::vector const& solver_output, Idx2D const& math_id) { - using sym = decode_symmetry_v; + using sym = SolverOutputType::sym; if (math_id.group == disconnected) { return source.template get_null_output(); @@ -152,7 +219,7 @@ inline auto output_result(Component const& source, std::vector template Component, steady_state_solver_output_type SolverOutputType> constexpr auto output_result(Component const& load_gen, std::vector const& solver_output, Idx2D const& math_id) { - using sym = decode_symmetry_v; + using sym = SolverOutputType::sym; if (math_id.group == disconnected) { return load_gen.template get_null_output(); @@ -169,7 +236,7 @@ inline auto output_result(Component const& load_gen, std::vector Component, steady_state_solver_output_type SolverOutputType> constexpr auto output_result(Component const& shunt, std::vector const& solver_output, Idx2D const& math_id) { - using sym = decode_symmetry_v; + using sym = SolverOutputType::sym; if (math_id.group == disconnected) { return shunt.template get_null_output(); @@ -191,7 +258,7 @@ template Component, class ComponentCont requires model_component_state_c constexpr auto output_result(Component const& voltage_sensor, MainModelState const& state, std::vector const& solver_output, Idx const node_seq) { - using sym = decode_symmetry_v; + using sym = SolverOutputType::sym; Idx2D const node_math_id = state.topo_comp_coup->node[node_seq]; if (node_math_id.group == disconnected) { @@ -213,7 +280,7 @@ template Component, class ComponentContai requires model_component_state_c constexpr auto output_result(Component const& power_sensor, MainModelState const& state, std::vector const& solver_output, Idx const obj_seq) { - using sym = decode_symmetry_v; + using sym = SolverOutputType::sym; auto const terminal_type = power_sensor.get_terminal_type(); Idx2D const obj_math_id = [&]() { @@ -293,7 +360,7 @@ template Component, class ComponentCont requires model_component_state_c constexpr auto output_result(Component const& current_sensor, MainModelState const& state, std::vector const& solver_output, Idx const obj_seq) { - using sym = decode_symmetry_v; + using sym = SolverOutputType::sym; auto const terminal_type = current_sensor.get_terminal_type(); Idx2D const obj_math_id = [&]() { @@ -492,22 +559,6 @@ constexpr void output_result(MainModelState const& state, return output_result(component, math_output.solver_output, math_id); }); } -template Component, class ComponentContainer, typename SolverOutputType, - non_owning_view_c ComponentOutput> - requires model_component_state_c && - requires(Component const& component, MainModelState const& state, - MathOutput const& math_output, Idx2D const& topo_id) { - { - output_result(component, state, math_output, topo_id) - } -> detail::assignable_to>; - } -constexpr void output_result(MainModelState const& state, - MathOutput const& math_output, ComponentOutput output) { - detail::produce_output( - state, output, [&state, &math_output](Component const& component, Idx2D const& topo_id) { - return output_result(component, state, math_output, topo_id); - }); -} template Component, class ComponentContainer, typename SolverOutputType, non_owning_view_c ComponentOutput> requires model_component_state_c && diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/state_queries.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/state_queries.hpp index 8483d99994..dc89be666c 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/state_queries.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/state_queries.hpp @@ -4,11 +4,10 @@ #pragma once -#include "container_queries.hpp" -#include "state.hpp" - #include "../common/common.hpp" #include "../common/enum.hpp" +#include "state.hpp" + #include "../component/branch.hpp" #include "../component/branch3.hpp" #include "../component/node.hpp" @@ -41,15 +40,15 @@ template inline auto get_topo_node(MainModelState const& state, Idx topology_index, ControlSide control_side) { auto const& nodes = get_branch_nodes(state, topology_index); - auto const control_side_idx = narrow_cast(std::to_underlying(control_side)); + auto const control_side_idx = static_cast(control_side); assert(0 <= control_side_idx); - assert(control_side_idx < std::ranges::ssize(nodes)); + assert(control_side_idx < static_cast(nodes.size())); return nodes[control_side_idx]; } -template ComponentType, class ComponentContainer> +template ComponentType, class ComponentContainer> requires model_component_state_c constexpr auto get_math_id(MainModelState const& state, Idx topology_sequence_idx) { return state.topo_comp_coup->node[topology_sequence_idx]; @@ -84,83 +83,4 @@ template ComponentType, class ComponentContainer> constexpr auto get_math_id(MainModelState const& state, Idx topology_sequence_idx) { return state.topo_comp_coup->regulator[topology_sequence_idx]; } - -template Component, class ComponentContainer> - requires model_component_state_c -constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { - return state.reduced_topology->topo_node_coup.coupling.user_nodes_to_topo_nodes.cbegin(); -} - -template Component, class ComponentContainer> - requires model_component_state_c -constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { - return state.topo_comp_coup->branch.cbegin() + get_component_sequence_offset(state.components); -} - -template Component, class ComponentContainer> - requires model_component_state_c -constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { - return state.topo_comp_coup->branch3.cbegin() + get_component_sequence_offset(state.components); -} - -template Component, class ComponentContainer> - requires model_component_state_c -constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { - return state.topo_comp_coup->source.cbegin(); -} - -template Component, class ComponentContainer> - requires model_component_state_c -constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { - return state.topo_comp_coup->load_gen.cbegin() + - get_component_sequence_offset(state.components); -} - -template Component, class ComponentContainer> - requires model_component_state_c -constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { - return state.topo_comp_coup->shunt.cbegin(); -} - -template Component, class ComponentContainer> - requires model_component_state_c -constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { - return state.comp_topo->voltage_sensor_node_idx.cbegin() + - get_component_sequence_offset(state.components); -} - -template Component, class ComponentContainer> - requires model_component_state_c -constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { - return state.comp_topo->power_sensor_object_idx.cbegin() + - get_component_sequence_offset(state.components); -} - -template Component, class ComponentContainer> - requires model_component_state_c -constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { - return state.comp_topo->current_sensor_object_idx.cbegin() + - get_component_sequence_offset(state.components); -} - -template Component, class ComponentContainer> - requires model_component_state_c -constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { - return state.comp_coup.fault.cbegin(); -} - -template Component, class ComponentContainer> - requires model_component_state_c -constexpr auto comp_base_sequence_cbegin(MainModelState const& state) { - return state.comp_topo->regulated_object_idx.cbegin() + - get_component_sequence_offset(state.components); -} - -template Component, class ComponentContainer> - requires model_component_state_c -constexpr auto comp_base_sequence(MainModelState const& state) { - auto const start = comp_base_sequence_cbegin(state); - return std::ranges::subrange{start, start + get_component_size(state.components)}; -} - } // namespace power_grid_model::main_core diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/topological_node_output.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/topological_node_output.hpp deleted file mode 100644 index 4f2565430a..0000000000 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/topological_node_output.hpp +++ /dev/null @@ -1,118 +0,0 @@ -// SPDX-FileCopyrightText: Contributors to the Power Grid Model project -// -// SPDX-License-Identifier: MPL-2.0 - -#pragma once - -#include "core_utils.hpp" - -#include "../calculation_parameters.hpp" -#include "../link_solver.hpp" -#include "../main_core/math_output_queries.hpp" -#include "../main_core/state.hpp" -#include "../main_core/state_queries.hpp" - -#include - -namespace power_grid_model::main_core { -namespace detail { - -template - requires symmetry_tag> && - (std::same_as>> || - std::same_as>>) -inline auto const& get_injection(ComponentSolverOutputType const& component_output) { - if constexpr (requires { component_output.s; }) { - return component_output.s; - } else if constexpr (requires { component_output.i; }) { - return component_output.i; - } else { - static_assert(false, "ComponentSolverOutputType must have either s or i member"); - } -} - -template -inline Idx get_node_sequence_idx(main_model_state_c auto const& state, Idx const& component_idx) { - if constexpr (std::same_as) { - return state.comp_topo - ->source_node_idx[get_component_sequence_offset(state.components) + component_idx]; - } else if constexpr (std::derived_from) { - return state.comp_topo - ->load_gen_node_idx[get_component_sequence_offset(state.components) + - component_idx]; - } else { - static_assert(false, "Unsupported component type for node sequence index retrieval"); - } -} - -template - requires std::invocable> const&> -inline void add_appliance_injection(main_model_state_c auto const& state, - MathOutput> const& math_output, - AddToTarget accumulate_injection) { - for (auto const& [component_idx, component_math_id] : enumerate(comp_base_sequence(state))) { - if (component_math_id.group == disconnected) { - continue; - } - auto const& component_output = get_component_output(math_output, component_math_id); - - auto const& user_node_idx = get_node_sequence_idx(state, component_idx); - auto const& user_topo_id = - state.reduced_topology->topo_node_coup.coupling.user_nodes_to_topo_nodes[user_node_idx]; - - auto const injection = get_injection(component_output); - accumulate_injection(user_topo_id, injection); - } -} - -template -inline std::vector> -solve_topological_nodes(State const& state, MathOutput>& math_output) { - using sym = decode_symmetry_v; - - std::vector> supernode_output = - state.reduced_topology->topo_node_coup.topo_nodes | - std::views::transform([](auto const& topo_node) -> SupernodeOutput { - (void)topo_node; // suppress unused variable warning when not steady-state solver output - if constexpr (steady_state_solver_output_type) { - return {.bus_injection = ComplexValueVector(topo_node.user_nodes.size()), .branch = {}}; - } else { - return {}; - } - }) | - std::ranges::to(); - - auto const accumulate_injection = [&supernode_output](Idx2D const& user_topo_id, - ComplexValue const& injection) { - (void)supernode_output; // suppress unused variable warning when not steady-state solver output - (void)user_topo_id; // suppress unused variable warning when not steady-state solver output - (void)injection; // suppress unused variable warning when not steady-state solver output - - if constexpr (steady_state_solver_output_type) { - supernode_output[user_topo_id.group].bus_injection[user_topo_id.pos] += injection; - } - }; - - if constexpr (steady_state_solver_output_type) { - using InjectionComponentTypesTuple = std::tuple; - - utils::run_functor_with_tuple_return_void( - [&state, &math_output, &accumulate_injection]() { - if constexpr (decltype(state.components)::template is_storageable_v) { - add_appliance_injection(state, math_output, accumulate_injection); - } - }); - } - - return supernode_output; -} -} // namespace detail - -template -inline void solve_topological_nodes(State const& state, MathOutput>& math_output) { - assert(std::ranges::empty(math_output.supernode_output)); - math_output.supernode_output = detail::solve_topological_nodes(state, math_output); -} -} // namespace power_grid_model::main_core diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model_impl.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model_impl.hpp index 142841c2ba..18ee220e47 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model_impl.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model_impl.hpp @@ -37,7 +37,6 @@ #include "main_core/input.hpp" #include "main_core/main_model_type.hpp" #include "main_core/output.hpp" -#include "main_core/topological_node_output.hpp" #include "main_core/topology.hpp" #include "main_core/update.hpp" @@ -288,7 +287,7 @@ class MainModelImpl { auto calculate_(PrepareInputFn prepare_input, SolveFn solve, Logger& logger) { using InputType = std::invoke_result_t::const_reference; using SolverOutputType = std::invoke_result_t; - using sym = decode_symmetry_v; + using sym = SolverOutputType::sym; assert(construction_complete_); // prepare @@ -370,9 +369,9 @@ class MainModelImpl { [cache_run]( MainModelImpl& main_model_, Options const& options_, MutableDataset const& result_data_, Logger& logger) { - main_model_.output_result( - main_model_.calculate_with_optimizer(options_, cache_run, logger), - result_data_, logger); + auto const math_output = + main_model_.calculate_with_optimizer(options_, cache_run, logger); + main_model_.output_result(math_output, result_data_, logger); }, *this, options, result_data, logger); } @@ -439,14 +438,10 @@ class MainModelImpl { private: template - void output_result(MathOutput> math_output, MutableDataset const& result_data, + void output_result(MathOutput> const& math_output, MutableDataset const& result_data, Logger& logger) const { assert(!result_data.is_batch()); - Timer const t_output{logger, LogEvent::produce_output}; - - main_core::solve_topological_nodes(state_, math_output); - auto const output_func = [this, &math_output, &result_data]() { result_data.for_each_component::type, CT>( [this, &math_output](auto const& span) { @@ -457,6 +452,7 @@ class MainModelImpl { }); }; + Timer const t_output{logger, LogEvent::produce_output}; ModelType::run_functor_with_all_component_types_return_void(output_func); } diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/base_optimizer.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/base_optimizer.hpp index b5083ea936..069f5474c7 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/base_optimizer.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/base_optimizer.hpp @@ -84,7 +84,7 @@ class NoOptimizer : public detail::BaseOptimizer { NoOptimizer(Calculator func) : func_{std::move(func)} {} auto optimize(State const& state, CalculationMethod method) -> MathOutput final { - return {.solver_output = func_(state, method), .optimizer_output = {}, .supernode_output = {}}; + return {.solver_output = func_(state, method), .optimizer_output = {}}; } private: diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp index 87b0951cbb..1bf89d119f 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/optimizer/tap_position_optimizer.hpp @@ -1041,8 +1041,7 @@ class TapPositionOptimizerImpl, StateCalculator, } return {.solver_output = {std::move(solver_output)}, - .optimizer_output = {std::move(transformer_tap_positions)}, - .supernode_output = {}}; + .optimizer_output = {std::move(transformer_tap_positions)}}; } auto iterate_with_fallback(State const& state, @@ -1118,7 +1117,7 @@ class TapPositionOptimizerImpl, StateCalculator, template auto compute_node_state_and_param(Regulator const& regulator, State const& state, ResultType const& solver_output) { - using sym = decode_symmetry_v; + using sym = ResultType::value_type::sym; auto const param = regulator.regulator.get().template calc_param(); auto const node_state = diff --git a/tests/cpp_unit_tests/common/test_common.cpp b/tests/cpp_unit_tests/common/test_common.cpp index dce229eab9..575527fd36 100644 --- a/tests/cpp_unit_tests/common/test_common.cpp +++ b/tests/cpp_unit_tests/common/test_common.cpp @@ -5,9 +5,7 @@ #include #include -#include #include -#include namespace power_grid_model { namespace { @@ -18,21 +16,6 @@ static_assert(!is_symmetric_v); static_assert(std::same_as, asymmetric_t>); static_assert(std::same_as, symmetric_t>); -struct B { - using sym = symmetric_t; -}; -struct C { - using sym = asymmetric_t; -}; -static_assert(is_symmetric_v>); -static_assert(is_symmetric_v>>); -static_assert(is_symmetric_v>>); -static_assert(is_symmetric_v>>>); -static_assert(is_asymmetric_v>); -static_assert(is_asymmetric_v>>); -static_assert(is_asymmetric_v>>); -static_assert(is_asymmetric_v>>>); - static_assert(std::invocable); static_assert(std::invocable); static_assert(std::invocable); @@ -51,23 +34,5 @@ static_assert(map_to_cyclic_range(12, 12) == 0); static_assert(map_to_cyclic_range(13, 12) == 1); static_assert(map_to_cyclic_range(11, 12) == 11); static_assert(map_to_cyclic_range(-1, -3) == -1); - -// underlying_value_t, decode_symmetry_v -template struct Foo { - using sym = sym_type; -}; -using SymFoo = Foo; -using AsymFoo = Foo; - -static_assert(std::same_as, SymFoo>); -static_assert(std::same_as>, AsymFoo>); -static_assert(std::same_as>, SymFoo>); -static_assert(std::same_as>>, AsymFoo>); - -static_assert(std::same_as, asymmetric_t>); -static_assert(std::same_as>, symmetric_t>); -static_assert(std::same_as>, asymmetric_t>); -static_assert(std::same_as>>, symmetric_t>); - } // namespace } // namespace power_grid_model diff --git a/tests/cpp_unit_tests/main_core/CMakeLists.txt b/tests/cpp_unit_tests/main_core/CMakeLists.txt index f895c1a5e3..133c44d9eb 100644 --- a/tests/cpp_unit_tests/main_core/CMakeLists.txt +++ b/tests/cpp_unit_tests/main_core/CMakeLists.txt @@ -7,7 +7,6 @@ add_executable( "../test_entry_point.cpp" "test_main_core_output.cpp" "test_main_model_type.cpp" - "test_topological_node_output.cpp" ) target_link_libraries( diff --git a/tests/cpp_unit_tests/main_core/test_main_core_output.cpp b/tests/cpp_unit_tests/main_core/test_main_core_output.cpp index be4564b24e..e248b10bf0 100644 --- a/tests/cpp_unit_tests/main_core/test_main_core_output.cpp +++ b/tests/cpp_unit_tests/main_core/test_main_core_output.cpp @@ -65,14 +65,11 @@ TEST_CASE("Test main core output") { .transformer_tap_positions = {{.transformer_id = 3, .tap_position = 1}}}; SUBCASE("Symmetric") { output_result( - state, SymOutput{.solver_output = {}, .optimizer_output = optimizer_output, .supernode_output = {}}, - output); + state, SymOutput{.solver_output = {}, .optimizer_output = optimizer_output}, output); } SUBCASE("Asymmetric") { output_result( - state, - AsymOutput{.solver_output = {}, .optimizer_output = optimizer_output, .supernode_output = {}}, - output); + state, AsymOutput{.solver_output = {}, .optimizer_output = optimizer_output}, output); } CHECK(output[0].id == 0); CHECK(output[0].energized == 0); @@ -88,14 +85,11 @@ TEST_CASE("Test main core output") { {.transformer_id = 2, .tap_position = 3}}}; SUBCASE("Symmetric") { output_result( - state, SymOutput{.solver_output = {}, .optimizer_output = optimizer_output, .supernode_output = {}}, - output); + state, SymOutput{.solver_output = {}, .optimizer_output = optimizer_output}, output); } SUBCASE("Asymmetric") { output_result( - state, - AsymOutput{.solver_output = {}, .optimizer_output = optimizer_output, .supernode_output = {}}, - output); + state, AsymOutput{.solver_output = {}, .optimizer_output = optimizer_output}, output); } CHECK(output[0].id == 0); CHECK(output[0].energized == 1); diff --git a/tests/cpp_unit_tests/main_core/test_topological_node_output.cpp b/tests/cpp_unit_tests/main_core/test_topological_node_output.cpp deleted file mode 100644 index d9aa2bd1ce..0000000000 --- a/tests/cpp_unit_tests/main_core/test_topological_node_output.cpp +++ /dev/null @@ -1,244 +0,0 @@ -// SPDX-FileCopyrightText: Contributors to the Power Grid Model project -// -// SPDX-License-Identifier: MPL-2.0 - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -namespace power_grid_model::main_core { -namespace { -template struct InjectionAccumulator { - void operator()(Idx2D const& math_id, ComplexValue const& injection) { - if (auto [it, inserted] = net_node_injections.try_emplace(math_id, injection); !inserted) { - it->second += injection; - } - } - std::unordered_map, Idx2DHash> net_node_injections{}; -}; -} // namespace - -TEST_CASE("Test topological node output") { - double const dummy_value = 0.0; - ComplexValue const dummy_complex_value_sym{3.14, 2.71}; - ComplexValue const dummy_complex_value_asym{{0.0, 1.0}, {-2.0, -3.0}, {4.0, -5.0}}; - - SUBCASE("get_injection") { - SUBCASE("ApplianceSolverOutput") { - ApplianceSolverOutput appliance_output; - appliance_output.s = dummy_complex_value_sym; - CHECK(detail::get_injection(appliance_output) == dummy_complex_value_sym); - - // asym - ApplianceSolverOutput appliance_output_asym; - appliance_output_asym.s = dummy_complex_value_asym; - CHECK((detail::get_injection(appliance_output_asym)).isApprox(dummy_complex_value_asym)); - } - SUBCASE("ApplianceShortCircuitSolverOutput") { - ApplianceShortCircuitSolverOutput appliance_short_circuit_output; - appliance_short_circuit_output.i = dummy_complex_value_sym; - CHECK(detail::get_injection(appliance_short_circuit_output) == dummy_complex_value_sym); - - // asym - ApplianceShortCircuitSolverOutput appliance_short_circuit_output_asym; - appliance_short_circuit_output_asym.i = dummy_complex_value_asym; - CHECK((detail::get_injection(appliance_short_circuit_output_asym)).isApprox(dummy_complex_value_asym)); - } - } - SUBCASE("get_node_sequence_idx") { - using ComponentContainer = Container, AsymLoad, Fault, - Node, SymLoad, Source, Shunt>; - using State = MainModelState; - - State state; - auto comp_topo = std::make_shared(); - // arbitrary node indices should not matter for this test - comp_topo->source_node_idx = {Idx{5}, Idx{1000}}; - comp_topo->shunt_node_idx = {Idx{-123}}; - comp_topo->load_gen_node_idx = {Idx{0}, Idx{-1}}; - state.comp_topo = std::make_shared(std::move(*comp_topo)); - - emplace_component(state.components, 0, SourceInput{}, dummy_value); - emplace_component(state.components, 1, SourceInput{}, dummy_value); - emplace_component(state.components, 2, ShuntInput{}, dummy_value); - emplace_component(state.components, 3, LoadGenInput{}, dummy_value); - emplace_component(state.components, 4, LoadGenInput{}, dummy_value); - emplace_component(state.components, 666, NodeInput{.id = 666}); // .id needed for fault linking - emplace_component(state.components, 5, FaultInput{.fault_object = 666}); - state.components.set_construction_complete(); - - SUBCASE("Source") { - CHECK(detail::get_node_sequence_idx(state, 0) == Idx{5}); - CHECK(detail::get_node_sequence_idx(state, 1) == Idx{1000}); - } - SUBCASE("LoadGen") { - CHECK(detail::get_node_sequence_idx(state, 0) == Idx{0}); - CHECK(detail::get_node_sequence_idx(state, 0) == Idx{-1}); - } - } - SUBCASE("add_appliance_injection") { - using ComponentContainer = - Container, SymLoad, Fault, Node, Source, Shunt>; - using State = MainModelState; - - State state; - auto comp_topo = std::make_shared(); - comp_topo->n_node = 2; - comp_topo->source_node_idx = {Idx{0}, Idx{1}}; - comp_topo->shunt_node_idx = {Idx{1}}; - comp_topo->load_gen_node_idx = {Idx{1}}; - - ComponentConnections const comp_conn; - // no links, so no supernodes, identity mapping - // TODO(figueroa1395): this needs to be modified later when link output is added - state.reduced_topology = - std::make_shared(supernodes::reduce_topology(*comp_topo, comp_conn)); - state.comp_topo = std::make_shared(std::move(*comp_topo)); - - state.topo_comp_coup = std::make_shared([] { - TopologicalComponentToMathCoupling result; - result.load_gen = {{.group = 0, .pos = 0}}; - result.source = {{.group = 0, .pos = 0}, {.group = disconnected, .pos = disconnected}}; - return result; - }()); - - state.comp_coup = ComponentToMathCoupling{ - .fault = {{.group = 0, .pos = 0}, {.group = 0, .pos = 1}}, - }; - - emplace_component(state.components, 0, SourceInput{}, dummy_value); - emplace_component(state.components, 1, ShuntInput{}, dummy_value); - emplace_component(state.components, 2, LoadGenInput{}, dummy_value); - emplace_component(state.components, 101, NodeInput{.id = 101}); // .id needed for fault linking - emplace_component(state.components, 102, NodeInput{.id = 102}); // .id needed for fault linking - emplace_component(state.components, 3, FaultInput{.fault_object = 101}); - emplace_component(state.components, 4, FaultInput{.fault_object = 102}); - state.components.set_construction_complete(); - - InjectionAccumulator accumulator; - - SUBCASE("Steady state output") { - MathOutput>> math_output{}; - math_output.solver_output.emplace_back( - SolverOutput{.u = {}, - .bus_injection = {}, - .bus = {}, - .branch = {}, - .source = {{.s = dummy_complex_value_sym, .i = dummy_complex_value_sym}}, - .shunt = {{.s = dummy_complex_value_sym, .i = dummy_complex_value_sym}}, - .load_gen = {{.s = dummy_complex_value_sym, .i = dummy_complex_value_sym}}, - .voltage_regulator = {}}); - - detail::add_appliance_injection(state, math_output, std::ref(accumulator)); - CHECK(accumulator.net_node_injections.size() == 1); - CHECK(accumulator.net_node_injections.at(Idx2D{.group = 0, .pos = 0}) == dummy_complex_value_sym); - CHECK(!accumulator.net_node_injections.contains(Idx2D{.group = 1, .pos = 0})); - - detail::add_appliance_injection(state, math_output, std::ref(accumulator)); - CHECK(accumulator.net_node_injections.size() == 2); - CHECK(accumulator.net_node_injections.at(Idx2D{.group = 0, .pos = 0}) == dummy_complex_value_sym); - CHECK(accumulator.net_node_injections.at(Idx2D{.group = 1, .pos = 0}) == dummy_complex_value_sym); - } - SUBCASE("Short circuit output") { - MathOutput>> math_output{}; - math_output.solver_output.emplace_back(ShortCircuitSolverOutput{ - .u_bus = {}, - .fault = {{.i_fault = dummy_complex_value_sym}, {.i_fault = dummy_complex_value_sym}}, - .branch = {}, - .source = {{.i = dummy_complex_value_sym}}, - .shunt = {{.i = dummy_complex_value_sym}}, - }); - - detail::add_appliance_injection(state, math_output, std::ref(accumulator)); - CHECK(accumulator.net_node_injections.size() == 1); - CHECK(accumulator.net_node_injections.at(Idx2D{.group = 0, .pos = 0}) == dummy_complex_value_sym); - CHECK(!accumulator.net_node_injections.contains(Idx2D{.group = 1, .pos = 0})); - } - } - SUBCASE("solve_topological_nodes") { - // first creates super node output empty - // then it accumulates injection from math output to super node output - only for nodes - // then gets supernode output - using ComponentContainer = - Container, SymLoad, Fault, Node, Source, Shunt>; - using State = MainModelState; - - State state; - auto comp_topo = std::make_shared(); - comp_topo->n_node = 2; - comp_topo->source_node_idx = {Idx{0}, Idx{1}}; - comp_topo->shunt_node_idx = {Idx{1}}; - comp_topo->load_gen_node_idx = {Idx{1}}; - - ComponentConnections const comp_conn; - // no links, so no supernodes, identity mapping - // TODO(figueroa1395): this needs to be modified later when link output is added - state.reduced_topology = - std::make_shared(supernodes::reduce_topology(*comp_topo, comp_conn)); - state.comp_topo = std::make_shared(std::move(*comp_topo)); - - state.topo_comp_coup = std::make_shared([] { - TopologicalComponentToMathCoupling result; - result.load_gen = {{.group = 0, .pos = 0}}; - result.source = {{.group = 0, .pos = 0}, {.group = disconnected, .pos = disconnected}}; - return result; - }()); - - state.comp_coup = ComponentToMathCoupling{ - .fault = {{.group = 0, .pos = 0}, {.group = 0, .pos = 1}}, - }; - - emplace_component(state.components, 0, SourceInput{}, dummy_value); - emplace_component(state.components, 1, ShuntInput{}, dummy_value); - emplace_component(state.components, 2, LoadGenInput{}, dummy_value); - emplace_component(state.components, 101, NodeInput{.id = 101}); // .id needed for fault linking - emplace_component(state.components, 102, NodeInput{.id = 102}); // .id needed for fault linking - emplace_component(state.components, 3, FaultInput{.fault_object = 101}); - emplace_component(state.components, 4, FaultInput{.fault_object = 102}); - state.components.set_construction_complete(); - - SUBCASE("Steady state output") { - MathOutput>> math_output{}; - math_output.solver_output.emplace_back( - SolverOutput{.u = {}, - .bus_injection = {}, - .bus = {}, - .branch = {}, - .source = {{.s = dummy_complex_value_sym, .i = dummy_complex_value_sym}}, - .shunt = {{.s = dummy_complex_value_sym, .i = dummy_complex_value_sym}}, - .load_gen = {{.s = dummy_complex_value_sym, .i = dummy_complex_value_sym}}, - .voltage_regulator = {}}); - - solve_topological_nodes(state, math_output); - CHECK(math_output.supernode_output.size() == 2); - CHECK(math_output.supernode_output[0].bus_injection[0] == dummy_complex_value_sym); - CHECK(math_output.supernode_output[1].bus_injection[0] == dummy_complex_value_sym); - } - - // TODO(figueroa1395): add short circuit output test when short circuit output is added - } -} -} // namespace power_grid_model::main_core diff --git a/tests/cpp_unit_tests/math_solver/test_math_solver_pf.hpp b/tests/cpp_unit_tests/math_solver/test_math_solver_pf.hpp index ddcbd6de08..86055d5f91 100644 --- a/tests/cpp_unit_tests/math_solver/test_math_solver_pf.hpp +++ b/tests/cpp_unit_tests/math_solver/test_math_solver_pf.hpp @@ -83,7 +83,7 @@ template struct PFSolverTestGrid : public SteadyStateSol }; TEST_CASE_TEMPLATE_DEFINE("Test math solver - PF", SolverType, test_math_solver_pf_id) { - using sym = decode_symmetry_v; + using sym = SolverType::sym; using common::logging::NoLogger; PFSolverTestGrid const grid; diff --git a/tests/cpp_unit_tests/math_solver/test_math_solver_se.hpp b/tests/cpp_unit_tests/math_solver/test_math_solver_se.hpp index 3df46ef009..ab07eb6258 100644 --- a/tests/cpp_unit_tests/math_solver/test_math_solver_se.hpp +++ b/tests/cpp_unit_tests/math_solver/test_math_solver_se.hpp @@ -315,7 +315,7 @@ TEST_CASE_TEMPLATE_DEFINE("Test math solver - SE", SolverType, test_math_solver_ constexpr auto error_tolerance{1e-10}; constexpr auto num_iter{20}; - using sym = decode_symmetry_v; + using sym = SolverType::sym; SESolverTestGrid const grid; diff --git a/tests/cpp_unit_tests/optimizer/test_optimizer.hpp b/tests/cpp_unit_tests/optimizer/test_optimizer.hpp index e7f410be98..885d04f6ab 100644 --- a/tests/cpp_unit_tests/optimizer/test_optimizer.hpp +++ b/tests/cpp_unit_tests/optimizer/test_optimizer.hpp @@ -91,8 +91,6 @@ using StubState = main_core::MainModelState; static_assert(main_core::main_model_state_c); struct StubStateCalculatorResultType { - using sym = symmetric_t; - Idx x{}; }; @@ -107,12 +105,6 @@ using AsymStubSteadyStateCalculator = std::vector> (* using StubUpdate = void (*)(StubUpdateType const& /* update_data */); using ConstDatasetUpdate = void (*)(ConstDataset const& /* update_data */); -} // namespace optimizer::test - -template T> struct SupernodeOutput {}; - -namespace optimizer::test { - static_assert(std::invocable); static_assert(std::same_as, StubStateCalculatorResultType>); diff --git a/tests/cpp_unit_tests/optimizer/test_tap_position_optimizer.cpp b/tests/cpp_unit_tests/optimizer/test_tap_position_optimizer.cpp index 4ba0a84f2f..d5e3a1f38e 100644 --- a/tests/cpp_unit_tests/optimizer/test_tap_position_optimizer.cpp +++ b/tests/cpp_unit_tests/optimizer/test_tap_position_optimizer.cpp @@ -802,7 +802,7 @@ template class MockSolverOutput : public SolverOutput { public: using type = solver_output_t; - using sym = decode_symmetry_v>; + using sym = SolverOutput::sym; Idx call_index{-1}; CalculationMethod method; diff --git a/tests/data/power_flow/dummy-test/sym_output.json b/tests/data/power_flow/dummy-test/sym_output.json index fab0729362..4a679e321a 100644 --- a/tests/data/power_flow/dummy-test/sym_output.json +++ b/tests/data/power_flow/dummy-test/sym_output.json @@ -18,7 +18,7 @@ "u_pu": 0.84, "u": 8400.0, "u_angle": 0.0, - "p": 0.0, + "p": -0.00961, "q": 0.0 }, { diff --git a/tests/data/state_estimation/distribution-case/sym_output_batch.json b/tests/data/state_estimation/distribution-case/sym_output_batch.json index 1cd9fb914f..ac44069d93 100644 --- a/tests/data/state_estimation/distribution-case/sym_output_batch.json +++ b/tests/data/state_estimation/distribution-case/sym_output_batch.json @@ -6,14 +6,14 @@ "data": [ { "node": [ - {"id": 1, "energized": 1, "u_pu": 0.8560431728248089, "u": 17120.86345649618, "u_angle": -0.235669426481254, "p": 208796.5974370964, "q": 79187.68503019326}, - {"id": 2, "energized": 1, "u_pu": 0.8528526001314131, "u": 341.1410400525652, "u_angle": -2.862596343594322, "p": 0, "q": 0}, - {"id": 3, "energized": 1, "u_pu": 0.8524340340819745, "u": 340.9736136327898, "u_angle": -2.862612005735382, "p": -59500, "q": -15000}, - {"id": 4, "energized": 1, "u_pu": 0.85250335421984, "u": 341.001341687936, "u_angle": -2.86274812851491, "p": 44500, "q": 9000}, - {"id": 5, "energized": 1, "u_pu": 0.8495450062127854, "u": 339.8180024851142, "u_angle": -2.862590489406438, "p": -65550, "q": -21540}, - {"id": 6, "energized": 1, "u_pu": 0.8435284908262257, "u": 337.4113963304903, "u_angle": -2.862339370471785, "p": -70000, "q": -30000}, - {"id": 7, "energized": 1, "u_pu": 0.7992792459031395, "u": 319.7116983612558, "u_angle": -2.858988906779594, "p": 0, "q": 0}, - {"id": 8, "energized": 1, "u_pu": 0.7508434380440624, "u": 300.337375217625, "u_angle": -2.868715195841156, "p": -50250, "q": -15800} + {"id": 1, "energized": 1, "u_pu": 0.8560431728248089, "u": 17120.86345649618, "u_angle": -0.235669426481254, "p": 208796.5974370983, "q": 79187.68503019707}, + {"id": 2, "energized": 1, "u_pu": 0.8528526001314131, "u": 341.1410400525652, "u_angle": -2.862596343594322, "p": -1.997686330964493e-07, "q": -6.798281342824914e-09}, + {"id": 3, "energized": 1, "u_pu": 0.8524340340819745, "u": 340.9736136327898, "u_angle": -2.862612005735382, "p": -59499.99999993332, "q": -14999.99999999823}, + {"id": 4, "energized": 1, "u_pu": 0.85250335421984, "u": 341.001341687936, "u_angle": -2.86274812851491, "p": 44500.00000005522, "q": 8999.999999967109}, + {"id": 5, "energized": 1, "u_pu": 0.8495450062127854, "u": 339.8180024851142, "u_angle": -2.862590489406438, "p": -65549.99999999226, "q": -21539.99999999868}, + {"id": 6, "energized": 1, "u_pu": 0.8435284908262257, "u": 337.4113963304903, "u_angle": -2.862339370471785, "p": -70000.00000000138, "q": -30000.00000000225}, + {"id": 7, "energized": 1, "u_pu": 0.7992792459031395, "u": 319.7116983612558, "u_angle": -2.858988906779594, "p": 1.552825440000203e-10, "q": 7.381143611087364e-10}, + {"id": 8, "energized": 1, "u_pu": 0.7508434380440624, "u": 300.337375217625, "u_angle": -2.868715195841156, "p": -50249.99999999988, "q": -15800.00000000021} ], "line": [ {"id": 9, "energized": 1, "loading": 0.02209738886894574, "p_from": 125334.3178071244, "q_from": 36595.2834364627, "i_from": 220.9738713516455, "s_from": 130567.629946983, "p_to": -125273.3786464605, "q_to": -36575.39756158792, "i_to": 220.9738886894574, "s_to": 130503.5597379921}, @@ -32,12 +32,12 @@ {"id": 16, "energized": 1, "p": 208796.5974370964, "q": 79187.68503019326, "i": 7.530417601791036, "s": 223308.5501313149, "pf": 0.9350138958598546} ], "asym_gen": [ - {"id": 23, "energized": 1, "p": 44500, "q": 9000, "i": 76.86853766819721, "s": 45400.99117860755, "pf": 0.9801548125884952} + {"id": 23, "energized": 1, "p": 44500.00000000001, "q": 9000.000000000002, "i": 76.86853766819721, "s": 45400.99117860755, "pf": 0.9801548125884952} ], "sym_load": [ {"id": 19, "energized": 1, "p": 65550, "q": 21540, "i": 117.228113796972, "s": 68998.36302406021, "pf": 0.9500225386092459}, {"id": 20, "energized": 1, "p": 70000, "q": 30000, "i": 130.314764129984, "s": 76157.73105863907, "pf": 0.9191450300180581}, - {"id": 21, "energized": 1, "p": 50250, "q": 15800, "i": 101.2600656038892, "s": 52675.44494354081, "pf": 0.9539549225233791} + {"id": 21, "energized": 1, "p": 50249.99999999999, "q": 15800, "i": 101.2600656038892, "s": 52675.44494354081, "pf": 0.9539549225233791} ], "asym_load": [ {"id": 22, "energized": 1, "p": 59500, "q": 15000, "i": 103.8999907711124, "s": 61361.6329639295, "pf": 0.9696612871266996} @@ -45,14 +45,14 @@ }, { "node": [ - {"id": 1, "energized": 1, "u_pu": 0.85889911850856, "u": 17177.9823701712, "u_angle": -0.2310256470571513, "p": 205479.7015637694, "q": 78314.90865825058}, - {"id": 2, "energized": 1, "u_pu": 0.8557550719997815, "u": 342.3020287999126, "u_angle": -2.857750987392809, "p": 0, "q": 0}, - {"id": 3, "energized": 1, "u_pu": 0.8551878706006839, "u": 342.0751482402736, "u_angle": -2.857753180680732, "p": -59500, "q": -15000}, - {"id": 4, "energized": 1, "u_pu": 0.8555928560276003, "u": 342.2371424110401, "u_angle": -2.857805570616444, "p": 44500, "q": 9000}, - {"id": 5, "energized": 1, "u_pu": 0.8503582471485877, "u": 340.143298859435, "u_angle": -2.857544589280911, "p": -65550, "q": -21540}, - {"id": 6, "energized": 1, "u_pu": 0.8499482723700497, "u": 339.9793089480199, "u_angle": -2.857621661550209, "p": -70000, "q": -30000}, - {"id": 7, "energized": 1, "u_pu": 0.842561694093326, "u": 337.0246776373304, "u_angle": -2.860245900881301, "p": 0, "q": 0}, - {"id": 8, "energized": 1, "u_pu": 0.7969314955680196, "u": 318.7725982272078, "u_angle": -2.868940596515285, "p": -50250, "q": -15800} + {"id": 1, "energized": 1, "u_pu": 0.85889911850856, "u": 17177.9823701712, "u_angle": -0.2310256470571513, "p": 205479.70156377, "q": 78314.90865824612}, + {"id": 2, "energized": 1, "u_pu": 0.8557550719997815, "u": 342.3020287999126, "u_angle": -2.857750987392809, "p": 9.339526889029868e-08, "q": 2.724510626852009e-08}, + {"id": 3, "energized": 1, "u_pu": 0.8551878706006839, "u": 342.0751482402736, "u_angle": -2.857753180680732, "p": -59500.00000009832, "q": -14999.99999994298}, + {"id": 4, "energized": 1, "u_pu": 0.8555928560276003, "u": 342.2371424110401, "u_angle": -2.857805570616444, "p": 44499.99999998496, "q": 8999.999999953134}, + {"id": 5, "energized": 1, "u_pu": 0.8503582471485877, "u": 340.143298859435, "u_angle": -2.857544589280911, "p": -65549.99999999917, "q": -21540.00000000034}, + {"id": 6, "energized": 1, "u_pu": 0.8499482723700497, "u": 339.9793089480199, "u_angle": -2.857621661550209, "p": -70000.00000000307, "q": -29999.99999999695}, + {"id": 7, "energized": 1, "u_pu": 0.842561694093326, "u": 337.0246776373304, "u_angle": -2.860245900881301, "p": 1.567705059969451e-09, "q": -3.377063503214469e-11}, + {"id": 8, "energized": 1, "u_pu": 0.7969314955680196, "u": 318.7725982272078, "u_angle": -2.868940596515285, "p": -50249.99999999984, "q": -15800.00000000024} ], "line": [ {"id": 9, "energized": 1, "loading": 0.0299292409082664, "p_from": 168842.8448571942, "q_from": 54581.25130631004, "i_from": 299.2923899915594, "s_from": 177445.8206147249, "p_to": -168731.0540835474, "q_to": -54544.74110847269, "i_to": 299.2924090826639, "s_to": 177328.2193976337}, @@ -71,12 +71,12 @@ {"id": 16, "energized": 1, "p": 205479.7015637694, "q": 78314.90865825058, "i": 7.3907499575293, "s": 219898.0051589506, "pf": 0.9344318581482396} ], "asym_gen": [ - {"id": 23, "energized": 1, "p": 44500, "q": 9000, "i": 76.5909693313268, "s": 45400.99117860755, "pf": 0.9801548125884952} + {"id": 23, "energized": 1, "p": 44500.00000000001, "q": 9000.000000000002, "i": 76.5909693313268, "s": 45400.99117860755, "pf": 0.9801548125884952} ], "sym_load": [ {"id": 19, "energized": 1, "p": 65550, "q": 21540, "i": 117.1160025764526, "s": 68998.36302406021, "pf": 0.9500225386092459}, {"id": 20, "energized": 1, "p": 70000, "q": 30000, "i": 129.3304779741728, "s": 76157.73105863907, "pf": 0.9191450300180581}, - {"id": 21, "energized": 1, "p": 50250, "q": 15800, "i": 95.40400425559811, "s": 52675.44494354081, "pf": 0.9539549225233791} + {"id": 21, "energized": 1, "p": 50249.99999999999, "q": 15800, "i": 95.40400425559811, "s": 52675.44494354081, "pf": 0.9539549225233791} ], "asym_load": [ {"id": 22, "energized": 1, "p": 59500, "q": 15000, "i": 103.5654168152423, "s": 61361.6329639295, "pf": 0.9696612871266996}