SpECTRE Documentation Coverage Report
Current view: top level - PointwiseFunctions/AnalyticData/GeneralRelativity - BrillLindquist.hpp Hit Total Coverage
Commit: aabde07399ba7837e5db64eedfd0a21f31f96922 Lines: 44 73 60.3 %
Date: 2024-04-26 02:38:13
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 <array>
       7             : #include <limits>
       8             : #include <pup.h>
       9             : 
      10             : #include "DataStructures/CachedTempBuffer.hpp"
      11             : #include "DataStructures/Tags/TempTensor.hpp"
      12             : #include "DataStructures/Tensor/IndexType.hpp"
      13             : #include "DataStructures/Tensor/TypeAliases.hpp"
      14             : #include "Options/Context.hpp"
      15             : #include "Options/String.hpp"
      16             : #include "PointwiseFunctions/AnalyticData/AnalyticData.hpp"
      17             : #include "PointwiseFunctions/AnalyticData/GeneralRelativity/AnalyticData.hpp"
      18             : #include "PointwiseFunctions/GeneralRelativity/TagsDeclarations.hpp"
      19             : #include "Utilities/TMPL.hpp"
      20             : #include "Utilities/TaggedTuple.hpp"
      21             : 
      22             : /// \cond
      23             : namespace Tags {
      24             : template <typename Tag>
      25             : struct dt;
      26             : }  // namespace Tags
      27             : namespace gsl {
      28             : template <class T>
      29             : class not_null;
      30             : }  // namespace gsl
      31             : /// \endcond
      32             : 
      33             : namespace gr::AnalyticData {
      34             : /*!
      35             :  * \brief Brill Lindquist data \cite Brill1963yv corresponding to two black
      36             :  * holes momentarily at rest
      37             :  *
      38             :  * The spatial metric is given by \f$\gamma_{ij} = \psi^4 \delta_{ij}\f$
      39             :  * where the conformal factor is given by
      40             :  * \f$\psi = 1 + \frac{m_A}{2 r_A} + \frac{m_B}{2 r_B}\f$ where
      41             :  * \f$m_{A,B}\f$ are the masses of the black holes and \f$r_{A,B}\f$ are the
      42             :  * positions of a point relative to the center of each black hole
      43             :  *
      44             :  * The data is time symmetric (\f$K_{ij} = 0\f$) and we arbitrarily choose
      45             :  * unit lapse and zero shift.
      46             :  */
      47           1 : class BrillLindquist : public AnalyticDataBase<3>, public MarkAsAnalyticData {
      48             :  public:
      49           0 :   struct MassA {
      50           0 :     using type = double;
      51           0 :     static constexpr Options::String help = {"Mass of the black hole A"};
      52           0 :     static type lower_bound() { return 0.; }
      53             :   };
      54           0 :   struct MassB {
      55           0 :     using type = double;
      56           0 :     static constexpr Options::String help = {"Mass of the black hole B"};
      57           0 :     static type lower_bound() { return 0.; }
      58             :   };
      59           0 :   struct CenterA {
      60           0 :     using type = std::array<double, 3>;
      61           0 :     static constexpr Options::String help = {
      62             :         "The [x,y,z] center of the black hole A"};
      63             :   };
      64           0 :   struct CenterB {
      65           0 :     using type = std::array<double, 3>;
      66           0 :     static constexpr Options::String help = {
      67             :         "The [x,y,z] center of the black hole B"};
      68             :   };
      69           0 :   using options = tmpl::list<MassA, MassB, CenterA, CenterB>;
      70           0 :   static constexpr Options::String help{
      71             :       "Brill-Lindquist data for two black holes"};
      72             : 
      73           0 :   BrillLindquist(double mass_a, double mass_b,
      74             :                  const std::array<double, 3>& center_a,
      75             :                  const std::array<double, 3>& center_b,
      76             :                  const Options::Context& context = {});
      77           0 :   explicit BrillLindquist(CkMigrateMessage* /*unused*/);
      78             : 
      79           0 :   BrillLindquist() = default;
      80           0 :   BrillLindquist(const BrillLindquist& /*rhs*/) = default;
      81           0 :   BrillLindquist& operator=(const BrillLindquist& /*rhs*/) = default;
      82           0 :   BrillLindquist(BrillLindquist&& /*rhs*/) = default;
      83           0 :   BrillLindquist& operator=(BrillLindquist&& /*rhs*/) = default;
      84           0 :   ~BrillLindquist() = default;
      85             : 
      86             :   /*!
      87             :    * \brief Computes and returns spacetime quantities for BrillLindquist data at
      88             :    * a specific Cartesian position
      89             :    *
      90             :    * \param x Cartesian coordinates of the position at which to compute
      91             :    * spacetime quantities
      92             :    */
      93             :   template <typename DataType, typename Frame, typename... Tags>
      94           1 :   tuples::TaggedTuple<Tags...> variables(
      95             :       const tnsr::I<DataType, volume_dim, Frame>& x,
      96             :       tmpl::list<Tags...> /*meta*/) const {
      97             :     static_assert(
      98             :         tmpl2::flat_all_v<
      99             :             tmpl::list_contains_v<tags<DataType, Frame>, Tags>...>,
     100             :         "At least one of the requested tags is not supported. The requested "
     101             :         "tags are listed as template parameters of the `variables` function.");
     102             :     IntermediateVars<DataType, Frame> cache(get_size(*x.begin()));
     103             :     IntermediateComputer<DataType, Frame> computer(*this, x);
     104             :     return {cache.get_var(computer, Tags{})...};
     105             :   }
     106             : 
     107             :   // NOLINTNEXTLINE(google-runtime-references)
     108           0 :   void pup(PUP::er& p);
     109             : 
     110             :   /*!
     111             :    * \brief Return the mass of black hole A
     112             :    */
     113           1 :   SPECTRE_ALWAYS_INLINE double mass_a() const { return mass_a_; }
     114             :   /*!
     115             :    * \brief Return the mass of black hole B
     116             :    */
     117           1 :   SPECTRE_ALWAYS_INLINE double mass_b() const { return mass_b_; }
     118             :   /*!
     119             :    * \brief Return the center of black hole A
     120             :    */
     121           1 :   SPECTRE_ALWAYS_INLINE const std::array<double, 3>& center_a() const {
     122             :     return center_a_;
     123             :   }
     124             :   /*!
     125             :    * \brief Return the center of black hole B
     126             :    */
     127           1 :   SPECTRE_ALWAYS_INLINE const std::array<double, 3>& center_b() const {
     128             :     return center_b_;
     129             :   }
     130             : 
     131             :   /*!
     132             :    * \brief Tags defined for intermediates specific to BrillLindquist data
     133             :    */
     134           1 :   struct internal_tags {
     135             :     /*!
     136             :      * \brief Tag for the position of a point relative to the center of
     137             :      * black hole A
     138             :      *
     139             :      * \details Defined as \f$X_A^i = \left(x^i - C_A^i\right)\f$, where
     140             :      * \f$C_A^i\f$ is the Cartesian coordinates of the center of black hole A
     141             :      * and \f$x^i\f$ is the Cartesian coordinates of the point where we're
     142             :      * wanting to compute spacetime quantities.
     143             :      */
     144             :     template <typename DataType, typename Frame>
     145           1 :     using x_minus_center_a = ::Tags::TempI<0, 3, Frame, DataType>;
     146             : 
     147             :     /*!
     148             :      * \brief Tag for the radius corresponding to the position of a point
     149             :      * relative to the center of black hole A
     150             :      *
     151             :      * \details Defined as \f$r_A = \sqrt{\delta_{ij} X_A^i X_A^j}\f$, where
     152             :      * \f$X_A^i\f$ is defined by `internal_tags::x_minus_center_a`.
     153             :      */
     154             :     template <typename DataType>
     155           1 :     using r_a = ::Tags::TempScalar<1, DataType>;
     156             : 
     157             :     /*!
     158             :      * \brief Tag for the position of a point relative to the center of
     159             :      * black hole B
     160             :      *
     161             :      * \details Defined as \f$X_B^i = \left(x^i - C_B^i\right)\f$, where
     162             :      * \f$C_B^i\f$ is the Cartesian coordinates of the center of black hole B
     163             :      * and \f$x^i\f$ is the Cartesian coordinates of the point where we're
     164             :      * wanting to compute spacetime quantities.
     165             :      */
     166             :     template <typename DataType, typename Frame>
     167           1 :     using x_minus_center_b = ::Tags::TempI<2, 3, Frame, DataType>;
     168             : 
     169             :     /*!
     170             :      * \brief Tag for the radius corresponding to the position of a point
     171             :      * relative to the center of black hole B
     172             :      *
     173             :      * \details Defined as \f$r_B = \sqrt{\delta_{ij} X_B^i X_B^j}\f$, where
     174             :      * \f$X_B^i\f$ is defined by `internal_tags::x_minus_center_b`.
     175             :      */
     176             :     template <typename DataType>
     177           1 :     using r_b = ::Tags::TempScalar<3, DataType>;
     178             :     /*!
     179             :      * \brief Tag for the conformal factor
     180             :      *
     181             :      * \details Defined as \f$\psi = 1 + \frac{m_A}{2 r_A} + \frac{m_B}{2
     182             :      * r_B}\f$ where \f$m_{A,B}\f$ are the masses of the black holes and
     183             :      * \f$r_{A,B}\f$ are the positions of a point relative to the center of each
     184             :      * black hole
     185             :      */
     186             :     template <typename DataType>
     187           1 :     using conformal_factor = ::Tags::TempScalar<4, DataType>;
     188             :     /*!
     189             :      * \brief Tag for the deriatives of the conformal factor
     190             :      *
     191             :      * \details Defined as \f$d_i\psi = -\frac{m_A X_A^j}{2 r_A^3} \delta_{ij}
     192             :      *  - \frac{m_B X_B^j}{2 r_B^3} \delta_{ij}\f$ where \f$m_{A,B}\f$ are the
     193             :      * masses of the black holes and \f$r_{A,B}\f$ are the positions of a point
     194             :      * relative to the center of each black hole.  (Note we are free to
     195             :      * raise/lower coordinate indices with a Eucledian metric)
     196             :      */
     197             :     template <typename DataType, typename Frame>
     198           1 :     using deriv_conformal_factor = ::Tags::Tempi<5, 3, Frame, DataType>;
     199             :   };
     200             : 
     201             :   template <typename DataType, typename Frame>
     202           0 :   using DerivSpatialMetric =
     203             :       ::Tags::deriv<gr::Tags::SpatialMetric<DataType, volume_dim, Frame>,
     204             :                     tmpl::size_t<volume_dim>, Frame>;
     205             : 
     206             :   /*!
     207             :    * \brief Buffer for caching computed intermediates and quantities that we do
     208             :    * not want to recompute across the solution's implementation
     209             :    *
     210             :    * \details See `internal_tags` documentation for details on what quantities
     211             :    * the internal tags represent
     212             :    */
     213             :   template <typename DataType, typename Frame>
     214           1 :   using CachedBuffer =
     215             :       CachedTempBuffer<internal_tags::x_minus_center_a<DataType, Frame>,
     216             :                        internal_tags::r_a<DataType>,
     217             :                        internal_tags::x_minus_center_b<DataType, Frame>,
     218             :                        internal_tags::r_b<DataType>,
     219             :                        internal_tags::conformal_factor<DataType>,
     220             :                        internal_tags::deriv_conformal_factor<DataType, Frame>,
     221             :                        gr::Tags::SpatialMetric<DataType, 3, Frame>,
     222             :                        DerivSpatialMetric<DataType, Frame>>;
     223             : 
     224             :   /*!
     225             :    * \brief Computes the intermediates and quantities that we do not want to
     226             :    * recompute across the solution's implementation
     227             :    */
     228             :   template <typename DataType, typename Frame>
     229           1 :   class IntermediateComputer {
     230             :    public:
     231           0 :     using CachedBuffer = BrillLindquist::CachedBuffer<DataType, Frame>;
     232             : 
     233             :     /*!
     234             :      * \brief Constructs a computer for spacetime quantities of a given
     235             :      * `gr::AnalyticData::BrillLindquist` solution at at a specific
     236             :      * Cartesian position
     237             :      *
     238             :      * \param analytic_data the given `gr::AnalyticData::BrillLindquist` data
     239             :      * \param x Cartesian coordinates of the position at which to compute
     240             :      * spacetime quantities
     241             :      */
     242           1 :     IntermediateComputer(const BrillLindquist& analytic_data,
     243             :                          const tnsr::I<DataType, 3, Frame>& x);
     244             : 
     245             :     /*!
     246             :      * \brief Computes the intermediate defined by
     247             :      * `internal_tags::x_minus_center_a`
     248             :      */
     249           1 :     void operator()(
     250             :         gsl::not_null<tnsr::I<DataType, 3, Frame>*> x_minus_center_a,
     251             :         gsl::not_null<CachedBuffer*> /*cache*/,
     252             :         internal_tags::x_minus_center_a<DataType, Frame> /*meta*/) const;
     253             : 
     254             :     /*!
     255             :      * \brief Computes the radius defined by `internal_tags::r_a`
     256             :      */
     257           1 :     void operator()(gsl::not_null<Scalar<DataType>*> r_a,
     258             :                     gsl::not_null<CachedBuffer*> cache,
     259             :                     internal_tags::r_a<DataType> /*meta*/) const;
     260             : 
     261             :     /*!
     262             :      * \brief Computes the intermediate defined by
     263             :      * `internal_tags::x_minus_center_b`
     264             :      */
     265           1 :     void operator()(
     266             :         gsl::not_null<tnsr::I<DataType, 3, Frame>*> x_minus_center_b,
     267             :         gsl::not_null<CachedBuffer*> /*cache*/,
     268             :         internal_tags::x_minus_center_b<DataType, Frame> /*meta*/) const;
     269             : 
     270             :     /*!
     271             :      * \brief Computes the radius defined by `internal_tags::r_b`
     272             :      */
     273           1 :     void operator()(gsl::not_null<Scalar<DataType>*> r_b,
     274             :                     gsl::not_null<CachedBuffer*> cache,
     275             :                     internal_tags::r_b<DataType> /*meta*/) const;
     276             : 
     277             :     /*!
     278             :      * \brief Computes the intermediate defined by
     279             :      * `internal_tags::conformal_factor`
     280             :      */
     281           1 :     void operator()(gsl::not_null<Scalar<DataType>*> conformal_factor,
     282             :                     gsl::not_null<CachedBuffer*> /*cache*/,
     283             :                     internal_tags::conformal_factor<DataType> /*meta*/) const;
     284             : 
     285             :     /*!
     286             :      * \brief Computes the intermediate defined by
     287             :      * `internal_tags::deriv_conformal_factor`
     288             :      */
     289           1 :     void operator()(
     290             :         gsl::not_null<tnsr::i<DataType, 3, Frame>*> deriv_conformal_factor,
     291             :         gsl::not_null<CachedBuffer*> /*cache*/,
     292             :         internal_tags::deriv_conformal_factor<DataType, Frame> /*meta*/) const;
     293             : 
     294             :     /*!
     295             :      * \brief Computes the spatial metric
     296             :      *
     297             :      * \details Computed as \f$\gamma_{ij} = \delta_{ij} \psi^4\f$
     298             :      * where \f$\psi\f$ is the conformal factor defined by
     299             :      * `internal_tags::conformal_factor`.
     300             :      */
     301           1 :     void operator()(gsl::not_null<tnsr::ii<DataType, 3, Frame>*> spatial_metric,
     302             :                     gsl::not_null<CachedBuffer*> cache,
     303             :                     gr::Tags::SpatialMetric<DataType, 3, Frame> /*meta*/) const;
     304             : 
     305             :     /*!
     306             :      * \brief Computes the spatial derivative of the spatial metric
     307             :      *
     308             :      * \details Computed as \f$\partial_k \gamma_{ij} = 4 \psi^3 \partial_k
     309             :      * \psi \delta_{ij} \f$ where \f$\psi\f$ is the conformal factor defined by
     310             :      * `internal_tags::conformal_factor`.
     311             :      */
     312           1 :     void operator()(
     313             :         gsl::not_null<tnsr::ijj<DataType, 3, Frame>*> deriv_spatial_metric,
     314             :         gsl::not_null<CachedBuffer*> cache,
     315             :         DerivSpatialMetric<DataType, Frame> /*meta*/) const;
     316             : 
     317             :    private:
     318             :     /*!
     319             :      * \brief The BrillLindquist data
     320             :      */
     321           1 :     const BrillLindquist& analytic_data_;
     322             :     /*!
     323             :      * \brief Cartesian coordinates of the position at which to compute
     324             :      * spacetime quantities
     325             :      */
     326           1 :     const tnsr::I<DataType, 3, Frame>& x_;
     327             :   };
     328             : 
     329             :   /*!
     330             :    * \brief Computes and returns spacetime quantities of interest
     331             :    */
     332             :   template <typename DataType, typename Frame>
     333           1 :   class IntermediateVars : public CachedBuffer<DataType, Frame> {
     334             :    public:
     335           0 :     using CachedBuffer = BrillLindquist::CachedBuffer<DataType, Frame>;
     336             :     using CachedBuffer::CachedBuffer;
     337           1 :     using CachedBuffer::get_var;
     338             : 
     339             :     /*!
     340             :      * \brief Returns the lapse, which is 1
     341             :      */
     342           1 :     Scalar<DataType> get_var(
     343             :         const IntermediateComputer<DataType, Frame>& computer,
     344             :         gr::Tags::Lapse<DataType> /*meta*/);
     345             : 
     346             :     /*!
     347             :      * \brief Returns the time derivative of the lapse, which is 0
     348             :      */
     349           1 :     Scalar<DataType> get_var(
     350             :         const IntermediateComputer<DataType, Frame>& computer,
     351             :         ::Tags::dt<gr::Tags::Lapse<DataType>> /*meta*/);
     352             : 
     353             :     /*!
     354             :      * \brief Returns the spatial derivative of the lapse, which is 0
     355             :      */
     356           1 :     tnsr::i<DataType, 3, Frame> get_var(
     357             :         const IntermediateComputer<DataType, Frame>& computer,
     358             :         DerivLapse<DataType, Frame> /*meta*/);
     359             : 
     360             :     /*!
     361             :      * \brief Returns the shift, which is 0
     362             :      */
     363           1 :     tnsr::I<DataType, 3, Frame> get_var(
     364             :         const IntermediateComputer<DataType, Frame>& computer,
     365             :         gr::Tags::Shift<DataType, 3, Frame> /*meta*/);
     366             : 
     367             :     /*!
     368             :      * \brief Returns the time derivative of the shift, which is 0
     369             :      */
     370           1 :     tnsr::I<DataType, 3, Frame> get_var(
     371             :         const IntermediateComputer<DataType, Frame>& computer,
     372             :         ::Tags::dt<gr::Tags::Shift<DataType, 3, Frame>> /*meta*/);
     373             : 
     374             :     /*!
     375             :      * \brief Returns the spatial derivative of the shift, which is 0
     376             :      */
     377           1 :     tnsr::iJ<DataType, 3, Frame> get_var(
     378             :         const IntermediateComputer<DataType, Frame>& computer,
     379             :         DerivShift<DataType, Frame> /*meta*/);
     380             : 
     381             :     /*!
     382             :      * \brief Returns the time derivative of the spatial metric, which is 0
     383             :      */
     384           1 :     tnsr::ii<DataType, 3, Frame> get_var(
     385             :         const IntermediateComputer<DataType, Frame>& computer,
     386             :         ::Tags::dt<gr::Tags::SpatialMetric<DataType, 3, Frame>> /*meta*/);
     387             : 
     388             :     /*!
     389             :      * \brief Computes and returns the square root of the determinant of the
     390             :      * spatial metric
     391             :      */
     392           1 :     Scalar<DataType> get_var(
     393             :         const IntermediateComputer<DataType, Frame>& computer,
     394             :         gr::Tags::SqrtDetSpatialMetric<DataType> /*meta*/);
     395             : 
     396             :     /*!
     397             :      * \brief Computes and returns the inverse spatial metric
     398             :      */
     399           1 :     tnsr::II<DataType, 3, Frame> get_var(
     400             :         const IntermediateComputer<DataType, Frame>& computer,
     401             :         gr::Tags::InverseSpatialMetric<DataType, 3, Frame> /*meta*/);
     402             : 
     403             :     /*!
     404             :      * \brief Computes and returns the extrinsic curvature which is 0
     405             :      */
     406           1 :     tnsr::ii<DataType, 3, Frame> get_var(
     407             :         const IntermediateComputer<DataType, Frame>& computer,
     408             :         gr::Tags::ExtrinsicCurvature<DataType, 3, Frame> /*meta*/);
     409             :   };
     410             : 
     411             :  private:
     412             :   /*!
     413             :    * \brief Mass of black hole A
     414             :    */
     415           1 :   double mass_a_{std::numeric_limits<double>::signaling_NaN()};
     416             :   /*!
     417             :    * \brief Mass of black hole B
     418             :    */
     419           1 :   double mass_b_{std::numeric_limits<double>::signaling_NaN()};
     420             :   /*!
     421             :    * \brief Center of black hole A
     422             :    */
     423           1 :   std::array<double, 3> center_a_ =
     424             :       make_array<3>(std::numeric_limits<double>::signaling_NaN());
     425             :   /*!
     426             :    * \brief Center of black hole B
     427             :    */
     428           1 :   std::array<double, 3> center_b_ =
     429             :       make_array<3>(std::numeric_limits<double>::signaling_NaN());
     430             : };
     431             : 
     432             : /*!
     433             :  * \brief Return whether two BrillLindquist data are equivalent
     434             :  */
     435           1 : SPECTRE_ALWAYS_INLINE bool operator==(const BrillLindquist& lhs,
     436             :                                       const BrillLindquist& rhs);
     437             : 
     438             : /*!
     439             :  * \brief Return whether two BrillLindquist data are not equivalent
     440             :  */
     441           1 : SPECTRE_ALWAYS_INLINE bool operator!=(const BrillLindquist& lhs,
     442             :                                       const BrillLindquist& rhs);
     443             : }  // namespace gr::AnalyticData

Generated by: LCOV version 1.14