20 use missing_values_mod
21 use fckit_log_module,
only : fckit_log
34 logical :: vert_interp_ops
36 real(kind_real) :: min_temp_grad
37 integer :: nlevp, nlevq, nlocs, iflip
38 real(kind_real),
allocatable :: k(:,:)
58 logical(c_bool),
intent(in) :: vert_interp_ops
59 logical(c_bool),
intent(in) :: pseudo_ops
60 real(c_float),
intent(in) :: min_temp_grad
62 self % vert_interp_ops = vert_interp_ops
63 self % pseudo_ops = pseudo_ops
64 self % min_temp_grad = min_temp_grad
79 type(c_ptr),
value,
intent(in) :: obss
82 character(len=*),
parameter :: myname_=
"ufo_gnssro_bendmetoffice_tlad_settraj"
85 character(max_string) :: err_msg
92 real(kind_real),
allocatable :: obsLat(:)
93 real(kind_real),
allocatable :: impact_param(:)
94 real(kind_real),
allocatable :: obsLocR(:)
95 real(kind_real),
allocatable :: obsGeoid(:)
97 write(err_msg,*)
"TRACE: ufo_gnssro_bendmetoffice_tlad_settraj: begin"
98 call fckit_log%info(err_msg)
110 self % nlevp = prs % nval
111 self % nlevq = q % nval
112 self % nlocs = obsspace_get_nlocs(obss)
116 if (prs%vals(1,1) .lt. prs%vals(prs%nval,1) )
then
118 write(err_msg,
'(a)')
' ufo_gnssro_bendmetoffice_tlad_settraj:'//new_line(
'a')// &
119 ' Model vertical height profile is in descending order,'//new_line(
'a')// &
120 ' The data will be flipped for processing'
121 call fckit_log%info(err_msg)
125 allocate(obslat(self%nlocs))
126 allocate(impact_param(self%nlocs))
127 allocate(obslocr(self%nlocs))
128 allocate(obsgeoid(self%nlocs))
129 call obsspace_get_db(obss,
"MetaData",
"latitude", obslat)
130 call obsspace_get_db(obss,
"MetaData",
"impact_parameter", impact_param)
131 call obsspace_get_db(obss,
"MetaData",
"earth_radius_of_curvature", obslocr)
132 call obsspace_get_db(obss,
"MetaData",
"geoid_height_above_reference_ellipsoid", obsgeoid)
133 ALLOCATE(self % K(1:self%nlocs, 1:prs%nval + q%nval))
136 obs_loop:
do iobs = 1, self % nlocs
137 if (self%iflip == 1)
then
140 rho_heights % vals(rho_heights%nval:1:-1, iobs), &
141 theta_heights % vals(theta_heights%nval:1:-1, iobs), &
142 q % vals(q%nval:1:-1, iobs), &
143 prs % vals(prs%nval:1:-1, iobs), &
145 self % vert_interp_ops, &
146 self % min_temp_grad, &
151 impact_param(iobs:iobs), &
152 self % K(iobs:iobs,1:prs%nval+q%nval))
156 rho_heights % vals(:,iobs), &
157 theta_heights % vals(:,iobs), &
159 prs % vals(:,iobs), &
161 self % vert_interp_ops, &
162 self % min_temp_grad, &
167 impact_param(iobs:iobs), &
168 self % K(iobs:iobs,1:prs%nval+q%nval))
176 deallocate(impact_param)
193 real(kind_real),
intent(inout) :: hofx(:)
194 type(c_ptr),
value,
intent(in) :: obss
197 character(len=*),
parameter :: myname_=
"ufo_gnssro_bendmetoffice_simobs_tl"
202 character(max_string) :: err_msg
205 real(kind_real),
allocatable :: x_d(:)
207 write(err_msg,*)
"TRACE: ufo_gnssro_bendmetoffice_simobs_tl: begin"
208 call fckit_log%info(err_msg)
211 if (.not. self%ltraj)
then
212 write(err_msg,*) myname_,
' trajectory wasnt set!'
213 call abor1_ftn(err_msg)
217 if (geovals%nlocs /=
size(hofx))
then
218 write(err_msg,*) myname_,
' error: nlocs inconsistent!'
219 call abor1_ftn(err_msg)
228 allocate(x_d(1:prs_d%nval+q_d%nval))
230 obs_loop:
do iobs = 1, nlocs
232 x_d(1:prs_d%nval) = prs_d % vals(:,iobs)
233 x_d(prs_d%nval+1:prs_d%nval+q_d%nval) = q_d % vals(:,iobs)
234 hofx(iobs) = sum(self % K(iobs,:) * x_d)
240 write(err_msg,*)
"TRACE: ufo_gnssro_bendmetoffice_simobs_tl: complete"
241 call fckit_log%info(err_msg)
253 use typesizes,
only: wp => eightbytereal
260 real(kind_real),
intent(in) :: hofx(:)
261 type(c_ptr),
value,
intent(in) :: obss
264 character(len=*),
parameter :: myname_=
"ufo_gnssro_bendmetoffice_simobs_ad"
267 real(c_double) :: missing
271 real(kind_real),
allocatable :: x_d(:)
272 character(max_string) :: err_msg
274 write(err_msg,*)
"TRACE: ufo_gnssro_bendmetoffice_simobs_ad: begin"
275 call fckit_log%info(err_msg)
278 if (.not. self%ltraj)
then
279 write(err_msg,*) myname_,
' trajectory wasnt set!'
280 call abor1_ftn(err_msg)
284 if (geovals%nlocs /=
size(hofx))
then
285 write(err_msg,*) myname_,
' error: nlocs inconsistent!'
286 call abor1_ftn(err_msg)
293 missing = missing_value(missing)
294 allocate(x_d(1:prs_d%nval + q_d%nval))
297 obs_loop:
do iobs = 1, self % nlocs
299 if (hofx(iobs) /= missing)
then
300 x_d = self % K(iobs,:) * hofx(iobs)
301 prs_d % vals(:,iobs) = x_d(1:prs_d%nval)
302 q_d % vals(:,iobs) = x_d(prs_d%nval+1:prs_d%nval+q_d%nval)
309 write(err_msg,*)
"TRACE: ufo_gnssro_bendmetoffice_simobs_ad: complete"
310 call fckit_log%info(err_msg)
323 character(len=*),
parameter :: myname_=
"ufo_gnssro_bendmetoffice_tlad_delete"
328 if (
allocated(self%K))
deallocate(self%K)
354 INTEGER,
INTENT(IN) :: nlevp
355 INTEGER,
INTENT(IN) :: nlevq
356 REAL(kind_real),
INTENT(IN) :: za(:)
357 REAL(kind_real),
INTENT(IN) :: zb(:)
358 REAL(kind_real),
INTENT(IN) :: q(1:nlevq)
359 REAL(kind_real),
INTENT(IN) :: prs(1:nlevp)
360 LOGICAL,
INTENT(IN) :: pseudo_ops
361 LOGICAL,
INTENT(IN) :: vert_interp_ops
362 REAL(kind_real),
INTENT(IN) :: min_temp_grad
363 REAL(kind_real),
INTENT(IN) :: ro_rad_curv
364 REAL(kind_real),
INTENT(IN) :: latitude
365 REAL(kind_real),
INTENT(IN) :: ro_geoid_und
366 INTEGER,
INTENT(IN) :: nobs
367 REAL(kind_real),
INTENT(IN) :: zobs(:)
368 REAL(kind_real),
INTENT(INOUT) :: K(:,:)
372 REAL(kind_real),
ALLOCATABLE :: model_heights(:)
373 REAL(kind_real),
ALLOCATABLE :: refractivity(:)
374 INTEGER :: nRefLevels
375 REAL(kind_real) :: T(1:nlevq)
376 REAL(kind_real),
ALLOCATABLE :: nr(:)
380 INTEGER :: num_pseudo
381 REAL(kind_real) :: x(1:nlevp+nlevq)
383 CHARACTER(LEN=200) :: err_msg
387 x(nlevp+1:nlevp+nlevq) = q
405 ALLOCATE(nr(1:nreflevels))
407 IF (.NOT. baerr)
THEN
439 write(err_msg,*)
"Error in refractivity calculation"
440 CALL fckit_log % warning(err_msg)
444 DEALLOCATE(refractivity)
445 DEALLOCATE(model_heights)
477 INTEGER,
INTENT(IN) :: nlevp
478 INTEGER,
INTENT(IN) :: nRefLevels
479 INTEGER,
INTENT(IN) :: nlevq
480 REAL(kind_real),
INTENT(IN) :: za(:)
481 REAL(kind_real),
INTENT(IN) :: zb(:)
482 REAL(kind_real),
INTENT(IN) :: model_heights(:)
483 LOGICAL,
INTENT(IN) :: pseudo_ops
484 LOGICAL,
INTENT(IN) :: vert_interp_ops
485 REAL(kind_real),
INTENT(IN) :: min_temp_grad
486 REAL(kind_real),
INTENT(IN) :: pressure(nlevp)
487 REAL(kind_real),
INTENT(IN) :: humidity(nlevq)
488 REAL(kind_real),
INTENT(IN) :: ro_rad_curv
489 REAL(kind_real),
INTENT(IN) :: latitude
490 REAL(kind_real),
INTENT(IN) :: ro_geoid_und
491 REAL(kind_real),
INTENT(IN) :: ref_model(nRefLevels)
492 INTEGER,
INTENT(IN) :: nobs
493 REAL(kind_real),
INTENT(IN) :: zobs(:)
494 REAL(kind_real),
INTENT(IN) :: nr(nRefLevels)
495 REAL(kind_real),
INTENT(OUT) :: K(nobs,nlevp+nlevq)
497 REAL(kind_real) :: m1(nobs, nRefLevels)
498 REAL(kind_real),
ALLOCATABLE :: dref_dp(:, :)
499 REAL(kind_real),
ALLOCATABLE :: dref_dq(:, :)
500 REAL(kind_real) :: dnr_dref(nRefLevels, nRefLevels)
501 REAL(kind_real) :: dalpha_dref(nobs, nRefLevels)
502 REAL(kind_real) :: dalpha_dnr(nobs, nRefLevels)
537 m1 = matmul(dalpha_dnr,dnr_dref)
538 k(1:nobs, 1:nlevp) = matmul(dalpha_dref,dref_dp) + matmul(m1,dref_dp)
539 k(1:nobs, nlevp+1:nlevp+nlevq) = matmul(dalpha_dref,dref_dq) + matmul(m1,dref_dq)
541 IF (
ALLOCATED(dref_dp))
DEALLOCATE(dref_dp)
542 IF (
ALLOCATED(dref_dq))
DEALLOCATE(dref_dq)
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 gnssro bending angle Met Office's tangent linear and adjoint.
subroutine jacobian_interface(nlevp, nlevq, za, zb, q, prs, pseudo_ops, vert_interp_ops, min_temp_grad, ro_rad_curv, latitude, ro_geoid_und, nobs, zobs, K)
subroutine ufo_gnssro_bendmetoffice_tlad_settraj(self, geovals, obss)
integer, parameter max_string
subroutine ufo_gnssro_bendmetoffice_simobs_ad(self, geovals, hofx, obss)
subroutine ufo_gnssro_bendmetoffice_tlad_delete(self)
subroutine ufo_gnssro_bendmetoffice_setup(self, vert_interp_ops, pseudo_ops, min_temp_grad)
subroutine ufo_gnssro_bendmetoffice_simobs_tl(self, geovals, hofx, obss)
subroutine ops_gpsro_getk(nlevp, nRefLevels, nlevq, za, zb, model_heights, pseudo_ops, vert_interp_ops, min_temp_grad, pressure, humidity, ro_rad_curv, latitude, ro_geoid_und, ref_model, nobs, zobs, nr, K)
subroutine, public ops_gpsrocalc_nrk(zb, nb, Rad, lat, und, refrac, dnr_dref)
subroutine, public ops_gpsrocalc_alphak(nobs, nlev, a, refrac, nr, Kmat_ref, Kmat_nr)
subroutine, public ops_gpsrocalc_nr(nb, zb, refrac, Rad, lat, und, nr)
Module for containing a general refractivity forward operator and its K-matrix.
subroutine, public ufo_calculate_refractivity(nlevP, nlevq, za, zb, P, q, vert_interp_ops, pseudo_ops, min_temp_grad, refracerr, nRefLevels, refractivity, model_heights, temperature, interp_pressure)
Calculation of the refractivity from the pressure and specific humidity.
subroutine, public ufo_refractivity_kmat(nlevP, nlevq, nRefLevels, za, zb, P, q, pseudo_ops, vert_interp_ops, min_temp_grad, dref_dP, dref_dq, dPb_dP, refractivity)
Calculate general refractivity K matrix.
character(len=maxvarlen), parameter, public var_prsi
character(len=maxvarlen), parameter, public var_q
character(len=maxvarlen), parameter, public var_zi
character(len=maxvarlen), parameter, public var_z
Fortran module to perform linear interpolation.
type to hold interpolated field for one variable, one observation
type to hold interpolated fields required by the obs operators
Fortran derived type for gnssro trajectory.