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
39 subroutine init_ropp_1d_statevec(step_time,rlon,rlat, temp,shum,pres,phi,lm,phi_sfc,x, iflip)
58 type(state1dfm),
intent(out) :: x
59 real(kind=dp),
intent(in) :: step_time
60 real(kind=kind_real),
intent(in) :: rlat, rlon
61 real(kind=kind_real),
intent(in) :: phi_sfc
62 integer,
intent(in) :: lm
63 real(kind=kind_real),
dimension(lm),
intent(in) :: temp,shum,pres,phi
66 character(len=250) :: err_msg
67 real(kind=kind_real) :: rlon_local
69 integer,
optional,
intent(in) :: iflip
71 x%direct_ion = .false.
75 x%lat = real(rlat,kind=wp)
77 if (rlon_local .gt. 180) rlon_local = rlon_local - 360.
78 x%lon = real(rlon_local,kind=wp)
79 x%time = real(step_time, kind=wp)
89 if (
associated(x%temp))
deallocate(x%temp)
90 if (
associated(x%shum))
deallocate(x%shum)
91 if (
associated(x%pres))
deallocate(x%pres)
92 if (
associated(x%geop))
deallocate(x%geop)
94 allocate(x%temp(x%n_lev))
95 allocate(x%shum(x%n_lev))
96 allocate(x%pres(x%n_lev))
97 allocate(x%geop(x%n_lev))
102 write(err_msg,
'(4a9,a11)')
'lvl',
'temp',
'shum',
'pres',
'geop'
105 if (
present(iflip) .and. iflip .eq. 1)
then
107 x%temp(n) = real(temp(k),kind=wp)
108 x%shum(n) = real(shum(k),kind=wp)
109 x%pres(n) = real(pres(k),kind=wp)
110 x%geop(n) = real(phi(k),kind=wp)
115 x%temp(k) = real(temp(k),kind=wp)
116 x%shum(k) = real(shum(k),kind=wp)
117 x%pres(k) = real(pres(k),kind=wp)
118 x%geop(k) = real(phi(k),kind=wp)
123 x%geop_sfc = real(phi_sfc,kind=wp)
124 write(err_msg,
'("geop_sfc",f15.2)') x%geop_sfc
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'
186 type(state1dfm),
intent(inout) :: x_ad
187 integer,
intent(in) :: lm
188 real(kind=kind_real),
dimension(lm),
intent(inout) :: temp_d,shum_d,pres_d,phi_d
192 integer,
optional,
intent(in) :: iflip
197 if (
present(iflip) .and. iflip .eq. 1)
then
201 temp_d(k) = temp_d(k) + real(x_ad%temp(n),kind=kind_real)
202 x_ad%temp(n) = 0.0_wp
205 shum_d(k) = shum_d(k) + real(x_ad%shum(n),kind=kind_real)
206 x_ad%shum(n) = 0.0_wp
209 pres_d(k) = pres_d(k) + real(x_ad%pres(n),kind=kind_real)
210 x_ad%pres(n) = 0.0_wp
213 phi_d(k) = phi_d(k) + real(x_ad%geop(n),kind=kind_real)
214 x_ad%geop(n) = 0.0_wp
220 temp_d(k) = temp_d(k) + real(x_ad%temp(k),kind=kind_real)
221 x_ad%temp(k) = 0.0_wp
222 shum_d(k) = shum_d(k) + real(x_ad%shum(k),kind=kind_real)
223 x_ad%shum(k) = 0.0_wp
224 pres_d(k) = pres_d(k) + real(x_ad%pres(k),kind=kind_real)
225 x_ad%pres(k) = 0.0_wp
226 phi_d(k) = phi_d(k) + real(x_ad%geop(k),kind=kind_real)
227 x_ad%geop(k) = 0.0_wp
254 real(kind=kind_real),
intent(in) :: rlat, station_height
255 real(kind=kind_real),
intent(out) :: station_phi
258 station_phi = geometric2geopotential(real(rlat,kind=wp), real(station_height,kind=wp))
282 integer,
intent(in) :: nlev
283 real(kind=kind_real),
intent(in) :: rlat
284 real(kind=kind_real),
dimension(nlev),
intent(in) :: model_phi
285 real(kind=kind_real),
dimension(nlev),
intent(out) :: model_z
291 model_z(ilev) = geopotential2geometric(real(rlat,kind=wp), real(model_phi(ilev),kind=wp))
318 type(state1dfm),
intent(in) :: x
320 type(obs1drefrac),
intent(out) :: y
322 integer,
intent(in) :: nlev
323 integer,
dimension(nlev),
intent(in) :: ichk
324 real(kind=kind_real),
intent(in) :: rlat, rlon, station_phi
325 real(kind=dp),
intent(in) :: ob_time
327 real(kind=wp) :: r8lat
328 real(kind=kind_real) :: rlon_local
329 character(len=250) :: err_msg
332 y%time = real(ob_time,kind=wp)
333 r8lat = real(rlat,kind=wp)
336 if (rlon_local .gt. 180) rlon_local = rlon_local - 360.
337 y%lon = real(rlon_local,kind=wp)
342 if (
associated(y%refrac))
then
344 deallocate(y%weights)
351 allocate(y%refrac(1:nlev))
352 allocate(y%weights(1:nlev))
353 allocate(y%geop(1:nlev))
356 if (ichk(i) .le. 0)
then
357 y%weights(i) = 1.0_wp
359 y%weights(i) = 0.0_wp
361 y%geop(i) = x%geop(i)
366 write(err_msg,
'(a9,2a11,2a15)')
'ROPPyvec:',
'lat',
'lon',
'geop(1)',
'station_phi'
367 call fckit_log%debug(err_msg)
368 write(err_msg,
'(9x,2f11.2,2f15.2)') y%lat, y%lon, y%geop(1), station_phi
369 call fckit_log%debug(err_msg)
385 type(state1dfm),
intent(in) :: x
387 type(obs1drefrac),
intent(out) :: y,y_p
389 integer,
intent(in) :: nlev
390 real(kind=kind_real),
intent(in) :: rlat,rlon
391 real(kind=wp) :: r8lat
392 real(kind=kind_real) :: rlon_local
395 y%time = real(0.0, kind=wp)
396 r8lat = real(rlat,kind=wp)
397 y%lat = real(rlat,kind=wp)
399 if (rlon_local .gt. 180) rlon_local = rlon_local - 360.
400 y%lon = real(rlon_local,kind=wp)
404 allocate(y%refrac(1:nlev))
405 allocate(y%weights(1:nlev))
406 allocate(y%geop(1:nlev))
407 allocate(y_p%refrac(1:nlev))
408 allocate(y_p%weights(1:nlev))
409 allocate(y_p%geop(1:nlev))
415 y%geop(:) = x%geop(:)
416 y_p%geop(:) = x%geop(:)
429 integer,
intent(in) :: lm
430 real(kind=kind_real),
intent(in),
dimension(lm) :: model_refrac, model_z
431 real(kind=kind_real),
intent(in) :: ob_terr
432 real(kind=kind_real),
intent(out) :: model_ztd
433 logical,
intent(inout) :: l_linear
435 integer,
parameter :: max_string = 800
436 character(max_string) :: err_msg
447 if ( model_refrac(k) <= 0 .or. model_refrac(k+1) <= 0 )
then
448 write(err_msg,
'(a,2es13.3)')
' unphysical refractivity ', &
449 model_refrac(k), model_refrac(k+1)
450 call fckit_log%info(err_msg)
454 if ( ob_terr < model_z(k) )
then
455 c_i = ( log(model_refrac(k+1)) - log(model_refrac(k)) ) / &
456 ( model_z(k) - model_z(k+1) )
458 write(err_msg,
'(a,2es13.3)')
' model refractivity repeating1 ', &
459 model_refrac(k), model_refrac(k+1)
460 call fckit_log%info(err_msg)
462 ddzd = model_refrac(k)*(model_z(k+1) - ob_terr)
465 ddzd = -1.0 * model_refrac(k)/c_i * exp(c_i*model_z(k)) * &
466 ( exp(-c_i*model_z(k+1)) - exp(-c_i*ob_terr) )
472 else if ( ob_terr >= model_z(k))
then
475 if ( model_refrac(k) <= 0 .or. model_refrac(k-1) <= 0 )
then
476 write(err_msg,
'(a,2es13.3)')
' unphysical refractivity ', &
477 model_refrac(k), model_refrac(k-1)
478 call fckit_log%info(err_msg)
482 if ( ob_terr >= model_z(k-1) .and. ob_terr < model_z(k) )
then
483 c_i = ( log(model_refrac(k)) - log(model_refrac(k-1)) ) / &
484 ( model_z(k-1) - model_z(k) )
486 write(err_msg,
'(a,2es13.3)')
' model refractivity repeating2 ', &
487 model_refrac(k), model_refrac(k-1)
488 call fckit_log%info(err_msg)
490 ddzd = model_refrac(k) * ( ob_terr - model_z(k-1) )
491 ddzd = ddzd + 0.5*(model_refrac(k)+model_refrac(k-1))*(model_z(k) - ob_terr)
494 ddzd = -1.0 * model_refrac(k-1)/c_i * exp(c_i*ob_terr) * &
495 ( exp(-c_i*model_z(k)) - exp(-c_i*ob_terr) )
500 ddzd = ddzd + 0.5*(model_refrac(k)+model_refrac(k-1))*(model_z(k) - ob_terr)
502 ddzd = 0.5*(model_refrac(k)+model_refrac(k-1))*(model_z(k) - model_z(k-1))
505 model_ztd = model_ztd + ddzd
509 model_ztd = model_ztd * 1.e-6
517 type(state1dfm),
intent(inout) :: x
518 type(obs1drefrac),
intent(inout) :: y
520 if (
associated(x%temp))
deallocate(x%temp)
521 if (
associated(x%shum))
deallocate(x%shum)
522 if (
associated(x%pres))
deallocate(x%pres)
523 if (
associated(x%geop))
deallocate(x%geop)
525 if (
associated(y%refrac))
deallocate(y%refrac)
526 if (
associated(y%geop))
deallocate(y%geop)
527 if (
associated(y%weights))
deallocate(y%weights)
535 type(state1dfm),
intent(inout) :: x,x_p
536 type(obs1drefrac),
intent(inout) :: y,y_p
549 deallocate(y_p%refrac)
551 deallocate(y%weights)
552 deallocate(y_p%weights)
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 ropp_tidy_up_1d(x, y)
subroutine, public init_ropp_1d_obvec_tlad(nlev, rlat, rlon, x, y, y_p)
subroutine, public calc_station_phi(rlat, station_height, station_phi)
subroutine, public init_ropp_1d_statevec_ad(temp_d, shum_d, pres_d, phi_d, lm, x_ad, iflip)
subroutine, public gnss_ztd_integral(lm, model_refrac, model_z, ob_terr, model_ztd, l_linear)
subroutine, public ropp_tidy_up_tlad_1d(x, x_p, y, y_p)