SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/Actions - LimiterActions.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 23.5 % 17 4
Test Date: 2026-10-22 17:29:42
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>
      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 "DataStructures/TaggedTuple.hpp"
      18              : #include "Domain/Structure/DirectionalId.hpp"
      19              : #include "Domain/Tags.hpp"
      20              : #include "Parallel/AlgorithmExecution.hpp"
      21              : #include "Parallel/GlobalCache.hpp"
      22              : #include "Parallel/InboxInserters.hpp"
      23              : #include "Parallel/Invoke.hpp"
      24              : #include "Utilities/ErrorHandling/Assert.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& neighbor_id = *(neighbors_in_direction.cbegin());
     171              :       const auto& orientation = neighbors_in_direction.orientation(neighbor_id);
     172              :       const auto direction_from_neighbor = orientation(direction.opposite());
     173              : 
     174              :       using argument_tags =
     175              :           typename Metavariables::limiter::type::package_argument_tags;
     176              :       const auto packaged_data = db::apply<argument_tags>(
     177              :           [&limiter](const auto&... args) {
     178              :             // Note: orientation is received as last element of pack `args`
     179              :             typename Metavariables::limiter::type::PackagedData pack{};
     180              :             limiter.package_data(make_not_null(&pack), args...);
     181              :             return pack;
     182              :           },
     183              :           box, orientation);
     184              : 
     185              :       for (const auto& neighbor : neighbors_in_direction) {
     186              :         Parallel::receive_data<limiter_comm_tag>(
     187              :             receiver_proxy[neighbor], temporal_id,
     188              :             std::make_pair(DirectionalId<volume_dim>{direction_from_neighbor,
     189              :                                                      element.id()},
     190              :                            packaged_data));
     191              : 
     192              :       }  // loop over neighbors_in_direction
     193              :     }    // loop over element.neighbors()
     194              : 
     195              :     return {Parallel::AlgorithmExecution::Continue, std::nullopt};
     196              :   }
     197              : };
     198              : }  // namespace Actions
     199              : }  // namespace Limiters
        

Generated by: LCOV version 2.0-1