UFO
ufo_gnssgb_refropp1d_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 for ground-based gnss refractivity ropp1d forward operator
7 !> following the ROPP (2018 Aug) implementation
8 
10 
11 use iso_c_binding
12 use kinds
13 use ufo_vars_mod
16 use ufo_basis_mod, only: ufo_basis
19 use obsspace_mod
20 use missing_values_mod
22 use fckit_log_module, only : fckit_log
23 
24 implicit none
25 public :: ufo_gnssgb_refropp1d
26 private
27 
28  !> Fortran derived type for ground based gnss trajectory
30  contains
31  procedure :: simobs => ufo_gnssgb_refropp1d_simobs
32 end type ufo_gnssgb_refropp1d
33 
34 contains
35 
36 ! ------------------------------------------------------------------------------
37 ! ------------------------------------------------------------------------------
38 subroutine ufo_gnssgb_refropp1d_simobs(self, geovals, hofx, obss)
39  use ropp_fm_types, only: state1dfm
40  use ropp_fm_types, only: obs1drefrac
41  use typesizes, only: wp => eightbytereal
42  use datetimetypes, only: dp
43 
44  implicit none
45  class(ufo_gnssgb_refropp1d), intent(in) :: self
46  type(ufo_geovals), intent(in) :: geovals
47  real(kind_real), intent(inout) :: hofx(:)
48  type(c_ptr), value, intent(in) :: obss
49  real(c_double) :: missing
50 
51  type(state1dfm) :: x
52  type(obs1drefrac) :: y
53 
54  character(len=*), parameter :: myname_="ufo_gnssgb_refropp1d_simobs"
55  real(kind=dp) :: ob_time
56  integer, parameter :: max_string = 800
57 
58  character(max_string) :: err_msg
59  integer :: nlev, nobs, iobs
60  integer, allocatable, dimension(:) :: ichk
61  type(ufo_geoval), pointer :: t, q, prs, gph, gph_sfc
62  real(kind_real), allocatable :: obsLat(:), obsLon(:), obsHeight(:), obsValue(:)
63  real(kind_real), allocatable :: model_z(:)
64  real(kind_real) :: station_phi, model_ztd
65  integer :: iflip
66  logical :: l_linear
67  write(err_msg,*) "TRACE: ufo_gnssgb_refropp1d_simobs: begin"
68  call fckit_log%info(err_msg)
69 
70 ! check if nlocs is consistent in geovals & hofx
71  if (geovals%nlocs /= size(hofx)) then
72  write(err_msg,*) myname_, ' error: nlocs inconsistent!'
73  call abor1_ftn(err_msg)
74  endif
75 
76 ! get variables from geovals
77  call ufo_geovals_get_var(geovals, var_ts, t) ! temperature
78  call ufo_geovals_get_var(geovals, var_q, q) ! specific humidity
79  call ufo_geovals_get_var(geovals, var_prs, prs) ! pressure
80  call ufo_geovals_get_var(geovals, var_z, gph) ! geopotential height
81  call ufo_geovals_get_var(geovals, var_sfc_geomz, gph_sfc) ! surface geopotential height
82 
83  missing = missing_value(missing)
84 
85  nlev = t%nval ! number of model levels
86  nobs = obsspace_get_nlocs(obss)
87 
88  if (nobs > 0) then
89  iflip = 0
90  if (prs%vals(1,1) .lt. prs%vals(prs%nval,1) ) then
91  iflip = 1
92  write(err_msg,'(a)') ' ufo_gnssgb_refropp1d_simobs:'//new_line('a')// &
93  ' Model vertical height profile is in descending order,'//new_line('a')// &
94  ' but ROPP requires it to be ascending order, need flip'
95  call fckit_log%info(err_msg)
96  end if
97 
98  ! set obs space struture
99  allocate(obslon(nobs))
100  allocate(obslat(nobs))
101  allocate(obsheight(nobs))
102  allocate(obsvalue(nobs))
103 
104  ! create array for model geometric heights
105  allocate(model_z(nlev))
106  model_z(:) = 0.0
107 
108  call obsspace_get_db(obss, "MetaData", "longitude", obslon)
109  call obsspace_get_db(obss, "MetaData", "latitude", obslat)
110  call obsspace_get_db(obss, "MetaData", "station_height", obsheight)
111  call obsspace_get_db(obss, "ObsValue", "ZTD", obsvalue)
112 ! obsValue = 0.0
113 
114  allocate(ichk(nlev))
115  ichk(:) = 0 ! this will hold QC values for observation from QC flags
116 
117  write(err_msg,*) "TRACE: ufo_gnssgb_refropp1d_simobs: begin observation loop, nobs = ", nobs
118  call fckit_log%info(err_msg) ! always print
119 
120  obs_loop: do iobs = 1, nobs
121 
122  ob_time = 0.0
123  l_linear = .false.
124  call init_ropp_1d_statevec(ob_time, &
125  obslon(iobs), &
126  obslat(iobs), &
127  t%vals(:,iobs), &
128  q%vals(:,iobs), &
129  prs%vals(:,iobs), &
130  gph%vals(:,iobs), &
131  nlev, &
132  gph_sfc%vals(1,iobs), &
133  x, iflip)
134 
135  call calc_station_phi(obslat(iobs), obsheight(iobs), station_phi)
136  call init_ropp_1d_obvec(nlev, &
137  ichk, ob_time, &
138  obslat(iobs), &
139  obslon(iobs), &
140  station_phi, &
141  x, y)
142 
143  call ropp_fm_refrac_1d(x,y)
144 
145  call calc_model_z(nlev, obslat(iobs), y%geop, model_z)
146  ! note the scaling of the refractivity by 1.e-6 is done in subroutine after integral
147  call gnss_ztd_integral(nlev, y%refrac, model_z, obsheight(iobs), model_ztd, l_linear)
148  ! add error trap ! model_ztd initialized to 0 in integral if 0 is returned something very wrong
149  if ( model_ztd == 0.0 ) then
150  model_ztd = missing
151  end if
152 
153  ! matching a print format used in initialization of obvec
154  write(err_msg,'(a9,2a11,2a15)') 'ROPPsim: ', 'ob', 'bk', 'station_hgt', 'model_terr'
155  call fckit_log%debug(err_msg) ! print when MAIN_DEBUG=1
156  write(err_msg,'(9x,2f11.3,2f15.3)') obsvalue(iobs), model_ztd, obsheight(iobs), model_z(1)
157  call fckit_log%debug(err_msg) ! print when MAIN_DEBUG=1
158 
159  hofx(iobs) = model_ztd
160 
161  ! hack -- handling ropp missing value
162  call ropp_tidy_up_1d(x,y)
163 
164  end do obs_loop
165 
166  deallocate(ichk)
167  deallocate(obslat)
168  deallocate(obslon)
169  deallocate(obsheight)
170  deallocate(obsvalue)
171  end if ! nobs > 0
172 
173  write(err_msg,*) "TRACE: ufo_gnssgb_refropp1d_simobs: completed"
174  call fckit_log%info(err_msg)
175 
176 end subroutine ufo_gnssgb_refropp1d_simobs
177 ! ------------------------------------------------------------------------------
178 
179 end module ufo_gnssgb_refropp1d_mod
Fortran module to prepare for Lagrange polynomial interpolation. based on GSI: lagmod....
Definition: lag_interp.F90:4
subroutine, public lag_interp_const(q, x, n)
Definition: lag_interp.F90:24
subroutine, public lag_interp_smthweights(x, xt, aq, bq, w, dw, n)
Definition: lag_interp.F90:174
type(registry_t), public ufo_geovals_registry
Linked list interface - defines registry_t type.
subroutine, public ufo_geovals_get_var(self, varname, geoval)
Fortran module for ground-based gnss refractivity ropp1d forward operator following the ROPP (2018 Au...
subroutine ufo_gnssgb_refropp1d_simobs(self, geovals, hofx, obss)
Fortran module to handle ground-based gnss observations following the ROPP (2018 Aug) implementation.
subroutine, public init_ropp_1d_statevec(step_time, rlon, rlat, temp, shum, pres, phi, lm, phi_sfc, x, iflip)
subroutine, public calc_model_z(nlev, rlat, model_phi, model_z)
subroutine, public init_ropp_1d_obvec(nlev, ichk, ob_time, rlat, rlon, station_phi, x, y)
subroutine, public calc_station_phi(rlat, station_height, station_phi)
subroutine, public gnss_ztd_integral(lm, model_refrac, model_z, ob_terr, model_ztd, l_linear)
character(len=maxvarlen), parameter, public var_prs
character(len=maxvarlen), parameter, public var_q
character(len=maxvarlen), parameter, public var_sfc_geomz
character(len=maxvarlen), parameter, public var_z
character(len=maxvarlen), parameter, public var_ts
Fortran module to perform linear interpolation.
Definition: vert_interp.F90:8
type to hold interpolated field for one variable, one observation
type to hold interpolated fields required by the obs operators
Fortran derived type for ground based gnss trajectory.