Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstddef>
7 :
8 : #include "DataStructures/DataBox/DataBox.hpp"
9 : #include "DataStructures/TaggedTuple.hpp"
10 : #include "Domain/Structure/Element.hpp"
11 : #include "Domain/Structure/ElementId.hpp"
12 : #include "IO/Logging/Tags.hpp"
13 : #include "IO/Logging/Verbosity.hpp"
14 : #include "NumericalAlgorithms/Convergence/HasConverged.hpp"
15 : #include "NumericalAlgorithms/Convergence/Tags.hpp"
16 : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
17 : #include "Parallel/AlgorithmExecution.hpp"
18 : #include "Parallel/GlobalCache.hpp"
19 : #include "Parallel/Printf/Printf.hpp"
20 : #include "ParallelAlgorithms/Amr/Protocols/Projector.hpp"
21 : #include "ParallelAlgorithms/Amr/Tags.hpp"
22 : #include "Utilities/ProtocolHelpers.hpp"
23 : #include "Utilities/TMPL.hpp"
24 :
25 : /// Actions to control the elliptic AMR algorithm
26 0 : namespace elliptic::amr::Actions {
27 :
28 : /*!
29 : * \brief Initializes items for the elliptic AMR algorithm projector
30 : *
31 : * When projecting these items during h-AMR, they are copied from the parent or
32 : * children to retain the AMR state.
33 : */
34 1 : struct Initialize : tt::ConformsTo<::amr::protocols::Projector> {
35 : private:
36 0 : using iteration_id_tag =
37 : Convergence::Tags::IterationId<::amr::OptionTags::AmrGroup>;
38 0 : using num_iterations_tag =
39 : Convergence::Tags::Iterations<::amr::OptionTags::AmrGroup>;
40 0 : using has_converged_tag =
41 : Convergence::Tags::HasConverged<::amr::OptionTags::AmrGroup>;
42 :
43 : public: // Initialization mutator
44 0 : using simple_tags = tmpl::list<iteration_id_tag, has_converged_tag>;
45 0 : using compute_tags = tmpl::list<>;
46 0 : using simple_tags_from_options = tmpl::list<>;
47 0 : using const_global_cache_tags = tmpl::list<num_iterations_tag>;
48 0 : using mutable_global_cache_tags = tmpl::list<>;
49 0 : using return_tags = simple_tags;
50 0 : using argument_tags = tmpl::list<num_iterations_tag>;
51 :
52 0 : static void apply(
53 : const gsl::not_null<size_t*> amr_iteration_id,
54 : const gsl::not_null<Convergence::HasConverged*> amr_has_converged,
55 : const size_t num_iterations) {
56 : *amr_iteration_id = 0;
57 : *amr_has_converged = Convergence::HasConverged{num_iterations, 0};
58 : }
59 :
60 : public: // amr::protocols::Projector
61 : // p-refinement
62 : template <size_t Dim>
63 0 : static void apply(
64 : const gsl::not_null<size_t*> /*amr_iteration_id*/,
65 : const gsl::not_null<Convergence::HasConverged*> /*amr_has_converged*/,
66 : const size_t /*num_iterations*/,
67 : const std::pair<Mesh<Dim>, Element<Dim>>& /*old_mesh_and_element*/) {}
68 :
69 : // h-refinement
70 : template <typename... ParentTags>
71 0 : static void apply(
72 : const gsl::not_null<size_t*> amr_iteration_id,
73 : const gsl::not_null<Convergence::HasConverged*> amr_has_converged,
74 : const size_t /*num_iterations*/,
75 : const tuples::TaggedTuple<ParentTags...>& parent_items) {
76 : *amr_iteration_id = get<iteration_id_tag>(parent_items);
77 : *amr_has_converged = get<has_converged_tag>(parent_items);
78 : }
79 :
80 : // h-coarsening
81 : template <size_t Dim, typename... ChildTags>
82 0 : static void apply(
83 : const gsl::not_null<size_t*> amr_iteration_id,
84 : const gsl::not_null<Convergence::HasConverged*> amr_has_converged,
85 : const size_t /*num_iterations*/,
86 : const std::unordered_map<
87 : ElementId<Dim>, tuples::TaggedTuple<ChildTags...>>& children_items) {
88 : *amr_iteration_id = get<iteration_id_tag>(children_items.begin()->second);
89 : *amr_has_converged = get<has_converged_tag>(children_items.begin()->second);
90 : }
91 : };
92 :
93 : /// Increment the AMR iteration ID and determine convergence
94 1 : struct IncrementIterationId {
95 : private:
96 0 : using iteration_id_tag =
97 : Convergence::Tags::IterationId<::amr::OptionTags::AmrGroup>;
98 0 : using num_iterations_tag =
99 : Convergence::Tags::Iterations<::amr::OptionTags::AmrGroup>;
100 0 : using has_converged_tag =
101 : Convergence::Tags::HasConverged<::amr::OptionTags::AmrGroup>;
102 :
103 : public:
104 : template <typename DataBox, typename... InboxTags, typename Metavariables,
105 : typename ArrayIndex, typename ActionList,
106 : typename ParallelComponent>
107 0 : static Parallel::iterable_action_return_t apply(
108 : DataBox& box, const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
109 : const Parallel::GlobalCache<Metavariables>& /*cache*/,
110 : const ArrayIndex& element_id, const ActionList /*meta*/,
111 : const ParallelComponent* const /*meta*/) {
112 : const size_t num_iterations = get<num_iterations_tag>(box);
113 : // Increment AMR iteration id and determine convergence
114 : db::mutate<iteration_id_tag, has_converged_tag>(
115 : [&num_iterations](
116 : const gsl::not_null<size_t*> iteration_id,
117 : const gsl::not_null<Convergence::HasConverged*> has_converged) {
118 : ++(*iteration_id);
119 : *has_converged =
120 : Convergence::HasConverged{num_iterations, *iteration_id};
121 : },
122 : make_not_null(&box));
123 : // Do some logging
124 : if (db::get<logging::Tags::Verbosity<::amr::OptionTags::AmrGroup>>(box) >=
125 : ::Verbosity::Debug) {
126 : Parallel::printf("%s AMR iteration %zu / %zu\n", element_id,
127 : db::get<iteration_id_tag>(box), num_iterations);
128 : }
129 : return {Parallel::AlgorithmExecution::Continue, std::nullopt};
130 : }
131 : };
132 :
133 : /// Stop the algorithm if it has converged
134 1 : struct StopAmr {
135 : private:
136 0 : using has_converged_tag =
137 : Convergence::Tags::HasConverged<::amr::OptionTags::AmrGroup>;
138 :
139 : public:
140 : template <typename DataBox, typename... InboxTags, typename Metavariables,
141 : typename ArrayIndex, typename ActionList,
142 : typename ParallelComponent>
143 0 : static Parallel::iterable_action_return_t apply(
144 : DataBox& box, const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
145 : const Parallel::GlobalCache<Metavariables>& /*cache*/,
146 : const ArrayIndex& /*element_id*/, const ActionList /*meta*/,
147 : const ParallelComponent* const /*meta*/) {
148 : return {db::get<has_converged_tag>(box)
149 : ? Parallel::AlgorithmExecution::Pause
150 : : Parallel::AlgorithmExecution::Continue,
151 : std::nullopt};
152 : }
153 : };
154 :
155 : } // namespace elliptic::amr::Actions
|