12 use fckit_log_module,
only: fckit_log
13 use kinds,
only: kind_real
16 use typesizes,
only: wp => eightbytereal
17 use datetimetypes,
only: dp
18 use ropp_fm_types,
only: state1dfm, obs1drefrac
19 use geodesy,
only: gravity, r_eff, geometric2geopotential, geopotential2geometric
20 use arrays,
only: callocate
40 pres, phi, lm, z_sfc, x, iflip)
59 real(kind=dp),
intent(in) :: step_time
60 real(kind=kind_real),
intent(in) :: rlat, rlon
61 real(kind=kind_real),
intent(in) :: z_sfc
62 integer,
intent(in) :: lm
63 real(kind=kind_real),
dimension(lm),
intent(in) :: temp, shum, pres, phi
64 integer,
optional,
intent(in) :: iflip
65 type(state1dfm),
intent(out) :: x
68 real(kind=kind_real) :: rlon_local
74 x%direct_ion = .false.
78 x%lat = real(rlat,kind=wp)
80 if (rlon_local .gt. 180) rlon_local = rlon_local - 360.
81 x%lon = real(rlon_local,kind=wp)
82 x%time = real(step_time, kind=wp)
91 if (
associated(x%temp))
deallocate(x%temp)
92 if (
associated(x%shum))
deallocate(x%shum)
93 if (
associated(x%pres))
deallocate(x%pres)
94 if (
associated(x%geop))
deallocate(x%geop)
96 allocate(x%temp(x%n_lev))
97 allocate(x%shum(x%n_lev))
98 allocate(x%pres(x%n_lev))
99 allocate(x%geop(x%n_lev))
106 if (
present(iflip) )
then
109 if ( local_flip .eq. 1)
then
111 x%temp(lm+1-k) = real(temp(k),kind=wp)
112 x%shum(lm+1-k) = real(shum(k),kind=wp)
113 x%pres(lm+1-k) = real(pres(k),kind=wp)
114 x%geop(lm+1-k) = real(phi(k),kind=wp)
117 x%temp(1:lm) = real(temp(1:lm),kind=wp)
118 x%shum(1:lm) = real(shum(1:lm),kind=wp)
119 x%pres(1:lm) = real(pres(1:lm),kind=wp)
120 x%geop(1:lm) = real(phi(1:lm),kind=wp)
124 x%geop_sfc = geometric2geopotential(real(rlat,kind=wp), real(z_sfc,kind=wp))
137 if (
associated(x%cov%d))
deallocate(x%cov%d)
138 call callocate(x%cov%d, n*(n+1)/2)
141 x%cov%d(i + i*(i-1)/2) = 1.0_wp
146 x%cov%d(j + j*(j-1)/2) = 1.0_wp
149 x%cov%d(n + n*(n-1)/2) = 1.0_wp
154 if (
associated(x%cov%e))
deallocate(x%cov%e)
155 if (
associated(x%cov%f))
deallocate(x%cov%f)
156 if (
associated(x%cov%s))
deallocate(x%cov%s)
158 x%cov%fact_chol = .false.
159 x%cov%equi_chol =
'N'
185 type(state1dfm),
intent(inout) :: x_ad
186 integer,
intent(in) :: lm
187 integer,
optional,
intent(in) :: iflip
188 real(kind=kind_real),
dimension(lm),
intent(inout) :: temp_d, shum_d, pres_d, phi_d
192 integer :: local_flip
198 if (
present(iflip) )
then
202 if ( local_flip == 1 )
then
204 temp_d(k) = real(x_ad%temp(lm+1-k),kind=kind_real)
205 shum_d(k) = real(x_ad%shum(lm+1-k),kind=kind_real)
206 pres_d(k) = real(x_ad%pres(lm+1-k),kind=kind_real)
207 phi_d(k) = real(x_ad%geop(lm+1-k),kind=kind_real)
210 temp_d(1:lm) = real(x_ad%temp(1:lm),kind=kind_real)
211 shum_d(1:lm) = real(x_ad%shum(1:lm),kind=kind_real)
212 pres_d(1:lm) = real(x_ad%pres(1:lm),kind=kind_real)
213 phi_d(1:lm) = real(x_ad%geop(1:lm),kind=kind_real)
215 x_ad%temp(:) = 0.0_wp
216 x_ad%shum(:) = 0.0_wp
217 x_ad%pres(:) = 0.0_wp
218 x_ad%geop(:) = 0.0_wp
241 real(kind=kind_real),
intent(in) :: rlat, station_height
242 real(kind=kind_real),
intent(out) :: station_phi
245 station_phi = geometric2geopotential(real(rlat,kind=wp), real(station_height,kind=wp))
269 integer,
intent(in) :: nlev
270 real(kind=kind_real),
intent(in) :: rlat
271 real(kind=kind_real),
dimension(nlev),
intent(in) :: model_phi
272 real(kind=kind_real),
dimension(nlev),
intent(out) :: model_z
278 model_z(ilev) = geopotential2geometric(real(rlat,kind=wp), real(model_phi(ilev),kind=wp))
305 type(state1dfm),
intent(in) :: x
307 type(obs1drefrac),
intent(out) :: y
309 integer,
intent(in) :: nlev
310 integer,
dimension(nlev),
intent(in) :: ichk
311 real(kind=kind_real),
intent(in) :: rlat, rlon
312 real(kind=kind_real),
intent(in) :: station_phi
313 real(kind=dp),
intent(in) :: ob_time
315 real(kind=kind_real) :: rlon_local
318 y%time = real(ob_time,kind=wp)
319 y%lat = real(rlat,kind=wp)
321 if (rlon_local .gt. 180) rlon_local = rlon_local - 360.
322 y%lon = real(rlon_local,kind=wp)
327 if (
associated(y%refrac))
then
329 deallocate(y%weights)
336 allocate(y%refrac(1:nlev))
337 allocate(y%weights(1:nlev))
338 allocate(y%geop(1:nlev))
341 if (ichk(i) .le. 0)
then
342 y%weights(i) = 1.0_wp
344 y%weights(i) = 0.0_wp
346 y%geop(i) = x%geop(i)
364 type(state1dfm),
intent(in) :: x
366 type(obs1drefrac),
intent(out) :: y,y_p
368 integer,
intent(in) :: nlev
369 real(kind=kind_real),
intent(in) :: rlat,rlon
370 real(kind=kind_real) :: rlon_local
373 y%time = real(0.0, kind=wp)
374 y%lat = real(rlat,kind=wp)
376 if (rlon_local .gt. 180) rlon_local = rlon_local - 360.
377 y%lon = real(rlon_local,kind=wp)
381 allocate(y%refrac(1:nlev))
382 allocate(y%weights(1:nlev))
383 allocate(y%geop(1:nlev))
384 allocate(y_p%refrac(1:nlev))
385 allocate(y_p%weights(1:nlev))
386 allocate(y_p%geop(1:nlev))
392 y%geop(:) = x%geop(:)
393 y_p%geop(:) = x%geop(:)
421 integer,
intent(in) :: lm
422 real(kind=kind_real),
intent(in),
dimension(lm) :: model_refrac, model_z
423 real(kind=kind_real),
intent(in) :: ob_terr
424 real(kind=kind_real),
intent(out) :: model_ztd
425 logical,
intent(inout) :: l_linear
428 integer,
parameter :: max_string = 800
429 character(max_string) :: err_msg
430 real(kind=kind_real) :: ddzd, scaled_refrac, c_i
440 if ( model_refrac(k) <= 0 .or. model_refrac(k+1) <= 0 )
then
441 write(err_msg,
'(a,2es13.3)')
' unphysical refractivity ', &
442 model_refrac(k), model_refrac(k+1)
443 call fckit_log%info(err_msg)
447 if ( ob_terr < model_z(k) )
then
448 c_i = ( log(model_refrac(k+1)) - log(model_refrac(k)) ) / &
449 ( model_z(k) - model_z(k+1) )
451 write(err_msg,
'(a,2es13.3)')
' model refractivity repeating1 ', &
452 model_refrac(k), model_refrac(k+1)
453 call fckit_log%info(err_msg)
455 ddzd = model_refrac(k)*(model_z(k+1) - ob_terr)
458 ddzd = -1.0 * model_refrac(k)/c_i * exp(c_i*model_z(k)) * &
459 ( exp(-c_i*model_z(k+1)) - exp(-c_i*ob_terr) )
461 else if ( ob_terr >= model_z(k))
then
464 if ( model_refrac(k) <= 0 .or. model_refrac(k-1) <= 0 )
then
465 write(err_msg,
'(a,2es13.3)')
' unphysical refractivity ', &
466 model_refrac(k), model_refrac(k-1)
467 call fckit_log%info(err_msg)
471 if ( ob_terr >= model_z(k-1) .and. ob_terr < model_z(k) )
then
472 c_i = ( log(model_refrac(k)) - log(model_refrac(k-1)) ) / &
473 ( model_z(k-1) - model_z(k) )
475 write(err_msg,
'(a,2es13.3)')
' model refractivity repeating2 ', &
476 model_refrac(k), model_refrac(k-1)
477 call fckit_log%info(err_msg)
479 ddzd = model_refrac(k) * ( ob_terr - model_z(k-1) )
483 scaled_refrac = model_refrac(k-1) * exp( -c_i * (ob_terr - model_z(k-1)) )
484 ddzd = -1.0 * scaled_refrac/c_i * exp(c_i*ob_terr) * &
485 ( exp(-c_i*model_z(k)) - exp(-c_i*ob_terr) )
488 ddzd = 0.5*(model_refrac(k)+model_refrac(k-1))*(model_z(k) - model_z(k-1))
491 model_ztd = model_ztd + ddzd
495 model_ztd = model_ztd * 1.e-6
503 type(state1dfm),
intent(inout) :: x
504 type(obs1drefrac),
intent(inout) :: y
506 if (
associated(x%temp))
deallocate(x%temp)
507 if (
associated(x%shum))
deallocate(x%shum)
508 if (
associated(x%pres))
deallocate(x%pres)
509 if (
associated(x%geop))
deallocate(x%geop)
511 if (
associated(y%refrac))
deallocate(y%refrac)
512 if (
associated(y%geop))
deallocate(y%geop)
513 if (
associated(y%weights))
deallocate(y%weights)
521 type(state1dfm),
intent(inout) :: x,x_p
522 type(obs1drefrac),
intent(inout) :: y,y_p
535 deallocate(y_p%refrac)
537 deallocate(y%weights)
538 deallocate(y_p%weights)
Fortran module to handle ground-based gnss observations following the ROPP (2018 Aug) implementation.
subroutine, public ropp_tidy_up_1d(x, y)
subroutine, public calc_model_z(nlev, rlat, model_phi, model_z)
subroutine, public ropp_tidy_up_tlad_1d(x, x_p, y, y_p)
subroutine, public init_ropp_1d_obvec(nlev, ichk, ob_time, rlat, rlon, station_phi, x, y)
subroutine, public gnss_ztd_integral(lm, model_refrac, model_z, ob_terr, model_ztd, l_linear)
subroutine, public init_ropp_1d_statevec_ad(temp_d, shum_d, pres_d, phi_d, lm, x_ad, iflip)
subroutine, public calc_station_phi(rlat, station_height, station_phi)
subroutine, public init_ropp_1d_obvec_tlad(nlev, rlat, rlon, x, y, y_p)
subroutine, public init_ropp_1d_statevec(step_time, rlon, rlat, temp, shum, pres, phi, lm, z_sfc, x, iflip)