Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <optional>
7 : #include <tuple>
8 :
9 : #include "DataStructures/DataBox/DataBox.hpp"
10 : #include "DataStructures/Variables.hpp"
11 : #include "Evolution/Systems/Cce/ReceiveTags.hpp"
12 : #include "Parallel/AlgorithmExecution.hpp"
13 : #include "Parallel/GlobalCache.hpp"
14 : #include "Parallel/Invoke.hpp"
15 : #include "Time/TimeStepId.hpp"
16 : #include "Utilities/Gsl.hpp"
17 : #include "Utilities/TMPL.hpp"
18 :
19 : /// \cond
20 : namespace Tags {
21 : struct TimeStepId;
22 : } // namespace Tags
23 : /// \endcond
24 :
25 : namespace Cce {
26 : namespace Actions {
27 :
28 : /*!
29 : * \ingroup ActionsGroup
30 : * \brief Takes the boundary data needed to perform the CCE linear solves as
31 : * arguments and puts them in the \ref DataBoxGroup, updating the
32 : * `Cce::Tags::BoundaryTime` accordingly.
33 : *
34 : * \details The boundary data is computed by a separate component, and packaged
35 : * into a `Variables<TagList>` which is sent in the argument
36 : * of the simple action invocation. The `TimeStepId` is also provided to confirm
37 : * the time associated with the passed boundary data.
38 : *
39 : * \ref DataBoxGroup changes:
40 : * - Adds: nothing
41 : * - Removes: nothing
42 : * - Modifies:
43 : * - All tags in `TagList`
44 : */
45 : template <typename Metavariables, typename TagList>
46 1 : struct ReceiveWorldtubeData {
47 0 : using inbox_tags = tmpl::list<Cce::ReceiveTags::BoundaryData<TagList>>;
48 :
49 : template <typename DbTags, typename... InboxTags, typename ArrayIndex,
50 : typename ActionList, typename ParallelComponent>
51 0 : static Parallel::iterable_action_return_t apply(
52 : db::DataBox<DbTags>& box, tuples::TaggedTuple<InboxTags...>& inboxes,
53 : const Parallel::GlobalCache<Metavariables>& /*cache*/,
54 : const ArrayIndex& /*array_index*/, const ActionList /*meta*/,
55 : const ParallelComponent* const /*meta*/) {
56 : auto& inbox = tuples::get<Cce::ReceiveTags::BoundaryData<TagList>>(inboxes);
57 : if (inbox.count(db::get<::Tags::TimeStepId>(box)) != 1) {
58 : return {Parallel::AlgorithmExecution::Pause,
59 : tmpl::index_of<ActionList, ReceiveWorldtubeData>::value};
60 : }
61 :
62 : tmpl::for_each<TagList>(
63 : [&inbox, &box](auto tag_v) {
64 : using tag = typename decltype(tag_v)::type;
65 : db::mutate<tag>(
66 : [&inbox](const gsl::not_null<typename tag::type*> destination,
67 : const TimeStepId& time) {
68 : *destination = get<tag>(inbox[time]);
69 : },
70 : make_not_null(&box), db::get<::Tags::TimeStepId>(box));
71 : });
72 : inbox.erase(db::get<::Tags::TimeStepId>(box));
73 : return {Parallel::AlgorithmExecution::Continue,
74 : tmpl::index_of<ActionList, ReceiveWorldtubeData>::value + 1};
75 : }
76 : };
77 : } // namespace Actions
78 : } // namespace Cce
|