11 use fckit_configuration_module,
only: fckit_configuration
21 use missing_values_mod
24 use fckit_log_module,
only : fckit_log
31 integer :: nval, nlocs
32 real(kind_real),
allocatable :: prs(:,:), t(:,:), q(:,:), gph(:,:), gph_sfc(:,:)
35 real(kind_real),
allocatable :: obslon2d(:), obslat2d(:)
50 type(fckit_configuration),
intent(in) :: f_conf
62 type(c_ptr),
value,
intent(in) :: obss
63 character(len=*),
parameter :: myname_=
"ufo_gnssro_bndropp2d_tlad_settraj"
64 character(max_string) :: err_msg
65 type(
ufo_geoval),
pointer :: t, q, prs, gph, gph_sfc
67 real(kind_real),
allocatable :: obsAzim(:)
68 real(kind_real),
allocatable :: obsLat(:), obsLon(:)
69 real(kind_real),
allocatable :: obsLonnh(:),obsLatnh(:)
71 real(kind_real) :: dtheta
73 write(err_msg,*)
"TRACE: ufo_gnssro_bndropp2d_tlad_settraj: begin"
74 call fckit_log%info(err_msg)
85 self%nlocs = obsspace_get_nlocs(obss)
88 n_horiz = self%roconf%n_horiz
89 dtheta = self%roconf%dtheta
91 if (prs%vals(1,1) .lt. prs%vals(prs%nval,1) )
then
93 write(err_msg,
'(a)')
' ufo_gnssro_bndropp2d_tlad_settraj:'//new_line(
'a')// &
94 ' Model vertical height profile is in descending order,'//new_line(
'a')// &
95 ' but ROPP requires it to be ascending order, need flip'
96 call fckit_log%info(err_msg)
99 allocate(self%obsLat2d(self%nlocs*n_horiz))
100 allocate(self%obsLon2d(self%nlocs*n_horiz))
102 allocate(obslon(self%nlocs))
103 allocate(obslat(self%nlocs))
104 allocate(obsazim(self%nlocs))
106 call obsspace_get_db(obss,
"MetaData",
"longitude", obslon)
107 call obsspace_get_db(obss,
"MetaData",
"latitude", obslat)
108 call obsspace_get_db(obss,
"MetaData",
"sensor_azimuth_angle", obsazim)
110 allocate(obslatnh(n_horiz))
111 allocate(obslonnh(n_horiz))
114 call ropp_fm_2d_plane(obslat(i),obslon(i),obsazim(i),dtheta,n_horiz,obslatnh,obslonnh,kerror)
115 self%obsLon2d((i-1)*n_horiz+1:i*n_horiz) = obslonnh
116 self%obsLat2d((i-1)*n_horiz+1:i*n_horiz) = obslatnh
125 allocate(self%t(self%nval,self%nlocs*n_horiz))
126 allocate(self%q(self%nval,self%nlocs*n_horiz))
127 allocate(self%prs(self%nval,self%nlocs*n_horiz))
128 allocate(self%gph(self%nval,self%nlocs*n_horiz))
129 allocate(self%gph_sfc(1,self%nlocs*n_horiz))
136 self%gph_sfc = gph_sfc%vals
146 use ropp_fm_types,
only: state2dfm, state1dfm
147 use ropp_fm_types,
only: obs1dbangle
148 use datetimetypes,
only: dp
152 real(kind_real),
intent(inout) :: hofx(:)
153 type(c_ptr),
value,
intent(in) :: obss
154 real(c_double) :: missing
156 type(state2dfm) :: x,x_tl
157 type(state1dfm) :: x1d,x1d_tl
158 type(obs1dbangle) :: y,y_tl
160 integer :: iobs,nlev, nlocs,nvprof
162 character(len=*),
parameter :: myname_=
"ufo_gnssro_bndropp2d_simobs_tl"
163 character(max_string) :: err_msg
167 real(kind_real),
allocatable :: gph_d_zero(:,:)
168 real(kind_real) :: gph_sfc_d_zero
170 real(kind_real),
allocatable :: obsImpP(:),obsLocR(:),obsGeoid(:),obsAzim(:)
171 real(kind_real),
allocatable :: obsLat(:),obsLon(:)
173 real(kind_real) :: dtheta
174 real(kind_real) :: ob_time
176 missing = missing_value(missing)
178 n_horiz = self%roconf%n_horiz
179 dtheta = self%roconf%dtheta
181 write(err_msg,*)
"TRACE: ufo_gnssro_bndropp2d_simobs_tl: begin"
182 call fckit_log%info(err_msg)
185 if (.not. self%ltraj)
then
186 write(err_msg,*) myname_,
' trajectory wasnt set!'
187 call abor1_ftn(err_msg)
191 if (geovals%nlocs /=
size(hofx)*n_horiz )
then
192 write(err_msg,*) myname_,
' error: 2d nlocs inconsistent! geovals%nlocs, size(hofx), &
193 and n_horiz are', geovals%nlocs,
size(hofx), n_horiz
194 call abor1_ftn(err_msg)
205 allocate(gph_d_zero(nlev,nlocs*n_horiz))
210 allocate(obslon(nlocs))
211 allocate(obslat(nlocs))
212 allocate(obsimpp(nlocs))
213 allocate(obslocr(nlocs))
214 allocate(obsgeoid(nlocs))
215 allocate(obsazim(nlocs))
216 call obsspace_get_db(obss,
"MetaData",
"longitude", obslon)
217 call obsspace_get_db(obss,
"MetaData",
"latitude", obslat)
218 call obsspace_get_db(obss,
"MetaData",
"impact_parameter", obsimpp)
219 call obsspace_get_db(obss,
"MetaData",
"earth_radius_of_curvature", obslocr)
220 call obsspace_get_db(obss,
"MetaData",
"geoid_height_above_reference_ellipsoid", obsgeoid)
221 call obsspace_get_db(obss,
"MetaData",
"sensor_azimuth_angle", obsazim)
227 obs_loop:
do iobs = 1, nlocs
229 if ( ( obsimpp(iobs)-obslocr(iobs)-obsgeoid(iobs) ) <= self%roconf%top_2d .and. &
230 obsazim(iobs) /= missing )
then
234 self%obsLat2d( (iobs-1)*n_horiz+1:iobs*n_horiz ), &
235 self%t(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
236 self%q(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
237 self%prs(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
238 self%gph(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
239 nlev, x, n_horiz, dtheta, self%iflip)
243 where(x%shum .le. 1e-8) x%shum = 1e-8
247 self%obsLat2d( (iobs-1)*n_horiz+1:iobs*n_horiz ), &
248 t_d%vals(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
249 q_d%vals(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
250 prs_d%vals(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
251 gph_d_zero(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
252 nlev, x_tl, n_horiz, dtheta, self%iflip)
264 call ropp_fm_bangle_2d_tl(x,x_tl,y, y_tl)
265 hofx(iobs) = y_tl%bangle(nvprof)
276 self%t(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
277 self%q(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
278 self%prs(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
279 self%gph(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
281 self%gph_sfc(1,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
284 where(x1d%shum .le. 1e-8) x1d%shum = 1e-8
289 t_d%vals(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
290 q_d%vals(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
291 prs_d%vals(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
292 gph_d_zero(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
307 call ropp_fm_bangle_1d_tl(x1d,x1d_tl,y,y_tl%bangle(nvprof))
308 hofx(iobs) = y_tl%bangle(nvprof)
322 deallocate(gph_d_zero)
324 write(err_msg,*)
"TRACE: ufo_gnssro_bndropp2d_simobs_tl: complete"
325 call fckit_log%info(err_msg)
335 use ropp_fm_types,
only: state2dfm, state1dfm
336 use ropp_fm_types,
only: obs1dbangle
337 use typesizes,
only: wp => eightbytereal
338 use datetimetypes,
only: dp
343 real(kind_real),
intent(in) :: hofx(:)
344 type(c_ptr),
value,
intent(in) :: obss
345 real(c_double) :: missing
350 real(kind_real),
allocatable :: gph_d_zero(:,:)
351 real(kind_real) :: gph_sfc_d_zero
353 real(kind_real),
allocatable :: obsLat(:), obsLon(:), obsImpP(:), obsLocR(:), obsGeoid(:)
354 real(kind_real),
allocatable :: obsAzim(:)
355 type(state2dfm) :: x,x_ad
356 type(state1dfm) :: x1d,x1d_ad
357 type(obs1dbangle) :: y,y_ad
358 integer :: iobs,nlev,nlocs,nvprof
359 character(len=*),
parameter :: myname_=
"ufo_gnssro_bndropp2d_simobs_ad"
360 character(max_string) :: err_msg
362 real(kind_real) :: dtheta
363 real(kind_real) :: ob_time
365 n_horiz = self%roconf%n_horiz
366 dtheta = self%roconf%dtheta
368 write(err_msg,*)
"TRACE: ufo_gnssro_bndropp2d_simobs_ad: begin"
369 call fckit_log%info(err_msg)
372 if (.not. self%ltraj)
then
373 write(err_msg,*) myname_,
' trajectory wasnt set!'
374 call abor1_ftn(err_msg)
377 if (geovals%nlocs /=
size(hofx)*n_horiz)
then
378 write(err_msg,*) myname_,
' error: 2d nlocs inconsistent!'
379 call abor1_ftn(err_msg)
390 allocate(gph_d_zero(nlev,nlocs*n_horiz))
395 allocate(obslon(nlocs))
396 allocate(obslat(nlocs))
397 allocate(obsimpp(nlocs))
398 allocate(obslocr(nlocs))
399 allocate(obsgeoid(nlocs))
400 allocate(obsazim(nlocs))
402 call obsspace_get_db(obss,
"MetaData",
"longitude", obslon)
403 call obsspace_get_db(obss,
"MetaData",
"latitude", obslat)
404 call obsspace_get_db(obss,
"MetaData",
"impact_parameter", obsimpp)
405 call obsspace_get_db(obss,
"MetaData",
"earth_radius_of_curvature", obslocr)
406 call obsspace_get_db(obss,
"MetaData",
"geoid_height_above_reference_ellipsoid", obsgeoid)
407 call obsspace_get_db(obss,
"MetaData",
"sensor_azimuth_angle", obsazim)
409 missing = missing_value(missing)
415 obs_loop:
do iobs = 1, nlocs
417 if (hofx(iobs) .gt. missing)
then
418 if ( ( obsimpp(iobs)-obslocr(iobs)-obsgeoid(iobs) ) <= self%roconf%top_2d .and. &
419 obsazim(iobs) /= missing )
then
423 self%obsLat2d((iobs-1)*n_horiz+1:iobs*n_horiz), &
424 self%t(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
425 self%q(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
426 self%prs(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
427 self%gph(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
428 nlev, x, n_horiz, dtheta, self%iflip)
431 self%obsLat2d( (iobs-1)*n_horiz+1:iobs*n_horiz ), &
432 t_d%vals(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
433 q_d%vals(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
434 prs_d%vals(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
435 gph_d_zero(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
436 nlev, x_ad, n_horiz, dtheta, self%iflip)
439 x_ad%temp(:,:) = 0.0_wp
440 x_ad%pres(:,:) = 0.0_wp
441 x_ad%shum(:,:) = 0.0_wp
442 x_ad%geop(:,:) = 0.0_wp
455 y_ad%bangle(:) = 0.0_wp
458 y_ad%bangle(nvprof) = y_ad%bangle(nvprof) + hofx(iobs)
459 call ropp_fm_bangle_2d_ad(x,x_ad,y,y_ad)
462 t_d%vals(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
463 q_d%vals(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
464 prs_d%vals(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
465 gph_d_zero(:,(iobs-1)*n_horiz+1:iobs*n_horiz), &
467 nlev, x_ad, n_horiz,self%iflip)
478 self%t(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
479 self%q(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
480 self%prs(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
481 self%gph(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
483 self%gph_sfc(1,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
489 t_d%vals(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
490 q_d%vals(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
491 prs_d%vals(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
492 gph_d_zero(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
499 x1d_ad%temp(:) = 0.0_wp
500 x1d_ad%pres(:) = 0.0_wp
501 x1d_ad%shum(:) = 0.0_wp
502 x1d_ad%geop(:) = 0.0_wp
515 y_ad%bangle(:) = 0.0_wp
518 y_ad%bangle(nvprof) = y_ad%bangle(nvprof) + hofx(iobs)
519 call ropp_fm_bangle_1d_ad(x1d,x1d_ad,y,y_ad)
521 t_d%vals(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
522 q_d%vals(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
523 prs_d%vals(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
524 gph_d_zero(:,(iobs-1)*n_horiz+1+(n_horiz-1)/2), &
525 nlev, x1d_ad, self%iflip)
543 deallocate(gph_d_zero)
545 write(err_msg,*)
"TRACE: ufo_gnssro_bndropp2d_simobs_ad: complete"
546 call fckit_log%info(err_msg)
558 character(len=*),
parameter :: myname_=
"ufo_gnssro_bndropp_tlad_delete"
561 if (
allocated(self%prs))
deallocate(self%prs)
562 if (
allocated(self%t))
deallocate(self%t)
563 if (
allocated(self%q))
deallocate(self%q)
564 if (
allocated(self%gph))
deallocate(self%gph)
565 if (
allocated(self%gph_sfc))
deallocate(self%gph_sfc)
566 if (
allocated(self%obsLat2d))
deallocate(self%obsLat2d)
567 if (
allocated(self%obsLon2d))
deallocate(self%obsLon2d)
subroutine, public gnssro_conf_setup(roconf, f_conf)
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 ropp2d tangent linear and adjoint following the ROPP (2018 Au...
subroutine ufo_gnssro_bndropp2d_simobs_ad(self, geovals, hofx, obss)
subroutine ufo_gnssro_bndropp2d_tlad_settraj(self, geovals, obss)
subroutine ufo_gnssro_bndropp2d_tlad_delete(self)
subroutine ufo_gnssro_bndropp2d_simobs_tl(self, geovals, hofx, obss)
integer, parameter max_string
subroutine ufo_gnssro_bndropp2d_tlad_setup(self, f_conf)
Fortran module to handle gnssro bending angle observations following the ROPP (2018 Aug) implementati...
subroutine, public init_ropp_1d_statevec_ad(temp_d, shum_d, pres_d, phi_d, lm, x_ad, iflip)
subroutine, public init_ropp_1d_statevec(step_time, rlon, rlat, temp, shum, pres, phi, lm, phi_sfc, x, iflip)
subroutine, public ropp_tidy_up_tlad_1d(x, x_p, y, y_p)
subroutine, public init_ropp_1d_obvec_tlad(iloop, nvprof, obs_impact, rlat, rlon, roc, undulat, y, y_p)
Fortran module to handle gnssro bending angle observations following the ROPP (2018 Aug) implementati...
subroutine, public init_ropp_2d_statevec(rlon, rlat, temp, shum, pres, phi, lm, x, n_horiz, dtheta, iflip)
subroutine, public ropp_tidy_up_tlad_2d(x, x_p, y, y_p)
subroutine, public init_ropp_2d_obvec_tlad(iloop, nvprof, obs_impact, rlat, rlon, roc, undulat, y, y_p)
subroutine, public init_ropp_2d_statevec_ad(temp_d, shum_d, pres_d, phi_d, lm, x_ad, n_horiz, iflip)
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.
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.