-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathUF23Field.h
158 lines (140 loc) · 4.66 KB
/
UF23Field.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#ifndef _UF23Field_h_
#define _UF23Field_h_
/**
@class UF23Field
@brief UF23Field Galactic magnetic field model
Implements the eight coherent magnetic field models of UF23
See: M. Unger and G.R. Farrar, arXiv:2311.12120
Assumes a galactocentric coordinate system with the Galactic center
at the origin, the x-axis pointing in the opposite direction of the
Sun, and the z-axis pointing towards Galactic North.
*/
#include <vector>
#include <map>
#include <string>
#include "Vector3.h"
class UF23Field {
public:
/// model variations (see Tab.2 of UF23 paper)
enum ModelType {
base,
neCL,
expX,
spur,
cre10,
synCG,
twistX,
nebCor
};
static const std::string& GetModelName(const ModelType m)
{ return fModelNames.at(m); }
static const std::map<ModelType, std::string>& GetModelNames()
{ return fModelNames; }
const std::string& GetModelName() const
{ return fModelNames.at(fModelType); }
/// model parameters, see Table 3 of UF23 paper
enum EPar {
eDiskB1 = 0,
eDiskB2,
eDiskB3,
eDiskH,
eDiskPhase1,
eDiskPhase2,
eDiskPhase3,
eDiskPitch,
eDiskW,
ePoloidalA,
ePoloidalB,
ePoloidalP,
ePoloidalR,
ePoloidalW,
ePoloidalZ,
ePoloidalXi,
eSpurCenter,
eSpurLength,
eSpurWidth,
eStriation,
eToroidalBN,
eToroidalBS,
eToroidalR,
eToroidalW,
eToroidalZ,
eTwistingTime,
eNpar
};
public:
/**
@brief constructor
@param mt model type (see Tab.2 of UF23 paper)
@param maxRadiusInKpc maximum radius of field in kpc
*/
UF23Field(const ModelType mt, const double maxRadiusInKpc = 30);
/// no default constructor
UF23Field() = delete;
/**
@brief calculate coherent magnetic field at a given position
@param posInKpc position with components given in kpc
@return coherent field in microgauss
*/
Vector3 operator()(const Vector3& posInKpc) const;
/// get parameter vector (units: kpc, microgauss, degree, Myr)
std::vector<double> GetParameters() const;
/// overwrite default model parameters (units: kpc, microgauss, degree, Myr)
void SetParameters(const std::vector<double>& newpar);
/// maximum squared radius of field model
double GetMaximumSquaredRadius() const;
private:
/// model type given in constructor
const ModelType fModelType;
/// maximum galacto-centric radius beyond which B=0
const double fMaxRadiusSquared;
// parameters are stored in array
double fParameters[eNpar] = { 0 };
// references to parameters for convience
double& fDiskB1 = fParameters[eDiskB1];
double& fDiskB2 = fParameters[eDiskB2];
double& fDiskB3 = fParameters[eDiskB3];
double& fDiskH = fParameters[eDiskH];
double& fDiskPhase1 = fParameters[eDiskPhase1];
double& fDiskPhase2 = fParameters[eDiskPhase2];
double& fDiskPhase3 = fParameters[eDiskPhase3];
double& fDiskPitch = fParameters[eDiskPitch];
double& fDiskW = fParameters[eDiskW];
double& fPoloidalA = fParameters[ePoloidalA];
double& fPoloidalB = fParameters[ePoloidalB];
double& fPoloidalP = fParameters[ePoloidalP];
double& fPoloidalR = fParameters[ePoloidalR];
double& fPoloidalW = fParameters[ePoloidalW];
double& fPoloidalZ = fParameters[ePoloidalZ];
double& fPoloidalXi = fParameters[ePoloidalXi];
double& fSpurCenter = fParameters[eSpurCenter];
double& fSpurLength = fParameters[eSpurLength];
double& fSpurWidth = fParameters[eSpurWidth];
double& fStriation = fParameters[eStriation];
double& fToroidalBN = fParameters[eToroidalBN];
double& fToroidalBS = fParameters[eToroidalBS];
double& fToroidalR = fParameters[eToroidalR];
double& fToroidalW = fParameters[eToroidalW];
double& fToroidalZ = fParameters[eToroidalZ];
double& fTwistingTime = fParameters[eTwistingTime];
// some pre-calculated derived parameter values
double fSinPitch = 0;
double fCosPitch = 0;
double fTanPitch = 0;
/// major field components
Vector3 GetDiskField(const Vector3& pos) const;
Vector3 GetHaloField(const Vector3& pos) const;
/// sub-components depending on model type
/// -- Sec. 5.2.2
Vector3 GetSpiralField(const double x, const double y, const double z) const;
/// -- Sec. 5.2.3
Vector3 GetSpurField(const double x, const double y, const double z) const;
/// -- Sec. 5.3.1
Vector3 GetToroidalHaloField(const double x, const double y, const double z) const;
/// -- Sec. 5.3.2
Vector3 GetPoloidalHaloField(const double x, const double y, const double z) const;
/// -- Sec. 5.3.3
Vector3 GetTwistedHaloField(const double x, const double y, const double z) const;
static const std::map<ModelType, std::string> fModelNames;
};
#endif