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 <vector>
9 :
10 : #include "DataStructures/DataBox/Tag.hpp"
11 : #include "DataStructures/DataVector.hpp"
12 : #include "DataStructures/Tensor/Slice.hpp"
13 : #include "DataStructures/Variables.hpp"
14 : #include "Evolution/Systems/CurvedScalarWave/Tags.hpp"
15 : #include "Evolution/Systems/CurvedScalarWave/Worldtube/ElementActions/SendToWorldtube.hpp"
16 : #include "Evolution/Systems/CurvedScalarWave/Worldtube/Inboxes.hpp"
17 : #include "Evolution/Systems/CurvedScalarWave/Worldtube/PunctureField.hpp"
18 : #include "Evolution/Systems/CurvedScalarWave/Worldtube/Tags.hpp"
19 : #include "Parallel/AlgorithmExecution.hpp"
20 : #include "Parallel/GlobalCache.hpp"
21 : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
22 : #include "Utilities/ErrorHandling/Assert.hpp"
23 : #include "Utilities/Gsl.hpp"
24 :
25 : namespace CurvedScalarWave::Worldtube::Actions {
26 : /*!
27 : * \brief Computes an updated iteration of the puncture field given the current
28 : * acceleration of the charge sent by the worldtube singleton.
29 : */
30 1 : struct IteratePunctureField {
31 0 : static constexpr size_t Dim = 3;
32 :
33 0 : using inbox_tags = tmpl::list<Tags::SelfForceInbox<Dim>>;
34 0 : using simple_tags = tmpl::list<Tags::IteratedPunctureField<Dim>>;
35 :
36 : template <typename DbTagsList, typename... InboxTags, typename Metavariables,
37 : typename ArrayIndex, typename ActionList,
38 : typename ParallelComponent>
39 0 : static Parallel::iterable_action_return_t apply(
40 : db::DataBox<DbTagsList>& box, tuples::TaggedTuple<InboxTags...>& inboxes,
41 : Parallel::GlobalCache<Metavariables>& /*cache*/,
42 : const ArrayIndex& /*array_index*/, const ActionList /*meta*/,
43 : const ParallelComponent* const /*meta*/) {
44 : const auto& centered_face_coordinates =
45 : db::get<Tags::FaceCoordinates<Dim, Frame::Inertial, true>>(box);
46 : if (not centered_face_coordinates.has_value()) {
47 : return {Parallel::AlgorithmExecution::Continue, std::nullopt};
48 : }
49 : const auto& time_step_id = db::get<::Tags::TimeStepId>(box);
50 : auto& inbox = get<Tags::SelfForceInbox<Dim>>(inboxes);
51 : if (not inbox.count(time_step_id)) {
52 : return {Parallel::AlgorithmExecution::Retry, std::nullopt};
53 : }
54 : db::mutate<Tags::IteratedPunctureField<Dim>>(
55 : [&self_force_data = get(inbox.at(time_step_id)),
56 : &position_velocity = db::get<Tags::ParticlePositionVelocity<Dim>>(box),
57 : ¢ered_face_coordinates, charge = db::get<Tags::Charge>(box),
58 : &puncture_field = db::get<Tags::PunctureFieldConfig>(box)](
59 : const auto iterated_puncture_field) {
60 : tnsr::I<double, Dim> iterated_acceleration{
61 : {self_force_data[0], self_force_data[1], self_force_data[2]}};
62 : const size_t face_size =
63 : get<0>(centered_face_coordinates.value()).size();
64 :
65 : if (not iterated_puncture_field->has_value()) {
66 : iterated_puncture_field->emplace(face_size);
67 : }
68 :
69 : puncture_field.apply_puncture(
70 : make_not_null(&iterated_puncture_field->value()),
71 : centered_face_coordinates.value(), position_velocity[0],
72 : position_velocity[1], iterated_acceleration);
73 : Variables<tmpl::list<CurvedScalarWave::Tags::Psi,
74 : ::Tags::dt<CurvedScalarWave::Tags::Psi>,
75 : ::Tags::deriv<CurvedScalarWave::Tags::Psi,
76 : tmpl::size_t<3>, Frame::Inertial>>>
77 : acceleration_terms(face_size);
78 : puncture_field.apply_acceleration_terms(
79 : make_not_null(&acceleration_terms),
80 : centered_face_coordinates.value(), position_velocity[0],
81 : position_velocity[1], iterated_acceleration, self_force_data[3],
82 : self_force_data[4], self_force_data[5], self_force_data[6],
83 : self_force_data[7], self_force_data[8], self_force_data[9],
84 : self_force_data[10], self_force_data[11], self_force_data[12],
85 : self_force_data[13], self_force_data[14]);
86 : iterated_puncture_field->value() += acceleration_terms;
87 : iterated_puncture_field->value() *= charge;
88 : },
89 : make_not_null(&box));
90 : inbox.erase(time_step_id);
91 : return {Parallel::AlgorithmExecution::Continue,
92 : tmpl::index_of<ActionList, SendToWorldtube>::value};
93 : }
94 : };
95 : } // namespace CurvedScalarWave::Worldtube::Actions
|