SpECTRE Documentation Coverage Report
Current view: top level - Evolution/DgSubcell - NeighborRdmpAndVolumeData.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 66.7 % 3 2
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 <algorithm>
       7              : #include <cstddef>
       8              : #include <optional>
       9              : 
      10              : #include "DataStructures/DataVector.hpp"
      11              : #include "Domain/Structure/DirectionalId.hpp"
      12              : #include "Domain/Structure/DirectionalIdMap.hpp"
      13              : #include "Domain/Structure/ElementId.hpp"
      14              : #include "Evolution/DgSubcell/GhostData.hpp"
      15              : #include "Evolution/DgSubcell/RdmpTciData.hpp"
      16              : #include "NumericalAlgorithms/Interpolation/IrregularInterpolant.hpp"
      17              : #include "NumericalAlgorithms/Spectral/ParityFromSymmetry.hpp"
      18              : #include "Utilities/Gsl.hpp"
      19              : #include "Utilities/TMPL.hpp"
      20              : 
      21              : /// \cond
      22              : template <size_t Dim>
      23              : class Element;
      24              : template <size_t Dim>
      25              : class Mesh;
      26              : /// \endcond
      27              : 
      28              : namespace evolution::dg::subcell::detail {
      29              : /*!
      30              :  * \brief Implementation of insert_or_update_neighbor_volume_data, accepting
      31              :  * parity information as runtime arguments so the caller can be a thin
      32              :  * template wrapper without needing VolumeFields in the function body.
      33              :  *
      34              :  * The impl-unique parameters are specifically for a ZernikeB1 basis:
      35              :  * - **`parity_list`** Run-length encoded even/odd parity of each component
      36              :  * (ignored when Dim != 3 or when the mesh is not ZernikeB1).
      37              :  * - **`num_even`** Number of even-parity components (0 when unused).
      38              :  * - **`num_odd`** Number of odd-parity components (0 when unused).
      39              :  */
      40              : template <bool InsertIntoMap, size_t Dim>
      41              : void insert_or_update_neighbor_volume_data_impl(
      42              :     gsl::not_null<DirectionalIdMap<Dim, GhostData>*> ghost_data_ptr,
      43              :     const DataVector& neighbor_subcell_data,
      44              :     size_t number_of_rdmp_vars_in_buffer,
      45              :     const DirectionalId<Dim>& directional_element_id,
      46              :     const Mesh<Dim>& neighbor_mesh, const Element<Dim>& element,
      47              :     const Mesh<Dim>& subcell_mesh, size_t number_of_ghost_zones,
      48              :     const DirectionalIdMap<Dim, std::optional<intrp::Irregular<Dim>>>&
      49              :         neighbor_dg_to_fd_interpolants,
      50              :     gsl::span<const size_t> parity_list, size_t num_even, size_t num_odd);
      51              : }  // namespace evolution::dg::subcell::detail
      52              : 
      53              : namespace evolution::dg::subcell {
      54              : /*!
      55              :  * \brief Check whether `neighbor_subcell_data` is FD or DG, and either insert
      56              :  * or copy into `ghost_data_ptr` the FD data (projecting if
      57              :  * `neighbor_subcell_data` is DG data).
      58              :  *
      59              :  * This is intended to be used during a rollback from DG to make sure neighbor
      60              :  * data is projected to the FD grid.
      61              :  *
      62              :  * The `VolumeFields` meta parameter is the tag list (a `tmpl::list`) of the
      63              :  * packed ghost DataVector so that per-component parity information can be
      64              :  * deduced for ZernikeB1 meshes.
      65              :  */
      66              : template <bool InsertIntoMap, size_t Dim, typename VolumeFields>
      67            1 : void insert_or_update_neighbor_volume_data(
      68              :     const gsl::not_null<DirectionalIdMap<Dim, GhostData>*> ghost_data_ptr,
      69              :     const DataVector& neighbor_subcell_data,
      70              :     const size_t number_of_rdmp_vars_in_buffer,
      71              :     const DirectionalId<Dim>& directional_element_id,
      72              :     const Mesh<Dim>& neighbor_mesh, const Element<Dim>& element,
      73              :     const Mesh<Dim>& subcell_mesh, const size_t number_of_ghost_zones,
      74              :     const DirectionalIdMap<Dim, std::optional<intrp::Irregular<Dim>>>&
      75              :         neighbor_dg_to_fd_interpolants,
      76              :     VolumeFields /*meta*/) {
      77              :   if constexpr (Dim == 3) {
      78              :     const auto parity_info = Spectral::compute_parity_list<VolumeFields>();
      79              :     const auto& parity_list = std::get<0>(parity_info);
      80              :     detail::insert_or_update_neighbor_volume_data_impl<InsertIntoMap, Dim>(
      81              :         ghost_data_ptr, neighbor_subcell_data, number_of_rdmp_vars_in_buffer,
      82              :         directional_element_id, neighbor_mesh, element, subcell_mesh,
      83              :         number_of_ghost_zones, neighbor_dg_to_fd_interpolants,
      84              :         gsl::span<const size_t>{parity_list.data(), parity_list.size()},
      85              :         std::get<1>(parity_info), std::get<2>(parity_info));
      86              :   } else {
      87              :     detail::insert_or_update_neighbor_volume_data_impl<InsertIntoMap, Dim>(
      88              :         ghost_data_ptr, neighbor_subcell_data, number_of_rdmp_vars_in_buffer,
      89              :         directional_element_id, neighbor_mesh, element, subcell_mesh,
      90              :         number_of_ghost_zones, neighbor_dg_to_fd_interpolants, {}, 0, 0);
      91              :   }
      92              : }
      93              : 
      94              : /*!
      95              :  * \brief Check whether the neighbor sent is DG volume or FD ghost data, and
      96              :  * orient project DG volume data if necessary.
      97              :  *
      98              :  * This is intended to be used by the `ReceiveDataForReconstruction` action.
      99              :  *
     100              :  * The `VolumeFields` parameter is the tag list (a `tmpl::list`) of the
     101              :  * packed ghost DataVector so that per-component parity information can be
     102              :  * deduced for ZernikeB1 meshes.
     103              :  */
     104              : template <size_t Dim, typename VolumeFields>
     105            1 : void insert_neighbor_rdmp_and_volume_data(
     106              :     const gsl::not_null<RdmpTciData*> rdmp_tci_data_ptr,
     107              :     const gsl::not_null<DirectionalIdMap<Dim, GhostData>*> ghost_data_ptr,
     108              :     const DataVector& received_neighbor_subcell_data,
     109              :     const size_t number_of_rdmp_vars,
     110              :     const DirectionalId<Dim>& directional_element_id,
     111              :     const Mesh<Dim>& neighbor_mesh, const Element<Dim>& element,
     112              :     const Mesh<Dim>& subcell_mesh, const size_t number_of_ghost_zones,
     113              :     const DirectionalIdMap<Dim, std::optional<intrp::Irregular<Dim>>>&
     114              :         neighbor_dg_to_fd_interpolants,
     115              :     VolumeFields volume_fields) {
     116              :   ASSERT(received_neighbor_subcell_data.size() != 0,
     117              :          "received_neighbor_subcell_data must be non-empty");
     118              :   // Note: since we determine the starting point of the RDMP vars
     119              :   // from how many RDMP vars there are, we don't need to account for
     120              :   // the mesh the neighbor sent (DG or FD)
     121              :   const size_t max_offset =
     122              :       received_neighbor_subcell_data.size() - 2 * number_of_rdmp_vars;
     123              :   const size_t min_offset =
     124              :       received_neighbor_subcell_data.size() - number_of_rdmp_vars;
     125              :   for (size_t var_index = 0; var_index < number_of_rdmp_vars; ++var_index) {
     126              :     rdmp_tci_data_ptr->max_variables_values[var_index] =
     127              :         std::max(rdmp_tci_data_ptr->max_variables_values[var_index],
     128              :                  received_neighbor_subcell_data[max_offset + var_index]);
     129              :     rdmp_tci_data_ptr->min_variables_values[var_index] =
     130              :         std::min(rdmp_tci_data_ptr->min_variables_values[var_index],
     131              :                  received_neighbor_subcell_data[min_offset + var_index]);
     132              :   }
     133              :   // Note: it would be good to assert that the neighbor is at the same
     134              :   // refinement level as us, but such a function does not yet exist.
     135              : 
     136              :   insert_or_update_neighbor_volume_data<true>(
     137              :       ghost_data_ptr, received_neighbor_subcell_data, number_of_rdmp_vars,
     138              :       directional_element_id, neighbor_mesh, element, subcell_mesh,
     139              :       number_of_ghost_zones, neighbor_dg_to_fd_interpolants, volume_fields);
     140              : }
     141              : }  // namespace evolution::dg::subcell
        

Generated by: LCOV version 2.0-1