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