FV3 Bundle
ufo_gnssro_ref_mod.F90
Go to the documentation of this file.
1 ! (C) Copyright 2017-2018 UCAR
2 !
3 ! This software is licensed under the terms of the Apache Licence Version 2.0
4 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5 
6 !> Fortran module to handle gnssro refractivity observations
7 
9  use iso_c_binding
10  use kinds
11  use ufo_vars_mod
12  use ufo_geovals_mod
14  use vert_interp_mod
15  use ufo_basis_mod, only: ufo_basis
16  use obsspace_mod
17 
18  implicit none
19  integer, parameter :: max_string=800
20  public :: ufo_gnssro_ref
21  private
22 
23  !> Fortran derived type for gnssro trajectory
24  type, extends(ufo_basis) :: ufo_gnssro_ref
25  contains
26  procedure :: simobs => ufo_gnssro_ref_simobs
27  end type ufo_gnssro_ref
28 
29 contains
30 ! ------------------------------------------------------------------------------
31  subroutine ufo_gnssro_ref_simobs(self, geovals, hofx, obss)
34  implicit none
35  logical,parameter :: use_compress=.true.
36  class(ufo_gnssro_Ref), intent(in) :: self
37  type(ufo_geovals), intent(in) :: geovals
38  real(kind_real), intent(inout) :: hofx(:)
39  type(c_ptr), value, intent(in) :: obss
40 
41  character(len=*), parameter :: myname_="ufo_gnssro_ref_simobs"
42  character(max_string) :: err_msg
43 
44  integer :: iobs,k
45  real(kind_real) :: wf
46  integer :: wi,ierr
47  integer :: nobs
48  type(ufo_geoval), pointer :: t,q,prs,gph
49  real(kind_real) :: refr1, refr2,refr3
50  real(kind_real), allocatable :: obsZ(:), obsLat(:)
51  real(kind_real) :: obsH, gesT,gesQ, gesTv, gesTv0,gesP
52  ! check if nobs is consistent in geovals & hofx
53  if (geovals%nobs /= size(hofx)) then
54  write(err_msg,*) myname_, ' error: nobs inconsistent!'
55  call abor1_ftn(err_msg)
56  endif
57  ! check if prs variable is in geovals and get it
58  call ufo_geovals_get_var(geovals, var_prs, prs,status=ierr)
59  if (ierr/=0) then
60  write(err_msg,*) myname_, trim(var_prs), ' doesnt exist'
61  call abor1_ftn(err_msg)
62  endif
63  ! check if t variable is in geovals and get it
64  call ufo_geovals_get_var(geovals, var_t, t,status=ierr)
65  if (ierr/=0) then
66  write(err_msg,*) myname_, trim(var_t), ' doesnt exist'
67  call abor1_ftn(err_msg)
68  endif
69  call ufo_geovals_get_var(geovals, var_q, q,status=ierr)
70  if (ierr/=0) then
71  write(err_msg,*) myname_, trim(var_q), ' doesnt exist'
72  call abor1_ftn(err_msg)
73  endif
74  call ufo_geovals_get_var(geovals, var_z, gph,status=ierr)
75  if (ierr/=0) then
76  write(err_msg,*) myname_, trim(var_z), ' doesnt exist'
77  call abor1_ftn(err_msg)
78  endif
79 
80  nobs = obsspace_get_nobs(obss)
81  allocate(obsz(nobs))
82  allocate(obslat(nobs))
83 
84  call obsspace_get_db(obss, "Metadata", "altitude", obsz)
85  call obsspace_get_db(obss, "Metadata", "latitude", obslat)
86 
87  call gnssro_ref_constants(use_compress)
88 
89  ! obs operator
90  do iobs = 1, geovals%nobs
91  ! Convert geometric height at observation to geopotential height
92  call geometric2geop(obslat(iobs), obsz(iobs), obsh)
93  call vert_interp_weights(gph%nval,obsh, gph%vals(:,iobs),wi,wf) ! calculate weights
94  call vert_interp_apply(t%nval, t%vals(:,iobs), gest, wi, wf)
95  call vert_interp_apply(q%nval, q%vals(:,iobs), gesq, wi, wf)
96 
97  ! use hypsometric equation to calculate pressure
98  gestv = 0.0
99  gestv0 = 0.0
100  gestv = gest*(one + (rv_over_rd-one)* (gesq/(1-gesq) ) )
101  gestv0 = t%vals(wi,iobs)*(one + (rv_over_rd-one) * (q%vals(wi,iobs)/(1-q%vals(wi,iobs)) ))
102  gesp = prs%vals(wi,iobs)/exp(two*grav*(obsh-gph%vals(wi,iobs))/(rd*(gestv+gestv0)))
103  refr1 = n_a*gesp/gest
104  refr2 = n_b*gesp*gesq/ ( gest**2 * (rd_over_rv+(1-rd_over_rv)*gesq) )
105  refr3 = n_c*gesp*gesq/ ( gest * (rd_over_rv+(1-rd_over_rv)*gesq) )
106  hofx(iobs) = refr1 + refr2 + refr3
107  enddo
108 
109  ! cleanup
110  deallocate(obsz)
111  deallocate(obslat)
112  end subroutine ufo_gnssro_ref_simobs
113 
114 ! ------------------------------------------------------------------------------
115 end module ufo_gnssro_ref_mod
subroutine, public ufo_geovals_get_var(self, varname, geoval, status)
subroutine vert_interp_apply(nlev, fvec, f, wi, wf)
Definition: vert_interp.F90:67
integer, parameter max_string
integer function, public obsspace_get_nobs(c_dom)
Return the number of observations.
Fortran module to handle gnssro refractivity observations.
real(kind_real), parameter, public rd
real(kind_real), parameter, public rd_over_rv
Fortran derived type for gnssro trajectory.
real(kind_real), parameter, public rv_over_rd
subroutine geometric2geop(Latitude, geometricZ, geopotentialH)
character(len=maxvarlen), public var_z
Fortran module to perform linear interpolation.
Definition: vert_interp.F90:8
real(fp), parameter, public one
character(len=maxvarlen), public var_q
real(kind_real), public n_c
subroutine, public gnssro_ref_constants(use_compress)
real(fp), parameter, public two
character(len=maxvarlen), public var_prs
subroutine ufo_gnssro_ref_simobs(self, geovals, hofx, obss)
type(registry_t), public ufo_geovals_registry
Linked list interface - defines registry_t type.
real(kind_real), parameter, public grav
real(kind_real), public n_b
character(len=maxvarlen), public var_t
Fortran interface to ObsSpace.
Definition: obsspace_mod.F90:9
subroutine vert_interp_weights(nlev, obl, vec, wi, wf)
Definition: vert_interp.F90:20
real(kind_real), public n_a