Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <array>
7 : #include <cstddef>
8 : #include <optional>
9 : #include <unordered_map>
10 : #include <utility>
11 :
12 : #include "NumericalAlgorithms/Spectral/Hash.hpp"
13 : #include "Options/Auto.hpp"
14 : #include "Options/Context.hpp"
15 : #include "Options/String.hpp"
16 : #include "Utilities/TMPL.hpp"
17 :
18 : /// \cond
19 : namespace PUP {
20 : class er;
21 : } // namespace PUP
22 : namespace Spectral {
23 : enum class Basis : uint8_t;
24 : enum class Quadrature : uint8_t;
25 : } // namespace Spectral
26 : /// \endcond
27 :
28 : namespace amr {
29 : /// \brief The limits on refinement level and resolution for AMR
30 : ///
31 : /// \details
32 : /// - For a default constructed Limits, the refinement level is
33 : /// bounded between 0 and ElementId<Dim>::max_refinement_level, and the
34 : /// resolution is bounded between Spectral::limits::min and
35 : /// Spectral::limits::max which are limits based on the implementation details
36 : /// of ElementId and Mesh. ErrorBeyondLimits is set to false.
37 : /// - Specifying `Auto` for any option uses the above limits.
38 : /// - If you specify a lower bound that violates the above limits, the limit
39 : /// will be raised to that needed by the code.
40 : /// - If you specify an upper bound that violates the above limits, the code
41 : /// will error on parsing the option.
42 1 : class Limits {
43 : public:
44 : /// Inclusive bounds on the refinement level
45 1 : struct RefinementLevel {
46 0 : using type = Options::Auto<std::array<size_t, 2>>;
47 0 : static constexpr Options::String help = {
48 : "Inclusive bounds on the refinement level for AMR."};
49 : };
50 :
51 : /// Inclusive bounds on the number of polynomial modes for a I1 or B1 topology
52 1 : struct NumPolynomialModes {
53 0 : using type = Options::Auto<std::array<size_t, 2>>;
54 0 : static constexpr Options::String help = {
55 : "Inclusive bounds on the number of polynomial modes for a I1 or B1 "
56 : "topology."};
57 : };
58 :
59 : /// Inclusive bounds on the \f$m\f$ of Fourier modes for a S1 or B2 topology
60 1 : struct FourierM {
61 0 : using type = Options::Auto<std::array<size_t, 2>>;
62 0 : static constexpr Options::String help = {
63 : "Inclusive bounds on m for the Fourier series in topology S1 or B2."};
64 : };
65 :
66 : /// Inclusive bounds on the \f$\ell\f$ of spherical harmonic modes
67 1 : struct SphericalHarmonicL {
68 0 : using type = Options::Auto<std::array<size_t, 2>>;
69 0 : static constexpr Options::String help = {
70 : "Inclusive bounds on l for spherical harmonics in topology S2 or B3."};
71 : };
72 :
73 : /// \brief Whether the code should error if EnforcePolicies has to prevent
74 : /// refinement from going beyond the given limits.
75 : ///
76 : /// \details The Limits class is just a holder for this value, the actual
77 : /// error happens in `amr::Actions::EvaluateRefinementCriteria` or
78 : /// `amr::Events::RefineMesh`
79 1 : struct ErrorBeyondLimits {
80 0 : using type = bool;
81 0 : static constexpr Options::String help = {
82 : "If adaptive mesh refinement tries to go beyond the RefinementLevel or "
83 : "NumGridPoints limit, error"};
84 : };
85 :
86 0 : using options = tmpl::list<RefinementLevel, NumPolynomialModes, FourierM,
87 : SphericalHarmonicL, ErrorBeyondLimits>;
88 :
89 0 : static constexpr Options::String help = {
90 : "Limits on refinement level and resolution for adaptive mesh "
91 : "refinement."};
92 :
93 0 : Limits();
94 :
95 0 : Limits(const std::optional<std::array<size_t, 2>>& refinement_level_bounds,
96 : const std::optional<std::array<size_t, 2>>& polynomial_mode_bounds,
97 : const std::optional<std::array<size_t, 2>>& fourier_mode_bounds,
98 : const std::optional<std::array<size_t, 2>>& spherical_harmonic_bounds,
99 : bool error_beyond_limits, const Options::Context& context = {});
100 :
101 0 : size_t minimum_refinement_level() const { return minimum_refinement_level_; }
102 0 : size_t maximum_refinement_level() const { return maximum_refinement_level_; }
103 0 : size_t minimum_resolution(Spectral::Basis basis,
104 : Spectral::Quadrature quadrature) const;
105 0 : size_t maximum_resolution(Spectral::Basis basis,
106 : Spectral::Quadrature quadrature) const;
107 0 : bool error_beyond_limits() const { return error_beyond_limits_; }
108 :
109 0 : std::ostream& print(std::ostream& os) const;
110 0 : void pup(PUP::er& p);
111 :
112 : private:
113 0 : friend bool operator==(const Limits& lhs, const Limits& rhs);
114 0 : size_t minimum_refinement_level_{0};
115 0 : size_t maximum_refinement_level_{16};
116 : std::unordered_map<std::pair<Spectral::Basis, Spectral::Quadrature>, size_t>
117 0 : minimum_resolution_;
118 : std::unordered_map<std::pair<Spectral::Basis, Spectral::Quadrature>, size_t>
119 0 : maximum_resolution_;
120 0 : bool error_beyond_limits_{false};
121 : };
122 :
123 0 : std::ostream& operator<<(std::ostream& os, const Limits& limits);
124 :
125 0 : bool operator!=(const Limits& lhs, const Limits& rhs);
126 : } // namespace amr
|