module modgps08refop 9,7
#if defined (DOC)
!
! Refractivity operator, with derivatives.
!
! Josep M. Aparicio
! Meteorological Service of Canada, 2003.
!
#endif
use modgps00base
, only : i4, dp
use modgps01ctmath
, only : m_pi
use modgps03diff
use modgps04profile
use modgps05refstruct
, only : gpspre, gpsref, gpsrefW, gpsztd
use modgps06gravity
, only : gpsgravityabove
use modgps07geostruct
, only : gpsgeo
implicit none
contains
subroutine gpsrefopv(hv, prf, refopv) 7,2
real(dp) , intent(in) :: hv(:)
type(gpsprofile) :: prf
type(gpsdiff) , intent(out):: refopv(:)
integer(i4) :: iSize, i, ngpslev
integer(i4) :: j, jloc
real(dp) :: h
type(gpsdiff) :: gpm
type(gpsdiff) :: gpp
type(gpsdiff) :: dz
type(gpsdiff) :: dxm
type(gpsdiff) :: dxp
type(gpsdiff) :: Nm
type(gpsdiff) :: Np
type(gpsdiff) :: N
call gpsref
(prf)
call gpsgeo
(prf)
ngpslev=prf%ngpslev
iSize = size(hv)
!
! Given a height
!
do i = 1, iSize
h = hv(i)
!
! Search where it is located
!
if (h > prf%gst(1)%Var) then
jloc = 1
endif
do j=1, ngpslev-1
if ((h <= prf%gst(j)%Var) .and. (h > prf%gst(j+1)%Var)) then
jloc = j
exit
endif
enddo
if (h <= prf%gst(ngpslev)%Var) then
jloc = ngpslev-1
endif
!
! Find properties in that band
!
gpm = prf%gst(jloc)
gpp = prf%gst(jloc+1)
dz = gpm - gpp
dxm = (h-gpp) / dz
dxp = (gpm-h) / dz
Nm = prf%rst(jloc)
Np = prf%rst(jloc+1)
N = exp(dxm * log(Nm) + dxp * log(Np))
refopv (i) = N
enddo
end subroutine gpsrefopv
subroutine gpsrefWopv(hv, prf, refWopv),2
real(dp) , intent(in) :: hv(:)
type(gpsprofile) :: prf
type(gpsdiff) , intent(out):: refWopv(:)
type(gpsdiff) , allocatable:: NWA(:)
integer(i4) :: iSize, i, ngpslev
integer(i4) :: j, jloc
real(dp) :: h
type(gpsdiff) :: gpm
type(gpsdiff) :: gpp
type(gpsdiff) :: dz
type(gpsdiff) :: dxm
type(gpsdiff) :: dxp
type(gpsdiff) :: Nm
type(gpsdiff) :: Np
type(gpsdiff) :: N
ngpslev=prf%ngpslev
allocate (NWA(ngpslev))
call gpsrefW
(prf, NWA)
call gpsgeo
(prf)
iSize = size(hv)
!
! Given a height
!
do i = 1, iSize
h = hv(i)
!
! Search where it is located
!
if (h > prf%gst(1)%Var) then
jloc = 1
endif
do j=1, ngpslev-1
if ((h <= prf%gst(j)%Var) .and. (h > prf%gst(j+1)%Var)) then
jloc = j
exit
endif
enddo
if (h <= prf%gst(ngpslev)%Var) then
jloc = ngpslev-1
endif
!
! Find properties in that band
!
gpm = prf%gst(jloc)
gpp = prf%gst(jloc+1)
dz = gpm - gpp
dxm = (h-gpp) / dz
dxp = (gpm-h) / dz
Nm = NWA(jloc)
Np = NWA(jloc+1)
N = exp(dxm * log(Nm) + dxp * log(Np))
refWopv (i) = N
enddo
deallocate (NWA)
end subroutine gpsrefWopv
subroutine gpstemgrdop(dh, prf, grd),1
real(dp) , intent(in) :: dh
type(gpsprofile) :: prf
type(gpsdiff) , intent(out):: grd
integer(i4) :: iSize, i, ngpslev
integer(i4) :: j, jloc
real(dp) :: h1, h2
type(gpsdiff) :: gpm
type(gpsdiff) :: gpp
type(gpsdiff) :: dz
type(gpsdiff) :: dxm
type(gpsdiff) :: dxp
type(gpsdiff) :: tm
type(gpsdiff) :: tp
type(gpsdiff) :: t
ngpslev=prf%ngpslev
call gpsgeo
(prf)
!
! Relevant heights
!
h1 = prf%gst(ngpslev)%Var
h2 = h1 + dh
!
! Search where h2 is located
!
if (h2 > prf%gst(1)%Var) then
jloc = 1
endif
do j=1, ngpslev-1
if ((h2 <= prf%gst(j)%Var) .and. (h2 > prf%gst(j+1)%Var)) then
jloc = j
exit
endif
enddo
if (h2 <= prf%gst(ngpslev)%Var) then
jloc = ngpslev-1
endif
!
! Find properties in that band
!
gpm = prf%gst(jloc)
gpp = prf%gst(jloc+1)
dz = gpm - gpp
dxm = (h2-gpp) / dz
dxp = (gpm-h2) / dz
tm = prf%tst(jloc)
tp = prf%tst(jloc+1)
t = dxm * tm + dxp * tp
grd = (t-prf%tst(ngpslev))/dh
end subroutine gpstemgrdop
subroutine gpshgtopv(pr, prf, hgtopv),2
real(dp) , intent(in) :: pr
type(gpsprofile) :: prf
type(gpsdiff) , intent(out):: hgtopv
type(gpsdiff) :: gst(ngpssize)
type(gpsdiff) :: vp(ngpssize)
integer :: iSize, ngpslev
integer(i4) :: i, j, jloc
real(dp) :: p
type(gpsdiff) :: vpm
type(gpsdiff) :: vpp
type(gpsdiff) :: dpr
type(gpsdiff) :: dxm
type(gpsdiff) :: dxp
type(gpsdiff) :: Hm
type(gpsdiff) :: Hp
type(gpsdiff) :: H
call gpspre
(prf)
call gpsgeo
(prf)
ngpslev=prf%ngpslev
!
! Given a pressure
!
p = pr
!
! Search where it is located
!
if (p < prf%pst(1)%Var) then
jloc = 1
endif
do j=1, ngpslev-1
if ((p >= prf%pst(j)%Var) .and. (p < prf%pst(j+1)%Var)) then
jloc = j
exit
endif
enddo
if (p >= prf%pst(ngpslev)%Var) then
jloc = ngpslev-1
endif
!
! Find properties in that band
!
vpm = log(prf%pst(jloc))
vpp = log(prf%pst(jloc+1))
dpr = vpp-vpm
dxm = (vpp-log(p)) / dpr
dxp = (log(p)-vpm) / dpr
Hm = prf%gst(jloc)
Hp = prf%gst(jloc+1)
H = dxm * Hm + dxp * Hp
hgtopv = H
end subroutine gpshgtopv
subroutine gpsZTDopv(hv, prf, ZTDopv),3
real(dp) , intent(in) :: hv(:)
type(gpsprofile) , intent(in) :: prf
type(gpsdiff) , intent(out):: ZTDopv(:)
type(gpsdiff) :: ZTDS(ngpssize)
integer(i4) :: iSize, i, ngpslev
integer(i4) :: j, jloc
real(dp) :: h
type(gpsdiff) :: gpm
type(gpsdiff) :: gpp
type(gpsdiff) :: dz
type(gpsdiff) :: dxm
type(gpsdiff) :: dxp
type(gpsdiff) :: Fm
type(gpsdiff) :: Fp
type(gpsdiff) :: F, pr
call gpsref
(prf)
call gpsgeo
(prf)
call gpsZTDS
(prf, ZTDS)
ngpslev=prf%ngpslev
iSize = size(hv)
!
! Given a height
!
do i = 1, iSize
h = hv(i)
!
! Search where it is located
!
if (h > prf%gst(1)%Var) then
jloc = 1
endif
do j=1, ngpslev-1
if ((h <= prf%gst(j)%Var) .and. (h > prf%gst(j+1)%Var)) then
jloc = j
exit
endif
enddo
if (h <= prf%gst(ngpslev)%Var) then
jloc = ngpslev-1
endif
!
! Find properties in that band
!
gpm = prf%gst(jloc)
gpp = prf%gst(jloc+1)
dz = gpm - gpp
dxm = (h-gpp) / dz
dxp = (gpm-h) / dz
Fm = ZTDS(jloc)
Fp = ZTDS(jloc+1)
pr = 0.01_dp * (prf%rP0-prf%rPT)
F = 1.e-6_dp * pr * (dxm * Fm + dxp * Fp)
ZTDopv(i) = F
enddo
end subroutine gpsZTDopv
subroutine gpsZTDS(prf, ZTDS) 1,1
type(gpsprofile) :: prf
type(gpsdiff) , intent(out):: ZTDS(:)
type(gpsdiff) :: ZTD(ngpssize)
integer(i4) :: i, ngpslev
ngpslev=prf%ngpslev
call gpsZTD
(prf, ZTD)
ZTDS(1)=ZTD(1)*prf%rPT/(prf%rP0-prf%rPT)
do i = 2, ngpslev
ZTDS(i) = ZTDS(i-1) + 0.5_dp * ( ZTD(i) + ZTD(i-1) ) * (prf%rHYB(i)-prf%rHYB(i-1))
enddo
end subroutine gpsZTDS
subroutine gpsscatpotopv(hv, prf, scpot1v, scpot2v),1
real(dp) , intent(in) :: hv(:)
type(gpsprofile) :: prf
type(gpsdiff) , intent(out):: scpot1v(:)
type(gpsdiff) , intent(out):: scpot2v(:)
type(gpsdiff), allocatable :: refopv(:)
integer(i4) :: iSize
real(dp) :: k1, k2
integer(i4) :: j
type(gpsdiff) :: n
iSize = size(hv)
allocate(refopv(iSize))
call gpsrefopv
(hv, prf, refopv)
k1 = 2 * m_pi * 1.57542e9 / 2.998792458e8
k2 = 2 * m_pi * 1.22760e9 / 2.998792458e8
!
! Given a height
!
do j = 1, iSize
n = 1._dp + 1.e-6_dp * refopv(j)
scpot1v(j) = k1**2 / (4 * m_pi) * (n * n - 1._dp)
scpot2v(j) = k2**2 / (4 * m_pi) * (n * n - 1._dp)
enddo
deallocate(refopv)
end subroutine gpsscatpotopv
end module modgps08refop