SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/EventsAndTriggers - EventsAndTriggers.hpp Hit Total Coverage
Commit: 3c072f0ce967e2e56649d3fa12aa2a0e4fe2a42e Lines: 2 26 7.7 %
Date: 2024-04-23 20:50:18
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>  // IWYU pragma: keep
       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 :     void pup(PUP::er& p) {
      54             :       p | trigger;
      55             :       p | events;
      56             :     }
      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() = default;
      64           0 :   explicit EventsAndTriggers(Storage events_and_triggers)
      65             :       : events_and_triggers_(std::move(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) { p | events_and_triggers_; }
     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