SpECTRE Documentation Coverage Report
Current view: top level - Domain - BoundaryVariables.hpp Hit Total Coverage
Commit: ecb8a275e1aebab77dcce48a5e098ed4e486ab4b Lines: 1 39 2.6 %
Date: 2026-08-22 01:05:40
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 1.14