SpECTRE Documentation Coverage Report
Current view: top level - PointwiseFunctions/AnalyticData/GrMhd - PolarMagnetizedFmDisk.hpp Hit Total Coverage
Commit: 22d59f0ec25cca6837adf897838d802980351e0d Lines: 2 26 7.7 %
Date: 2024-04-27 04:42:14
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 <algorithm>
       7             : #include <array>
       8             : #include <cmath>
       9             : #include <cstddef>
      10             : #include <iterator>
      11             : #include <type_traits>
      12             : 
      13             : #include "DataStructures/Tensor/EagerMath/Determinant.hpp"
      14             : #include "DataStructures/Tensor/EagerMath/FrameTransform.hpp"
      15             : #include "DataStructures/Tensor/Tensor.hpp"
      16             : #include "Options/Options.hpp"
      17             : #include "PointwiseFunctions/AnalyticData/AnalyticData.hpp"
      18             : #include "PointwiseFunctions/AnalyticData/GrMhd/AnalyticData.hpp"
      19             : #include "PointwiseFunctions/AnalyticData/GrMhd/MagnetizedFmDisk.hpp"
      20             : #include "PointwiseFunctions/AnalyticData/GrMhd/SphericalTorus.hpp"
      21             : #include "PointwiseFunctions/AnalyticSolutions/GeneralRelativity/Solutions.hpp"
      22             : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp"
      23             : #include "Utilities/Gsl.hpp"
      24             : #include "Utilities/Serialization/CharmPupable.hpp"
      25             : #include "Utilities/TMPL.hpp"
      26             : #include "Utilities/TaggedTuple.hpp"
      27             : 
      28             : /// \cond
      29             : namespace PUP {
      30             : class er;
      31             : }  // namespace PUP
      32             : /// \endcond
      33             : 
      34             : namespace grmhd::AnalyticData {
      35             : /*!
      36             :  * \brief Magnetized fluid disk orbiting a Kerr black hole in the Kerr-Schild
      37             :  * Cartesian coordinates, but in a toroidal mesh defined from a torus map
      38             :  * (see grmhd::AnalyticData::SphericalTorus).
      39             :  */
      40           1 : class PolarMagnetizedFmDisk
      41             :     : public virtual evolution::initial_data::InitialData,
      42             :       public MarkAsAnalyticData,
      43             :       public AnalyticDataBase {
      44             :  public:
      45           0 :   struct DiskParameters {
      46           0 :     using type = MagnetizedFmDisk;
      47           0 :     static constexpr Options::String help = "Parameters for the disk.";
      48             :   };
      49             : 
      50           0 :   struct TorusParameters {
      51           0 :     using type = grmhd::AnalyticData::SphericalTorus;
      52           0 :     static constexpr Options::String help =
      53             :         "Parameters for the evolution region.";
      54             :   };
      55             : 
      56           0 :   using options = tmpl::list<DiskParameters, TorusParameters>;
      57             : 
      58           0 :   static constexpr Options::String help =
      59             :       "Magnetized Fishbone-Moncrief disk in polar coordinates.";
      60             : 
      61           0 :   PolarMagnetizedFmDisk() = default;
      62           0 :   PolarMagnetizedFmDisk(const PolarMagnetizedFmDisk& /*rhs*/) = default;
      63           0 :   PolarMagnetizedFmDisk& operator=(const PolarMagnetizedFmDisk& /*rhs*/) =
      64             :       default;
      65           0 :   PolarMagnetizedFmDisk(PolarMagnetizedFmDisk&& /*rhs*/) = default;
      66           0 :   PolarMagnetizedFmDisk& operator=(PolarMagnetizedFmDisk&& /*rhs*/) = default;
      67           0 :   ~PolarMagnetizedFmDisk() override = default;
      68             : 
      69           0 :   PolarMagnetizedFmDisk(MagnetizedFmDisk fm_disk,
      70             :                         grmhd::AnalyticData::SphericalTorus torus_map);
      71             : 
      72           0 :   auto get_clone() const
      73             :       -> std::unique_ptr<evolution::initial_data::InitialData> override;
      74             : 
      75             :   /// \cond
      76             :   explicit PolarMagnetizedFmDisk(CkMigrateMessage* msg);
      77             :   using PUP::able::register_constructor;
      78             :   WRAPPED_PUPable_decl_template(PolarMagnetizedFmDisk);
      79             :   /// \endcond
      80             : 
      81             :   /// The grmhd variables.
      82             :   ///
      83             :   /// \note The functions are optimized for retrieving the hydro variables
      84             :   /// before the metric variables.
      85             :   template <typename DataType, typename... Tags>
      86           1 :   tuples::TaggedTuple<Tags...> variables(const tnsr::I<DataType, 3>& x,
      87             :                                          tmpl::list<Tags...> /*meta*/) const {
      88             :     // In this function, we label the coordinates this solution works
      89             :     // in with Frame::BlockLogical, and the coordinates the wrapped
      90             :     // solution uses Frame::Inertial.  This means the input and output
      91             :     // have to be converted to the correct label.
      92             : 
      93             :     const tnsr::I<DataType, 3> observation_coordinates(torus_map_(x));
      94             : 
      95             :     using dependencies = tmpl::map<
      96             :         tmpl::pair<gr::AnalyticSolution<3>::DerivShift<DataType>,
      97             :                    gr::Tags::Shift<DataType, 3, Frame::Inertial>>,
      98             :         tmpl::pair<gr::AnalyticSolution<3>::DerivSpatialMetric<DataType>,
      99             :                    gr::Tags::SpatialMetric<DataType, 3, Frame::Inertial>>>;
     100             :     using required_tags = tmpl::remove_duplicates<
     101             :         tmpl::remove<tmpl::list<Tags..., tmpl::at<dependencies, Tags>...>,
     102             :                      tmpl::no_such_type_>>;
     103             : 
     104             :     auto observation_data =
     105             :         fm_disk_.variables(observation_coordinates, required_tags{});
     106             : 
     107             :     const auto jacobian = torus_map_.jacobian(x);
     108             :     const auto inv_jacobian = torus_map_.inv_jacobian(x);
     109             : 
     110             :     const auto change_frame = [this, &inv_jacobian, &jacobian, &x](
     111             :                                   const auto& data, auto tag) {
     112             :       using Tag = decltype(tag);
     113             :       auto result =
     114             :           transform::to_different_frame(get<Tag>(data), jacobian, inv_jacobian);
     115             : 
     116             :       if constexpr (std::is_same_v<
     117             :                         Tag, gr::AnalyticSolution<3>::DerivShift<DataType>>) {
     118             :         const auto deriv_inv_jacobian =
     119             :             torus_map_.derivative_of_inv_jacobian(x);
     120             :         const auto& shift =
     121             :             get<gr::Tags::Shift<DataType, 3, Frame::Inertial>>(data);
     122             :         for (size_t i = 0; i < 3; ++i) {
     123             :           for (size_t j = 0; j < 3; ++j) {
     124             :             for (size_t k = 0; k < 3; ++k) {
     125             :               result.get(i, j) +=
     126             :                   deriv_inv_jacobian.get(j, k, i) * shift.get(k);
     127             :             }
     128             :           }
     129             :         }
     130             :       } else if constexpr (std::is_same_v<
     131             :                                Tag, gr::AnalyticSolution<3>::DerivSpatialMetric<
     132             :                                         DataType>>) {
     133             :         const auto hessian = torus_map_.hessian(x);
     134             :         const auto& spatial_metric =
     135             :             get<gr::Tags::SpatialMetric<DataType, 3, Frame::Inertial>>(data);
     136             :         for (size_t i = 0; i < 3; ++i) {
     137             :           for (size_t j = 0; j < 3; ++j) {
     138             :             for (size_t k = j; k < 3; ++k) {
     139             :               for (size_t l = 0; l < 3; ++l) {
     140             :                 for (size_t m = 0; m < 3; ++m) {
     141             :                   result.get(i, j, k) +=
     142             :                       (hessian.get(l, j, i) * jacobian.get(m, k) +
     143             :                        hessian.get(l, k, i) * jacobian.get(m, j)) *
     144             :                       spatial_metric.get(l, m);
     145             :                 }
     146             :               }
     147             :             }
     148             :           }
     149             :         }
     150             :       } else if constexpr (std::is_same_v<
     151             :                                Tag, gr::Tags::SqrtDetSpatialMetric<DataType>>) {
     152             :         get(result) *= abs(get(determinant(jacobian)));
     153             :       }
     154             : 
     155             :       typename Tag::type result_with_replaced_frame{};
     156             :       std::copy(std::move_iterator(result.begin()),
     157             :                 std::move_iterator(result.end()),
     158             :                 result_with_replaced_frame.begin());
     159             :       return result_with_replaced_frame;
     160             :     };
     161             : 
     162             :     return {change_frame(observation_data, Tags{})...};
     163             :   }
     164             : 
     165           0 :   using equation_of_state_type = MagnetizedFmDisk::equation_of_state_type;
     166           0 :   const equation_of_state_type& equation_of_state() const {
     167             :     return fm_disk_.equation_of_state();
     168             :   }
     169             : 
     170             :   // NOLINTNEXTLINE(google-runtime-references)
     171           0 :   void pup(PUP::er& p) override;
     172             : 
     173             :  private:
     174           0 :   friend bool operator==(const PolarMagnetizedFmDisk& lhs,
     175             :                          const PolarMagnetizedFmDisk& rhs);
     176             : 
     177           0 :   MagnetizedFmDisk fm_disk_;
     178           0 :   grmhd::AnalyticData::SphericalTorus torus_map_;
     179             : };
     180             : 
     181           0 : bool operator!=(const PolarMagnetizedFmDisk& lhs,
     182             :                 const PolarMagnetizedFmDisk& rhs);
     183             : }  // namespace grmhd::AnalyticData

Generated by: LCOV version 1.14