SpECTRE Documentation Coverage Report
Current view: top level - Evolution/Systems/CurvedScalarWave/Worldtube/SingletonActions - ObserveWorldtubeSolution.hpp Hit Total Coverage
Commit: 1f2210958b4f38fdc0400907ee7c6d5af5111418 Lines: 1 6 16.7 %
Date: 2025-12-05 05:03:31
Legend: Lines: hit not hit

          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 "DataStructures/Tensor/EagerMath/Magnitude.hpp"
      14             : #include "Evolution/Systems/CurvedScalarWave/Tags.hpp"
      15             : #include "Evolution/Systems/CurvedScalarWave/Worldtube/Tags.hpp"
      16             : #include "IO/Observer/Helpers.hpp"
      17             : #include "IO/Observer/ObservationId.hpp"
      18             : #include "IO/Observer/ObserverComponent.hpp"
      19             : #include "IO/Observer/ReductionActions.hpp"
      20             : #include "IO/Observer/TypeOfObservation.hpp"
      21             : #include "NumericalAlgorithms/SphericalHarmonics/Tags.hpp"
      22             : #include "Parallel/GlobalCache.hpp"
      23             : #include "Parallel/Reduction.hpp"
      24             : #include "Time/Tags/TimeStepId.hpp"
      25             : #include "Utilities/ConstantExpressions.hpp"
      26             : #include "Utilities/TMPL.hpp"
      27             : #include "Utilities/TaggedTuple.hpp"
      28             : 
      29             : /// \cond
      30             : namespace Tags {
      31             : struct Time;
      32             : }  // namespace Tags
      33             : /// \endcond
      34             : 
      35             : namespace CurvedScalarWave::Worldtube::Actions {
      36             : 
      37             : /*!
      38             :  * \brief When Tags::ObserveCoefficientsTrigger is triggered, write the
      39             :  * coefficients of the Taylor expansion of the regular field as well as the
      40             :  * current particle's position, velocity and acceleration to file. A brief
      41             :  * summary is printed to stdout.
      42             :  */
      43           1 : struct ObserveWorldtubeSolution {
      44           0 :   using reduction_data = Parallel::ReductionData<
      45             :       Parallel::ReductionDatum<double, funcl::AssertEqual<>>,
      46             :       Parallel::ReductionDatum<std::vector<double>, funcl::AssertEqual<>>>;
      47             : 
      48           0 :   using observed_reduction_data_tags =
      49             :       observers::make_reduction_data_tags<tmpl::list<reduction_data>>;
      50           0 :   static constexpr size_t Dim = 3;
      51             :   template <typename DbTagsList, typename... InboxTags, typename Metavariables,
      52             :             typename ArrayIndex, typename ActionList,
      53             :             typename ParallelComponent>
      54           0 :   static Parallel::iterable_action_return_t apply(
      55             :       db::DataBox<DbTagsList>& box,
      56             :       const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
      57             :       Parallel::GlobalCache<Metavariables>& cache,
      58             :       const ArrayIndex& /*array_index*/, const ActionList /*meta*/,
      59             :       const ParallelComponent* const /*meta*/) {
      60             :     if (db::get<Tags::ObserveCoefficientsTrigger>(box).is_triggered(box) and
      61             :         db::get<::Tags::TimeStepId>(box).substep() == 0) {
      62             :       const auto& inertial_particle_position =
      63             :           db::get<Tags::EvolvedPosition<Dim>>(box);
      64             :       const auto& particle_velocity = db::get<Tags::EvolvedVelocity<Dim>>(box);
      65             :       const auto& particle_acceleration =
      66             :           db::get<::Tags::dt<Tags::EvolvedVelocity<Dim>>>(box);
      67             :       const size_t expansion_order = db::get<Tags::ExpansionOrder>(box);
      68             :       const auto& psi_monopole = db::get<
      69             :           Stf::Tags::StfTensor<Tags::PsiWorldtube, 0, Dim, Frame::Inertial>>(
      70             :           box);
      71             :       const auto& dt_psi_monopole =
      72             :           db::get<Stf::Tags::StfTensor<::Tags::dt<Tags::PsiWorldtube>, 0, Dim,
      73             :                                        Frame::Inertial>>(box);
      74             : 
      75             :       // number of components in Taylor series
      76             :       const size_t num_coefs = ((expansion_order + 3) * (expansion_order + 2) *
      77             :                                 (expansion_order + 1)) /
      78             :                                6;
      79             :       // offset everything by the 3 * 3 components for position, velocity and
      80             :       // acceleration
      81             :       const size_t pos_offset = 9;
      82             :       std::vector<double> psi_coefs(2 * num_coefs + pos_offset);
      83             :       for (size_t i = 0; i < 3; ++i) {
      84             :         psi_coefs[i] = inertial_particle_position.get(i)[0];
      85             :         psi_coefs[i + 3] = particle_velocity.get(i)[0];
      86             :         psi_coefs[i + 6] = particle_acceleration.get(i)[0];
      87             :       }
      88             :       psi_coefs[0 + pos_offset] = get(psi_monopole);
      89             :       psi_coefs[num_coefs + pos_offset] = get(dt_psi_monopole);
      90             :       if (expansion_order > 0) {
      91             :         const auto& psi_dipole = db::get<
      92             :             Stf::Tags::StfTensor<Tags::PsiWorldtube, 1, Dim, Frame::Inertial>>(
      93             :             box);
      94             :         const auto& dt_psi_dipole =
      95             :             db::get<Stf::Tags::StfTensor<::Tags::dt<Tags::PsiWorldtube>, 1, Dim,
      96             :                                          Frame::Inertial>>(box);
      97             :         for (size_t i = 0; i < Dim; ++i) {
      98             :           psi_coefs[1 + i + pos_offset] = psi_dipole.get(i);
      99             :           psi_coefs[num_coefs + 1 + i + pos_offset] = dt_psi_dipole.get(i);
     100             :         }
     101             :       }
     102             :       const auto legend = [&expansion_order]() -> std::vector<std::string> {
     103             :         switch (expansion_order) {
     104             :           case (0):
     105             :             return {"Time",           "Position_x",     "Position_y",
     106             :                     "Position_z",     "Velocity_x",     "Velocity_y",
     107             :                     "Velocity_z",     "Acceleration_x", "Acceleration_y",
     108             :                     "Acceleration_z", "Psi0",           "dtPsi0"};
     109             :             break;
     110             :           case (1):
     111             :             return {"Time",           "Position_x",     "Position_y",
     112             :                     "Position_z",     "Velocity_x",     "Velocity_y",
     113             :                     "Velocity_z",     "Acceleration_x", "Acceleration_y",
     114             :                     "Acceleration_z", "Psi0",           "Psix",
     115             :                     "Psiy",           "Psiz",           "dtPsi0",
     116             :                     "dtPsix",         "dtPsiy",         "dtPsiz"};
     117             :             break;
     118             :           default:
     119             :             ERROR("requested invalid expansion order");
     120             :         }
     121             :       }();
     122             :       const auto current_time = db::get<::Tags::Time>(box);
     123             :       if (Parallel::get<Tags::Verbosity>(cache) >= ::Verbosity::Quiet) {
     124             :         Parallel::printf(
     125             :             "Time: %.16f, field value: %.16f, worldtube radius: %.16f, orbital "
     126             :             "radius: %.16f\n",
     127             :             current_time, psi_coefs[9], db::get<Tags::WorldtubeRadius>(box),
     128             :             get(magnitude(inertial_particle_position))[0]);
     129             :       }
     130             : 
     131             :       const auto observation_id =
     132             :           observers::ObservationId(current_time, "/Worldtube");
     133             :       auto& reduction_writer = Parallel::get_parallel_component<
     134             :           observers::ObserverWriter<Metavariables>>(cache);
     135             : 
     136             :       Parallel::threaded_action<
     137             :           observers::ThreadedActions::WriteReductionDataRow>(
     138             :           reduction_writer[0], std::string{"/PsiTaylorCoefs"}, legend,
     139             :           std::make_tuple(current_time, psi_coefs));
     140             :     }
     141             :     return {Parallel::AlgorithmExecution::Continue, std::nullopt};
     142             :   }
     143             : };
     144             : }  // namespace CurvedScalarWave::Worldtube::Actions

Generated by: LCOV version 1.14