SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/Events - Tags.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 24.5 % 49 12
Test Date: 2026-10-22 17:29:42
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 <optional>
       8              : #include <string>
       9              : 
      10              : #include "DataStructures/DataBox/Tag.hpp"
      11              : #include "DataStructures/DataVector.hpp"
      12              : #include "DataStructures/Tensor/Tensor.hpp"
      13              : #include "Domain/Tags.hpp"
      14              : #include "Domain/TagsTimeDependent.hpp"
      15              : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
      16              : #include "Utilities/GetOutput.hpp"
      17              : #include "Utilities/Gsl.hpp"
      18              : #include "Utilities/TMPL.hpp"
      19              : 
      20            0 : namespace Events::Tags {
      21              : /// \brief The mesh for the observation computational grid. For hybrid methods
      22              : /// like DG-FD the observer mesh changes throughout the evolution.
      23              : template <size_t Dim>
      24            1 : struct ObserverMesh : db::SimpleTag {
      25            0 :   using type = ::Mesh<Dim>;
      26              : };
      27              : 
      28              : /// \brief Sets the `ObserverMesh` to `domain::Tags::Mesh`
      29              : ///
      30              : /// This is what you would use for a single numerical method simulation. Hybrid
      31              : /// methods will supply their own tags.
      32              : template <size_t Dim>
      33            1 : struct ObserverMeshCompute : ObserverMesh<Dim>, db::ComputeTag {
      34            0 :   using base = ObserverMesh<Dim>;
      35            0 :   using return_type = typename base::type;
      36            0 :   using argument_tags = tmpl::list<::domain::Tags::Mesh<Dim>>;
      37            0 :   static void function(const gsl::not_null<return_type*> observer_mesh,
      38              :                        const ::Mesh<Dim>& mesh) {
      39              :     *observer_mesh = mesh;
      40              :   }
      41              : };
      42              : 
      43              : /*!
      44              :  * \brief The coordinates used for observation.
      45              :  *
      46              :  * In methods like DG-FD the mesh and coordinates change throughout the
      47              :  * simulation, so we need to always grab the right ones.
      48              :  */
      49              : template <size_t Dim, typename Fr>
      50            1 : struct ObserverCoordinates : db::SimpleTag {
      51            0 :   static std::string name() { return get_output(Fr{}) + "Coordinates"; }
      52            0 :   using type = tnsr::I<DataVector, Dim, Fr>;
      53              : };
      54              : 
      55              : /// \brief Sets the `ObserverCoordinates` to `domain::Tags::Coordinates`
      56              : ///
      57              : /// This is what you would use for a single numerical method simulation. Hybrid
      58              : /// methods will supply their own tags.
      59              : template <size_t Dim, typename Fr>
      60            1 : struct ObserverCoordinatesCompute : ObserverCoordinates<Dim, Fr>,
      61              :                                     db::ComputeTag {
      62            0 :   using base = ObserverCoordinates<Dim, Fr>;
      63            0 :   using return_type = typename base::type;
      64            0 :   using argument_tags = tmpl::list<::domain::Tags::Coordinates<Dim, Fr>>;
      65            0 :   static void function(const gsl::not_null<return_type*> observer_coords,
      66              :                        const return_type& coords) {
      67              :     for (size_t i = 0; i < Dim; ++i) {
      68              :       observer_coords->get(i).set_data_ref(
      69              :           // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
      70              :           make_not_null(&const_cast<DataVector&>(coords.get(i))));
      71              :     }
      72              :   }
      73              : };
      74              : 
      75              : /*!
      76              :  * \brief The inverse Jacobian used for observation.
      77              :  *
      78              :  * In methods like DG-FD the mesh and inverse Jacobian change throughout the
      79              :  * simulation, so we need to always grab the right ones.
      80              :  */
      81              : template <size_t Dim, typename SourceFrame, typename TargetFrame>
      82            1 : struct ObserverInverseJacobian : db::SimpleTag {
      83            0 :   static std::string name() {
      84              :     return "InverseJacobian(" + get_output(SourceFrame{}) + "," +
      85              :            get_output(TargetFrame{}) + ")";
      86              :   }
      87            0 :   using type = ::InverseJacobian<DataVector, Dim, SourceFrame, TargetFrame>;
      88              : };
      89              : 
      90              : /// \brief Sets the `ObserverInverseJacobian` to `domain::Tags::InverseJacobian`
      91              : ///
      92              : /// This is what you would use for a single numerical method simulation. Hybrid
      93              : /// methods will supply their own tags.
      94              : template <size_t Dim, typename SourceFrame, typename TargetFrame>
      95            1 : struct ObserverInverseJacobianCompute
      96              :     : ObserverInverseJacobian<Dim, SourceFrame, TargetFrame>,
      97              :       db::ComputeTag {
      98            0 :   using base = ObserverInverseJacobian<Dim, SourceFrame, TargetFrame>;
      99            0 :   using return_type = typename base::type;
     100            0 :   using argument_tags = tmpl::list<
     101              :       ::domain::Tags::InverseJacobian<Dim, SourceFrame, TargetFrame>>;
     102            0 :   static void function(
     103              :       const gsl::not_null<return_type*> observer_inverse_jacobian,
     104              :       const return_type& inverse_jacobian) {
     105              :     for (size_t i = 0; i < inverse_jacobian.size(); ++i) {
     106              :       (*observer_inverse_jacobian)[i].set_data_ref(
     107              :           // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
     108              :           make_not_null(&const_cast<DataVector&>(inverse_jacobian[i])));
     109              :     }
     110              :   }
     111              : };
     112              : 
     113              : /*!
     114              :  * \brief The Jacobian used for observation.
     115              :  *
     116              :  * In methods like DG-FD the mesh and  Jacobian change throughout the
     117              :  * simulation, so we need to always grab the right ones.
     118              :  */
     119              : template <size_t Dim, typename SourceFrame, typename TargetFrame>
     120            1 : struct ObserverJacobian : db::SimpleTag {
     121            0 :   static std::string name() {
     122              :     return "Jacobian(" + get_output(SourceFrame{}) + "," +
     123              :            get_output(TargetFrame{}) + ")";
     124              :   }
     125            0 :   using type = ::Jacobian<DataVector, Dim, SourceFrame, TargetFrame>;
     126              : };
     127              : 
     128              : /// \brief Sets the `ObserverJacobian` to `domain::Tags::Jacobian`
     129              : ///
     130              : /// This is what you would use for a single numerical method simulation. Hybrid
     131              : /// methods will supply their own tags.
     132              : template <size_t Dim, typename SourceFrame, typename TargetFrame>
     133            1 : struct ObserverJacobianCompute
     134              :     : ObserverJacobian<Dim, SourceFrame, TargetFrame>,
     135              :       db::ComputeTag {
     136            0 :   using base = ObserverJacobian<Dim, SourceFrame, TargetFrame>;
     137            0 :   using return_type = typename base::type;
     138            0 :   using argument_tags =
     139              :       tmpl::list<::domain::Tags::Jacobian<Dim, SourceFrame, TargetFrame>>;
     140            0 :   static void function(const gsl::not_null<return_type*> observer_jacobian,
     141              :                        const return_type& jacobian) {
     142              :     for (size_t i = 0; i < jacobian.size(); ++i) {
     143              :       (*observer_jacobian)[i].set_data_ref(
     144              :           // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
     145              :           make_not_null(&const_cast<DataVector&>(jacobian[i])));
     146              :     }
     147              :   }
     148              : };
     149              : 
     150              : /*!
     151              :  * \brief The determinant of the inverse Jacobian used for observation.
     152              :  *
     153              :  * In methods like DG-FD the mesh and inverse Jacobian change throughout the
     154              :  * simulation, so we need to always grab the right ones.
     155              :  */
     156              : template <typename SourceFrame, typename TargetFrame>
     157            1 : struct ObserverDetInvJacobian : db::SimpleTag {
     158            0 :   static std::string name() {
     159              :     return "DetInvJacobian(" + get_output(SourceFrame{}) + "," +
     160              :            get_output(TargetFrame{}) + ")";
     161              :   }
     162            0 :   using type = Scalar<DataVector>;
     163              : };
     164              : 
     165              : /// \brief Sets the `ObserverDetInvJacobian` to `domain::Tags::DetInvJacobian`
     166              : ///
     167              : /// This is what you would use for a single numerical method simulation. Hybrid
     168              : /// methods will supply their own tags.
     169              : template <typename SourceFrame, typename TargetFrame>
     170            1 : struct ObserverDetInvJacobianCompute
     171              :     : ObserverDetInvJacobian<SourceFrame, TargetFrame>,
     172              :       db::ComputeTag {
     173            0 :   using base = ObserverDetInvJacobian<SourceFrame, TargetFrame>;
     174            0 :   using return_type = typename base::type;
     175            0 :   using argument_tags =
     176              :       tmpl::list<::domain::Tags::DetInvJacobian<SourceFrame, TargetFrame>>;
     177            0 :   static void function(
     178              :       const gsl::not_null<return_type*> observer_det_inverse_jacobian,
     179              :       const return_type& det_inverse_jacobian) {
     180              :     for (size_t i = 0; i < det_inverse_jacobian.size(); ++i) {
     181              :       (*observer_det_inverse_jacobian)[i].set_data_ref(
     182              :           // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
     183              :           make_not_null(&const_cast<DataVector&>(det_inverse_jacobian[i])));
     184              :     }
     185              :   }
     186              : };
     187              : 
     188              : /// \brief The mesh velocity used for observations
     189              : ///
     190              : /// The type is a `std::optional`, which when it is not set indicates that the
     191              : /// mesh is not moving.
     192              : template <size_t Dim, typename Frame = ::Frame::Inertial>
     193            1 : struct ObserverMeshVelocity : db::SimpleTag {
     194            0 :   static std::string name() { return get_output(Frame{}) + "MeshVelocity"; }
     195            0 :   using type = std::optional<tnsr::I<DataVector, Dim, Frame>>;
     196              : };
     197              : 
     198              : /// \brief Sets the `ObserverMeshVelocty` to `domain::Tags::MeshVelocty`
     199              : ///
     200              : /// This is what you would use for a single numerical method simulation. Hybrid
     201              : /// methods will supply their own tags.
     202              : template <size_t Dim, typename Frame = ::Frame::Inertial>
     203            1 : struct ObserverMeshVelocityCompute : ObserverMeshVelocity<Dim, Frame>,
     204              :                                      db::ComputeTag {
     205            0 :   using base = ObserverMeshVelocity<Dim, Frame>;
     206            0 :   using return_type = typename base::type;
     207            0 :   using argument_tags = tmpl::list<::domain::Tags::MeshVelocity<Dim, Frame>>;
     208            0 :   static void function(const gsl::not_null<return_type*> observer_mesh_velocity,
     209              :                        const return_type& mesh_velocity) {
     210              :     if (mesh_velocity.has_value()) {
     211              :       *observer_mesh_velocity = tnsr::I<DataVector, Dim, Frame>{};
     212              :       for (size_t i = 0; i < mesh_velocity->size(); ++i) {
     213              :         observer_mesh_velocity->value()[i].set_data_ref(
     214              :             // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
     215              :             make_not_null(&const_cast<DataVector&>(mesh_velocity.value()[i])));
     216              :       }
     217              :     } else {
     218              :       *observer_mesh_velocity = std::nullopt;
     219              :     }
     220              :   }
     221              : };
     222              : }  // namespace Events::Tags
        

Generated by: LCOV version 2.0-1