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 <pup.h>
8 : #include <string>
9 : #include <type_traits>
10 : #include <utility>
11 :
12 : #include "DataStructures/TaggedTuple.hpp"
13 : #include "Evolution/Systems/GeneralizedHarmonic/Bbh/CompletionCriteria.hpp"
14 : #include "Options/String.hpp"
15 : #include "Parallel/GlobalCache.hpp"
16 : #include "Parallel/Phase.hpp"
17 : #include "Parallel/PhaseControl/ContributeToPhaseChangeReduction.hpp"
18 : #include "Parallel/PhaseControl/PhaseChange.hpp"
19 : #include "Utilities/ErrorHandling/Error.hpp"
20 : #include "Utilities/Functional.hpp"
21 : #include "Utilities/Serialization/CharmPupable.hpp"
22 : #include "Utilities/TMPL.hpp"
23 :
24 0 : namespace gh::bbh::phase_control {
25 0 : namespace Tags {
26 : /// Storage in the phase-change decision tuple for whether the
27 : /// BBH completion path has requested completion.
28 1 : struct CheckpointRequested {
29 0 : using type = bool;
30 0 : using combine_method = funcl::Or<>;
31 0 : using main_combine_method = funcl::Or<>;
32 : };
33 :
34 : /// Storage in the phase-change decision tuple for jumping from
35 : /// `WriteCheckpoint` to `Exit`.
36 1 : struct ExitAfterWriteCheckpoint {
37 0 : using type = bool;
38 :
39 0 : struct combine_method {
40 0 : bool operator()(const bool /*first*/, const bool /*second*/) {
41 : ERROR(
42 : "ExitAfterWriteCheckpoint should only be modified during "
43 : "phase-change arbitration on Main.");
44 : }
45 : };
46 :
47 0 : using main_combine_method = combine_method;
48 : };
49 : } // namespace Tags
50 :
51 : /*!
52 : * \brief If BBH completion has been requested, jump from `Evolve` to
53 : * `WriteCheckpoint`, then immediately to `Exit`.
54 : *
55 : * \details The `WriteCheckpoint` phase executes checkpoint actions, typically
56 : * including final volume data writes, as specified by
57 : * `EventsAndTriggersAtCheckpoints`.
58 : */
59 1 : struct CheckpointAndExitIfComplete : public PhaseChange {
60 : /// \cond
61 : CheckpointAndExitIfComplete() = default;
62 : explicit CheckpointAndExitIfComplete(CkMigrateMessage* /*unused*/) {}
63 : using PUP::able::register_constructor;
64 : WRAPPED_PUPable_decl_template(CheckpointAndExitIfComplete); // NOLINT
65 : /// \endcond
66 :
67 0 : static std::string name() { return "BbhCheckpointAndExitIfComplete"; }
68 0 : using options = tmpl::list<>;
69 0 : static constexpr Options::String help{
70 : "When BBH completion has been requested, jump from Evolve to "
71 : "WriteCheckpoint so all elements write final volume data at a "
72 : "synchronized time, then jump to Exit."};
73 :
74 0 : using argument_tags = tmpl::list<gh::bbh::Tags::ElementCompletionRequested>;
75 0 : using return_tags = tmpl::list<>;
76 :
77 0 : using phase_change_tags_and_combines =
78 : tmpl::list<Tags::CheckpointRequested, Tags::ExitAfterWriteCheckpoint>;
79 :
80 : template <typename Metavariables>
81 0 : using participating_components = typename Metavariables::component_list;
82 :
83 : template <typename... DecisionTags>
84 0 : void initialize_phase_data_impl(
85 : const gsl::not_null<tuples::TaggedTuple<DecisionTags...>*>
86 : phase_change_decision_data) const {
87 : tuples::get<Tags::CheckpointRequested>(*phase_change_decision_data) = false;
88 : tuples::get<Tags::ExitAfterWriteCheckpoint>(*phase_change_decision_data) =
89 : false;
90 : }
91 :
92 : template <typename ParallelComponent, typename ArrayIndex,
93 : typename Metavariables>
94 0 : void contribute_phase_data_impl(const bool element_completion_requested,
95 : Parallel::GlobalCache<Metavariables>& cache,
96 : const ArrayIndex& array_index) const {
97 : if constexpr (std::is_same_v<typename ParallelComponent::chare_type,
98 : Parallel::Algorithms::Array>) {
99 : Parallel::contribute_to_phase_change_reduction<ParallelComponent>(
100 : tuples::TaggedTuple<Tags::CheckpointRequested>{
101 : element_completion_requested},
102 : cache, array_index);
103 : } else {
104 : Parallel::contribute_to_phase_change_reduction<ParallelComponent>(
105 : tuples::TaggedTuple<Tags::CheckpointRequested>{
106 : element_completion_requested},
107 : cache);
108 : }
109 : }
110 :
111 : template <typename... DecisionTags, typename Metavariables>
112 : std::optional<std::pair<Parallel::Phase, PhaseControl::ArbitrationStrategy>>
113 0 : arbitrate_phase_change_impl(
114 : const gsl::not_null<tuples::TaggedTuple<DecisionTags...>*>
115 : phase_change_decision_data,
116 : const Parallel::Phase current_phase,
117 : const Parallel::GlobalCache<Metavariables>& /*cache*/) const {
118 : auto& checkpoint_requested =
119 : tuples::get<Tags::CheckpointRequested>(*phase_change_decision_data);
120 : auto& exit_after_write_checkpoint =
121 : tuples::get<Tags::ExitAfterWriteCheckpoint>(
122 : *phase_change_decision_data);
123 :
124 : if (current_phase == Parallel::Phase::WriteCheckpoint and
125 : exit_after_write_checkpoint) {
126 : exit_after_write_checkpoint = false;
127 : return std::make_pair(
128 : Parallel::Phase::Exit,
129 : PhaseControl::ArbitrationStrategy::RunPhaseImmediately);
130 : }
131 :
132 : if (current_phase == Parallel::Phase::Evolve and checkpoint_requested) {
133 : checkpoint_requested = false;
134 : exit_after_write_checkpoint = true;
135 : return std::make_pair(
136 : Parallel::Phase::WriteCheckpoint,
137 : PhaseControl::ArbitrationStrategy::RunPhaseImmediately);
138 : }
139 :
140 : checkpoint_requested = false;
141 : return std::nullopt;
142 : }
143 :
144 : // NOLINTNEXTLINE(google-runtime-references)
145 0 : void pup(PUP::er& p) override;
146 : };
147 : } // namespace gh::bbh::phase_control
|