SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/EventsAndDenseTriggers - DenseTrigger.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 50.0 % 10 5
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 <limits>
       7              : #include <optional>
       8              : #include <pup.h>
       9              : #include <type_traits>
      10              : 
      11              : #include "DataStructures/DataBox/DataBox.hpp"
      12              : #include "DataStructures/DataBox/MetavariablesTag.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 2.0-1