SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/Events - Tags.hpp Hit Total Coverage
Commit: 5b6dac11263b5fb9107cb6ea064c64c61b65a417 Lines: 12 49 24.5 %
Date: 2024-04-19 22:56:45
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 1.14