SpECTRE Documentation Coverage Report
Current view: top level - DataStructures - SliceVariables.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 75.0 % 4 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 <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 2.0-1