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 :
8 : #include "DataStructures/Tensor/TypeAliases.hpp"
9 : #include "Utilities/Gsl.hpp"
10 :
11 : /// \cond
12 : class DataVector;
13 : template <size_t>
14 : class Mesh;
15 :
16 : namespace EquationsOfState {
17 : template <bool, size_t>
18 : class EquationOfState;
19 : } // namespace EquationsOfState
20 : /// \endcond
21 :
22 : namespace NewtonianEuler::Limiters {
23 :
24 : /// \ingroup LimitersGroup
25 : /// \brief Encodes the action taken by `flatten_solution`
26 0 : enum class FlattenerAction {
27 : NoOp = 0,
28 : ScaledSolution = 1,
29 : SetSolutionToMean = 2,
30 : };
31 :
32 : /// \ingroup LimitersGroup
33 : /// \brief Scale a NewtonianEuler solution around its mean to remove pointwise
34 : /// positivity violations.
35 : ///
36 : /// If the solution has points with negative density, scales the solution
37 : /// to make these points positive again. For each component \f$u\f$ of the
38 : /// solution, the scaling takes the form
39 : /// \f$u \to \bar{u} + \theta (u - \bar{u})\f$,
40 : /// where \f$\bar{u}\f$ is the cell-average value of \f$u\f$, and \f$\theta\f$
41 : /// is a factor less than 1, chosen to restore positive density.
42 : /// The cell averages in this implementation are computed in inertial
43 : /// coordinates, so the flattener is conservative even on deformed grids.
44 : ///
45 : /// A scaling of this form used to restore positivity is usually called a
46 : /// flattener (we use this name) or a bounds-preserving filter. Note that the
47 : /// scaling approach only works if the cell-averaged solution is itself
48 : /// physical, in other words, if the cell-averaged density is positive.
49 : ///
50 : /// After checking for (and correcting) negative densities, if the equation of
51 : /// state is two-dimensional, then the pressure is also checked for positivity.
52 : /// If negative pressures are found, each solution component is set to its mean
53 : /// (this is equivalent to \f$\theta = 0\f$ in the scaling form above).
54 : /// In principle, a less aggressive scaling could be used, but solving for the
55 : /// correct \f$\theta\f$ in this case is more involved.
56 : template <size_t VolumeDim>
57 1 : FlattenerAction flatten_solution(
58 : gsl::not_null<Scalar<DataVector>*> mass_density_cons,
59 : gsl::not_null<tnsr::I<DataVector, VolumeDim>*> momentum_density,
60 : gsl::not_null<Scalar<DataVector>*> energy_density,
61 : const Mesh<VolumeDim>& mesh,
62 : const Scalar<DataVector>& det_logical_to_inertial_jacobian,
63 : const EquationsOfState::EquationOfState<false, 2>& equation_of_state);
64 :
65 : } // namespace NewtonianEuler::Limiters
|