Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -9,6 +9,7 @@
#include "common/common.hpp"
#include "common/exception.hpp"
#include "common/iterator_facade.hpp"
#include "container_fwd.hpp"

#include <boost/range.hpp>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
//
// SPDX-License-Identifier: MPL-2.0

#pragma once

#include "common/common.hpp"

#include <concepts>

namespace power_grid_model::common {

namespace detail {
template <typename ContainerType, typename RetrievableType>
concept single_component_container_c = requires(ContainerType const& c, ID id, Idx2D idx2d) {
{ c.template citer<RetrievableType>().begin() } -> std::forward_iterator;
{ c.template citer<RetrievableType>().end() } -> std::forward_iterator;
{ *(c.template citer<RetrievableType>().begin()) } -> std::same_as<RetrievableType const&>;
{
c.template citer<RetrievableType>().end()
} -> std::same_as<decltype(c.template citer<RetrievableType>().begin())>;
{ c.template get_item<RetrievableType>(id) } -> std::convertible_to<RetrievableType const&>;
{ c.template size<RetrievableType>() } -> std::same_as<Idx>;
{ c.template get_seq<RetrievableType>(idx2d) } -> std::same_as<Idx>;
};
} // namespace detail

template <typename ContainerType, typename... RetrievableType>
concept component_container_c = (detail::single_component_container_c<ContainerType, RetrievableType> && ...);

} // namespace power_grid_model::common
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
//
// SPDX-License-Identifier: MPL-2.0

#pragma once

#include "../container.hpp"

namespace power_grid_model::main_core {

// TODO Reconfirm if there is duplication with state_queries and if we can remove either one of them

template <typename ComponentType, class ComponentContainer>
requires common::component_container_c<ComponentContainer, ComponentType>
constexpr auto get_component_size(ComponentContainer const& components) {
return components.template size<ComponentType>();
}

template <typename ComponentType, class ComponentContainer>
requires common::component_container_c<ComponentContainer, ComponentType>
inline Idx get_component_sequence_idx(ComponentContainer const& components, auto const& id_or_index) {
return components.template get_seq<ComponentType>(id_or_index);
}

} // namespace power_grid_model::main_core
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,9 @@ template <class CompContainer> struct MainModelState {
template <class StateType>
concept main_model_state_c = std::same_as<StateType, MainModelState<typename StateType::ComponentContainer>>;

template <typename ContainerType, typename ComponentType>
concept component_container_c = requires(ContainerType const& c, ID id) {
{ c.template citer<ComponentType>().begin() } -> std::forward_iterator;
{ c.template citer<ComponentType>().end() } -> std::forward_iterator;
{ *(c.template citer<ComponentType>().begin()) } -> std::same_as<ComponentType const&>;
{ *(c.template citer<ComponentType>().end()) } -> std::same_as<ComponentType const&>;
{ c.template get_item<ComponentType>(id) } -> std::convertible_to<ComponentType const&>;
};

template <template <typename T> class StateType, typename ContainerType, typename ComponentType>
concept model_component_state_c =
component_container_c<typename StateType<ContainerType>::ComponentContainer, ComponentType> &&
common::component_container_c<typename StateType<ContainerType>::ComponentContainer, ComponentType> &&
std::same_as<StateType<ContainerType>, MainModelState<ContainerType>>;

} // namespace power_grid_model::main_core
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "../all_components.hpp"

namespace power_grid_model::main_core {

template <typename ComponentType, class ComponentContainer>
requires model_component_state_c<MainModelState, ComponentContainer, ComponentType>
inline Idx get_component_type_index(MainModelState<ComponentContainer> const& state) {
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -314,22 +314,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
construction_complete_ = true;
#endif // !NDEBUG
state_.components.set_construction_complete();
construct_topology();
}

void construct_topology() {
ComponentTopology comp_topo;
main_core::register_topology_components<Node>(state_, comp_topo);
main_core::register_topology_components<Branch>(state_, comp_topo);
main_core::register_topology_components<Branch3>(state_, comp_topo);
main_core::register_topology_components<Source>(state_, comp_topo);
main_core::register_topology_components<Shunt>(state_, comp_topo);
main_core::register_topology_components<GenericLoadGen>(state_, comp_topo);
main_core::register_topology_components<GenericVoltageSensor>(state_, comp_topo);
main_core::register_topology_components<GenericPowerSensor>(state_, comp_topo);
main_core::register_topology_components<GenericCurrentSensor>(state_, comp_topo);
main_core::register_topology_components<Regulator>(state_, comp_topo);
state_.comp_topo = std::make_shared<ComponentTopology const>(std::move(comp_topo));
state_.comp_topo = std::make_shared<ComponentTopology const>(main_core::construct_topology(state_.components));
}

void reset_solvers() {
Expand Down Expand Up @@ -652,33 +637,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
assert(construction_complete_);
// clear old solvers
reset_solvers();
// get connection info
ComponentConnections comp_conn;
comp_conn.branch_connected.resize(state_.comp_topo->branch_node_idx.size());
comp_conn.branch_phase_shift.resize(state_.comp_topo->branch_node_idx.size());
comp_conn.branch3_connected.resize(state_.comp_topo->branch3_node_idx.size());
comp_conn.branch3_phase_shift.resize(state_.comp_topo->branch3_node_idx.size());
comp_conn.source_connected.resize(state_.comp_topo->source_node_idx.size());
std::transform(
state_.components.template citer<Branch>().begin(), state_.components.template citer<Branch>().end(),
comp_conn.branch_connected.begin(), [](Branch const& branch) {
return BranchConnected{static_cast<IntS>(branch.from_status()), static_cast<IntS>(branch.to_status())};
});
std::transform(state_.components.template citer<Branch>().begin(),
state_.components.template citer<Branch>().end(), comp_conn.branch_phase_shift.begin(),
[](Branch const& branch) { return branch.phase_shift(); });
std::transform(
state_.components.template citer<Branch3>().begin(), state_.components.template citer<Branch3>().end(),
comp_conn.branch3_connected.begin(), [](Branch3 const& branch3) {
return Branch3Connected{static_cast<IntS>(branch3.status_1()), static_cast<IntS>(branch3.status_2()),
static_cast<IntS>(branch3.status_3())};
});
std::transform(state_.components.template citer<Branch3>().begin(),
state_.components.template citer<Branch3>().end(), comp_conn.branch3_phase_shift.begin(),
[](Branch3 const& branch3) { return branch3.phase_shift(); });
std::transform(state_.components.template citer<Source>().begin(),
state_.components.template citer<Source>().end(), comp_conn.source_connected.begin(),
[](Source const& source) { return source.status(); });
ComponentConnections const comp_conn = main_core::construct_components_connections(state_.components);
// re build
Topology topology{*state_.comp_topo, comp_conn};
std::tie(state_.math_topology, state_.topo_comp_coup) = topology.build_topology();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ constexpr auto get_optimizer(OptimizerType optimizer_type, OptimizerStrategy str
case automatic_tap_adjustment:
if constexpr (detail::steady_state_calculator_c<StateCalculator, State> &&
std::invocable<std::remove_cvref_t<StateUpdater>, ConstDataset const&> &&
main_core::component_container_c<typename State::ComponentContainer, TransformerTapRegulator>) {
common::component_container_c<typename State::ComponentContainer, TransformerTapRegulator>) {
return BaseOptimizer::template make_shared<TapPositionOptimizer<StateCalculator, StateUpdater, State>>(
std::move(calculator), std::move(updater), strategy, meta_data, search);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ template <transformer_c... TransformerTypes> struct TapRegulatorRef {
};

template <typename State>
requires main_core::component_container_c<typename State::ComponentContainer, TransformerTapRegulator>
requires common::component_container_c<typename State::ComponentContainer, TransformerTapRegulator>
TransformerTapRegulator const& find_regulator(State const& state, ID regulated_object) {
auto const regulators = get_component_citer<TransformerTapRegulator>(state);

Expand Down Expand Up @@ -503,7 +503,7 @@ template <typename... Ts> struct transformer_types_s<std::tuple<std::tuple<Ts...
template <typename... Ts> using transformer_types_t = typename transformer_types_s<std::tuple<Ts...>>::type;

template <transformer_c... TransformerTypes, typename State>
requires(main_core::component_container_c<typename State::ComponentContainer, TransformerTypes> && ...)
requires(common::component_container_c<typename State::ComponentContainer, TransformerTypes> && ...)
inline TapRegulatorRef<TransformerTypes...> regulator_mapping(State const& state, Idx2D const& transformer_index) {
using ResultType = TapRegulatorRef<TransformerTypes...>;
using IsType = bool (*)(Idx2D const&);
Expand Down Expand Up @@ -536,7 +536,7 @@ inline TapRegulatorRef<TransformerTypes...> regulator_mapping(State const& state
}

template <transformer_c... TransformerTypes, typename State>
requires(main_core::component_container_c<typename State::ComponentContainer, TransformerTypes> && ...)
requires(common::component_container_c<typename State::ComponentContainer, TransformerTypes> && ...)
inline auto regulator_mapping(State const& state, std::vector<Idx2D> const& order) {
std::vector<TapRegulatorRef<TransformerTypes...>> result;
result.reserve(order.size());
Expand All @@ -549,7 +549,7 @@ inline auto regulator_mapping(State const& state, std::vector<Idx2D> const& orde
}

template <transformer_c... TransformerTypes, typename State>
requires(main_core::component_container_c<typename State::ComponentContainer, TransformerTypes> && ...)
requires(common::component_container_c<typename State::ComponentContainer, TransformerTypes> && ...)
inline auto regulator_mapping(State const& state, RankedTransformerGroups const& order) {
std::vector<std::vector<TapRegulatorRef<TransformerTypes...>>> result;
result.reserve(order.size());
Expand Down Expand Up @@ -598,15 +598,15 @@ inline auto i_pu(std::vector<SolverOutputType> const& solver_output, Idx2DBranch

template <component_c ComponentType, typename... RegulatedTypes, typename State,
steady_state_solver_output_type SolverOutputType>
requires main_core::component_container_c<typename State::ComponentContainer, ComponentType>
requires common::component_container_c<typename State::ComponentContainer, ComponentType>
inline auto i_pu_controlled_node(TapRegulatorRef<RegulatedTypes...> const& regulator, State const& state,
std::vector<SolverOutputType> const& solver_output) {
auto const& branch_math_id = get_math_id<ComponentType>(state, regulator.transformer.topology_index());
return i_pu<ComponentType>(solver_output, branch_math_id, regulator.regulator.get().control_side());
}

template <transformer_c ComponentType, typename State, steady_state_solver_output_type SolverOutputType>
requires main_core::component_container_c<typename State::ComponentContainer, ComponentType> &&
requires common::component_container_c<typename State::ComponentContainer, ComponentType> &&
requires(State const& state, Idx const i) {
{ get_branch_nodes<ComponentType>(state, i)[i] } -> std::convertible_to<Idx>;
}
Expand All @@ -619,15 +619,15 @@ inline auto u_pu(State const& state, std::vector<SolverOutputType> const& solver

template <component_c ComponentType, typename... RegulatedTypes, typename State,
steady_state_solver_output_type SolverOutputType>
requires main_core::component_container_c<typename State::ComponentContainer, ComponentType>
requires common::component_container_c<typename State::ComponentContainer, ComponentType>
inline auto u_pu_controlled_node(TapRegulatorRef<RegulatedTypes...> const& regulator, State const& state,
std::vector<SolverOutputType> const& solver_output) {
return u_pu<ComponentType>(state, solver_output, regulator.transformer.topology_index(),
regulator.regulator.get().control_side());
}

template <component_c ComponentType, typename... RegulatedTypes, typename State>
requires main_core::component_container_c<typename State::ComponentContainer, ComponentType>
requires common::component_container_c<typename State::ComponentContainer, ComponentType>
inline bool is_regulated_transformer_connected(TapRegulatorRef<RegulatedTypes...> const& regulator,
State const& state) {
auto const controlled_node_idx = get_topo_node<ComponentType>(state, regulator.transformer.topology_index(),
Expand Down Expand Up @@ -702,7 +702,7 @@ class RankIteration {
template <typename... T> class TapPositionOptimizerImpl;
template <transformer_c... TransformerTypes, typename StateCalculator, typename StateUpdater_, typename State_,
typename TransformerRanker_>
requires(main_core::component_container_c<typename State_::ComponentContainer, TransformerTypes> && ...) &&
requires(common::component_container_c<typename State_::ComponentContainer, TransformerTypes> && ...) &&
detail::steady_state_calculator_c<StateCalculator, State_> &&
std::invocable<std::remove_cvref_t<StateUpdater_>, ConstDataset const&> &&
requires(TransformerRanker_ const& ranker, State_ const& state) {
Expand Down
15 changes: 15 additions & 0 deletions tests/cpp_unit_tests/test_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,21 @@ TEST_CASE("Test component container") {
CHECK(const_container.get_id_by_idx(Idx2D{2, 0}) == 3);
}
#endif // NDEBUG

SUBCASE("Component Container concept") {
static_assert(common::component_container_c<CompContainer, C>);
static_assert(common::component_container_c<CompContainer, C1>);
static_assert(common::component_container_c<CompContainer, C2>);
static_assert(common::component_container_c<CompContainer, C, C1>);
static_assert(common::component_container_c<CompContainer, C1, C2>);
static_assert(common::component_container_c<CompContainer, C, C1, C2>);
static_assert(common::component_container_c<CompContainer2, C>);
static_assert(common::component_container_c<CompContainer2, C1>);
static_assert(common::component_container_c<CompContainer2, C2>);
static_assert(common::component_container_c<CompContainer2, C, C1>);
static_assert(common::component_container_c<CompContainer2, C1, C2>);
static_assert(common::component_container_c<CompContainer2, C, C1, C2>);
}
}

} // namespace power_grid_model
6 changes: 3 additions & 3 deletions tests/cpp_unit_tests/test_optimizer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ static_assert(transformer_c<StubTransformerA>);
static_assert(transformer_c<StubTransformerB>);

template <std::derived_from<StubTransformer> ComponentType, typename State>
requires main_core::component_container_c<typename State::ComponentContainer, ComponentType>
requires common::component_container_c<typename State::ComponentContainer, ComponentType>
constexpr auto get_topology_index(State const& /* state */, auto const& /* id_or_index */) {
return Idx{};
}

template <std::derived_from<StubTransformer> ComponentType, typename State>
requires main_core::component_container_c<typename State::ComponentContainer, ComponentType>
requires common::component_container_c<typename State::ComponentContainer, ComponentType>
constexpr auto get_math_id(State const& /* state */, Idx /* topology_sequence_idx */) {
return StubTransformerMathIdType{};
}
Expand All @@ -73,7 +73,7 @@ inline auto i_pu(std::vector<SolverOutputType> const& /* solver_output */,

template <std::derived_from<StubTransformer> ComponentType, typename State,
steady_state_solver_output_type SolverOutputType>
requires main_core::component_container_c<typename State::ComponentContainer, ComponentType>
requires common::component_container_c<typename State::ComponentContainer, ComponentType>
inline auto u_pu(State const& /* state */, std::vector<SolverOutputType> const& /* solver_output */,
Idx /* topology_index */, ControlSide /* control_side */) {
return ComplexValue<typename SolverOutputType::sym>{};
Expand Down
8 changes: 4 additions & 4 deletions tests/cpp_unit_tests/test_tap_position_optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ class MockSolverOutput : public SolverOutput<symmetric_t> {
template <typename... T> struct AddTapPositions;
template <typename T> struct AddTapPositions<T> {
void operator()(main_core::MainModelState<ContainerType> const& state, std::map<ID, IntS>& target) {
if constexpr (transformer_c<T> && main_core::component_container_c<ContainerType, T>) {
if constexpr (transformer_c<T> && common::component_container_c<ContainerType, T>) {
for (auto const& component : state.components.template citer<T>()) {
target[component.id()] = component.tap_pos();
}
Expand Down Expand Up @@ -732,14 +732,14 @@ struct MockTransformer {
static_assert(transformer_c<MockTransformer>);

template <std::derived_from<MockTransformer> ComponentType, typename State>
requires main_core::component_container_c<typename State::ComponentContainer, ComponentType>
requires common::component_container_c<typename State::ComponentContainer, ComponentType>
constexpr auto get_topology_index(State const& state, auto const& id_or_index) {
auto const& transformer = main_core::get_component<ComponentType>(state, id_or_index);
return transformer.state.math_id.pos;
}

template <std::derived_from<MockTransformer> ComponentType, typename State>
requires main_core::component_container_c<typename State::ComponentContainer, ComponentType>
requires common::component_container_c<typename State::ComponentContainer, ComponentType>
constexpr auto get_math_id(State const& state, Idx topology_index) {
return main_core::get_component_by_sequence<MockTransformer>(state, topology_index).state.math_id;
}
Expand All @@ -763,7 +763,7 @@ inline DoubleComplex i_pu(std::vector<MockSolverOutput<ContainerType>> const& so

template <std::derived_from<MockTransformer> ComponentType, typename State,
steady_state_solver_output_type SolverOutputType>
requires main_core::component_container_c<typename State::ComponentContainer, ComponentType>
requires common::component_container_c<typename State::ComponentContainer, ComponentType>
inline auto u_pu(State const& state, std::vector<SolverOutputType> const& /* solver_output */, Idx topology_index,
ControlSide side) {
return main_core::get_component_by_sequence<MockTransformer>(state, topology_index).state.u_pu(side);
Expand Down
Loading