Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstddef>
7 : #include <optional>
8 : #include <tuple>
9 : #include <type_traits>
10 :
11 : #include "DataStructures/DataBox/DataBox.hpp"
12 : #include "Parallel/AlgorithmExecution.hpp"
13 : #include "Utilities/TMPL.hpp"
14 : #include "Utilities/TaggedTuple.hpp"
15 :
16 : /// \cond
17 : namespace Parallel {
18 : template <typename Metavariables>
19 : class GlobalCache;
20 : } // namespace Parallel
21 : namespace db {
22 : template <typename TagsList>
23 : class DataBox;
24 : } // namespace db
25 : /// \endcond
26 :
27 : namespace Actions {
28 : /// \ingroup ActionsGroup
29 : /// Labels a location in the action list that can be jumped to using Goto.
30 : ///
31 : /// Uses:
32 : /// - GlobalCache: nothing
33 : /// - DataBox: nothing
34 : ///
35 : /// DataBox changes:
36 : /// - Adds: nothing
37 : /// - Removes: nothing
38 : /// - Modifies: nothing
39 : template <typename Tag>
40 1 : struct Label {
41 : template <typename DbTags, typename... InboxTags, typename Metavariables,
42 : typename ArrayIndex, typename ActionList,
43 : typename ParallelComponent>
44 0 : static Parallel::iterable_action_return_t apply(
45 : db::DataBox<DbTags>& /*box*/,
46 : const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
47 : const Parallel::GlobalCache<Metavariables>& /*cache*/,
48 : const ArrayIndex& /*array_index*/, const ActionList /*meta*/,
49 : const ParallelComponent* const /*meta*/) {
50 : static_assert(
51 : tmpl::count_if<ActionList,
52 : std::is_same<tmpl::_1, tmpl::pin<Label<Tag>>>>::value ==
53 : 1,
54 : "Duplicate label");
55 : return {Parallel::AlgorithmExecution::Continue, std::nullopt};
56 : }
57 : };
58 :
59 : /// \ingroup ActionsGroup
60 : /// Jumps to a Label.
61 : ///
62 : /// Uses:
63 : /// - GlobalCache: nothing
64 : /// - DataBox: nothing
65 : ///
66 : /// DataBox changes:
67 : /// - Adds: nothing
68 : /// - Removes: nothing
69 : /// - Modifies: nothing
70 : template <typename Tag>
71 1 : struct Goto {
72 : template <typename DbTags, typename... InboxTags, typename Metavariables,
73 : typename ArrayIndex, typename ActionList,
74 : typename ParallelComponent>
75 0 : static Parallel::iterable_action_return_t apply(
76 : db::DataBox<DbTags>& /*box*/,
77 : const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
78 : const Parallel::GlobalCache<Metavariables>& /*cache*/,
79 : const ArrayIndex& /*array_index*/, const ActionList /*meta*/,
80 : const ParallelComponent* const /*meta*/) {
81 : constexpr size_t index =
82 : tmpl::index_of<ActionList, Actions::Label<Tag>>::value;
83 : return {Parallel::AlgorithmExecution::Continue, index};
84 : }
85 : };
86 :
87 : namespace Goto_detail {
88 :
89 : template <typename ConditionTag>
90 : struct RepeatEnd;
91 :
92 : template <typename ConditionTag>
93 : struct RepeatStart {
94 : template <typename DbTagsList, typename... InboxTags, typename Metavariables,
95 : typename ArrayIndex, typename ActionList,
96 : typename ParallelComponent>
97 : static Parallel::iterable_action_return_t apply(
98 : db::DataBox<DbTagsList>& box,
99 : tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
100 : const Parallel::GlobalCache<Metavariables>& /*cache*/,
101 : const ArrayIndex& /*array_index*/, const ActionList /*meta*/,
102 : const ParallelComponent* const /*meta*/) {
103 : return {Parallel::AlgorithmExecution::Continue,
104 : db::get<ConditionTag>(box)
105 : ? tmpl::index_of<ActionList, RepeatEnd<ConditionTag>>::value + 1
106 : : tmpl::index_of<ActionList, RepeatStart>::value + 1};
107 : }
108 : };
109 :
110 : template <typename ConditionTag>
111 : struct RepeatEnd {
112 : template <typename DbTagsList, typename... InboxTags, typename Metavariables,
113 : typename ArrayIndex, typename ActionList,
114 : typename ParallelComponent>
115 : static Parallel::iterable_action_return_t apply(
116 : db::DataBox<DbTagsList>& box,
117 : tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
118 : const Parallel::GlobalCache<Metavariables>& /*cache*/,
119 : const ArrayIndex& /*array_index*/, const ActionList /*meta*/,
120 : const ParallelComponent* const /*meta*/) {
121 : return {
122 : Parallel::AlgorithmExecution::Continue,
123 : db::get<ConditionTag>(box)
124 : ? tmpl::index_of<ActionList, RepeatEnd>::value + 1
125 : : tmpl::index_of<ActionList, RepeatStart<ConditionTag>>::value + 1};
126 : }
127 : };
128 :
129 : } // namespace Goto_detail
130 :
131 : /// Repeats the `ActionList` until `ConditionTag` is `True`.
132 : template <typename ConditionTag, typename ActionList>
133 1 : using RepeatUntil =
134 : tmpl::flatten<tmpl::list<Goto_detail::RepeatStart<ConditionTag>, ActionList,
135 : Goto_detail::RepeatEnd<ConditionTag>>>;
136 : } // namespace Actions
|