SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/Interpolation/Actions - InterpolatorReceivePoints.hpp Hit Total Coverage
Commit: 1f2210958b4f38fdc0400907ee7c6d5af5111418 Lines: 1 3 33.3 %
Date: 2025-12-05 05:03:31
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 <utility>
       9             : #include <vector>
      10             : 
      11             : #include "DataStructures/DataBox/DataBox.hpp"
      12             : #include "DataStructures/Tensor/TypeAliases.hpp"
      13             : #include "Domain/BlockLogicalCoordinates.hpp"
      14             : #include "IO/Logging/Verbosity.hpp"
      15             : #include "Parallel/Printf/Printf.hpp"
      16             : #include "ParallelAlgorithms/Interpolation/Actions/TryToInterpolate.hpp"
      17             : #include "ParallelAlgorithms/Interpolation/InterpolatedVars.hpp"
      18             : #include "ParallelAlgorithms/Interpolation/Tags.hpp"
      19             : #include "Utilities/Algorithm.hpp"
      20             : #include "Utilities/ErrorHandling/Error.hpp"
      21             : #include "Utilities/Gsl.hpp"
      22             : #include "Utilities/PrettyType.hpp"
      23             : #include "Utilities/Requires.hpp"
      24             : #include "Utilities/TaggedTuple.hpp"
      25             : 
      26             : /// \cond
      27             : 
      28             : namespace Parallel {
      29             : template <typename Metavariables>
      30             : class GlobalCache;
      31             : }  // namespace Parallel
      32             : namespace domain {
      33             : class BlockId;
      34             : }  // namespace domain
      35             : template <typename IdType, typename DataType>
      36             : class IdPair;
      37             : namespace intrp {
      38             : namespace Tags {
      39             : template <size_t Dim>
      40             : struct NumberOfElements;
      41             : template <typename Metavariables>
      42             : struct InterpolatedVarsHolders;
      43             : }  // namespace Tags
      44             : }  // namespace intrp
      45             : /// \endcond
      46             : 
      47             : namespace intrp {
      48             : namespace Actions {
      49             : 
      50             : /// \ingroup ActionsGroup
      51             : /// \brief Receives target points from an InterpolationTarget.
      52             : ///
      53             : /// After receiving the points, interpolates volume data onto them
      54             : /// if it already has all the volume data.
      55             : ///
      56             : /// The `iteration` parameter is used to order receives of
      57             : /// `block_logical_coords`. Because of the asynchronous nature of communication,
      58             : /// it is possible that a more recent set of points arrives before an older set.
      59             : /// It is assumed that if a more recent set arrives, then the old set is no
      60             : /// longer needed. This `iteration` parameter tags each communication as "more
      61             : /// recent" or "older" so if we receive an older set of points after a more
      62             : /// recent set, we don't overwrite the more recent set.
      63             : ///
      64             : /// \note If the interpolator receives points with the same iteration, an ERROR
      65             : /// will occur.
      66             : ///
      67             : /// Uses:
      68             : /// - Databox:
      69             : ///   - `Tags::NumberOfElements`
      70             : ///   - `Tags::InterpolatedVarsHolders<Metavariables>`
      71             : ///   - `Tags::VolumeVarsInfo<Metavariables>`
      72             : ///
      73             : /// DataBox changes:
      74             : /// - Adds: nothing
      75             : /// - Removes: nothing
      76             : /// - Modifies:
      77             : ///   - `Tags::InterpolatedVarsHolders<Metavariables>`
      78             : ///
      79             : /// For requirements on InterpolationTargetTag, see InterpolationTarget
      80             : template <typename InterpolationTargetTag>
      81           1 : struct ReceivePoints {
      82             :   template <typename ParallelComponent, typename DbTags, typename Metavariables,
      83             :             typename ArrayIndex, size_t VolumeDim>
      84           0 :   static void apply(
      85             :       db::DataBox<DbTags>& box, Parallel::GlobalCache<Metavariables>& cache,
      86             :       const ArrayIndex& /*array_index*/,
      87             :       const typename InterpolationTargetTag::temporal_id::type& temporal_id,
      88             :       std::vector<BlockLogicalCoords<VolumeDim>>&& block_logical_coords,
      89             :       const size_t iteration = 0_st,
      90             :       const size_t reinterpolation_iteration = 0_st) {
      91             :     const auto& finished_ids =
      92             :         get<intrp::Vars::HolderTag<InterpolationTargetTag, Metavariables>>(
      93             :             get<intrp::Tags::InterpolatedVarsHolders<Metavariables>>(box))
      94             :             .temporal_ids_when_data_has_been_interpolated;
      95             : 
      96             :     // If we are receiving points from a target after the interpolation has
      97             :     // finished, we discard the points and don't do anything
      98             :     if (alg::found(finished_ids, temporal_id)) {
      99             :       return;
     100             :     }
     101             : 
     102             :     db::mutate<intrp::Tags::InterpolatedVarsHolders<Metavariables>>(
     103             :         [&temporal_id, &block_logical_coords, &iteration,
     104             :          &reinterpolation_iteration](
     105             :             const gsl::not_null<typename intrp::Tags::InterpolatedVarsHolders<
     106             :                 Metavariables>::type*>
     107             :                 vars_holders) {
     108             :           auto& vars_infos =
     109             :               get<intrp::Vars::HolderTag<InterpolationTargetTag,
     110             :                                          Metavariables>>(*vars_holders)
     111             :                   .infos;
     112             : 
     113             :           // Add the new target interpolation points at this temporal_id. There
     114             :           // are three conditions that allow us to overwrite the current target
     115             :           // points:
     116             :           //
     117             :           //  1. There are no current target points at the temporal_id, OR
     118             :           //  2. There are target points already at this temporal_id, but the
     119             :           //     iteration of the new target points is greater than the
     120             :           //     iteration of the current target points (even if we are retrying
     121             :           //     interpolation).
     122             :           //  3. There are target points already at this temporal_id, but the
     123             :           //     iteration of the new target points is equal to the iteration of
     124             :           //     the current target points, and the incoming reinterpolation
     125             :           //     iteration is greater than the current reinterpolation
     126             :           //     iteration.
     127             :           //
     128             :           // If we already have target points and the iteration of the new
     129             :           // points is less than or equal to the iteration of the current target
     130             :           // points (and we aren't retrying an interpolation with new points),
     131             :           // then we ignore the new points. The new points are outdated and we
     132             :           // definitely didn't have any of the new target points in our element
     133             :           // by the fact that we have already received the next iteration of
     134             :           // points.
     135             :           //
     136             :           // However, it occasionally happens where interpolation fails at some
     137             :           // iteration, and the horizon finder is able to send a new set of
     138             :           // points to try for the same iteration.
     139             :           //
     140             :           // Whenever we overwrite the target points, we also empty the
     141             :           // `interpolation_is_done_for_these_elements` (by virtue of a default
     142             :           // constructed `intrp::Vars::Info`) so that we always check every
     143             :           // element for this new set of target points.
     144             :           if (vars_infos.count(temporal_id) == 0 or
     145             :               vars_infos.at(temporal_id).iteration < iteration or
     146             :               (vars_infos.at(temporal_id).iteration == iteration and
     147             :                vars_infos.at(temporal_id).reinterpolation_iteration <
     148             :                    reinterpolation_iteration)) {
     149             :             vars_infos.insert_or_assign(
     150             :                 temporal_id,
     151             :                 intrp::Vars::Info<VolumeDim, typename InterpolationTargetTag::
     152             :                                                  vars_to_interpolate_to_target>{
     153             :                     std::move(block_logical_coords), iteration});
     154             :           } else if (vars_infos.at(temporal_id).iteration == iteration and
     155             :                      vars_infos.at(temporal_id).reinterpolation_iteration ==
     156             :                          reinterpolation_iteration) {
     157             :             ERROR("Interpolator received target points at iteration "
     158             :                   << iteration << " (and reinterpolation iteration "
     159             :                   << reinterpolation_iteration << ") twice.");
     160             :           }
     161             :         },
     162             :         make_not_null(&box));
     163             : 
     164             :     if (Parallel::get<intrp::Tags::Verbosity>(cache) >= ::Verbosity::Debug) {
     165             :       Parallel::printf("%s, received points.\n",
     166             :                        InterpolationTarget_detail::interpolator_output_prefix<
     167             :                            InterpolationTargetTag>(temporal_id));
     168             :     }
     169             : 
     170             :     try_to_interpolate<InterpolationTargetTag>(
     171             :         make_not_null(&box), make_not_null(&cache), temporal_id);
     172             :   }
     173             : };
     174             : 
     175             : }  // namespace Actions
     176             : }  // namespace intrp

Generated by: LCOV version 1.14