dgrf15.f 11.6 KB
      subroutine dgrf15 (year,rre,thet,phi,br,bt,bp,bb,ier)
c*
c***********************************************************************
c*
c*          "Copyright [c] CNES 98 - tous droits reserves"
c*          **********************************************
c*
c*PRO MAGLIB
c*
c*VER 17.02.23 - V 1.0
c*VER 20.07.07 - V 2.0
c*
c*AUT spec. CNES - JC KOSIK - fevrier 2001
c*AUT port. AKKA
c*
c*ROL         Calcul du champ magnetique d'origine interne avec les
c*ROL         coefficients definitifs du modele IGRF-13.
c*
c*PAR year (I) : annee fractionnaire (>= 2015.)
c*
c*PAR rre  (I) : distance radiale geocentrique (rayons terrestres)
c*PAR thet (I) : colatitude geocentrique (radians)
c*PAR phi  (I) : longitude geocentrique (radians)
c*
c*PAR br   (O) : composante radiale du champ magnetique le long du
c*             : meridien positive vers l'exterieur (gauss)
c*PAR bt   (O) : composante tangentielle du champ magnetique le long
c*PAR          : du meridien positive vers le sud (gauss)
c*PAR bp   (O) : composante azimuthale du champ magnetique, positive
c*PAR          : vers l'est (gauss)
c*
c*PAR bb   (O) : module du champ magnetique (gauss)
c*
c*PAR ier  (O) : code de retour
c*
c*NOT ier      : sans objet
c*
c*NOT Dans le cas ou l'angle thet est nul, son sinus est
c*NOT remplacee par 1.d-15 afin d'eviter des divisions par 0 et
c*NOT son cosinus est remplace par 1.0d0.
c*NOT Dans le cas ou l'angle thet est egal a pi, son sinus est
c*NOT remplacee par 1.d-15 afin d'eviter des divisions par 0 et
c*NOT son cosinus est remplace par -1.0d0.
c*
c*NOT common   : util, util2
c*
c*INF utilise  : sans objet
c*
c*HST version 1.0 - 17.02.23 - Coefficients de Schmidt et variations
c*HST                          seculaires provisoires 2015
c*HST version 2.0 - 20.07.07 - Coefficients de Schmidt definitifs
c*HST                          variations seculaires interpolées 2020
c*
c***********************************************************************
c*
      implicit none
c
c     ---------------------------------
c*FON Declaration identificateur rcs_id
c     ---------------------------------
c
      character rcs_id*100
c
c     --------------------------
c*FON Declaration des parametres
c     --------------------------
c
      double precision year, rre, thet, phi
      double precision br, bt, bp, bb
      integer ier
c
c     ----------------------------------
c*FON Declaration des variables communes
c     ----------------------------------
c
      double precision pi,dpi,rad,deg,pid,xmu,rayt
c
c*COM pi   : constante pi (obtenue a partir de acos(-1.))
c*COM dpi  : constante 2 * pi
c*COM pid  : constante pi / 2
c*COM rad  : facteur de conversion degres  ----> radians
c*COM deg  : facteur de conversion radians ----> degres
c*COM xmu  : constante de gravitation terrestre (km**3/sec**2)
c*COM rayt : rayon equatorial terrestre (km)
c
      common/util/pi,dpi,rad,deg,pid,xmu,rayt
c
      double precision rgmt
c
c*COM rgmt : rayon geocentrique terrestre (km)
c
      common/util2/rgmt
c
c     ---------------------------------
c*FON Declaration des variables locales
c     ---------------------------------
c
      integer lg(14,14),lgt(14,14)
c*LOC lg, lgt : coefficients du modele igrf 2015
c
      integer kmax
c*LOC kmax : nombre de pas de calcul (= 14)
c
      integer n,m,jj
c*LOC n,m,jj : indices de boucles et de tableaux
c
      double precision gg(14,14),ggt(14,14)
      double precision shmit(14,14)
      double precision g(14,14)
      double precision const(14,14),fn(14),fm(14)
      double precision p(14,14),dp(14,14),sp(14),cp(14)
      double precision tmold,tzero,sph,st,t,temp,par,f2
      double precision cph,ct,f1,aor,ar,rrmag
c*LOC Variables de travail intermediaires
c
      SAVE
c
c     ---------------------------------
c*FON Affectation identificateur rcs_id
c     ---------------------------------
c
      data rcs_id /"
     >$Id$"/
c
c     --------------------------
c*FON Affectation des constantes
c     --------------------------
c
c     Revision février 2017- coefficients lg et lgt
c
      data lg/100,
     > -2944146,-244588,135033,90742,-23291,6955,8129,2398,533,-201,300,
     > -209,-2,
     >  479599,-150177,301220,-235226,81368,36014,6757,-7599,889,883,
     > -626,-140,-16,-92,
     > -284541,-64217,167635,122585,12049,19235,7279,-679,-1678,302,17,
     > -230,46,42,
     > -11529,24504,-53870,58169,-33485,-14094,-12985,5182,-316,-322,55,
     >  208,123,63,
     >  28354,-18843,18095,-32923,7038,-15740,-2893,1507,-2056,67,-55,
     > -79,-89,-42,
     >  4698,19698,-11914,1598,10012,430,1314,932,1333,-1320,170,58,85,
     >  96,
     > -2061,3330,5874,-6664,735,6241,-7085,-288,1176,-10,-67,-70,10,
     > -19,
     > -5427,-1953,559,2445,327,-2750,-232,661,-1598,868,213,14,54,81,
     >  1004,-1826,1318,-1460,1616,569,-910,226,-202,-906,233,170,-37,
     > -13,
     > -2177,1076,1174,-674,-688,779,104,-389,844,-1054,-180,-22,-43,38,
     >  328,-40,455,440,-792,-61,-416,-285,-112,-872,-359,44,22,8,
     >  0,211,-60,-105,76,-20,-212,-144,-257,-201,-234,349,-94,46,
     > -108,37,175,-219,27,72,-9,29,23,-89,-16,72,-3,-35,
     > -88,49,156,-50,-124,-10,42,-4,48,48,-30,-43,-71,-36
     > /
c
       data lgt/1000,
     >  7332,-10744,2574,-884,-278,-710,-138,-56,-66,22,0,18,24,
     > -28698,10174,-6040,-5788,-836,612,-414,-142,162,-86,12,0,12,4,
     > -29238,-18486,130,2070,-6838,-910,22,-282,-164,-24,-54,-40,8,16,
     >  6638,-628,-940,-11198,5090,48,1670,936,532,344,230,44,14,14,
     > -328,6006,3750,-4094,-4476,1240,-1454,146,-108,-354,-70,-22,-62,
     >  24,
     >  144,2264,-412,3264,-244,1840,72,-584,394,0,-200,-56,-30,-32,
     >  302,-1640,-1188,428,310,1138,1230,-864,388,240,-46,0,40,38,
     >  554,526,-678,-190,-1094,60,104,638,-104,24,-46,-48,-8,-2,
     > -328,592,-76,580,-252,-418,440,108,344,-48,-186,-60,14,26,
     > -326,48,-388,328,116,2,-128,498,232,-272,-120,-76,-14,4,
     >  24,40,-190,80,-136,102,-28,-110,204,-16,-42,-48,-24,4,
     >  0,78,0,130,-32,0,84,-32,-86,2,-52,-78,-32,8,
     > -24,26,-70,78,-34,16,-22,62,-6,-2,32,-44,-54,-30,
     > -4,22,-32,20,-12,0,-24,-12,4,4,-20,6,22,-8
     > /
c
      data f1 /10.d0/, f2 /10.d0/
c
      data kmax /14/
c
      data p(1,1)  /1.d0/
      data cp(1)   /1.d0/
      data dp(1,1) /0.d0/
      data sp(1)   /0.d0/
c
      data shmit(1,1) /0.d0/
c
      data tmold /0.d0/
c
      data tzero /2015.d0/
c
c     ******************
c     Debut de programme
c     ******************
c
      ier = 0
c
c     ---------------------------------------------------------------
c*FON Initialisation a 0 des composantes du champ ainsi que du module
c     ---------------------------------------------------------------
c
      br = 0.0d0
      bt = 0.0d0
      bp = 0.0d0
      bb = 0.0d0
c
c     --------------------------------------------------
c*FON Initialisations  faites au premier appel du module
c     --------------------------------------------------
c
      if (shmit(1,1) .ne. -1.d0) then
c
c     ----------------------------------
c*FON Calcul des tableaux fn,fm et const
c     ----------------------------------
c
         shmit(1,1) = -1.d0
         do 10 n = 1, 14
            fn(n) = n
            do 20 m = 1, 14
               fm(m)      = m - 1
               const(n,m) = dble((n - 2)**2 - (m - 1)**2) /
     >                      dble((2 * n - 3) * (2 * n - 5))
20         continue
10       continue
c
c     ----------------------------
c*FON Calcul du tableau shmit(n,m)
c     ----------------------------
c
         do 30 n = 2, 14
            shmit(n,1) = dble(2 * n - 3) * shmit(n-1,1) / dble(n - 1)
            jj = 2
            do 40 m = 2, n
               shmit(n,m)   = shmit(n,m-1) *
     >                        sqrt(dble((n - m + 1) * jj) / (n + m - 2))
               shmit(m-1,n) = shmit(n,m)
               jj           = 1
40          continue
30       continue
c
c     ---------------------------------------
c*FON Calcul des tableaux gg(n,m) et ggt(n,m)
c     ---------------------------------------
c
         f1 = dble(lg(1,1))
         f2 = dble(lgt(1,1))
         do 50 n = 1, kmax
            do 60 m = 1, kmax
               gg(n,m)  = dble(lg(n,m)) * shmit(n,m) / f1
               ggt(n,m) = dble(lgt(n,m)) * shmit(n,m) / f2
60          continue
50       continue
c
c     --------------------------------------------------
c*FON Traitements effectues si ce n'est pas le 1er appel
c     --------------------------------------------------
c
      endif
c
c     ------------------------
c*FON Calcul du tableau g(n,m)
c     ------------------------
c
      if (year .ne. tmold) then
c
         tmold = year
         t     = year - tzero
c
         do 70 n = 1, kmax
            do 80 m= 1, kmax
               g(n,m) = gg(n,m) + t * ggt(n,m)
80          continue
70       continue
c
      endif
c
c     ----------------------------------------------------
c*FON Calcul des cosinus directeurs de la colatitude et de
c*FON la longitude geocentriques
c     ----------------------------------------------------
c
      cph = cos(phi)
      sph = sin(phi)
c
      if (thet .ne. 0.0d0 .and. thet .ne. acos(-1.0d0)) then
c
         ct  = cos(thet)
         st  = sin(thet)
c
      else
c
         if (thet .ne. acos(-1.0d0)) then
            ct  = 1.0d0
            st  = 1.d-15
         elseif (thet .ne. 0.0d0) then
            ct  = -1.0d0
            st  = 1.d-15
         endif
c
      endif
c
      sp(2) = sph
      cp(2) = cph
c
c     ----------------------------
c*FON Calcul des tableaux cp et sp
c     ----------------------------
c
      do 90 m = 3, kmax
         sp(m) = sp(2) * cp(m-1) + cp(2) * sp(m-1)
         cp(m) = cp(2) * cp(m-1) - sp(2) * sp(m-1)
90    continue
c
c     ---------------------------------------------------
c*FON Premiers termes des composantes du champ magnetique
c     ---------------------------------------------------
c
      rrmag   = rre * rayt / rgmt
      aor     = 1.d0 / rrmag
      ar      = aor * aor * aor
c
      p(2,1)  = ct
      dp(2,1) = -st
      p(2,2)  = st
      dp(2,2) = ct
c
      br = - (ar + ar) * (g(2,1) * p(2,1) + p(2,2) * (g(2,2) * cp(2) +
     >     g(1,2) * sp(2)))
      bt = ar * (g(2,1) * dp(2,1) + dp(2,2) * (g(2,2) * cp(2) +
     >     g(1,2) * sp(2)))
      bp = ar * (g(1,2) * cp(2) - g(2,2) * sp(2)) * p(2,2)
c
c     -----------------------------------------------------
c*FON Evaluation finale des composantes du champ magnetique
c     -----------------------------------------------------
c
      do 100 n = 3, kmax
         ar = aor * ar
         do 110 m = 1, n
c
            if (m .eq. n) then
               p(n,n)  = st * p(n-1,n-1)
               dp(n,n) = st * dp(n-1,n-1) + ct * p(n-1,n-1)
            else
               if (const(n,m) .eq. 0) then
                  p(n,m)  = ct * p(n-1,m)
                  dp(n,m) = ct * dp(n-1,m) - st * p(n-1,m)
               else
                  p(n,m)  = ct * p(n-1,m) - const(n,m) * p(n-2,m)
                  dp(n,m) = ct * dp(n-1,m) - st * p(n-1,m)
     >                      - const(n,m) * dp(n-2,m)
               endif
            endif
c
            par = p(n,m) * ar
c
            if (m .eq. 1) then
               temp = g(n,m)
            else
               temp = g(n,m) * cp(m) + g(m-1,n) * sp(m)
               bp   = bp - (g(n,m) * sp(m) - g(m-1,n) * cp(m)) *
     >                fm(m) * par
            endif
c
            br = br - temp * fn(n) * par
            bt = bt + temp * dp(n,m) * ar
c
110      continue
c
100   continue
c
      bp = bp / st
c
c     ---------------------------------------
c*FON Expression du champ magnetique en gauss
c     ---------------------------------------
c
      br = br / 100000.d0
      bt = bt / 100000.d0
      bp = bp / 100000.d0
c
      bb = sqrt(bp * bp + bt * bt + br * br)
c
c     ****************
c     Fin de programme
c     ****************
c
      return
      end