SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/ApparentHorizonFinder - Storage.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 42.9 % 56 24
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 <optional>
       8              : #include <pup.h>
       9              : #include <set>
      10              : #include <string>
      11              : #include <unordered_map>
      12              : #include <unordered_set>
      13              : #include <vector>
      14              : 
      15              : #include "DataStructures/DataVector.hpp"
      16              : #include "DataStructures/LinkedMessageId.hpp"
      17              : #include "DataStructures/Tensor/Tensor.hpp"
      18              : #include "DataStructures/Variables.hpp"
      19              : #include "Domain/BlockLogicalCoordinates.hpp"
      20              : #include "Domain/Structure/ElementId.hpp"
      21              : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
      22              : #include "NumericalAlgorithms/Strahlkorper/Strahlkorper.hpp"
      23              : #include "Parallel/MultiReaderSpinlock.hpp"
      24              : #include "ParallelAlgorithms/ApparentHorizonFinder/Destination.hpp"
      25              : #include "ParallelAlgorithms/ApparentHorizonFinder/FastFlow.hpp"
      26              : #include "ParallelAlgorithms/ApparentHorizonFinder/HorizonAliases.hpp"
      27              : 
      28            0 : namespace ah::Storage {
      29              : /*!
      30              :  * \brief Holds the `ah::source_vars`, mesh, and other variables on the horizon
      31              :  * finder for a given element.
      32              :  */
      33              : template <typename Fr>
      34            1 : struct VolumeVariables {
      35              :   /*!
      36              :    * \brief The mesh that corresponds to the volume vars.
      37              :    */
      38            1 :   Mesh<3> mesh;
      39              : 
      40              :   /*!
      41              :    * \brief A `Variables` of the tensors in the volume that we need to
      42              :    * interpolate onto the horizon.
      43              :    */
      44              :   Variables<ah::vars_to_interpolate_to_target<3, Fr>>
      45            1 :       vars_to_interpolate_to_target{};
      46              : 
      47              :   // NOLINTNEXTLINE(google-runtime-references)
      48            0 :   void pup(PUP::er& p);
      49              : };
      50              : 
      51              : template <typename Fr>
      52            0 : bool operator==(const VolumeVariables<Fr>& lhs, const VolumeVariables<Fr>& rhs);
      53              : template <typename Fr>
      54            0 : bool operator!=(const VolumeVariables<Fr>& lhs, const VolumeVariables<Fr>& rhs);
      55              : 
      56              : /*!
      57              :  * \brief Holds the `ylm::Strahlkorper` and associated quantities for a single
      58              :  * `FastFlow` iteration.
      59              :  */
      60              : template <typename Fr>
      61            1 : struct Iteration {
      62              :   /*!
      63              :    * \brief The surface for this iteration
      64              :    */
      65            1 :   ylm::Strahlkorper<Fr> strahlkorper;
      66              :   /*!
      67              :    *  \brief Holds the list of all points (in block logical coordinates) that
      68              :    *  need to be interpolated onto.
      69              :    *
      70              :    * \details If an element of the vector is `std::nullopt`, then that point is
      71              :    * outside the domain.
      72              :    */
      73            1 :   std::optional<std::vector<BlockLogicalCoords<3>>> block_coord_holders;
      74              :   /*!
      75              :    * \brief Holds the interpolated `Variables` on the points in
      76              :    * `block_coord_holders`.
      77              :    *
      78              :    * \details The grid points inside are indexed according to
      79              :    * `block_coord_holders`.
      80              :    */
      81            1 :   Variables<ah::vars_to_interpolate_to_target<3, Fr>> interpolated_vars{};
      82              :   /*!
      83              :    * \brief Keeps track of the indices in `interpolated_vars` that have
      84              :    * already been interpolated to.
      85              :    */
      86            1 :   std::vector<bool> indices_interpolated_to_thus_far{};
      87              :   /*!
      88              :    * \brief Holds the element IDs of all elements that intersect with the
      89              :    * current iteration surface. Used to determine which elements will send
      90              :    * data for the next horizon find.
      91              :    */
      92            1 :   std::unordered_set<ElementId<3>> intersecting_element_ids{};
      93              :   /*!
      94              :    * \brief Offsets of newly interpolated points in the overall tensor (used as
      95              :    * memory buffer)
      96              :    */
      97            1 :   std::vector<size_t> offsets_of_newly_interpolated_points{};
      98              :   /*!
      99              :    * \brief Logical coordinates of newly interpolated points (used as memory
     100              :    * buffer)
     101              :    *
     102              :    * These `std::vector`s are used to reserve memory and then append points to
     103              :    * them as we find them in an element. The memory is reused for each element.
     104              :    * Then, a non-owning DataVector is created by pointing into this memory.
     105              :    * That's why this is a `std::array` of `std::vector`s, not vice versa.
     106              :    */
     107              :   std::array<std::vector<double>, 3>
     108            1 :       x_element_logical_of_newly_interpolated_points{};
     109              :   /*!
     110              :    * \brief Buffer for newly interpolated variables (used as memory buffer)
     111              :    */
     112            1 :   std::vector<double> newly_interpolated_vars_buffer{};
     113              : 
     114              :   /*!
     115              :    * \brief How many times we've tried to compute the coordinates for this
     116              :    * iteration.
     117              :    */
     118            1 :   size_t compute_coords_retries = 0;
     119              : 
     120              :   /*!
     121              :    * \brief Whether all points in `interpolated_vars` have been filled.
     122              :    */
     123            1 :   bool interpolation_is_complete() const;
     124              : 
     125            0 :   void reset_for_next_iteration();
     126              : 
     127              :   // NOLINTNEXTLINE(google-runtime-references)
     128            0 :   void pup(PUP::er& p);
     129              : };
     130              : 
     131              : template <typename Fr>
     132            0 : bool operator==(const Iteration<Fr>& lhs, const Iteration<Fr>& rhs);
     133              : template <typename Fr>
     134            0 : bool operator!=(const Iteration<Fr>& lhs, const Iteration<Fr>& rhs);
     135              : 
     136              : /*!
     137              :  * \brief Holds all data necessary for a single horizon find.
     138              :  *
     139              :  * \details This includes volume variables which persist for the entire horizon
     140              :  * find, and also interpolated variables that are updated for each iteration.
     141              :  */
     142              : template <typename Fr>
     143            1 : struct SingleTimeStorage {
     144              :   /*!
     145              :    * \brief Map between `ElementId`s and the volume variables from that element.
     146              :    */
     147            1 :   std::unordered_map<ElementId<3>, VolumeVariables<Fr>> all_volume_variables;
     148              :   /*!
     149              :    * \brief Elements in which we have found points to interpolate to in previous
     150              :    * iterations, to try first before searching all elements.
     151              :    *
     152              :    * This is only a performance optimization. The interpolated values don't
     153              :    * depend on the order because points that lie directly on shared element
     154              :    * boundaries are always assigned to the same element (see
     155              :    * `element_contains`). Otherwise, the interpolated values at these points
     156              :    * would fluctuate with the order in which element data arrives, which can
     157              :    * prevent convergence (see
     158              :    * https://github.com/sxs-collaboration/spectre/issues/3899) and makes
     159              :    * simulations nondeterministic.
     160              :    */
     161            1 :   std::vector<ElementId<3>> element_order{};
     162              :   /*!
     163              :    * \brief The `Iteration` data for the current fast flow iteration.
     164              :    */
     165            1 :   Iteration<Fr> current_iteration;
     166              :   /*!
     167              :    * \brief The previous iteration surface, used if interpolation fails.
     168              :    */
     169            1 :   ylm::Strahlkorper<Fr> previous_iteration_surface;
     170              :   /*!
     171              :    * \brief The `ah::Destination` for this horizon find.
     172              :    */
     173            1 :   Destination destination{};
     174              :   /*!
     175              :    * \brief The dependency that was sent along with the volume data for this
     176              :    * horizon find, if any.
     177              :    *
     178              :    * \details This is copied into `ah::Tags::Dependency` right before the
     179              :    * callbacks for this horizon find are invoked, on success as well as on
     180              :    * failure, so that e.g. `ah::callbacks::SendDependencyToObserverWriter` can
     181              :    * tell the ObserverWriter whether to write or drop the volume data it holds
     182              :    * for this time.
     183              :    */
     184            1 :   std::optional<std::string> dependency = std::nullopt;
     185              :   /*!
     186              :    * \brief Whether we have checked if the functions of time are up to date for
     187              :    * this horizon find.
     188              :    */
     189            1 :   bool time_is_ready = false;
     190              : 
     191              :   // NOLINTNEXTLINE(google-runtime-references)
     192            0 :   void pup(PUP::er& p);
     193              : };
     194              : 
     195              : template <typename Fr>
     196            0 : bool operator==(const SingleTimeStorage<Fr>& lhs,
     197              :                 const SingleTimeStorage<Fr>& rhs);
     198              : template <typename Fr>
     199            0 : bool operator!=(const SingleTimeStorage<Fr>& lhs,
     200              :                 const SingleTimeStorage<Fr>& rhs);
     201              : 
     202              : /*!
     203              :  * \brief The time and final surface for a previous horizon find.
     204              :  */
     205              : template <typename Fr>
     206            1 : struct PreviousSurface {
     207            0 :   PreviousSurface() = default;
     208            0 :   PreviousSurface(const LinkedMessageId<double>& time_in,
     209              :                   ylm::Strahlkorper<Fr> surface_in,
     210              :                   std::unordered_set<ElementId<3>> intersecting_element_ids_in);
     211              : 
     212            0 :   LinkedMessageId<double> time;
     213            0 :   ylm::Strahlkorper<Fr> surface;
     214            0 :   std::unordered_set<ElementId<3>> intersecting_element_ids;
     215              : 
     216              :   // NOLINTNEXTLINE(google-runtime-references)
     217            0 :   void pup(PUP::er& p);
     218              : };
     219              : 
     220              : template <typename Fr>
     221            0 : bool operator==(const PreviousSurface<Fr>& lhs, const PreviousSurface<Fr>& rhs);
     222              : template <typename Fr>
     223            0 : bool operator!=(const PreviousSurface<Fr>& lhs, const PreviousSurface<Fr>& rhs);
     224              : 
     225              : /*!
     226              :  * \brief Holds a previous surface and a lock that protects it.
     227              :  *
     228              :  * \details This is used to store and update a previous surface in the global
     229              :  * cache and allow multiple readers (elements) to access it simultaneously.
     230              :  */
     231              : template <typename Fr>
     232            1 : struct LockedPreviousSurface {
     233            0 :   std::optional<PreviousSurface<Fr>> surface;
     234              :   // Lock is mutable so it can be retrieved from the const global cache and put
     235              :   // in read-lock mode by elements.
     236              :   // NOLINTNEXTLINE(spectre-mutable)
     237            0 :   mutable Parallel::MultiReaderSpinlock lock;
     238              : 
     239            0 :   LockedPreviousSurface();
     240            0 :   explicit LockedPreviousSurface(const PreviousSurface<Fr>& rhs);
     241            0 :   LockedPreviousSurface(const LockedPreviousSurface& rhs);
     242            0 :   LockedPreviousSurface& operator=(const LockedPreviousSurface& rhs);
     243            0 :   LockedPreviousSurface(LockedPreviousSurface&& rhs);
     244            0 :   LockedPreviousSurface& operator=(LockedPreviousSurface&& rhs);
     245            0 :   ~LockedPreviousSurface() = default;
     246              : 
     247              :   // NOLINTNEXTLINE(google-runtime-references)
     248            0 :   void pup(PUP::er& p);
     249              : };
     250              : 
     251              : template <typename Fr>
     252            0 : bool operator==(const LockedPreviousSurface<Fr>& lhs,
     253              :                 const LockedPreviousSurface<Fr>& rhs);
     254              : template <typename Fr>
     255            0 : bool operator!=(const LockedPreviousSurface<Fr>& lhs,
     256              :                 const LockedPreviousSurface<Fr>& rhs);
     257              : 
     258              : }  // namespace ah::Storage
        

Generated by: LCOV version 2.0-1