Minmod.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <array>
7 #include <cstdlib>
8 #include <unordered_map>
9 #include <utility>
10 
11 #include "DataStructures/Tags.hpp" // IWYU pragma: keep
13 #include "Domain/Tags.hpp"
14 #include "Evolution/DiscontinuousGalerkin/Limiters/Minmod.hpp"
15 #include "Evolution/DiscontinuousGalerkin/Limiters/MinmodType.hpp"
16 #include "Evolution/DiscontinuousGalerkin/Limiters/Tags.hpp"
17 #include "Evolution/Systems/NewtonianEuler/Limiters/VariablesToLimit.hpp"
18 #include "Evolution/Systems/NewtonianEuler/Tags.hpp"
19 #include "Options/Options.hpp"
20 #include "PointwiseFunctions/Hydro/EquationsOfState/EquationOfState.hpp"
21 #include "PointwiseFunctions/Hydro/TagsDeclarations.hpp"
22 #include "Utilities/Gsl.hpp"
23 #include "Utilities/TMPL.hpp"
24 
25 /// \cond
26 class DataVector;
27 template <size_t VolumeDim>
28 class Direction;
29 template <size_t VolumeDim>
30 class Element;
31 template <size_t VolumeDim>
32 class ElementId;
33 template <size_t VolumeDim>
34 class Mesh;
35 template <size_t VolumeDim>
36 class OrientationMap;
37 
38 namespace boost {
39 template <class T>
40 struct hash;
41 } // namespace boost
42 
43 namespace PUP {
44 class er;
45 } // namespace PUP
46 
47 namespace domain {
48 namespace Tags {
49 template <size_t Dim, typename Frame>
50 struct Coordinates;
51 template <size_t VolumeDim>
52 struct Element;
53 template <size_t VolumeDim>
54 struct Mesh;
55 template <size_t VolumeDim>
56 struct SizeOfElement;
57 } // namespace Tags
58 } // namespace domain
59 /// \endcond
60 
61 namespace NewtonianEuler {
62 namespace Limiters {
63 
64 /// \ingroup LimitersGroup
65 /// \brief A minmod-based generalized slope limiter for the NewtonianEuler
66 /// system.
67 ///
68 /// Implements the three minmod-based generalized slope limiters from
69 /// \cite Cockburn1999 Sec. 2.4: \f$\Lambda\Pi^1\f$, \f$\Lambda\Pi^N\f$, and
70 /// MUSCL. See the documentation of the system-agnostic ::Limiters::Minmod
71 /// limiter for a general discussion of the algorithm and the various options
72 /// that control the action of the limiter.
73 ///
74 /// This implemention is specialized to the NewtonianEuler evolution system.
75 /// By specializing the limiter to the system, we can add two features that
76 /// improve its robustness:
77 /// - the limiter can be applied to the system's characteristic variables. This
78 /// is the recommendation of the reference, because it reduces spurious
79 /// oscillations in the post-limiter solution.
80 /// - after limiting, the solution can be processed to remove any remaining
81 /// unphysical values like negative densities and pressures. We do this by
82 /// scaling the solution around its mean (a "flattener" or "bounds-preserving"
83 /// filter). Note: the flattener is applied to all elements, including those
84 /// where the limiter did not act to reduce the solution's slopes.
85 template <size_t VolumeDim>
86 class Minmod {
87  public:
89  VolumeDim, tmpl::list<NewtonianEuler::Tags::MassDensityCons,
92 
95  static type suggested_value() noexcept {
96  return NewtonianEuler::Limiters::VariablesToLimit::Characteristic;
97  }
98  static constexpr Options::String help = {
99  "Variable representation on which to apply the limiter"};
100  };
101  struct ApplyFlattener {
102  using type = bool;
103  static constexpr Options::String help = {
104  "Flatten after limiting to restore pointwise positivity"};
105  };
106  using options =
107  tmpl::list<typename ConservativeVarsMinmod::Type, VariablesToLimit,
108  typename ConservativeVarsMinmod::TvbConstant, ApplyFlattener,
109  typename ConservativeVarsMinmod::DisableForDebugging>;
110  static constexpr Options::String help = {
111  "A Minmod limiter specialized to the NewtonianEuler system"};
112  static std::string name() noexcept { return "NewtonianEulerMinmod"; };
113 
114  explicit Minmod(::Limiters::MinmodType minmod_type,
116  double tvb_constant, bool apply_flattener,
117  bool disable_for_debugging = false) noexcept;
118 
119  Minmod() noexcept = default;
120  Minmod(const Minmod& /*rhs*/) = default;
121  Minmod& operator=(const Minmod& /*rhs*/) = default;
122  Minmod(Minmod&& /*rhs*/) noexcept = default;
123  Minmod& operator=(Minmod&& /*rhs*/) noexcept = default;
124  ~Minmod() = default;
125 
126  // clang-tidy: google-runtime-references
127  void pup(PUP::er& p) noexcept; // NOLINT
128 
129  using PackagedData = typename ConservativeVarsMinmod::PackagedData;
130  using package_argument_tags =
131  typename ConservativeVarsMinmod::package_argument_tags;
132 
133  /// \brief Package data for sending to neighbor elements.
134  void package_data(
135  gsl::not_null<PackagedData*> packaged_data,
136  const Scalar<DataVector>& mass_density_cons,
137  const tnsr::I<DataVector, VolumeDim>& momentum_density,
138  const Scalar<DataVector>& energy_density, const Mesh<VolumeDim>& mesh,
139  const std::array<double, VolumeDim>& element_size,
140  const OrientationMap<VolumeDim>& orientation_map) const noexcept;
141 
142  using limit_tags =
143  tmpl::list<NewtonianEuler::Tags::MassDensityCons,
144  NewtonianEuler::Tags::MomentumDensity<VolumeDim>,
145  NewtonianEuler::Tags::EnergyDensity>;
146  using limit_argument_tags =
147  tmpl::list<domain::Tags::Mesh<VolumeDim>,
148  domain::Tags::Element<VolumeDim>,
149  domain::Tags::Coordinates<VolumeDim, Frame::Logical>,
150  domain::Tags::SizeOfElement<VolumeDim>,
151  domain::Tags::DetInvJacobian<Frame::Logical, Frame::Inertial>,
152  ::hydro::Tags::EquationOfStateBase>;
153 
154  /// \brief Limits the solution on the element.
155  template <size_t ThermodynamicDim>
156  bool operator()(
157  gsl::not_null<Scalar<DataVector>*> mass_density_cons,
158  gsl::not_null<tnsr::I<DataVector, VolumeDim>*> momentum_density,
159  gsl::not_null<Scalar<DataVector>*> energy_density,
160  const Mesh<VolumeDim>& mesh, const Element<VolumeDim>& element,
161  const tnsr::I<DataVector, VolumeDim, Frame::Logical>& logical_coords,
162  const std::array<double, VolumeDim>& element_size,
163  const Scalar<DataVector>& det_inv_logical_to_inertial_jacobian,
164  const EquationsOfState::EquationOfState<false, ThermodynamicDim>&
165  equation_of_state,
166  const std::unordered_map<
167  std::pair<Direction<VolumeDim>, ElementId<VolumeDim>>, PackagedData,
168  boost::hash<std::pair<Direction<VolumeDim>, ElementId<VolumeDim>>>>&
169  neighbor_data) const noexcept;
170 
171  private:
172  template <size_t LocalDim>
173  // NOLINTNEXTLINE(readability-redundant-declaration) false positive
174  friend bool operator==(const Minmod<LocalDim>& lhs,
175  const Minmod<LocalDim>& rhs) noexcept;
176 
177  ::Limiters::MinmodType minmod_type_;
178  NewtonianEuler::Limiters::VariablesToLimit vars_to_limit_;
179  double tvb_constant_;
180  bool apply_flattener_;
181  bool disable_for_debugging_;
182  ConservativeVarsMinmod conservative_vars_minmod_;
183 };
184 
185 template <size_t VolumeDim>
186 bool operator!=(const Minmod<VolumeDim>& lhs,
187  const Minmod<VolumeDim>& rhs) noexcept;
188 
189 } // namespace Limiters
190 } // namespace NewtonianEuler
EquationsOfState
Contains all equations of state, including base class.
Definition: DarkEnergyFluid.hpp:26
Limiters
Things relating to limiting.
Definition: HwenoImpl.hpp:42
std::string
utility
NewtonianEuler::Limiters::Minmod
A minmod-based generalized slope limiter for the NewtonianEuler system.
Definition: Minmod.hpp:86
NewtonianEuler::Limiters::Minmod::package_data
void package_data(gsl::not_null< PackagedData * > packaged_data, const Scalar< DataVector > &mass_density_cons, const tnsr::I< DataVector, VolumeDim > &momentum_density, const Scalar< DataVector > &energy_density, const Mesh< VolumeDim > &mesh, const std::array< double, VolumeDim > &element_size, const OrientationMap< VolumeDim > &orientation_map) const noexcept
Package data for sending to neighbor elements.
Options.hpp
Tags.hpp
NewtonianEuler::Limiters::Minmod::ApplyFlattener
Definition: Minmod.hpp:101
NewtonianEuler
Items related to evolving the Newtonian Euler system.
Definition: EvolveNewtonianEulerFwd.hpp:8
OrientationMap
A mapping of the logical coordinate axes of a host to the logical coordinate axes of a neighbor of th...
Definition: OrientationMap.hpp:34
NewtonianEuler::Tags::MassDensityCons
The mass density of the fluid (as a conservative variable).
Definition: Tags.hpp:31
Direction
Definition: Direction.hpp:23
Element
Definition: Element.hpp:29
NewtonianEuler::Limiters::Minmod::VariablesToLimit
Definition: Minmod.hpp:93
ElementId
An ElementId uniquely labels an Element.
Definition: ElementId.hpp:51
NewtonianEuler::Limiters::VariablesToLimit
VariablesToLimit
Type of NewtonianEuler variables to apply limiter to.
Definition: VariablesToLimit.hpp:20
array
Limiters::MinmodType
MinmodType
Possible types of the minmod slope limiter and/or troubled-cell indicator.
Definition: MinmodType.hpp:20
DataVector
Stores a collection of function values.
Definition: DataVector.hpp:46
hydro
Items related to hydrodynamic systems.
Definition: SmoothFlow.hpp:19
NewtonianEuler::Tags::EnergyDensity
The energy density of the fluid.
Definition: Tags.hpp:45
Mesh
Holds the number of grid points, basis, and quadrature in each direction of the computational grid.
Definition: Mesh.hpp:49
tnsr
Type aliases to construct common Tensors.
Definition: TypeAliases.hpp:31
NewtonianEuler::Tags::MomentumDensity
The momentum density of the fluid.
Definition: Tags.hpp:37
cstdlib
Scalar
Tensor< T, Symmetry<>, index_list<> > Scalar
Definition: TypeAliases.hpp:21
Gsl.hpp
Options::String
const char *const String
The string used in option structs.
Definition: Options.hpp:32
Frame
Definition: IndexType.hpp:36
Tensor.hpp
unordered_map
gsl
Implementations from the Guideline Support Library.
Definition: ReadSpecPiecewisePolynomial.hpp:11
TMPL.hpp