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