SpECTRE Documentation Coverage Report
Current view: top level - Evolution/Systems/GeneralizedHarmonic/GaugeSourceFunctions - AnalyticChristoffel.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 14.3 % 21 3
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 <memory>
       8              : #include <pup.h>
       9              : #include <string>
      10              : #include <type_traits>
      11              : 
      12              : #include "DataStructures/DataVector.hpp"
      13              : #include "DataStructures/TaggedTuple.hpp"
      14              : #include "DataStructures/Tensor/Tensor.hpp"
      15              : #include "Evolution/Systems/GeneralizedHarmonic/GaugeSourceFunctions/Gauges.hpp"
      16              : #include "Evolution/Systems/GeneralizedHarmonic/Tags.hpp"
      17              : #include "Options/String.hpp"
      18              : #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp"
      19              : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
      20              : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp"
      21              : #include "Utilities/CallWithDynamicType.hpp"
      22              : #include "Utilities/ErrorHandling/Assert.hpp"
      23              : #include "Utilities/Gsl.hpp"
      24              : #include "Utilities/TMPL.hpp"
      25              : 
      26              : /// \cond
      27              : template <size_t Dim>
      28              : class Mesh;
      29              : /// \endcond
      30              : 
      31            1 : namespace gh::gauges {
      32              : /*!
      33              :  * \brief Imposes the analytic gauge condition,
      34              :  * \f$H_a=\Gamma_a^{\mathrm{analytic}}\f$ from an analytic solution or analytic
      35              :  * data.
      36              :  *
      37              :  * \warning Assumes \f$\partial_t \Gamma_a=0\f$ i.e. the solution is static or
      38              :  * in harmonic gauge.
      39              :  */
      40            1 : class AnalyticChristoffel final : public GaugeCondition {
      41              :  private:
      42              :   template <size_t SpatialDim>
      43            0 :   using solution_tags =
      44              :       tmpl::list<gh::Tags::Pi<DataVector, SpatialDim>,
      45              :                  gh::Tags::Phi<DataVector, SpatialDim>,
      46              :                  gr::Tags::SpacetimeMetric<DataVector, SpatialDim>,
      47              :                  gr::Tags::Lapse<DataVector>,
      48              :                  gr::Tags::Shift<DataVector, SpatialDim>,
      49              :                  gr::Tags::SpatialMetric<DataVector, SpatialDim>>;
      50              : 
      51              :  public:
      52              :   /// \brief What analytic solution/data to prescribe.
      53            1 :   struct AnalyticPrescription {
      54            0 :     static constexpr Options::String help =
      55              :         "What analytic solution/data to prescribe.";
      56            0 :     using type = std::unique_ptr<evolution::initial_data::InitialData>;
      57              :   };
      58              : 
      59            0 :   using options = tmpl::list<AnalyticPrescription>;
      60              : 
      61            0 :   static constexpr Options::String help{
      62              :       "Apply the analytic gauge condition H_a = Gamma_a, where Gamma_a comes "
      63              :       "from the AnalyticPrescription."};
      64              : 
      65            0 :   AnalyticChristoffel() = default;
      66            0 :   AnalyticChristoffel(const AnalyticChristoffel&);
      67            0 :   AnalyticChristoffel& operator=(const AnalyticChristoffel&);
      68            0 :   AnalyticChristoffel(AnalyticChristoffel&&) = default;
      69            0 :   AnalyticChristoffel& operator=(AnalyticChristoffel&&) = default;
      70            0 :   ~AnalyticChristoffel() override = default;
      71              : 
      72            0 :   explicit AnalyticChristoffel(
      73              :       std::unique_ptr<evolution::initial_data::InitialData>
      74              :           analytic_prescription);
      75              : 
      76              :   /// \cond
      77              :   explicit AnalyticChristoffel(CkMigrateMessage* msg);
      78              :   using PUP::able::register_constructor;
      79              :   WRAPPED_PUPable_decl_template(AnalyticChristoffel);  // NOLINT
      80              :   /// \endcond
      81              : 
      82              :   template <size_t SpatialDim, class AllSolutionsForChristoffelAnalytic>
      83            0 :   void gauge_and_spacetime_derivative(
      84              :       const gsl::not_null<tnsr::a<DataVector, SpatialDim, Frame::Inertial>*>
      85              :           gauge_h,
      86              :       const gsl::not_null<tnsr::ab<DataVector, SpatialDim, Frame::Inertial>*>
      87              :           d4_gauge_h,
      88              :       const Mesh<SpatialDim>& mesh, const double time,
      89              :       const tnsr::I<DataVector, SpatialDim, Frame::Inertial>& inertial_coords,
      90              :       const InverseJacobian<DataVector, SpatialDim, Frame::ElementLogical,
      91              :                             Frame::Inertial>& inverse_jacobian,
      92              :       const AllSolutionsForChristoffelAnalytic /*meta*/) const {
      93              :     // Use .get() to avoid Clang-13 bug: with -Og in C++20 mode, the compiler
      94              :     // rewrites unique_ptr != nullptr via std::operator== but fails to emit the
      95              :     // out-of-line instantiation, causing a linker error.
      96              :     ASSERT(analytic_prescription_.get() != nullptr,
      97              :            "The analytic prescription cannot be nullptr.");
      98              :     // Unwrap wrapper types (e.g. WithNoise) to reach inner analytic solution
      99              :     const auto solution_vars = call_with_dynamic_type<
     100              :         tuples::tagged_tuple_from_typelist<solution_tags<SpatialDim>>,
     101              :         AllSolutionsForChristoffelAnalytic>(
     102              :         &analytic_prescription_->unwrap(),
     103              :         [&inertial_coords, &time](const auto* const analytic_solution_or_data) {
     104              :           if constexpr (is_analytic_solution_v<std::decay_t<
     105              :                             decltype(*analytic_solution_or_data)>>) {
     106              :             return analytic_solution_or_data->variables(
     107              :                 inertial_coords, time, solution_tags<SpatialDim>{});
     108              : 
     109              :           } else {
     110              :             (void)time;
     111              :             return analytic_solution_or_data->variables(
     112              :                 inertial_coords, solution_tags<SpatialDim>{});
     113              :           }
     114              :         });
     115              :     gauge_and_spacetime_derivative_impl(gauge_h, d4_gauge_h, mesh,
     116              :                                         inverse_jacobian, inertial_coords,
     117              :                                         solution_vars);
     118              :   }
     119              : 
     120              :   // NOLINTNEXTLINE(google-runtime-references)
     121            0 :   void pup(PUP::er& p) override;
     122              : 
     123            0 :   std::unique_ptr<GaugeCondition> get_clone() const override;
     124              : 
     125              :  private:
     126              :   template <size_t SpatialDim>
     127            0 :   void gauge_and_spacetime_derivative_impl(
     128              :       gsl::not_null<tnsr::a<DataVector, SpatialDim, Frame::Inertial>*> gauge_h,
     129              :       gsl::not_null<tnsr::ab<DataVector, SpatialDim, Frame::Inertial>*>
     130              :           d4_gauge_h,
     131              :       const Mesh<SpatialDim>& mesh,
     132              :       const InverseJacobian<DataVector, SpatialDim, Frame::ElementLogical,
     133              :                             Frame::Inertial>& inverse_jacobian,
     134              :       const tnsr::I<DataVector, SpatialDim, Frame::Inertial>& inertial_coords,
     135              :       const tuples::tagged_tuple_from_typelist<solution_tags<SpatialDim>>&
     136              :           solution_vars) const;
     137              : 
     138            0 :   std::unique_ptr<evolution::initial_data::InitialData> analytic_prescription_;
     139              : };
     140              : }  // namespace gh::gauges
        

Generated by: LCOV version 2.0-1