3 #include <utl/AugerUnits.h>
4 #include <utl/SVector.h>
5 #include <utl/Vector.h>
8 #include <fwk/LocalCoordinateSystem.h>
9 #include <fwk/CoordinateSystemRegistry.h>
17 const double g[],
const double h[]) :
20 fG(std::valarray<double>(g, order*(order+1)/2)),
21 fH(std::valarray<double>(h, order*(order+1)/2))
36 const double sin_longitude = sl[0] = sin(longitude);
37 const double cos_longitude = cl[0] = cos(longitude);
38 for (
size_t i = 1; i <
fOrder; ++i) {
39 sl[i] = sl[i-1] * cos_longitude + cl[i-1] * sin_longitude;
40 cl[i] = cl[i-1] * cos_longitude - sl[i-1] * sin_longitude;
48 const double sin_latitude = sin(latitude);
49 const double cos_latitude = cos(latitude);
50 p[0] = 2 * sin_latitude;
51 p[1] = 2 * cos_latitude;
52 p[2] = 4.5 * sin_latitude * sin_latitude - 1.5;
53 p[3] = 3 *
sqrt(3) * cos_latitude * sin_latitude;
56 q[2] = -3 * cos_latitude * sin_latitude;
57 q[3] =
sqrt(3) * (sin_latitude*sin_latitude - cos_latitude * cos_latitude);
59 for (
size_t k = 4, n = 2,
m = 2; k < npq; ++k, ++
m) {
65 const double aa =
sqrt(1 - 0.5/n);
66 const size_t j = k - n - 1;
67 p[k] = aa * (1 + 1./n) * cos_latitude *
p[j];
68 q[k] = aa * (cos_latitude * q[j] + sin_latitude/n *
p[j]);
72 const double aa =
sqrt (fn*fn - fm*fm);
73 const double bb =
sqrt ((fn - 1)*(fn - 1) - (fm*fm)) / aa;
74 const double cc = (2*fn - 1) / aa;
75 const size_t i = k - n;
76 const size_t j = k - 2*n + 1;
77 p[k] = (fn + 1) * (cc * sin_latitude / fn *
p[i] - bb/(fn - 1) *
p[j]);
78 q[k] = cc * (sin_latitude * q[i] - cos_latitude / fn *
p[i]) - bb * q[j];
87 const double ratio = earth_radius / elevation;
89 for (
size_t n = 1, k = 0; n <
fOrder; ++n) {
90 const double rr =
pow(ratio, n + 2);
91 const double aa = rr *
fG[k];
97 for (
size_t m = 0;
m < n; ++
m, ++k) {
98 const double aa = rr * fG[k];
99 const double bb = rr *
fH[k];
100 const double cc = aa * cl[
m] + bb * sl[
m];
105 if (cos_latitude > 0) {
106 const double fm =
m + 1;
108 y += (aa * sl[
m] - bb * cl[
m]) * fm * p[k] / ((fn + 1) * cos_latitude);
110 y += (aa * sl[
m] - bb * cl[
m]) * q[k] * sin_latitude;
138 const double x = where.
GetX(earthCS);
139 const double y = where.
GetY(earthCS);
140 const double z = where.
GetZ(earthCS);
142 const double longitude = atan2(y, x);
143 const double rho = where.
GetRho(earthCS);
144 const double latitude = atan2(z, rho);
145 const double height = where.
GetR(earthCS);
150 return utl::Vector(xyz[1], xyz[0], -xyz[2], localCS);
158 WARNING(
"Forgetting coefficients by shrinking model. You asked for it.");
161 fG.resize(order*(order+1) / 2, 0.);
162 fH.resize(order*(order+1) / 2, 0.);
182 model.
fG += factor * (later.
fG - model.
fG);
183 model.
fH += factor * (later.
fH - model.
fH);
188 ERROR(
"Order adaption of shrinking models unimplemented (laziness failure)");
double GetPhi(const CoordinateSystemPtr &coordinateSystem) const
azimuth (phi) angle in spherical and cylindrical coordinates
double GetR(const CoordinateSystemPtr &coordinateSystem) const
radius r in spherical coordinates coordinates (distance to origin)
ParametricGeoMagneticField Interpolate(const double year, const ParametricGeoMagneticField &later) const
Interpolate between two models Given a time as decimal year, interpolate coefficients between this an...
double pow(const double x, const unsigned int i)
double GetBaseYear() const
std::valarray< double > fG
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
double GetX(const CoordinateSystemPtr &coordinateSystem) const
void Grow(const size_t order)
#define WARNING(message)
Macro for logging warning messages.
double GetRho(const CoordinateSystemPtr &coordinateSystem) const
radius r in cylindrical coordinates (distance to z axis)
Spherical harmonics parametrisation of geomagnetic field.
double GetY(const CoordinateSystemPtr &coordinateSystem) const
constexpr double kilometer
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
static ParametricGeoMagneticField IGRF2010()
Named constructor for 2010 IGRF model This is meant for testing. Coefficients should rather be read f...
double GetDeclination(const utl::Point &where) const
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
#define ERROR(message)
Macro for logging error messages.
utl::SVector< 3, double > GetXYZ(const double latitude, const double longitude, const double elevation) const
Get magnetic field components from geocentric(!) coordinates Given the position relative to the earth...
utl::Vector Get(const utl::Point &where) const
std::valarray< double > fH
ParametricGeoMagneticField(const double baseyear, const size_t order, const double g[], const double h[])