OscProb
PMNS_OQS.cxx
Go to the documentation of this file.
1
8
9#include <unsupported/Eigen/MatrixFunctions>
10
11#include "PMNS_OQS.h"
12#include "exceptions.h"
13
14#include <iostream>
15
16using namespace std;
17using namespace OscProb;
18
19constexpr int SU3_DIM = PMNS_OQS::SU3_DIM;
20
21//.............................................................................
27PMNS_OQS::PMNS_OQS()
28 : PMNS_DensityMatrix(), fUM(3, vectorC(3, 0)), fHVMB(3, vectorC(3, 0)),
29 fHGM(SU3_DIM, vectorD(SU3_DIM, 0)), fD(SU3_DIM, vectorD(SU3_DIM, 0)),
30 fcos(SU3_DIM, vectorD(SU3_DIM, 1)), fa(SU3_DIM, 0), fR(SU3_DIM),
31 fRt(SU3_DIM), fM(8, 8)
32{
33 SetPower(0);
34 fBuiltDissipator = false;
35}
36
37//.............................................................................
42
43//.............................................................................
49void PMNS_OQS::SetPower(int n) { fPower = n; }
50
51//.............................................................................
58void PMNS_OQS::SetDecoElement(int i, double val)
59{
60 THROW_ON_INVALID_ARG(i > 0, i);
62
63 fBuiltDissipator *= (fa[i] == abs(val));
64 fa[i] = abs(val);
65}
66
67//.............................................................................
75void PMNS_OQS::SetDecoAngle(int i, int j, double th)
76{
77 THROW_ON_INVALID_ARG(i > 0, i);
79 THROW_ON_INVALID_ARG(j > 0, i);
81 THROW_ON_INVALID_ARG(i != j, i, j);
82
83 double val = cos(th);
84 fBuiltDissipator *= (fcos[i][j] == val);
85 fcos[i][j] = val;
86 fcos[j][i] = val;
87}
88
89//.............................................................................
95int PMNS_OQS::GetPower() { return fPower; }
96
97//.............................................................................
106{
107 THROW_ON_INVALID_ARG(i > 0, i);
109
110 return fa[i];
111}
112
113//.............................................................................
122double PMNS_OQS::GetDecoAngle(int i, int j)
123{
124 THROW_ON_INVALID_ARG(i > 0, i);
126 THROW_ON_INVALID_ARG(j > 0, i);
128 THROW_ON_INVALID_ARG(i != j, i, j);
129
130 return acos(fcos[i][j]);
131}
132
133//.............................................................................
142double PMNS_OQS::GetHGM(int i, int j)
143{
144 THROW_ON_INVALID_ARG(i >= 0, i);
146 THROW_ON_INVALID_ARG(j >= 0, i);
148
149 return fHGM[i][j];
150}
151
152//.............................................................................
162{
163 THROW_ON_INVALID_ARG(i >= 0, i);
165 THROW_ON_INVALID_ARG(j >= 0, i);
167
168 return fD[i][j];
169}
170
171//.............................................................................
177void PMNS_OQS::SetIsNuBar(bool isNuBar)
178{
179 fBuiltHms *= (fIsNuBar == isNuBar);
180 PMNS_Base::SetIsNuBar(isNuBar);
181}
182
183//.............................................................................
188{
189 if (fBuiltHms) return;
191 for (int i = 0; i < 3; i++) {
192 for (int j = 0; j < 3; j++) { fUM[i][j] = conj(fEvec[i][j]); }
193 }
195}
196
197//.............................................................................
204{
205 // Set the neutrino path
206 SetCurPath(p);
207
208 double kr2GNe = kK2 * M_SQRT2 * kGf;
209 kr2GNe *= fPath.density * fPath.zoa; // Matter potential in eV
210
211 double Ve = 0;
212
213 if (!fIsNuBar)
214 Ve = kr2GNe;
215 else
216 Ve = -kr2GNe;
217
218 BuildHms();
219
220 for (int i = 0; i < 3; i++) {
221 for (int j = i; j < 3; j++) {
222 fHVMB[i][j] = conj(fUM[0][i]) * Ve * fUM[0][j];
223 if (i > j) fHVMB[j][i] = conj(fHVMB[i][j]);
224 }
225 }
226
227 double lv = 2 * kGeV2eV * fEnergy; // 2E in eV
228
229 // add mass terms
230 fHVMB[1][1] += fDm[1] / lv;
231 fHVMB[2][2] += fDm[2] / lv;
232}
233
234//.............................................................................
242void get_GM(const matrixC& A, vectorD& v)
243{
244 v[0] = real(A[0][0] + A[1][1] + A[2][2]) / sqrt(6);
245 v[3] = real(A[0][0] - A[1][1]) / 2;
246 v[8] = real(A[0][0] + A[1][1] - 2. * A[2][2]) / sqrt(12);
247
248 v[1] = real(A[0][1]);
249 v[4] = real(A[0][2]);
250 v[6] = real(A[1][2]);
251
252 v[2] = -imag(A[0][1]);
253 v[5] = -imag(A[0][2]);
254 v[7] = -imag(A[1][2]);
255}
256
257//.............................................................................
265void get_SU3(const vectorD& v, matrixC& A)
266{
267 A[0][0] = v[0] * sqrt(2 / 3.) + v[3] + v[8] / sqrt(3);
268 A[1][1] = v[0] * sqrt(2 / 3.) - v[3] + v[8] / sqrt(3);
269 A[2][2] = v[0] * sqrt(2 / 3.) - 2 * v[8] / sqrt(3);
270
271 A[1][0] = complexD(v[1], v[2]);
272 A[2][0] = complexD(v[4], v[5]);
273 A[2][1] = complexD(v[6], v[7]);
274
275 for (int i = 0; i < 3; i++) {
276 for (int j = 0; j < i; j++) { A[j][i] = conj(A[i][j]); }
277 }
278}
279
280//.............................................................................
288void get_GMOP(const matrixC& A, matrixD& B)
289{
290 B[1][2] = real(A[0][0] - A[1][1]);
291 B[1][3] = 2 * imag(A[0][1]);
292 B[1][4] = -imag(A[1][2]);
293 B[1][5] = -real(A[1][2]);
294 B[1][6] = -imag(A[0][2]);
295 B[1][7] = -real(A[0][2]);
296
297 B[2][3] = 2 * real(A[0][1]);
298 B[2][4] = real(A[1][2]);
299 B[2][5] = -imag(A[1][2]);
300 B[2][6] = -real(A[0][2]);
301 B[2][7] = imag(A[0][2]);
302
303 B[3][4] = -imag(A[0][2]);
304 B[3][5] = -real(A[0][2]);
305 B[3][6] = imag(A[1][2]);
306 B[3][7] = real(A[1][2]);
307
308 B[4][5] = real(A[0][0] - A[2][2]);
309 B[4][6] = -imag(A[0][1]);
310 B[4][7] = real(A[0][1]);
311 B[4][8] = sqrt(3) * imag(A[0][2]);
312
313 B[5][6] = -real(A[0][1]);
314 B[5][7] = -imag(A[0][1]);
315 B[5][8] = sqrt(3) * real(A[0][2]);
316
317 B[6][7] = real(A[1][1] - A[2][2]);
318 B[6][8] = sqrt(3) * imag(A[1][2]);
319
320 B[7][8] = sqrt(3) * real(A[1][2]);
321
322 for (int i = 1; i < SU3_DIM; ++i) {
323 for (int j = i + 1; j < SU3_DIM; ++j) { B[j][i] = -B[i][j]; }
324 }
325}
326
327//.............................................................................
334{
335 BuildHVMB(p);
337}
338
339//.............................................................................
344{
345 if (fBuiltDissipator) return;
346
347 double aa[SU3_DIM][SU3_DIM];
348 for (int i = 1; i < SU3_DIM; i++) {
349 for (int j = i; j < SU3_DIM; j++) {
350 aa[i][j] = fa[i] * fa[j];
351 if (i == 8) aa[i][j] *= sqrt(3);
352 if (j == 8) aa[i][j] *= sqrt(3);
353 if (i < j) aa[i][j] *= fcos[i][j];
354 }
355 }
356 double sum12 = aa[1][1] + aa[2][2];
357 double sum45 = aa[4][4] + aa[5][5];
358 double sum67 = aa[6][6] + aa[7][7];
359 double gamma21 = aa[3][3];
360 double gamma31 = (aa[3][3] + aa[8][8] + 2 * aa[3][8]) / 4;
361 double gamma32 = (aa[3][3] + aa[8][8] - 2 * aa[3][8]) / 4;
362
363 fD[1][1] = gamma21 + aa[2][2] + (sum45 + sum67) / 4;
364 fD[2][2] = gamma21 + aa[1][1] + (sum45 + sum67) / 4;
365 fD[3][3] = sum12 + (sum45 + sum67) / 4;
366
367 fD[4][4] = gamma31 + aa[5][5] + (sum12 + sum67) / 4;
368 fD[5][5] = gamma31 + aa[4][4] + (sum12 + sum67) / 4;
369 fD[6][6] = gamma32 + aa[7][7] + (sum12 + sum45) / 4;
370 fD[7][7] = gamma32 + aa[6][6] + (sum12 + sum45) / 4;
371
372 fD[8][8] = (sum45 + sum67) * 3 / 4;
373 fD[3][8] = (sum45 - sum67) * sqrt(3) / 4;
374
375 fD[1][2] = -aa[1][2];
376 fD[1][3] = -aa[1][3];
377 fD[2][3] = -aa[2][3];
378 fD[4][5] = -aa[4][5];
379 fD[6][7] = -aa[6][7];
380
381 fD[1][8] = (aa[4][6] + aa[5][7]) * sqrt(3) / 2;
382 fD[2][8] = (aa[5][6] - aa[4][7]) * sqrt(3) / 2;
383
384 fD[4][6] = -(aa[4][6] - 2 * aa[1][8] - 3 * aa[5][7]) / 4;
385 fD[4][7] = -(aa[4][7] + 2 * aa[2][8] + 3 * aa[5][6]) / 4;
386 fD[5][6] = -(aa[5][6] - 2 * aa[2][8] + 3 * aa[4][7]) / 4;
387 fD[5][7] = -(aa[5][7] - 2 * aa[1][8] - 3 * aa[4][6]) / 4;
388
389 fD[1][4] = -(aa[1][4] - 3 * (aa[2][5] - aa[3][6]) + aa[6][8]) / 4;
390 fD[1][5] = -(aa[1][5] + 3 * (aa[2][4] + aa[3][7]) + aa[7][8]) / 4;
391 fD[1][6] = -(aa[1][6] + 3 * (aa[2][7] - aa[3][4]) + aa[4][8]) / 4;
392 fD[1][7] = -(aa[1][7] - 3 * (aa[2][6] + aa[3][5]) + aa[5][8]) / 4;
393 fD[2][4] = -(aa[2][4] + 3 * (aa[1][5] - aa[3][7]) - aa[7][8]) / 4;
394 fD[2][5] = -(aa[2][5] - 3 * (aa[1][4] - aa[3][6]) + aa[6][8]) / 4;
395 fD[2][6] = -(aa[2][6] - 3 * (aa[1][7] + aa[3][5]) + aa[5][8]) / 4;
396 fD[2][7] = -(aa[2][7] + 3 * (aa[1][6] + aa[3][4]) - aa[4][8]) / 4;
397 fD[3][4] = -(aa[3][4] - 3 * (aa[1][6] - aa[2][7]) + aa[4][8]) / 4;
398 fD[3][5] = -(aa[3][5] - 3 * (aa[1][7] + aa[2][6]) + aa[5][8]) / 4;
399 fD[3][6] = -(aa[3][6] + 3 * (aa[1][4] + aa[2][5]) - aa[6][8]) / 4;
400 fD[3][7] = -(aa[3][7] + 3 * (aa[1][5] - aa[2][4]) - aa[7][8]) / 4;
401
402 fD[4][8] = -(aa[1][6] - aa[2][7] + aa[3][4] + aa[4][8]) * sqrt(3) / 4;
403 fD[5][8] = -(aa[1][7] + aa[2][6] + aa[3][5] + aa[5][8]) * sqrt(3) / 4;
404 fD[6][8] = -(aa[1][4] + aa[2][5] - aa[3][6] + aa[6][8]) * sqrt(3) / 4;
405 fD[7][8] = -(aa[1][5] - aa[2][4] - aa[3][7] + aa[7][8]) * sqrt(3) / 4;
406
407 for (int j = 1; j < SU3_DIM; j++) {
408 for (int k = j; k < SU3_DIM; k++) {
409 fD[j][k] = -fD[j][k] * kGeV2eV;
410 fD[k][j] = fD[j][k];
411 }
412 }
413
414 fBuiltDissipator = true;
415}
416
417//.............................................................................
424{
425 BuildHGM(p);
427 double energyCorr = pow(fEnergy, fPower);
428 for (int k = 1; k < SU3_DIM; ++k) {
429 for (int j = 1; j < SU3_DIM; ++j) {
430 fM(k - 1, j - 1) = fHGM[k][j] + fD[k][j] * energyCorr;
431 }
432 }
433}
434
435//.............................................................................
440
441//.............................................................................
446
447//.............................................................................
453void PMNS_OQS::RotateState(bool to_mass)
454{
455 BuildHms();
456 if (!to_mass) UpdateRho();
458 if (to_mass) BuildR();
459}
460
461//.............................................................................
466{
467 RotateState(true);
469 RotateState(false);
470}
471
472//.............................................................................
479{
480 BuildM(p);
481
482 // Solve for eigensystem
483 SolveHam();
484
485 // Convert path length to eV
486 double lengthIneV = kKm2eV * p.length;
487
488 fM *= lengthIneV;
489 fM = fM.exp();
490
491 fRt[0] = fR[0];
492
493 for (int i = 1; i < SU3_DIM; ++i) {
494 fRt[i] = 0;
495 for (int j = 1; j < SU3_DIM; ++j) { fRt[i] += fM(i - 1, j - 1) * fR[j]; }
496 }
497 fR = fRt;
498}
499
500//.............................................................................
514matrixD PMNS_OQS::ProbMatrix(int nflvi, int nflvf)
515{
516 THROW_ON_INVALID_ARG(nflvi >= 0, nflvi);
517 THROW_ON_INVALID_ARG(nflvi <= fNumNus, nflvi, fNumNus);
518 THROW_ON_INVALID_ARG(nflvf >= 0, nflvf);
519 THROW_ON_INVALID_ARG(nflvf <= fNumNus, nflvf, fNumNus);
520
521 // Output probabilities
522 matrixD probs(nflvi, vectorD(nflvf));
523
524 // List of states
525 vector<vectorD> allstates(nflvi, vectorD(9));
526
527 // Reset all initial states
528 for (int i = 0; i < nflvi; i++) {
530 RotateState(true);
531 allstates[i] = fR;
532 }
533
534 // Propagate all states in parallel
535 for (int i = 0; i < int(fNuPaths.size()); i++) {
536 for (int flvi = 0; flvi < nflvi; flvi++) {
537 fR = allstates[flvi];
539 allstates[flvi] = fR;
540 }
541 }
542
543 // Get all probabilities
544 for (int flvi = 0; flvi < nflvi; flvi++) {
545 fR = allstates[flvi];
546 RotateState(false);
547 for (int flvj = 0; flvj < nflvf; flvj++) { probs[flvi][flvj] = P(flvj); }
548 }
549
550 return probs;
551}
552
void get_GM(const matrixC &A, vectorD &v)
Definition: PMNS_OQS.cxx:242
void get_SU3(const vectorD &v, matrixC &A)
Definition: PMNS_OQS.cxx:265
constexpr int SU3_DIM
Definition: PMNS_OQS.cxx:19
void get_GMOP(const matrixC &A, matrixD &B)
Definition: PMNS_OQS.cxx:288
virtual void Propagate()
Propagate neutrino through full path.
Definition: PMNS_Base.cxx:1018
bool fIsNuBar
Anti-neutrino flag.
Definition: PMNS_Base.h:293
int fNumNus
Number of neutrino flavours.
Definition: PMNS_Base.h:277
std::vector< NuPath > fNuPaths
Vector of neutrino paths.
Definition: PMNS_Base.h:295
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
static const double kKm2eV
km to eV^-1
Definition: PMNS_Base.h:215
virtual void SetIsNuBar(bool isNuBar)
Set the anti-neutrino flag.
Definition: PMNS_Base.cxx:243
static const double kGf
G_F in units of GeV^-2.
Definition: PMNS_Base.h:220
matrixC fEvec
Eigenvectors of the Hamiltonian.
Definition: PMNS_Base.h:290
NuPath fPath
Current neutrino path.
Definition: PMNS_Base.h:296
bool fBuiltHms
Tag to avoid rebuilding Hms.
Definition: PMNS_Base.h:298
virtual void SetCurPath(NuPath p)
Set the path currently in use by the class.
Definition: PMNS_Base.cxx:274
vectorD fDm
m^2_i - m^2_1 in vacuum
Definition: PMNS_Base.h:279
virtual void BuildHms()
Build the matrix of masses squared.
Definition: PMNS_Base.cxx:955
static const double kGeV2eV
GeV to eV.
Definition: PMNS_Base.h:217
Base class for methods based on density matrices.
virtual void ResetToFlavour(int flv)
Reset neutrino state to pure flavour flv.
virtual void RotateState(bool to_basis, matrixC U)
Rotate rho to/from a given basis.
virtual double P(int flv)
Return the probability of final state in flavour flv.
matrixC fRho
The neutrino density matrix state.
virtual void SetVacuumEigensystem()
Set the eigensystem to the analytic solution of the vacuum Hamiltonian.
Definition: PMNS_Fast.cxx:154
virtual void SolveHam()
Solve the full Hamiltonian for eigenvectors and eigenvalues.
Definition: PMNS_Fast.cxx:98
int fPower
Power-law index (n).
Definition: PMNS_OQS.h:86
matrixD fHGM
Effective Hamiltonian in GMB (9x9).
Definition: PMNS_OQS.h:94
vectorD fa
Dissipator parameters |a_i|.
Definition: PMNS_OQS.h:87
vectorD fR
Initial state of density matrix in Gell-Mann basis.
Definition: PMNS_OQS.h:90
virtual int GetPower()
Get the currently set power-law index for decoherence parameters.
Definition: PMNS_OQS.cxx:95
virtual void SetDecoAngle(int i, int j, double th)
Set mixing angle between two decoherence parameters a_i, a_j.
Definition: PMNS_OQS.cxx:75
virtual void SetDecoElement(int i, double val)
Set value of the a_i decoherence element in Gell-Mann basis.
Definition: PMNS_OQS.cxx:58
bool fBuiltDissipator
Flag to rebuild dissipator.
Definition: PMNS_OQS.h:99
virtual matrixD ProbMatrix(int nflvi, int nflvf)
Reimplemented from PMNS_DensityMatrix.
Definition: PMNS_OQS.cxx:514
virtual void BuildR()
Build Gell-Mann representation of density matrix.
Definition: PMNS_OQS.cxx:439
virtual void BuildM(NuPath p)
Build the matrix M used in evolution equations.
Definition: PMNS_OQS.cxx:423
virtual void BuildHVMB(NuPath p)
Build effective Hamiltonian in Vacuum Mass Basis (VMB).
Definition: PMNS_OQS.cxx:203
matrixD fD
Off-diagonal, 9x9 dissipator.
Definition: PMNS_OQS.h:95
matrixC fHVMB
Effective Hamiltonian in VMB (3x3).
Definition: PMNS_OQS.h:93
static constexpr int SU3_DIM
Dimension of the SU(3) Gell-Mann basis.
Definition: PMNS_OQS.h:34
vectorD fRt
Time evolution of density matrix in Gell-Mann basis.
Definition: PMNS_OQS.h:91
virtual void PropagatePath(NuPath p)
Reimplemented from PMNS_Base.
Definition: PMNS_OQS.cxx:478
virtual void SetPower(int n)
Definition: PMNS_OQS.cxx:49
virtual void SetIsNuBar(bool isNuBar)
Reimplemented from PMNS_Base.
Definition: PMNS_OQS.cxx:177
virtual double GetDissipatorElement(int i, int j)
Get dissipator element in Gell-Mann basis.
Definition: PMNS_OQS.cxx:161
virtual double GetHGM(int i, int j)
Get element i,j of the dissipator matrix in Gell-Mann basis.
Definition: PMNS_OQS.cxx:142
virtual void UpdateRho()
Update density matrix from Gell-Mann representation.
Definition: PMNS_OQS.cxx:445
virtual void BuildDissipator()
Build the dissipator in Gell-Mann representation.
Definition: PMNS_OQS.cxx:343
virtual void Propagate()
Reimplemented from PMNS_Base.
Definition: PMNS_OQS.cxx:465
virtual ~PMNS_OQS()
Destructor.
Definition: PMNS_OQS.cxx:41
virtual void BuildHGM(NuPath p)
Build effective Hamiltonian in Gell-Mann representation (GM).
Definition: PMNS_OQS.cxx:333
virtual void RotateState(bool to_mass)
Rotate rho to/from mass basis.
Definition: PMNS_OQS.cxx:453
virtual void BuildHms()
Reimplemented from PMNS_Base.
Definition: PMNS_OQS.cxx:187
matrixD fcos
cosines ai . aj
Definition: PMNS_OQS.h:88
Eigen::MatrixXd fM
Buffer matrix for exponential.
Definition: PMNS_OQS.h:97
virtual double GetDecoAngle(int i, int j)
Get mixing angle between two decoherence parameters a_i, a_j.
Definition: PMNS_OQS.cxx:122
matrixC fUM
PMNS Matrix.
Definition: PMNS_OQS.h:92
virtual double GetDecoElement(int i)
Get the value of the a_i decoherence parameter in Gell-Mann basis.
Definition: PMNS_OQS.cxx:105
#define THROW_ON_INVALID_ARG(condition,...)
Definition: exceptions.h:85
Some useful general definitions.
Definition: Absorption.h:6
std::complex< double > complexD
Definition: Definitions.h:21
std::vector< complexD > vectorC
Definition: Definitions.h:22
std::vector< double > vectorD
Definition: Definitions.h:18
std::vector< vectorD > matrixD
Definition: Definitions.h:19
std::vector< vectorC > matrixC
Definition: Definitions.h:23
Definition: EigenPoint.h:44
A struct representing a neutrino path segment.
Definition: NuPath.h:34
double density
The density of the path segment in g/cm^3.
Definition: NuPath.h:79
double length
The length of the path segment in km.
Definition: NuPath.h:78
double zoa
The effective Z/A value of the path segment.
Definition: NuPath.h:80