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/SelfForce.hpp" 18 : #include "Evolution/Systems/CurvedScalarWave/Worldtube/SingletonActions/ReceiveElementData.hpp" 19 : #include "Evolution/Systems/CurvedScalarWave/Worldtube/Tags.hpp" 20 : #include "NumericalAlgorithms/SphericalHarmonics/Tags.hpp" 21 : #include "Parallel/AlgorithmExecution.hpp" 22 : #include "Parallel/GlobalCache.hpp" 23 : #include "Time/TimeStepId.hpp" 24 : #include "Utilities/ErrorHandling/Assert.hpp" 25 : #include "Utilities/Gsl.hpp" 26 : 27 : namespace CurvedScalarWave::Worldtube::Actions { 28 : /*! 29 : * \brief Computes the next iteration of the acceleration due to scalar self 30 : * force from the current iteration of the regular field. 31 : */ 32 : template <typename Metavariables> 33 1 : struct IterateAccelerationTerms { 34 0 : static constexpr size_t Dim = Metavariables::volume_dim; 35 : 36 : template <typename DbTagsList, typename... InboxTags, typename ArrayIndex, 37 : typename ActionList, typename ParallelComponent> 38 0 : static Parallel::iterable_action_return_t apply( 39 : db::DataBox<DbTagsList>& box, 40 : tuples::TaggedTuple<InboxTags...>& /*inboxes*/, 41 : Parallel::GlobalCache<Metavariables>& cache, 42 : const ArrayIndex& /*array_index*/, const ActionList /*meta*/, 43 : const ParallelComponent* const /*meta*/) { 44 : ASSERT(db::get<Tags::MaxIterations>(box) > 1, 45 : "Internal action error: In Action `IterateAccelerationTerms` but " 46 : "`MaxIterations` is less than 2."); 47 : const size_t data_size = 3; 48 : Scalar<DataVector> data_to_send(data_size); 49 : const auto& geodesic_acc = db::get<Tags::GeodesicAcceleration<Dim>>(box); 50 : const auto& dt_psi_monopole = 51 : db::get<Stf::Tags::StfTensor<::Tags::dt<Tags::PsiWorldtube>, 0, Dim, 52 : Frame::Inertial>>(box); 53 : const auto& psi_dipole = db::get< 54 : Stf::Tags::StfTensor<Tags::PsiWorldtube, 1, Dim, Frame::Inertial>>(box); 55 : const auto& particle_velocity = 56 : db::get<Tags::ParticlePositionVelocity<Dim>>(box).at(1); 57 : const auto& background = get<Tags::BackgroundQuantities<Dim>>(box); 58 : const auto& inverse_metric = 59 : get<gr::Tags::InverseSpacetimeMetric<double, Dim>>(background); 60 : const auto& dilation_factor = get<Tags::TimeDilationFactor>(background); 61 : const auto self_force_acc = self_force_acceleration( 62 : dt_psi_monopole, psi_dipole, particle_velocity, 63 : db::get<Tags::Charge>(box), db::get<Tags::Mass>(box).value(), 64 : inverse_metric, dilation_factor); 65 : for (size_t i = 0; i < Dim; ++i) { 66 : get(data_to_send)[i] = geodesic_acc.get(i) + self_force_acc.get(i); 67 : } 68 : const auto& faces_grid_coords = 69 : get<Tags::ElementFacesGridCoordinates<Dim>>(box); 70 : auto& element_proxies = Parallel::get_parallel_component< 71 : typename Metavariables::dg_element_array>(cache); 72 : for (const auto& [element_id, _] : faces_grid_coords) { 73 : auto data_to_send_copy = data_to_send; 74 : Parallel::receive_data<Tags::SelfForceInbox<Dim>>( 75 : element_proxies[element_id], db::get<::Tags::TimeStepId>(box), 76 : std::move(data_to_send_copy)); 77 : } 78 : return {Parallel::AlgorithmExecution::Continue, 79 : tmpl::index_of<ActionList, ReceiveElementData>::value}; 80 : } 81 : }; 82 : } // namespace CurvedScalarWave::Worldtube::Actions