SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/Interpolation/Actions - InterpolatorReceiveVolumeData.hpp Hit Total Coverage
Commit: d0fc80462417e83e5cddfa1b9901bb4a9b6af4d6 Lines: 1 3 33.3 %
Date: 2024-03-29 00:33: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 <algorithm>
       7             : #include <deque>
       8             : #include <type_traits>
       9             : #include <unordered_map>
      10             : #include <utility>
      11             : 
      12             : #include "DataStructures/DataBox/DataBox.hpp"
      13             : #include "DataStructures/Variables.hpp"
      14             : #include "Domain/Tags.hpp"
      15             : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
      16             : #include "Parallel/GlobalCache.hpp"
      17             : #include "ParallelAlgorithms/Interpolation/Actions/TryToInterpolate.hpp"
      18             : #include "ParallelAlgorithms/Interpolation/Tags.hpp"
      19             : #include "Utilities/Algorithm.hpp"
      20             : #include "Utilities/Gsl.hpp"
      21             : #include "Utilities/TMPL.hpp"
      22             : #include "Utilities/TaggedTuple.hpp"
      23             : 
      24             : namespace intrp {
      25             : namespace Actions {
      26             : namespace detail {
      27             : template <typename Metavariables, typename Tag, typename = std::void_t<>>
      28             : struct get_interpolating_component_or_interpolator {
      29             :   using type = Interpolator<Metavariables>;
      30             : };
      31             : template <typename Metavariables, typename Tag>
      32             : struct get_interpolating_component_or_interpolator<
      33             :     Metavariables, Tag,
      34             :     std::void_t<
      35             :         typename Tag::template interpolating_component<Metavariables>>> {
      36             :   using type = typename Tag::template interpolating_component<Metavariables>;
      37             : };
      38             : template <typename Metavariables, typename Tag>
      39             : using get_interpolating_component_or_interpolator_t =
      40             :     typename get_interpolating_component_or_interpolator<Metavariables,
      41             :                                                          Tag>::type;
      42             : 
      43             : template <typename Metavariables, typename Tag>
      44             : constexpr bool using_interpolator_component_v = std::is_same_v<
      45             :     get_interpolating_component_or_interpolator_t<Metavariables, Tag>,
      46             :     Interpolator<Metavariables>>;
      47             : }  // namespace detail
      48             : 
      49             : /// \ingroup ActionsGroup
      50             : /// \brief Adds volume data from an `Element`.
      51             : ///
      52             : /// Attempts to interpolate if it already has received target points from
      53             : /// any InterpolationTargets.
      54             : ///
      55             : /// Uses:
      56             : /// - DataBox:
      57             : ///   - `Tags::NumberOfElements`
      58             : ///
      59             : /// DataBox changes:
      60             : /// - Adds: nothing
      61             : /// - Removes: nothing
      62             : /// - Modifies:
      63             : ///   - `Tags::VolumeVarsInfo<Metavariables>`
      64             : ///   - `Tags::InterpolatedVarsHolders<Metavariables>`
      65             : template <typename TemporalId>
      66           1 : struct InterpolatorReceiveVolumeData {
      67             :   template <typename ParallelComponent, typename DbTags, typename Metavariables,
      68             :             typename ArrayIndex, size_t VolumeDim>
      69           0 :   static void apply(
      70             :       db::DataBox<DbTags>& box, Parallel::GlobalCache<Metavariables>& cache,
      71             :       const ArrayIndex& /*array_index*/,
      72             :       const typename TemporalId::type& temporal_id,
      73             :       const ElementId<VolumeDim>& element_id, const ::Mesh<VolumeDim>& mesh,
      74             :       Variables<typename Metavariables::interpolator_source_vars>&&
      75             :           interpolator_source_vars) {
      76             :     // Determine if we have already finished interpolating on this
      77             :     // temporal_id.  If so, then we simply return, ignore the incoming
      78             :     // data, and do not interpolate.
      79             :     //
      80             :     // This scenario can happen if there is an element that is not
      81             :     // used or needed for any InterpolationTarget, and if that element
      82             :     // calls InterpolatorReceiveVolumeData so late that all the
      83             :     // InterpolationTargets for the current temporal_id have already
      84             :     // finished.
      85             :     bool this_temporal_id_is_done = true;
      86             :     const auto& holders =
      87             :         db::get<Tags::InterpolatedVarsHolders<Metavariables>>(box);
      88             :     tmpl::for_each<typename Metavariables::interpolation_target_tags>(
      89             :         [&holders, &this_temporal_id_is_done, &temporal_id](auto tag_v) {
      90             :           using tag = typename decltype(tag_v)::type;
      91             :           // Here we decide whether this interpolation target is "done" (i.e. it
      92             :           // does not need to interpolate) at this temporal_id. If it is "done",
      93             :           // then we don't need to store the volume data. Usually "done" means
      94             :           // that it has already done its interpolation at this temporal_id. But
      95             :           // note that if an interpolation target is not using the Interpolator
      96             :           // at all, it is considered "done", because we don't need any volume
      97             :           // data for it and should not store it. Similarly, interpolation
      98             :           // targets whose temporal_id has a different type than TemporalId are
      99             :           // considered "done" because they too do not use the Interpolator and
     100             :           // don't need volume data to be saved.
     101             :           if constexpr (detail::using_interpolator_component_v<Metavariables,
     102             :                                                                tag> and
     103             :                         std::is_same_v<TemporalId, typename tag::temporal_id>) {
     104             :             const auto& finished_temporal_ids =
     105             :                 get<Vars::HolderTag<tag, Metavariables>>(holders)
     106             :                     .temporal_ids_when_data_has_been_interpolated;
     107             :             if (not alg::found(finished_temporal_ids, temporal_id)) {
     108             :               this_temporal_id_is_done = false;
     109             :             }
     110             :           }
     111             :         });
     112             : 
     113             :     if (this_temporal_id_is_done) {
     114             :       return;
     115             :     }
     116             : 
     117             :     // Add to the VolumeVarsInfo for this TemporalId type.  (Note that
     118             :     // multiple VolumeVarsInfos, each with a different TemporalId
     119             :     // type, can be in the databox.  Note also that the above check
     120             :     // for this_temporal_id_is_done and the interpolation below are
     121             :     // done only for this TemporalId type and not for any other
     122             :     // VolumeVarsInfos that might be in the DataBox.)
     123             :     db::mutate<Tags::VolumeVarsInfo<Metavariables, TemporalId>>(
     124             :         [&temporal_id, &element_id, &mesh, &interpolator_source_vars](
     125             :             const gsl::not_null<
     126             :                 typename Tags::VolumeVarsInfo<Metavariables, TemporalId>::type*>
     127             :                 container) {
     128             :           if (container->find(temporal_id) == container->end()) {
     129             :             container->emplace(
     130             :                 temporal_id,
     131             :                 std::unordered_map<ElementId<VolumeDim>,
     132             :                                    typename Tags::VolumeVarsInfo<
     133             :                                        Metavariables, TemporalId>::Info>{});
     134             :           }
     135             :           container->at(temporal_id)
     136             :               .emplace(std::make_pair(
     137             :                   element_id,
     138             :                   typename Tags::VolumeVarsInfo<Metavariables,
     139             :                                                 TemporalId>::Info{
     140             :                       mesh, std::move(interpolator_source_vars), {}}));
     141             :         },
     142             :         make_not_null(&box));
     143             : 
     144             :     // Try to interpolate data for all InterpolationTargets for this
     145             :     // temporal_id. Also make sure this target is using the interpolator. No
     146             :     // sense in calling this for targets that don't use it.
     147             :     tmpl::for_each<typename Metavariables::interpolation_target_tags>(
     148             :         [&box, &cache, &temporal_id](auto tag_v) {
     149             :           using tag = typename decltype(tag_v)::type;
     150             :           if constexpr (detail::using_interpolator_component_v<Metavariables,
     151             :                                                                tag> and
     152             :                         std::is_same_v<typename tag::temporal_id, TemporalId>) {
     153             :             try_to_interpolate<tag>(make_not_null(&box), make_not_null(&cache),
     154             :                                     temporal_id);
     155             :           }
     156             :         });
     157             :   }
     158             : };
     159             : 
     160             : }  // namespace Actions
     161             : }  // namespace intrp

Generated by: LCOV version 1.14