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 : #include <pup.h> 8 : 9 : #include "DataStructures/Tensor/TypeAliases.hpp" 10 : #include "Evolution/Systems/RadiationTransport/M1Grey/Tags.hpp" 11 : #include "Options/Options.hpp" 12 : #include "PointwiseFunctions/AnalyticData/AnalyticData.hpp" 13 : #include "PointwiseFunctions/AnalyticSolutions/GeneralRelativity/Minkowski.hpp" 14 : #include "PointwiseFunctions/Hydro/TagsDeclarations.hpp" 15 : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp" 16 : #include "Utilities/TMPL.hpp" 17 : #include "Utilities/TaggedTuple.hpp" 18 : 19 : /// \cond 20 : class DataVector; 21 : /// \endcond 22 : 23 : namespace RadiationTransport::M1Grey::AnalyticData { 24 : /*! 25 : * \brief Construct a homogeneous sphere of neutrino radiation. 26 : * 27 : * We follow the homogeneous sphere test problem in Section 4.5 of 28 : * \cite radice2022. The initial data has radius = 1, with equal emissivity 29 : * and absorption \f$\eta = \kappa_a = 10\f$ inside the uniform sphere. 30 : * Outside of the sphere the absorption is much lower, allowing the neutrinos 31 : * to stream out. Initially the neutrino energy density is distributed 32 : * uniformly inside the sphere. The momentum density is initialized to 0. 33 : * 34 : * Note: 35 : * To avoid sharp discontinuities, we round the edges of the energy profile 36 : * with an arctangent function, instead of the step function, which has 37 : * sharper features. 38 : */ 39 1 : class HomogeneousSphere : public virtual evolution::initial_data::InitialData, 40 : public MarkAsAnalyticData { 41 : public: 42 0 : static constexpr Options::String help = { 43 : "A homogeneous sphere emitting and absorbing neutrinos."}; 44 : 45 : /// The sphere radius. 46 1 : struct Radius { 47 0 : using type = double; 48 0 : static constexpr Options::String help = "Sphere radius"; 49 : }; 50 : 51 : /// The emissivity and absorption opacity. 52 1 : struct EmissivityAndOpacity { 53 0 : using type = double; 54 0 : static constexpr Options::String help = "Emissivity and absorption opacity"; 55 : }; 56 : 57 : /// The absorption opacity of the exterior 58 1 : struct OuterOpacity { 59 0 : using type = double; 60 0 : static constexpr Options::String help = 61 : "Opacity of outer absorption region"; 62 : }; 63 : 64 : /// BoundaryRoundness 65 1 : struct BoundaryRoundness { 66 0 : using type = double; 67 0 : static constexpr Options::String help = 68 : "How rounded the interface is between the sphere radius and outer " 69 : "region. Closer to 0 corresponds to sharper (more step like) " 70 : "interface."; 71 0 : static type lower_bound() { return 1e-5; } 72 : }; 73 : 74 0 : using options = 75 : tmpl::list<Radius, EmissivityAndOpacity, OuterOpacity, BoundaryRoundness>; 76 : 77 0 : HomogeneousSphere() = default; 78 : 79 0 : auto get_clone() const 80 : -> std::unique_ptr<evolution::initial_data::InitialData> override; 81 : 82 : /// \cond 83 : explicit HomogeneousSphere(CkMigrateMessage* /*message*/) {} 84 : using PUP::able::register_constructor; 85 : WRAPPED_PUPable_decl_template(HomogeneousSphere); 86 : /// \endcond 87 : 88 0 : HomogeneousSphere(double radius, double emissivity_and_opacity, 89 : double outer_opacity, double boundary_roundness); 90 : 91 : /// @{ 92 : /// Retrieve fluid and neutrino variables 93 : template <typename NeutrinoSpecies> 94 1 : auto variables(const tnsr::I<DataVector, 3>& x, 95 : tmpl::list<RadiationTransport::M1Grey::Tags::TildeE< 96 : Frame::Inertial, NeutrinoSpecies>> /*meta*/) const 97 : -> tuples::TaggedTuple<RadiationTransport::M1Grey::Tags::TildeE< 98 : Frame::Inertial, NeutrinoSpecies>>; 99 : 100 : template <typename NeutrinoSpecies> 101 1 : auto variables(const tnsr::I<DataVector, 3>& x, 102 : tmpl::list<RadiationTransport::M1Grey::Tags::TildeS< 103 : Frame::Inertial, NeutrinoSpecies>> /*meta*/) const 104 : -> tuples::TaggedTuple<RadiationTransport::M1Grey::Tags::TildeS< 105 : Frame::Inertial, NeutrinoSpecies>>; 106 : 107 : template <typename NeutrinoSpecies> 108 1 : auto variables(const tnsr::I<DataVector, 3>& x, 109 : tmpl::list<RadiationTransport::M1Grey::Tags::GreyEmissivity< 110 : NeutrinoSpecies>> /*meta*/) const 111 : -> tuples::TaggedTuple< 112 : RadiationTransport::M1Grey::Tags::GreyEmissivity<NeutrinoSpecies>>; 113 : 114 : template <typename NeutrinoSpecies> 115 1 : auto variables( 116 : const tnsr::I<DataVector, 3>& x, 117 : tmpl::list<RadiationTransport::M1Grey::Tags::GreyAbsorptionOpacity< 118 : NeutrinoSpecies>> /*meta*/) const 119 : -> tuples::TaggedTuple<RadiationTransport::M1Grey::Tags:: 120 : GreyAbsorptionOpacity<NeutrinoSpecies>>; 121 : 122 : template <typename NeutrinoSpecies> 123 1 : auto variables( 124 : const tnsr::I<DataVector, 3>& x, 125 : tmpl::list<RadiationTransport::M1Grey::Tags::GreyScatteringOpacity< 126 : NeutrinoSpecies>> /*meta*/) const 127 : -> tuples::TaggedTuple<RadiationTransport::M1Grey::Tags:: 128 : GreyScatteringOpacity<NeutrinoSpecies>>; 129 : 130 1 : static auto variables( 131 : const tnsr::I<DataVector, 3>& x, 132 : tmpl::list<hydro::Tags::LorentzFactor<DataVector>> /*meta*/) 133 : -> tuples::TaggedTuple<hydro::Tags::LorentzFactor<DataVector>>; 134 : 135 1 : static auto variables( 136 : const tnsr::I<DataVector, 3>& x, 137 : tmpl::list<hydro::Tags::SpatialVelocity<DataVector, 3>> /*meta*/) 138 : -> tuples::TaggedTuple<hydro::Tags::SpatialVelocity<DataVector, 3>>; 139 : /// @} 140 : 141 : /// Retrieve the metric variables 142 : template <typename Tag> 143 1 : tuples::TaggedTuple<Tag> variables(const tnsr::I<DataVector, 3>& x, 144 : tmpl::list<Tag> /*meta*/) const { 145 : return gr::Solutions::Minkowski<3>{}.variables(x, 0.0, tmpl::list<Tag>{}); 146 : } 147 : 148 : /// Retrieve a collection of variables 149 : template <typename... Tags> 150 1 : tuples::TaggedTuple<Tags...> variables(const tnsr::I<DataVector, 3>& x, 151 : tmpl::list<Tags...> /*meta*/) const { 152 : return {get<Tags>(variables(x, tmpl::list<Tags>{}))...}; 153 : } 154 : 155 : // NOLINTNEXTLINE(google-runtime-references) 156 0 : void pup(PUP::er& p) override; 157 : 158 : private: 159 0 : friend bool operator==(const HomogeneousSphere& lhs, 160 : const HomogeneousSphere& rhs) { 161 : return lhs.radius_ == rhs.radius_ and 162 : lhs.emissivity_and_opacity_ == rhs.emissivity_and_opacity_ and 163 : lhs.outer_opacity_ == rhs.outer_opacity_ and 164 : lhs.boundary_roundness_ == rhs.boundary_roundness_; 165 : } 166 : 167 0 : double radius_ = std::numeric_limits<double>::signaling_NaN(); 168 0 : double emissivity_and_opacity_ = std::numeric_limits<double>::signaling_NaN(); 169 0 : double outer_opacity_ = std::numeric_limits<double>::signaling_NaN(); 170 0 : double boundary_roundness_ = std::numeric_limits<double>::signaling_NaN(); 171 : }; 172 : 173 0 : bool operator!=(const HomogeneousSphere& lhs, const HomogeneousSphere& rhs); 174 : 175 : } // namespace RadiationTransport::M1Grey::AnalyticData