SpECTRE Documentation Coverage Report
Current view: top level - Evolution/DgSubcell - NeighborRdmpAndVolumeData.hpp Hit Total Coverage
Commit: c3e43f8d41800b0ecefb9d1393f1de1d5a280c8f Lines: 2 3 66.7 %
Date: 2026-07-24 22:09:25
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 1.14