SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/Actions - LimiterActions.hpp Hit Total Coverage
Commit: d7dc5bae4c2eeb465c1a076e919d884f4ccca7c5 Lines: 4 17 23.5 %
Date: 2024-05-01 22:09:14
Legend: Lines: hit not hit

          Line data    Source code
       1           1 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : /// \file
       5             : /// Defines actions ApplyLimiter and SendDataForLimiter
       6             : 
       7             : #pragma once
       8             : 
       9             : #include <boost/functional/hash.hpp>  // IWYU pragma: keep
      10             : #include <cstddef>
      11             : #include <map>
      12             : #include <optional>
      13             : #include <unordered_map>
      14             : #include <utility>
      15             : 
      16             : #include "DataStructures/DataBox/DataBox.hpp"
      17             : #include "Domain/Structure/DirectionalId.hpp"
      18             : #include "Domain/Tags.hpp"
      19             : #include "Parallel/AlgorithmExecution.hpp"
      20             : #include "Parallel/GlobalCache.hpp"
      21             : #include "Parallel/InboxInserters.hpp"
      22             : #include "Parallel/Invoke.hpp"
      23             : #include "Utilities/ErrorHandling/Assert.hpp"
      24             : #include "Utilities/TaggedTuple.hpp"
      25             : 
      26             : namespace Limiters {
      27           0 : namespace Tags {
      28             : /// \ingroup DiscontinuousGalerkinGroup
      29             : /// \ingroup LimitersGroup
      30             : /// \brief The inbox tag for limiter communication.
      31             : template <typename Metavariables>
      32           1 : struct LimiterCommunicationTag : public Parallel::InboxInserters::Map<
      33             :                                      LimiterCommunicationTag<Metavariables>> {
      34           0 :   static constexpr size_t volume_dim = Metavariables::system::volume_dim;
      35           0 :   using packaged_data_t = typename Metavariables::limiter::type::PackagedData;
      36           0 :   using temporal_id = typename Metavariables::temporal_id::type;
      37           0 :   using type =
      38             :       std::map<temporal_id,
      39             :                std::unordered_map<DirectionalId<volume_dim>, packaged_data_t,
      40             :                                   boost::hash<DirectionalId<volume_dim>>>>;
      41             : };
      42             : }  // namespace Tags
      43             : 
      44           0 : namespace Actions {
      45             : /// \ingroup ActionsGroup
      46             : /// \ingroup DiscontinuousGalerkinGroup
      47             : /// \ingroup LimitersGroup
      48             : /// \brief Receive limiter data from neighbors, then apply limiter.
      49             : ///
      50             : /// Currently, is not tested for support of:
      51             : /// - h-refinement
      52             : /// Currently, does not support:
      53             : /// - Local time-stepping
      54             : ///
      55             : /// Uses:
      56             : /// - GlobalCache:
      57             : ///   - Metavariables::limiter
      58             : /// - DataBox:
      59             : ///   - Metavariables::limiter::type::limit_argument_tags
      60             : ///   - Metavariables::temporal_id
      61             : ///   - Tags::Element<volume_dim>
      62             : /// DataBox changes:
      63             : /// - Adds: nothing
      64             : /// - Removes: nothing
      65             : /// - Modifies:
      66             : ///   - Metavariables::limiter::type::limit_tags
      67             : ///
      68             : /// \see SendDataForLimiter
      69             : template <typename Metavariables>
      70           1 : struct Limit {
      71           0 :   using const_global_cache_tags = tmpl::list<typename Metavariables::limiter>;
      72             : 
      73             :  public:
      74           0 :   using limiter_comm_tag =
      75             :       Limiters::Tags::LimiterCommunicationTag<Metavariables>;
      76           0 :   using inbox_tags = tmpl::list<limiter_comm_tag>;
      77             : 
      78             :   template <typename DbTags, typename... InboxTags, typename ArrayIndex,
      79             :             typename ActionList, typename ParallelComponent>
      80           0 :   static Parallel::iterable_action_return_t apply(
      81             :       db::DataBox<DbTags>& box, tuples::TaggedTuple<InboxTags...>& inboxes,
      82             :       const Parallel::GlobalCache<Metavariables>& cache,
      83             :       const ArrayIndex& /*array_index*/, const ActionList /*meta*/,
      84             :       const ParallelComponent* const /*meta*/) {
      85             :     static_assert(
      86             :         not Metavariables::local_time_stepping,
      87             :         "Limiter communication actions do not yet support local time stepping");
      88             : 
      89             :     constexpr size_t volume_dim = Metavariables::system::volume_dim;
      90             : 
      91             :     const auto& local_temporal_id =
      92             :         db::get<typename Metavariables::temporal_id>(box);
      93             :     auto& inbox = tuples::get<limiter_comm_tag>(inboxes);
      94             :     const auto& received = inbox.find(local_temporal_id);
      95             : 
      96             :     const auto& element = db::get<domain::Tags::Element<volume_dim>>(box);
      97             :     const auto num_expected = element.neighbors().size();
      98             :     if (num_expected > 0 and
      99             :         (received == inbox.end() or received->second.size() != num_expected)) {
     100             :       return {Parallel::AlgorithmExecution::Retry, std::nullopt};
     101             :     }
     102             : 
     103             :     const auto& limiter = get<typename Metavariables::limiter>(cache);
     104             :     using mutate_tags = typename Metavariables::limiter::type::limit_tags;
     105             :     using argument_tags =
     106             :         typename Metavariables::limiter::type::limit_argument_tags;
     107             :     db::mutate_apply<mutate_tags, argument_tags>(limiter, make_not_null(&box),
     108             :                                                  inbox[local_temporal_id]);
     109             : 
     110             :     inbox.erase(local_temporal_id);
     111             : 
     112             :     return {Parallel::AlgorithmExecution::Continue, std::nullopt};
     113             :   }
     114             : };
     115             : 
     116             : /// \ingroup ActionsGroup
     117             : /// \ingroup DiscontinuousGalerkinGroup
     118             : /// \ingroup LimitersGroup
     119             : /// \brief Send local data needed for limiting.
     120             : ///
     121             : /// Currently, is not tested for support of:
     122             : /// - h-refinement
     123             : /// Currently, does not support:
     124             : /// - Local time-stepping
     125             : ///
     126             : /// Uses:
     127             : /// - GlobalCache:
     128             : ///   - Metavariables::limiter
     129             : /// - DataBox:
     130             : ///   - Tags::Element<volume_dim>
     131             : ///   - Metavariables::limiter::type::package_argument_tags
     132             : ///   - Metavariables::temporal_id
     133             : ///
     134             : /// DataBox changes:
     135             : /// - Adds: nothing
     136             : /// - Removes: nothing
     137             : /// - Modifies: nothing
     138             : ///
     139             : /// \see ApplyLimiter
     140             : template <typename Metavariables>
     141           1 : struct SendData {
     142           0 :   using const_global_cache_tags = tmpl::list<typename Metavariables::limiter>;
     143           0 :   using limiter_comm_tag =
     144             :       Limiters::Tags::LimiterCommunicationTag<Metavariables>;
     145             : 
     146             :   template <typename DbTags, typename... InboxTags, typename ArrayIndex,
     147             :             typename ActionList, typename ParallelComponent>
     148           0 :   static Parallel::iterable_action_return_t apply(
     149             :       db::DataBox<DbTags>& box, tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
     150             :       Parallel::GlobalCache<Metavariables>& cache,
     151             :       const ArrayIndex& /*array_index*/, const ActionList /*meta*/,
     152             :       const ParallelComponent* const /*meta*/) {
     153             :     constexpr size_t volume_dim = Metavariables::system::volume_dim;
     154             : 
     155             :     auto& receiver_proxy =
     156             :         Parallel::get_parallel_component<ParallelComponent>(cache);
     157             :     const auto& element = db::get<domain::Tags::Element<volume_dim>>(box);
     158             :     const auto& temporal_id = db::get<typename Metavariables::temporal_id>(box);
     159             :     const auto& limiter = get<typename Metavariables::limiter>(cache);
     160             : 
     161             :     for (const auto& direction_neighbors : element.neighbors()) {
     162             :       const auto& direction = direction_neighbors.first;
     163             :       const size_t dimension = direction.dimension();
     164             :       const auto& neighbors_in_direction = direction_neighbors.second;
     165             :       ASSERT(neighbors_in_direction.size() == 1,
     166             :              "h-adaptivity is not supported yet.\nDirection: "
     167             :                  << direction << "\nDimension: " << dimension
     168             :                  << "\nNeighbors:\n"
     169             :                  << neighbors_in_direction);
     170             :       const auto& orientation = neighbors_in_direction.orientation();
     171             :       const auto direction_from_neighbor = orientation(direction.opposite());
     172             : 
     173             :       using argument_tags =
     174             :           typename Metavariables::limiter::type::package_argument_tags;
     175             :       const auto packaged_data = db::apply<argument_tags>(
     176             :           [&limiter](const auto&... args) {
     177             :             // Note: orientation is received as last element of pack `args`
     178             :             typename Metavariables::limiter::type::PackagedData pack{};
     179             :             limiter.package_data(make_not_null(&pack), args...);
     180             :             return pack;
     181             :           },
     182             :           box, orientation);
     183             : 
     184             :       for (const auto& neighbor : neighbors_in_direction) {
     185             :         Parallel::receive_data<limiter_comm_tag>(
     186             :             receiver_proxy[neighbor], temporal_id,
     187             :             std::make_pair(DirectionalId<volume_dim>{direction_from_neighbor,
     188             :                                                      element.id()},
     189             :                            packaged_data));
     190             : 
     191             :       }  // loop over neighbors_in_direction
     192             :     }    // loop over element.neighbors()
     193             : 
     194             :     return {Parallel::AlgorithmExecution::Continue, std::nullopt};
     195             :   }
     196             : };
     197             : }  // namespace Actions
     198             : }  // namespace Limiters

Generated by: LCOV version 1.14