SpECTRE Documentation Coverage Report
Current view: top level - Parallel/ArrayCollection - PerformAlgorithmOnElement.hpp Hit Total Coverage
Commit: 6e1258ccd353220e12442198913007fb6c170b6b Lines: 3 4 75.0 %
Date: 2024-10-23 19:54:13
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 <mutex>
       8             : 
       9             : #include "DataStructures/DataBox/DataBox.hpp"
      10             : #include "Domain/Structure/ElementId.hpp"
      11             : #include "Parallel/GlobalCache.hpp"
      12             : #include "Parallel/Invoke.hpp"
      13             : #include "Parallel/NodeLock.hpp"
      14             : #include "Utilities/Gsl.hpp"
      15             : 
      16             : namespace Parallel::Actions {
      17             : /// \brief A threaded action that calls `perform_algorithm()` for a specified
      18             : /// element on the nodegroup.
      19             : ///
      20             : /// If `Block` is `true` then the action will wait until the element is free
      21             : /// to be operated on. If it is `false` then a message will be sent to the
      22             : /// nodegroup to try invoking the element again.
      23             : ///
      24             : /// This is a threaded action intended to be run on the DG nodegroup.
      25             : template <bool Block>
      26           1 : struct PerformAlgorithmOnElement {
      27             :   /// \brief Invoke `perform_algorithm()` on a single element
      28             :   template <typename ParallelComponent, typename DbTagsList,
      29             :             typename Metavariables, typename ArrayIndex,
      30             :             typename DistributedObject, size_t Dim>
      31           1 :   static void apply(db::DataBox<DbTagsList>& box,
      32             :                     Parallel::GlobalCache<Metavariables>& cache,
      33             :                     const ArrayIndex& /*array_index*/,
      34             :                     const gsl::not_null<Parallel::NodeLock*> /*node_lock*/,
      35             :                     const DistributedObject* /*distributed_object*/,
      36             :                     const ElementId<Dim>& element_to_execute_on) {
      37             :     const size_t my_node = Parallel::my_node<size_t>(cache);
      38             :     auto& my_proxy = Parallel::get_parallel_component<ParallelComponent>(cache);
      39             : 
      40             :     auto& element_collection = db::get_mutable_reference<
      41             :         typename ParallelComponent::element_collection_tag>(
      42             :         make_not_null(&box));
      43             :     auto& element = element_collection.at(element_to_execute_on);
      44             :     std::unique_lock element_lock(element.element_lock(), std::defer_lock);
      45             :     if constexpr (Block) {
      46             :       element_lock.lock();
      47             :       element.perform_algorithm();
      48             :     } else {
      49             :       if (element_lock.try_lock()) {
      50             :         element.perform_algorithm();
      51             :       } else {
      52             :         Parallel::threaded_action<
      53             :             Parallel::Actions::PerformAlgorithmOnElement<Block>>(
      54             :             my_proxy[my_node], element_to_execute_on);
      55             :       }
      56             :     }
      57             :   }
      58             : 
      59             :   /// \brief Invoke `perform_algorithm()` on all elements
      60             :   ///
      61             :   /// \note This loops over all elements and spawns a message for each element.
      62             :   template <typename ParallelComponent, typename DbTagsList,
      63             :             typename Metavariables, typename ArrayIndex,
      64             :             typename DistributedObject, size_t Dim>
      65           1 :   static void apply(db::DataBox<DbTagsList>& box,
      66             :                     Parallel::GlobalCache<Metavariables>& cache,
      67             :                     const ArrayIndex& /*array_index*/,
      68             :                     const gsl::not_null<Parallel::NodeLock*> /*node_lock*/,
      69             :                     const DistributedObject* /*distributed_object*/) {
      70             :     const size_t my_node = Parallel::my_node<size_t>(cache);
      71             :     auto& my_proxy = Parallel::get_parallel_component<ParallelComponent>(cache);
      72             : 
      73             :     auto& element_collection = db::get_mutable_reference<
      74             :         typename ParallelComponent::element_collection_tag>(
      75             :         make_not_null(&box));
      76             :     for (const auto& [element_id, element] : element_collection) {
      77             :       Parallel::threaded_action<
      78             :           Parallel::Actions::PerformAlgorithmOnElement<Block>>(
      79             :           my_proxy[my_node], element_id);
      80             :     }
      81             :   }
      82             : };
      83             : }  // namespace Parallel::Actions

Generated by: LCOV version 1.14