SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/Actions - FunctionsOfTimeAreReady.hpp Hit Total Coverage
Commit: d7dc5bae4c2eeb465c1a076e919d884f4ccca7c5 Lines: 4 11 36.4 %
Date: 2024-05-01 22:09:14
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 <array>
       7             : #include <cstddef>
       8             : #include <memory>
       9             : #include <optional>
      10             : #include <string>
      11             : #include <tuple>
      12             : #include <unordered_map>
      13             : #include <unordered_set>
      14             : #include <utility>
      15             : 
      16             : #include "DataStructures/DataBox/DataBox.hpp"
      17             : #include "Domain/FunctionsOfTime/FunctionOfTime.hpp"
      18             : #include "Parallel/AlgorithmExecution.hpp"
      19             : #include "Parallel/ArrayComponentId.hpp"
      20             : #include "Parallel/Callback.hpp"
      21             : #include "Parallel/GlobalCache.hpp"
      22             : #include "Parallel/ParallelComponentHelpers.hpp"
      23             : #include "Utilities/Algorithm.hpp"
      24             : #include "Utilities/ErrorHandling/Assert.hpp"
      25             : #include "Utilities/StdHelpers.hpp"
      26             : 
      27             : /// \cond
      28             : namespace Tags {
      29             : struct Time;
      30             : }  // namespace Tags
      31             : namespace domain::Tags {
      32             : struct FunctionsOfTime;
      33             : }  // namespace domain::Tags
      34             : namespace tuples {
      35             : template <class... Tags>
      36             : class TaggedTuple;
      37             : }  // namespace tuples
      38             : /// \endcond
      39             : 
      40             : namespace domain {
      41             : namespace detail {
      42             : template <typename CacheTag, typename Callback, typename Metavariables,
      43             :           typename ArrayIndex, typename Component, typename... Args>
      44             : bool functions_of_time_are_ready_impl(
      45             :     Parallel::GlobalCache<Metavariables>& cache, const ArrayIndex& array_index,
      46             :     const Component* /*meta*/, const double time,
      47             :     const std::optional<std::unordered_set<std::string>>& functions_to_check,
      48             :     Args&&... args) {
      49             :   if constexpr (Parallel::is_in_mutable_global_cache<Metavariables, CacheTag>) {
      50             :     const auto& proxy =
      51             :         ::Parallel::get_parallel_component<Component>(cache)[array_index];
      52             :     const Parallel::ArrayComponentId array_component_id =
      53             :         Parallel::make_array_component_id<Component>(array_index);
      54             : 
      55             :     return Parallel::mutable_cache_item_is_ready<CacheTag>(
      56             :         cache, array_component_id,
      57             :         [&functions_to_check, &proxy, &time,
      58             :          &args...](const std::unordered_map<
      59             :                    std::string,
      60             :                    std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
      61             :                        functions_of_time) {
      62             :           using ::operator<<;
      63             :           ASSERT(
      64             :               alg::all_of(
      65             :                   functions_to_check.value_or(
      66             :                       std::unordered_set<std::string>{}),
      67             :                   [&functions_of_time](const std::string& function_to_check) {
      68             :                     return functions_of_time.count(function_to_check) == 1;
      69             :                   }),
      70             :               "Not all functions to check ("
      71             :                   << functions_to_check.value() << ") are in the global cache ("
      72             :                   << keys_of(functions_of_time) << ")");
      73             :           for (const auto& [name, f_of_t] : functions_of_time) {
      74             :             if (functions_to_check.has_value() and
      75             :                 functions_to_check->count(name) == 0) {
      76             :               continue;
      77             :             }
      78             :             const double expiration_time = f_of_t->time_bounds()[1];
      79             :             if (time > expiration_time) {
      80             :               return std::unique_ptr<Parallel::Callback>(
      81             :                   new Callback(proxy, std::forward<Args>(args)...));
      82             :             }
      83             :           }
      84             :           return std::unique_ptr<Parallel::Callback>{};
      85             :         });
      86             :   } else {
      87             :     (void)cache;
      88             :     (void)array_index;
      89             :     (void)time;
      90             :     (void)functions_to_check;
      91             :     EXPAND_PACK_LEFT_TO_RIGHT((void)args);
      92             :     return true;
      93             :   }
      94             : }
      95             : }  // namespace detail
      96             : 
      97             : /// \ingroup ComputationalDomainGroup
      98             : /// Check that functions of time are up-to-date.
      99             : ///
     100             : /// Check that functions of time in \p CacheTag with names in \p
     101             : /// functions_to_check are ready at time \p time.  If  \p functions_to_check is
     102             : /// a `std::nullopt`, checks all functions in \p CacheTag.  If any function is
     103             : /// not ready, schedules a `Parallel::PerformAlgorithmCallback` with the
     104             : /// GlobalCache..
     105             : template <typename CacheTag, typename Metavariables, typename ArrayIndex,
     106             :           typename Component>
     107           1 : bool functions_of_time_are_ready_algorithm_callback(
     108             :     Parallel::GlobalCache<Metavariables>& cache, const ArrayIndex& array_index,
     109             :     const Component* component_p, const double time,
     110             :     const std::optional<std::unordered_set<std::string>>& functions_to_check =
     111             :         std::nullopt) {
     112             :   using ProxyType =
     113             :       std::decay_t<decltype(::Parallel::get_parallel_component<Component>(
     114             :           cache)[array_index])>;
     115             :   return detail::functions_of_time_are_ready_impl<
     116             :       CacheTag, Parallel::PerformAlgorithmCallback<ProxyType>>(
     117             :       cache, array_index, component_p, time, functions_to_check);
     118             : }
     119             : 
     120             : /// \ingroup ComputationalDomainGroup
     121             : /// Check that functions of time are up-to-date.
     122             : ///
     123             : /// Check that functions of time in \p CacheTag with names in \p
     124             : /// functions_to_check are ready at time \p time.  If  \p functions_to_check is
     125             : /// a `std::nullopt`, checks all functions in \p CacheTag.  If any function is
     126             : /// ready, schedules a `Parallel::SimpleActionCallback` with the GlobalCache
     127             : /// which calls the simple action passed in as a template parameter. The `Args`
     128             : /// are moved into the callback.
     129             : template <typename CacheTag, typename SimpleAction, typename Metavariables,
     130             :           typename ArrayIndex, typename Component, typename... Args>
     131           1 : bool functions_of_time_are_ready_simple_action_callback(
     132             :     Parallel::GlobalCache<Metavariables>& cache, const ArrayIndex& array_index,
     133             :     const Component* component_p, const double time,
     134             :     const std::optional<std::unordered_set<std::string>>& functions_to_check,
     135             :     Args&&... args) {
     136             :   using ProxyType =
     137             :       std::decay_t<decltype(::Parallel::get_parallel_component<Component>(
     138             :           cache)[array_index])>;
     139             :   return detail::functions_of_time_are_ready_impl<
     140             :       CacheTag,
     141             :       Parallel::SimpleActionCallback<SimpleAction, ProxyType, Args...>>(
     142             :       cache, array_index, component_p, time, functions_to_check,
     143             :       std::forward<Args>(args)...);
     144             : }
     145             : 
     146           0 : namespace Actions {
     147             : /// \ingroup ComputationalDomainGroup
     148             : /// Check that functions of time are up-to-date.
     149             : ///
     150             : /// Wait for all functions of time in `domain::Tags::FunctionsOfTime`
     151             : /// to be ready at `::Tags::Time`.  This ensures that the coordinates
     152             : /// can be safely accessed in later actions without first verifying
     153             : /// the state of the time-dependent maps.
     154           1 : struct CheckFunctionsOfTimeAreReady {
     155             :   template <typename DbTags, typename... InboxTags, typename Metavariables,
     156             :             typename ArrayIndex, typename ActionList,
     157             :             typename ParallelComponent>
     158           0 :   static Parallel::iterable_action_return_t apply(
     159             :       db::DataBox<DbTags>& box, tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
     160             :       Parallel::GlobalCache<Metavariables>& cache,
     161             :       const ArrayIndex& array_index, ActionList /*meta*/,
     162             :       const ParallelComponent* component) {
     163             :     const bool ready = functions_of_time_are_ready_algorithm_callback<
     164             :         domain::Tags::FunctionsOfTime>(cache, array_index, component,
     165             :                                        db::get<::Tags::Time>(box));
     166             :     return {ready ? Parallel::AlgorithmExecution::Continue
     167             :                   : Parallel::AlgorithmExecution::Retry,
     168             :             std::nullopt};
     169             :   }
     170             : };
     171             : }  // namespace Actions
     172             : 
     173             : /// \ingroup ComputationalDomainGroup Dense-output postprocessor to
     174             : /// check that functions of time are up-to-date.
     175             : ///
     176             : /// Check that all functions of time in
     177             : /// `domain::Tags::FunctionsOfTime` are ready at `::Tags::Time`.  This
     178             : /// ensures that the coordinates can be safely accessed in later
     179             : /// actions without first verifying the state of the time-dependent
     180             : /// maps.  This postprocessor does not actually modify anything.
     181           1 : struct CheckFunctionsOfTimeAreReadyPostprocessor {
     182           0 :   using return_tags = tmpl::list<>;
     183           0 :   using argument_tags = tmpl::list<>;
     184           0 :   static void apply() {}
     185             : 
     186             :   template <typename DbTagsList, typename... InboxTags, typename Metavariables,
     187             :             typename ArrayIndex, typename ParallelComponent>
     188           0 :   static bool is_ready(
     189             :       const gsl::not_null<db::DataBox<DbTagsList>*> box,
     190             :       const gsl::not_null<tuples::TaggedTuple<InboxTags...>*> /*inboxes*/,
     191             :       Parallel::GlobalCache<Metavariables>& cache,
     192             :       const ArrayIndex& array_index, const ParallelComponent* component) {
     193             :     return functions_of_time_are_ready_algorithm_callback<
     194             :         domain::Tags::FunctionsOfTime>(cache, array_index, component,
     195             :                                        db::get<::Tags::Time>(*box));
     196             :   }
     197             : };
     198             : }  // namespace domain

Generated by: LCOV version 1.14