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
|