13
13
14
14
#include < map>
15
15
16
- namespace power_grid_model ::main_core {
16
+ namespace power_grid_model ::main_core::update {
17
+
18
+ constexpr Idx invalid_index{-1 };
19
+
20
+ // main core utils
21
+ template <class CompType , class ... ComponentTypes>
22
+ constexpr auto index_of_component = main_core::utils::index_of_component<CompType, ComponentTypes...>;
23
+ template <class ... ComponentTypes> using SequenceIdx = main_core::utils::SequenceIdx<ComponentTypes...>;
24
+ template <class ... ComponentTypes> using ComponentFlags = main_core::utils::ComponentFlags<ComponentTypes...>;
17
25
18
26
namespace detail {
19
27
template <component_c Component, forward_iterator_like<typename Component::UpdateType> ForwardIterator, typename Func>
@@ -31,115 +39,6 @@ inline void iterate_component_sequence(Func&& func, ForwardIterator begin, Forwa
31
39
}
32
40
}
33
41
34
- } // namespace detail
35
-
36
- template <component_c Component, class ComponentContainer ,
37
- forward_iterator_like<typename Component::UpdateType> ForwardIterator,
38
- std::output_iterator<Idx2D> OutputIterator>
39
- requires model_component_state_c<MainModelState, ComponentContainer, Component>
40
- inline void get_component_sequence (MainModelState<ComponentContainer> const & state, ForwardIterator begin,
41
- ForwardIterator end, OutputIterator destination, Idx n_comp_elements) {
42
- using UpdateType = typename Component::UpdateType;
43
-
44
- if (n_comp_elements < 0 ) {
45
- std::ranges::transform (begin, end, destination, [&state](UpdateType const & update) {
46
- return get_component_idx_by_id<Component>(state, update.id );
47
- });
48
- } else {
49
- assert (std::distance (begin, end) <= n_comp_elements);
50
- std::ranges::transform (
51
- begin, end, destination,
52
- [group = get_component_group_idx<Component>(state), index = 0 ](auto const & /* update*/ ) mutable {
53
- return Idx2D{group, index++}; // NOSONAR
54
- });
55
- }
56
- }
57
-
58
- template <component_c Component, class ComponentContainer ,
59
- forward_iterator_like<typename Component::UpdateType> ForwardIterator>
60
- requires model_component_state_c<MainModelState, ComponentContainer, Component>
61
- inline std::vector<Idx2D> get_component_sequence (MainModelState<ComponentContainer> const & state, ForwardIterator begin,
62
- ForwardIterator end, Idx n_comp_elements = na_Idx) {
63
- std::vector<Idx2D> result;
64
- result.reserve (std::distance (begin, end));
65
- get_component_sequence<Component>(state, begin, end, std::back_inserter (result), n_comp_elements);
66
- return result;
67
- }
68
-
69
- // template to update components
70
- // using forward interators
71
- // different selection based on component type
72
- // if sequence_idx is given, it will be used to load the object instead of using IDs via hash map.
73
- template <component_c Component, class ComponentContainer ,
74
- forward_iterator_like<typename Component::UpdateType> ForwardIterator,
75
- std::output_iterator<Idx2D> OutputIterator>
76
- requires model_component_state_c<MainModelState, ComponentContainer, Component>
77
- inline UpdateChange update_component (MainModelState<ComponentContainer>& state, ForwardIterator begin,
78
- ForwardIterator end, OutputIterator changed_it,
79
- std::span<Idx2D const > sequence_idx) {
80
- using UpdateType = typename Component::UpdateType;
81
-
82
- UpdateChange state_changed;
83
-
84
- detail::iterate_component_sequence<Component>(
85
- [&state_changed, &changed_it, &state](UpdateType const & update_data, Idx2D const & sequence_single) {
86
- auto & comp = get_component<Component>(state, sequence_single);
87
- assert (state.components .get_id_by_idx (sequence_single) == comp.id ());
88
- auto const comp_changed = comp.update (update_data);
89
- state_changed = state_changed || comp_changed;
90
-
91
- if (comp_changed.param || comp_changed.topo ) {
92
- *changed_it++ = sequence_single;
93
- }
94
- },
95
- begin, end, sequence_idx);
96
-
97
- return state_changed;
98
- }
99
- template <component_c Component, class ComponentContainer ,
100
- forward_iterator_like<typename Component::UpdateType> ForwardIterator,
101
- std::output_iterator<Idx2D> OutputIterator>
102
- requires model_component_state_c<MainModelState, ComponentContainer, Component>
103
- inline UpdateChange update_component (MainModelState<ComponentContainer>& state, ForwardIterator begin,
104
- ForwardIterator end, OutputIterator changed_it) {
105
- return update_component<Component>(state, begin, end, changed_it,
106
- get_component_sequence<Component>(state, begin, end));
107
- }
108
-
109
- // template to get the inverse update for components
110
- // using forward interators
111
- // different selection based on component type
112
- // if sequence_idx is given, it will be used to load the object instead of using IDs via hash map.
113
- template <component_c Component, class ComponentContainer ,
114
- forward_iterator_like<typename Component::UpdateType> ForwardIterator,
115
- std::output_iterator<typename Component::UpdateType> OutputIterator>
116
- requires model_component_state_c<MainModelState, ComponentContainer, Component>
117
- inline void update_inverse (MainModelState<ComponentContainer> const & state, ForwardIterator begin, ForwardIterator end,
118
- OutputIterator destination, std::span<Idx2D const > sequence_idx) {
119
- using UpdateType = typename Component::UpdateType;
120
-
121
- detail::iterate_component_sequence<Component>(
122
- [&destination, &state](UpdateType const & update_data, Idx2D const & sequence_single) {
123
- auto const & comp = get_component<Component>(state, sequence_single);
124
- *destination++ = comp.inverse (update_data);
125
- },
126
- begin, end, sequence_idx);
127
- }
128
- template <component_c Component, class ComponentContainer ,
129
- forward_iterator_like<typename Component::UpdateType> ForwardIterator,
130
- std::output_iterator<typename Component::UpdateType> OutputIterator>
131
- requires model_component_state_c<MainModelState, ComponentContainer, Component>
132
- inline void update_inverse (MainModelState<ComponentContainer> const & state, ForwardIterator begin, ForwardIterator end,
133
- OutputIterator destination) {
134
- return update_inverse<Component>(state, begin, end, destination,
135
- get_component_sequence<Component>(state, begin, end));
136
- }
137
-
138
- namespace update_independence {
139
- namespace detail {
140
-
141
- constexpr Idx invalid_index{-1 };
142
-
143
42
template <typename T> bool check_id_na (T const & obj) {
144
43
if constexpr (requires { obj.id ; }) {
145
44
return is_nan (obj.id );
@@ -150,6 +49,9 @@ template <typename T> bool check_id_na(T const& obj) {
150
49
}
151
50
}
152
51
52
+ } // namespace detail
53
+
54
+ namespace independence {
153
55
struct UpdateCompProperties {
154
56
std::string name{};
155
57
bool has_any_elements{false }; // whether the component has any elements in the update data
@@ -180,17 +82,19 @@ struct UpdateCompProperties {
180
82
181
83
template <typename CompType> void process_buffer_span (auto const & all_spans, UpdateCompProperties& properties) {
182
84
properties.ids_all_na = std::ranges::all_of (all_spans, [](auto const & vec) {
183
- return std::ranges::all_of (vec, [](auto const & item) { return check_id_na (item); });
85
+ return std::ranges::all_of (vec, [](auto const & item) { return detail:: check_id_na (item); });
184
86
});
185
- properties.ids_part_na =
186
- std::ranges::any_of (all_spans,
187
- [](auto const & vec) {
188
- return std::ranges::any_of (vec, [](auto const & item) { return check_id_na (item); });
189
- }) &&
190
- !properties.ids_all_na ;
87
+ properties.ids_part_na = std::ranges::any_of (all_spans,
88
+ [](auto const & vec) {
89
+ return std::ranges::any_of (vec, [](auto const & item) {
90
+ return detail::check_id_na (item);
91
+ });
92
+ }) &&
93
+ !properties.ids_all_na ;
191
94
192
95
if (all_spans.empty ()) {
193
96
properties.update_ids_match = true ;
97
+ return ;
194
98
} else {
195
99
// Remember the begin iterator of the first scenario, then loop over the remaining scenarios and
196
100
// check the ids
@@ -254,21 +158,65 @@ inline void validate_update_data_independence(UpdateCompProperties const& comp)
254
158
}
255
159
}
256
160
257
- } // namespace detail
161
+ template <class ... ComponentTypes>
162
+ ComponentFlags<ComponentTypes...> is_update_independent (ConstDataset const & update_data,
163
+ std::span<Idx const > relevant_component_count) {
164
+ ComponentFlags<ComponentTypes...> result{};
165
+ size_t comp_idx{};
166
+ utils::run_functor_with_all_types_return_void<ComponentTypes...>(
167
+ [&result, &relevant_component_count, &update_data, &comp_idx]<typename CompType>() {
168
+ Idx const n_component = relevant_component_count[comp_idx];
169
+ result[comp_idx] = check_component_independence<CompType>(update_data, n_component).is_independent ();
170
+ ++comp_idx;
171
+ });
172
+ return result;
173
+ }
258
174
259
- // main core utils
260
- template <class CompType , class ... ComponentTypes>
261
- constexpr auto index_of_component = main_core::utils::index_of_component<CompType, ComponentTypes...>;
262
- template <class ... ComponentTypes> using SequenceIdx = main_core::utils::SequenceIdx<ComponentTypes...>;
263
- template <class ... ComponentTypes> using ComponentFlags = main_core::utils::ComponentFlags<ComponentTypes...>;
175
+ } // namespace independence
176
+
177
+ namespace detail {
178
+
179
+ template <component_c Component, class ComponentContainer ,
180
+ forward_iterator_like<typename Component::UpdateType> ForwardIterator,
181
+ std::output_iterator<Idx2D> OutputIterator>
182
+ requires model_component_state_c<MainModelState, ComponentContainer, Component>
183
+ inline void get_component_sequence_impl (MainModelState<ComponentContainer> const & state, ForwardIterator begin,
184
+ ForwardIterator end, OutputIterator destination, Idx n_comp_elements) {
185
+ using UpdateType = typename Component::UpdateType;
186
+
187
+ if (n_comp_elements < 0 ) {
188
+ std::ranges::transform (begin, end, destination, [&state](UpdateType const & update) {
189
+ return get_component_idx_by_id<Component>(state, update.id );
190
+ });
191
+ } else {
192
+ assert (std::distance (begin, end) <= n_comp_elements);
193
+ std::ranges::transform (
194
+ begin, end, destination,
195
+ [group = get_component_group_idx<Component>(state), index = 0 ](auto const & /* update*/ ) mutable {
196
+ return Idx2D{group, index++}; // NOSONAR
197
+ });
198
+ }
199
+ }
200
+
201
+ template <component_c Component, class ComponentContainer ,
202
+ forward_iterator_like<typename Component::UpdateType> ForwardIterator>
203
+ requires model_component_state_c<MainModelState, ComponentContainer, Component>
204
+ inline std::vector<Idx2D> get_component_sequence_by_it (MainModelState<ComponentContainer> const & state,
205
+ ForwardIterator begin, ForwardIterator end,
206
+ Idx n_comp_elements = na_Idx) {
207
+ std::vector<Idx2D> result;
208
+ result.reserve (std::distance (begin, end));
209
+ get_component_sequence_impl<Component>(state, begin, end, std::back_inserter (result), n_comp_elements);
210
+ return result;
211
+ }
264
212
265
213
// get sequence idx map of a certain batch scenario
266
214
template <typename CompType, class ComponentContainer >
267
215
std::vector<Idx2D> get_component_sequence (MainModelState<ComponentContainer> const & state,
268
216
ConstDataset const & update_data, Idx scenario_idx,
269
- detail ::UpdateCompProperties const & comp_independence = {}) {
217
+ independence ::UpdateCompProperties const & comp_independence = {}) {
270
218
auto const get_sequence = [&state, n_comp_elements = comp_independence.get_n_elements ()](auto const & span) {
271
- return get_component_sequence <CompType>(state, std::begin (span), std::end (span), n_comp_elements);
219
+ return get_component_sequence_by_it <CompType>(state, std::begin (span), std::end (span), n_comp_elements);
272
220
};
273
221
if (update_data.is_columnar (CompType::name)) {
274
222
auto const buffer_span =
@@ -278,6 +226,7 @@ std::vector<Idx2D> get_component_sequence(MainModelState<ComponentContainer> con
278
226
auto const buffer_span = update_data.get_buffer_span <meta_data::update_getter_s, CompType>(scenario_idx);
279
227
return get_sequence (buffer_span);
280
228
}
229
+ } // namespace detail
281
230
282
231
template <class ... ComponentTypes, class ComponentContainer >
283
232
SequenceIdx<ComponentTypes...> get_all_sequence_idx_map (MainModelState<ComponentContainer> const & state,
@@ -289,9 +238,9 @@ SequenceIdx<ComponentTypes...> get_all_sequence_idx_map(MainModelState<Component
289
238
return std::vector<Idx2D>{};
290
239
}
291
240
auto const n_components = state.components .template size <CompType>();
292
- auto const independence = detail ::check_component_independence<CompType>(update_data, n_components);
293
- detail ::validate_update_data_independence (independence);
294
- return get_component_sequence<CompType>(state, update_data, scenario_idx, independence);
241
+ auto const independence = independence ::check_component_independence<CompType>(update_data, n_components);
242
+ independence ::validate_update_data_independence (independence);
243
+ return detail:: get_component_sequence<CompType>(state, update_data, scenario_idx, independence);
295
244
});
296
245
}
297
246
// Get sequence idx map of an entire batch for fast caching of component sequences.
@@ -308,20 +257,73 @@ SequenceIdx<ComponentTypes...> get_all_sequence_idx_map(MainModelState<Component
308
257
return get_all_sequence_idx_map<ComponentTypes...>(state, update_data, 0 , all_true);
309
258
}
310
259
311
- template <class ... ComponentTypes>
312
- ComponentFlags<ComponentTypes...> is_update_independent (ConstDataset const & update_data,
313
- std::span<Idx const > relevant_component_count) {
314
- ComponentFlags<ComponentTypes...> result{};
315
- size_t comp_idx{};
316
- utils::run_functor_with_all_types_return_void<ComponentTypes...>([&result, &relevant_component_count, &update_data,
317
- &comp_idx]<typename CompType>() {
318
- Idx const n_component = relevant_component_count[comp_idx];
319
- result[comp_idx] = detail::check_component_independence<CompType>(update_data, n_component).is_independent ();
320
- ++comp_idx;
321
- });
322
- return result;
260
+ // template to update components
261
+ // using forward interators
262
+ // different selection based on component type
263
+ // if sequence_idx is given, it will be used to load the object instead of using IDs via hash map.
264
+ template <component_c Component, class ComponentContainer ,
265
+ forward_iterator_like<typename Component::UpdateType> ForwardIterator,
266
+ std::output_iterator<Idx2D> OutputIterator>
267
+ requires model_component_state_c<MainModelState, ComponentContainer, Component>
268
+ inline UpdateChange update_component (MainModelState<ComponentContainer>& state, ForwardIterator begin,
269
+ ForwardIterator end, OutputIterator changed_it,
270
+ std::span<Idx2D const > sequence_idx) {
271
+ using UpdateType = typename Component::UpdateType;
272
+
273
+ UpdateChange state_changed;
274
+
275
+ detail::iterate_component_sequence<Component>(
276
+ [&state_changed, &changed_it, &state](UpdateType const & update_data, Idx2D const & sequence_single) {
277
+ auto & comp = get_component<Component>(state, sequence_single);
278
+ assert (state.components .get_id_by_idx (sequence_single) == comp.id ());
279
+ auto const comp_changed = comp.update (update_data);
280
+ state_changed = state_changed || comp_changed;
281
+
282
+ if (comp_changed.param || comp_changed.topo ) {
283
+ *changed_it++ = sequence_single;
284
+ }
285
+ },
286
+ begin, end, sequence_idx);
287
+
288
+ return state_changed;
289
+ }
290
+ template <component_c Component, class ComponentContainer ,
291
+ forward_iterator_like<typename Component::UpdateType> ForwardIterator,
292
+ std::output_iterator<Idx2D> OutputIterator>
293
+ requires model_component_state_c<MainModelState, ComponentContainer, Component>
294
+ inline UpdateChange update_component (MainModelState<ComponentContainer>& state, ForwardIterator begin,
295
+ ForwardIterator end, OutputIterator changed_it) {
296
+ return update_component<Component>(state, begin, end, changed_it,
297
+ detail::get_component_sequence_by_it<Component>(state, begin, end));
323
298
}
324
299
325
- } // namespace update_independence
300
+ // template to get the inverse update for components
301
+ // using forward interators
302
+ // different selection based on component type
303
+ // if sequence_idx is given, it will be used to load the object instead of using IDs via hash map.
304
+ template <component_c Component, class ComponentContainer ,
305
+ forward_iterator_like<typename Component::UpdateType> ForwardIterator,
306
+ std::output_iterator<typename Component::UpdateType> OutputIterator>
307
+ requires model_component_state_c<MainModelState, ComponentContainer, Component>
308
+ inline void update_inverse (MainModelState<ComponentContainer> const & state, ForwardIterator begin, ForwardIterator end,
309
+ OutputIterator destination, std::span<Idx2D const > sequence_idx) {
310
+ using UpdateType = typename Component::UpdateType;
311
+
312
+ detail::iterate_component_sequence<Component>(
313
+ [&destination, &state](UpdateType const & update_data, Idx2D const & sequence_single) {
314
+ auto const & comp = get_component<Component>(state, sequence_single);
315
+ *destination++ = comp.inverse (update_data);
316
+ },
317
+ begin, end, sequence_idx);
318
+ }
319
+ template <component_c Component, class ComponentContainer ,
320
+ forward_iterator_like<typename Component::UpdateType> ForwardIterator,
321
+ std::output_iterator<typename Component::UpdateType> OutputIterator>
322
+ requires model_component_state_c<MainModelState, ComponentContainer, Component>
323
+ inline void update_inverse (MainModelState<ComponentContainer> const & state, ForwardIterator begin, ForwardIterator end,
324
+ OutputIterator destination) {
325
+ return update_inverse<Component>(state, begin, end, destination,
326
+ detail::get_component_sequence_by_it<Component>(state, begin, end));
327
+ }
326
328
327
- } // namespace power_grid_model::main_core
329
+ } // namespace power_grid_model::main_core::update
0 commit comments