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 "Domain/Structure/Element.hpp" 10 : #include "Domain/Structure/ElementId.hpp" 11 : #include "IO/Logging/Tags.hpp" 12 : #include "IO/Logging/Verbosity.hpp" 13 : #include "NumericalAlgorithms/Convergence/HasConverged.hpp" 14 : #include "NumericalAlgorithms/Convergence/Tags.hpp" 15 : #include "NumericalAlgorithms/Spectral/Mesh.hpp" 16 : #include "Parallel/AlgorithmExecution.hpp" 17 : #include "Parallel/GlobalCache.hpp" 18 : #include "Parallel/Printf/Printf.hpp" 19 : #include "ParallelAlgorithms/Amr/Protocols/Projector.hpp" 20 : #include "ParallelAlgorithms/Amr/Tags.hpp" 21 : #include "Utilities/ProtocolHelpers.hpp" 22 : #include "Utilities/TMPL.hpp" 23 : #include "Utilities/TaggedTuple.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