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

Feature / Add columnar data support in main model #712

Merged
merged 12 commits into from
Sep 10, 2024
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>);
mgovers marked this conversation as resolved.
Show resolved Hide resolved

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 <powergridmodel@lfenergy.org>
//
// 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>
mgovers marked this conversation as resolved.
Show resolved Hide resolved
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>;
figueroa1395 marked this conversation as resolved.
Show resolved Hide resolved

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>
figueroa1395 marked this conversation as resolved.
Show resolved Hide resolved
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>>>;
figueroa1395 marked this conversation as resolved.
Show resolved Hide resolved
}
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
Loading