SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/EventsAndTriggers - EventsAndTriggers.hpp Hit Total Coverage
Commit: 3ffcbc8ecf43797401b60bcca17d6040ee06f013 Lines: 2 28 7.1 %
Date: 2026-03-03 02:01:44
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 <memory>
       7             : #include <optional>
       8             : #include <pup.h>
       9             : #include <vector>
      10             : 
      11             : #include "DataStructures/DataBox/DataBox.hpp"
      12             : #include "DataStructures/DataBox/ObservationBox.hpp"
      13             : #include "Options/Options.hpp"
      14             : #include "Options/String.hpp"
      15             : #include "ParallelAlgorithms/EventsAndTriggers/Event.hpp"
      16             : #include "ParallelAlgorithms/EventsAndTriggers/Trigger.hpp"
      17             : #include "Utilities/Gsl.hpp"
      18             : #include "Utilities/TMPL.hpp"
      19             : 
      20             : /// \cond
      21             : namespace Parallel {
      22             : template <typename Metavariables>
      23             : class GlobalCache;
      24             : }  // namespace Parallel
      25             : namespace db {
      26             : template <typename TagsList>
      27             : class DataBox;
      28             : }  // namespace db
      29             : /// \endcond
      30             : 
      31             : /// \ingroup EventsAndTriggersGroup
      32             : /// Class that checks triggers and runs events
      33           1 : class EventsAndTriggers {
      34             :  private:
      35             :   template <typename Event>
      36           0 :   struct get_tags {
      37           0 :     using type = typename Event::compute_tags_for_observation_box;
      38             :   };
      39             : 
      40             :  public:
      41           0 :   struct TriggerAndEvents {
      42           0 :     struct Trigger {
      43           0 :       using type = std::unique_ptr<::Trigger>;
      44           0 :       static constexpr Options::String help = "Determines when the Events run.";
      45             :     };
      46           0 :     struct Events {
      47           0 :       using type = std::vector<std::unique_ptr<::Event>>;
      48           0 :       static constexpr Options::String help =
      49             :           "These events run when the Trigger fires.";
      50             :     };
      51           0 :     static constexpr Options::String help =
      52             :         "Events that run when the Trigger fires.";
      53           0 :     using options = tmpl::list<Trigger, Events>;
      54           0 :     TriggerAndEvents();
      55           0 :     TriggerAndEvents(std::unique_ptr<::Trigger> trigger_in,
      56             :                      std::vector<std::unique_ptr<::Event>> events_in);
      57           0 :     void pup(PUP::er& p);
      58           0 :     std::unique_ptr<::Trigger> trigger;
      59           0 :     std::vector<std::unique_ptr<::Event>> events;
      60             :   };
      61             : 
      62           0 :   using Storage = std::vector<TriggerAndEvents>;
      63             : 
      64           0 :   EventsAndTriggers();
      65           0 :   explicit EventsAndTriggers(Storage events_and_triggers);
      66             : 
      67             :   /// Check the triggers and run the associated events.
      68             :   ///
      69             :   /// By default the trigger check just calls the `is_triggered`
      70             :   /// method, but the last argument can be passed to override this.
      71             :   /// It must be a functor taking a `const Trigger&` and returning
      72             :   /// `bool`.
      73             :   template <typename DbTags, typename Metavariables, typename ArrayIndex,
      74             :             typename Component, typename CheckTrigger = std::nullptr_t>
      75           1 :   void run_events(const gsl::not_null<db::DataBox<DbTags>*> box,
      76             :                   Parallel::GlobalCache<Metavariables>& cache,
      77             :                   const ArrayIndex& array_index, const Component* component,
      78             :                   const Event::ObservationValue& observation_value,
      79             :                   const CheckTrigger& check_trigger = nullptr) const {
      80             :     using compute_tags = tmpl::remove_duplicates<tmpl::filter<
      81             :         tmpl::flatten<tmpl::transform<
      82             :             tmpl::at<typename Metavariables::factory_creation::factory_classes,
      83             :                      Event>,
      84             :             get_tags<tmpl::_1>>>,
      85             :         db::is_compute_tag<tmpl::_1>>>;
      86             :     std::optional<decltype(make_observation_box<compute_tags>(box))>
      87             :         observation_box{};
      88             :     for (const auto& trigger_and_events : events_and_triggers_) {
      89             :       const auto& trigger = trigger_and_events.trigger;
      90             :       const auto& events = trigger_and_events.events;
      91             :       const bool is_triggered = [&]() {
      92             :         if constexpr (std::is_same_v<std::decay_t<CheckTrigger>,
      93             :                                      std::nullptr_t>) {
      94             :           return trigger->is_triggered(*box);
      95             :         } else {
      96             :           return check_trigger(std::as_const(*trigger));
      97             :         }
      98             :       }();
      99             :       if (is_triggered) {
     100             :         if (not observation_box.has_value()) {
     101             :           observation_box = make_observation_box<compute_tags>(box);
     102             :         }
     103             :         for (const auto& event : events) {
     104             :           event->run(make_not_null(&observation_box.value()), cache,
     105             :                      array_index, component, observation_value);
     106             :         }
     107             :       }
     108             :     }
     109             :   }
     110             : 
     111             :   // NOLINTNEXTLINE(google-runtime-references)
     112           0 :   void pup(PUP::er& p);
     113             : 
     114             :   template <typename F>
     115           0 :   void for_each_event(F&& f) const {
     116             :     for (const auto& trigger_and_events : events_and_triggers_) {
     117             :       for (const auto& event : trigger_and_events.events) {
     118             :         f(*event);
     119             :       }
     120             :     }
     121             :   }
     122             : 
     123             :  private:
     124             :   // The unique pointer contents *must* be treated as const everywhere
     125             :   // in order to make the const global cache behave sanely.  They are
     126             :   // only non-const to make pup work.
     127           0 :   Storage events_and_triggers_;
     128             : };
     129             : 
     130             : template <>
     131           0 : struct Options::create_from_yaml<EventsAndTriggers> {
     132           0 :   using type = EventsAndTriggers;
     133             :   template <typename Metavariables>
     134           0 :   static type create(const Options::Option& options) {
     135             :     return type(options.parse_as<typename type::Storage, Metavariables>());
     136             :   }
     137             : };

Generated by: LCOV version 1.14