Skip to content

Commit

Permalink
Merge pull request PowerGridModel#712 from PowerGridModel/feature/mai…
Browse files Browse the repository at this point in the history
…n-model-columnar-data

Feature / Add columnar data support in main model
  • Loading branch information
mgovers authored Sep 10, 2024
2 parents 7ffcca3 + 8e9effa commit a05b88a
Show file tree
Hide file tree
Showing 9 changed files with 338 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ template <typename T, dataset_type_tag dataset_type> class ColumnarAttributeRang
ctype_func_selector(
meta_attribute.ctype, [&value, &attribute_buffer, &meta_attribute, this]<typename AttributeType> {
AttributeType* buffer_ptr = reinterpret_cast<AttributeType*>(attribute_buffer.data) + idx_;
AttributeType const& attribute_ref = meta_attribute.template get_attribute<AttributeType const>(
auto const& attribute_ref = meta_attribute.template get_attribute<AttributeType const>(
reinterpret_cast<RawDataConstPtr>(&value));
*buffer_ptr = attribute_ref;
});
Expand All @@ -95,7 +95,7 @@ template <typename T, dataset_type_tag dataset_type> class ColumnarAttributeRang
meta_attribute.ctype, [&result, &attribute_buffer, &meta_attribute, this]<typename AttributeType> {
AttributeType const* buffer_ptr =
reinterpret_cast<AttributeType const*>(attribute_buffer.data) + idx_;
AttributeType& attribute_ref =
auto& attribute_ref =
meta_attribute.template get_attribute<AttributeType>(reinterpret_cast<RawDataPtr>(&result));
attribute_ref = *buffer_ptr;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "common.hpp"
#include "counting_iterator.hpp"
#include "iterator_like_concepts.hpp"
#include "typing.hpp"

#include <boost/iterator/iterator_facade.hpp>
Expand Down Expand Up @@ -36,6 +37,9 @@ namespace power_grid_model {
using IdxRange = boost::iterator_range<IdxCount>;

namespace detail {
// TODO(mgovers): replace the below relevant iterator concepts with the STD equivalent when we have index ranges.
// boost::counting_iterator does not satisfy all requirements std::*_iterator concepts:
static_assert(!std::random_access_iterator<IdxCount>);

inline auto sparse_encode(IdxVector const& element_groups, Idx num_groups) {
IdxVector result(num_groups + 1);
Expand All @@ -55,42 +59,6 @@ inline auto sparse_decode(IdxVector const& indptr) {
return result;
}

// TODO(mgovers): replace the below relevant subset here ourselves with the STD equivalent when we have std::ranges.
// boost::counting_iterator does not satisfy all requirements std::*_iterator concepts:
static_assert(!std::random_access_iterator<IdxCount>);
// we have to declare the relevant subset here ourselves.
template <typename T, typename ElementType>
concept iterator_like = requires(T const t) {
{ *t } -> std::convertible_to<std::remove_cvref_t<ElementType> const&>;
};

template <typename T, typename ElementType>
concept random_access_iterator_like =
std::regular<T> && iterator_like<T, ElementType> && std::totally_ordered<T> && requires(T t, Idx n) {
{ t++ } -> std::same_as<T>;
{ t-- } -> std::same_as<T>;
{ ++t } -> std::same_as<T&>;
{ --t } -> std::same_as<T&>;

{ t + n } -> std::same_as<T>;
{ t - n } -> std::same_as<T>;
{ t += n } -> std::same_as<T&>;
{ t -= n } -> std::same_as<T&>;
};

template <typename T, typename ElementType>
concept random_access_iterable_like = requires(T const t) {
{ t.begin() } -> random_access_iterator_like<ElementType>;
{ t.end() } -> random_access_iterator_like<ElementType>;
};

template <typename T>
concept index_range_iterator =
random_access_iterator_like<T, typename T::iterator> && requires(T const t) {
typename T::iterator;
{ *t } -> random_access_iterable_like<Idx>;
};

template <typename T>
concept grouped_index_vector_type = std::default_initializable<T> && requires(T const t, Idx const idx) {
typename T::iterator;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-FileCopyrightText: Contributors to the Power Grid Model project <[email protected]>
//
// SPDX-License-Identifier: MPL-2.0

#pragma once

namespace power_grid_model {
// TODO(mgovers): replace the below relevant iterator concepts with the STD equivalent when we have index ranges.
// e.g.: boost::counting_iterator does not satisfy all requirements std::*_iterator concepts:
// we have to declare the relevant subset here ourselves.

template <typename T, typename ElementType>
concept iterator_like = requires(T const t) {
{ *t } -> std::convertible_to<std::remove_cvref_t<ElementType> const&>;
};

template <typename T, typename ElementType>
concept forward_iterator_like = std::regular<T> && iterator_like<T, ElementType> && requires(T t) {
{ t++ } -> std::same_as<T>;
{ ++t } -> std::same_as<T&>;
};

template <typename T, typename ElementType>
concept bidirectional_iterator_like = forward_iterator_like<T, ElementType> && requires(T t) {
{ t-- } -> std::same_as<T>;
{ --t } -> std::same_as<T&>;
};

template <typename T, typename ElementType>
concept random_access_iterator_like =
bidirectional_iterator_like<T, ElementType> && std::totally_ordered<T> && requires(T t, Idx n) {
{ t + n } -> std::same_as<T>;
{ t - n } -> std::same_as<T>;
{ t += n } -> std::same_as<T&>;
{ t -= n } -> std::same_as<T&>;
};

template <typename T, typename ElementType>
concept random_access_iterable_like = requires(T const t) {
{ t.begin() } -> random_access_iterator_like<ElementType>;
{ t.end() } -> random_access_iterator_like<ElementType>;
};

template <typename T>
concept index_range_iterator =
random_access_iterator_like<T, typename T::iterator> && requires(T const t) {
typename T::iterator;
{ *t } -> random_access_iterable_like<Idx>;
};

} // namespace power_grid_model
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "state_queries.hpp"

#include "../all_components.hpp"
#include "../common/iterator_like_concepts.hpp"

#include <unordered_set>

Expand All @@ -19,16 +20,20 @@ constexpr std::array<Branch3Side, 3> const branch3_sides = {Branch3Side::side_1,
// template to construct components
// using forward interators
// different selection based on component type
template <std::derived_from<Base> Component, class ComponentContainer, std::forward_iterator ForwardIterator>
template <std::derived_from<Base> Component, class ComponentContainer,
forward_iterator_like<typename Component::InputType> ForwardIterator>
requires model_component_state_c<MainModelState, ComponentContainer, Component>
inline void add_component(MainModelState<ComponentContainer>& state, ForwardIterator begin, ForwardIterator end,
double system_frequency) {
using ComponentView = std::conditional_t<std::same_as<decltype(*begin), typename Component::InputType const&>,
typename Component::InputType const&, typename Component::InputType>;

reserve_component<Component>(state, std::distance(begin, end));
// do sanity check on the transformer tap regulator
std::vector<Idx2D> regulated_objects;
// loop to add component
for (auto it = begin; it != end; ++it) {
auto const& input = *it;
ComponentView const input = *it;
ID const id = input.id;
// construct based on type of component
if constexpr (std::derived_from<Component, Node>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ namespace power_grid_model::main_core {

namespace detail {

template <typename T, typename U>
concept assignable_to = std::assignable_from<U, T>;

template <std::same_as<Node> Component, class ComponentContainer>
requires model_component_state_c<MainModelState, ComponentContainer, Component>
constexpr auto comp_base_sequence_cbegin(MainModelState<ComponentContainer> const& state) {
Expand Down Expand Up @@ -75,12 +78,11 @@ constexpr auto comp_base_sequence_cbegin(MainModelState<ComponentContainer> cons
return state.comp_topo->regulated_object_idx.cbegin() + get_component_sequence_offset<Regulator, Component>(state);
}

template <typename Component, typename IndexType, class ComponentContainer, std::forward_iterator ResIt,
typename ResFunc>
template <typename Component, typename IndexType, class ComponentContainer, typename ResIt, typename ResFunc>
requires model_component_state_c<MainModelState, ComponentContainer, Component> &&
std::invocable<std::remove_cvref_t<ResFunc>, Component const&, IndexType> &&
std::convertible_to<std::invoke_result_t<ResFunc, Component const&, IndexType>,
std::iter_value_t<ResIt>> &&
assignable_to<std::invoke_result_t<ResFunc, Component const&, IndexType>,
std::add_lvalue_reference_t<std::iter_value_t<ResIt>>> &&
std::convertible_to<IndexType,
decltype(*comp_base_sequence_cbegin<Component>(MainModelState<ComponentContainer>{}))>
constexpr ResIt produce_output(MainModelState<ComponentContainer> const& state, ResIt res_it, ResFunc&& func) {
Expand Down Expand Up @@ -359,12 +361,12 @@ output_result(Component const& transformer_tap_regulator, MainModelState<Compone

// output base component
template <std::derived_from<Base> Component, class ComponentContainer, solver_output_type SolverOutputType,
std::forward_iterator ResIt>
typename ResIt>
requires model_component_state_c<MainModelState, ComponentContainer, Component> &&
requires(Component const& component, std::vector<SolverOutputType> const& solver_output, Idx2D math_id) {
{
output_result<Component>(component, solver_output, math_id)
} -> std::convertible_to<std::iter_value_t<ResIt>>;
} -> detail::assignable_to<std::add_lvalue_reference_t<std::iter_value_t<ResIt>>>;
}
constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
MathOutput<std::vector<SolverOutputType>> const& math_output, ResIt res_it) {
Expand All @@ -374,13 +376,13 @@ constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
});
}
template <std::derived_from<Base> Component, class ComponentContainer, solver_output_type SolverOutputType,
std::forward_iterator ResIt>
typename ResIt>
requires model_component_state_c<MainModelState, ComponentContainer, Component> &&
requires(Component const& component, MainModelState<ComponentContainer> const& state,
std::vector<SolverOutputType> const& solver_output, Idx2D math_id) {
{
output_result<Component>(component, state, solver_output, math_id)
} -> std::convertible_to<std::iter_value_t<ResIt>>;
} -> detail::assignable_to<std::add_lvalue_reference_t<std::iter_value_t<ResIt>>>;
}
constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
MathOutput<std::vector<SolverOutputType>> const& math_output, ResIt res_it) {
Expand All @@ -390,13 +392,13 @@ constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
});
}
template <std::derived_from<Base> Component, class ComponentContainer, solver_output_type SolverOutputType,
std::forward_iterator ResIt>
typename ResIt>
requires model_component_state_c<MainModelState, ComponentContainer, Component> &&
requires(Component const& component, MainModelState<ComponentContainer> const& state,
std::vector<SolverOutputType> const& solver_output, Idx obj_seq) {
{
output_result<Component>(component, state, solver_output, obj_seq)
} -> std::convertible_to<std::iter_value_t<ResIt>>;
} -> detail::assignable_to<std::add_lvalue_reference_t<std::iter_value_t<ResIt>>>;
}
constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
MathOutput<std::vector<SolverOutputType>> const& math_output, ResIt res_it) {
Expand All @@ -406,13 +408,13 @@ constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
});
}
template <std::derived_from<Base> Component, class ComponentContainer, solver_output_type SolverOutputType,
std::forward_iterator ResIt>
typename ResIt>
requires model_component_state_c<MainModelState, ComponentContainer, Component> &&
requires(Component const& component, std::vector<SolverOutputType> const& solver_output,
Idx2DBranch3 const& math_id) {
{
output_result<Component>(component, solver_output, math_id)
} -> std::convertible_to<std::iter_value_t<ResIt>>;
} -> detail::assignable_to<std::add_lvalue_reference_t<std::iter_value_t<ResIt>>>;
}
constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
MathOutput<std::vector<SolverOutputType>> const& math_output, ResIt res_it) {
Expand All @@ -421,14 +423,13 @@ constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
return output_result<Component>(component, math_output.solver_output, math_id);
});
}
template <std::derived_from<Base> Component, class ComponentContainer, typename SolverOutputType,
std::forward_iterator ResIt>
template <std::derived_from<Base> Component, class ComponentContainer, typename SolverOutputType, typename ResIt>
requires model_component_state_c<MainModelState, ComponentContainer, Component> &&
requires(Component const& component, MainModelState<ComponentContainer> const& state,
MathOutput<SolverOutputType> const& math_output, Idx const obj_seq) {
{
output_result<Component>(component, state, math_output, obj_seq)
} -> std::convertible_to<std::iter_value_t<ResIt>>;
} -> detail::assignable_to<std::add_lvalue_reference_t<std::iter_value_t<ResIt>>>;
}
constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
MathOutput<SolverOutputType> const& math_output, ResIt res_it) {
Expand All @@ -440,7 +441,7 @@ constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,

// output source, load_gen, shunt individually
template <std::same_as<Appliance> Component, class ComponentContainer, solver_output_type SolverOutputType,
std::forward_iterator ResIt>
typename ResIt>
requires model_component_state_c<MainModelState, ComponentContainer, Component>
constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
MathOutput<std::vector<SolverOutputType>> const& math_output, ResIt res_it) {
Expand Down
Loading

0 comments on commit a05b88a

Please sign in to comment.