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

Generated by: LCOV version 1.14