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 <unordered_map>
10 :
11 : #include "DataStructures/DataBox/DataBox.hpp"
12 : #include "DataStructures/DataBox/Prefixes.hpp"
13 : #include "DataStructures/Variables.hpp"
14 : #include "Domain/Structure/ElementId.hpp"
15 : #include "Domain/Tags.hpp"
16 : #include "Evolution/Systems/CurvedScalarWave/Worldtube/Inboxes.hpp"
17 : #include "Evolution/Systems/CurvedScalarWave/Worldtube/Tags.hpp"
18 : #include "NumericalAlgorithms/Strahlkorper/Tags.hpp"
19 : #include "Parallel/AlgorithmExecution.hpp"
20 : #include "Parallel/GlobalCache.hpp"
21 : #include "ParallelAlgorithms/Initialization/MutateAssign.hpp"
22 : #include "Time/TimeStepId.hpp"
23 : #include "Utilities/ErrorHandling/Assert.hpp"
24 : #include "Utilities/Gsl.hpp"
25 : #include "Utilities/TMPL.hpp"
26 :
27 : /// \cond
28 : namespace Tags {
29 : struct TimeStepId;
30 : } // namespace Tags
31 : /// \endcond
32 :
33 : namespace CurvedScalarWave::Worldtube::Actions {
34 : /*!
35 : * \brief Sends the regular field coefficients to each element abutting the
36 : * worldtube.
37 : */
38 : template <typename Metavariables>
39 1 : struct SendToElements {
40 0 : static constexpr size_t Dim = Metavariables::volume_dim;
41 0 : using psi_tag = CurvedScalarWave::Tags::Psi;
42 0 : using dt_psi_tag = ::Tags::dt<CurvedScalarWave::Tags::Psi>;
43 0 : using tags_to_send = tmpl::list<psi_tag, dt_psi_tag>;
44 :
45 : template <typename DbTagsList, typename... InboxTags, typename ArrayIndex,
46 : typename ActionList, typename ParallelComponent>
47 0 : static Parallel::iterable_action_return_t apply(
48 : db::DataBox<DbTagsList>& box,
49 : tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
50 : Parallel::GlobalCache<Metavariables>& cache,
51 : const ArrayIndex& /*array_index*/, const ActionList /*meta*/,
52 : const ParallelComponent* const /*meta*/) {
53 : const size_t order = db::get<Tags::ExpansionOrder>(box);
54 : auto& element_proxies = Parallel::get_parallel_component<
55 : typename Metavariables::dg_element_array>(cache);
56 : const auto& faces_grid_coords =
57 : get<Tags::ElementFacesGridCoordinates<Dim>>(box);
58 : const auto& psi_l0 =
59 : get<Stf::Tags::StfTensor<Tags::PsiWorldtube, 0, Dim, Frame::Inertial>>(
60 : box);
61 : const auto& dt_psi_l0 =
62 : get<Stf::Tags::StfTensor<::Tags::dt<Tags::PsiWorldtube>, 0, Dim,
63 : Frame::Inertial>>(box);
64 : const auto& psi_l1 =
65 : get<Stf::Tags::StfTensor<Tags::PsiWorldtube, 1, Dim, Frame::Inertial>>(
66 : box);
67 : const auto& dt_psi_l1 =
68 : get<Stf::Tags::StfTensor<::Tags::dt<Tags::PsiWorldtube>, 1, Dim,
69 : Frame::Inertial>>(box);
70 : const size_t num_coefs = order == 0 ? 1 : 4;
71 : Variables<tags_to_send> vars_to_send(num_coefs);
72 : get(get<psi_tag>(vars_to_send))[0] = get(psi_l0);
73 : get(get<dt_psi_tag>(vars_to_send))[0] = get(dt_psi_l0);
74 : if (order > 0) {
75 : for (size_t i = 0; i < Dim; ++i) {
76 : get(get<psi_tag>(vars_to_send))[i + 1] = psi_l1.get(i);
77 : get(get<dt_psi_tag>(vars_to_send))[i + 1] = dt_psi_l1.get(i);
78 : }
79 : }
80 : for (const auto& [element_id, _] : faces_grid_coords) {
81 : auto vars_to_send_copy = vars_to_send;
82 : Parallel::receive_data<Tags::RegularFieldInbox<Dim>>(
83 : element_proxies[element_id], db::get<::Tags::TimeStepId>(box),
84 : std::move(vars_to_send_copy));
85 : }
86 : return {Parallel::AlgorithmExecution::Continue, std::nullopt};
87 : }
88 : };
89 : } // namespace CurvedScalarWave::Worldtube::Actions
|