SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/Interpolation/Targets - Sphere.hpp Hit Total Coverage
Commit: 3c072f0ce967e2e56649d3fa12aa2a0e4fe2a42e Lines: 2 46 4.3 %
Date: 2024-04-23 20:50:18
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 <cstddef>
       9             : #include <limits>
      10             : #include <set>
      11             : #include <variant>
      12             : #include <vector>
      13             : 
      14             : #include "DataStructures/DataBox/DataBox.hpp"
      15             : #include "DataStructures/Transpose.hpp"
      16             : #include "NumericalAlgorithms/SphericalHarmonics/Strahlkorper.hpp"
      17             : #include "NumericalAlgorithms/SphericalHarmonics/Tags.hpp"
      18             : #include "Options/String.hpp"
      19             : #include "Parallel/GlobalCache.hpp"
      20             : #include "ParallelAlgorithms/Initialization/MutateAssign.hpp"
      21             : #include "ParallelAlgorithms/Interpolation/Protocols/ComputeTargetPoints.hpp"
      22             : #include "ParallelAlgorithms/Interpolation/Tags.hpp"
      23             : #include "ParallelAlgorithms/Interpolation/Targets/AngularOrdering.hpp"
      24             : #include "Utilities/Algorithm.hpp"
      25             : #include "Utilities/ErrorHandling/Assert.hpp"
      26             : #include "Utilities/PrettyType.hpp"
      27             : #include "Utilities/ProtocolHelpers.hpp"
      28             : 
      29             : /// \cond
      30             : class DataVector;
      31             : namespace PUP {
      32             : class er;
      33             : }  // namespace PUP
      34             : namespace db {
      35             : template <typename TagsList>
      36             : class DataBox;
      37             : }  // namespace db
      38             : namespace intrp {
      39             : namespace Tags {
      40             : template <typename TemporalId>
      41             : struct TemporalIds;
      42             : }  // namespace Tags
      43             : }  // namespace intrp
      44             : /// \endcond
      45             : 
      46             : namespace intrp {
      47             : 
      48             : namespace OptionHolders {
      49             : /// A series of concentric spherical surfaces.
      50             : ///
      51             : /// \details The parameter `LMax` sets the number of collocation points on
      52             : /// each spherical surface equal to `(l_max + 1) * (2 * l_max + 1)`. The
      53             : /// parameter `AngularOrdering` encodes the collocation ordering. For example,
      54             : /// the apparent horizon finder relies on spherepack routines that require
      55             : /// `Strahlkorper` for `AngularOrdering`, and using these surfaces for a CCE
      56             : /// worldtube requires `Cce` for `AngularOrdering`.
      57           1 : struct Sphere {
      58           0 :   struct LMax {
      59           0 :     using type = size_t;
      60           0 :     static constexpr Options::String help = {
      61             :         "The number of collocation points on each sphere will be equal to "
      62             :         "`(l_max + 1) * (2 * l_max + 1)`"};
      63             :   };
      64           0 :   struct Center {
      65           0 :     using type = std::array<double, 3>;
      66           0 :     static constexpr Options::String help = {"Center of every sphere"};
      67             :   };
      68           0 :   struct Radius {
      69           0 :     using type = std::variant<double, std::vector<double>>;
      70           0 :     static constexpr Options::String help = {"Radius of the sphere(s)"};
      71             :   };
      72           0 :   struct AngularOrdering {
      73           0 :     using type = intrp::AngularOrdering;
      74           0 :     static constexpr Options::String help = {
      75             :         "Chooses theta,phi ordering in 2d array"};
      76             :   };
      77           0 :   using options = tmpl::list<LMax, Center, Radius, AngularOrdering>;
      78           0 :   static constexpr Options::String help = {
      79             :       "An arbitrary number of spherical surface."};
      80           0 :   Sphere(const size_t l_max_in, const std::array<double, 3> center_in,
      81             :          const typename Radius::type& radius_in,
      82             :          intrp::AngularOrdering angular_ordering_in,
      83             :          const Options::Context& context = {});
      84             : 
      85           0 :   Sphere() = default;
      86             : 
      87             :   // NOLINTNEXTLINE(google-runtime-references)
      88           0 :   void pup(PUP::er& p);
      89             : 
      90           0 :   size_t l_max{0};
      91           0 :   std::array<double, 3> center{std::numeric_limits<double>::signaling_NaN()};
      92           0 :   std::set<double> radii;
      93           0 :   intrp::AngularOrdering angular_ordering;
      94             : };
      95             : 
      96           0 : bool operator==(const Sphere& lhs, const Sphere& rhs);
      97           0 : bool operator!=(const Sphere& lhs, const Sphere& rhs);
      98             : 
      99             : }  // namespace OptionHolders
     100             : 
     101             : namespace OptionTags {
     102             : template <typename InterpolationTargetTag>
     103           0 : struct Sphere {
     104           0 :   using type = OptionHolders::Sphere;
     105           0 :   static constexpr Options::String help{
     106             :       "Options for interpolation onto a sphere(s)."};
     107           0 :   static std::string name() {
     108             :     return pretty_type::name<InterpolationTargetTag>();
     109             :   }
     110           0 :   using group = InterpolationTargets;
     111             : };
     112             : }  // namespace OptionTags
     113             : 
     114             : namespace Tags {
     115             : template <typename InterpolationTargetTag>
     116           0 : struct Sphere : db::SimpleTag {
     117           0 :   using type = OptionHolders::Sphere;
     118           0 :   using option_tags = tmpl::list<OptionTags::Sphere<InterpolationTargetTag>>;
     119             : 
     120           0 :   static constexpr bool pass_metavariables = false;
     121           0 :   static OptionHolders::Sphere create_from_options(
     122             :       const OptionHolders::Sphere& option) {
     123             :     return option;
     124             :   }
     125             : };
     126             : 
     127             : template <typename Frame>
     128           0 : struct AllCoords : db::SimpleTag {
     129           0 :   using type = tnsr::I<DataVector, 3, Frame>;
     130             : };
     131             : }  // namespace Tags
     132             : 
     133             : namespace TargetPoints {
     134             : /// \brief Computes points on spherical surfaces.
     135             : ///
     136             : /// Conforms to the intrp::protocols::ComputeTargetPoints protocol
     137             : ///
     138             : /// For requirements on InterpolationTargetTag, see
     139             : /// intrp::protocols::InterpolationTargetTag
     140             : template <typename InterpolationTargetTag, typename Frame>
     141           1 : struct Sphere : tt::ConformsTo<intrp::protocols::ComputeTargetPoints> {
     142           0 :   using const_global_cache_tags =
     143             :       tmpl::list<Tags::Sphere<InterpolationTargetTag>>;
     144           0 :   using is_sequential = std::false_type;
     145           0 :   using frame = Frame;
     146             : 
     147           0 :   using simple_tags =
     148             :       tmpl::list<ylm::Tags::Strahlkorper<Frame>, Tags::AllCoords<Frame>>;
     149           0 :   using compute_tags = typename ylm::Tags::compute_items_tags<Frame>;
     150             : 
     151             :   template <typename DbTags, typename Metavariables>
     152           0 :   static void initialize(const gsl::not_null<db::DataBox<DbTags>*> box,
     153             :                          const Parallel::GlobalCache<Metavariables>& cache) {
     154             :     const auto& sphere =
     155             :         Parallel::get<Tags::Sphere<InterpolationTargetTag>>(cache);
     156             :     const size_t l_max = sphere.l_max;
     157             :     const auto& radii = sphere.radii;
     158             : 
     159             :     // Total number of points is number of points for one sphere times the
     160             :     // number of spheres we use.
     161             :     const size_t num_points = radii.size() * (l_max + 1) * (2 * l_max + 1);
     162             : 
     163             :     tnsr::I<DataVector, 3, Frame> all_coords{num_points};
     164             : 
     165             :     size_t index = 0;
     166             :     for (const double radius : radii) {
     167             :       ylm::Strahlkorper<Frame> strahlkorper(
     168             :           l_max, l_max, DataVector{(l_max + 1) * (2 * l_max + 1), radius},
     169             :           sphere.center);
     170             : 
     171             :       db::mutate<ylm::Tags::Strahlkorper<Frame>>(
     172             :           [&strahlkorper](const gsl::not_null<ylm::Strahlkorper<Frame>*>
     173             :                               local_strahlkorper) {
     174             :             *local_strahlkorper = std::move(strahlkorper);
     175             :           },
     176             :           box);
     177             : 
     178             :       // This copy is ok because it's just in initialization
     179             :       auto coords = db::get<ylm::Tags::CartesianCoords<Frame>>(*box);
     180             : 
     181             :       // If the angular ordering is Strahlkorper then we don't have to do
     182             :       // anything to the coords because they are already in the right order
     183             :       if (sphere.angular_ordering == intrp::AngularOrdering::Cce) {
     184             :         const auto physical_extents =
     185             :             strahlkorper.ylm_spherepack().physical_extents();
     186             :         auto transposed_coords =
     187             :             tnsr::I<DataVector, 3, Frame>(get<0>(coords).size());
     188             : 
     189             :         for (size_t i = 0; i < 3; ++i) {
     190             :           transpose(make_not_null(&transposed_coords.get(i)), coords.get(i),
     191             :                     physical_extents[0], physical_extents[1]);
     192             :         }
     193             :         coords = std::move(transposed_coords);
     194             :       }
     195             : 
     196             :       const size_t tmp_index = index;
     197             :       for (size_t i = 0; i < 3; ++i) {
     198             :         for (size_t local_index = 0; local_index < coords.get(i).size();
     199             :              local_index++, index++) {
     200             :           all_coords.get(i)[index] = coords.get(i)[local_index];
     201             :         }
     202             :         if (i != 2) {
     203             :           index = tmp_index;
     204             :         }
     205             :       }
     206             :     }
     207             : 
     208             :     // If this fails, there is a bug. Can't really test it
     209             :     // LCOV_EXCL_START
     210             :     ASSERT(index == all_coords.get(0).size(),
     211             :            "Didn't initialize points of Sphere target correctly. index = "
     212             :                << index << " all_coords.size() = " << all_coords.get(0).size());
     213             :     // LCOV_EXCL_STOP
     214             : 
     215             :     Initialization::mutate_assign<tmpl::list<Tags::AllCoords<Frame>>>(
     216             :         box, std::move(all_coords));
     217             :   }
     218             : 
     219             :   template <typename Metavariables, typename DbTags, typename TemporalId>
     220           0 :   static tnsr::I<DataVector, 3, Frame> points(
     221             :       const db::DataBox<DbTags>& box,
     222             :       const tmpl::type_<Metavariables>& metavariables_v,
     223             :       const TemporalId& /*temporal_id*/) {
     224             :     return points(box, metavariables_v);
     225             :   }
     226             :   template <typename Metavariables, typename DbTags>
     227           0 :   static tnsr::I<DataVector, 3, Frame> points(
     228             :       const db::DataBox<DbTags>& box,
     229             :       const tmpl::type_<Metavariables>& /*meta*/) {
     230             :     return db::get<Tags::AllCoords<Frame>>(box);
     231             :   }
     232             : };
     233             : }  // namespace TargetPoints
     234             : }  // namespace intrp

Generated by: LCOV version 1.14