10 use oops_variables_mod
12 use missing_values_mod
25 type(oops_variables),
public :: obsvars
26 integer,
allocatable,
public :: obsvarindices(:)
28 type(oops_variables),
public :: geovars
29 character(len=MAXVARLEN) :: da_psfc_scheme
41 use fckit_configuration_module,
only: fckit_configuration
42 use fckit_log_module,
only : fckit_log
45 type(fckit_configuration),
intent(in) :: f_conf
46 character(len=:),
allocatable :: str_psfc_scheme, str_var_sfc_geomz, str_var_geomz
47 character(max_string) :: debug_msg
53 if (f_conf%has(
"geovar_geomz"))
then
54 call f_conf%get_or_die(
"geovar_geomz", str_var_geomz)
55 write(debug_msg,*)
"ufo_sfcpcorrected_mod.F90: overriding default var_geomz with ", trim(str_var_geomz)
56 call fckit_log%debug(debug_msg)
59 if (f_conf%has(
"geovar_sfc_geomz"))
then
60 call f_conf%get_or_die(
"geovar_sfc_geomz", str_var_sfc_geomz)
61 write(debug_msg,*)
"ufo_sfcpcorrected_mod.F90: overriding default var_sfc_geomz with ", trim(str_var_sfc_geomz)
62 call fckit_log%debug(debug_msg)
68 self%da_psfc_scheme =
"UKMO"
69 if (f_conf%has(
"da_psfc_scheme"))
then
70 call f_conf%get_or_die(
"da_psfc_scheme",str_psfc_scheme)
71 self%da_psfc_scheme = str_psfc_scheme
81 use fckit_log_module,
only : fckit_log
84 integer,
intent(in) :: nvars, nlocs
86 real(c_double),
intent(inout) :: hofx(nvars, nlocs)
87 type(c_ptr),
value,
intent(in) :: obss
90 real(c_double) :: missing
91 real(kind_real) :: H2000 = 2000.0
92 integer :: nobs, iobs, ivar, iobsvar, k, kbot, idx_geop
93 real(kind_real),
allocatable :: cor_psfc(:)
94 type(
ufo_geoval),
pointer :: model_ps, model_p, model_sfc_geomz, model_tv, model_geomz
95 character(len=*),
parameter :: myname_=
"ufo_sfcpcorrected_simobs"
96 character(max_string) :: err_msg
99 logical :: variable_present
100 real(kind_real),
dimension(:),
allocatable :: obs_height, obs_t, obs_q, obs_psfc, obs_lat
101 real(kind_real),
dimension(:),
allocatable :: model_tvs, model_zs, model_level1, model_p_2000, model_tv_2000, model_psfc
102 real(kind_real) :: model_znew
104 missing = missing_value(missing)
105 nobs = obsspace_get_nlocs(obss)
108 if (geovals%nlocs /= nobs)
then
109 write(err_msg,*) myname_,
' error: nlocs of model and obs is inconsistent!'
110 call abor1_ftn(err_msg)
114 allocate(cor_psfc(nobs))
118 allocate(obs_height(nobs))
119 allocate(obs_psfc(nobs))
120 call obsspace_get_db(obss,
"MetaData",
"station_elevation",obs_height)
121 call obsspace_get_db(obss,
"ObsValue",
"surface_pressure", obs_psfc)
124 write(err_msg,
'(a)')
' ufo_sfcpcorrected:'//new_line(
'a')// &
125 ' retrieving GeoVaLs with these names: '//trim(
geovars_list(1))// &
128 call fckit_log%debug(err_msg)
138 if (obs_psfc(iobs).ne.missing)
then
139 if (model_geomz%vals(1,iobs) .gt. model_geomz%vals(model_geomz%nval,iobs))
then
140 write(err_msg,
'(a)')
' ufo_sfcpcorrected:'//new_line(
'a')// &
141 ' Model vertical height profile is from top to bottom'
142 call fckit_log%debug(err_msg)
143 kbot = model_geomz%nval
149 allocate(model_zs(nobs))
150 allocate(model_level1(nobs))
151 allocate(model_psfc(nobs))
158 if (idx_geop.gt.0)
then
159 write(err_msg,
'(a)')
' ufo_sfcpcorrected:'//new_line(
'a')// &
161 ' variable to z-geometric'
162 call fckit_log%debug(err_msg)
163 if (.not.
allocated(obs_lat))
then
164 variable_present = obsspace_has(obss,
"MetaData",
"latitude")
165 if (variable_present)
then
166 call fckit_log%debug(
' allocating obs_lat array')
167 allocate(obs_lat(nobs))
168 call obsspace_get_db(obss,
"MetaData",
"latitude", obs_lat)
170 call abor1_ftn(
'Variable latitude@MetaData does not exist, aborting')
174 if (obs_psfc(iobs).ne.missing)
then
175 do k = 1, model_geomz%nval
177 geopotentialh=model_geomz%vals(k,iobs), &
178 geometricz=model_znew)
179 model_geomz%vals(k,iobs) = model_znew
188 if (idx_geop.gt.0)
then
189 write(err_msg,
'(a)')
' ufo_sfcpcorrected:'//new_line(
'a')// &
191 ' variable to z-sfc-geometric'
192 call fckit_log%debug(err_msg)
193 if (.not.
allocated(obs_lat))
then
194 variable_present = obsspace_has(obss,
"MetaData",
"latitude")
195 if (variable_present)
then
196 call fckit_log%debug(
' allocating obs_lat array')
197 allocate(obs_lat(nobs))
198 call obsspace_get_db(obss,
"MetaData",
"latitude", obs_lat)
200 call abor1_ftn(
'Variable latitude@MetaData does not exist, aborting')
204 if (obs_psfc(iobs).ne.missing)
then
206 geopotentialh=model_sfc_geomz%vals(1,iobs), &
207 geometricz=model_znew)
208 model_sfc_geomz%vals(1,iobs) = model_znew
213 if (
allocated(obs_lat))
deallocate(obs_lat)
215 model_zs = model_sfc_geomz%vals(1,:)
216 model_psfc = model_ps%vals(1,:)
217 model_level1 = model_geomz%vals(kbot,:)
220 select case (trim(self%da_psfc_scheme))
224 variable_present = obsspace_has(obss,
"ObsValue",
"air_temperature")
225 if (variable_present)
then
226 allocate(obs_t(nobs))
227 call obsspace_get_db(obss,
"ObsValue",
"air_temperature", obs_t)
229 variable_present = obsspace_has(obss,
"ObsValue",
"specific_humidity")
230 if (variable_present)
then
231 allocate(obs_q(nobs))
232 call obsspace_get_db(obss,
"ObsValue",
"specific_humidity", obs_q)
236 allocate(model_tvs(nobs))
237 model_tvs = model_tv%vals(kbot,:) +
lclr * ( model_level1 - model_zs )
240 call da_intpsfc_prs(nobs, missing, cor_psfc, obs_height, obs_psfc, model_zs, model_tvs, obs_t, obs_q)
244 deallocate(model_tvs)
248 allocate(model_p_2000(nobs))
249 allocate(model_tv_2000(nobs))
253 call vert_interp_apply(model_p%nval, model_p%vals(:,iobs), model_p_2000(iobs), wi, wf)
254 call vert_interp_apply(model_tv%nval, model_tv%vals(:,iobs), model_tv_2000(iobs), wi, wf)
258 call da_intpsfc_prs_ukmo(nobs, missing, cor_psfc, obs_height, obs_psfc, model_zs, model_psfc, model_tv_2000, model_p_2000)
260 deallocate(model_p_2000)
261 deallocate(model_tv_2000)
264 write(err_msg,*)
"ufo_sfcpcorrected_mod.F90: da_psfc_scheme must be WRFDA or UKMO"
265 call fckit_log%debug(err_msg)
266 call abor1_ftn(err_msg)
270 do iobsvar = 1,
size(self%obsvarindices)
272 ivar = self%obsvarindices(iobsvar)
274 if ( cor_psfc(iobs) /= missing)
then
275 hofx(ivar,iobs) = obs_psfc(iobs) - cor_psfc(iobs) + model_psfc(iobs)
277 hofx(ivar,iobs) = model_psfc(iobs)
282 deallocate(obs_height)
286 deallocate(model_level1)
287 deallocate(model_psfc)
315 integer,
intent (in) :: nobs
316 real(c_double),
intent (in) :: missing
317 real(kind_real),
dimension(nobs),
intent (out) :: P_o2m
318 real(kind_real),
dimension(nobs),
intent (in) :: H_o, P_o
319 real(kind_real),
dimension(nobs),
intent (in) :: H_m, TV_m
320 real(kind_real),
dimension(nobs),
intent (in),
optional :: T_o, Q_o
321 real(kind_real),
dimension(nobs) :: TV_o, TV
326 if (
present(t_o) .and.
present(q_o))
then
327 tv_o = t_o * (1.0 +
t2tv * q_o)
328 else if (
present(t_o) .and. .not.(
present(q_o)))
then
334 tv = 0.5 * (tv_m + tv_o)
339 where ( h_o /= missing .and. p_o /= missing )
340 p_o2m = p_o * exp( - (h_m - h_o) *
grav / (
rd * tv) )
381 integer,
intent (in) :: nobs
382 real(c_double),
intent (in) :: missing
383 real(kind_real),
dimension(nobs),
intent (out) :: P_o2m
384 real(kind_real),
dimension(nobs),
intent (in) :: H_o, P_o
385 real(kind_real),
dimension(nobs),
intent (in) :: H_m, P_m, TV_2000, P_2000
386 real(kind_real) :: ind
387 real(kind_real),
dimension(nobs) :: P_m2o, T_m, T_m2o
393 where ( h_o /= missing .and. p_o /= missing )
396 t_m = tv_2000 * (p_m / p_2000) ** ind
397 t_m2o = t_m +
lclr * ( h_m - h_o)
398 p_m2o = p_m * (t_m2o / t_m) ** (1.0 / ind)
401 p_o2m = p_o * p_m / p_m2o
real(kind_real), parameter, public grav
real(kind_real), parameter, public rd
real(kind_real), parameter, public t2tv
real(kind_real), parameter, public lclr
subroutine, public ufo_geovals_get_var(self, varname, geoval)
Fortran module for sfcpcorrected observation operator.
character(len=maxvarlen), dimension(5) geovars_list
subroutine da_intpsfc_prs_ukmo(nobs, missing, P_o2m, H_o, P_o, H_m, P_m, TV_2000, P_2000)
\Conduct terrain height correction for surface pressure
subroutine ufo_sfcpcorrected_setup(self, f_conf)
subroutine da_intpsfc_prs(nobs, missing, P_o2m, H_o, P_o, H_m, TV_m, T_o, Q_o)
\Conduct terrain height correction for surface pressure
integer, parameter max_string
subroutine ufo_sfcpcorrected_simobs(self, geovals, obss, nvars, nlocs, hofx)
character(len=maxvarlen), parameter, public var_geomz
character(len=maxvarlen), parameter, public var_prs
character(len=maxvarlen), parameter, public var_sfc_geomz
character(len=maxvarlen), parameter, public var_ps
character(len=maxvarlen), parameter, public var_tv
Fortran module to perform linear interpolation.
subroutine vert_interp_weights(nlev, obl, vec, wi, wf)
subroutine vert_interp_apply(nlev, fvec, f, wi, wf)
type to hold interpolated field for one variable, one observation
type to hold interpolated fields required by the obs operators
Fortran derived type for the observation type.