OscProb
PMNS_SiderealLIV.cxx
Go to the documentation of this file.
1
15
16#include <algorithm>
17#include <cmath>
18#include <iostream>
19
21#include "PMNS_SiderealLIV.h"
22
23using namespace OscProb;
24
25using namespace std;
26
27//.............................................................................
32PMNS_SiderealLIV::PMNS_SiderealLIV()
33 : PMNS_Fast(), fa{}, fc{}, fN{0.0, 0.0, 0.0}, fTime(0.0), fChi(0.0)
34{
35 SetStdPath();
36 // The Maltoni averaging method assumes H ∝ 1/E, which is not valid here
37 // because the LIV terms scale as E^0 (aT) and E^1 (cT).
38 SetIsOscProbAvg(true);
39}
40
41//.............................................................................
46
47//.............................................................................
50bool PMNS_SiderealLIV::ValidateAndOrder(int& flvi, int& flvj, const char* name)
51{
52 if (flvi > flvj) {
53 cerr << "WARNING: First argument should be smaller or equal to second "
54 "argument"
55 << endl
56 << "Setting reverse order (" << name << "_" << flvj << flvi << "). "
57 << endl;
58 std::swap(flvi, flvj);
59 }
60 if (flvi < 0 || flvi > 2 || flvj < flvi || flvj > 2) {
61 cerr << "WARNING: " << name << "_" << flvi << flvj
62 << " not valid for 3 neutrinos. Doing nothing." << endl;
63 return false;
64 }
65 return true;
66}
67
68//.............................................................................
71bool PMNS_SiderealLIV::ValidateCoord(int coord, const char* coordName,
72 const char* paramName)
73{
74 if (coord < 0 || coord > 2) {
75 cerr << "WARNING: " << coordName << " = " << coord
76 << " out of range [0,2] for " << paramName << ". Doing nothing."
77 << endl;
78 return false;
79 }
80 return true;
81}
82
83//.............................................................................
97void PMNS_SiderealLIV::SetA(int flvi, int flvj, int coord, double val)
98{
99 if (!ValidateAndOrder(flvi, flvj, "aT")) return;
100 if (!ValidateCoord(coord, "coord", "aT")) return;
101
102 fa[flvi][flvj][coord] = val;
103}
104
105//.............................................................................
120void PMNS_SiderealLIV::SetC(int flvi, int flvj, int coord1, int coord2,
121 double val)
122{
123 if (!ValidateAndOrder(flvi, flvj, "cT")) return;
124 if (!ValidateCoord(coord1, "coord1", "cT")) return;
125 if (!ValidateCoord(coord2, "coord2", "cT")) return;
126
127 fc[flvi][flvj][coord1][coord2] = val;
128}
129
130//.............................................................................
146double PMNS_SiderealLIV::GetA(int flvi, int flvj, int coord)
147{
148 if (!ValidateAndOrder(flvi, flvj, "aT")) return 0;
149 if (!ValidateCoord(coord, "coord", "aT")) return 0;
150
151 return fa[flvi][flvj][coord];
152}
153
154//.............................................................................
171double PMNS_SiderealLIV::GetC(int flvi, int flvj, int coord1, int coord2)
172{
173 if (!ValidateAndOrder(flvi, flvj, "cT")) return 0;
174 if (!ValidateCoord(coord1, "coord1", "cT")) return 0;
175 if (!ValidateCoord(coord2, "coord2", "cT")) return 0;
176
177 return fc[flvi][flvj][coord1][coord2];
178}
179
180//.............................................................................
187void PMNS_SiderealLIV::SetNeutrinoDirection(double zenith, double azimuth)
188{
189 double chi = fChi * M_PI / 180.0;
190 double zen = zenith * M_PI / 180.0;
191 double azi = azimuth * M_PI / 180.0;
192 double N0 = cos(chi) * sin(zen) * cos(azi) + sin(chi) * cos(zen);
193 double N1 = sin(zen) * sin(azi);
194 double N2 = -sin(chi) * sin(zen) * cos(azi) + cos(chi) * cos(zen);
195
196 fGotES *= (fN[0] == N0 && fN[1] == N1 && fN[2] == N2);
197
198 fN[0] = N0;
199 fN[1] = N1;
200 fN[2] = N2;
201}
202
203//.............................................................................
210{
211 fGotES *= (fTime == hours);
212 fTime = hours;
213}
214
215//.............................................................................
221void PMNS_SiderealLIV::SetColatitude(double chi) { fChi = chi; }
222
223//.............................................................................
233void PMNS_SiderealLIV::SetColatitude(double deg, double min, double sec)
234{
235 double latitude = deg + min / 60.0 + sec / 3600.0;
236 fChi = 90.0 - latitude;
237}
238
239//.............................................................................
245double PMNS_SiderealLIV::GetColatitude() const { return fChi; }
246
247//.............................................................................
252{
253 double lv = 2 * kGeV2eV * fEnergy; // 2*E in eV
254
255 // Set the vacuum Hamiltonian
256 for (int i = 0; i < fNumNus; i++) {
257 for (int j = i; j < fNumNus; j++) { fHam[i][j] = fHms[i][j] / lv; }
258 }
259
260 // Add matter potential
261 double kr2GNe = kK2 * M_SQRT2 * kGf * fPath.density * fPath.zoa;
262 if (!fIsNuBar)
263 fHam[0][0] += kr2GNe;
264 else
265 fHam[0][0] -= kr2GNe;
266
267 for (int i = 0; i < fNumNus; i++) {
268 for (int j = i; j < fNumNus; j++) {
269 double sign = fIsNuBar ? -kGeV2eV : kGeV2eV;
270
271 double C0 = -sign * fa[i][j][2] * fN[2];
272
273 double As0 = sign * (fa[i][j][0] * fN[1] - fa[i][j][1] * fN[0]);
274 double Ac0 = -sign * (fa[i][j][0] * fN[0] + fa[i][j][1] * fN[1]);
275
276 double As1 = 2 * fN[1] * fN[2] * fc[i][j][0][2] -
277 2 * fN[0] * fN[2] * fc[i][j][1][2];
278 double Ac1 = -2 * fN[0] * fN[2] * fc[i][j][0][2] -
279 2 * fN[1] * fN[2] * fc[i][j][1][2];
280
281 double Bs1 = fN[0] * fN[1] * (fc[i][j][0][0] - fc[i][j][1][1]) -
282 (fN[0] * fN[0] - fN[1] * fN[1]) * fc[i][j][0][1];
283 double Bs = fEnergy * Bs1;
284
285 double Bc1 = -0.5 * (fN[0] * fN[0] - fN[1] * fN[1]) *
286 (fc[i][j][0][0] - fc[i][j][1][1]) -
287 2.0 * fN[0] * fN[1] * fc[i][j][0][1];
288 double Bc = fEnergy * Bc1;
289
290 double As = As0 + fEnergy * As1;
291 double Ac = Ac0 + fEnergy * Ac1;
292
293 double liv_term =
294 C0 + As * sin(kOmegaSidereal * fTime) +
295 Ac * cos(kOmegaSidereal * fTime) +
296 Bs * 2 * sin(kOmegaSidereal * fTime) * cos(kOmegaSidereal * fTime) +
297 Bc * (cos(kOmegaSidereal * fTime) * cos(kOmegaSidereal * fTime) -
298 sin(kOmegaSidereal * fTime) * sin(kOmegaSidereal * fTime));
299
300 fHam[i][j] += liv_term;
301 }
302 }
303
304 // Conjugate Hamiltonian for antineutrinos
305 if (fIsNuBar) {
306 for (int i = 0; i < fNumNus; i++) {
307 for (int j = i + 1; j < fNumNus; j++) { fHam[i][j] = conj(fHam[i][j]); }
308 }
309 }
310}
311
bool fIsNuBar
Anti-neutrino flag.
Definition: PMNS_Base.h:293
int fNumNus
Number of neutrino flavours.
Definition: PMNS_Base.h:277
double fEnergy
Neutrino energy.
Definition: PMNS_Base.h:292
static const double kK2
mol/GeV^2/cm^3 to eV
Definition: PMNS_Base.h:216
matrixC fHms
matrix H*2E in eV^2
Definition: PMNS_Base.h:284
bool fGotES
Tag to avoid recalculating eigensystem.
Definition: PMNS_Base.h:299
static const double kGf
G_F in units of GeV^-2.
Definition: PMNS_Base.h:220
NuPath fPath
Current neutrino path.
Definition: PMNS_Base.h:296
static const double kGeV2eV
GeV to eV.
Definition: PMNS_Base.h:217
virtual void SetStdPath()
Set standard neutrino path.
Definition: PMNS_Base.cxx:205
Implementation of oscillations of neutrinos in matter in a three-neutrino framework.
Definition: PMNS_Fast.h:40
complexD fHam[3][3]
The full hamiltonian.
Definition: PMNS_Fast.h:64
virtual void SetIsOscProbAvg(bool isOscProbAvg)
Set flag for which averaging to use.
virtual void SetA(int flvi, int flvj, int coord, double val)
virtual double GetC(int flvi, int flvj, int coord1, int coord2)
virtual ~PMNS_SiderealLIV()
Destructor.
virtual void SetColatitude(double chi)
virtual double GetA(int flvi, int flvj, int coord)
static bool ValidateAndOrder(int &flvi, int &flvj, const char *name)
double fc[3][3][3][3]
cT LIVS parameters (mass dimension 4)
double fa[3][3][3]
aT LIVS parameters (mass dimension 3)
static bool ValidateCoord(int coord, const char *coordName, const char *paramName)
virtual double GetColatitude() const
Get the detector colatitude (chi), in degrees.
double fTime
Local sidereal time, in hours.
virtual void SetC(int flvi, int flvj, int coord1, int coord2, double val)
virtual void UpdateHam()
Build the full Hamiltonian.
static constexpr double kOmegaSidereal
Angular sidereal frequency, in rad/h.
double fN[3]
Neutrino directional factors (NX, NY, NZ)
virtual void SetNeutrinoDirection(double zenith, double azimuth)
virtual void SetTimeHours(double hours)
Some useful general definitions.
Definition: Absorption.h:6
Definition: EigenPoint.h:44
double density
The density of the path segment in g/cm^3.
Definition: NuPath.h:79
double zoa
The effective Z/A value of the path segment.
Definition: NuPath.h:80