gps_pvt 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/CHANGELOG.md +5 -0
  4. data/CODE_OF_CONDUCT.md +84 -0
  5. data/Gemfile +10 -0
  6. data/README.md +86 -0
  7. data/Rakefile +86 -0
  8. data/bin/console +15 -0
  9. data/bin/setup +8 -0
  10. data/ext/gps_pvt/Coordinate/Coordinate_wrap.cxx +6613 -0
  11. data/ext/gps_pvt/GPS/GPS_wrap.cxx +16019 -0
  12. data/ext/gps_pvt/SylphideMath/SylphideMath_wrap.cxx +21050 -0
  13. data/ext/gps_pvt/extconf.rb +70 -0
  14. data/ext/ninja-scan-light/tool/navigation/EGM.h +2971 -0
  15. data/ext/ninja-scan-light/tool/navigation/GPS.h +2432 -0
  16. data/ext/ninja-scan-light/tool/navigation/GPS_Solver.h +479 -0
  17. data/ext/ninja-scan-light/tool/navigation/GPS_Solver_Base.h +1081 -0
  18. data/ext/ninja-scan-light/tool/navigation/GPS_Solver_MultiFrequency.h +199 -0
  19. data/ext/ninja-scan-light/tool/navigation/GPS_Solver_RAIM.h +210 -0
  20. data/ext/ninja-scan-light/tool/navigation/MagneticField.h +928 -0
  21. data/ext/ninja-scan-light/tool/navigation/NTCM.h +211 -0
  22. data/ext/ninja-scan-light/tool/navigation/RINEX.h +1781 -0
  23. data/ext/ninja-scan-light/tool/navigation/WGS84.h +186 -0
  24. data/ext/ninja-scan-light/tool/navigation/coordinate.h +406 -0
  25. data/ext/ninja-scan-light/tool/param/bit_array.h +145 -0
  26. data/ext/ninja-scan-light/tool/param/complex.h +558 -0
  27. data/ext/ninja-scan-light/tool/param/matrix.h +4049 -0
  28. data/ext/ninja-scan-light/tool/param/matrix_fixed.h +665 -0
  29. data/ext/ninja-scan-light/tool/param/matrix_special.h +562 -0
  30. data/ext/ninja-scan-light/tool/param/quaternion.h +765 -0
  31. data/ext/ninja-scan-light/tool/param/vector3.h +651 -0
  32. data/ext/ninja-scan-light/tool/swig/Coordinate.i +177 -0
  33. data/ext/ninja-scan-light/tool/swig/GPS.i +1102 -0
  34. data/ext/ninja-scan-light/tool/swig/SylphideMath.i +1234 -0
  35. data/ext/ninja-scan-light/tool/swig/extconf.rb +5 -0
  36. data/ext/ninja-scan-light/tool/swig/makefile +53 -0
  37. data/ext/ninja-scan-light/tool/swig/spec/GPS_spec.rb +417 -0
  38. data/ext/ninja-scan-light/tool/swig/spec/SylphideMath_spec.rb +489 -0
  39. data/gps_pvt.gemspec +57 -0
  40. data/lib/gps_pvt/receiver.rb +375 -0
  41. data/lib/gps_pvt/ubx.rb +148 -0
  42. data/lib/gps_pvt/version.rb +5 -0
  43. data/lib/gps_pvt.rb +9 -0
  44. data/sig/gps_pvt.rbs +4 -0
  45. metadata +117 -0
@@ -0,0 +1,928 @@
1
+ /*
2
+ * Copyright (c) 2015, M.Naruoka (fenrir)
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without modification,
6
+ * are permitted provided that the following conditions are met:
7
+ *
8
+ * - Redistributions of source code must retain the above copyright notice,
9
+ * this list of conditions and the following disclaimer.
10
+ * - Redistributions in binary form must reproduce the above copyright notice,
11
+ * this list of conditions and the following disclaimer in the documentation
12
+ * and/or other materials provided with the distribution.
13
+ * - Neither the name of the naruoka.org nor the names of its contributors
14
+ * may be used to endorse or promote products derived from this software
15
+ * without specific prior written permission.
16
+ *
17
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
21
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
22
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ *
30
+ */
31
+
32
+ #ifndef __MAGNETIC_FIELD_H__
33
+ #define __MAGNETIC_FIELD_H__
34
+
35
+ #define _USE_MATH_DEFINES
36
+ #include <cmath>
37
+
38
+ #include "WGS84.h"
39
+
40
+ template <class FloatT>
41
+ class MagneticFieldGeneric {
42
+ public:
43
+ struct model_t {
44
+ const char *name;
45
+ FloatT year;
46
+ int dof;
47
+ FloatT coef[256];
48
+ };
49
+
50
+ static void model_inter_extra_polation(
51
+ model_t &model_new,
52
+ const model_t &model_early, const model_t &model_late){
53
+ FloatT factor((model_new.year - model_early.year)
54
+ / (model_late.year - model_early.year));
55
+
56
+ model_new.name = "(generated)";
57
+ int coef_common;
58
+
59
+ if(model_new.dof > 0){ // fixed DOF
60
+ coef_common = model_new.dof * (model_new.dof + 2);
61
+ }else{ // automatically determine DOF
62
+ if(model_early.dof >= model_late.dof){
63
+ coef_common = model_late.dof * (model_late.dof + 2);
64
+ model_new.dof = model_early.dof;
65
+
66
+ for(int i(coef_common); i < model_early.dof * (model_early.dof + 2); i--){
67
+ model_new.coef[i] = model_early.coef[i] * (1.0 - factor);
68
+ }
69
+ }else{
70
+ coef_common = model_early.dof * (model_early.dof + 2);
71
+ model_new.dof = model_late.dof;
72
+
73
+ for(int i(coef_common); i < model_late.dof * (model_late.dof + 2); i--){
74
+ model_new.coef[i] = model_late.coef[i] * factor;
75
+ }
76
+ }
77
+ }
78
+ for(int i(0); i < coef_common; i++){
79
+ model_new.coef[i] = model_early.coef[i]
80
+ + factor * (model_late.coef[i] - model_early.coef[i]);
81
+ }
82
+ }
83
+ static model_t model_inter_extra_polation(
84
+ const FloatT &year,
85
+ const model_t &model_early, const model_t &model_late,
86
+ const int &dof = 0){
87
+ model_t model_new;
88
+ model_new.year = year;
89
+ model_new.dof = dof; // default(0): automatically determine DOF
90
+ model_inter_extra_polation(model_new, model_early, model_late);
91
+ return model_new;
92
+ }
93
+
94
+ static void make_model(
95
+ model_t &model_new, const model_t *models[], const unsigned int &models_size){
96
+ if(models_size < 1){
97
+ return;
98
+ }else if(models_size == 1){
99
+ model_new = *models[0];
100
+ return;
101
+ }
102
+ const model_t *a(models[0]), *b(models[1]);
103
+ FloatT a_dist(std::abs(model_new.year - a->year)), b_dist(std::abs(model_new.year - b->year));
104
+ for(unsigned int i(2); i < models_size; ++i){
105
+ FloatT dist(std::abs(model_new.year - models[i]->year));
106
+ if(dist < a_dist){
107
+ if(a_dist < b_dist){
108
+ b = models[i];
109
+ b_dist = dist;
110
+ }else{
111
+ a = models[i];
112
+ a_dist = dist;
113
+ }
114
+ }else if(dist < b_dist){
115
+ b = models[i];
116
+ b_dist = dist;
117
+ }
118
+ }
119
+ model_inter_extra_polation(model_new, *a, *b);
120
+ }
121
+ static model_t make_model(
122
+ const FloatT &year,
123
+ const model_t *models[], const unsigned int &models_size,
124
+ const int &dof = 0){
125
+ model_t res;
126
+ res.year = year;
127
+ res.dof = dof; // default(0): automatically determine DOF
128
+ make_model(res, models, models_size);
129
+ return res;
130
+ }
131
+
132
+ struct field_components_res_t {FloatT north, east, down;};
133
+ protected:
134
+ static field_components_res_t field_components_geocentric(
135
+ const model_t &model,
136
+ const FloatT &sin_geocentric_latitude, const FloatT &cos_geocentric_latitude,
137
+ const FloatT &longitude_rad,
138
+ const FloatT &radius_meter){
139
+ using std::cos;
140
+ using std::sin;
141
+ using std::pow;
142
+ using std::sqrt;
143
+ field_components_res_t res;
144
+
145
+ // @see http://mooring.ucsd.edu/software/matlab/mfiles/toolbox/geo/IGRF/geomag60.c
146
+
147
+ const FloatT slat(sin_geocentric_latitude);
148
+ const FloatT clat(cos_geocentric_latitude);
149
+
150
+ FloatT sl[13] = {sin(longitude_rad)};
151
+ FloatT cl[13] = {cos(longitude_rad)};
152
+
153
+ res.north = res.east = res.down = 0;
154
+
155
+ FloatT aa, bb, cc, rr;
156
+
157
+ aa = sqrt(3.0);
158
+ FloatT p[118] = {
159
+ 2.0 * slat,
160
+ 2.0 * clat,
161
+ 4.5 * slat * slat - 1.5,
162
+ 3.0 * aa * clat * slat};
163
+ FloatT q[118] = {
164
+ -clat,
165
+ slat,
166
+ -3.0 * clat * slat,
167
+ aa * (slat * slat - clat * clat)};
168
+
169
+ for(int k(0), l(0), m(0), n(-1); k < ((model.dof * (model.dof + 3)) / 2); k++, m++){
170
+ if(m > n){
171
+ m = -1;
172
+ n++;
173
+ static const FloatT earths_radius(6371.2E3);
174
+ rr = pow(earths_radius / radius_meter, n + 3);
175
+ }
176
+ FloatT fm(m + 1), fn(n + 1);
177
+ if (k > 3){
178
+ if (m == n){
179
+ aa = sqrt(1.0 - 0.5 / fm);
180
+ int j(k - n - 2);
181
+ p[k] = (1.0 + 1.0 / fm) * aa * clat * p[j];
182
+ q[k] = aa * (clat * q[j] + slat/fm * p[j]);
183
+ sl[m] = sl[m-1] * cl[0] + cl[m-1] * sl[0];
184
+ cl[m] = cl[m-1] * cl[0] - sl[m-1] * sl[0];
185
+ }else{
186
+ aa = sqrt(fn * fn - fm * fm);
187
+ bb = sqrt(((fn - 1.0) * (fn - 1.0)) - (fm * fm)) / aa;
188
+ cc = (2.0 * fn - 1.0) / aa;
189
+ int i(k - n - 1), j(k - 2 * n - 1);
190
+ p[k] = (fn + 1.0) * (cc * slat / fn * p[i] - bb / (fn - 1.0) * p[j]);
191
+ q[k] = cc * (slat * q[i] - clat / fn * p[i]) - bb * q[j];
192
+ }
193
+ }
194
+ aa = rr * model.coef[l];
195
+
196
+ if(m < 0){
197
+ res.north += aa * q[k];
198
+ res.down -= aa * p[k];
199
+ l++;
200
+ }else{
201
+ bb = rr * model.coef[l + 1];
202
+ cc = aa * cl[m] + bb * sl[m];
203
+ res.north += cc * q[k];
204
+ res.down -= cc * p[k];
205
+ if (clat > 0){
206
+ res.east += (aa * sl[m] - bb * cl[m]) * fm * p[k]/((fn + 1.0) * clat);
207
+ }else{
208
+ res.east += (aa * sl[m] - bb * cl[m]) * q[k] * slat;
209
+ }
210
+ l += 2;
211
+ }
212
+ }
213
+
214
+ return res;
215
+ }
216
+
217
+ public:
218
+ static field_components_res_t field_components_geocentric(
219
+ const model_t &model,
220
+ const FloatT &geocentric_latitude,
221
+ const FloatT &longitude_rad,
222
+ const FloatT &radius_meter = 6371.2E3){
223
+
224
+ return field_components_geocentric(model,
225
+ std::sin(geocentric_latitude), std::cos(geocentric_latitude),
226
+ longitude_rad,
227
+ radius_meter);
228
+ }
229
+
230
+ static field_components_res_t field_components(
231
+ const model_t &model,
232
+ const FloatT &latitude_rad, const FloatT &longitude_rad,
233
+ const FloatT &height_meter){
234
+ using std::cos;
235
+ using std::sin;
236
+ using std::pow;
237
+ using std::sqrt;
238
+
239
+ FloatT slat(sin(latitude_rad)), clat(cos(latitude_rad));
240
+ FloatT sd, cd, r;
241
+
242
+ {
243
+ // Correction of latitude
244
+ FloatT latitude_deg(latitude_rad / M_PI * 180);
245
+ if((90.0 - latitude_deg) < 1E-3){
246
+ clat = cos((90.0 - 1E-3) / 180 * M_PI); // 300 ft. from North pole
247
+ }else if((90.0 + latitude_deg) < 1E-3){
248
+ clat = cos((-90.0 + 1E-3) / 180 * M_PI); // 300 ft. from South pole
249
+ }
250
+ }
251
+
252
+ {
253
+ // Convert geographic lat/lng(�n���ܓx�o�x) to geocentric lat/lng(�n�S�ܓx�o�x)
254
+ FloatT aa, bb, cc, dd;
255
+ static const FloatT a2(40680631.59E6); /* WGS84, a*a (m^2) */
256
+ static const FloatT b2(40408299.98E6); /* WGS84, b*b (m^2) */
257
+ aa = a2 * clat * clat;
258
+ bb = b2 * slat * slat;
259
+ cc = aa + bb;
260
+ dd = sqrt(cc);
261
+ r = sqrt(height_meter * (height_meter + 2.0 * dd) + (a2 * aa + b2 * bb) / cc);
262
+ cd = (height_meter + dd) / r;
263
+ sd = (a2 - b2) / dd * slat * clat / r;
264
+ }
265
+
266
+ field_components_res_t res(field_components_geocentric(
267
+ model,
268
+ slat * cd - clat * sd, clat * cd + slat * sd,
269
+ longitude_rad, r));
270
+
271
+ { // coordinate transform
272
+ FloatT _north(res.north);
273
+ res.north = _north * cd + res.down * sd;
274
+ res.down = res.down * cd - _north * sd;
275
+ }
276
+
277
+ return res;
278
+ }
279
+
280
+ struct latlng_t {
281
+ FloatT latitude, longitude;
282
+ };
283
+ /**
284
+ * Calculate geomagnetic latitude and longitude
285
+ *
286
+ * @see "Magnetic Coordinate Systems" DOI 10.1007/s11214-016-0275-y
287
+ */
288
+ static latlng_t geomagnetic_latlng(
289
+ const model_t &model,
290
+ const FloatT &geocentric_latitude, const FloatT &longitude){
291
+ const FloatT &g10(model.coef[0]), &g11(model.coef[1]), &h11(model.coef[2]);
292
+ FloatT m[] = {g11, h11, g10}; // Eq.(11)
293
+ FloatT b0(-std::sqrt(std::pow(m[0], 2) + std::pow(m[1], 2) + std::pow(m[2], 2))); // Eq.(12)
294
+ FloatT z_cd[] = {m[0] / b0, m[1] / b0, m[2] / b0}; // Eq.(16)
295
+ FloatT y_cd_denom(-std::sqrt((h11 * h11) + (g11 * g11)));
296
+ FloatT y_cd[] = {-h11 / y_cd_denom, g11 / y_cd_denom, 0}; /* = [0,0,1] * z_cd */
297
+ FloatT x_cd[] = { /* y_cd * z_cd */
298
+ y_cd[1] * z_cd[2] - y_cd[2] * z_cd[1],
299
+ y_cd[2] * z_cd[0] - y_cd[0] * z_cd[2],
300
+ y_cd[0] * z_cd[1] - y_cd[1] * z_cd[0],
301
+ };
302
+ FloatT
303
+ clat(std::cos(geocentric_latitude)), slat(std::sin(geocentric_latitude)),
304
+ clng(std::cos(longitude)), slng(std::sin(longitude));
305
+ FloatT vec_geoc[] = {clat * clng, clat * slng, slat}; // Eq.(13) Theta_N = (pi - lat)
306
+ FloatT vec_geom[] = {
307
+ x_cd[0] * vec_geoc[0] + x_cd[1] * vec_geoc[1] + x_cd[2] * vec_geoc[2],
308
+ y_cd[0] * vec_geoc[0] + y_cd[1] * vec_geoc[1] + y_cd[2] * vec_geoc[2],
309
+ z_cd[0] * vec_geoc[0] + z_cd[1] * vec_geoc[1] + z_cd[2] * vec_geoc[2],
310
+ };
311
+ latlng_t res = {
312
+ std::asin(vec_geom[2]),
313
+ std::atan2(vec_geom[1], vec_geom[0])
314
+ };
315
+ return res;
316
+ }
317
+ };
318
+
319
+ typedef MagneticFieldGeneric<double> MagneticField;
320
+
321
+ template <class FloatT, template <class> class Binder>
322
+ struct MagneticFieldGeneric2 : public MagneticFieldGeneric<FloatT> {
323
+ static typename MagneticFieldGeneric<FloatT>::model_t get_model(
324
+ const FloatT &year, const int &dof = 0){
325
+ return MagneticFieldGeneric<FloatT>::make_model(
326
+ year,
327
+ Binder<FloatT>::models,
328
+ #if defined(__GNUC__)
329
+ sizeof(Binder<FloatT>::models) / sizeof(Binder<FloatT>::models[0]),
330
+ #else
331
+ Binder<FloatT>::models_num,
332
+ #endif
333
+ dof);
334
+ }
335
+ static typename MagneticFieldGeneric<FloatT>::latlng_t geomagnetic_latlng(
336
+ const FloatT &year,
337
+ const FloatT &geocentric_latitude, const FloatT &longitude){
338
+ return MagneticFieldGeneric<FloatT>::geomagnetic_latlng(
339
+ get_model(year, 1),
340
+ geocentric_latitude, longitude);
341
+ }
342
+ };
343
+
344
+ /* IGRF11 is the eleventh generation standard main field model adopted
345
+ * by the International Association of Geomagnetism and Aeronomy (IAGA).
346
+ * This is a degree and order 10 model from 1900 to 1995 and a degree and
347
+ * order 13 model from 2000 to 2015, providing estimates of the main field
348
+ * for dates between January 1, 1900 and January 1, 2015. For more information
349
+ * on the IGRF and IAGA, visit the IAGA Working Group V-MOD Web site at:
350
+ * http://www.ngdc.noaa.gov/IAGA/vmod/
351
+ */
352
+
353
+ template <class FloatT>
354
+ struct IGRF11Preset {
355
+ static const typename MagneticFieldGeneric<FloatT>::model_t DGRF2000;
356
+ static const typename MagneticFieldGeneric<FloatT>::model_t DGRF2005;
357
+ static const typename MagneticFieldGeneric<FloatT>::model_t DGRF45;
358
+ static const typename MagneticFieldGeneric<FloatT>::model_t DGRF50;
359
+ static const typename MagneticFieldGeneric<FloatT>::model_t DGRF55;
360
+ static const typename MagneticFieldGeneric<FloatT>::model_t DGRF60;
361
+ static const typename MagneticFieldGeneric<FloatT>::model_t DGRF65;
362
+ static const typename MagneticFieldGeneric<FloatT>::model_t DGRF70;
363
+ static const typename MagneticFieldGeneric<FloatT>::model_t DGRF75;
364
+ static const typename MagneticFieldGeneric<FloatT>::model_t DGRF80;
365
+ static const typename MagneticFieldGeneric<FloatT>::model_t DGRF85;
366
+ static const typename MagneticFieldGeneric<FloatT>::model_t DGRF90;
367
+ static const typename MagneticFieldGeneric<FloatT>::model_t DGRF95;
368
+ static const typename MagneticFieldGeneric<FloatT>::model_t IGRF00;
369
+ static const typename MagneticFieldGeneric<FloatT>::model_t IGRF05;
370
+ static const typename MagneticFieldGeneric<FloatT>::model_t IGRF10;
371
+ static const typename MagneticFieldGeneric<FloatT>::model_t IGRF15;
372
+ static const typename MagneticFieldGeneric<FloatT>::model_t IGRF20;
373
+ static const typename MagneticFieldGeneric<FloatT>::model_t IGRF2010;
374
+ static const typename MagneticFieldGeneric<FloatT>::model_t IGRF25;
375
+ static const typename MagneticFieldGeneric<FloatT>::model_t IGRF30;
376
+ static const typename MagneticFieldGeneric<FloatT>::model_t IGRF35;
377
+ static const typename MagneticFieldGeneric<FloatT>::model_t IGRF40;
378
+ };
379
+
380
+ template <class FloatT>
381
+ struct IGRF11Generic : public MagneticFieldGeneric2<FloatT, IGRF11Generic>, public IGRF11Preset<FloatT> {
382
+ typedef IGRF11Preset<FloatT> preset_t;
383
+ static const typename MagneticFieldGeneric<FloatT>::model_t *models[];
384
+ static const int models_num;
385
+ };
386
+
387
+ typedef IGRF11Generic<double> IGRF11;
388
+
389
+ template <class FloatT>
390
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::DGRF2000 = {
391
+ "DGRF2000",
392
+ 2000.0,
393
+ 13,
394
+ {-29619.4, -1728.2, 5186.1, // 1
395
+ -2267.7, 3068.4, -2481.6, 1670.9, -458.0, // 2
396
+ 1339.6, -2288.0, -227.6, 1252.1, 293.4, 714.5, -491.1, // 3
397
+ 932.3, 786.8, 272.6, 250.0, -231.9, -403.0, 119.8, 111.3, -303.8, // 4
398
+ -218.8, 351.4, 43.8, 222.3, 171.9, -130.4, -133.1, -168.6, -39.3, -12.9, 106.3, // 5
399
+ 72.3, 68.2, -17.4, 74.2, 63.7, -160.9, 65.1, -5.9, -61.2, 16.9, 0.7, -90.4, 43.8, // 6
400
+ 79.0, -74.0, -64.6, 0.0, -24.2, 33.3, 6.2, 9.1, 24.0, 6.9, 14.8, 7.3, -25.4, -1.2, -5.8, // 7
401
+ 24.4, 6.6, 11.9, -9.2, -21.5, -7.9, 8.5, -16.6, -21.5, 9.1, 15.5, 7.0, 8.9, -7.9, -14.9, -7.0, -2.1, // 8
402
+ 5.0, 9.4, -19.7, 3.0, 13.4, -8.4, 12.5, 6.3, -6.2, -8.9, -8.4, -1.5, 8.4, 9.3, 3.8, -4.3, -8.2, -8.2, 4.8, // 9
403
+ -2.6, -6.0, 1.7, 1.7, 0.0, -3.1, 4.0, -0.5, 4.9, 3.7, -5.9, 1.0, -1.2, 2.0, -2.9, 4.2, 0.2, 0.3, -2.2, -1.1, -7.4, // 10
404
+ 2.7, -1.7, 0.1, -1.9, 1.3, 1.5, -0.9, -0.1, -2.6, 0.1, 0.9, -0.7, -0.7, 0.7, -2.8, 1.7, -0.9, 0.1, -1.2, 1.2, -1.9, 4.0, -0.9, // 11
405
+ -2.2, -0.3, -0.4, 0.2, 0.3, 0.9, 2.5, -0.2, -2.6, 0.9, 0.7, -0.5, 0.3, 0.3, 0.0, -0.3, 0.0, -0.4, 0.3, -0.1, -0.9, -0.2, -0.4, -0.4, 0.8, // 12
406
+ -0.2, -0.9, -0.9, 0.3, 0.2, 0.1, 1.8, -0.4, -0.4, 1.3, -1.0, -0.4, -0.1, 0.7, 0.7, -0.4, 0.3, 0.3, 0.6, -0.1, 0.3, 0.4, -0.2, 0.0, -0.5, 0.1, -0.9, } // 13
407
+ };
408
+ template <class FloatT>
409
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::DGRF2005 = {
410
+ "DGRF2005",
411
+ 2005.0,
412
+ 13,
413
+ {-29554.63, -1669.05, 5077.99, // 1
414
+ -2337.24, 3047.69, -2594.5, 1657.76, -515.43, // 2
415
+ 1336.3, -2305.83, -198.86, 1246.39, 269.72, 672.51, -524.72, // 3
416
+ 920.55, 797.96, 282.07, 210.65, -225.23, -379.86, 145.15, 100.0, -305.36, // 4
417
+ -227.0, 354.41, 42.72, 208.95, 180.25, -136.54, -123.45, -168.05, -19.57, -13.55, 103.85, // 5
418
+ 73.6, 69.56, -20.33, 76.74, 54.75, -151.34, 63.63, -14.58, -63.53, 14.58, 0.24, -86.36, 50.94, // 6
419
+ 79.88, -74.46, -61.14, -1.65, -22.57, 38.73, 6.82, 12.3, 25.35, 9.37, 10.93, 5.42, -26.32, 1.94, -4.64, // 7
420
+ 24.8, 7.62, 11.2, -11.73, -20.88, -6.88, 9.83, -18.11, -19.71, 10.17, 16.22, 9.36, 7.61, -11.25, -12.76, -4.87, -0.06, // 8
421
+ 5.58, 9.76, -20.11, 3.58, 12.69, -6.94, 12.67, 5.01, -6.72, -10.76, -8.16, -1.25, 8.1, 8.76, 2.92, -6.66, -7.73, -9.22, 6.01, // 9
422
+ -2.17, -6.12, 2.19, 1.42, 0.1, -2.35, 4.46, -0.15, 4.76, 3.06, -6.58, 0.29, -1.01, 2.06, -3.47, 3.77, -0.86, -0.21, -2.31, -2.09, -7.93, // 10
423
+ 2.95, -1.6, 0.26, -1.88, 1.44, 1.44, -0.77, -0.31, -2.27, 0.29, 0.9, -0.79, -0.58, 0.53, -2.69, 1.8, -1.08, 0.16, -1.58, 0.96, -1.9, 3.99, -1.39, // 11
424
+ -2.15, -0.29, -0.55, 0.21, 0.23, 0.89, 2.38, -0.38, -2.63, 0.96, 0.61, -0.3, 0.4, 0.46, 0.01, -0.35, 0.02, -0.36, 0.28, 0.08, -0.87, -0.49, -0.34, -0.08, 0.88, // 12
425
+ -0.16, -0.88, -0.76, 0.3, 0.33, 0.28, 1.72, -0.43, -0.54, 1.18, -1.07, -0.37, -0.04, 0.75, 0.63, -0.26, 0.21, 0.35, 0.53, -0.05, 0.38, 0.41, -0.22, -0.1, -0.57, -0.18, -0.82, } // 13
426
+ };
427
+ template <class FloatT>
428
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::DGRF45 = {
429
+ "DGRF45",
430
+ 1945.0,
431
+ 10,
432
+ {-30594.0, -2285.0, 5810.0, // 1
433
+ -1244.0, 2990.0, -1702.0, 1578.0, 477.0, // 2
434
+ 1282.0, -1834.0, -499.0, 1255.0, 186.0, 913.0, -11.0, // 3
435
+ 944.0, 776.0, 144.0, 544.0, -276.0, -421.0, -55.0, 304.0, -178.0, // 4
436
+ -253.0, 346.0, -12.0, 194.0, 95.0, -20.0, -67.0, -142.0, -119.0, -82.0, 82.0, // 5
437
+ 59.0, 57.0, 6.0, 6.0, 100.0, -246.0, 16.0, -25.0, -9.0, 21.0, -16.0, -104.0, -39.0, // 6
438
+ 70.0, -40.0, -45.0, 0.0, -18.0, 0.0, 2.0, -29.0, 6.0, -10.0, 28.0, 15.0, -17.0, 29.0, -22.0, // 7
439
+ 13.0, 7.0, 12.0, -8.0, -21.0, -5.0, -12.0, 9.0, -7.0, 7.0, 2.0, -10.0, 18.0, 7.0, 3.0, 2.0, -11.0, // 8
440
+ 5.0, -21.0, -27.0, 1.0, 17.0, -11.0, 29.0, 3.0, -9.0, 16.0, 4.0, -3.0, 9.0, -4.0, 6.0, -3.0, 1.0, -4.0, 8.0, // 9
441
+ -3.0, 11.0, 5.0, 1.0, 1.0, 2.0, -20.0, -5.0, -1.0, -1.0, -6.0, 8.0, 6.0, -1.0, -4.0, -3.0, -2.0, 5.0, 0.0, -2.0, -2.0, } // 10
442
+ };
443
+ template <class FloatT>
444
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::DGRF50 = {
445
+ "DGRF50",
446
+ 1950.0,
447
+ 10,
448
+ {-30554.0, -2250.0, 5815.0, // 1
449
+ -1341.0, 2998.0, -1810.0, 1576.0, 381.0, // 2
450
+ 1297.0, -1889.0, -476.0, 1274.0, 206.0, 896.0, -46.0, // 3
451
+ 954.0, 792.0, 136.0, 528.0, -278.0, -408.0, -37.0, 303.0, -210.0, // 4
452
+ -240.0, 349.0, 3.0, 211.0, 103.0, -20.0, -87.0, -147.0, -122.0, -76.0, 80.0, // 5
453
+ 54.0, 57.0, -1.0, 4.0, 99.0, -247.0, 33.0, -16.0, -12.0, 12.0, -12.0, -105.0, -30.0, // 6
454
+ 65.0, -55.0, -35.0, 2.0, -17.0, 1.0, 0.0, -40.0, 10.0, -7.0, 36.0, 5.0, -18.0, 19.0, -16.0, // 7
455
+ 22.0, 15.0, 5.0, -4.0, -22.0, -1.0, 0.0, 11.0, -21.0, 15.0, -8.0, -13.0, 17.0, 5.0, -4.0, -1.0, -17.0, // 8
456
+ 3.0, -7.0, -24.0, -1.0, 19.0, -25.0, 12.0, 10.0, 2.0, 5.0, 2.0, -5.0, 8.0, -2.0, 8.0, 3.0, -11.0, 8.0, -7.0, // 9
457
+ -8.0, 4.0, 13.0, -1.0, -2.0, 13.0, -10.0, -4.0, 2.0, 4.0, -3.0, 12.0, 6.0, 3.0, -3.0, 2.0, 6.0, 10.0, 11.0, 3.0, 8.0, } // 10
458
+ };
459
+ template <class FloatT>
460
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::DGRF55 = {
461
+ "DGRF55",
462
+ 1955.0,
463
+ 10,
464
+ {-30500.0, -2215.0, 5820.0, // 1
465
+ -1440.0, 3003.0, -1898.0, 1581.0, 291.0, // 2
466
+ 1302.0, -1944.0, -462.0, 1288.0, 216.0, 882.0, -83.0, // 3
467
+ 958.0, 796.0, 133.0, 510.0, -274.0, -397.0, -23.0, 290.0, -230.0, // 4
468
+ -229.0, 360.0, 15.0, 230.0, 110.0, -23.0, -98.0, -152.0, -121.0, -69.0, 78.0, // 5
469
+ 47.0, 57.0, -9.0, 3.0, 96.0, -247.0, 48.0, -8.0, -16.0, 7.0, -12.0, -107.0, -24.0, // 6
470
+ 65.0, -56.0, -50.0, 2.0, -24.0, 10.0, -4.0, -32.0, 8.0, -11.0, 28.0, 9.0, -20.0, 18.0, -18.0, // 7
471
+ 11.0, 9.0, 10.0, -6.0, -15.0, -14.0, 5.0, 6.0, -23.0, 10.0, 3.0, -7.0, 23.0, 6.0, -4.0, 9.0, -13.0, // 8
472
+ 4.0, 9.0, -11.0, -4.0, 12.0, -5.0, 7.0, 2.0, 6.0, 4.0, -2.0, 1.0, 10.0, 2.0, 7.0, 2.0, -6.0, 5.0, 5.0, // 9
473
+ -3.0, -5.0, -4.0, -1.0, 0.0, 2.0, -8.0, -3.0, -2.0, 7.0, -4.0, 4.0, 1.0, -2.0, -3.0, 6.0, 7.0, -2.0, -1.0, 0.0, -3.0, } // 10
474
+ };
475
+ template <class FloatT>
476
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::DGRF60 = {
477
+ "DGRF60",
478
+ 1960.0,
479
+ 10,
480
+ {-30421.0, -2169.0, 5791.0, // 1
481
+ -1555.0, 3002.0, -1967.0, 1590.0, 206.0, // 2
482
+ 1302.0, -1992.0, -414.0, 1289.0, 224.0, 878.0, -130.0, // 3
483
+ 957.0, 800.0, 135.0, 504.0, -278.0, -394.0, 3.0, 269.0, -255.0, // 4
484
+ -222.0, 362.0, 16.0, 242.0, 125.0, -26.0, -117.0, -156.0, -114.0, -63.0, 81.0, // 5
485
+ 46.0, 58.0, -10.0, 1.0, 99.0, -237.0, 60.0, -1.0, -20.0, -2.0, -11.0, -113.0, -17.0, // 6
486
+ 67.0, -56.0, -55.0, 5.0, -28.0, 15.0, -6.0, -32.0, 7.0, -7.0, 23.0, 17.0, -18.0, 8.0, -17.0, // 7
487
+ 15.0, 6.0, 11.0, -4.0, -14.0, -11.0, 7.0, 2.0, -18.0, 10.0, 4.0, -5.0, 23.0, 10.0, 1.0, 8.0, -20.0, // 8
488
+ 4.0, 6.0, -18.0, 0.0, 12.0, -9.0, 2.0, 1.0, 0.0, 4.0, -3.0, -1.0, 9.0, -2.0, 8.0, 3.0, 0.0, -1.0, 5.0, // 9
489
+ 1.0, -3.0, 4.0, 4.0, 1.0, 0.0, 0.0, -1.0, 2.0, 4.0, -5.0, 6.0, 1.0, 1.0, -1.0, -1.0, 6.0, 2.0, 0.0, 0.0, -7.0, } // 10
490
+ };
491
+ template <class FloatT>
492
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::DGRF65 = {
493
+ "DGRF65",
494
+ 1965.0,
495
+ 10,
496
+ {-30334.0, -2119.0, 5776.0, // 1
497
+ -1662.0, 2997.0, -2016.0, 1594.0, 114.0, // 2
498
+ 1297.0, -2038.0, -404.0, 1292.0, 240.0, 856.0, -165.0, // 3
499
+ 957.0, 804.0, 148.0, 479.0, -269.0, -390.0, 13.0, 252.0, -269.0, // 4
500
+ -219.0, 358.0, 19.0, 254.0, 128.0, -31.0, -126.0, -157.0, -97.0, -62.0, 81.0, // 5
501
+ 45.0, 61.0, -11.0, 8.0, 100.0, -228.0, 68.0, 4.0, -32.0, 1.0, -8.0, -111.0, -7.0, // 6
502
+ 75.0, -57.0, -61.0, 4.0, -27.0, 13.0, -2.0, -26.0, 6.0, -6.0, 26.0, 13.0, -23.0, 1.0, -12.0, // 7
503
+ 13.0, 5.0, 7.0, -4.0, -12.0, -14.0, 9.0, 0.0, -16.0, 8.0, 4.0, -1.0, 24.0, 11.0, -3.0, 4.0, -17.0, // 8
504
+ 8.0, 10.0, -22.0, 2.0, 15.0, -13.0, 7.0, 10.0, -4.0, -1.0, -5.0, -1.0, 10.0, 5.0, 10.0, 1.0, -4.0, -2.0, 1.0, // 9
505
+ -2.0, -3.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 4.0, -4.0, 4.0, 0.0, 0.0, -2.0, 2.0, 3.0, 2.0, 0.0, 0.0, -6.0, } // 10
506
+ };
507
+ template <class FloatT>
508
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::DGRF70 = {
509
+ "DGRF70",
510
+ 1970.0,
511
+ 10,
512
+ {-30220.0, -2068.0, 5737.0, // 1
513
+ -1781.0, 3000.0, -2047.0, 1611.0, 25.0, // 2
514
+ 1287.0, -2091.0, -366.0, 1278.0, 251.0, 838.0, -196.0, // 3
515
+ 952.0, 800.0, 167.0, 461.0, -266.0, -395.0, 26.0, 234.0, -279.0, // 4
516
+ -216.0, 359.0, 26.0, 262.0, 139.0, -42.0, -139.0, -160.0, -91.0, -56.0, 83.0, // 5
517
+ 43.0, 64.0, -12.0, 15.0, 100.0, -212.0, 72.0, 2.0, -37.0, 3.0, -6.0, -112.0, 1.0, // 6
518
+ 72.0, -57.0, -70.0, 1.0, -27.0, 14.0, -4.0, -22.0, 8.0, -2.0, 23.0, 13.0, -23.0, -2.0, -11.0, // 7
519
+ 14.0, 6.0, 7.0, -2.0, -15.0, -13.0, 6.0, -3.0, -17.0, 5.0, 6.0, 0.0, 21.0, 11.0, -6.0, 3.0, -16.0, // 8
520
+ 8.0, 10.0, -21.0, 2.0, 16.0, -12.0, 6.0, 10.0, -4.0, -1.0, -5.0, 0.0, 10.0, 3.0, 11.0, 1.0, -2.0, -1.0, 1.0, // 9
521
+ -3.0, -3.0, 1.0, 2.0, 1.0, -5.0, 3.0, -1.0, 4.0, 6.0, -4.0, 4.0, 0.0, 1.0, -1.0, 0.0, 3.0, 3.0, 1.0, -1.0, -4.0, } // 10
522
+ };
523
+ template <class FloatT>
524
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::DGRF75 = {
525
+ "DGRF75",
526
+ 1975.0,
527
+ 10,
528
+ {-30100.0, -2013.0, 5675.0, // 1
529
+ -1902.0, 3010.0, -2067.0, 1632.0, -68.0, // 2
530
+ 1276.0, -2144.0, -333.0, 1260.0, 262.0, 830.0, -223.0, // 3
531
+ 946.0, 791.0, 191.0, 438.0, -265.0, -405.0, 39.0, 216.0, -288.0, // 4
532
+ -218.0, 356.0, 31.0, 264.0, 148.0, -59.0, -152.0, -159.0, -83.0, -49.0, 88.0, // 5
533
+ 45.0, 66.0, -13.0, 28.0, 99.0, -198.0, 75.0, 1.0, -41.0, 6.0, -4.0, -111.0, 11.0, // 6
534
+ 71.0, -56.0, -77.0, 1.0, -26.0, 16.0, -5.0, -14.0, 10.0, 0.0, 22.0, 12.0, -23.0, -5.0, -12.0, // 7
535
+ 14.0, 6.0, 6.0, -1.0, -16.0, -12.0, 4.0, -8.0, -19.0, 4.0, 6.0, 0.0, 18.0, 10.0, -10.0, 1.0, -17.0, // 8
536
+ 7.0, 10.0, -21.0, 2.0, 16.0, -12.0, 7.0, 10.0, -4.0, -1.0, -5.0, -1.0, 10.0, 4.0, 11.0, 1.0, -3.0, -2.0, 1.0, // 9
537
+ -3.0, -3.0, 1.0, 2.0, 1.0, -5.0, 3.0, -2.0, 4.0, 5.0, -4.0, 4.0, -1.0, 1.0, -1.0, 0.0, 3.0, 3.0, 1.0, -1.0, -5.0, } // 10
538
+ };
539
+ template <class FloatT>
540
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::DGRF80 = {
541
+ "DGRF80",
542
+ 1980.0,
543
+ 10,
544
+ {-29992.0, -1956.0, 5604.0, // 1
545
+ -1997.0, 3027.0, -2129.0, 1663.0, -200.0, // 2
546
+ 1281.0, -2180.0, -336.0, 1251.0, 271.0, 833.0, -252.0, // 3
547
+ 938.0, 782.0, 212.0, 398.0, -257.0, -419.0, 53.0, 199.0, -297.0, // 4
548
+ -218.0, 357.0, 46.0, 261.0, 150.0, -74.0, -151.0, -162.0, -78.0, -48.0, 92.0, // 5
549
+ 48.0, 66.0, -15.0, 42.0, 93.0, -192.0, 71.0, 4.0, -43.0, 14.0, -2.0, -108.0, 17.0, // 6
550
+ 72.0, -59.0, -82.0, 2.0, -27.0, 21.0, -5.0, -12.0, 16.0, 1.0, 18.0, 11.0, -23.0, -2.0, -10.0, // 7
551
+ 18.0, 6.0, 7.0, 0.0, -18.0, -11.0, 4.0, -7.0, -22.0, 4.0, 9.0, 3.0, 16.0, 6.0, -13.0, -1.0, -15.0, // 8
552
+ 5.0, 10.0, -21.0, 1.0, 16.0, -12.0, 9.0, 9.0, -5.0, -3.0, -6.0, -1.0, 9.0, 7.0, 10.0, 2.0, -6.0, -5.0, 2.0, // 9
553
+ -4.0, -4.0, 1.0, 2.0, 0.0, -5.0, 3.0, -2.0, 6.0, 5.0, -4.0, 3.0, 0.0, 1.0, -1.0, 2.0, 4.0, 3.0, 0.0, 0.0, -6.0, } // 10
554
+ };
555
+ template <class FloatT>
556
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::DGRF85 = {
557
+ "DGRF85",
558
+ 1985.0,
559
+ 10,
560
+ {-29873.0, -1905.0, 5500.0, // 1
561
+ -2072.0, 3044.0, -2197.0, 1687.0, -306.0, // 2
562
+ 1296.0, -2208.0, -310.0, 1247.0, 284.0, 829.0, -297.0, // 3
563
+ 936.0, 780.0, 232.0, 361.0, -249.0, -424.0, 69.0, 170.0, -297.0, // 4
564
+ -214.0, 355.0, 47.0, 253.0, 150.0, -93.0, -154.0, -164.0, -75.0, -46.0, 95.0, // 5
565
+ 53.0, 65.0, -16.0, 51.0, 88.0, -185.0, 69.0, 4.0, -48.0, 16.0, -1.0, -102.0, 21.0, // 6
566
+ 74.0, -62.0, -83.0, 3.0, -27.0, 24.0, -2.0, -6.0, 20.0, 4.0, 17.0, 10.0, -23.0, 0.0, -7.0, // 7
567
+ 21.0, 6.0, 8.0, 0.0, -19.0, -11.0, 5.0, -9.0, -23.0, 4.0, 11.0, 4.0, 14.0, 4.0, -15.0, -4.0, -11.0, // 8
568
+ 5.0, 10.0, -21.0, 1.0, 15.0, -12.0, 9.0, 9.0, -6.0, -3.0, -6.0, -1.0, 9.0, 7.0, 9.0, 1.0, -7.0, -5.0, 2.0, // 9
569
+ -4.0, -4.0, 1.0, 3.0, 0.0, -5.0, 3.0, -2.0, 6.0, 5.0, -4.0, 3.0, 0.0, 1.0, -1.0, 2.0, 4.0, 3.0, 0.0, 0.0, -6.0, } // 10
570
+ };
571
+ template <class FloatT>
572
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::DGRF90 = {
573
+ "DGRF90",
574
+ 1990.0,
575
+ 10,
576
+ {-29775.0, -1848.0, 5406.0, // 1
577
+ -2131.0, 3059.0, -2279.0, 1686.0, -373.0, // 2
578
+ 1314.0, -2239.0, -284.0, 1248.0, 293.0, 802.0, -352.0, // 3
579
+ 939.0, 780.0, 247.0, 325.0, -240.0, -423.0, 84.0, 141.0, -299.0, // 4
580
+ -214.0, 353.0, 46.0, 245.0, 154.0, -109.0, -153.0, -165.0, -69.0, -36.0, 97.0, // 5
581
+ 61.0, 65.0, -16.0, 59.0, 82.0, -178.0, 69.0, 3.0, -52.0, 18.0, 1.0, -96.0, 24.0, // 6
582
+ 77.0, -64.0, -80.0, 2.0, -26.0, 26.0, 0.0, -1.0, 21.0, 5.0, 17.0, 9.0, -23.0, 0.0, -4.0, // 7
583
+ 23.0, 5.0, 10.0, -1.0, -19.0, -10.0, 6.0, -12.0, -22.0, 3.0, 12.0, 4.0, 12.0, 2.0, -16.0, -6.0, -10.0, // 8
584
+ 4.0, 9.0, -20.0, 1.0, 15.0, -12.0, 11.0, 9.0, -7.0, -4.0, -7.0, -2.0, 9.0, 7.0, 8.0, 1.0, -7.0, -6.0, 2.0, // 9
585
+ -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 3.0, -2.0, 6.0, 4.0, -4.0, 3.0, 0.0, 1.0, -2.0, 3.0, 3.0, 3.0, -1.0, 0.0, -6.0, } // 10
586
+ };
587
+ template <class FloatT>
588
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::DGRF95 = {
589
+ "DGRF95",
590
+ 1995.0,
591
+ 10,
592
+ {-29692.0, -1784.0, 5306.0, // 1
593
+ -2200.0, 3070.0, -2366.0, 1681.0, -413.0, // 2
594
+ 1335.0, -2267.0, -262.0, 1249.0, 302.0, 759.0, -427.0, // 3
595
+ 940.0, 780.0, 262.0, 290.0, -236.0, -418.0, 97.0, 122.0, -306.0, // 4
596
+ -214.0, 352.0, 46.0, 235.0, 165.0, -118.0, -143.0, -166.0, -55.0, -17.0, 107.0, // 5
597
+ 68.0, 67.0, -17.0, 68.0, 72.0, -170.0, 67.0, -1.0, -58.0, 19.0, 1.0, -93.0, 36.0, // 6
598
+ 77.0, -72.0, -69.0, 1.0, -25.0, 28.0, 4.0, 5.0, 24.0, 4.0, 17.0, 8.0, -24.0, -2.0, -6.0, // 7
599
+ 25.0, 6.0, 11.0, -6.0, -21.0, -9.0, 8.0, -14.0, -23.0, 9.0, 15.0, 6.0, 11.0, -5.0, -16.0, -7.0, -4.0, // 8
600
+ 4.0, 9.0, -20.0, 3.0, 15.0, -10.0, 12.0, 8.0, -6.0, -8.0, -8.0, -1.0, 8.0, 10.0, 5.0, -2.0, -8.0, -8.0, 3.0, // 9
601
+ -3.0, -6.0, 1.0, 2.0, 0.0, -4.0, 4.0, -1.0, 5.0, 4.0, -5.0, 2.0, -1.0, 2.0, -2.0, 5.0, 1.0, 1.0, -2.0, 0.0, -7.0, } // 10
602
+ };
603
+ template <class FloatT>
604
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::IGRF00 = {
605
+ "IGRF00",
606
+ 1900.0,
607
+ 10,
608
+ {-31543.0, -2298.0, 5922.0, // 1
609
+ -677.0, 2905.0, -1061.0, 924.0, 1121.0, // 2
610
+ 1022.0, -1469.0, -330.0, 1256.0, 3.0, 572.0, 523.0, // 3
611
+ 876.0, 628.0, 195.0, 660.0, -69.0, -361.0, -210.0, 134.0, -75.0, // 4
612
+ -184.0, 328.0, -210.0, 264.0, 53.0, 5.0, -33.0, -86.0, -124.0, -16.0, 3.0, // 5
613
+ 63.0, 61.0, -9.0, -11.0, 83.0, -217.0, 2.0, -58.0, -35.0, 59.0, 36.0, -90.0, -69.0, // 6
614
+ 70.0, -55.0, -45.0, 0.0, -13.0, 34.0, -10.0, -41.0, -1.0, -21.0, 28.0, 18.0, -12.0, 6.0, -22.0, // 7
615
+ 11.0, 8.0, 8.0, -4.0, -14.0, -9.0, 7.0, 1.0, -13.0, 2.0, 5.0, -9.0, 16.0, 5.0, -5.0, 8.0, -18.0, // 8
616
+ 8.0, 10.0, -20.0, 1.0, 14.0, -11.0, 5.0, 12.0, -3.0, 1.0, -2.0, -2.0, 8.0, 2.0, 10.0, -1.0, -2.0, -1.0, 2.0, // 9
617
+ -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 6.0, -4.0, 4.0, 0.0, 0.0, -2.0, 2.0, 4.0, 2.0, 0.0, 0.0, -6.0, } // 10
618
+ };
619
+ template <class FloatT>
620
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::IGRF05 = {
621
+ "IGRF05",
622
+ 1905.0,
623
+ 10,
624
+ {-31464.0, -2298.0, 5909.0, // 1
625
+ -728.0, 2928.0, -1086.0, 1041.0, 1065.0, // 2
626
+ 1037.0, -1494.0, -357.0, 1239.0, 34.0, 635.0, 480.0, // 3
627
+ 880.0, 643.0, 203.0, 653.0, -77.0, -380.0, -201.0, 146.0, -65.0, // 4
628
+ -192.0, 328.0, -193.0, 259.0, 56.0, -1.0, -32.0, -93.0, -125.0, -26.0, 11.0, // 5
629
+ 62.0, 60.0, -7.0, -11.0, 86.0, -221.0, 4.0, -57.0, -32.0, 57.0, 32.0, -92.0, -67.0, // 6
630
+ 70.0, -54.0, -46.0, 0.0, -14.0, 33.0, -11.0, -41.0, 0.0, -20.0, 28.0, 18.0, -12.0, 6.0, -22.0, // 7
631
+ 11.0, 8.0, 8.0, -4.0, -15.0, -9.0, 7.0, 1.0, -13.0, 2.0, 5.0, -8.0, 16.0, 5.0, -5.0, 8.0, -18.0, // 8
632
+ 8.0, 10.0, -20.0, 1.0, 14.0, -11.0, 5.0, 12.0, -3.0, 1.0, -2.0, -2.0, 8.0, 2.0, 10.0, 0.0, -2.0, -1.0, 2.0, // 9
633
+ -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 6.0, -4.0, 4.0, 0.0, 0.0, -2.0, 2.0, 4.0, 2.0, 0.0, 0.0, -6.0, } // 10
634
+ };
635
+ template <class FloatT>
636
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::IGRF10 = {
637
+ "IGRF10",
638
+ 1910.0,
639
+ 10,
640
+ {-31354.0, -2297.0, 5898.0, // 1
641
+ -769.0, 2948.0, -1128.0, 1176.0, 1000.0, // 2
642
+ 1058.0, -1524.0, -389.0, 1223.0, 62.0, 705.0, 425.0, // 3
643
+ 884.0, 660.0, 211.0, 644.0, -90.0, -400.0, -189.0, 160.0, -55.0, // 4
644
+ -201.0, 327.0, -172.0, 253.0, 57.0, -9.0, -33.0, -102.0, -126.0, -38.0, 21.0, // 5
645
+ 62.0, 58.0, -5.0, -11.0, 89.0, -224.0, 5.0, -54.0, -29.0, 54.0, 28.0, -95.0, -65.0, // 6
646
+ 71.0, -54.0, -47.0, 1.0, -14.0, 32.0, -12.0, -40.0, 1.0, -19.0, 28.0, 18.0, -13.0, 6.0, -22.0, // 7
647
+ 11.0, 8.0, 8.0, -4.0, -15.0, -9.0, 6.0, 1.0, -13.0, 2.0, 5.0, -8.0, 16.0, 5.0, -5.0, 8.0, -18.0, // 8
648
+ 8.0, 10.0, -20.0, 1.0, 14.0, -11.0, 5.0, 12.0, -3.0, 1.0, -2.0, -2.0, 8.0, 2.0, 10.0, 0.0, -2.0, -1.0, 2.0, // 9
649
+ -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 6.0, -4.0, 4.0, 0.0, 0.0, -2.0, 2.0, 4.0, 2.0, 0.0, 0.0, -6.0, } // 10
650
+ };
651
+ template <class FloatT>
652
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::IGRF15 = {
653
+ "IGRF15",
654
+ 1915.0,
655
+ 10,
656
+ {-31212.0, -2306.0, 5875.0, // 1
657
+ -802.0, 2956.0, -1191.0, 1309.0, 917.0, // 2
658
+ 1084.0, -1559.0, -421.0, 1212.0, 84.0, 778.0, 360.0, // 3
659
+ 887.0, 678.0, 218.0, 631.0, -109.0, -416.0, -173.0, 178.0, -51.0, // 4
660
+ -211.0, 327.0, -148.0, 245.0, 58.0, -16.0, -34.0, -111.0, -126.0, -51.0, 32.0, // 5
661
+ 61.0, 57.0, -2.0, -10.0, 93.0, -228.0, 8.0, -51.0, -26.0, 49.0, 23.0, -98.0, -62.0, // 6
662
+ 72.0, -54.0, -48.0, 2.0, -14.0, 31.0, -12.0, -38.0, 2.0, -18.0, 28.0, 19.0, -15.0, 6.0, -22.0, // 7
663
+ 11.0, 8.0, 8.0, -4.0, -15.0, -9.0, 6.0, 2.0, -13.0, 3.0, 5.0, -8.0, 16.0, 6.0, -5.0, 8.0, -18.0, // 8
664
+ 8.0, 10.0, -20.0, 1.0, 14.0, -11.0, 5.0, 12.0, -3.0, 1.0, -2.0, -2.0, 8.0, 2.0, 10.0, 0.0, -2.0, -1.0, 2.0, // 9
665
+ -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 6.0, -4.0, 4.0, 0.0, 0.0, -2.0, 1.0, 4.0, 2.0, 0.0, 0.0, -6.0, } // 10
666
+ };
667
+ template <class FloatT>
668
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::IGRF20 = {
669
+ "IGRF20",
670
+ 1920.0,
671
+ 10,
672
+ {-31060.0, -2317.0, 5845.0, // 1
673
+ -839.0, 2959.0, -1259.0, 1407.0, 823.0, // 2
674
+ 1111.0, -1600.0, -445.0, 1205.0, 103.0, 839.0, 293.0, // 3
675
+ 889.0, 695.0, 220.0, 616.0, -134.0, -424.0, -153.0, 199.0, -57.0, // 4
676
+ -221.0, 326.0, -122.0, 236.0, 58.0, -23.0, -38.0, -119.0, -125.0, -62.0, 43.0, // 5
677
+ 61.0, 55.0, 0.0, -10.0, 96.0, -233.0, 11.0, -46.0, -22.0, 44.0, 18.0, -101.0, -57.0, // 6
678
+ 73.0, -54.0, -49.0, 2.0, -14.0, 29.0, -13.0, -37.0, 4.0, -16.0, 28.0, 19.0, -16.0, 6.0, -22.0, // 7
679
+ 11.0, 7.0, 8.0, -3.0, -15.0, -9.0, 6.0, 2.0, -14.0, 4.0, 5.0, -7.0, 17.0, 6.0, -5.0, 8.0, -19.0, // 8
680
+ 8.0, 10.0, -20.0, 1.0, 14.0, -11.0, 5.0, 12.0, -3.0, 1.0, -2.0, -2.0, 9.0, 2.0, 10.0, 0.0, -2.0, -1.0, 2.0, // 9
681
+ -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 6.0, -4.0, 4.0, 0.0, 0.0, -2.0, 1.0, 4.0, 3.0, 0.0, 0.0, -6.0, } // 10
682
+ };
683
+ template <class FloatT>
684
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::IGRF2010 = {
685
+ "IGRF2010",
686
+ 2010.0,
687
+ 13,
688
+ {-29496.5, -1585.9, 4945.1, // 1
689
+ -2396.6, 3026.0, -2707.7, 1668.6, -575.4, // 2
690
+ 1339.7, -2326.3, -160.5, 1231.7, 251.7, 634.2, -536.8, // 3
691
+ 912.6, 809.0, 286.4, 166.6, -211.2, -357.1, 164.4, 89.7, -309.2, // 4
692
+ -231.1, 357.2, 44.7, 200.3, 188.9, -141.2, -118.1, -163.1, 0.1, -7.7, 100.9, // 5
693
+ 72.8, 68.6, -20.8, 76.0, 44.2, -141.4, 61.5, -22.9, -66.3, 13.1, 3.1, -77.9, 54.9, // 6
694
+ 80.4, -75.0, -57.8, -4.7, -21.2, 45.3, 6.6, 14.0, 24.9, 10.4, 7.0, 1.6, -27.7, 4.9, -3.4, // 7
695
+ 24.3, 8.2, 10.9, -14.5, -20.0, -5.7, 11.9, -19.3, -17.4, 11.6, 16.7, 10.9, 7.1, -14.1, -10.8, -3.7, 1.7, // 8
696
+ 5.4, 9.4, -20.5, 3.4, 11.6, -5.3, 12.8, 3.1, -7.2, -12.4, -7.4, -0.8, 8.0, 8.4, 2.2, -8.4, -6.1, -10.1, 7.0, // 9
697
+ -2.0, -6.3, 2.8, 0.9, -0.1, -1.1, 4.7, -0.2, 4.4, 2.5, -7.2, -0.3, -1.0, 2.2, -4.0, 3.1, -2.0, -1.0, -2.0, -2.8, -8.3, // 10
698
+ 3.0, -1.5, 0.1, -2.1, 1.7, 1.6, -0.6, -0.5, -1.8, 0.5, 0.9, -0.8, -0.4, 0.4, -2.5, 1.8, -1.3, 0.2, -2.1, 0.8, -1.9, 3.8, -1.8, // 11
699
+ -2.1, -0.2, -0.8, 0.3, 0.3, 1.0, 2.2, -0.7, -2.5, 0.9, 0.5, -0.1, 0.6, 0.5, 0.0, -0.4, 0.1, -0.4, 0.3, 0.2, -0.9, -0.8, -0.2, 0.0, 0.8, // 12
700
+ -0.2, -0.9, -0.8, 0.3, 0.3, 0.4, 1.7, -0.4, -0.6, 1.1, -1.2, -0.3, -0.1, 0.8, 0.5, -0.2, 0.1, 0.4, 0.5, 0.0, 0.4, 0.4, -0.2, -0.3, -0.5, -0.3, -0.8, } // 13
701
+ };
702
+ template <class FloatT>
703
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::IGRF25 = {
704
+ "IGRF25",
705
+ 1925.0,
706
+ 10,
707
+ {-30926.0, -2318.0, 5817.0, // 1
708
+ -893.0, 2969.0, -1334.0, 1471.0, 728.0, // 2
709
+ 1140.0, -1645.0, -462.0, 1202.0, 119.0, 881.0, 229.0, // 3
710
+ 891.0, 711.0, 216.0, 601.0, -163.0, -426.0, -130.0, 217.0, -70.0, // 4
711
+ -230.0, 326.0, -96.0, 226.0, 58.0, -28.0, -44.0, -125.0, -122.0, -69.0, 51.0, // 5
712
+ 61.0, 54.0, 3.0, -9.0, 99.0, -238.0, 14.0, -40.0, -18.0, 39.0, 13.0, -103.0, -52.0, // 6
713
+ 73.0, -54.0, -50.0, 3.0, -14.0, 27.0, -14.0, -35.0, 5.0, -14.0, 29.0, 19.0, -17.0, 6.0, -21.0, // 7
714
+ 11.0, 7.0, 8.0, -3.0, -15.0, -9.0, 6.0, 2.0, -14.0, 4.0, 5.0, -7.0, 17.0, 7.0, -5.0, 8.0, -19.0, // 8
715
+ 8.0, 10.0, -20.0, 1.0, 14.0, -11.0, 5.0, 12.0, -3.0, 1.0, -2.0, -2.0, 9.0, 2.0, 10.0, 0.0, -2.0, -1.0, 2.0, // 9
716
+ -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 6.0, -4.0, 4.0, 0.0, 0.0, -2.0, 1.0, 4.0, 3.0, 0.0, 0.0, -6.0, } // 10
717
+ };
718
+ template <class FloatT>
719
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::IGRF30 = {
720
+ "IGRF30",
721
+ 1930.0,
722
+ 10,
723
+ {-30805.0, -2316.0, 5808.0, // 1
724
+ -951.0, 2980.0, -1424.0, 1517.0, 644.0, // 2
725
+ 1172.0, -1692.0, -480.0, 1205.0, 133.0, 907.0, 166.0, // 3
726
+ 896.0, 727.0, 205.0, 584.0, -195.0, -422.0, -109.0, 234.0, -90.0, // 4
727
+ -237.0, 327.0, -72.0, 218.0, 60.0, -32.0, -53.0, -131.0, -118.0, -74.0, 58.0, // 5
728
+ 60.0, 53.0, 4.0, -9.0, 102.0, -242.0, 19.0, -32.0, -16.0, 32.0, 8.0, -104.0, -46.0, // 6
729
+ 74.0, -54.0, -51.0, 4.0, -15.0, 25.0, -14.0, -34.0, 6.0, -12.0, 29.0, 18.0, -18.0, 6.0, -20.0, // 7
730
+ 11.0, 7.0, 8.0, -3.0, -15.0, -9.0, 5.0, 2.0, -14.0, 5.0, 5.0, -6.0, 18.0, 8.0, -5.0, 8.0, -19.0, // 8
731
+ 8.0, 10.0, -20.0, 1.0, 14.0, -12.0, 5.0, 12.0, -3.0, 1.0, -2.0, -2.0, 9.0, 3.0, 10.0, 0.0, -2.0, -2.0, 2.0, // 9
732
+ -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 6.0, -4.0, 4.0, 0.0, 0.0, -2.0, 1.0, 4.0, 3.0, 0.0, 0.0, -6.0, } // 10
733
+ };
734
+ template <class FloatT>
735
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::IGRF35 = {
736
+ "IGRF35",
737
+ 1935.0,
738
+ 10,
739
+ {-30715.0, -2306.0, 5812.0, // 1
740
+ -1018.0, 2984.0, -1520.0, 1550.0, 586.0, // 2
741
+ 1206.0, -1740.0, -494.0, 1215.0, 146.0, 918.0, 101.0, // 3
742
+ 903.0, 744.0, 188.0, 565.0, -226.0, -415.0, -90.0, 249.0, -114.0, // 4
743
+ -241.0, 329.0, -51.0, 211.0, 64.0, -33.0, -64.0, -136.0, -115.0, -76.0, 64.0, // 5
744
+ 59.0, 53.0, 4.0, -8.0, 104.0, -246.0, 25.0, -25.0, -15.0, 25.0, 4.0, -106.0, -40.0, // 6
745
+ 74.0, -53.0, -52.0, 4.0, -17.0, 23.0, -14.0, -33.0, 7.0, -11.0, 29.0, 18.0, -19.0, 6.0, -19.0, // 7
746
+ 11.0, 7.0, 8.0, -3.0, -15.0, -9.0, 5.0, 1.0, -15.0, 6.0, 5.0, -6.0, 18.0, 8.0, -5.0, 7.0, -19.0, // 8
747
+ 8.0, 10.0, -20.0, 1.0, 15.0, -12.0, 5.0, 11.0, -3.0, 1.0, -3.0, -2.0, 9.0, 3.0, 11.0, 0.0, -2.0, -2.0, 2.0, // 9
748
+ -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 6.0, -4.0, 4.0, 0.0, 0.0, -1.0, 2.0, 4.0, 3.0, 0.0, 0.0, -6.0, } // 10
749
+ };
750
+ template <class FloatT>
751
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF11Preset<FloatT>::IGRF40 = {
752
+ "IGRF40",
753
+ 1940.0,
754
+ 10,
755
+ {-30654.0, -2292.0, 5821.0, // 1
756
+ -1106.0, 2981.0, -1614.0, 1566.0, 528.0, // 2
757
+ 1240.0, -1790.0, -499.0, 1232.0, 163.0, 916.0, 43.0, // 3
758
+ 914.0, 762.0, 169.0, 550.0, -252.0, -405.0, -72.0, 265.0, -141.0, // 4
759
+ -241.0, 334.0, -33.0, 208.0, 71.0, -33.0, -75.0, -141.0, -113.0, -76.0, 69.0, // 5
760
+ 57.0, 54.0, 4.0, -7.0, 105.0, -249.0, 33.0, -18.0, -15.0, 18.0, 0.0, -107.0, -33.0, // 6
761
+ 74.0, -53.0, -52.0, 4.0, -18.0, 20.0, -14.0, -31.0, 7.0, -9.0, 29.0, 17.0, -20.0, 5.0, -19.0, // 7
762
+ 11.0, 7.0, 8.0, -3.0, -14.0, -10.0, 5.0, 1.0, -15.0, 6.0, 5.0, -5.0, 19.0, 9.0, -5.0, 7.0, -19.0, // 8
763
+ 8.0, 10.0, -21.0, 1.0, 15.0, -12.0, 5.0, 11.0, -3.0, 1.0, -3.0, -2.0, 9.0, 3.0, 11.0, 1.0, -2.0, -2.0, 2.0, // 9
764
+ -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 6.0, -4.0, 4.0, 0.0, 0.0, -1.0, 2.0, 4.0, 3.0, 0.0, 0.0, -6.0, } // 10
765
+ };
766
+
767
+ template <class FloatT>
768
+ const typename MagneticFieldGeneric<FloatT>::model_t *IGRF11Generic<FloatT>::models[] = {
769
+ &preset_t::IGRF00,
770
+ &preset_t::IGRF05,
771
+ &preset_t::IGRF10,
772
+ &preset_t::IGRF15,
773
+ &preset_t::IGRF20,
774
+ &preset_t::IGRF25,
775
+ &preset_t::IGRF30,
776
+ &preset_t::IGRF35,
777
+ &preset_t::IGRF40,
778
+ &preset_t::DGRF45,
779
+ &preset_t::DGRF50,
780
+ &preset_t::DGRF55,
781
+ &preset_t::DGRF60,
782
+ &preset_t::DGRF65,
783
+ &preset_t::DGRF70,
784
+ &preset_t::DGRF75,
785
+ &preset_t::DGRF80,
786
+ &preset_t::DGRF85,
787
+ &preset_t::DGRF90,
788
+ &preset_t::DGRF95,
789
+ &preset_t::DGRF2000,
790
+ &preset_t::DGRF2005,
791
+ &preset_t::IGRF2010,
792
+ };
793
+
794
+ template <class FloatT>
795
+ const int IGRF11Generic<FloatT>::models_num = sizeof(models) / sizeof(models[0]);
796
+
797
+ template <class FloatT>
798
+ struct IGRF12Preset : public IGRF11Preset<FloatT> {
799
+ static const typename MagneticFieldGeneric<FloatT>::model_t DGRF2010;
800
+ static const typename MagneticFieldGeneric<FloatT>::model_t IGRF2015;
801
+ };
802
+
803
+ template <class FloatT>
804
+ struct IGRF12Generic : public MagneticFieldGeneric2<FloatT, IGRF12Generic>, public IGRF12Preset<FloatT> {
805
+ typedef IGRF12Preset<FloatT> preset_t;
806
+ static const typename MagneticFieldGeneric<FloatT>::model_t *models[];
807
+ static const int models_num;
808
+ };
809
+
810
+ typedef IGRF12Generic<double> IGRF12;
811
+
812
+ template <class FloatT>
813
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF12Preset<FloatT>::DGRF2010 = {
814
+ "DGRF2010",
815
+ 2010.0,
816
+ 13,
817
+ {-29496.57, -1586.42, 4944.26, // 1
818
+ -2396.06, 3026.34, -2708.54, 1668.17, -575.73, // 2
819
+ 1339.85, -2326.54, -160.4, 1232.1, 251.75, 633.73, -537.03, // 3
820
+ 912.66, 808.97, 286.48, 166.58, -211.03, -356.83, 164.46, 89.4, -309.72, // 4
821
+ -230.87, 357.29, 44.58, 200.26, 189.01, -141.05, -118.06, -163.17, -0.01, -8.03, 101.04, // 5
822
+ 72.78, 68.69, -20.9, 75.92, 44.18, -141.4, 61.54, -22.83, -66.26, 13.1, 3.02, -78.09, 55.4, // 6
823
+ 80.44, -75.0, -57.8, -4.55, -21.2, 45.24, 6.54, 14.0, 24.96, 10.46, 7.03, 1.64, -27.61, 4.92, -3.28, // 7
824
+ 24.41, 8.21, 10.84, -14.5, -20.03, -5.59, 11.83, -19.34, -17.41, 11.61, 16.71, 10.85, 6.96, -14.05, -10.74, -3.54, 1.64, // 8
825
+ 5.5, 9.45, -20.54, 3.45, 11.51, -5.27, 12.75, 3.13, -7.14, -12.38, -7.42, -0.76, 7.97, 8.43, 2.14, -8.42, -6.08, -10.08, 7.01, // 9
826
+ -1.94, -6.24, 2.73, 0.89, -0.1, -1.07, 4.71, -0.16, 4.44, 2.45, -7.22, -0.33, -0.96, 2.13, -3.95, 3.09, -1.99, -1.03, -1.97, -2.8, -8.31, // 10
827
+ 3.05, -1.48, 0.13, -2.03, 1.67, 1.65, -0.66, -0.51, -1.76, 0.54, 0.85, -0.79, -0.39, 0.37, -2.51, 1.79, -1.27, 0.12, -2.11, 0.75, -1.94, 3.75, -1.86, // 11
828
+ -2.12, -0.21, -0.87, 0.3, 0.27, 1.04, 2.13, -0.63, -2.49, 0.95, 0.49, -0.11, 0.59, 0.52, 0.0, -0.39, 0.13, -0.37, 0.27, 0.21, -0.86, -0.77, -0.23, 0.04, 0.87, // 12
829
+ -0.09, -0.89, -0.87, 0.31, 0.3, 0.42, 1.66, -0.45, -0.59, 1.08, -1.14, -0.31, -0.07, 0.78, 0.54, -0.18, 0.1, 0.38, 0.49, 0.02, 0.44, 0.42, -0.25, -0.26, -0.53, -0.26, -0.79, } // 13
830
+ };
831
+ template <class FloatT>
832
+ const typename MagneticFieldGeneric<FloatT>::model_t IGRF12Preset<FloatT>::IGRF2015 = {
833
+ "IGRF2015",
834
+ 2015.0,
835
+ 13,
836
+ {-29442.0, -1501.0, 4797.1, // 1
837
+ -2445.1, 3012.9, -2845.6, 1676.7, -641.9, // 2
838
+ 1350.7, -2352.3, -115.3, 1225.6, 244.9, 582.0, -538.4, // 3
839
+ 907.6, 813.7, 283.3, 120.4, -188.7, -334.9, 180.9, 70.4, -329.5, // 4
840
+ -232.6, 360.1, 47.3, 192.4, 197.0, -140.9, -119.3, -157.5, 16.0, 4.1, 100.2, // 5
841
+ 70.0, 67.7, -20.8, 72.7, 33.2, -129.9, 58.9, -28.9, -66.7, 13.2, 7.3, -70.9, 62.6, // 6
842
+ 81.6, -76.1, -54.1, -6.8, -19.5, 51.8, 5.7, 15.0, 24.4, 9.4, 3.4, -2.8, -27.4, 6.8, -2.2, // 7
843
+ 24.2, 8.8, 10.1, -16.9, -18.3, -3.2, 13.3, -20.6, -14.6, 13.4, 16.2, 11.7, 5.7, -15.9, -9.1, -2.0, 2.1, // 8
844
+ 5.4, 8.8, -21.6, 3.1, 10.8, -3.3, 11.8, 0.7, -6.8, -13.3, -6.9, -0.1, 7.8, 8.7, 1.0, -9.1, -4.0, -10.5, 8.4, // 9
845
+ -1.9, -6.3, 3.2, 0.1, -0.4, 0.5, 4.6, -0.5, 4.4, 1.8, -7.9, -0.7, -0.6, 2.1, -4.2, 2.4, -2.8, -1.8, -1.2, -3.6, -8.7, // 10
846
+ 3.1, -1.5, -0.1, -2.3, 2.0, 2.0, -0.7, -0.8, -1.1, 0.6, 0.8, -0.7, -0.2, 0.2, -2.2, 1.7, -1.4, -0.2, -2.5, 0.4, -2.0, 3.5, -2.4, // 11
847
+ -1.9, -0.2, -1.1, 0.4, 0.4, 1.2, 1.9, -0.8, -2.2, 0.9, 0.3, 0.1, 0.7, 0.5, -0.1, -0.3, 0.3, -0.4, 0.2, 0.2, -0.9, -0.9, -0.1, 0.0, 0.7, // 12
848
+ 0.0, -0.9, -0.9, 0.4, 0.4, 0.5, 1.6, -0.5, -0.5, 1.0, -1.2, -0.2, -0.1, 0.8, 0.4, -0.1, -0.1, 0.3, 0.4, 0.1, 0.5, 0.5, -0.3, -0.4, -0.4, -0.3, -0.8, } // 13
849
+ };
850
+
851
+ template <class FloatT>
852
+ const typename MagneticFieldGeneric<FloatT>::model_t *IGRF12Generic<FloatT>::models[] = {
853
+ &preset_t::IGRF00,
854
+ &preset_t::IGRF05,
855
+ &preset_t::IGRF10,
856
+ &preset_t::IGRF15,
857
+ &preset_t::IGRF20,
858
+ &preset_t::IGRF25,
859
+ &preset_t::IGRF30,
860
+ &preset_t::IGRF35,
861
+ &preset_t::IGRF40,
862
+ &preset_t::DGRF45,
863
+ &preset_t::DGRF50,
864
+ &preset_t::DGRF55,
865
+ &preset_t::DGRF60,
866
+ &preset_t::DGRF65,
867
+ &preset_t::DGRF70,
868
+ &preset_t::DGRF75,
869
+ &preset_t::DGRF80,
870
+ &preset_t::DGRF85,
871
+ &preset_t::DGRF90,
872
+ &preset_t::DGRF95,
873
+ &preset_t::DGRF2000,
874
+ &preset_t::DGRF2005,
875
+ &preset_t::DGRF2010,
876
+ &preset_t::IGRF2015,
877
+ };
878
+
879
+ template <class FloatT>
880
+ const int IGRF12Generic<FloatT>::models_num = sizeof(models) / sizeof(models[0]);
881
+
882
+ /*
883
+ * WMM2010 is the standard model for the U.S. and U.K. Departments of Defense
884
+ * and for NATO, also used widely in civilian navigation systems. This is a
885
+ * degree and order 12 main field model for 2010.0 and degree and order 12
886
+ * secular variation model for 2010 - 2015. For more information on the WMM or
887
+ * to download the Technical Report, visit the WMM Web site at:
888
+ * http://www.ngdc.noaa.gov/geomag/WMM/
889
+ */
890
+
891
+ template <class FloatT>
892
+ struct WMM2010Generic : public MagneticFieldGeneric<FloatT> {
893
+ static const typename MagneticFieldGeneric<FloatT>::model_t WMM;
894
+
895
+ static typename MagneticFieldGeneric<FloatT>::model_t get_model(const FloatT &year){
896
+ return WMM;
897
+ }
898
+ static typename MagneticFieldGeneric<FloatT>::latlng_t geomagnetic_latlng(
899
+ const FloatT &year,
900
+ const FloatT &geocentric_latitude, const FloatT &longitude){
901
+ return MagneticFieldGeneric<FloatT>::geomagnetic_latlng(
902
+ WMM,
903
+ geocentric_latitude, longitude);
904
+ }
905
+ };
906
+
907
+ typedef WMM2010Generic<double> WMM2010;
908
+
909
+ template <class FloatT>
910
+ const typename MagneticFieldGeneric<FloatT>::model_t WMM2010Generic<FloatT>::WMM = {
911
+ "WMM2010",
912
+ 2010.0,
913
+ 12,
914
+ {-29496.6, -1586.3, 4944.4, // 1
915
+ -2396.6, 3026.1, -2707.7, 1668.6, -576.1, // 2
916
+ 1340.1, -2326.2, -160.2, 1231.9, 251.9, 634.0, -536.6, // 3
917
+ 912.6, 808.9, 286.4, 166.7, -211.2, -357.1, 164.3, 89.4, -309.1, // 4
918
+ -230.9, 357.2, 44.6, 200.3, 188.9, -141.1, -118.2, -163.0, 0.0, -7.8, 100.9, // 5
919
+ 72.8, 68.6, -20.8, 76.0, 44.1, -141.4, 61.5, -22.8, -66.3, 13.2, 3.1, -77.9, 55.0, // 6
920
+ 80.5, -75.1, -57.9, -4.7, -21.1, 45.3, 6.5, 13.9, 24.9, 10.4, 7.0, 1.7, -27.7, 4.9, -3.3, // 7
921
+ 24.4, 8.1, 11.0, -14.5, -20.0, -5.6, 11.9, -19.3, -17.4, 11.5, 16.7, 10.9, 7.0, -14.1, -10.8, -3.7, 1.7, // 8
922
+ 5.4, 9.4, -20.5, 3.4, 11.5, -5.2, 12.8, 3.1, -7.2, -12.4, -7.4, -0.7, 8.0, 8.4, 2.1, -8.5, -6.1, -10.1, 7.0, // 9
923
+ -2.0, -6.3, 2.8, 0.9, -0.1, -1.1, 4.7, -0.2, 4.4, 2.5, -7.2, -0.3, -1.0, 2.2, -3.9, 3.1, -2.0, -1.0, -2.0, -2.8, -8.3, // 10
924
+ 3.0, -1.5, 0.2, -2.1, 1.7, 1.7, -0.6, -0.5, -1.8, 0.5, 0.9, -0.8, -0.4, 0.4, -2.5, 1.8, -1.3, 0.1, -2.1, 0.7, -1.9, 3.8, -1.8, // 11
925
+ -2.2, -0.2, -0.9, 0.3, 0.3, 1.0, 2.1, -0.6, -2.5, 0.9, 0.5, -0.1, 0.6, 0.5, -0.0, -0.4, 0.1, -0.4, 0.3, 0.2, -0.9, -0.8, -0.2, 0.0, 0.9, } // 12
926
+ };
927
+
928
+ #endif /* __MAGNETIC_FIELD_H__ */