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 : #include <pup.h> 8 : 9 : #include "Domain/Amr/Flag.hpp" 10 : #include "Domain/Structure/ElementId.hpp" 11 : #include "Options/String.hpp" 12 : #include "Parallel/GlobalCache.hpp" 13 : #include "ParallelAlgorithms/Amr/Criteria/Criterion.hpp" 14 : #include "Utilities/MakeArray.hpp" 15 : #include "Utilities/Serialization/CharmPupable.hpp" 16 : #include "Utilities/TMPL.hpp" 17 : 18 : namespace amr::Criteria { 19 : /*! 20 : * \brief Randomly h-refine (or coarsen) an Element in each dimension. 21 : * 22 : * \details Let \f$f\f$ be `ChangeRefinementFraction`, \f$L_{max}\f$ be 23 : * `MaximumRefinementLevel`, and \f$L_d\f$ be the current refinement level 24 : * of an Element in a particular dimension. In each dimension, a random 25 : * number \f$r_d \in [0, 1]\f$ is generated. If \f$r_d > f\f$ the refinement 26 : * flag is set to amr::Flags::DoNothing. If \f$r_d < f L_d / L_{max}\f$ 27 : * the refinement flag is set to amr::Flags::Join. Otherwise the 28 : * refinement flag is set to amr::Flag::Split. 29 : * 30 : * \note This criterion is primarily useful for testing the mechanics of 31 : * h-refinement 32 : */ 33 1 : class Random : public Criterion { 34 : public: 35 : /// The fraction of the time random refinement does changes the grid 36 1 : struct ChangeRefinementFraction { 37 0 : using type = double; 38 0 : static constexpr Options::String help = { 39 : "The fraction of the time that random refinement will change the " 40 : "grid."}; 41 0 : static double lower_bound() { return 0.0; } 42 0 : static double upper_bound() { return 1.0; } 43 : }; 44 : 45 : /// The maximum allowed refinement level 46 1 : struct MaximumRefinementLevel { 47 0 : using type = size_t; 48 0 : static constexpr Options::String help = { 49 : "The maximum allowed refinement level."}; 50 0 : static size_t upper_bound() { return ElementId<3>::max_refinement_level; } 51 : }; 52 : 53 0 : using options = tmpl::list<ChangeRefinementFraction, MaximumRefinementLevel>; 54 : 55 0 : static constexpr Options::String help = { 56 : "Randomly h-refine (or coarsen) the grid"}; 57 : 58 0 : Random() = default; 59 : 60 0 : Random(const double do_something_fraction, 61 : const size_t maximum_refinement_level); 62 : 63 : /// \cond 64 : explicit Random(CkMigrateMessage* msg); 65 : using PUP::able::register_constructor; 66 : WRAPPED_PUPable_decl_template(Random); // NOLINT 67 : /// \endcond 68 : 69 0 : using compute_tags_for_observation_box = tmpl::list<>; 70 : 71 0 : using argument_tags = tmpl::list<>; 72 : 73 : template <typename Metavariables> 74 0 : auto operator()(Parallel::GlobalCache<Metavariables>& /*cache*/, 75 : const ElementId<Metavariables::volume_dim>& element_id) const; 76 : 77 0 : void pup(PUP::er& p) override; 78 : 79 : private: 80 0 : amr::Flag random_flag(size_t current_refinement_level) const; 81 : 82 0 : double do_something_fraction_{0.0}; 83 0 : size_t maximum_refinement_level_{0}; 84 : }; 85 : 86 : template <typename Metavariables> 87 : auto Random::operator()( 88 : Parallel::GlobalCache<Metavariables>& /*cache*/, 89 : const ElementId<Metavariables::volume_dim>& element_id) const { 90 : constexpr size_t volume_dim = Metavariables::volume_dim; 91 : auto result = make_array<volume_dim>(amr::Flag::Undefined); 92 : for (size_t d = 0; d < volume_dim; ++d) { 93 : result[d] = random_flag(element_id.segment_ids()[d].refinement_level()); 94 : } 95 : return result; 96 : } 97 : } // namespace amr::Criteria