Skip to content

Commit de6a639

Browse files
committed
[include] update TBetaGenerator.hh
1 parent c17b9dd commit de6a639

1 file changed

Lines changed: 52 additions & 54 deletions

File tree

include/TBetaGenerator.hh

Lines changed: 52 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,20 @@
88
#include <complex>
99
#include <functional>
1010

11+
// references for value updates:
12+
// [C1] CODATA 2022: P.J. Mohr et al, Rev. Mod. Phys. 97 (2025) 025002
13+
// [C2] M.M. Restrepo and E.G. Myers, PRL 131 (2023) 243002
1114
namespace TBeta
1215
{
1316
static constexpr double pi = 3.141592653589793238462643383279502884; // Pi
1417
static constexpr double twopi = 2.0 * pi; // 2 Pi
15-
static constexpr double me = 510.99895; // electron mass [keV]
18+
static constexpr double me = 510.99895069; // [C1] electron mass [keV]
1619
static constexpr double gA = 1.2646; // nucleon axial coupling
1720
static constexpr double gAq = 1.24983; // quenched gA
1821
static constexpr double gV = 1.0; // nucleon vector coupling
19-
static constexpr double MTr = 2808920.8205; // bare nuclear tritium mass [keV]
20-
static constexpr double Mf = 2808391.2193; // bare nuclear 3He+ mass [keV]
21-
static constexpr double alpha = 7.2973525693e-3; // fine structure constant
22+
static constexpr double MTr = 2808921.1367789; // [C2] bare nuclear tritium mass [keV]
23+
static constexpr double Mf = 2808391.6111557; // [C2] bare nuclear 3He+ mass [keV]
24+
static constexpr double alpha = 7.2973525643e-3; // [C1] ine structure constant
2225
static constexpr double Gf = 1.1663787e-17; // Fermi interaction strength [keV^-2]
2326
static constexpr double Rn = 2.884e-3; // nuclear radius of 3He [me]
2427
static constexpr double keVInvSec = 1.52e18; // conversion [keV s]
@@ -39,12 +42,17 @@ namespace TBeta
3942
static constexpr double dm31Sq = 2.517e-9;
4043
static constexpr double dm32Sq = -2.498e-9;
4144

45+
// formula constants
46+
static constexpr double emin = 0.2; // [keV] low-energy cut-off, avoiding atomic effects in S(Z,en)
47+
static constexpr double v0 = 76.0e-3; // =76 eV in ref [1]
48+
static constexpr double mcc = Mf / me; // mass of He3 in units of me [1]
49+
4250
//
4351
// function interfaces
4452
//
4553

4654
// heaviside function
47-
inline double heavyside(double x){
55+
double heavyside(double x){
4856
double result;
4957
if (x>0.0) result = 1.0;
5058
else if (x==0.0) result = 0.5;
@@ -53,7 +61,7 @@ namespace TBeta
5361
}
5462

5563
// Lanczos approximation - needs testing!
56-
inline std::complex<double> Gamma(std::complex<double> z) {
64+
std::complex<double> Gamma(std::complex<double> z) {
5765
double g = 7;
5866
static const double p[9] = {0.99999999999980993, 676.5203681218851, -1259.1392167224028,
5967
771.32342877765313, -176.61502916214059, 12.507343278686905,
@@ -107,23 +115,15 @@ namespace TBeta
107115
// [1] Preprint arXiv 1806.00369
108116
// [2] PRL 5(85) 807
109117

110-
// 3-body endpoint energy of bare tritium [keV] (neutrino mass munu [keV])
111-
inline double endpoint(double munu) {
112-
double m2 = MTr*MTr;
113-
double me2 = me*me;
114-
double msum2 = (Mf+munu)*(Mf+munu);
115-
return (m2 + me2 - msum2)/(2.0*MTr) - me;
116-
}
117-
118118
// Atomic 3He mass including n-th energy level binding
119-
inline double MfAt(int n){
119+
double MfAt(int n){
120120
if (n<1) n=1; // remove illegal n values
121121
return Mf + me - 4.0*Ryd/(n*n);
122122
}
123123

124124
// 3-body endpoint energy of atomic tritium [keV] (neutrino mass [keV])
125125
// and energy level n
126-
inline double endAt(double munu, int n){
126+
double endAt(double munu, int n){
127127
double mat2 = MAt*MAt;
128128
double me2 = me*me;
129129
double matn = MfAt(n);
@@ -132,17 +132,16 @@ namespace TBeta
132132
}
133133

134134
// Simpson approximation of Fermi function [1] (A.2)
135-
inline double Fermi(int Z, double beta) {
135+
double Fermi(int Z, double beta) {
136136
double eta = alpha * Z / beta; // Sommerfeld parameter
137137
double nom = twopi * eta * (1.002037 - 0.001427*beta);
138138
double denom = 1.0-std::exp(-twopi * eta);
139139
return nom / denom;
140140
}
141141

142142
// Radiative correction [1] (A.3)
143-
inline double G(double en, double endp) {
144-
if (endp<=en) return 0.0;
145-
if (en<0.04) en = 0.04; // avoid zero energy
143+
double G(double en, double endp) {
144+
if (endp<=en || en<emin) return 0.0;
146145
double w = (en + me) / me; // total electron energy [me]
147146
double w0 = (endp + me) / me;
148147
double p = std::sqrt(w*w - 1.0);
@@ -156,9 +155,8 @@ namespace TBeta
156155
}
157156

158157
// Orbital electron shielding [1] (A.4)
159-
inline double S(int Z, double en) {
160-
if (en<0.04) en = 0.04; // check announced anomaly
161-
static constexpr double v0 = 1.45*alpha*alpha * me; // =76 eV in ref [1]
158+
double S(int Z, double en) {
159+
if (en<emin) return 1.0; // check announced anomaly
162160
double w = (en + me) / me; // total electron energy [me]
163161
double p = std::sqrt(w*w - 1.0);
164162
double wb = w - v0 / me;
@@ -168,13 +166,15 @@ namespace TBeta
168166
double gamma = std::sqrt(1.0-(alpha*alpha*Z*Z));
169167
double fac1 = wb/w*std::pow(pb/p, -1.0+2.0*gamma);
170168
std::complex<double> arg1 (gamma, etab), arg2 (gamma, eta);
171-
double nom = std::norm(Gamma(arg1));
172-
double denom = std::norm(Gamma(arg2));
169+
std::complex<double> d1 = Gamma(arg1);
170+
std::complex<double> d2 = Gamma(arg2);
171+
double nom = std::norm(d1 * d1);
172+
double denom = std::norm(d2 * d2);
173173
return fac1 * std::exp(pi*(etab-eta)) * nom/denom;
174174
}
175175

176176
// Scaling od the electric field within nucleus [1] (A.7)
177-
inline double L(int Z, double en) {
177+
double L(int Z, double en) {
178178
double w = (en + me) / me; // total electron energy [me]
179179
double fac = alpha * Z;
180180
double gamma = std::sqrt(1.0-fac*fac);
@@ -184,8 +184,8 @@ namespace TBeta
184184
}
185185

186186
// Convolution of electron and neutrino wavefunctions within nucleus [1] (A.8)
187-
inline double CC(int Z, double en, double endp) {
188-
if (endp<=en) return 1.0;
187+
double CC(int Z, double en, double endp) {
188+
if (endp<=en || en<emin) return 1.0;
189189
double w = (en + me) / me; // total electron energy [me]
190190
double w0 = (endp + me) / me;
191191
double fac = alpha * Z;
@@ -197,11 +197,9 @@ namespace TBeta
197197

198198

199199
// Recoiling nuclear charge field [1] (A.9)
200-
inline double Q(int Z, double en, double endp) {
201-
if (endp<=en) return 1.0;
202-
if (en<0.04) en = 0.04; // avoid zero energy
203-
static const double mcc = 5497.885;
204-
static const double lt = 1.265;
200+
double Q(int Z, double en, double endp) {
201+
if (endp<=en || en<emin) return 1.0;
202+
double lt = gA / gV;
205203
double w = (en + me) / me; // total electron energy [me]
206204
double w0 = (endp + me) / me;
207205
double p = std::sqrt(w*w - 1.0);
@@ -212,18 +210,18 @@ namespace TBeta
212210
// Combined correction factor for atomic tritium
213211
// function of neutrino mass munu [keV], n atomic energy level
214212
// of daughter nucleus, en electron energy [kev]
215-
inline double Corr(double en, double munu, int n) {
216-
double arg = std::sqrt((en+me)*(en+me)-me*me)/(en+me);
213+
double Corr(double en, double munu, int n) {
217214
double e0 = endAt(munu, n);
218-
if (e0<=en) return 1.0; // no correction
215+
if (e0<=en || en<emin) return 1.0; // no correction
216+
double arg = std::sqrt((en+me)*(en+me)-me*me)/(en+me);
219217
return Fermi(2,arg)*S(2,en)*G(en,e0)*L(2,en)*CC(2,en,e0)*Q(2,en,e0);
220218
}
221219

222220
// Differential decay rate with energy en [kev], applicable to LH SM currents
223221
// for the emission of an electron antineutrino with mass munu [kev] and
224222
// the endpoint of the n-th 3He energy level. With corrections.
225-
inline double stub(double en, double munu, double e0) { // used twice, factor out
226-
if (e0<en) return 0.0;
223+
double stub(double en, double munu, double e0) { // used twice, factor out
224+
if (e0<en || en<emin) return 0.0;
227225
double fac1 = (Gf*Gf*Vud*Vud)/(2.0*pi*pi*pi);
228226
double denom = MTr*MTr - 2.0*MTr*(en+me) + me*me;
229227
double nom1 = MTr*(en+me) - me*me;
@@ -243,7 +241,7 @@ namespace TBeta
243241
return fac1*(term1+term2+term3);
244242
}
245243

246-
inline double Diff(double en, double munu, int n) {
244+
double Diff(double en, double munu, int n) {
247245
double e0 = endAt(munu, n);
248246
double fac = stub(en, munu, e0);
249247
return fac * Corr(en,munu,n);
@@ -252,7 +250,7 @@ namespace TBeta
252250
// neutrino mass spectrum
253251
// order is boolean True for Normal order (NO)
254252
// False for Inverted order (IO)
255-
const inline std::array<double,3>& nuSpectrum(bool order, double munu) {
253+
const std::array<double,3>& nuSpectrum(bool order, double munu) {
256254
static const std::array<double,3> no = {munu, std::sqrt(munu*munu+dm21Sq), std::sqrt(munu*munu+dm31Sq)};
257255
static const std::array<double,3> io = {std::sqrt(munu*munu-dm21Sq-dm32Sq), std::sqrt(munu*munu-dm32Sq), munu};
258256
return order ? no : io;
@@ -261,7 +259,7 @@ namespace TBeta
261259
// like Diff but summing over all three light neutrinos with weights.
262260
// order is boolean True for Normal order (NO)
263261
// False for Inverted order (IO)
264-
inline double Diff3nu(bool order, double en, double munu, int n) {
262+
double Diff3nu(bool order, double en, double munu, int n) {
265263
const std::array<double,3>& UeSq = order ? UeSqNO : UeSqIO;
266264
double sum = 0.0;
267265
for (int i=0;i<3;++i) {
@@ -273,26 +271,26 @@ namespace TBeta
273271
// like Diff but summing over all three light neutrinos with weights and
274272
// a sterile neutrino with mass mN [keV] with active-sterile mixing
275273
// strength eta (0<=eta<1)
276-
inline double Diff4nu(bool order, double mN, double eta, double en, double munu, int n) {
274+
double Diff4nu(bool order, double mN, double eta, double en, double munu, int n) {
277275
double e0 = endAt(mN, n);
278276
return (1.0-eta*eta)*Diff3nu(order, en, munu, n) + eta*eta*Diff(en, mN, n)*heavyside(e0-en);
279277
}
280278

281279
// Sum over discrete atomic energy levels of 3He
282280
// with branching ratios, [2]
283-
inline double etaL(double en) {
281+
double etaL(double en) {
284282
double denom = (en+me)*(en+me) - me*me;
285283
return -2.0*alpha*me/std::sqrt(denom);
286284
}
287285

288-
inline double aL(double en) {
286+
double aL(double en) {
289287
double eta = etaL(en);
290288
double nom = std::exp(2.0*eta*std::atan(-2.0/eta));
291289
double denom = (1.0 + eta*eta/4.0)*(1.0 + eta*eta/4.0);
292290
return eta*eta*eta*eta*nom/denom;
293291
}
294292

295-
inline double Lev(int n, double en) {
293+
double Lev(int n, double en) {
296294
double al = aL(en);
297295
if (n==2) // special case
298296
return 0.25 * (1.0 + al*al - al);
@@ -304,7 +302,7 @@ namespace TBeta
304302
// Full (SM+sterile) differential decay rate as function of electron energy [keV].
305303
// Includes all corrections (no continuum orbital e- states) and
306304
// the first 5 bound discrete atomic states.
307-
inline double dGammadE(bool order, double munu, double mN, double eta, double en) {
305+
double dGammadE(bool order, double munu, double mN, double eta, double en) {
308306
double sum = 0.0;
309307
for (int n=1;n<=5;++n)
310308
sum += Lev(n, en) * Diff4nu(order, mN, eta, en, munu, n);
@@ -313,40 +311,40 @@ namespace TBeta
313311

314312
// Set up all contributions including continous states and first 5
315313
// discrete states. Here consider state n as double for continuum states.
316-
inline double endCont(double munu, double n) {
314+
double endCont(double munu, double n) {
317315
return endAt(munu, 1)-4.0*Ryd*(1.0+1.0/(n*n));
318316
}
319317

320-
inline double CorrCont(double en, double munu, double n) {
318+
double CorrCont(double en, double munu, double n) {
321319
double e0 = endCont(munu, n);
322320
double nom = (en+me)*(en+me) - me*me;
323321
double fac = Fermi(2,std::sqrt(nom)/(en+me))*S(2,en)*G(en,e0);
324322
return fac*L(2,en)*CC(2,en,e0)*Q(2,en,e0);
325323
}
326324

327-
inline double DiffCont(double en, double munu, double n) {
325+
double DiffCont(double en, double munu, double n) {
328326
double e0 = endCont(munu, n);
329327
double fac = stub(en, munu, e0);
330328
return fac * CorrCont(en, munu, n);
331329
}
332330

333331
// integrand over states g
334-
inline double integrand(double g, double en, double munu) {
332+
double integrand(double g, double en, double munu) {
335333
double fac1 = DiffCont(en, munu, g)*twopi/(g*g*g*(std::exp(twopi*g)-1.0));
336334
double fac2 = g*g*g*g*std::exp(2.0*g*std::atan(-2.0/g))/((1.0+g*g/4.0)*(1.0+g*g/4.0));
337335
return fac1*(fac2*fac2 + aL(en)*aL(en) - aL(en)*fac2);
338336
}
339337

340338
// Contribution only from the continuum orbital electron states.
341339
// integrate over g.
342-
inline double gammaCont(double en, double munu) {
343-
if (en > endCont(munu, 1e10)) return 0.0;
340+
double gammaCont(double en, double munu) {
341+
if (en > endCont(munu, 1e10) || en<emin) return 0.0;
344342
std::function<double(double,double,double)> fn = integrand;
345343
SimpsonIntegral sint(fn, en, munu);
346344
return sint.integrate(-99, etaL(en), 1000)/pi;
347345
}
348346

349-
inline double dGammadECont(bool order, double munu, double mN, double eta, double en) {
347+
double dGammadECont(bool order, double munu, double mN, double eta, double en) {
350348
const std::array<double,3>& UeSq = order ? UeSqNO : UeSqIO;
351349
double sum = 0.0;
352350
for (int i=0;i<3;++i) {
@@ -355,7 +353,7 @@ namespace TBeta
355353
return (1-eta*eta)*sum + eta*eta*gammaCont(en, mN);
356354
}
357355

358-
inline double dGammadEFull(bool order, double munu, double mN, double eta, double en) {
356+
double dGammadEFull(bool order, double munu, double mN, double eta, double en) {
359357
return dGammadE(order, munu, mN, eta, en) + dGammadECont(order, munu, mN, eta, en);
360358
}
361359
} // namespace TBeta

0 commit comments

Comments
 (0)