Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <limits> 7 : 8 : #include "DataStructures/Tensor/Tensor.hpp" 9 : #include "Evolution/Systems/NewtonianEuler/Sources/LaneEmdenGravitationalField.hpp" 10 : #include "Evolution/Systems/NewtonianEuler/Tags.hpp" 11 : #include "Options/String.hpp" 12 : #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp" 13 : #include "PointwiseFunctions/Hydro/EquationsOfState/EquationOfState.hpp" 14 : #include "PointwiseFunctions/Hydro/EquationsOfState/PolytropicFluid.hpp" // IWYU pragma: keep 15 : #include "Utilities/TMPL.hpp" 16 : #include "Utilities/TaggedTuple.hpp" 17 : 18 : /// \cond 19 : namespace PUP { 20 : class er; // IWYU pragma: keep 21 : } // namespace PUP 22 : /// \endcond 23 : 24 : // IWYU pragma: no_include <pup.h> 25 : 26 : namespace NewtonianEuler { 27 : namespace Solutions { 28 : 29 : /*! 30 : * \brief A static spherically symmetric star in Newtonian gravity 31 : * 32 : * The solution for a static, spherically-symmetric star in 3 dimensions, found 33 : * by solving the Lane-Emden equation \cite Chandrasekhar1939 34 : * \cite Shapiro1983 . 35 : * The Lane-Emden equation has closed-form solutions for certain equations of 36 : * state; this class implements the solution for a polytropic fluid with 37 : * polytropic exponent \f$\Gamma=2\f$ (i.e., with polytropic index \f$n=1\f$). 38 : * The solution is returned in units where \f$G=1\f$, with \f$G\f$ the 39 : * gravitational constant. 40 : * 41 : * The radius and mass of the star are determined by the polytropic constant 42 : * \f$\kappa\f$ and central density \f$\rho_c\f$. 43 : * The radius is \f$R = \pi \alpha\f$, 44 : * and the mass is \f$M = 4 \pi^2 \alpha^3 \rho_c\f$, 45 : * where \f$\alpha = \sqrt{\kappa / (2 \pi)}\f$ and \f$G=1\f$. 46 : */ 47 1 : class LaneEmdenStar : public MarkAsAnalyticSolution { 48 : public: 49 0 : using equation_of_state_type = EquationsOfState::PolytropicFluid<false>; 50 0 : using source_term_type = Sources::LaneEmdenGravitationalField; 51 : 52 : /// The central mass density of the star. 53 1 : struct CentralMassDensity { 54 0 : using type = double; 55 0 : static constexpr Options::String help = { 56 : "The central mass density of the star."}; 57 0 : static type lower_bound() { return 0.; } 58 : }; 59 : 60 : /// The polytropic constant of the polytropic fluid. 61 1 : struct PolytropicConstant { 62 0 : using type = double; 63 0 : static constexpr Options::String help = { 64 : "The polytropic constant of the fluid."}; 65 0 : static type lower_bound() { return 0.; } 66 : }; 67 : 68 0 : using options = tmpl::list<CentralMassDensity, PolytropicConstant>; 69 : 70 0 : static constexpr Options::String help = { 71 : "A static, spherically-symmetric star in Newtonian gravity, found by\n" 72 : "solving the Lane-Emden equations, with a given central density and\n" 73 : "polytropic fluid. The fluid has polytropic index 1, but the polytropic\n" 74 : "constant is specifiable"}; 75 : 76 0 : LaneEmdenStar() = default; 77 0 : LaneEmdenStar(const LaneEmdenStar& /*rhs*/) = default; 78 0 : LaneEmdenStar& operator=(const LaneEmdenStar& /*rhs*/) = default; 79 0 : LaneEmdenStar(LaneEmdenStar&& /*rhs*/) = default; 80 0 : LaneEmdenStar& operator=(LaneEmdenStar&& /*rhs*/) = default; 81 0 : ~LaneEmdenStar() = default; 82 : 83 0 : LaneEmdenStar(double central_mass_density, double polytropic_constant); 84 : 85 : /// Retrieve a collection of variables at `(x, t)` 86 : template <typename DataType, typename... Tags> 87 1 : tuples::TaggedTuple<Tags...> variables(const tnsr::I<DataType, 3>& x, 88 : const double /*t*/, 89 : tmpl::list<Tags...> /*meta*/) const { 90 : const auto mass_density = precompute_mass_density(x); 91 : return {tuples::get<Tags>(variables(tmpl::list<Tags>{}, mass_density))...}; 92 : } 93 : 94 : /// \brief Compute the gravitational field for the corresponding source term, 95 : /// LaneEmdenGravitationalField. 96 : /// 97 : /// The result is the vector-field giving the acceleration due to gravity 98 : /// that is felt by a test particle. 99 : template <typename DataType> 100 1 : tnsr::I<DataType, 3> gravitational_field(const tnsr::I<DataType, 3>& x) const; 101 : 102 0 : const EquationsOfState::PolytropicFluid<false>& equation_of_state() const { 103 : return equation_of_state_; 104 : } 105 : 106 0 : const Sources::LaneEmdenGravitationalField& source_term() const { 107 : return source_term_; 108 : } 109 : 110 : // clang-tidy: no runtime references 111 0 : void pup(PUP::er& /*p*/); // NOLINT 112 : 113 : private: 114 : template <typename DataType> 115 0 : Scalar<DataType> precompute_mass_density(const tnsr::I<DataType, 3>& x) const; 116 : 117 : template <typename DataType> 118 0 : tuples::TaggedTuple<Tags::MassDensity<DataType>> variables( 119 : tmpl::list<Tags::MassDensity<DataType>> /*meta*/, 120 : const Scalar<DataType>& mass_density) const; 121 : 122 : template <typename DataType> 123 0 : tuples::TaggedTuple<Tags::Velocity<DataType, 3>> variables( 124 : tmpl::list<Tags::Velocity<DataType, 3>> /*meta*/, 125 : const Scalar<DataType>& mass_density) const; 126 : 127 : template <typename DataType> 128 0 : tuples::TaggedTuple<Tags::Pressure<DataType>> variables( 129 : tmpl::list<Tags::Pressure<DataType>> /*meta*/, 130 : const Scalar<DataType>& mass_density) const; 131 : 132 : template <typename DataType> 133 0 : tuples::TaggedTuple<Tags::SpecificInternalEnergy<DataType>> variables( 134 : tmpl::list<Tags::SpecificInternalEnergy<DataType>> /*meta*/, 135 : const Scalar<DataType>& mass_density) const; 136 : 137 0 : friend bool operator==(const LaneEmdenStar& lhs, const LaneEmdenStar& rhs); 138 : 139 0 : double central_mass_density_ = std::numeric_limits<double>::signaling_NaN(); 140 0 : double polytropic_constant_ = std::numeric_limits<double>::signaling_NaN(); 141 0 : EquationsOfState::PolytropicFluid<false> equation_of_state_{}; 142 0 : Sources::LaneEmdenGravitationalField source_term_{}; 143 : }; 144 : 145 0 : bool operator!=(const LaneEmdenStar& lhs, const LaneEmdenStar& rhs); 146 : 147 : } // namespace Solutions 148 : } // namespace NewtonianEuler