Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <optional> 7 : 8 : #include "DataStructures/DataBox/DataBox.hpp" 9 : #include "DataStructures/DataBox/TagName.hpp" 10 : #include "Parallel/AlgorithmExecution.hpp" 11 : #include "Parallel/GlobalCache.hpp" 12 : #include "ParallelAlgorithms/EventsAndTriggers/Tags.hpp" 13 : #include "Time/SelfStart.hpp" 14 : #include "Time/Tags/Time.hpp" 15 : #include "Time/Triggers/OnSubsteps.hpp" 16 : #include "Utilities/Gsl.hpp" 17 : #include "Utilities/TMPL.hpp" 18 : #include "Utilities/TaggedTuple.hpp" 19 : 20 : /// \cond 21 : namespace Tags { 22 : struct TimeStepId; 23 : } // namespace Tags 24 : /// \endcond 25 : 26 : namespace evolution::Actions { 27 : /// \ingroup ActionsGroup 28 : /// \ingroup EventsAndTriggersGroup 29 : /// \brief Run the events and triggers 30 : /// 31 : /// Triggers will only be checked on the first step of each slab to 32 : /// ensure that a consistent set of events is run across all elements. 33 : /// 34 : /// Uses: 35 : /// - GlobalCache: the EventsAndTriggers tag, as required by 36 : /// events and triggers 37 : /// - DataBox: as required by events and triggers 38 : /// 39 : /// DataBox changes: 40 : /// - Adds: nothing 41 : /// - Removes: nothing 42 : /// - Modifies: nothing 43 1 : struct RunEventsAndTriggers { 44 0 : using const_global_cache_tags = tmpl::list<::Tags::EventsAndTriggers>; 45 : 46 : template <typename DbTags, typename... InboxTags, typename Metavariables, 47 : typename ArrayIndex, typename ActionList, 48 : typename ParallelComponent> 49 0 : static Parallel::iterable_action_return_t apply( 50 : db::DataBox<DbTags>& box, tuples::TaggedTuple<InboxTags...>& /*inboxes*/, 51 : Parallel::GlobalCache<Metavariables>& cache, 52 : const ArrayIndex& array_index, const ActionList /*meta*/, 53 : const ParallelComponent* const component) { 54 : const auto time_step_id = db::get<::Tags::TimeStepId>(box); 55 : if (SelfStart::is_self_starting(time_step_id) or 56 : not time_step_id.step_time().is_at_slab_boundary()) { 57 : return {Parallel::AlgorithmExecution::Continue, std::nullopt}; 58 : } 59 : 60 : if (time_step_id.substep() == 0) { 61 : Parallel::get<::Tags::EventsAndTriggers>(cache).run_events( 62 : make_not_null(&box), cache, array_index, component, 63 : {db::tag_name<::Tags::Time>(), db::get<::Tags::Time>(box)}); 64 : } else { 65 : const double substep_offset = 1.0e6; 66 : const double observation_value = time_step_id.step_time().value() + 67 : substep_offset * time_step_id.substep(); 68 : 69 : Parallel::get<::Tags::EventsAndTriggers>(cache).run_events( 70 : make_not_null(&box), cache, array_index, component, 71 : {db::tag_name<::Tags::Time>(), observation_value}, 72 : [&box](const Trigger& trigger) { 73 : const auto* substep_trigger = 74 : dynamic_cast<const ::Triggers::OnSubsteps*>(&trigger); 75 : return substep_trigger != nullptr and 76 : substep_trigger->is_triggered(box); 77 : }); 78 : } 79 : 80 : return {Parallel::AlgorithmExecution::Continue, std::nullopt}; 81 : } 82 : }; 83 : } // namespace evolution::Actions