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