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 <limits> 8 : #include <pup.h> 9 : #include <unordered_map> 10 : 11 : #include "Domain/Amr/Flag.hpp" 12 : #include "Domain/Structure/ElementId.hpp" 13 : #include "Options/String.hpp" 14 : #include "Parallel/GlobalCache.hpp" 15 : #include "ParallelAlgorithms/Amr/Criteria/Criterion.hpp" 16 : #include "Utilities/MakeArray.hpp" 17 : #include "Utilities/Serialization/CharmPupable.hpp" 18 : #include "Utilities/TMPL.hpp" 19 : 20 : namespace amr::Criteria { 21 : namespace detail { 22 : amr::Flag random_flag( 23 : const std::unordered_map<amr::Flag, size_t>& probability_weights); 24 : } // namespace detail 25 : 26 : /*! 27 : * \brief Randomly refine (or coarsen) an Element in each dimension. 28 : * 29 : * You can specify a probability for each possible `amr::Flag`. It is evaluated 30 : * in each dimension separately. Details: 31 : * 32 : * - Probabilities are specified as integer weights. The probability for an 33 : * `amr::Flag` is its weight over the sum of all weights. 34 : * - Flags with weight zero do not need to be specified. 35 : * - If all weights are zero, `amr::Flag::DoNothing` is always chosen. 36 : */ 37 1 : class Random : public Criterion { 38 : public: 39 0 : struct ProbabilityWeights { 40 0 : using type = std::unordered_map<amr::Flag, size_t>; 41 0 : static constexpr Options::String help = { 42 : "Possible refinement types and their probability, specified as integer " 43 : "weights. The probability for a refinement type is its weight over the " 44 : "sum of all weights. For example, set 'Split: 1' and 'DoNothing: 4' to " 45 : "split each element with 20% probability. The refinement is evaluated " 46 : "in each dimension separately."}; 47 : }; 48 : 49 0 : using options = tmpl::list<ProbabilityWeights>; 50 : 51 0 : static constexpr Options::String help = { 52 : "Randomly refine (or coarsen) the grid"}; 53 : 54 0 : Random() = default; 55 : 56 0 : explicit Random(std::unordered_map<amr::Flag, size_t> probability_weights); 57 : 58 : /// \cond 59 : explicit Random(CkMigrateMessage* msg); 60 : using PUP::able::register_constructor; 61 : WRAPPED_PUPable_decl_template(Random); // NOLINT 62 : /// \endcond 63 : 64 0 : std::string observation_name() override { return "Random"; } 65 : 66 0 : using compute_tags_for_observation_box = tmpl::list<>; 67 : 68 0 : using argument_tags = tmpl::list<>; 69 : 70 : template <size_t Dim, typename Metavariables> 71 0 : auto operator()(Parallel::GlobalCache<Metavariables>& /*cache*/, 72 : const ElementId<Dim>& element_id) const; 73 : 74 0 : void pup(PUP::er& p) override; 75 : 76 : private: 77 0 : std::unordered_map<amr::Flag, size_t> probability_weights_{}; 78 : }; 79 : 80 : template <size_t Dim, typename Metavariables> 81 : auto Random::operator()(Parallel::GlobalCache<Metavariables>& /*cache*/, 82 : const ElementId<Dim>& /*element_id*/) const { 83 : auto result = make_array<Dim>(amr::Flag::Undefined); 84 : for (size_t d = 0; d < Dim; ++d) { 85 : result[d] = detail::random_flag(probability_weights_); 86 : } 87 : return result; 88 : } 89 : } // namespace amr::Criteria