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 : #include <tuple> 8 : 9 : #include "DataStructures/DataBox/DataBox.hpp" 10 : #include "DataStructures/DataBox/ObservationBox.hpp" 11 : #include "DataStructures/DataBox/TagName.hpp" 12 : #include "Parallel/AlgorithmExecution.hpp" 13 : #include "Parallel/GlobalCache.hpp" 14 : #include "ParallelAlgorithms/EventsAndTriggers/Event.hpp" 15 : #include "ParallelAlgorithms/EventsAndTriggers/Tags.hpp" 16 : #include "Utilities/CloneUniquePtrs.hpp" 17 : #include "Utilities/ErrorHandling/FloatingPointExceptions.hpp" 18 : #include "Utilities/Gsl.hpp" 19 : #include "Utilities/TMPL.hpp" 20 : #include "Utilities/TaggedTuple.hpp" 21 : 22 : namespace Actions { 23 : /*! 24 : * \brief Invokes all events specified in `Tags::EventsRunAtCleanup`. 25 : * 26 : * Before running the events, floating point exceptions are disabled. This is 27 : * to allow manipulating data even if there are `NaN` or other problematic 28 : * values. We ultimately just want to be able to see the state of the 29 : * simulation at failure. 30 : * 31 : * This action is intended to be executed in the 32 : * `Parallel::Phase::PostFailureCleanup` phase. 33 : * 34 : * \note The simulation will almost certainly fail with different 35 : * elements at different times. 36 : */ 37 : template <typename ObservationId> 38 1 : struct RunEventsOnFailure { 39 : private: 40 : template <typename Event> 41 0 : struct get_tags { 42 0 : using type = typename Event::compute_tags_for_observation_box; 43 : }; 44 : 45 : public: 46 0 : using const_global_cache_tags = 47 : tmpl::list<::Tags::EventsRunAtCleanup, 48 : ::Tags::EventsRunAtCleanupObservationValue>; 49 : 50 : template <typename DbTags, typename... InboxTags, typename Metavariables, 51 : typename ArrayIndex, typename ActionList, 52 : typename ParallelComponent> 53 0 : static Parallel::iterable_action_return_t apply( 54 : db::DataBox<DbTags>& box, tuples::TaggedTuple<InboxTags...>& /*inboxes*/, 55 : Parallel::GlobalCache<Metavariables>& cache, 56 : const ArrayIndex& array_index, const ActionList /*meta*/, 57 : const ParallelComponent* const component) { 58 : // We explicitly disable FPEs because we are dumping during a failure and 59 : // so can't rely on the data being safe. 60 : disable_floating_point_exceptions(); 61 : 62 : const Event::ObservationValue observation_value{ 63 : db::tag_name<ObservationId>(), 64 : db::get<Tags::EventsRunAtCleanupObservationValue>(box)}; 65 : 66 : using compute_tags = tmpl::remove_duplicates<tmpl::filter< 67 : tmpl::flatten<tmpl::transform< 68 : tmpl::at<typename Metavariables::factory_creation::factory_classes, 69 : Event>, 70 : get_tags<tmpl::_1>>>, 71 : db::is_compute_tag<tmpl::_1>>>; 72 : std::optional observation_box{ 73 : make_observation_box<compute_tags>(make_not_null(&box))}; 74 : 75 : for (const auto& event : db::get<::Tags::EventsRunAtCleanup>(box)) { 76 : event->run(make_not_null(&observation_box.value()), cache, array_index, 77 : component, observation_value); 78 : } 79 : 80 : // Do not re-enable FPEs because other parts of the pipeline might rely on 81 : // them being disabled. We generally have them disabled during cleanup. 82 : return {Parallel::AlgorithmExecution::Continue, std::nullopt}; 83 : } 84 : }; 85 : } // namespace Actions