dgrf95.f 11.3 KB
      subroutine dgrf95 (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 99.03.31 - V 1.0
c*VER 01.05.30 - V 2.0
c*VER 03.01.06 - V 2.1
c*VER 01.01.07 - V 3.0
c*
c*AUT adap. CNES - JC KOSIK - juillet 1995
c*AUT port. CISI
c*
c*ROL Theme : Modeles de champs magnetiques
c*ROL         Calcul du champ magnetique d'origine interne avec les
c*ROL         coefficients du modele  DGRF 95.
c*
c*PAR year (I) : annee fractionnaire (>= 1995.)
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 - 99.03.31 - creation de la maglib au CDPP
c*HST version 2.0 - 01.05.30 - correction de commentaires de code
c*HST version 2.1 - 03.01.06 - corrections en compilation avec g77
c*HST version 3.0 - 01.01.07 - adoption des coefficients definitifs
c*HST                          du champ 1995 et variations seculaires
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 dgrf95
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 octobre 2006, nouveaux lg et lgt
c
      data lg/
     s 10,-296920,-22000,13350,9400,-2140,680,770,250,40,-30,3*0,
     s 53060,-17840,30700,-22670,7800,3520,670,-720,60,90,-60,3*0,
     s -23660,-4130,16810,12490,2900,2350,680,10,-60,30,20,3*0,
     s -2620,3020,-4270,7590,-4180,-1180,-1700,280,-90,-100,-40,3*0,
     s 2620,-2360,970,-3060,1220,-1660,-10,50,-140,80,-10,3*0,
     s 460,1650,-1430,-550,1070,-170,190,40,90,-80,40,3*0,
     s -170,720,670,-580,10,360,-930,80,60,-10,20,3*0,
     s -690,-250,40,240,170,-240,-60,-20,-50,100,20,3*0,
     s 110,-210,80,-230,150,110,-160,-40,-70,-20,50,3*0,
     s -200,150,120,-60,-80,80,50,-80,30,-80,10,3*0,
     s  10,0,40,50,-50,-10,-20,10,-20,-70,0,45*0/
c
      data lgt/100,
     > 1452, -1354, 92, -154, -96, 86, 40, -12, 20, 8,
     > 54, -44, -4, -2398, 1116, -32, -420, 136, -12, 24,
     > -40, 12, 8, 0, -34, -6, -18, -2312, -900, -202,
     > 62, -800, -254, 124, -20, -64, 0, -6, -38, 4,
     > 6, 688, -172, -1282, -890, 300, -248, 182, 106, 22,
     > 32, 18, 30, 18, 2, 212, 82, 456, 44, -214,
     > -52, -98, 82, -52, -34, 10, -2, -4, -8, -44,
     > 138, 198, 314, -14, 82, -42, 58, 2, -18, -6,
     > 2, 18, 26, -8, -166, -38, -64, -6, 156, 52,
     > -14, 20, -10, -20, -14, -10, -8, 88, 16, 44,
     > 0, -44, -28, 4, 16, -58, -14, 0, 14, 6,
     > 14, 18, -10, 10, 30, 10, -42, 22, 38, 0,
     > -46, -16, 34, -6, -8, 6, -32, 10, -4, -8,
     > 8, -24, -4, 36, -4, -14, 2, -8, 6, 14,
     > 0, 0, -2, -18, -4, -18, -16, -4, -8, -22,
     > 24, -2, -2, 2, 26, -18, -52, 18, -14, -56,
     > -18, -24, -38, -18, 80, -4, 8, -8, 6, 50,
     > -52, 14, 6, 0, 0, 6, -18, -8, 16, -8,
     > 0, -18, 4, 36, -8, -20, -2, 14, 6, 12,
     > 6, -4, -10, -18, 2/
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 /1995.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