SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/Interpolation/Actions - CleanUpInterpolator.hpp Hit Total Coverage
Commit: 1bd361db2ecec890b34404958975897856517ca1 Lines: 1 3 33.3 %
Date: 2024-05-08 20:10:16
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 <deque>
       9             : 
      10             : #include "DataStructures/DataBox/DataBox.hpp"
      11             : #include "DataStructures/Variables.hpp"
      12             : #include "ParallelAlgorithms/Interpolation/Actions/InterpolatorReceiveVolumeData.hpp"
      13             : #include "Utilities/Algorithm.hpp"
      14             : #include "Utilities/Gsl.hpp"
      15             : #include "Utilities/Requires.hpp"
      16             : #include "Utilities/TMPL.hpp"
      17             : #include "Utilities/TaggedTuple.hpp"
      18             : 
      19             : /// \cond
      20             : // IWYU pragma: no_forward_declare db::DataBox
      21             : namespace Parallel {
      22             : template <typename Metavariables>
      23             : class GlobalCache;
      24             : }  // namespace Parallel
      25             : namespace intrp {
      26             : namespace Tags {
      27             : struct NumberOfElements;
      28             : template <typename Metavariables>
      29             : struct InterpolatedVarsHolders;
      30             : template <typename Metavariables, typename TemporalId>
      31             : struct VolumeVarsInfo;
      32             : }  // namespace Tags
      33             : namespace Vars {
      34             : template <typename InterpolationTargetTag, typename Metavariables>
      35             : struct HolderTag;
      36             : }  // namespace Vars
      37             : }  // namespace intrp
      38             : /// \endcond
      39             : 
      40             : namespace intrp {
      41             : namespace Actions {
      42             : 
      43             : /// \ingroup ActionsGroup
      44             : /// \brief Cleans up stored volume data that is no longer needed.
      45             : ///
      46             : /// Called by InterpolationTargetReceiveVars.
      47             : ///
      48             : /// Uses:
      49             : /// - Databox:
      50             : ///   - `Tags::InterpolatedVarsHolders<Metavariables>`
      51             : ///   - `Tags::VolumeVarsInfo<Metavariables>`
      52             : ///
      53             : /// DataBox changes:
      54             : /// - Adds: nothing
      55             : /// - Removes: nothing
      56             : /// - Modifies:
      57             : ///   - `Tags::InterpolatedVarsHolders<Metavariables>`
      58             : ///   - `Tags::VolumeVarsInfo<Metavariables>`
      59             : ///
      60             : /// For requirements on InterpolationTargetTag, see InterpolationTarget
      61             : template <typename InterpolationTargetTag>
      62           1 : struct CleanUpInterpolator {
      63             :   template <typename ParallelComponent, typename DbTags, typename Metavariables,
      64             :             typename ArrayIndex>
      65           0 :   static void apply(
      66             :       db::DataBox<DbTags>& box,  // HorizonManager's box
      67             :       const Parallel::GlobalCache<Metavariables>& /*cache*/,
      68             :       const ArrayIndex& /*array_index*/,
      69             :       const typename InterpolationTargetTag::temporal_id::type& temporal_id) {
      70             :     // Signal that this InterpolationTarget is done at this time.
      71             :     db::mutate<Tags::InterpolatedVarsHolders<Metavariables>>(
      72             :         [&temporal_id](
      73             :             const gsl::not_null<
      74             :                 typename Tags::InterpolatedVarsHolders<Metavariables>::type*>
      75             :                 holders) {
      76             :           get<Vars::HolderTag<InterpolationTargetTag, Metavariables>>(*holders)
      77             :               .temporal_ids_when_data_has_been_interpolated.push_back(
      78             :                   temporal_id);
      79             :         },
      80             :         make_not_null(&box));
      81             : 
      82             :     // If we don't need any of the volume data anymore for this
      83             :     // temporal_id, we will remove them.
      84             :     bool this_temporal_id_is_done = true;
      85             :     const auto& holders =
      86             :         db::get<Tags::InterpolatedVarsHolders<Metavariables>>(box);
      87             :     tmpl::for_each<typename Metavariables::interpolation_target_tags>(
      88             :         [&holders, &this_temporal_id_is_done, &temporal_id](auto tag) {
      89             :           using Tag = typename decltype(tag)::type;
      90             :           // Here we decide whether this interpolation target is "done" (i.e. it
      91             :           // does not need to interpolate) at this temporal_id. If it is "done",
      92             :           // then we don't need to store the volume data. Usually "done" means
      93             :           // that it has already done its interpolation at this temporal_id. But
      94             :           // note that if an interpolation target is not using the Interpolator
      95             :           // at all, it is considered "done", because we don't need any volume
      96             :           // data for it and should not store it. Similarly, interpolation
      97             :           // targets whose temporal_id has a different type than TemporalId are
      98             :           // considered "done" because they too do not use the Interpolator and
      99             :           // don't need volume data to be saved.
     100             :           if constexpr (detail::using_interpolator_component_v<Metavariables,
     101             :                                                                Tag> and
     102             :                         std::is_same_v<
     103             :                             typename InterpolationTargetTag::temporal_id,
     104             :                             typename Tag::temporal_id>) {
     105             :             const auto& finished_temporal_ids =
     106             :                 get<Vars::HolderTag<Tag, Metavariables>>(holders)
     107             :                     .temporal_ids_when_data_has_been_interpolated;
     108             :             if (not alg::found(finished_temporal_ids, temporal_id)) {
     109             :               this_temporal_id_is_done = false;
     110             :             }
     111             :           }
     112             :         });
     113             : 
     114             :     // We don't need any more volume data for this temporal_id, so
     115             :     // remove it.  Note that the removal (and the computation of
     116             :     // this_temporal_id_is_done above) loop over only those
     117             :     // InterpolationTargets whose temporal_id type matches
     118             :     // InterpolationTargetTag::temporal_id.
     119             :     if (this_temporal_id_is_done) {
     120             :       db::mutate<Tags::VolumeVarsInfo<
     121             :           Metavariables, typename InterpolationTargetTag::temporal_id>>(
     122             :           [&temporal_id](
     123             :               const gsl::not_null<typename Tags::VolumeVarsInfo<
     124             :                   Metavariables,
     125             :                   typename InterpolationTargetTag::temporal_id>::type*>
     126             :                   volume_vars_info) { volume_vars_info->erase(temporal_id); },
     127             :           make_not_null(&box));
     128             : 
     129             :       // Clean up temporal_ids_when_data_has_been_interpolated, if
     130             :       // it is too large.
     131             :       [[maybe_unused]] constexpr size_t finished_temporal_ids_max_size = 1000;
     132             : 
     133             :       db::mutate<Tags::InterpolatedVarsHolders<Metavariables>>(
     134             :           [](const gsl::not_null<
     135             :               typename Tags::InterpolatedVarsHolders<Metavariables>::type*>
     136             :                  holders_l) {
     137             :             tmpl::for_each<typename Metavariables::interpolation_target_tags>(
     138             :                 [&](auto tag) {
     139             :                   using Tag = typename decltype(tag)::type;
     140             :                   if constexpr (std::is_same_v<typename InterpolationTargetTag::
     141             :                                                    temporal_id,
     142             :                                                typename Tag::temporal_id>) {
     143             :                     auto& finished_temporal_ids =
     144             :                         get<Vars::HolderTag<Tag, Metavariables>>(*holders_l)
     145             :                             .temporal_ids_when_data_has_been_interpolated;
     146             :                     if (finished_temporal_ids.size() >
     147             :                         finished_temporal_ids_max_size) {
     148             :                       const size_t num_to_remove =
     149             :                           finished_temporal_ids.size() -
     150             :                           finished_temporal_ids_max_size;
     151             :                       for (size_t i = 0; i < num_to_remove; ++i) {
     152             :                         // All the new temporal_ids are added with push_back,
     153             :                         // so we remove the oldest ones by using pop_front.
     154             :                         finished_temporal_ids.pop_front();
     155             :                       }
     156             :                     }
     157             :                   }
     158             :                 });
     159             :           },
     160             :           make_not_null(&box));
     161             :     }
     162             :   }
     163             : };
     164             : }  // namespace Actions
     165             : }  // namespace intrp

Generated by: LCOV version 1.14