| 1 | /*  module magfield.c */
 | 
|---|
| 2 | 
 | 
|---|
| 3 | /* Module to calculate magnetic variation and field given position,
 | 
|---|
| 4 | **               altitude, and date
 | 
|---|
| 5 | ** Implements the NIMA (formerly DMA) WMM and IGRF models
 | 
|---|
| 6 | **
 | 
|---|
| 7 | **    http://www.nima.mil/GandG/ngdc-wmm2000.html
 | 
|---|
| 8 | **    For WMM2000 coefficients:
 | 
|---|
| 9 | **    ftp://ftp.ngdc.noaa.gov/Solid_Earth/Mainfld_Mag/DoD_Model/wmm.cof
 | 
|---|
| 10 | **    For IGRF/DGRF coefficients:
 | 
|---|
| 11 | **    http://swdcdb.kugi.kyoto-u.ac.jp/igrf/coef/igrfall.d
 | 
|---|
| 12 | **
 | 
|---|
| 13 | ** Copyright (C) 2000  Edward A Williams <Ed_Williams@compuserve.com>
 | 
|---|
| 14 | **
 | 
|---|
| 15 | **  The routine uses a spherical harmonic expansion of the magnetic
 | 
|---|
| 16 | ** potential up to twelfth order, together with its time variation, as
 | 
|---|
| 17 | ** described in Chapter 4 of "Geomagnetism, Vol 1, Ed. J.A.Jacobs,
 | 
|---|
| 18 | ** Academic Press (London 1987)". The program first converts geodetic
 | 
|---|
| 19 | ** coordinates (lat/long on elliptic earth and altitude) to spherical
 | 
|---|
| 20 | ** geocentric (spherical lat/long and radius) coordinates. Using this,
 | 
|---|
| 21 | ** the spherical (B_r, B_theta, B_phi) magnetic field components are
 | 
|---|
| 22 | ** computed from the model. These are finally referred to surface (X, Y,
 | 
|---|
| 23 | ** Z) coordinates.
 | 
|---|
| 24 | **
 | 
|---|
| 25 | **   Fields are accurate to better than 200nT, variation and dip to
 | 
|---|
| 26 | ** better than 0.5 degrees, with the exception of the declination near
 | 
|---|
| 27 | ** the magnetic poles (where it is ill-defined) where the error may reach
 | 
|---|
| 28 | ** 4 degrees or more.
 | 
|---|
| 29 | **
 | 
|---|
| 30 | **   Variation is undefined at both the geographic and  
 | 
|---|
| 31 | ** magnetic poles, even though the field itself is well-behaved. To
 | 
|---|
| 32 | ** avoid the routine blowing up, latitude entries corresponding to
 | 
|---|
| 33 | ** the geographic poles are slightly offset. At the magnetic poles,
 | 
|---|
| 34 | ** the routine returns zero variation.
 | 
|---|
| 35 | **
 | 
|---|
| 36 | ** HISTORY
 | 
|---|
| 37 | ** Adapted from EAW Excel 3.0 version 3/27/94 EAW
 | 
|---|
| 38 | ** Recoded in C++ by Starry Chan
 | 
|---|
| 39 | ** WMM95 added and rearranged in ANSI-C EAW 7/9/95
 | 
|---|
| 40 | ** Put shell around program and made Borland & GCC compatible EAW 11/22/95
 | 
|---|
| 41 | ** IGRF95 added 2/96 EAW
 | 
|---|
| 42 | ** WMM2000 IGR2000 added 2/00 EAW
 | 
|---|
| 43 | ** Released under GPL  3/26/00 EAW
 | 
|---|
| 44 | ** Adaptions and modifications for the SimGear project  3/27/2000 CLO
 | 
|---|
| 45 | ** Removed all pow() calls and made static roots[][] arrays to
 | 
|---|
| 46 | ** save many sqrt() calls on subsequent invocations
 | 
|---|
| 47 | ** 3/28/2000  Norman Vine -- nhv@yahoo.com
 | 
|---|
| 48 | ** Put in some bullet-proofing to handle magnetic and geographic poles.
 | 
|---|
| 49 | ** 3/28/2000 EAW
 | 
|---|
| 50 | ** Added missing comment close, the lack of which caused the altitude 
 | 
|---|
| 51 | ** correction to be omitted.
 | 
|---|
| 52 | ** 01/31/01 Jim Seymour (jseymour@LinxNet.com)
 | 
|---|
| 53 | **
 | 
|---|
| 54 | ** This program is free software; you can redistribute it and/or
 | 
|---|
| 55 | ** modify it under the terms of the GNU General Public License as
 | 
|---|
| 56 | ** published by the Free Software Foundation; either version 2 of the
 | 
|---|
| 57 | ** License, or (at your option) any later version.
 | 
|---|
| 58 | **
 | 
|---|
| 59 | ** This program is distributed in the hope that it will be useful, but
 | 
|---|
| 60 | ** WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
| 61 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
|---|
| 62 | ** General Public License for more details.
 | 
|---|
| 63 | **
 | 
|---|
| 64 | ** You should have received a copy of the GNU General Public License
 | 
|---|
| 65 | ** along with this program; if not, write to the Free Software
 | 
|---|
| 66 | ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
|---|
| 67 | **
 | 
|---|
| 68 | */ 
 | 
|---|
| 69 | 
 | 
|---|
| 70 | #include        <stdio.h>
 | 
|---|
| 71 | #include        <stdlib.h>
 | 
|---|
| 72 | #include        <math.h>
 | 
|---|
| 73 | #include        "magfield.h"
 | 
|---|
| 74 | 
 | 
|---|
| 75 | #define max(a,b)        (((a) > (b)) ? (a) : (b))
 | 
|---|
| 76 | 
 | 
|---|
| 77 | static const double pi = 3.14159265358979;
 | 
|---|
| 78 | static const double a = 6378.16;        /* major radius (km) IAU66 ellipsoid */
 | 
|---|
| 79 | static const double f = 1.0 / 298.25;   /* inverse flattening IAU66 ellipsoid */
 | 
|---|
| 80 | static const double b = 6378.16 * (1.0 -1.0 / 298.25 );
 | 
|---|
| 81 |         /* minor radius b=a*(1-f) */
 | 
|---|
| 82 | static const double r_0 = 6371.2;       /* "mean radius" for spherical harmonic expansion */
 | 
|---|
| 83 | 
 | 
|---|
| 84 | /*IGRF90 constants */
 | 
|---|
| 85 | static const double gnm_igrf90[13][13] = 
 | 
|---|
| 86 |         {
 | 
|---|
| 87 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 88 |         {-29775.4, -1851, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 89 |         {-2135.8, 3058.2, 1693.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 90 |         {1314.6, -2240.2, 1245.6, 806.5, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 91 |         {938.9, 782.3, 323.9, -422.7, 141.7, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 92 |         {-211, 352.5, 243.8, -110.8, -165.6, -37, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 93 |         {60.7, 63.9, 60.4, -177.5, 2, 16.7, -96.3, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 94 |         {76.6, -64.2, 3.7, 27.5, 0.9, 5.7, 9.8, -0.5, 0, 0, 0, 0, 0}, 
 | 
|---|
| 95 |         {22.4, 5.1, -0.9, -10.8, -12.4, 3.8, 3.8, 2.6, -6, 0, 0, 0, 0}, 
 | 
|---|
| 96 |         {4.4, 9.9, 0.8, -12, 9.3, -3.9, -1.4, 7.3, 1.5, -5.5, 0, 0, 0}, 
 | 
|---|
| 97 |         {-3.6, -3.9, 2.4, -5.3, -2.4, 4.4, 3, 1.2, 2.2, 2.9, 0, 0, 0},
 | 
|---|
| 98 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 99 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
 | 
|---|
| 100 | static const double hnm_igrf90[13][13] = 
 | 
|---|
| 101 |         {
 | 
|---|
| 102 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 103 |         {0, 5410.9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 104 |         {0, -2277.7, -380, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 105 |         {0, -286.5, 293.3, -348.5, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 106 |         {0, 248.1, -239.5, 87, -299.4, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 107 |         {0, 47.2, 153.5, -154.4, -69.2, 97.7, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 108 |         {0, -15.8, 82.7, 68.3, -52.5, 1.8, 26.9, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 109 |         {0, -81.1, -27.3, 0.6, 20.4, 16.4, -22.6, -5, 0, 0, 0, 0, 0}, 
 | 
|---|
| 110 |         {0, 9.7, -19.9, 7.1, -22.1, 11.9, 11, -16, -10.7, 0, 0, 0, 0}, 
 | 
|---|
| 111 |         {0, -20.8, 15.4, 9.5, -5.7, -6.4, 8.6, 9.1, -6.6, 1.9, 0, 0, 0}, 
 | 
|---|
| 112 |         {0, 1.3, 0.4, 3.1, 5.6, -4.2, -0.5, -1.5, 3.8, -0.5, -6.2, 0, 0}, 
 | 
|---|
| 113 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 114 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
 | 
|---|
| 115 | static const double gtnm_igrf90[13][13] = 
 | 
|---|
| 116 |         {
 | 
|---|
| 117 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 118 |         {18, 10.6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 119 |         {-12.9, 2.4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 120 |         {3.3, -6.7, 0, -5.9, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 121 |         {0.5, 0.6, -7, 0.5, -5.5, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 122 |         {0.6, -0.1, -1.6, -3.1, 0, 2.3, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 123 |         {1.3, -0.2, 1.8, 1.3, -0.2, 0.1, 1.2, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 124 |         {0.6, -0.5, -0.3, 0.6, 1.6, 0.2, 0.2, 0.3, 0, 0, 0, 0, 0}, 
 | 
|---|
| 125 |         {0.2, -0.7, -0.2, 0.1, -1.1, 0, 0, -0.5, -0.6, 0, 0, 0, 0}, 
 | 
|---|
| 126 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 127 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 128 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 129 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
 | 
|---|
| 130 | static const double htnm_igrf90[13][13] =
 | 
|---|
| 131 |         {
 | 
|---|
| 132 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 133 |         {0, -16.1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 134 |         {0, -15.8, -13.8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 135 |         {0, 4.4, 1.6, -10.6, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 136 |         {0, 2.6, 1.8, 3.1, -1.4, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 137 |         {0, -0.1, 0.5, 0.4, 1.7, 0.4, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 138 |         {0, 0.2, -1.3, 0, -0.9, 0.5, 1.2, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 139 |         {0, 0.6, 0.2, 0.8, -0.5, -0.2, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 140 |         {0, 0.5, -0.2, 0.3, 0.3, 0.4, -0.5, -0.3, 0.6, 0, 0, 0, 0}, 
 | 
|---|
| 141 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 142 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 143 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 144 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
 | 
|---|
| 145 | /* IGRF95 */
 | 
|---|
| 146 | static const double gnm_igrf95[13][13] =
 | 
|---|
| 147 | {
 | 
|---|
| 148 |   {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 149 |   {-29682.0, -1789.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 150 |   {-2197.0, 3074.0, 1685.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 151 |   {1329.0, -2268.0, 1249.0, 769.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 152 |   {941.0, 782.0, 291.0, -421.0, 116.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 153 |   {-210.0, 352.0, 237.0, -122.0, -167.0, -26.0, 0.0, 0.0, 0.0, 0.0,0.0,0.0,0.0},
 | 
|---|
| 154 |   {66.0, 64.0, 65.0, -172.0, 2.0, 17.0, -94.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 155 |   {78.0, -67.0, 1.0, 29.0, 4.0, 8.0, 10.0, -2.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 156 |   {24.0, 4.0, -1.0, -9.0, -14.0, 4.0, 5.0, 0.0, -7.0, 0.0,0.0, 0.0, 0.0},
 | 
|---|
| 157 |   {4.0, 9.0, 1.0, -12.0, 9.0, -4.0, -2.0, 7.0, 0.0, -6.0, 0.0, 0.0, 0.0},
 | 
|---|
| 158 |   {-3.0, -4.0, 2.0, -5.0, -2.0, 4.0, 3.0, 1.0, 3.0, 3.0, 0.0, 0.0, 0.0},
 | 
|---|
| 159 |   {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 160 |   {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0}
 | 
|---|
| 161 |  };
 | 
|---|
| 162 | 
 | 
|---|
| 163 | static const double hnm_igrf95[13][13]=
 | 
|---|
| 164 | {
 | 
|---|
| 165 |   {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 166 |   {0.0, 5318.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 167 |   {0.0, -2356.0, -425.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 168 |   {0.0, -263.0, 302.0, -406.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 169 |   {0.0, 262.0, -232.0, 98.0, -301.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 170 |   {0.0, 44.0, 157.0, -152.0, -64.0, 99.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 171 |   {0.0, -16.0, 77.0, 67.0, -57.0, 4.0, 28.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 172 |   {0.0, -77.0, -25.0, 3.0, 22.0, 16.0, -23.0, -3.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 173 |   {0.0, 12.0, -20.0, 7.0, -21.0, 12.0, 10.0, -17.0, -10.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 174 |   {0.0, -19.0, 15.0, 11.0, -7.0, -7.0, 9.0, 7.0, -8.0, 1.0, 0.0, 0.0, 0.0},
 | 
|---|
| 175 |   {0.0, 2.0, 1.0, 3.0, 6.0, -4.0, 0.0, -2.0, 3.0, -1.0, -6.0, 0.0, 0.0},
 | 
|---|
| 176 |   {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 177 |   {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0}
 | 
|---|
| 178 | };
 | 
|---|
| 179 | 
 | 
|---|
| 180 | static const double gtnm_igrf95[13][13]=
 | 
|---|
| 181 | {
 | 
|---|
| 182 |   {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 183 |   {17.6, 13.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 184 |   {-13.2, 3.7, -0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 185 |   {1.5, -6.4, -0.2, -8.1, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 186 |   {0.8, 0.9, -6.9, 0.5, -4.6, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 187 |   {0.8, 0.1, -1.5, -2.0, -0.1, 2.3, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 188 |   {0.5, -0.4, 0.6, 1.9, -0.2, -0.2, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 189 |   {-0.2, -0.8, -0.6, 0.6, 1.2, 0.1, 0.2, -0.6, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 190 |   {0.3, -0.2, 0.1, 0.4, -1.1, 0.3, 0.2, -0.9, -0.3, 0.0,0.0, 0.0, 0.0},
 | 
|---|
| 191 |   {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 192 |   {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 193 |   {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 194 |   {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0}
 | 
|---|
| 195 |  };
 | 
|---|
| 196 | 
 | 
|---|
| 197 | static const double htnm_igrf95[13][13]=
 | 
|---|
| 198 | {
 | 
|---|
| 199 |   {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 200 |   {0.0, -18.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 201 |   {0.0, -15.0, -8.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 202 |   {0.0, 4.1, 2.2, -12.1, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 203 |   {0.0, 1.8, 1.2, 2.7, -1.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 204 |   {0.0, 0.2, 1.2, 0.3, 1.8, 0.9, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 205 |   {0.0, 0.3, -1.6, -0.2, -0.9, 1.0, 2.2, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 206 |   {0.0, 0.8, 0.2, 0.6, -0.4, 0.0, -0.3, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 207 |   {0.0, 0.4, -0.2, 0.2, 0.7, 0.0, -1.2, -0.7, -0.6, 0.0,0.0, 0.0, 0.0},
 | 
|---|
| 208 |   {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 209 |   {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 210 |   {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 211 |   {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0}
 | 
|---|
| 212 | };
 | 
|---|
| 213 | 
 | 
|---|
| 214 | /*WMM85 constants */
 | 
|---|
| 215 | static const double gnm_wmm85[13][13] = 
 | 
|---|
| 216 |         {
 | 
|---|
| 217 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 218 |         {-29879.8, -1903.3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 219 |         {-2070.6, 3040.8, 1696.7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 220 |         {1303.9, -2203, 1241.7, 839.4, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 221 |         {933.8, 781.8, 359, -424.5, 164.5, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 222 |         {-216.4, 353, 254.3, -93.7, -157.5, -45.2, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 223 |         {53.2, 63.8, 51.3, -188.4, 3.3, 20.3, -101.7, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 224 |         {76.9, -60.7, 0.7, 25.4, -8.1, 6.9, 7, -4.4, 0, 0, 0, 0, 0}, 
 | 
|---|
| 225 |         {18.4, 5.1, 1.2, -12, -9.1, 0.1, 4.7, 6.5, -9.5, 0, 0, 0, 0}, 
 | 
|---|
| 226 |         {5.7, 10.9, 0.9, -12.2, 9.5, -3.3, -1, 6.5, 1.5, -4.8, 0, 0, 0}, 
 | 
|---|
| 227 |         {-3.4, -4.7, 2.5, -5.5, -2.1, 4.6, 3.2, 0.6, 1.9, 2.8, -0.2, 0, 0}, 
 | 
|---|
| 228 |         {2.3, -0.8, -2, 2.1, 0.2, -0.4, -0.4, 1.6, 1.5, -0.7, 2.3, 3.5, 0}, 
 | 
|---|
| 229 |         {-1.8, 0, 0.1, -0.3, 0.5, 0.5, -0.6, -0.4, 0, -0.5, 0, 0.7, -0.2}};
 | 
|---|
| 230 | static const double hnm_wmm85[13][13] = 
 | 
|---|
| 231 |         {
 | 
|---|
| 232 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 233 |         {0, 5490.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 234 |         {0, -2189.1, -312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 235 |         {0, -310.3, 282.6, -299.2, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 236 |         {0, 227.2, -246.7, 72.5, -299.1, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 237 |         {0, 43.4, 148.2, -154.8, -71.8, 91.5, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 238 |         {0, -12.3, 87.9, 67.8, -51.1, -4, 20.8, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 239 |         {0, -80.1, -25.9, -0.9, 21.6, 18.5, -20, -7.7, 0, 0, 0, 0, 0}, 
 | 
|---|
| 240 |         {0, 3.8, -20.2, 5, -24.2, 12.2, 7.6, -16.3, -10.9, 0, 0, 0, 0}, 
 | 
|---|
| 241 |         {0, -20.8, 15.8, 9, -5, -6.4, 9.1, 9.9, -5.8, 2.3, 0, 0, 0}, 
 | 
|---|
| 242 |         {0, 1.2, 0.4, 2.5, 5.6, -4.4, -0.5, -1.6, 3.7, -0.5, -6.1, 0, 0}, 
 | 
|---|
| 243 |         {0, 1.3, 2, -1.1, -2.8, 0.7, -0.1, -2.4, -0.4, -1.5, -1.5, 0.7, 0},
 | 
|---|
| 244 |         {0, 0.3, 0.6, 2.5, -1.7, 0.3, 0.2, -0.1, 0.1, 0.1, -1.4, 0.4, 0.7}};
 | 
|---|
| 245 | static const double gtnm_wmm85[13][13] = 
 | 
|---|
| 246 |         {
 | 
|---|
| 247 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 248 |         {21.9, 10.6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 249 |         {-11.2, 1.8, 9.3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 250 |         {8.3, -2, -0.6, 2.4, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 251 |         {-1.2, 0.1, -9.7, -1.7, -9.3, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 252 |         {1.4, -0.5, -1.2, -2.2, 0.9, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 253 |         {3.1, 0, 1.8, -0.2, -0.4, 2.4, 1.8, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 254 |         {-0.1, -0.8, -1.2, 1.1, 0, 0.6, -1.8, -1.2, 0, 0, 0, 0, 0},
 | 
|---|
| 255 |         {0.2, 0, 0.7, 0.1, 0.2, -0.3, -0.1, 0.2, -2.2, 0, 0, 0, 0}, 
 | 
|---|
| 256 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 257 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 258 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 259 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
 | 
|---|
| 260 | static const double htnm_wmm85[13][13] = 
 | 
|---|
| 261 |         {
 | 
|---|
| 262 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 263 |         {0, -31.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 264 |         {0, -9.7, -19.9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 265 |         {0, 6.1, 1.3, -13, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 266 |         {0, 1.3, 3.6, 2.5, 0.6, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 267 |         {0, -0.9, 0.6, 0.3, 2.4, -1.4, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 268 |         {0, 0.7, -2.1, -1.4, -4.3, -0.7, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 269 |         {0, 0, 1.2, 2, 2.6, 0.9, 0.8, 0.4, 0, 0, 0, 0, 0}, 
 | 
|---|
| 270 |         {0, -0.6, -1.5, 0.1, -1.1, 0.4, -2, 0.9, 1.5, 0, 0, 0, 0}, 
 | 
|---|
| 271 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 272 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 273 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 274 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
 | 
|---|
| 275 | 
 | 
|---|
| 276 | /* wmm90 constants */
 | 
|---|
| 277 | static const double gnm_wmm90[13][13] =
 | 
|---|
| 278 |         {
 | 
|---|
| 279 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 280 |         {-29780.5, -1851.7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 281 |         {-2134.3, 3062.2, 1691.9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 282 |         {1312.9, -2244.7, 1246.8, 808.6, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 283 |         {933.5, 784.9, 323.5, -421.7, 139.2, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 284 |         {-208.3, 352.2, 246.5, -110.8, -162.3, -37.2, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 285 |         {59, 63.7, 60, -181.3, 0.4, 15.4, -96, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 286 |         {76.1, -62.1, 1.3, 30.2, 4.7, 7.9, 10.1, 1.9, 0, 0, 0, 0, 0}, 
 | 
|---|
| 287 |         {22.9, 2.3, -1.2, -11.7, -17.5, 2.2, 5.7, 3, -7, 0, 0, 0, 0}, 
 | 
|---|
| 288 |         {3.6, 9.5, -0.9, -10.7, 10.7, -3.2, -1.4, 6.3, 0.8, -5.5, 0, 0, 0},
 | 
|---|
| 289 |         {-3.3, -2.6, 4.5, -5.6, -3.6, 3.9, 3.2, 1.7, 3, 3.7, 0.7, 0, 0}, 
 | 
|---|
| 290 |         {1.3, -1.4, -2.5, 3.2, 0.2, -1.1, 0.3, -0.3, 0.9, -1.1, 2.4, 3, 0}, 
 | 
|---|
| 291 |         {-1.3, 0.1, 0.5, 0.7, 0.4, -0.2, -1.1, 0.9, -0.6, 0.8, 0.2, 0.4, 0.2}};
 | 
|---|
| 292 | static const double hnm_wmm90[13][13] = 
 | 
|---|
| 293 |         {
 | 
|---|
| 294 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 295 |         {0, 5407.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 296 |         {0, -2278.3, -384.3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 297 |         {0, -284.9, 291.7, -352.4, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 298 |         {0, 249.4, -232.7, 91.3, -296.5, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 299 |         {0, 40.8, 148.7, -154.6, -67.6, 97.4, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 300 |         {0, -14.7, 82.2, 70, -56.2, -1.4, 24.6, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 301 |         {0, -78.6, -26.7, 0.1, 19.9, 17.9, -21.5, -6.8, 0, 0, 0, 0, 0}, 
 | 
|---|
| 302 |         {0, 9.7, -19.3, 6.6, -20.1, 13.4, 9.8, -19, -9.1, 0, 0, 0, 0}, 
 | 
|---|
| 303 |         {0, -21.9, 14.3, 9.5, -6.7, -6.4, 9.1, 8.9, -8, 2.1, 0, 0, 0}, 
 | 
|---|
| 304 |         {0, 2.6, 1.2, 2.6, 5.7, -4, -0.4, -1.7, 3.8, -0.8, -6.5, 0, 0}, 
 | 
|---|
| 305 |         {0, 0, 1, -1.6, -2.2, 1.1, -0.7, -1.7, -1.5, -1.3, -1.1, 0.6, 0}, 
 | 
|---|
| 306 |         {0, 0.7, 0.7, 1.3, -1.5, 0.3, 0.2, -1.1, 1.2, -0.2, -1.3, 0.6, 0.6}};
 | 
|---|
| 307 | static const double gtnm_wmm90[13][13] = 
 | 
|---|
| 308 |         {
 | 
|---|
| 309 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 310 |         {16, 9.3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 311 |         {-11.7, 3.7, 1.8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 312 |         {2.1, -7.6, 0, -5.8, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 313 |         {-0.8, 1, -7.4, 0.8, -6.4, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 314 |         {1.7, 0, 0, -2.7, 0, 3, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 315 |         {0.8, 0, 1.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 316 |         {0.5, 0, -0.9, 1.5, 2.7, -1, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 317 |         {0, -1.1, 0, 0, -2.1, 0, 1, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 318 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 319 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 320 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 321 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
 | 
|---|
| 322 | static const double htnm_wmm90[13][13] = 
 | 
|---|
| 323 |         {
 | 
|---|
| 324 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 325 |         {0, -13.8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 326 |         {0, -12.8, -14.9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 327 |         {0, 3.1, 0.8, -11.3, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 328 |         {0, 3.3, 3.7, 2.8, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 329 |         {0, 0, -2.1, 1.2, 1.2, 0.6, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 330 |         {0, -0.6, -0.6, 0, -2.3, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 331 |         {0, 0.6, 0.8, 0, 0, 0, 0.4, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 332 |         {0, 0.4, -0.8, 0.5, 0.3, 0.5, 0, -0.7, 0, 0, 0, 0, 0},
 | 
|---|
| 333 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 334 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 335 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
 | 
|---|
| 336 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
 | 
|---|
| 337 | /* wmm95 constants */
 | 
|---|
| 338 | static const double gnm_wmm95[13][13] =
 | 
|---|
| 339 |         {
 | 
|---|
| 340 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 341 |         {-29682.1,-1782.2,0,0,0,0,0,0,0,0,0,0,0},
 | 
|---|
| 342 |         {-2194.7,3078.6,1685.7,0,0,0,0,0,0,0,0,0,0},
 | 
|---|
| 343 |         {1318.8,-2273.6,1246.9,766.3,0,0,0,0,0,0,0,0,0},
 | 
|---|
| 344 |         {940,782.9,290.9,-418.9,113.8,0,0,0,0,0,0,0,0},
 | 
|---|
| 345 |         {-209.5,354,238.2,-122.1,-162.8,-23.3,0,0,0,0,0,0,0},
 | 
|---|
| 346 |         {68.5,65.6,64.1,-169.1,-0.5,16.5,-91,0,0,0,0,0,0},
 | 
|---|
| 347 |         {78,-68.1,0.1,29.6,6,8.7,9.2,-2.4,0,0,0,0,0},
 | 
|---|
| 348 |         {24.7,3.4,-1.5,-9.6,-16.5,2.6,3.6,-4.9,-8.5,0,0,0,0},
 | 
|---|
| 349 |         {2.9,7.5,0.4,-10.3,9.7,-2.3,-2.4,6.8,-0.5,-6.5,0,0,0},
 | 
|---|
| 350 |         {-2.9,-3.3,2.8,-4.3,-3.1,2.4,2.8,0.7,4.1,3.6,0.6,0,0},
 | 
|---|
| 351 |         {1.7,-1.6,-3.6,1.2,-0.6,0.1,-0.7,-0.8,1.3,-0.3,2.2,4.2,0},
 | 
|---|
| 352 |         {-1.8,0.9,-0.1,-0.5,0.8,0.2,0.5,0.4,-0.4,0.3,0.2,0.4,0.6}};
 | 
|---|
| 353 | static const double hnm_wmm95[13][13] =
 | 
|---|
| 354 |         {
 | 
|---|
| 355 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 356 |         {0,5315.6,0,0,0,0,0,0,0,0,0,0,0},
 | 
|---|
| 357 |         {0,-2359.1,-418.6,0,0,0,0,0,0,0,0,0,0},
 | 
|---|
| 358 |         {0,-261.1,301,-416.5,0,0,0,0,0,0,0,0,0},
 | 
|---|
| 359 |         {0,259.4,-230.9,99.8,-306.1,0,0,0,0,0,0,0,0},
 | 
|---|
| 360 |         {0,43.7,157.6,-150.1,-59.2,104.4,0,0,0,0,0,0,0},
 | 
|---|
| 361 |         {0,-15.2,74.3,69.4,-55.3,3,33.3,0,0,0,0,0,0},
 | 
|---|
| 362 |         {0,-76.1,-24.5,1.6,20,16.5,-23.6,-6.8,0,0,0,0,0},
 | 
|---|
| 363 |         {0,14.9,-19.5,6.3,-20.4,12.2,7,-19,-8.8,0,0,0,0},
 | 
|---|
| 364 |         {0,-19.8,14.6,10.9,-7.5,-6.8,9.3,7.7,-8.1,2.6,0,0,0},
 | 
|---|
| 365 |         {0,3.2,1.7,2.9,5.6,-3.4,-0.7,-2.9,2.3,-1.6,-6.6,0,0},
 | 
|---|
| 366 |         {0,0.3,1,-3.6,-1.4,1.9,0.2,-1.3,-2.4,-0.6,-2.2,1.3,0},
 | 
|---|
| 367 |         {0,0.3,1.4,0.8,-3,0.7,0.5,-0.8,0.6,0.1,-1.3,-0.4,0.9}};
 | 
|---|
| 368 | static const double gtnm_wmm95[13][13] =
 | 
|---|
| 369 |         {
 | 
|---|
| 370 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 371 |         {17.6,13.2,0,0,0,0,0,0,0,0,0,0,0},
 | 
|---|
| 372 |         {-13.7,4,-0.3,0,0,0,0,0,0,0,0,0,0},
 | 
|---|
| 373 |         {0.8,-6.6,-0.5,-8.5,0,0,0,0,0,0,0,0,0},
 | 
|---|
| 374 |         {1.2,1.1,-6.8,0.3,-4.5,0,0,0,0,0,0,0,0},
 | 
|---|
| 375 |         {0.9,0.5,-1.4,-1.7,0,2.1,0,0,0,0,0,0,0},
 | 
|---|
| 376 |         {0.4,-0.3,0.3,2.1,0,-0.4,-0.4,0,0,0,0,0,0},
 | 
|---|
| 377 |         {-0.3,-1.1,-0.5,0.5,1.3,0.1,0,-0.9,0,0,0,0,0},
 | 
|---|
| 378 |         {0.1,0,0.4,0.3,-1.3,0.5,0.4,-0.9,0.1,0,0,0,0},
 | 
|---|
| 379 |         {0,0,0,0,0,0,0,0,0,0,0,0,0},
 | 
|---|
| 380 |         {0,0,0,0,0,0,0,0,0,0,0,0,0},
 | 
|---|
| 381 |         {0,0,0,0,0,0,0,0,0,0,0,0,0},
 | 
|---|
| 382 |         {0,0,0,0,0,0,0,0,0,0,0,0,0}};
 | 
|---|
| 383 | static const double htnm_wmm95[13][13] =
 | 
|---|
| 384 |         {
 | 
|---|
| 385 |         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 | 
|---|
| 386 |         {0,-18,0,0,0,0,0,0,0,0,0,0,0},
 | 
|---|
| 387 |         {0,-14.6,-7.2,0,0,0,0,0,0,0,0,0,0},
 | 
|---|
| 388 |         {0,4,2.2,-12.6,0,0,0,0,0,0,0,0,0},
 | 
|---|
| 389 |         {0,1.3,1,2.5,-1.2,0,0,0,0,0,0,0,0},
 | 
|---|
| 390 |         {0,0.5,1.5,0.6,1.7,0.6,0,0,0,0,0,0,0},
 | 
|---|
| 391 |         {0,0.7,-1.5,-0.5,-0.7,1.1,2.6,0,0,0,0,0,0},
 | 
|---|
| 392 |         {0,0.3,0,0.7,-0.6,0.1,-0.6,-0.4,0,0,0,0,0},
 | 
|---|
| 393 |         {0,0.4,-0.3,0.1,0.8,-0.1,-1.3,-0.9,-1.1,0,0,0,0},
 | 
|---|
| 394 |         {0,0,0,0,0,0,0,0,0,0,0,0,0},
 | 
|---|
| 395 |         {0,0,0,0,0,0,0,0,0,0,0,0,0},
 | 
|---|
| 396 |         {0,0,0,0,0,0,0,0,0,0,0,0,0},
 | 
|---|
| 397 |         {0,0,0,0,0,0,0,0,0,0,0,0,0}};
 | 
|---|
| 398 | 
 | 
|---|
| 399 | static const double gnm_wmm2000[13][13] =
 | 
|---|
| 400 |         {
 | 
|---|
| 401 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 402 |         {-29616.0, -1722.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 403 |         {-2266.7, 3070.2, 1677.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 404 |         {1322.4, -2291.5, 1255.9, 724.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 405 |         {932.1, 786.3, 250.6, -401.5, 106.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 406 |         {-211.9, 351.6, 220.8, -134.5, -168.8, -13.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 407 |         {73.8, 68.2, 74.1, -163.5, -3.8, 17.1, -85.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 408 |         {77.4, -73.9, 2.2, 35.7, 7.3, 5.2, 8.4, -1.5, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 409 |         {23.3, 7.3, -8.5, -6.6, -16.9, 8.6, 4.9, -7.8, -7.6, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 410 |         {5.7, 8.5, 2.0, -9.8, 7.6, -7.0, -2.0, 9.2, -2.2, -6.6, 0.0, 0.0, 0.0},
 | 
|---|
| 411 |         {-2.2, -5.7, 1.6, -3.7, -0.6, 4.1, 2.2, 2.2, 4.6, 2.3, 0.1, 0.0, 0.0},
 | 
|---|
| 412 |         {3.3, -1.1, -2.4, 2.6, -1.3, -1.7, -0.6, 0.4, 0.7, -0.3, 2.3, 4.2, 0.0},
 | 
|---|
| 413 |         {-1.5, -0.2, -0.3, 0.5, 0.2, 0.9, -1.4, 0.6, -0.6, -1.0, -0.3, 0.3, 0.4},
 | 
|---|
| 414 |         };
 | 
|---|
| 415 | 
 | 
|---|
| 416 | static const double hnm_wmm2000[13][13]=
 | 
|---|
| 417 |         {
 | 
|---|
| 418 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 419 |         {0.0, 5194.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 420 |         {0.0, -2484.8, -467.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 421 |         {0.0, -224.7, 293.0, -486.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 422 |         {0.0, 273.3, -227.9, 120.9, -302.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 423 |         {0.0, 42.0, 173.8, -135.0, -38.6, 105.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 424 |         {0.0, -17.4, 61.2, 63.2, -62.9, 0.2, 43.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 425 |         {0.0, -62.3, -24.5, 8.9, 23.4, 15.0, -27.6, -7.8, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 426 |         {0.0, 12.4, -20.8, 8.4, -21.2, 15.5, 9.1, -15.5, -5.4, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 427 |         {0.0, -20.4, 13.9, 12.0, -6.2, -8.6, 9.4, 5.0, -8.4, 3.2, 0.0, 0.0, 0.0},
 | 
|---|
| 428 |         {0.0, 0.9, -0.7, 3.9, 4.8, -5.3, -1.0, -2.4, 1.3, -2.3, -6.4, 0.0, 0.0},
 | 
|---|
| 429 |         {0.0, -1.5, 0.7, -1.1, -2.3, 1.3, -0.6, -2.8, -1.6, -0.1, -1.9, 1.4, 0.0},
 | 
|---|
| 430 |         {0.0, -1.0, 0.7, 2.2, -2.5, -0.2, 0.0, -0.2, 0.0, 0.2, -0.9, -0.2, 1.0},
 | 
|---|
| 431 |         };
 | 
|---|
| 432 | 
 | 
|---|
| 433 | static const double gtnm_wmm2000[13][13]=
 | 
|---|
| 434 |         {
 | 
|---|
| 435 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 436 |         {14.7, 11.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 437 |         {-13.6, -0.7, -1.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 438 |         {0.3, -4.3, 0.9, -8.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 439 |         {-1.6, 0.9, -7.6, 2.2, -3.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 440 |         {-0.9, -0.2, -2.5, -2.7, -0.9, 1.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 441 |         {1.2, 0.2, 1.7, 1.6, -0.1, -0.3, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 442 |         {-0.4, -0.8, -0.2, 1.1, 0.4, 0.0, -0.2, -0.2, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 443 |         {-0.3, 0.6, -0.8, 0.3, -0.2, 0.5, 0.0, -0.6, 0.1, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 444 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 445 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 446 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 447 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 448 |         };
 | 
|---|
| 449 | 
 | 
|---|
| 450 | static const double htnm_wmm2000[13][13]=
 | 
|---|
| 451 |         {
 | 
|---|
| 452 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 453 |         {0.0, -20.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 454 |         {0.0, -21.5, -9.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 455 |         {0.0, 6.4, -1.3, -13.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 456 |         {0.0, 2.3, 0.7, 3.7, -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 457 |         {0.0, 0.0, 2.1, 2.3, 3.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 458 |         {0.0, -0.3, -1.7, -0.9, -1.0, -0.1, 1.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 459 |         {0.0, 1.4, 0.2, 0.7, 0.4, -0.3, -0.8, -0.1, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 460 |         {0.0, -0.5, 0.1, -0.2, 0.0, 0.1, -0.1, 0.3, 0.2, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 461 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 462 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 463 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 464 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 465 |         };
 | 
|---|
| 466 | 
 | 
|---|
| 467 | static const double gnm_igrf2000[13][13] =
 | 
|---|
| 468 |         {
 | 
|---|
| 469 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 470 |         {-29615.0, -1728.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 471 |         {-2267.0, 3072.0, 1672.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 472 |         {1341.0, -2290.0, 1253.0, 715.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 473 |         {935.0, 787.0, 251.0, -405.0, 110.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 474 |         {-217.0, 351.0, 222.0, -131.0, -169.0, -12.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 475 |         {72.0, 68.0, 74.0, -161.0, -5.0, 17.0, -91.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 476 |         {79.0, -74.0, 0.0, 33.0, 9.0, 7.0, 8.0, -2.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 477 |         {25.0, 6.0, -9.0, -8.0, -17.0, 9.0, 7.0, -8.0, -7.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 478 |         {5.0, 9.0, 3.0, -8.0, 6.0, -9.0, -2.0, 9.0, -4.0, -8.0, 0.0, 0.0, 0.0},
 | 
|---|
| 479 |         {-2.0, -6.0, 2.0, -3.0, 0.0, 4.0, 1.0, 2.0, 4.0, 0.0, -1.0, 0.0, 0.0},
 | 
|---|
| 480 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 481 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 482 |         };
 | 
|---|
| 483 | 
 | 
|---|
| 484 | static const double hnm_igrf2000[13][13]=
 | 
|---|
| 485 |         {
 | 
|---|
| 486 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 487 |         {0.0, 5186.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 488 |         {0.0, -2478.0, -458.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 489 |         {0.0, -227.0, 296.0, -492.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 490 |         {0.0, 272.0, -232.0, 119.0, -304.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 491 |         {0.0, 44.0, 172.0, -134.0, -40.0, 107.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 492 |         {0.0, -17.0, 64.0, 65.0, -61.0, 1.0, 44.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 493 |         {0.0, -65.0, -24.0, 6.0, 24.0, 15.0, -25.0, -6.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 494 |         {0.0, 12.0, -22.0, 8.0, -21.0, 15.0, 9.0, -16.0, -3.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 495 |         {0.0, -20.0, 13.0, 12.0, -6.0, -8.0, 9.0, 4.0, -8.0, 5.0, 0.0, 0.0, 0.0},
 | 
|---|
| 496 |         {0.0, 1.0, 0.0, 4.0, 5.0, -6.0, -1.0, -3.0, 0.0, -2.0, -8.0, 0.0, 0.0},
 | 
|---|
| 497 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 498 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 499 |         };
 | 
|---|
| 500 | 
 | 
|---|
| 501 | static const double gtnm_igrf2000[13][13]=
 | 
|---|
| 502 |         {
 | 
|---|
| 503 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 504 |         {14.6, 10.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 505 |         {-12.4, 1.1, -1.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 506 |         {0.7, -5.4, 0.9, -7.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 507 |         {-1.3, 1.6, -7.3, 2.9, -3.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 508 |         {0.0, -0.7, -2.1, -2.8, -0.8, 2.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 509 |         {1.0, -0.4, 0.9, 2.0, -0.6, -0.3, 1.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 510 |         {-0.4, -0.4, -0.3, 1.1, 1.1, -0.2, 0.6, -0.9, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 511 |         {-0.3, 0.2, -0.3, 0.4, -1.0, 0.3, -0.5, -0.7, -0.4, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 512 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 513 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 514 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 515 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 516 |         };
 | 
|---|
| 517 | 
 | 
|---|
| 518 | static const double htnm_igrf2000[13][13]=
 | 
|---|
| 519 |         {
 | 
|---|
| 520 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 521 |         {0.0, -22.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 522 |         {0.0, -20.6, -9.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 523 |         {0.0, 6.0, -0.1, -14.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 524 |         {0.0, 2.1, 1.3, 5.0, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 525 |         {0.0, -0.1, 0.6, 1.7, 1.9, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 526 |         {0.0, -0.2, -1.4, 0.0, -0.8, 0.0, 0.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 527 |         {0.0, 1.1, 0.0, 0.3, -0.1, -0.6, -0.7, 0.2, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 528 |         {0.0, 0.1, 0.0, 0.0, 0.3, 0.6, -0.4, 0.3, 0.7, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 529 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 530 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 531 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 532 |         {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 | 
|---|
| 533 |         };
 | 
|---|
| 534 | 
 | 
|---|
| 535 | 
 | 
|---|
| 536 | 
 | 
|---|
| 537 | static const int nmax = 12;
 | 
|---|
| 538 | 
 | 
|---|
| 539 | double P[13][13];
 | 
|---|
| 540 | double DP[13][13];
 | 
|---|
| 541 | double gnm[13][13];
 | 
|---|
| 542 | double hnm[13][13];
 | 
|---|
| 543 | double sm[13];
 | 
|---|
| 544 | double cm[13];
 | 
|---|
| 545 | 
 | 
|---|
| 546 | static double root[13];
 | 
|---|
| 547 | static double roots[13][13][2];
 | 
|---|
| 548 | 
 | 
|---|
| 549 | /* Convert date to Julian day    1950-2049 */
 | 
|---|
| 550 | unsigned long int yymmdd_to_julian_days(int yy,int mm,int dd)
 | 
|---|
| 551 | {
 | 
|---|
| 552 |   unsigned long jd;
 | 
|---|
| 553 |  
 | 
|---|
| 554 |   yy = (yy < 50) ? (2000 + yy) : (1900 + yy);
 | 
|---|
| 555 |   jd = dd - 32075L + 1461L * (yy + 4800L + (mm - 14) / 12 ) / 4;
 | 
|---|
| 556 |   jd = jd + 367L * (mm - 2 - (mm - 14) / 12*12) / 12;
 | 
|---|
| 557 |   jd = jd - 3 * ((yy + 4900L + (mm - 14) / 12) / 100) / 4;
 | 
|---|
| 558 | 
 | 
|---|
| 559 |   return(jd);
 | 
|---|
| 560 | } 
 | 
|---|
| 561 | 
 | 
|---|
| 562 | /* Convert degrees to radians */
 | 
|---|
| 563 | double deg_to_rad(double deg)
 | 
|---|
| 564 | {
 | 
|---|
| 565 | return deg*pi/180.;
 | 
|---|
| 566 | }
 | 
|---|
| 567 | 
 | 
|---|
| 568 | /* Convert radians to degrees */
 | 
|---|
| 569 | double rad_to_deg(double rad)
 | 
|---|
| 570 | {
 | 
|---|
| 571 | return rad*180./pi;
 | 
|---|
| 572 | }
 | 
|---|
| 573 |              
 | 
|---|
| 574 | 
 | 
|---|
| 575 | 
 | 
|---|
| 576 | 
 | 
|---|
| 577 | /* 
 | 
|---|
| 578 |  * return variation (in radians) given geodetic latitude (radians), longitude
 | 
|---|
| 579 |  * (radians) ,height (km) and (Julian) date
 | 
|---|
| 580 |  * model=1 is IGRF90, 2 is WMM85, 3 is WMM90, 4 is WMM95, 
 | 
|---|
| 581 |  * 5 is IGRF95, 6 is WMM2000, 7 is IGRF2000
 | 
|---|
| 582 |  * N and E lat and long are positive, S and W negative
 | 
|---|
| 583 | */
 | 
|---|
| 584 | 
 | 
|---|
| 585 | double SGMagVar( double lat, double lon, double h, long dat, int model, double* field )
 | 
|---|
| 586 | {
 | 
|---|
| 587 |     /* output field B_r,B_th,B_phi,B_x,B_y,B_z */
 | 
|---|
| 588 |     int n,m;
 | 
|---|
| 589 |     double yearfrac,sr,r,theta,c,s,psi,fn,fn_0,B_r,B_theta,B_phi,X,Y,Z;
 | 
|---|
| 590 |     double sinpsi, cospsi, inv_s;
 | 
|---|
| 591 | 
 | 
|---|
| 592 |     static int been_here = 0;
 | 
|---|
| 593 |         
 | 
|---|
| 594 |     double sinlat = sin(lat);
 | 
|---|
| 595 |     double coslat = cos(lat);
 | 
|---|
| 596 | 
 | 
|---|
| 597 |     /* convert to geocentric */ 
 | 
|---|
| 598 |     sr = sqrt(a*a*coslat*coslat + b*b*sinlat*sinlat);
 | 
|---|
| 599 |     /* sr is effective radius */
 | 
|---|
| 600 |     theta = atan2(coslat * (h*sr + a*a), sinlat * (h*sr + b*b));
 | 
|---|
| 601 |                   
 | 
|---|
| 602 |     /* theta is geocentric co-latitude */
 | 
|---|
| 603 | 
 | 
|---|
| 604 |     r = h*h + 2.0*h * sr +
 | 
|---|
| 605 |         (a*a*a*a - ( a*a*a*a - b*b*b*b ) * sinlat*sinlat ) / 
 | 
|---|
| 606 |         (a*a - (a*a - b*b) * sinlat*sinlat );
 | 
|---|
| 607 | 
 | 
|---|
| 608 |     r = sqrt(r);
 | 
|---|
| 609 | 
 | 
|---|
| 610 |     /* r is geocentric radial distance */
 | 
|---|
| 611 |     c = cos(theta);
 | 
|---|
| 612 |     s = sin(theta);
 | 
|---|
| 613 |       /* protect against zero divide at geographic poles */
 | 
|---|
| 614 |     inv_s =  1.0 / (s + (s == 0.)*1.0e-8); 
 | 
|---|
| 615 | 
 | 
|---|
| 616 |     /*zero out arrays */
 | 
|---|
| 617 |     for ( n = 0; n <= nmax; n++ ) {
 | 
|---|
| 618 |       for ( m = 0; m <= n; m++ ) {
 | 
|---|
| 619 |         P[n][m] = 0;
 | 
|---|
| 620 |         DP[n][m] = 0;
 | 
|---|
| 621 |       }
 | 
|---|
| 622 |     }
 | 
|---|
| 623 | 
 | 
|---|
| 624 |     /* diagonal elements */
 | 
|---|
| 625 |     P[0][0] = 1;
 | 
|---|
| 626 |     P[1][1] = s;
 | 
|---|
| 627 |     DP[0][0] = 0;
 | 
|---|
| 628 |     DP[1][1] = c;
 | 
|---|
| 629 |     P[1][0] = c ;
 | 
|---|
| 630 |     DP[1][0] = -s;
 | 
|---|
| 631 | 
 | 
|---|
| 632 |     /* these values will not change for subsequent function calls */
 | 
|---|
| 633 |     if( !been_here ) {
 | 
|---|
| 634 |       for ( n = 2; n <= nmax; n++ ) {
 | 
|---|
| 635 |         root[n] = sqrt((2.0*n-1) / (2.0*n));
 | 
|---|
| 636 |       }
 | 
|---|
| 637 |         
 | 
|---|
| 638 |       for ( m = 0; m <= nmax; m++ ) {
 | 
|---|
| 639 |         double mm = m*m;
 | 
|---|
| 640 |         for ( n = max(m + 1, 2); n <= nmax; n++ ) {
 | 
|---|
| 641 |           roots[m][n][0] = sqrt((n-1)*(n-1) - mm);
 | 
|---|
| 642 |           roots[m][n][1] = 1.0 / sqrt( n*n - mm);
 | 
|---|
| 643 |         }
 | 
|---|
| 644 |       }
 | 
|---|
| 645 |       been_here = 1;
 | 
|---|
| 646 |     }
 | 
|---|
| 647 |         
 | 
|---|
| 648 |     for ( n=2; n <= nmax; n++ ) {
 | 
|---|
| 649 |       /*  double root = sqrt((2.0*n-1) / (2.0*n)); */
 | 
|---|
| 650 |       P[n][n] = P[n-1][n-1] * s * root[n];
 | 
|---|
| 651 |       DP[n][n] = (DP[n-1][n-1] * s + P[n-1][n-1] * c) * root[n];
 | 
|---|
| 652 |     }
 | 
|---|
| 653 | 
 | 
|---|
| 654 |     /* lower triangle */
 | 
|---|
| 655 |     for ( m = 0; m <= nmax; m++ ) {
 | 
|---|
| 656 |       /*  double mm = m*m;  */
 | 
|---|
| 657 |       for ( n = max(m + 1, 2); n <= nmax; n++ ) {
 | 
|---|
| 658 |         /* double root1 = sqrt((n-1)*(n-1) - mm); */
 | 
|---|
| 659 |         /* double root2 = 1.0 / sqrt( n*n - mm);  */
 | 
|---|
| 660 |         P[n][m] = (P[n-1][m] * c * (2.0*n-1) -
 | 
|---|
| 661 |                    P[n-2][m] * roots[m][n][0]) * roots[m][n][1];
 | 
|---|
| 662 |         DP[n][m] = ((DP[n-1][m] * c - P[n-1][m] * s) *
 | 
|---|
| 663 |                     (2.0*n-1) - DP[n-2][m] * roots[m][n][0]) * roots[m][n][1];
 | 
|---|
| 664 |       }
 | 
|---|
| 665 |     }
 | 
|---|
| 666 | 
 | 
|---|
| 667 |     /* compute gnm, hnm at dat */
 | 
|---|
| 668 |     switch(model) {
 | 
|---|
| 669 |     case 1:     /* IGRF90 */
 | 
|---|
| 670 |       yearfrac = (dat - yymmdd_to_julian_days(90,1,1)) / 365.25;
 | 
|---|
| 671 |       for (n=1;n<=nmax;n++)
 | 
|---|
| 672 |         for (m = 0;m<=nmax;m++) {
 | 
|---|
| 673 |           gnm[n][m] = gnm_igrf90[n][m] + yearfrac * gtnm_igrf90[n][m];
 | 
|---|
| 674 |           hnm[n][m] = hnm_igrf90[n][m] + yearfrac * htnm_igrf90[n][m];
 | 
|---|
| 675 |         }
 | 
|---|
| 676 |       break;
 | 
|---|
| 677 | 
 | 
|---|
| 678 |     case 2:     /* WMM85 */
 | 
|---|
| 679 |       yearfrac = (dat - yymmdd_to_julian_days(85,1,1)) / 365.25;
 | 
|---|
| 680 |       for (n=1;n<=nmax;n++)
 | 
|---|
| 681 |         for (m = 0;m<=nmax;m++) {
 | 
|---|
| 682 |           gnm[n][m] = gnm_wmm85[n][m] + yearfrac * gtnm_wmm85[n][m];
 | 
|---|
| 683 |           hnm[n][m] = hnm_wmm85[n][m] + yearfrac * htnm_wmm85[n][m];
 | 
|---|
| 684 |         }
 | 
|---|
| 685 |       break;
 | 
|---|
| 686 | 
 | 
|---|
| 687 |     case 3:     /* WMM90 */
 | 
|---|
| 688 |       yearfrac = (dat - yymmdd_to_julian_days(90,1,1)) / 365.25;
 | 
|---|
| 689 |       for (n=1;n<=nmax;n++)
 | 
|---|
| 690 |         for (m = 0;m<=nmax;m++) {
 | 
|---|
| 691 |           gnm[n][m] = gnm_wmm90[n][m] + yearfrac * gtnm_wmm90[n][m];
 | 
|---|
| 692 |           hnm[n][m] = hnm_wmm90[n][m] + yearfrac * htnm_wmm90[n][m];
 | 
|---|
| 693 |         }
 | 
|---|
| 694 |       break;
 | 
|---|
| 695 | 
 | 
|---|
| 696 |     case 4:     /* WMM95 */
 | 
|---|
| 697 |       yearfrac = (dat - yymmdd_to_julian_days(95,1,1)) / 365.25;
 | 
|---|
| 698 |       for (n=1;n<=nmax;n++)
 | 
|---|
| 699 |         for (m = 0;m<=nmax;m++) {
 | 
|---|
| 700 |            gnm[n][m] = gnm_wmm95[n][m] + yearfrac * gtnm_wmm95[n][m];
 | 
|---|
| 701 |            hnm[n][m] = hnm_wmm95[n][m] + yearfrac * htnm_wmm95[n][m];
 | 
|---|
| 702 |         }
 | 
|---|
| 703 |       break;
 | 
|---|
| 704 |     case 5:     /* IGRF95 */
 | 
|---|
| 705 |       yearfrac = (dat - yymmdd_to_julian_days(95,1,1)) / 365.25;
 | 
|---|
| 706 |       for (n=1;n<=nmax;n++)
 | 
|---|
| 707 |         for (m = 0;m<=nmax;m++) {
 | 
|---|
| 708 |            gnm[n][m] = gnm_igrf95[n][m] + yearfrac * gtnm_igrf95[n][m];
 | 
|---|
| 709 |            hnm[n][m] = hnm_igrf95[n][m] + yearfrac * htnm_igrf95[n][m];
 | 
|---|
| 710 |         }
 | 
|---|
| 711 |       break;
 | 
|---|
| 712 |     case 6:      /* WMM2000 */
 | 
|---|
| 713 |       yearfrac = (dat - yymmdd_to_julian_days(0,1,1)) / 365.25;
 | 
|---|
| 714 |        for (n=1;n<=nmax;n++)
 | 
|---|
| 715 |          for (m = 0;m<=nmax;m++) {
 | 
|---|
| 716 |            gnm[n][m] = gnm_wmm2000[n][m] + yearfrac * gtnm_wmm2000[n][m];
 | 
|---|
| 717 |            hnm[n][m] = hnm_wmm2000[n][m] + yearfrac * htnm_wmm2000[n][m];
 | 
|---|
| 718 |          }
 | 
|---|
| 719 |        break;
 | 
|---|
| 720 |     case 7:      /* IGRF2000 */
 | 
|---|
| 721 |       yearfrac = (dat - yymmdd_to_julian_days(0,1,1)) / 365.25;
 | 
|---|
| 722 |       for (n=1;n<=nmax;n++)
 | 
|---|
| 723 |         for (m = 0;m<=nmax;m++) {
 | 
|---|
| 724 |           gnm[n][m] = gnm_igrf2000[n][m] + yearfrac * gtnm_igrf2000[n][m];
 | 
|---|
| 725 |           hnm[n][m] = hnm_igrf2000[n][m] + yearfrac * htnm_igrf2000[n][m];
 | 
|---|
| 726 |         }
 | 
|---|
| 727 |       break;  
 | 
|---|
| 728 |     }
 | 
|---|
| 729 | 
 | 
|---|
| 730 |     /* compute sm (sin(m lon) and cm (cos(m lon)) */
 | 
|---|
| 731 |     for (m = 0;m<=nmax;m++) {
 | 
|---|
| 732 |       sm[m] = sin(m * lon);
 | 
|---|
| 733 |       cm[m] = cos(m * lon);
 | 
|---|
| 734 |     }
 | 
|---|
| 735 | 
 | 
|---|
| 736 |     /* compute B fields */
 | 
|---|
| 737 |     B_r = 0.0;
 | 
|---|
| 738 |     B_theta = 0.0;
 | 
|---|
| 739 |     B_phi = 0.0;
 | 
|---|
| 740 |     fn_0 = r_0/r;
 | 
|---|
| 741 |     fn = fn_0 * fn_0;
 | 
|---|
| 742 |         
 | 
|---|
| 743 |     for ( n = 1; n <= nmax; n++ ) {
 | 
|---|
| 744 |       double c1_n=0;
 | 
|---|
| 745 |       double c2_n=0;
 | 
|---|
| 746 |       double c3_n=0;
 | 
|---|
| 747 |       for ( m = 0; m <= n; m++ ) {
 | 
|---|
| 748 |         double tmp = (gnm[n][m] * cm[m] + hnm[n][m] * sm[m]); 
 | 
|---|
| 749 |         c1_n += tmp * P[n][m];
 | 
|---|
| 750 |         c2_n += tmp * DP[n][m];
 | 
|---|
| 751 |         c3_n +=  m * (gnm[n][m] * sm[m] - hnm[n][m] * cm[m]) * P[n][m];
 | 
|---|
| 752 |       }
 | 
|---|
| 753 |       /* fn=pow(r_0/r,n+2.0);   */
 | 
|---|
| 754 |       fn *= fn_0;
 | 
|---|
| 755 |       B_r += (n + 1) * c1_n * fn;
 | 
|---|
| 756 |       B_theta -= c2_n * fn;
 | 
|---|
| 757 |       B_phi += c3_n * fn * inv_s;
 | 
|---|
| 758 |     }
 | 
|---|
| 759 | 
 | 
|---|
| 760 | 
 | 
|---|
| 761 | 
 | 
|---|
| 762 |     /* Find geodetic field components: */
 | 
|---|
| 763 |     psi = theta - (pi / 2.0 - lat);
 | 
|---|
| 764 |     sinpsi = sin(psi);
 | 
|---|
| 765 |     cospsi = cos(psi);
 | 
|---|
| 766 |     X = -B_theta * cospsi - B_r * sinpsi;
 | 
|---|
| 767 |     Y = B_phi;
 | 
|---|
| 768 |     Z = B_theta * sinpsi - B_r * cospsi;
 | 
|---|
| 769 | 
 | 
|---|
| 770 |     field[0]=B_r;
 | 
|---|
| 771 |     field[1]=B_theta;
 | 
|---|
| 772 |     field[2]=B_phi;
 | 
|---|
| 773 |     field[3]=X;
 | 
|---|
| 774 |     field[4]=Y;
 | 
|---|
| 775 |     field[5]=Z;   /* output fields */
 | 
|---|
| 776 |     /* find variation in radians */
 | 
|---|
| 777 |     /* return zero variation at magnetic pole X=Y=0. */
 | 
|---|
| 778 |     /* E is positive */
 | 
|---|
| 779 |     return (X != 0. || Y != 0.) ? atan2(Y, X) : (double) 0.; 
 | 
|---|
| 780 | }
 | 
|---|
| 781 | 
 | 
|---|