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/SphericalHarmonics/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