SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/EventsAndDenseTriggers - DenseTrigger.hpp Hit Total Coverage
Commit: 94cdae68f6da58feb2ca71d33dfdd10964304540 Lines: 5 10 50.0 %
Date: 2025-03-19 23:33:02
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 <limits>
       7             : #include <optional>
       8             : #include <pup.h>
       9             : #include <type_traits>
      10             : 
      11             : #include "DataStructures/DataBox/DataBox.hpp"
      12             : #include "Parallel/Tags/Metavariables.hpp"
      13             : #include "Utilities/CallWithDynamicType.hpp"
      14             : #include "Utilities/Gsl.hpp"
      15             : #include "Utilities/Serialization/CharmPupable.hpp"
      16             : #include "Utilities/Serialization/PupStlCpp17.hpp"
      17             : 
      18             : /// \cond
      19             : namespace Parallel {
      20             : template <typename Metavariables>
      21             : class GlobalCache;
      22             : }  // namespace Parallel
      23             : namespace Tags {
      24             : struct Time;
      25             : }  // namespace Tags
      26             : /// \endcond
      27             : 
      28             : /*!
      29             :  * \ingroup EventsAndTriggersGroup
      30             :  * \brief Contains denser triggers.
      31             :  */
      32           1 : namespace DenseTriggers {}
      33             : 
      34             : /// \ingroup EventsAndTriggersGroup
      35             : /// Base class for checking whether to run an Event at arbitrary times.
      36             : ///
      37             : /// The DataBox passed to the member functions will have
      38             : /// `::Tags::Time`, and therefore any compute tags depending on that
      39             : /// value, set to the time to be tested.  Any discrete properties of
      40             : /// steps or slabs, such as the step size, may have the values from
      41             : /// times off by one step.  The evolved variables will be in an
      42             : /// unspecified state.
      43           1 : class DenseTrigger : public PUP::able {
      44             :  protected:
      45             :   /// \cond
      46             :   DenseTrigger() = default;
      47             :   DenseTrigger(const DenseTrigger&) = default;
      48             :   DenseTrigger(DenseTrigger&&) = default;
      49             :   DenseTrigger& operator=(const DenseTrigger&) = default;
      50             :   DenseTrigger& operator=(DenseTrigger&&) = default;
      51             :   /// \endcond
      52             : 
      53             :  public:
      54           0 :   ~DenseTrigger() override = default;
      55             : 
      56             :   /// \cond
      57             :   explicit DenseTrigger(CkMigrateMessage* const msg) : PUP::able(msg) {}
      58             :   WRAPPED_PUPable_abstract(DenseTrigger);  // NOLINT
      59             :   /// \endcond
      60             : 
      61             :   /// Check whether the trigger fires.  Returns std::nullopt if
      62             :   /// insufficient data is available to make the decision.  The
      63             :   /// trigger is not responsible for checking whether dense output of
      64             :   /// the evolved variables is possible, but may need to check things
      65             :   /// such as the availability of FunctionOfTime data.
      66             :   template <typename DbTags, typename Metavariables, typename ArrayIndex,
      67             :             typename Component>
      68           1 :   std::optional<bool> is_triggered(
      69             :       const gsl::not_null<db::DataBox<DbTags>*> box,
      70             :       Parallel::GlobalCache<Metavariables>& cache,
      71             :       const ArrayIndex& array_index, const Component* const component) {
      72             :     using factory_classes =
      73             :         typename std::decay_t<decltype(db::get<Parallel::Tags::Metavariables>(
      74             :             *box))>::factory_creation::factory_classes;
      75             :     previous_trigger_time_ = next_previous_trigger_time_;
      76             :     return call_with_dynamic_type<std::optional<bool>,
      77             :                                   tmpl::at<factory_classes, DenseTrigger>>(
      78             :         this,
      79             :         [this, &array_index, &box, &cache, &component](auto* const trigger) {
      80             :           using TriggerType = std::decay_t<decltype(*trigger)>;
      81             :           const auto result = db::mutate_apply<
      82             :               typename TriggerType::is_triggered_return_tags,
      83             :               typename TriggerType::is_triggered_argument_tags>(
      84             :               [&array_index, &cache, &component,
      85             :                &trigger](const auto&... args) {
      86             :                 return trigger->is_triggered(cache, array_index, component,
      87             :                                              args...);
      88             :               },
      89             :               box);
      90             :           if (result == std::optional{true}) {
      91             :             next_previous_trigger_time_ = db::get<::Tags::Time>(*box);
      92             :           }
      93             :           return result;
      94             :         });
      95             :   }
      96             : 
      97             :   /// Obtain the next time to check the trigger, or std::nullopt if the
      98             :   /// trigger is not ready to report yet.
      99             :   template <typename DbTags, typename Metavariables, typename ArrayIndex,
     100             :             typename Component>
     101           1 :   std::optional<double> next_check_time(
     102             :       const gsl::not_null<db::DataBox<DbTags>*> box,
     103             :       Parallel::GlobalCache<Metavariables>& cache,
     104             :       const ArrayIndex& array_index, const Component* component) {
     105             :     using factory_classes =
     106             :         typename std::decay_t<decltype(db::get<Parallel::Tags::Metavariables>(
     107             :             *box))>::factory_creation::factory_classes;
     108             :     return call_with_dynamic_type<std::optional<double>,
     109             :                                   tmpl::at<factory_classes, DenseTrigger>>(
     110             :         this, [&array_index, &box, &cache, &component](auto* const trigger) {
     111             :           using TriggerType = std::decay_t<decltype(*trigger)>;
     112             :           return db::mutate_apply<
     113             :               typename TriggerType::next_check_time_return_tags,
     114             :               typename TriggerType::next_check_time_argument_tags>(
     115             :               [&array_index, &cache, &component,
     116             :                &trigger](const auto&... args) {
     117             :                 return trigger->next_check_time(cache, array_index, component,
     118             :                                                 args...);
     119             :               },
     120             :               box);
     121             :         });
     122             :   }
     123             : 
     124             :   /// \brief Reports the value of `::Tags::Time` when the trigger most recently
     125             :   /// fired, except for the most recent call of `is_triggered`.
     126             :   ///
     127             :   /// \details The most recent call of `is_triggered` is not used for reporting
     128             :   /// the previous trigger so that the time reported to the event is actually
     129             :   /// the previous time value on which the trigger fired and activated the
     130             :   /// event. Without ignoring the most recent call of `is_triggered`, we'd just
     131             :   /// always be reporting the current time to the event, because events always
     132             :   /// run after their associated triggers fire via a call to `is_triggered`.
     133           1 :   std::optional<double> previous_trigger_time() const {
     134             :     return previous_trigger_time_;
     135             :   }
     136             : 
     137           0 :   void pup(PUP::er& p) override {
     138             :     p | next_previous_trigger_time_;
     139             :     p | previous_trigger_time_;
     140             :   }
     141             : 
     142             :  private:
     143           0 :   std::optional<double> next_previous_trigger_time_ = std::nullopt;
     144           0 :   std::optional<double> previous_trigger_time_ = std::nullopt;
     145             : };

Generated by: LCOV version 1.14