module modgps06gravity 11,2
#if defined (DOC)
!
! Josep M. Aparicio
! Meteorological Service of Canada, 2003.
!
#endif
use modgps00base
, only : i4, dp
use modgps02wgs84const
, only : WGS_a, WGS_f, WGS_m, &
WGS_TNGk, WGS_e2, WGS_GammaE
implicit none
!private gpsgravitysurf
contains
! Normal gravity on ellipsoidal surface:
! Input: Latitude
! Latitude : rad
!
! Output: Normal gravity
! gpsgravitysurf : m/s2
!
function gpsgravitysurf(Latitude) 3
real(dp), intent(in) :: Latitude
real(dp) :: gpsgravitysurf
real(dp) :: ks2
real(dp) :: e2s
ks2 = WGS_TNGk * sin(Latitude)**2
e2s = 1._dp - WGS_e2 * sin(Latitude)**2
gpsgravitysurf = WGS_GammaE * (1._dp + ks2) / sqrt(e2s)
end function gpsgravitysurf
! Normal gravity above the ellipsoidal surface:
! Input: Latitude, altitude
! Latitude : rad
! Altitude : m
!
! Output: Normal gravity
! gpsgravityabove : m/s2
!
function gpsgravityabove(Latitude, Altitude) 2,1
real(dp), intent(in) :: Latitude
real(dp), intent(in) :: Altitude
real(dp) :: gpsgravityabove
real(dp) :: C1
real(dp) :: C2
C1 =-2._dp/WGS_a*(1._dp+WGS_f+WGS_m-2*WGS_f*sin(Latitude)**2)
C2 = 3._dp/WGS_a**2
gpsgravityabove = gpsgravitysurf
(Latitude)* &
(1._dp + C1 * Altitude + C2 * Altitude**2)
end function gpsgravityabove
function gpsgravitydiffabove(Latitude, Altitude),1
real(dp), intent(in) :: Latitude
real(dp), intent(in) :: Altitude
real(dp) :: gpsgravitydiffabove
real(dp) :: C1
real(dp) :: C2
C1 =-2._dp/WGS_a*(1._dp+WGS_f+WGS_m-2*WGS_f*sin(Latitude)**2)
C2 = 3._dp/WGS_a**2
gpsgravitydiffabove = gpsgravitysurf
(Latitude)* &
(C1 + 2 * C2 * Altitude)
end function gpsgravitydiffabove
! Geopotential energy at a given point.
! Result is based on the WGS84 approximate expression for the
! gravity acceleration as a function of latitude and altitude,
! integrated with the trapezoidal rule.
! Input: Latitude, altitude
! Latitude : rad
! Altitude : m
!
! Output: Geopotential
! gpsgeopotential : m2/s2
function gpsgeopotential(Latitude, Altitude) 15,1
real(dp), intent(in) :: Latitude
real(dp), intent(in) :: Altitude
real(dp) :: gpsgeopotential
real(dp) :: dh
real(dp) :: geop
integer :: n, i
real(dp), allocatable :: hi(:)
real(dp), allocatable :: gi(:)
dh = 500._dp
n = 1 + int(Altitude/dh)
allocate(hi(0:n))
allocate(gi(0:n))
do i = 0, n
hi(i) = i * dh
if (i.eq.n) hi(i) = Altitude
gi(i) = gpsgravityabove
(Latitude, hi(i))
enddo
gpsgeopotential = 0._dp
do i = 1, n
gpsgeopotential = gpsgeopotential + 0.5_dp * (gi(i)+gi(i-1)) * (hi(i)-hi(i-1))
enddo
deallocate(hi)
deallocate(gi)
end function gpsgeopotential
end module modgps06gravity