CLASSpp Manual
Cosmology reference and developer manual
Loading...
Searching...
No Matches
wdm_decay_product.h
1#pragma once
2#include <optional>
3#include <string>
4#include <string_view>
5#include <vector>
6
7#include "../species/ncdm_base_species.h"
8#include "background.h"
9
10class BackgroundModule;
11class DCDMSpecies;
12
35 public:
36 static constexpr std::string_view kTypeName = "dcdm_wdm";
37 static constexpr double kQKick = 10.0; // p/T0, internal convention
38
51 static constexpr double kSparsityFloor = 1e-12;
52
53 // ── Fiducial-cosmology placement helpers ───────────────────────────────────
54 // Placement-only fixed LCDM background — NOT physics. Maps a decay time t (Mpc)
55 // to the scale factor a at which those decays inject, so the momentum grid is a
56 // function of Gamma alone (invariant across the run's cosmology). See spec
57 // docs/superpowers/specs/2026-07-18-dcdm-wdm-adaptive-momentum-grid-design.md.
58 static constexpr double kFidOmegaM = 0.31;
59 static constexpr double kFidOmegaR = 9.2e-5; // photons+nu, T_cmb=2.7255, Neff=3.044
60 static constexpr double kFidH = 0.674; // h
61 static double FiducialCosmicTime(double a); // t(a) [Mpc], radiation+matter
62 static double FiducialScaleFactorAtTime(double t_mpc); // inverse (monotone)
63
65 const std::string& instance_name,
66 const NcdmSettings& settings,
67 const background* pba,
68 const BackgroundModule* bgm);
69
70 double Gamma() const {
71 return Gamma_;
72 }
73 double vkick() const {
74 return vkick_;
75 }
76 double epsilon_retention() const {
77 return eps_;
78 }
79 const std::vector<double>& dq() const {
80 return dq_;
81 }
82 const std::vector<double>& u() const {
83 return u_;
84 }
85 const std::vector<double>& u_edge() const {
86 return u_edge_;
87 }
93 double SigmaAt(double u_cut) const;
94
96 void SetParent(const DCDMSpecies* dcdm) {
97 parent_ = dcdm;
98 }
99
100 const std::optional<double>& Omega_ini_pending() const {
101 return Omega_ini_pending_;
102 }
103 const std::optional<double>& Omega_combined_pending() const {
104 return Omega_combined_pending_;
105 }
106
121 void FillInjection(double a, double rho_dcdm, double* J, double* dJdlnq) const;
122
123 // ── Background (Task 2) ────────────────────────────────────────────────────
124 void RegisterBackgroundIndices(int& index_bg) override;
125 void RegisterIntegrationIndices(int& index_bi) override;
126 void SetBackgroundInitialConditions(const BackgroundICContext& ctx) override;
127 void ComputeBackground(double a, const double* pvecback_B, double* pvecback) override;
128
129 double Rho(const double* pvecback) const override {
130 return pvecback[index_bg_rho_];
131 }
132 double P(const double* pvecback) const override {
133 return pvecback[index_bg_p_];
134 }
135 double PPrime(double a,
136 double H,
137 const double* pvecback_B,
138 const double* pvecback) const override;
139 double RhoDotOverRho(const double* pvecback, double a_prime_over_a) const override;
140
142 void WriteBackgroundData(const double* pvecback, BackgroundColumnWriter& w) const override;
143
144 // ── Decay-product neutrality overrides ─────────────────────────────────────
145 // The daughter starts empty: it contributes nothing to the early-time
146 // radiation budget, fnu, N_eff, or the flatness budget (the combined sector
147 // density is owned by the DCDM_WDM composite).
148 double GetOmega0() const override {
149 return 0.;
150 }
151 double NeutrinoOmega0() const override {
152 return 0.;
153 }
154 double NeffContribution(double /*z*/) const override {
155 return 0.;
156 }
157 bool IsFreestreaming() const override {
158 return false;
159 }
160 double BackgroundAIni(double a_proposed, double /*tol*/) const override {
161 return a_proposed; // empty at early times; no relativistic-start constraint
162 }
163 void CheckUltraRelativisticAtIc(const double* /*pvecback*/, double /*tol*/) const override {}
164 bool IsUltraRelativisticAtIc(const double* /*pvecback*/, double /*tol*/) const override {
165 return true;
166 }
167 void PrintNeffInfo() const override;
168 void PrintMassInfo() const override;
169
170 // ── Perturbations (Task 4) ─────────────────────────────────────────────────
171 void RegisterPerturbationIndices(BaseSpecies::PerturbLayout& layout,
172 perturb_vector* pv,
173 const precision* ppr,
174 int& index_pt,
175 const perturb_workspace* ppw,
176 int gauge) override;
177 void PerturbDerivs(const BaseSpecies::PerturbLayout& layout,
178 double tau,
179 const double* y,
180 double* dy,
181 const perturb_parameters_and_workspace& ppaw) const override;
183 double* y,
184 const PerturbIcContext& ctx) override;
185 StressEnergyContribution StressEnergy(const BaseSpecies::PerturbLayout& layout,
186 const perturb_vector* pv,
187 const double* y,
188 const double* pvecback,
189 const perturb_workspace* ppw) const override;
190 void FillSources(const BaseSpecies::PerturbLayout& layout,
191 const double* y,
192 const double* dy,
193 PerturbSourceContext& ctx) const override;
195 PerturbColumnWriter& writer,
196 const PerturbationsModule& mod,
197 file_format fmt,
198 TransferColumnSection section = TransferColumnSection::all) const override;
199
203 perturb_vector* /*pv*/,
204 const precision* /*ppr*/,
205 int& /*index_pt*/,
206 const perturb_workspace* /*ppw*/,
207 int /*gauge*/) override {}
211 double* /*y*/,
212 const PerturbIcContext& /*ctx*/) override {}
213
214 // ── Index accessors for the composite ──────────────────────────────────────
215 int bg_f_index() const {
216 return index_bg_f_;
217 }
218 int bg_dfdlnq_index() const {
219 return index_bg_dfdlnq_;
220 }
221 int bg_inj_index() const {
222 return index_bg_inj_;
223 }
224 int bg_number_index() const {
225 return index_bg_number_;
226 }
227 int bi_f_index() const {
228 return index_bi_f_;
229 }
230 int bi_dfdlnq_index() const {
231 return index_bi_dfdlnq_;
232 }
233
234 protected:
236 double GetDlnf0Dlnq(int /*iq*/, const double* /*pvecback*/) const override {
237 return 0.;
238 }
239
240 private:
247 static constexpr double kFSeed = 1e-10;
248
251 void BuildInjectionAdaptedGrid();
257 void GaussWeights(double u_cut, double sigma, double* w) const;
258
259 const background* pba_;
260 const DCDMSpecies* parent_ = nullptr;
261
262 double Gamma_ = 0.; // decay rate, CLASS units (Mpc^-1 after both conversions)
263 double vkick_ = 0.; // kick velocity in units of c
264 double eps_ = 0.; // total mass retention (m_d = eps*m_parent/2)
265
266 int n_bins_ = 96;
267 double q_edge_tol_ = 1e-3; // decayed-fraction trimmed off each end (grid F-span);
268 // the trimmed tail is clamped into the edge bin, not dropped
269 int l_max_input_ = -1; // -1 → ppr->l_max_ncdm
270 std::optional<double> q_min_ratio_floor_; // optional hard floor on q_lo/q_kick
271
272 static constexpr double kSigmaMin = 0.03; // ≈ 4 background-table samples (7e-3 in ln a)
273 static constexpr double kSigmaMax = 0.25; // bounds the wide-bin placement bias
274 double F_lo_ = 0.; // realized decayed-fraction span of the grid (0,0 = fallback grid)
275 double F_hi_ = 0.;
276
277 std::vector<double> u_; // ln q_i (bin centres = q(F_mid[i]))
278 std::vector<double> dq_; // cell widths q_edge[i+1] - q_edge[i]
279 std::vector<double> u_edge_; // N+1 cell edges in u (F-quantile edges)
280
281 std::optional<double> Omega_ini_pending_;
282 std::optional<double> Omega_combined_pending_;
283
284 // Background indices (per-bin arrays are n_bins_ long)
285 int index_bg_number_ = -1;
286 int index_bg_pseudo_p_ = -1;
287 int index_bg_f_ = -1;
288 int index_bg_dfdlnq_ = -1;
289 int index_bg_inj_ = -1;
290 int index_bi_f_ = -1;
291 int index_bi_dfdlnq_ = -1;
292
293 mutable std::vector<double> scratch_w_; // erf energy-deposit weights (background thread only)
294};
Definition base_species.h:32
Definition dcdm.h:13
Definition parser.h:21
Definition ncdm_base_species.h:42
Definition perturb_source_context.h:63
Definition wdm_decay_product.h:34
void RegisterBackgroundIndices(int &index_bg) override
Definition wdm_decay_product.cpp:420
void WriteBackgroundData(const double *pvecback, BackgroundColumnWriter &w) const override
Definition wdm_decay_product.cpp:509
void CheckUltraRelativisticAtIc(const double *, double) const override
Definition wdm_decay_product.h:163
void PerturbDerivs(const BaseSpecies::PerturbLayout &layout, double tau, const double *y, double *dy, const perturb_parameters_and_workspace &ppaw) const override
Definition wdm_decay_product.cpp:542
void PerturbSynchronousToNewtonian(const BaseSpecies::PerturbLayout &, double *, const PerturbIcContext &) override
Definition wdm_decay_product.h:210
double P(const double *pvecback) const override
Definition wdm_decay_product.h:132
void PrintNeffInfo() const override
Definition wdm_decay_product.cpp:396
void RegisterTensorPerturbationIndices(BaseSpecies::PerturbLayout &, perturb_vector *, const precision *, int &, const perturb_workspace *, int) override
Definition wdm_decay_product.h:202
double PPrime(double a, double H, const double *pvecback_B, const double *pvecback) const override
Definition wdm_decay_product.cpp:472
double NeffContribution(double) const override
Definition wdm_decay_product.h:154
void SetBackgroundInitialConditions(const BackgroundICContext &ctx) override
Definition wdm_decay_product.cpp:440
void SetParent(const DCDMSpecies *dcdm)
Definition wdm_decay_product.h:96
void WriteOutputColumns(PerturbColumnWriter &writer, const PerturbationsModule &mod, file_format fmt, TransferColumnSection section=TransferColumnSection::all) const override
Definition wdm_decay_product.cpp:696
double GetOmega0() const override
Definition wdm_decay_product.h:148
void ComputeBackground(double a, const double *pvecback_B, double *pvecback) override
Definition wdm_decay_product.cpp:450
void FillSources(const BaseSpecies::PerturbLayout &layout, const double *y, const double *dy, PerturbSourceContext &ctx) const override
Definition wdm_decay_product.cpp:641
StressEnergyContribution StressEnergy(const BaseSpecies::PerturbLayout &layout, const perturb_vector *pv, const double *y, const double *pvecback, const perturb_workspace *ppw) const override
Definition wdm_decay_product.cpp:605
void RegisterIntegrationIndices(int &index_bi) override
Definition wdm_decay_product.cpp:433
double GetDlnf0Dlnq(int, const double *) const override
Definition wdm_decay_product.h:236
double RhoDotOverRho(const double *pvecback, double a_prime_over_a) const override
Definition wdm_decay_product.cpp:490
void ApplyInitialConditions(const BaseSpecies::PerturbLayout &layout, double *y, const PerturbIcContext &ctx) override
Definition wdm_decay_product.cpp:587
double Rho(const double *pvecback) const override
Definition wdm_decay_product.h:129
static constexpr double kSparsityFloor
Definition wdm_decay_product.h:51
void FillInjection(double a, double rho_dcdm, double *J, double *dJdlnq) const
Definition wdm_decay_product.cpp:318
bool IsFreestreaming() const override
Definition wdm_decay_product.h:157
bool IsUltraRelativisticAtIc(const double *, double) const override
Definition wdm_decay_product.h:164
void PrintMassInfo() const override
Definition wdm_decay_product.cpp:407
double NeutrinoOmega0() const override
Definition wdm_decay_product.h:151
double SigmaAt(double u_cut) const
Definition wdm_decay_product.cpp:266
double BackgroundAIni(double a_proposed, double) const override
Definition wdm_decay_product.h:160
void WriteBackgroundColumnTitles(BackgroundColumnWriter &w) const override
Definition wdm_decay_product.cpp:501
Definition perturbations.h:250
Definition perturbations.h:344
file_format
Definition precision.h:40
Definition background_ic_context.h:11
Definition base_species.h:89
Definition perturb_source_context.h:125
Definition perturb_source_context.h:103
Definition perturbations_module.h:341
Definition precision.h:63