SpECTRE Documentation Coverage Report
Current view: top level - DataStructures - SliceVariables.hpp Hit Total Coverage
Commit: aabde07399ba7837e5db64eedfd0a21f31f96922 Lines: 3 4 75.0 %
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 <cstddef>
       7             : #include <ostream>
       8             : 
       9             : #include "DataStructures/Index.hpp"
      10             : #include "DataStructures/SliceIterator.hpp"
      11             : #include "DataStructures/Variables.hpp"
      12             : #include "Utilities/ErrorHandling/Assert.hpp"
      13             : #include "Utilities/Gsl.hpp"
      14             : #include "Utilities/TMPL.hpp"
      15             : 
      16             : /// @{
      17             : /*!
      18             :  * \ingroup DataStructuresGroup
      19             :  * \brief Slices the data within `vars` to a codimension 1 slice. The
      20             :  * slice has a constant logical coordinate in direction `sliced_dim`,
      21             :  * slicing the volume at `fixed_index` in that dimension.  For
      22             :  * example, to get the lower boundary of `sliced_dim`, pass `0` for
      23             :  * `fixed_index`; to get the upper boundary, pass
      24             :  * `extents[sliced_dim] - 1`.
      25             :  *
      26             :  * \see add_slice_to_data
      27             :  *
      28             :  * Returns Variables class sliced to a hypersurface.
      29             :  */
      30             : template <std::size_t VolumeDim, typename TagsList>
      31           1 : void data_on_slice(const gsl::not_null<Variables<TagsList>*> interface_vars,
      32             :                    const Variables<TagsList>& vars,
      33             :                    const Index<VolumeDim>& element_extents,
      34             :                    const size_t sliced_dim, const size_t fixed_index) {
      35             :   const size_t interface_grid_points =
      36             :       element_extents.slice_away(sliced_dim).product();
      37             :   const size_t volume_grid_points = vars.number_of_grid_points();
      38             :   constexpr const size_t number_of_independent_components =
      39             :       Variables<TagsList>::number_of_independent_components;
      40             : 
      41             :   if (interface_vars->number_of_grid_points() != interface_grid_points) {
      42             :     *interface_vars = Variables<TagsList>(interface_grid_points);
      43             :   }
      44             :   using value_type = typename Variables<TagsList>::value_type;
      45             :   const value_type* vars_data = vars.data();
      46             :   value_type* interface_vars_data = interface_vars->data();
      47             :   for (SliceIterator si(element_extents, sliced_dim, fixed_index); si; ++si) {
      48             :     for (size_t i = 0; i < number_of_independent_components; ++i) {
      49             :       // clang-tidy: do not use pointer arithmetic
      50             :       interface_vars_data[si.slice_offset() +                      // NOLINT
      51             :                           i * interface_grid_points] =             // NOLINT
      52             :           vars_data[si.volume_offset() + i * volume_grid_points];  // NOLINT
      53             :     }
      54             :   }
      55             : }
      56             : 
      57             : template <std::size_t VolumeDim, typename TagsList>
      58           1 : Variables<TagsList> data_on_slice(const Variables<TagsList>& vars,
      59             :                                   const Index<VolumeDim>& element_extents,
      60             :                                   const size_t sliced_dim,
      61             :                                   const size_t fixed_index) {
      62             :   Variables<TagsList> interface_vars(
      63             :       element_extents.slice_away(sliced_dim).product());
      64             :   data_on_slice(make_not_null(&interface_vars), vars, element_extents,
      65             :                 sliced_dim, fixed_index);
      66             :   return interface_vars;
      67             : }
      68             : /// @}
      69             : 
      70             : /*!
      71             :  * \ingroup DataStructuresGroup
      72             :  * \brief Adds data on a codimension 1 slice to a volume quantity. The
      73             :  * slice has a constant logical coordinate in direction `sliced_dim`,
      74             :  * slicing the volume at `fixed_index` in that dimension.  For
      75             :  * example, to add to the lower boundary of `sliced_dim`, pass `0` for
      76             :  * `fixed_index`; to add to the upper boundary, pass
      77             :  * `extents[sliced_dim] - 1`.
      78             :  *
      79             :  * \see data_on_slice
      80             :  */
      81             : template <std::size_t VolumeDim, typename... VolumeTags, typename... SliceTags>
      82           1 : void add_slice_to_data(
      83             :     const gsl::not_null<Variables<tmpl::list<VolumeTags...>>*> volume_vars,
      84             :     const Variables<tmpl::list<SliceTags...>>& vars_on_slice,
      85             :     const Index<VolumeDim>& extents, const size_t sliced_dim,
      86             :     const size_t fixed_index) {
      87             :   static_assert((std::is_same_v<db::remove_all_prefixes<VolumeTags>,
      88             :                                 db::remove_all_prefixes<SliceTags>> and
      89             :                  ...));
      90             :   static_assert(
      91             :       (std::is_same_v<typename VolumeTags::type, typename SliceTags::type> and
      92             :        ...),
      93             :       "Tensor types do not match.");
      94             :   constexpr const size_t number_of_independent_components =
      95             :       Variables<tmpl::list<VolumeTags...>>::number_of_independent_components;
      96             :   const size_t volume_grid_points = extents.product();
      97             :   const size_t slice_grid_points = extents.slice_away(sliced_dim).product();
      98             :   ASSERT(volume_vars->number_of_grid_points() == volume_grid_points,
      99             :          "volume_vars has wrong number of grid points.  Expected "
     100             :              << volume_grid_points << ", got "
     101             :              << volume_vars->number_of_grid_points());
     102             :   ASSERT(vars_on_slice.number_of_grid_points() == slice_grid_points,
     103             :          "vars_on_slice has wrong number of grid points.  Expected "
     104             :              << slice_grid_points << ", got "
     105             :              << vars_on_slice.number_of_grid_points());
     106             :   using value_type = typename Variables<tmpl::list<VolumeTags...>>::value_type;
     107             :   value_type* const volume_data = volume_vars->data();
     108             :   const value_type* const slice_data = vars_on_slice.data();
     109             :   for (SliceIterator si(extents, sliced_dim, fixed_index); si; ++si) {
     110             :     for (size_t i = 0; i < number_of_independent_components; ++i) {
     111             :       // clang-tidy: do not use pointer arithmetic
     112             :       volume_data[si.volume_offset() + i * volume_grid_points] +=  // NOLINT
     113             :           slice_data[si.slice_offset() + i * slice_grid_points];   // NOLINT
     114             :     }
     115             :   }
     116             : }

Generated by: LCOV version 1.14