/**********************/ /*** igrf.c ***/ /****************************************************************************/ /* Usage from FORTRAN : ( All variables are in single precision ) */ /* First specify the Generation Number with the Year of Calc. */ /* by CALL gigrf(NGEN, YEAR), */ /* or specify the Model Type (IGRF/DGRF/PGRF) with the Year of Calc. */ /* by CALL sigrf(YEAR), CALL sdgrf(YEAR) or CALL spgrf(YEAR) . */ /* Then, CALL igrfc(FI, FK, H, F) gives TotalForce (F) of that model */ /* at the point of Lat.=FI, Long.=FK, Alt.=H */ /* If other components are desired, CALL igrfm(FM) . */ /* Here FM is an array with 6 elements, which correspond to */ /* North(X), East(Y), Downward(Z), Horizontal(H) components, */ /* Inclination(I) and Declination(D). */ /* Unit Convention: Lat.(FI), Long.(FK), Inc.(I), Dec.(D) are in degrees, */ /* Mag.Fields(F,X,Y,Z,H) in nT, and Alt.(H) in meters. */ /****************************************************************************/ /* Prototype definition for C : */ /*--------------------------------------------------------------------------*/ /* < Conventional Functions and their FORTRAN Interfaces > */ /*--------------------------------------------------------------------------*/ /* void sigrf(double year); | void sigrf_(float *year); */ /* / void sdgrf(double year); | / void sdgrf_(float *year); */ /* / void spgrf(double year); | / void spgrf_(float *year); */ /* void gigrf(int gen, double year);| void gigrf_(int *gen, float *year); */ /* void igrfc(double fi, double fk, | void igrfc_(float *fi, float *fk, */ /* double h, double *f); | float *h, float *f); */ /* void igrfm(double fm[6]); | void igrfm_(float fm[6]); */ /*--------------------------------------------------------------------------*/ /* < Substantial Calculation Functions > */ /*--------------------------------------------------------------------------*/ /* void field(double are, double aflat, double ara, int maxoda); */ /* void tcoef(double agh[MxOD+1][MxOD+1], double aght[MxOD+1][MxOD+1], */ /* double atzero, int kexta, double aext[3]); */ /* void tyear(double ayear); */ /* void mfldg(double alat, double alon, double ahi, */ /* double *ax, double *ay, double *az, double *af); */ /* void mfldc(double athe, double alon, double ar, */ /* double *ax, double *ay, double *az, double *af); */ /* void gcomp(double *axg, double *ayg, double *azg); */ /****************************************************************************/ #include #include #include #include /*--------------------*/ /* Basic Routines */ /*--------------------*/ #define MxOD 19 #define URAD (180./3.14159265359) #define COEFPATH "/home/SHARE/data/IGRFCOEF/" static double ra, rpre, re, re2, re4, rp, rp2, rp4, tzero; static int maxod, kg, kgc, kr, kth, kph, kext; static double blat, blon, bhi, br, bthe, bthc; static double rlat, slat, slat2, clat, clat2; static double r, the, phi, cth, sth, cph, sph; static double x, y, z, f, ext0, ext1, ext2; static double gh[MxOD+1][MxOD+1], ght[MxOD+1][MxOD+1], g[MxOD+1][MxOD+1]; static double rar[MxOD+1], csp[MxOD+1], snp[MxOD+1], p[MxOD+2][MxOD+1]; static double vgh[MxOD+1][MxOD+1], vght[MxOD+1][MxOD+1]; static void fcalc(void) /* This is an internal function */ { double t, pn1m, tx, ty, tz; int n, m; if (kr != 0) { kr=0; t=ra/r; rar[0]=t*t; for (n=0; n 1.5e-9) { rc=r*cth; rs=r*sth; rep2=re2-rp2; tlat=slat/clat; tlat2=tlat*tlat; rlat=atan(tlat); do {rlatp=rlat; rmc2=re2+rp2*tlat2; rmc=sqrt(rmc2); rmc3=rmc2*rmc; ffp=rp2*rep2*tlat/rmc3+rc/tlat2; ff=rep2/rmc+rc/tlat-rs; tlat+=ff/ffp; tlat2=tlat*tlat; rlat=atan(tlat); } while (fabs(rlat-rlatp) > 1.5e-9); clat2=1./(1.+tlat2); clat=sqrt(clat2); slat=tlat*clat; } } cga=cth*slat+sth*clat; sga=cth*clat-sth*slat; xg=x*cga-z*sga; zg=x*sga+z*cga; *axg=xg; *ayg=y; *azg=zg; } /*---------------------------*/ /* Conventional Routines */ /*---------------------------*/ #define MxGEN 10 #define RAD (180./3.14159265359) #define MxMOD 19 #define MxELM ((MxMOD+1)*(MxMOD+1)-1) #define MxCOL 50 #define LLINE (MxCOL*9 + 10) void gigrf(int gen, double year) { int maxod, i, n, m, l, k, ncol, nlin; double y1, y2, yr1, yr2, dy; double tzero, dmy[3], cb[MxELM], cv[MxELM]; char file[] = COEFPATH "igrf00.coef"; char *pgen, *line, buf[LLINE]; FILE *fp; if ((gen<1) || (MxGENMxMOD) || (ncol<2) || (ncol>MxCOL)) { fprintf(stderr, "gigrf: Line-1 invalid\n"); exit(1); } nlin = (maxod+1)*(maxod+1) - 1; if ((yeary2)) fprintf(stderr, "gigrf: IGRF-%02d not defined for %9.3lf\n", gen,year); if (fgets(buf,LLINE,fp) == NULL) { fprintf(stderr, "gigrf: EOF before Line-2\n"); exit(1); } line = &buf[1]; if (sscanf(line,"%*c%*d%*d%lf%n",&yr2,&n) == EOF) { fprintf(stderr, "gigrf: Line-2 invalid\n"); exit(1); } for (l=2; l= 7) l=6; if (l < 2) maxod=8; else maxod=10; tzero=(double)(l*5 + 1970); if (l==0) tzero=1965.; if ((year<1955.) || (year>2005.)) fprintf(stderr, "sigrf: IGRF not available for %8.3lf\n", year); for (i=0,n=1; n<=maxod; n++) { vgh[0][n]=rf[l][i]; if (n<=8) vght[0][n]=sv[l][i]; else vght[0][n]=0.; i++; for (m=1; m<=n; m++) { vgh[m][n]=rf[l][i]; if (n<=8) vght[m][n]=sv[l][i]; else vght[m][n]=0.; i++; vgh[n][m-1]=rf[l][i]; if (n<=8) vght[n][m-1]=sv[l][i]; else vght[n][m-1]=0.; i++; } } field(6378.16, 298.25, 6371.2, maxod); tcoef(vgh, vght, tzero, 0, dmy); tyear(year); } void sdgrf(double year) { int i, n, m, l; double dmy[3]; l=(int)(year-1945.)/5; if (l < 0) l=0; else if (l >= 9) l=8; if ((year<1945.) || (year>1990.)) fprintf(stderr, "sdgrf: DGRF not available for %8.3lf\n", year); for (i=0,n=1; n<=10; n++) { vgh[0][n]=df[l][i]; vght[0][n]=(df[l+1][i]-df[l][i])/5.; i++; for (m=1; m<=n; m++) { vgh[m][n]=df[l][i]; vght[m][n]=(df[l+1][i]-df[l][i])/5.; i++; vgh[n][m-1]=df[l][i]; vght[n][m-1]=(df[l+1][i]-df[l][i])/5.; i++; } } field(6378.16, 298.25, 6371.2, 10); tcoef(vgh, vght, (double)(1945+l*5), 0, dmy); tyear(year); } void spgrf(double year) { int i, n, m, l; double dmy[3]; l=(int)(year-1945.)/5; if (l < 6) l=6; else if (l >= 10) l=9; if ((year<1975.) || (year>1995.)) fprintf(stderr, "spgrf: PGRF not available for %8.3lf\n", year); for (i=0,n=1; n<=10; n++) { vgh[0][n]=df[l][i]; vght[0][n]=(rf[l-4][i]-df[l][i])/5.; i++; for (m=1; m<=n; m++) { vgh[m][n]=df[l][i]; vght[m][n]=(rf[l-4][i]-df[l][i])/5.; i++; vgh[n][m-1]=df[l][i]; vght[n][m-1]=(rf[l-4][i]-df[l][i])/5.; i++; } } field(6378.16, 298.25, 6371.2, 10); tcoef(vgh, vght, (double)(1945+l*5), 0, dmy); tyear(year); } /*------------------------*/ /* FORTRAN Interfaces */ /*------------------------*/ void gigrf_(int *gen, float *year) { gigrf(*gen, (double)*year); } void igrfc_(float *fi, float *fk, float *h, float *f) { double df; igrfc((double)*fi,(double)*fk,(double)*h,&df); *f=df; } void igrfm_(float fm[6]) { double dfm[6]; int i; igrfm(dfm); for (i=0; i<6; i++) fm[i]=dfm[i]; } void sigrf_(float *year) { sigrf((double)*year); } void sdgrf_(float *year) { sdgrf((double)*year); } void spgrf_(float *year) { spgrf((double)*year); } void tyear_(float *year) { tyear((double)*year); }