Skip to content

Commit a05b88a

Browse files
authored
Merge pull request #712 from PowerGridModel/feature/main-model-columnar-data
Feature / Add columnar data support in main model
2 parents 7ffcca3 + 8e9effa commit a05b88a

File tree

9 files changed

+338
-80
lines changed

9 files changed

+338
-80
lines changed

power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ template <typename T, dataset_type_tag dataset_type> class ColumnarAttributeRang
7878
ctype_func_selector(
7979
meta_attribute.ctype, [&value, &attribute_buffer, &meta_attribute, this]<typename AttributeType> {
8080
AttributeType* buffer_ptr = reinterpret_cast<AttributeType*>(attribute_buffer.data) + idx_;
81-
AttributeType const& attribute_ref = meta_attribute.template get_attribute<AttributeType const>(
81+
auto const& attribute_ref = meta_attribute.template get_attribute<AttributeType const>(
8282
reinterpret_cast<RawDataConstPtr>(&value));
8383
*buffer_ptr = attribute_ref;
8484
});
@@ -95,7 +95,7 @@ template <typename T, dataset_type_tag dataset_type> class ColumnarAttributeRang
9595
meta_attribute.ctype, [&result, &attribute_buffer, &meta_attribute, this]<typename AttributeType> {
9696
AttributeType const* buffer_ptr =
9797
reinterpret_cast<AttributeType const*>(attribute_buffer.data) + idx_;
98-
AttributeType& attribute_ref =
98+
auto& attribute_ref =
9999
meta_attribute.template get_attribute<AttributeType>(reinterpret_cast<RawDataPtr>(&result));
100100
attribute_ref = *buffer_ptr;
101101
});

power_grid_model_c/power_grid_model/include/power_grid_model/common/grouped_index_vector.hpp

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "common.hpp"
88
#include "counting_iterator.hpp"
9+
#include "iterator_like_concepts.hpp"
910
#include "typing.hpp"
1011

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

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

4044
inline auto sparse_encode(IdxVector const& element_groups, Idx num_groups) {
4145
IdxVector result(num_groups + 1);
@@ -55,42 +59,6 @@ inline auto sparse_decode(IdxVector const& indptr) {
5559
return result;
5660
}
5761

58-
// TODO(mgovers): replace the below relevant subset here ourselves with the STD equivalent when we have std::ranges.
59-
// boost::counting_iterator does not satisfy all requirements std::*_iterator concepts:
60-
static_assert(!std::random_access_iterator<IdxCount>);
61-
// we have to declare the relevant subset here ourselves.
62-
template <typename T, typename ElementType>
63-
concept iterator_like = requires(T const t) {
64-
{ *t } -> std::convertible_to<std::remove_cvref_t<ElementType> const&>;
65-
};
66-
67-
template <typename T, typename ElementType>
68-
concept random_access_iterator_like =
69-
std::regular<T> && iterator_like<T, ElementType> && std::totally_ordered<T> && requires(T t, Idx n) {
70-
{ t++ } -> std::same_as<T>;
71-
{ t-- } -> std::same_as<T>;
72-
{ ++t } -> std::same_as<T&>;
73-
{ --t } -> std::same_as<T&>;
74-
75-
{ t + n } -> std::same_as<T>;
76-
{ t - n } -> std::same_as<T>;
77-
{ t += n } -> std::same_as<T&>;
78-
{ t -= n } -> std::same_as<T&>;
79-
};
80-
81-
template <typename T, typename ElementType>
82-
concept random_access_iterable_like = requires(T const t) {
83-
{ t.begin() } -> random_access_iterator_like<ElementType>;
84-
{ t.end() } -> random_access_iterator_like<ElementType>;
85-
};
86-
87-
template <typename T>
88-
concept index_range_iterator =
89-
random_access_iterator_like<T, typename T::iterator> && requires(T const t) {
90-
typename T::iterator;
91-
{ *t } -> random_access_iterable_like<Idx>;
92-
};
93-
9462
template <typename T>
9563
concept grouped_index_vector_type = std::default_initializable<T> && requires(T const t, Idx const idx) {
9664
typename T::iterator;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// SPDX-FileCopyrightText: Contributors to the Power Grid Model project <[email protected]>
2+
//
3+
// SPDX-License-Identifier: MPL-2.0
4+
5+
#pragma once
6+
7+
namespace power_grid_model {
8+
// TODO(mgovers): replace the below relevant iterator concepts with the STD equivalent when we have index ranges.
9+
// e.g.: boost::counting_iterator does not satisfy all requirements std::*_iterator concepts:
10+
// we have to declare the relevant subset here ourselves.
11+
12+
template <typename T, typename ElementType>
13+
concept iterator_like = requires(T const t) {
14+
{ *t } -> std::convertible_to<std::remove_cvref_t<ElementType> const&>;
15+
};
16+
17+
template <typename T, typename ElementType>
18+
concept forward_iterator_like = std::regular<T> && iterator_like<T, ElementType> && requires(T t) {
19+
{ t++ } -> std::same_as<T>;
20+
{ ++t } -> std::same_as<T&>;
21+
};
22+
23+
template <typename T, typename ElementType>
24+
concept bidirectional_iterator_like = forward_iterator_like<T, ElementType> && requires(T t) {
25+
{ t-- } -> std::same_as<T>;
26+
{ --t } -> std::same_as<T&>;
27+
};
28+
29+
template <typename T, typename ElementType>
30+
concept random_access_iterator_like =
31+
bidirectional_iterator_like<T, ElementType> && std::totally_ordered<T> && requires(T t, Idx n) {
32+
{ t + n } -> std::same_as<T>;
33+
{ t - n } -> std::same_as<T>;
34+
{ t += n } -> std::same_as<T&>;
35+
{ t -= n } -> std::same_as<T&>;
36+
};
37+
38+
template <typename T, typename ElementType>
39+
concept random_access_iterable_like = requires(T const t) {
40+
{ t.begin() } -> random_access_iterator_like<ElementType>;
41+
{ t.end() } -> random_access_iterator_like<ElementType>;
42+
};
43+
44+
template <typename T>
45+
concept index_range_iterator =
46+
random_access_iterator_like<T, typename T::iterator> && requires(T const t) {
47+
typename T::iterator;
48+
{ *t } -> random_access_iterable_like<Idx>;
49+
};
50+
51+
} // namespace power_grid_model

power_grid_model_c/power_grid_model/include/power_grid_model/main_core/input.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "state_queries.hpp"
99

1010
#include "../all_components.hpp"
11+
#include "../common/iterator_like_concepts.hpp"
1112

1213
#include <unordered_set>
1314

@@ -19,16 +20,20 @@ constexpr std::array<Branch3Side, 3> const branch3_sides = {Branch3Side::side_1,
1920
// template to construct components
2021
// using forward interators
2122
// different selection based on component type
22-
template <std::derived_from<Base> Component, class ComponentContainer, std::forward_iterator ForwardIterator>
23+
template <std::derived_from<Base> Component, class ComponentContainer,
24+
forward_iterator_like<typename Component::InputType> ForwardIterator>
2325
requires model_component_state_c<MainModelState, ComponentContainer, Component>
2426
inline void add_component(MainModelState<ComponentContainer>& state, ForwardIterator begin, ForwardIterator end,
2527
double system_frequency) {
28+
using ComponentView = std::conditional_t<std::same_as<decltype(*begin), typename Component::InputType const&>,
29+
typename Component::InputType const&, typename Component::InputType>;
30+
2631
reserve_component<Component>(state, std::distance(begin, end));
2732
// do sanity check on the transformer tap regulator
2833
std::vector<Idx2D> regulated_objects;
2934
// loop to add component
3035
for (auto it = begin; it != end; ++it) {
31-
auto const& input = *it;
36+
ComponentView const input = *it;
3237
ID const id = input.id;
3338
// construct based on type of component
3439
if constexpr (std::derived_from<Component, Node>) {

power_grid_model_c/power_grid_model/include/power_grid_model/main_core/output.hpp

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ namespace power_grid_model::main_core {
1313

1414
namespace detail {
1515

16+
template <typename T, typename U>
17+
concept assignable_to = std::assignable_from<U, T>;
18+
1619
template <std::same_as<Node> Component, class ComponentContainer>
1720
requires model_component_state_c<MainModelState, ComponentContainer, Component>
1821
constexpr auto comp_base_sequence_cbegin(MainModelState<ComponentContainer> const& state) {
@@ -75,12 +78,11 @@ constexpr auto comp_base_sequence_cbegin(MainModelState<ComponentContainer> cons
7578
return state.comp_topo->regulated_object_idx.cbegin() + get_component_sequence_offset<Regulator, Component>(state);
7679
}
7780

78-
template <typename Component, typename IndexType, class ComponentContainer, std::forward_iterator ResIt,
79-
typename ResFunc>
81+
template <typename Component, typename IndexType, class ComponentContainer, typename ResIt, typename ResFunc>
8082
requires model_component_state_c<MainModelState, ComponentContainer, Component> &&
8183
std::invocable<std::remove_cvref_t<ResFunc>, Component const&, IndexType> &&
82-
std::convertible_to<std::invoke_result_t<ResFunc, Component const&, IndexType>,
83-
std::iter_value_t<ResIt>> &&
84+
assignable_to<std::invoke_result_t<ResFunc, Component const&, IndexType>,
85+
std::add_lvalue_reference_t<std::iter_value_t<ResIt>>> &&
8486
std::convertible_to<IndexType,
8587
decltype(*comp_base_sequence_cbegin<Component>(MainModelState<ComponentContainer>{}))>
8688
constexpr ResIt produce_output(MainModelState<ComponentContainer> const& state, ResIt res_it, ResFunc&& func) {
@@ -359,12 +361,12 @@ output_result(Component const& transformer_tap_regulator, MainModelState<Compone
359361

360362
// output base component
361363
template <std::derived_from<Base> Component, class ComponentContainer, solver_output_type SolverOutputType,
362-
std::forward_iterator ResIt>
364+
typename ResIt>
363365
requires model_component_state_c<MainModelState, ComponentContainer, Component> &&
364366
requires(Component const& component, std::vector<SolverOutputType> const& solver_output, Idx2D math_id) {
365367
{
366368
output_result<Component>(component, solver_output, math_id)
367-
} -> std::convertible_to<std::iter_value_t<ResIt>>;
369+
} -> detail::assignable_to<std::add_lvalue_reference_t<std::iter_value_t<ResIt>>>;
368370
}
369371
constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
370372
MathOutput<std::vector<SolverOutputType>> const& math_output, ResIt res_it) {
@@ -374,13 +376,13 @@ constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
374376
});
375377
}
376378
template <std::derived_from<Base> Component, class ComponentContainer, solver_output_type SolverOutputType,
377-
std::forward_iterator ResIt>
379+
typename ResIt>
378380
requires model_component_state_c<MainModelState, ComponentContainer, Component> &&
379381
requires(Component const& component, MainModelState<ComponentContainer> const& state,
380382
std::vector<SolverOutputType> const& solver_output, Idx2D math_id) {
381383
{
382384
output_result<Component>(component, state, solver_output, math_id)
383-
} -> std::convertible_to<std::iter_value_t<ResIt>>;
385+
} -> detail::assignable_to<std::add_lvalue_reference_t<std::iter_value_t<ResIt>>>;
384386
}
385387
constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
386388
MathOutput<std::vector<SolverOutputType>> const& math_output, ResIt res_it) {
@@ -390,13 +392,13 @@ constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
390392
});
391393
}
392394
template <std::derived_from<Base> Component, class ComponentContainer, solver_output_type SolverOutputType,
393-
std::forward_iterator ResIt>
395+
typename ResIt>
394396
requires model_component_state_c<MainModelState, ComponentContainer, Component> &&
395397
requires(Component const& component, MainModelState<ComponentContainer> const& state,
396398
std::vector<SolverOutputType> const& solver_output, Idx obj_seq) {
397399
{
398400
output_result<Component>(component, state, solver_output, obj_seq)
399-
} -> std::convertible_to<std::iter_value_t<ResIt>>;
401+
} -> detail::assignable_to<std::add_lvalue_reference_t<std::iter_value_t<ResIt>>>;
400402
}
401403
constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
402404
MathOutput<std::vector<SolverOutputType>> const& math_output, ResIt res_it) {
@@ -406,13 +408,13 @@ constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
406408
});
407409
}
408410
template <std::derived_from<Base> Component, class ComponentContainer, solver_output_type SolverOutputType,
409-
std::forward_iterator ResIt>
411+
typename ResIt>
410412
requires model_component_state_c<MainModelState, ComponentContainer, Component> &&
411413
requires(Component const& component, std::vector<SolverOutputType> const& solver_output,
412414
Idx2DBranch3 const& math_id) {
413415
{
414416
output_result<Component>(component, solver_output, math_id)
415-
} -> std::convertible_to<std::iter_value_t<ResIt>>;
417+
} -> detail::assignable_to<std::add_lvalue_reference_t<std::iter_value_t<ResIt>>>;
416418
}
417419
constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
418420
MathOutput<std::vector<SolverOutputType>> const& math_output, ResIt res_it) {
@@ -421,14 +423,13 @@ constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
421423
return output_result<Component>(component, math_output.solver_output, math_id);
422424
});
423425
}
424-
template <std::derived_from<Base> Component, class ComponentContainer, typename SolverOutputType,
425-
std::forward_iterator ResIt>
426+
template <std::derived_from<Base> Component, class ComponentContainer, typename SolverOutputType, typename ResIt>
426427
requires model_component_state_c<MainModelState, ComponentContainer, Component> &&
427428
requires(Component const& component, MainModelState<ComponentContainer> const& state,
428429
MathOutput<SolverOutputType> const& math_output, Idx const obj_seq) {
429430
{
430431
output_result<Component>(component, state, math_output, obj_seq)
431-
} -> std::convertible_to<std::iter_value_t<ResIt>>;
432+
} -> detail::assignable_to<std::add_lvalue_reference_t<std::iter_value_t<ResIt>>>;
432433
}
433434
constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
434435
MathOutput<SolverOutputType> const& math_output, ResIt res_it) {
@@ -440,7 +441,7 @@ constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
440441

441442
// output source, load_gen, shunt individually
442443
template <std::same_as<Appliance> Component, class ComponentContainer, solver_output_type SolverOutputType,
443-
std::forward_iterator ResIt>
444+
typename ResIt>
444445
requires model_component_state_c<MainModelState, ComponentContainer, Component>
445446
constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
446447
MathOutput<std::vector<SolverOutputType>> const& math_output, ResIt res_it) {

0 commit comments

Comments
 (0)