SpECTRE Documentation Coverage Report
Current view: top level - Parallel/ArrayCollection - SetTerminateOnElement.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 20.0 % 5 1
Test Date: 2026-10-22 17:29:42
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              : #include <stdexcept>
       9              : 
      10              : #include "DataStructures/DataBox/DataBox.hpp"
      11              : #include "Domain/Structure/ElementId.hpp"
      12              : #include "Parallel/ArrayCollection/Tags/NumberOfElementsTerminated.hpp"
      13              : #include "Parallel/GlobalCache.hpp"
      14              : #include "Parallel/Local.hpp"
      15              : #include "Parallel/NodeLock.hpp"
      16              : #include "Utilities/ErrorHandling/Assert.hpp"
      17              : #include "Utilities/ErrorHandling/Error.hpp"
      18              : #include "Utilities/Gsl.hpp"
      19              : 
      20              : namespace Parallel::Actions {
      21              : /// \brief Set the element with ID `my_element_id` to be terminated. This is
      22              : /// always invoked on the local component via
      23              : /// `Parallel::local_synchronous_action`
      24              : ///
      25              : /// In the future we can use this to try and elide Charm++ calls when the
      26              : /// receiver is local.
      27            1 : struct SetTerminateOnElement {
      28            0 :   using return_type = void;
      29              : 
      30              :   template <typename ParallelComponent, typename DbTagList,
      31              :             typename Metavariables, size_t Dim>
      32            0 :   static return_type apply(
      33              :       db::DataBox<DbTagList>& box, gsl::not_null<Parallel::NodeLock*> node_lock,
      34              :       gsl::not_null<Parallel::GlobalCache<Metavariables>*> cache,
      35              :       const ElementId<Dim>& my_element_id, bool terminate_value);
      36              : };
      37              : 
      38              : template <typename ParallelComponent, typename DbTagList,
      39              :           typename Metavariables, size_t Dim>
      40            0 : auto SetTerminateOnElement::apply(
      41              :     db::DataBox<DbTagList>& box,
      42              :     const gsl::not_null<Parallel::NodeLock*> node_lock,
      43              :     const gsl::not_null<Parallel::GlobalCache<Metavariables>*> cache,
      44              :     const ElementId<Dim>& my_element_id, const bool terminate_value)
      45              :     -> return_type {
      46              :   std::lock_guard node_guard(*node_lock);
      47              :   db::mutate<typename ParallelComponent::element_collection_tag,
      48              :              Parallel::Tags::NumberOfElementsTerminated>(
      49              :       [&cache, &my_element_id, &node_lock, terminate_value](
      50              :           const auto element_collection_ptr,
      51              :           const auto num_terminated_ptr) -> void {
      52              :         try {
      53              :           // Note: The nodelock is checked by set_terminate as a sanity
      54              :           // check and as a way of making set_terminate difficult to use
      55              :           // without this action.
      56              :           //
      57              :           // Note: since this is a local synchronous action running on the
      58              :           // element that called it, we already have the element locked and so
      59              :           // setting terminate is threadsafe.
      60              :           //
      61              :           // Note: the element's set_terminate updates num_terminated
      62              :           // correctly so we don't need to handle that here.
      63              :           element_collection_ptr->at(my_element_id)
      64              :               .set_terminate(num_terminated_ptr, node_lock, terminate_value);
      65              : 
      66              :           // Update the state of the nodegroup. Specifically, if _all_
      67              :           // elements are set to be terminated, we terminate the nodegroup,
      68              :           // otherwise we do not.
      69              :           auto* local_branch = Parallel::local_branch(
      70              :               Parallel::get_parallel_component<ParallelComponent>(*cache));
      71              :           ASSERT(local_branch != nullptr,
      72              :                  "The local branch is nullptr, which is inconsistent");
      73              :           local_branch->set_terminate(*num_terminated_ptr ==
      74              :                                       element_collection_ptr->size());
      75              :         } catch (const std::out_of_range&) {
      76              :           ERROR("Could not find element with ID " << my_element_id
      77              :                                                   << " on node");
      78              :         }
      79              :       },
      80              :       make_not_null(&box));
      81              : }
      82              : }  // namespace Parallel::Actions
        

Generated by: LCOV version 2.0-1