include file: modgps05refstruct.cdk90
! -*- F90 -*-

!
! Structure containing the refractivity and derivatives
! of a model profile.
!
! Functions:
!      Construct the cached profiles.
!
! Josep M. Aparicio, 2003-2012.
! ARMA/ASTD
! Environment Canada
!
! Revisions:
!        J.M. Aparicio - ARMA Feb 2012
!          Improved compressibility and refractivity.
!


module modgps05refstruct 2,8
  use modgps00base   , only : i4, dp, ngpssize
  use modgps01ctphys , only : p_TC
  use modgps03diff
  use modgps04profile, only : gpsprofile

  implicit none
  
contains


  subroutine gpscmp(prf, cmp) 2
    type(gpsprofile) :: prf
    type(gpsdiff)   , intent(out):: cmp(:)

    integer(i4)      :: i, ngpslev
    type(gpsdiff)               :: p, t, q
    !type(gpsdiff)               :: Zd,Zn,Zo,Za,Zw,Zt
    type(gpsdiff)               :: x,tc,pt,tc2,x2,ZtC
    real(dp)                    :: a0,a1,a2,b0,b1,c0,c1,d,e
    real(dp), parameter         :: md=28.965516_dp
    real(dp), parameter         :: mw=18.015254_dp
    real(dp), parameter         :: wa=md/mw
    real(dp), parameter         :: wb=(md-mw)/mw
    !
    a0=1.58123e-6_dp
    a1=-2.9331e-8_dp
    a2=1.1043e-10_dp
    b0=5.707e-6_dp
    b1=-2.051e-8_dp
    c0=1.9898e-4_dp
    c1=-2.376e-6_dp
    d =1.83e-11_dp
    e =-0.765e-8_dp
    !
    ngpslev = prf%ngpslev
    do i = 1, ngpslev
       p  = prf%pst(i)
       t  = prf%tst(i)
       q  = prf%qst(i)
       x  = wa*q/(1._dp+wb*q)
       ! First implementation (2007)
       !Zn=1._dp+(0.03913_dp-1.408_dp/(0.08314472_dp*t))*p/(83.14472_dp*t)
       !Zo=1._dp+(0.03183_dp-1.378_dp/(0.08314472_dp*t))*p/(83.14472_dp*t)
       !Za=1._dp+(0.03219_dp-1.363_dp/(0.08314472_dp*t))*p/(83.14472_dp*t)
       !Zw=1._dp+(0.03049_dp-5.536_dp/(0.08314472_dp*t))*p/(83.14472_dp*t)
       !Zd=0.78_dp*Zn+0.21_dp*Zo+0.01_dp*Za
       !Zt=(1._dp-q)*Zd+q*Zw
       ! Better estimate, from CIPM, Piccard (2008)
       tc = t-p_TC
       pt = 1.e2_dp*p/t
       tc2= tc*tc
       x2 = x*x
       ZtC= 1._dp-pt*(a0+a1*tc+a2*tc2+(b0+b1*tc)*x+(c0+c1*tc)*x2)       !+pt*pt*(d+e*x2)
       ! Either choose Zt (First implementation) or ZtC (CIPM, better)
       cmp(i)=ZtC
    enddo
  end subroutine gpscmp


  subroutine gpsden(prf, den) 2,2
    type(gpsprofile)              :: prf
    type(gpsdiff)   , intent(out) :: den(:)
    type(gpsdiff)                 :: mold, dd, dw, cmp(ngpssize)
    integer(i4)      :: i, ngpslev
    real(dp), parameter         :: R=8.314472_dp
    real(dp), parameter         :: md=28.965516_dp
    real(dp), parameter         :: mw=18.015254_dp
    real(dp), parameter         :: wa=md/mw
    real(dp), parameter         :: wb=(md-mw)/mw
    type(gpsdiff)               :: p, t, q, x

    call gpscmp(prf, cmp)
    ngpslev = prf%ngpslev
    do i = 1, ngpslev
       p  = prf%pst(i)
       t  = prf%tst(i)
       q  = prf%qst(i)
       x  = wa*q/(1._dp+wb*q)

       ! Densities (molar, total, dry, water vapor):
       mold  = 100._dp*p/(R*t*cmp(i))               ! note that p is in hPa
       dd = mold * (1._dp-x) * (md/1000._dp)
       dw = mold * x         * (mw/1000._dp)
       den(i)=dd+dw
    enddo
  end subroutine gpsden

end module modgps05refstruct