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 <string> 8 : #include <tuple> 9 : 10 : #include "DataStructures/DataBox/DataBox.hpp" 11 : #include "DataStructures/DataBox/Prefixes.hpp" 12 : #include "DataStructures/DataVector.hpp" 13 : #include "Evolution/Systems/CurvedScalarWave/Tags.hpp" 14 : #include "Evolution/Systems/CurvedScalarWave/Worldtube/Tags.hpp" 15 : #include "IO/Observer/Helpers.hpp" 16 : #include "IO/Observer/ObservationId.hpp" 17 : #include "IO/Observer/ObserverComponent.hpp" 18 : #include "IO/Observer/ReductionActions.hpp" 19 : #include "IO/Observer/TypeOfObservation.hpp" 20 : #include "NumericalAlgorithms/SphericalHarmonics/Tags.hpp" 21 : #include "Parallel/GlobalCache.hpp" 22 : #include "Parallel/Reduction.hpp" 23 : #include "Utilities/ConstantExpressions.hpp" 24 : #include "Utilities/TMPL.hpp" 25 : #include "Utilities/TaggedTuple.hpp" 26 : 27 : /// \cond 28 : namespace Tags { 29 : struct Time; 30 : } // namespace Tags 31 : /// \endcond 32 : 33 : namespace CurvedScalarWave::Worldtube::Actions { 34 : 35 : /*! 36 : * \brief When Tags::ObserveCoefficientsTrigger is triggered, write the 37 : * coefficients of the Taylor expansion of the regular field to file. 38 : */ 39 1 : struct ObserveWorldtubeSolution { 40 0 : using reduction_data = Parallel::ReductionData< 41 : Parallel::ReductionDatum<double, funcl::AssertEqual<>>, 42 : Parallel::ReductionDatum<std::vector<double>, funcl::AssertEqual<>>>; 43 : 44 0 : using observed_reduction_data_tags = 45 : observers::make_reduction_data_tags<tmpl::list<reduction_data>>; 46 0 : static constexpr size_t Dim = 3; 47 : template <typename DbTagsList, typename... InboxTags, typename Metavariables, 48 : typename ArrayIndex, typename ActionList, 49 : typename ParallelComponent> 50 0 : static Parallel::iterable_action_return_t apply( 51 : db::DataBox<DbTagsList>& box, 52 : const tuples::TaggedTuple<InboxTags...>& /*inboxes*/, 53 : Parallel::GlobalCache<Metavariables>& cache, 54 : const ArrayIndex& /*array_index*/, const ActionList /*meta*/, 55 : const ParallelComponent* const /*meta*/) { 56 : if (db::get<Tags::ObserveCoefficientsTrigger>(box).is_triggered(box)) { 57 : const size_t expansion_order = db::get<Tags::ExpansionOrder>(box); 58 : const auto& psi_monopole = db::get< 59 : Stf::Tags::StfTensor<Tags::PsiWorldtube, 0, Dim, Frame::Inertial>>( 60 : box); 61 : const auto& dt_psi_monopole = 62 : db::get<Stf::Tags::StfTensor<::Tags::dt<Tags::PsiWorldtube>, 0, Dim, 63 : Frame::Inertial>>(box); 64 : 65 : // number of components in Taylor series 66 : const size_t num_coefs = ((expansion_order + 3) * (expansion_order + 2) * 67 : (expansion_order + 1)) / 68 : 6; 69 : std::vector<double> psi_coefs(2 * num_coefs); 70 : psi_coefs[0] = get(psi_monopole); 71 : psi_coefs[num_coefs] = get(dt_psi_monopole); 72 : 73 : if (expansion_order > 0) { 74 : const auto& psi_dipole = db::get< 75 : Stf::Tags::StfTensor<Tags::PsiWorldtube, 1, Dim, Frame::Inertial>>( 76 : box); 77 : const auto& dt_psi_dipole = 78 : db::get<Stf::Tags::StfTensor<::Tags::dt<Tags::PsiWorldtube>, 1, Dim, 79 : Frame::Inertial>>(box); 80 : for (size_t i = 0; i < Dim; ++i) { 81 : psi_coefs[1 + i] = psi_dipole.get(i); 82 : psi_coefs[num_coefs + 1 + i] = dt_psi_dipole.get(i); 83 : } 84 : } 85 : const auto legend = [&expansion_order]() -> std::vector<std::string> { 86 : switch (expansion_order) { 87 : case (0): 88 : return {"Time", "Psi0", "dtPsi0"}; 89 : break; 90 : case (1): 91 : return {"Time", "Psi0", "Psix", "Psiy", "Psiz", 92 : "dtPsi0", "dtPsix", "dtPsiy", "dtPsiz"}; 93 : break; 94 : default: 95 : ERROR("requested invalid expansion order"); 96 : } 97 : }(); 98 : const auto current_time = db::get<::Tags::Time>(box); 99 : const auto observation_id = 100 : observers::ObservationId(current_time, "/Worldtube"); 101 : auto& reduction_writer = Parallel::get_parallel_component< 102 : observers::ObserverWriter<Metavariables>>(cache); 103 : 104 : Parallel::threaded_action< 105 : observers::ThreadedActions::WriteReductionDataRow>( 106 : reduction_writer[0], std::string{"/PsiTaylorCoefs"}, legend, 107 : std::make_tuple(current_time, psi_coefs)); 108 : } 109 : return {Parallel::AlgorithmExecution::Continue, std::nullopt}; 110 : } 111 : }; 112 : } // namespace CurvedScalarWave::Worldtube::Actions