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 : 8 : #include "DataStructures/DataBox/MetavariablesTag.hpp" 9 : #include "DataStructures/DataBox/ObservationBox.hpp" 10 : #include "Utilities/CallWithDynamicType.hpp" 11 : #include "Utilities/Serialization/CharmPupable.hpp" 12 : #include "Utilities/TMPL.hpp" 13 : 14 : /// \cond 15 : namespace Parallel { 16 : template <typename Metavariables> 17 : class GlobalCache; 18 : } // namespace Parallel 19 : /// \endcond 20 : 21 : /// \ingroup EventsAndTriggersGroup 22 : namespace Events {} 23 : 24 : /// \ingroup EventsAndTriggersGroup 25 : /// Base class for something that can happen during a simulation (such 26 : /// as an observation). 27 : /// 28 : /// Derived events must have a `compute_tags_for_observation_box` that is a 29 : /// `tmpl::list` of simple or compute tags. Simple tags are assumed to already 30 : /// be in the `DataBox`. Evolved variables, for example, would be listed as 31 : /// simple tags. The compute tags are used to compute additional quantities that 32 : /// may be observed. For example, in the scalar wave system the 1- and 2-index 33 : /// constraints would be added as compute tags, as well as anything they depend 34 : /// on that's not already in the `DataBox`. 35 1 : class Event : public PUP::able { 36 : protected: 37 : /// \cond 38 : Event() = default; 39 : Event(const Event&) = default; 40 : Event(Event&&) = default; 41 : Event& operator=(const Event&) = default; 42 : Event& operator=(Event&&) = default; 43 : /// \endcond 44 : 45 : public: 46 0 : ~Event() override = default; 47 0 : explicit Event(CkMigrateMessage* msg) : PUP::able(msg) {} 48 : 49 0 : WRAPPED_PUPable_abstract(Event); // NOLINT 50 : 51 0 : struct ObservationValue { 52 0 : std::string name{}; 53 0 : double value = std::numeric_limits<double>::signaling_NaN(); 54 : }; 55 : 56 : template <typename ComputeTagsList, typename DataBoxType, 57 : typename Metavariables, typename ArrayIndex, 58 : typename ComponentPointer> 59 0 : void run( 60 : const gsl::not_null<ObservationBox<ComputeTagsList, DataBoxType>*> box, 61 : Parallel::GlobalCache<Metavariables>& cache, 62 : const ArrayIndex& array_index, const ComponentPointer /*meta*/, 63 : const ObservationValue& observation_value) const { 64 : using factory_classes = 65 : typename std::decay_t<Metavariables>::factory_creation::factory_classes; 66 : call_with_dynamic_type<void, tmpl::at<factory_classes, Event>>( 67 : this, [&](auto* const event) { 68 : mutate_apply(*event, box, cache, array_index, ComponentPointer{}, 69 : observation_value); 70 : }); 71 : } 72 : 73 : template <typename DbTags, typename Metavariables, typename ArrayIndex, 74 : typename ComponentPointer> 75 0 : bool is_ready(const db::DataBox<DbTags>& box, 76 : Parallel::GlobalCache<Metavariables>& cache, 77 : const ArrayIndex& array_index, 78 : const ComponentPointer /*meta*/) const { 79 : using factory_classes = 80 : typename std::decay_t<decltype(db::get<Parallel::Tags::Metavariables>( 81 : box))>::factory_creation::factory_classes; 82 : return call_with_dynamic_type<bool, tmpl::at<factory_classes, Event>>( 83 : this, [&box, &cache, &array_index](auto* const event) { 84 : return db::apply< 85 : typename std::decay_t<decltype(*event)>::is_ready_argument_tags>( 86 : [&event, &cache, &array_index](const auto&... args) { 87 : return event->is_ready(args..., cache, array_index, 88 : ComponentPointer{}); 89 : }, 90 : box); 91 : }); 92 : } 93 : 94 : /// Whether the event uses anything depending on the 95 : /// evolved_variables. If this returns false, anything depending on 96 : /// the evolved variables may have an incorrect value when the event 97 : /// is run. 98 1 : virtual bool needs_evolved_variables() const = 0; 99 : };