SpECTRE Documentation Coverage Report
Current view: top level - Domain - BoundaryVariables.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 2.6 % 39 1
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 <pup.h>
       8              : #include <utility>
       9              : 
      10              : #include "DataStructures/Variables.hpp"
      11              : #include "Domain/Structure/DirectionMap.hpp"
      12              : #include "Utilities/ErrorHandling/Assert.hpp"
      13              : #include "Utilities/Gsl.hpp"
      14              : #include "Utilities/MakeWithValue.hpp"
      15              : 
      16              : /*!
      17              :  * \ingroup DataStructuresGroup
      18              :  * \brief A data structure holding Variables associated with directions.
      19              :  *
      20              :  * This class holds Variables of sizes `points_per_direction`, all
      21              :  * referencing a single memory allocation.  The individual Variables
      22              :  * can be accessed through the `variables()` member.  Access to the
      23              :  * underlying buffer is provided so that the class can, for example,
      24              :  * be used as the evolved variables for an evolution system.
      25              :  */
      26              : template <size_t Dim, typename Tags>
      27            1 : class BoundaryVariables {
      28              :   static_assert(
      29              :       DirectionMap<Dim, size_t>::hash_is_perfect,
      30              :       "Map must use a perfect hash to ensure consistent data ordering.");
      31              : 
      32              :  public:
      33            0 :   using tags_list = Tags;
      34            0 :   using VariablesType = Variables<tags_list>;
      35            0 :   using Vector = typename VariablesType::vector_type;
      36              : 
      37            0 :   BoundaryVariables() = default;
      38            0 :   BoundaryVariables(BoundaryVariables&& other)
      39              :       : points_per_direction_(std::move(other.points_per_direction_)),
      40              :         buffer_(std::move(other.buffer_)) {
      41              :     other.clear();
      42              :     setup_variables();
      43              :   }
      44            0 :   BoundaryVariables(const BoundaryVariables& other)
      45              :       : points_per_direction_(other.points_per_direction_),
      46              :         buffer_(other.buffer_) {
      47              :     setup_variables();
      48              :   }
      49              : 
      50            0 :   BoundaryVariables& operator=(BoundaryVariables&& other) {
      51              :     if (this == &other) {
      52              :       return *this;
      53              :     }
      54              :     points_per_direction_ = std::move(other.points_per_direction_);
      55              :     buffer_ = std::move(other.buffer_);
      56              :     other.clear();
      57              :     setup_variables();
      58              :     return *this;
      59              :   }
      60            0 :   BoundaryVariables& operator=(const BoundaryVariables& other) {
      61              :     points_per_direction_ = other.points_per_direction_;
      62              :     buffer_ = other.buffer_;
      63              :     setup_variables();
      64              :     return *this;
      65              :   }
      66              : 
      67            0 :   ~BoundaryVariables() = default;
      68              : 
      69            0 :   explicit BoundaryVariables(DirectionMap<Dim, size_t> points_per_direction) {
      70              :     initialize(std::move(points_per_direction));
      71              :   }
      72              : 
      73            0 :   BoundaryVariables(DirectionMap<Dim, size_t> points_per_direction,
      74              :                     const typename Vector::value_type& initial_value) {
      75              :     initialize(std::move(points_per_direction), initial_value);
      76              :   }
      77              : 
      78            0 :   void initialize(DirectionMap<Dim, size_t> points_per_direction) {
      79              :     points_per_direction_ = std::move(points_per_direction);
      80              :     buffer_ = Vector(buffer_size());
      81              :     setup_variables();
      82              :   }
      83              : 
      84            0 :   void initialize(DirectionMap<Dim, size_t> points_per_direction,
      85              :                   const typename Vector::value_type& initial_value) {
      86              :     points_per_direction_ = std::move(points_per_direction);
      87              :     buffer_ = Vector(buffer_size(), initial_value);
      88              :     setup_variables();
      89              :   }
      90              : 
      91            0 :   size_t size() const { return buffer_.size(); }
      92            0 :   bool empty() const { return buffer_.size() == 0; }
      93              : 
      94            0 :   void clear() {
      95              :     points_per_direction_.clear();
      96              :     buffer_.clear();
      97              :     variables_.clear();
      98              :   }
      99              : 
     100            0 :   const DirectionMap<Dim, size_t>& points_per_direction() const {
     101              :     return points_per_direction_;
     102              :   }
     103              : 
     104            0 :   const Vector& buffer() const {
     105              :     check_pointers();
     106              :     return buffer_;
     107              :   }
     108            0 :   Vector& buffer() {
     109              :     check_pointers();
     110              :     return buffer_;
     111              :   }
     112              : 
     113            0 :   DirectionMap<Dim, VariablesType>& variables() {
     114              :     check_pointers();
     115              :     return variables_;
     116              :   }
     117            0 :   const DirectionMap<Dim, VariablesType>& variables() const {
     118              :     check_pointers();
     119              :     return variables_;
     120              :   }
     121              : 
     122            0 :   void pup(PUP::er& p) {
     123              :     p | points_per_direction_;
     124              :     p | buffer_;
     125              :     if (p.isUnpacking()) {
     126              :       setup_variables();
     127              :     }
     128              :   }
     129              : 
     130              :  private:
     131            0 :   size_t buffer_size() const {
     132              :     size_t num_points = 0;
     133              :     for (const auto& [direction, points] : points_per_direction_) {
     134              :       num_points += points;
     135              :     }
     136              :     return num_points * VariablesType::number_of_independent_components;
     137              :   }
     138              : 
     139            0 :   void setup_variables() {
     140              :     variables_.clear();
     141              :     size_t offset = 0;
     142              :     for (const auto& [direction, points] : points_per_direction_) {
     143              :       const size_t vars_size =
     144              :           points * VariablesType::number_of_independent_components;
     145              :       variables_.emplace(direction,
     146              :                          VariablesType(buffer_.data() + offset, vars_size));
     147              :       offset += vars_size;
     148              :     }
     149              :   }
     150              : 
     151            0 :   void check_pointers() const {
     152              : #ifdef SPECTRE_DEBUG
     153              :     if (points_per_direction_.empty()) {
     154              :       return;
     155              :     }
     156              :     ASSERT(buffer_.size() == buffer_size(),
     157              :            "Buffer has been manually resized.  Have "
     158              :                << buffer_.size() << " entries but should be " << buffer_size());
     159              :     const auto first_direction = points_per_direction_.begin()->first;
     160              :     ASSERT(variables_.at(first_direction).data() == buffer_.data(),
     161              :            "Pointer mismatch.  Data buffers have been replaced.");
     162              : #endif
     163              :   }
     164              : 
     165            0 :   DirectionMap<Dim, size_t> points_per_direction_{};
     166            0 :   Vector buffer_{};
     167            0 :   DirectionMap<Dim, VariablesType> variables_{};
     168              : };
     169              : 
     170              : template <size_t Dim, typename Tags>
     171            0 : bool operator==(const BoundaryVariables<Dim, Tags>& a,
     172              :                 const BoundaryVariables<Dim, Tags>& b) {
     173              :   return a.points_per_direction() == b.points_per_direction() and
     174              :          a.buffer() == b.buffer();
     175              : }
     176              : 
     177              : template <size_t Dim, typename Tags>
     178            0 : bool operator!=(const BoundaryVariables<Dim, Tags>& a,
     179              :                 const BoundaryVariables<Dim, Tags>& b) {
     180              :   return not(a == b);
     181              : }
     182              : 
     183              : template <size_t Dim, typename Tags>
     184            0 : auto make_math_wrapper(
     185              :     const gsl::not_null<BoundaryVariables<Dim, Tags>*> data) {
     186              :   return make_math_wrapper(&data->buffer());
     187              : }
     188              : 
     189              : template <size_t Dim, typename Tags>
     190            0 : auto make_math_wrapper(const BoundaryVariables<Dim, Tags>& data) {
     191              :   return make_math_wrapper(data.buffer());
     192              : }
     193              : 
     194              : template <size_t Dim, typename Tags>
     195            0 : auto into_math_wrapper_type(BoundaryVariables<Dim, Tags>&& data) {
     196              :   auto result = into_math_wrapper_type(std::move(data.buffer()));
     197              :   data.clear();
     198              :   return result;
     199              : }
     200              : 
     201              : // We can't set the size from an arbitrary object, but we can copy
     202              : // sizes from one BoundaryVariables to another.
     203              : template <size_t Dim, typename Tags1, typename Tags2>
     204            0 : struct MakeWithValueImpls::MakeWithValueImpl<BoundaryVariables<Dim, Tags1>,
     205              :                                              BoundaryVariables<Dim, Tags2>> {
     206              :   template <typename ValueType>
     207            0 :   static BoundaryVariables<Dim, Tags1> apply(
     208              :       const BoundaryVariables<Dim, Tags2>& input, const ValueType value) {
     209              :     return {input.points_per_direction(), value};
     210              :   }
     211              : };
     212              : 
     213              : template <size_t Dim, typename Tags1, typename Tags2>
     214            0 : void set_number_of_grid_points(
     215              :     const gsl::not_null<BoundaryVariables<Dim, Tags1>*> result,
     216              :     const BoundaryVariables<Dim, Tags2>& pattern) {
     217              :   if (UNLIKELY(result->points_per_direction() !=
     218              :                pattern.points_per_direction())) {
     219              :     *result = BoundaryVariables<Dim, Tags1>(pattern.points_per_direction());
     220              :   }
     221              : }
     222              : 
     223              : template <size_t Dim, typename Tags>
     224            0 : bool contains_allocations(const BoundaryVariables<Dim, Tags>& value) {
     225              :   return contains_allocations(value.buffer());
     226              : }
        

Generated by: LCOV version 2.0-1