UFO
ufo_groundgnss_metoffice_mod.F90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
2 ! (C) British Crown Copyright 2020 Met Office
3 !
4 ! This software is licensed under the terms of the Apache Licence Version 2.0
5 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6 !-------------------------------------------------------------------------------
7 
8 !> Fortran module for ground based gnss Met Office forward operator
9 
11 
12 use iso_c_binding
13 use kinds
14 use ufo_vars_mod
17 use ufo_basis_mod, only: ufo_basis
18 use obsspace_mod
19 use missing_values_mod
22 use fckit_log_module, only : fckit_log
23 
24 implicit none
26 private
27 
28  !> Fortran derived type for groundgnss trajectory
30  contains
31  procedure :: setup => ufo_groundgnss_metoffice_setup
32  procedure :: simobs => ufo_groundgnss_metoffice_simobs
34 
35 contains
36 
37 ! ------------------------------------------------------------------------------
38 ! Get the optional settings for the forward model, and save them in the object
39 ! so that they can be used in the code.
40 ! ------------------------------------------------------------------------------
41 subroutine ufo_groundgnss_metoffice_setup(self, f_conf)
42 
43 use fckit_configuration_module, only: fckit_configuration
44 implicit none
45 class(ufo_groundgnss_metoffice), intent(inout) :: self
46 type(fckit_configuration), intent(in) :: f_conf
47 
48 end subroutine ufo_groundgnss_metoffice_setup
49 
50 
51 ! ------------------------------------------------------------------------------
52 ! Ground GNSS forward operator for the Met Office system
53 ! ------------------------------------------------------------------------------
54 subroutine ufo_groundgnss_metoffice_simobs(self, geovals, hofx, obss)
55 
56  implicit none
57 
58  ! Arguments to this routine
59  class(ufo_groundgnss_metoffice), intent(in) :: self ! The object in which this operator is contained
60  type(ufo_geovals), intent(in) :: geovals ! The model values, interpolated to the obsevation locations
61  real(kind_real), intent(inout) :: hofx(:) ! The model forecast of the observations
62  type(c_ptr), value, intent(in) :: obss ! The observations, and meta-data for those observations
63 
64  character(len=*), parameter :: myname_ = "ufo_groundgnss_metoffice_simobs"
65  integer, parameter :: max_string = 800
66 
67  character(max_string) :: err_msg ! Error message for output
68  character(max_string) :: message ! General message for output
69  integer :: nobs ! Number of observations
70  integer :: iobs ! Loop variable, observation number
71  type(ufo_geoval), pointer :: q ! Model background values of specific humidity
72  type(ufo_geoval), pointer :: prs ! Model background values of air pressure
73  type(ufo_geoval), pointer :: theta_heights ! Model heights of levels containing specific humidity
74  type(ufo_geoval), pointer :: rho_heights ! Model heights of levels containing air pressure
75 
76  real(kind_real), allocatable :: zStation(:)
77 
78  write(err_msg,*) "TRACE: ufo_groundgnss_metoffice_simobs: begin"
79  call fckit_log%info(err_msg)
80 
81 ! check if nlocs is consistent in geovals & hofx
82  if (geovals%nlocs /= size(hofx)) then
83  write(err_msg,*) myname_, ' error: nlocs inconsistent!'
84  call abor1_ftn(err_msg)
85  endif
86 
87 
88 ! get variables from geovals
89  call ufo_geovals_get_var(geovals, var_q, q) ! specific humidity
90  call ufo_geovals_get_var(geovals, var_prsi, prs) ! pressure
91  call ufo_geovals_get_var(geovals, var_z, theta_heights) ! Geopotential height of the normal model levels
92  call ufo_geovals_get_var(geovals, var_zi, rho_heights) ! Geopotential height of the pressure levels
93 
94  nobs = obsspace_get_nlocs(obss)
95  allocate(zstation(nobs))
96 
97  call obsspace_get_db(obss, "MetaData", "station_height", zstation)
98 
99  write(err_msg,*) "TRACE: ufo_groundgnss_metoffice_simobs: begin observation loop, nobs = ", nobs
100  call fckit_log%info(err_msg)
101 
102  obs_loop: do iobs = 1, nobs
103 
104  call ops_groundgnss_forwardmodel(prs % nval, &
105  q % nval, &
106  rho_heights % vals(:,iobs), &
107  theta_heights % vals(:,iobs), &
108  prs % vals(:,iobs), &
109  q % vals(:,iobs), &
110  1, &
111  zstation(iobs), &
112  hofx(iobs))
113 
114  write(message,'(A,10I6)') "Size of hofx = ", shape(hofx)
115  call fckit_log%info(message)
116  write(message,'(A,1F2.4)') "hofx(iobs) = ", hofx(iobs)
117  call fckit_log%info(message)
118  end do obs_loop
119 
120  write(err_msg,*) "TRACE: ufo_groundgnss_metoffice_simobs: completed"
121  call fckit_log%info(err_msg)
122 
123 end subroutine ufo_groundgnss_metoffice_simobs
124 ! ------------------------------------------------------------------------------
125 
126 
127 SUBROUTINE ops_groundgnss_forwardmodel(nlevP, &
128  nlevq, &
129  za, &
130  zb, &
131  pressure, &
132  humidity, &
133  nobs, &
134  zStation, &
135  Model_ZTD)
136 
137 INTEGER, INTENT(IN) :: nlevP ! no. of p levels in state vec.
138 INTEGER, INTENT(IN) :: nlevq ! no. of theta levels
139 REAL(kind_real), INTENT(IN) :: za(1:nlevP) ! heights of rho levs
140 REAL(kind_real), INTENT(IN) :: zb(1:nlevq) ! heights of theta levs
141 REAL(kind_real), INTENT(IN) :: pressure(1:nlevP) ! Model background pressure
142 REAL(kind_real), INTENT(IN) :: humidity(1:nlevq) ! Model background specific humidity
143 INTEGER, INTENT(IN) :: nobs ! Number of observations
144 
145 REAL(kind_real), INTENT(IN) :: zStation
146 REAL(kind_real), INTENT(INOUT) :: Model_ZTD ! Model forecast of the observations
147 
148 !
149 ! Things that may need to be output, as they are used by the TL/AD calculation
150 !
151 
152 REAL(kind_real) :: pN(nlevq) ! Presure on theta levels
153 REAL(kind_real) :: refrac(nlevq)
154 LOGICAL :: refracerr
155 
156 REAL(kind_real) :: TopCorrection
157 !
158 ! Local parameters
159 !
160 integer, parameter :: max_string = 800 ! Length of strings
161 character(len=*), parameter :: myname_ = "Ops_Groundgnss_ForwardModel"
162 !
163 ! Local variables
164 !
165 INTEGER :: nstate ! no. of levels in state vec.
166 REAL(kind_real) :: x(1:nlevP+nlevQ) ! state vector
167 character(max_string) :: err_msg ! Error message to be output
168 character(max_string) :: message ! General message for output
169 
170 ! The model data must be on a staggered grid, with nlevp = nlevq+1
171 IF (nlevp /= nlevq + 1) THEN
172  write(err_msg,*) myname_ // ':' // ' Data must be on a staggered grid nlevp, nlevq = ', nlevp, nlevq
173  call fckit_log % warning(err_msg)
174  write(err_msg,*) myname_ // ':' // ' error: number of levels inconsistent!'
175  call abor1_ftn(err_msg)
176 END IF
177 
178 nstate = nlevp + nlevq
179 x(1:nlevp) = pressure
180 x(nlevp+1:nstate) = humidity
181 
182 CALL ufo_refractivity(nlevq, &
183  nlevp, &
184  za, &
185  zb, &
186  x, &
187  pn, &
188  refracerr, &
189  refrac)
190 
192  nlevq, &
193  topcorrection)
194 
195 CALL ops_groundgnss_ztd (nlevq, &
196  refrac, &
197  zb, &
198  zstation, &
199  model_ztd)
200 
201 model_ztd = model_ztd + topcorrection
202 
203 write(message,'(A,F10.4)') "Model_ZTD = ", model_ztd
204 call fckit_log%info(message)
205 
206 END SUBROUTINE ops_groundgnss_forwardmodel
207 
ufo_groundgnss_metoffice_mod::ufo_groundgnss_metoffice_setup
subroutine ufo_groundgnss_metoffice_setup(self, f_conf)
Definition: ufo_groundgnss_metoffice_mod.F90:42
ufo_vars_mod::var_zi
character(len=maxvarlen), parameter, public var_zi
Definition: ufo_variables_mod.F90:30
ufo_groundgnss_metoffice_mod::ufo_groundgnss_metoffice
Fortran derived type for groundgnss trajectory.
Definition: ufo_groundgnss_metoffice_mod.F90:29
ufo_basis_mod
Definition: ufo_basis_mod.F90:6
ufo_groundgnss_ukmo_utils_mod::ops_groundgnss_ztd
subroutine, public ops_groundgnss_ztd(nlevq, refrac, zb, zStation, Model_ZTD)
Definition: ufo_groundgnss_metoffice_utils_mod.F90:38
ufo_groundgnss_ukmo_utils_mod::ops_groundgnss_topcorrection
subroutine, public ops_groundgnss_topcorrection(pN, nlevq, TopCorrection)
Definition: ufo_groundgnss_metoffice_utils_mod.F90:120
ufo_refractivity_utils_mod
Definition: ufo_refractivity_utils_mod.F90:8
ufo_refractivity_utils_mod::ufo_refractivity
subroutine, public ufo_refractivity(nlevq, nlevP, za, zb, x, pN, refracerr, refrac)
Definition: ufo_refractivity_utils_mod.F90:44
ufo_groundgnss_metoffice_mod::ops_groundgnss_forwardmodel
subroutine ops_groundgnss_forwardmodel(nlevP, nlevq, za, zb, pressure, humidity, nobs, zStation, Model_ZTD)
Definition: ufo_groundgnss_metoffice_mod.F90:136
ufo_geovals_mod
Definition: ufo_geovals_mod.F90:7
ufo_geovals_mod_c
Definition: GeoVaLs.interface.F90:7
ufo_vars_mod::var_prsi
character(len=maxvarlen), parameter, public var_prsi
Definition: ufo_variables_mod.F90:26
ufo_groundgnss_ukmo_utils_mod
Definition: ufo_groundgnss_metoffice_utils_mod.F90:8
ufo_groundgnss_metoffice_mod
Fortran module for ground based gnss Met Office forward operator.
Definition: ufo_groundgnss_metoffice_mod.F90:10
ufo_basis_mod::ufo_basis
Definition: ufo_basis_mod.F90:12
ufo_vars_mod
Definition: ufo_variables_mod.F90:8
ufo_vars_mod::var_z
character(len=maxvarlen), parameter, public var_z
Definition: ufo_variables_mod.F90:29
ufo_geovals_mod::ufo_geovals_get_var
subroutine, public ufo_geovals_get_var(self, varname, geoval)
Definition: ufo_geovals_mod.F90:128
ufo_vars_mod::var_q
character(len=maxvarlen), parameter, public var_q
Definition: ufo_variables_mod.F90:22
ufo_groundgnss_metoffice_mod::ufo_groundgnss_metoffice_simobs
subroutine ufo_groundgnss_metoffice_simobs(self, geovals, hofx, obss)
Definition: ufo_groundgnss_metoffice_mod.F90:55
ufo_geovals_mod::ufo_geovals
type to hold interpolated fields required by the obs operators
Definition: ufo_geovals_mod.F90:47
ufo_geovals_mod::ufo_geoval
type to hold interpolated field for one variable, one observation
Definition: ufo_geovals_mod.F90:40
ufo_geovals_mod_c::ufo_geovals_registry
type(registry_t), public ufo_geovals_registry
Linked list interface - defines registry_t type.
Definition: GeoVaLs.interface.F90:30