10 use oops_variables_mod
20 type(oops_variables),
public :: obsvars
21 integer,
allocatable,
public :: obsvarindices(:)
23 type(oops_variables),
public :: geovars
25 real(kind_real) :: magl
35 use fckit_configuration_module,
only: fckit_configuration
38 type(fckit_configuration),
intent(in) :: f_conf
39 integer :: nvars, ivar, fact10tmp
42 self%use_fact10 = .false.
44 if (f_conf%has(
"use_fact10"))
call f_conf%get_or_die(
"use_fact10",fact10tmp)
45 if (fact10tmp /= 0)
then
46 self%use_fact10 = .true.
49 nvars = self%obsvars%nvars()
51 call self%geovars%push_back(self%obsvars%variable(ivar))
55 call self%geovars%push_back(
var_z)
63 call self%geovars%push_back(
var_ps)
64 call self%geovars%push_back(
var_prs)
65 call self%geovars%push_back(
var_prsi)
66 call self%geovars%push_back(
var_ts)
67 call self%geovars%push_back(
var_tv)
68 call self%geovars%push_back(
var_q)
69 call self%geovars%push_back(
var_u)
70 call self%geovars%push_back(
var_v)
87 use fckit_log_module,
only: fckit_log
90 integer,
intent(in) :: nvars, nlocs
92 real(c_double),
intent(inout) :: hofx(nvars, nlocs)
93 type(c_ptr),
value,
intent(in) :: obss
94 type(
ufo_geoval),
pointer :: phi, hgt, tsfc, roughlen, psfc, prs, prsi, &
95 tsen, tv, q, u, v, landmask, &
98 integer :: ivar, iobs, iobsvar
99 real(kind_real),
allocatable :: obselev(:), obshgt(:)
100 real(kind_real),
parameter :: minroughlen = 1.0e-4_kind_real
101 character(len=MAXVARLEN) :: geovar
102 character(len=MAXVARLEN) :: var_zdir
103 real(kind_real) :: thv1, thv2, th1, thg, thvg, rib, V2, agl, zbot
104 real(kind_real) :: gzsoz0, gzzoz0
105 real(kind_real) :: redfac, psim, psimz, psih, psihz
106 real(kind_real) :: ttmp1, ttmpg, eg, qg
107 real(kind_real) :: z0, zq0, tvsfc
108 real(kind_real),
parameter :: fv =
rv/
rd - 1.0_kind_real
109 real(kind_real) :: psit, psitz, ust, psiq, psiqz
110 real(kind_real),
parameter :: zint0 = 0.01_kind_real
111 real(kind_real),
parameter :: ka = 2.4e-5_kind_real
112 character(1024) :: debug_msg
116 if (nlocs .lt. 1)
return
155 allocate(obselev(nlocs))
156 call obsspace_get_db(obss,
"MetaData",
"station_elevation", obselev)
159 allocate(obshgt(nlocs))
160 call obsspace_get_db(obss,
"MetaData",
"height", obshgt)
164 z0 = roughlen%vals(1,iobs)
165 if (z0 < minroughlen) z0 = minroughlen
168 if (landmask%vals(1,iobs) < 0.01) zq0 = z0
171 call gsi_tp_to_qs(tsfc%vals(1,iobs), psfc%vals(1,iobs), eg, qg)
172 tvsfc = tsfc%vals(1,iobs) * (1.0_kind_real + fv * qg)
175 call calc_theta(tv%vals(1,iobs), prs%vals(1,iobs), thv1)
176 call calc_theta(tv%vals(2,iobs), prs%vals(2,iobs), thv2)
177 call calc_theta(tsen%vals(1,iobs), prs%vals(1,iobs), th1)
178 call calc_theta(tsfc%vals(1,iobs), psfc%vals(1,iobs), thg)
179 call calc_theta(tvsfc, psfc%vals(1,iobs), thvg)
185 zbot = max(0.1,phi%vals(1,iobs))
186 agl = max(1.0, (obshgt(iobs)-obselev(iobs)))
189 rib = (
grav * zbot / th1) * (thv1 - thvg) / v2
191 gzsoz0 = log(zbot/z0)
196 thg, zbot, agl, psim, psih, psimz, psihz)
198 do iobsvar = 1,
size(self%obsvarindices)
200 ivar = self%obsvarindices(iobsvar)
203 geovar = self%obsvars%variable(iobsvar)
207 select case(trim(geovar))
208 case(
"air_temperature",
"virtual_temperature")
210 psitz = gzzoz0 - psihz
218 hofx(ivar,iobs) = (ttmpg + (ttmp1 - ttmpg)*psitz/psit)*(psfc%vals(1,iobs)/1.0e5_kind_real)**
rd_over_cp
219 case(
"eastward_wind",
"northward_wind")
220 if (self%use_fact10)
then
221 hofx(ivar,iobs) = profile%vals(1,iobs) * rad10%vals(1,iobs)
223 call sfc_wind_fact_gsi(u%vals(1,iobs), v%vals(1,iobs), tsen%vals(1,iobs), q%vals(1,iobs),&
224 psfc%vals(1,iobs), prsi%vals(1,iobs), prsi%vals(2,iobs),&
225 tsfc%vals(1,iobs), z0, landmask%vals(1,iobs), redfac)
226 hofx(ivar,iobs) = profile%vals(1,iobs) * redfac
228 case(
"specific_humidity")
229 ust = max(0.01_kind_real,
von_karman * sqrt(v2) / (gzsoz0 - psim))
230 psiq = log(
von_karman*ust*zbot/ka + zbot/zq0) - psih
231 psiqz = log(
von_karman*ust*agl/ka + agl/zq0) - psihz
232 hofx(ivar,iobs) = qg + (q%vals(1,iobs) - qg)*psiqz/psiq
237 deallocate(obshgt,obselev)
subroutine calc_conv_vel_gsi(u1, v1, thvg, thv1, V2)
subroutine sfc_wind_fact_gsi(u, v, tsen, q, psfc, prsi1, prsi2, skint, z0, lsmask, f10m)
subroutine calc_psi_vars_gsi(rib, gzsoz0, gzzoz0, thv1, thv2, V2, th1, thg, phi1, obshgt, psim, psih, psimz, psihz)
Fortran module for thermodynamic computations and conversions for use in UFO.
subroutine gsi_tp_to_qs(t, p, es, qs)
subroutine calc_theta(t_in, p_in, t_out)
Fortran module for atmsfcinterp observation operator.
subroutine atmsfcinterp_setup_(self, f_conf)
subroutine atmsfcinterp_simobs_(self, geovals_in, obss, nvars, nlocs, hofx)
real(kind_real), parameter, public grav
real(kind_real), parameter, public von_karman
real(kind_real), parameter, public rd
real(kind_real), parameter, public rd_over_cp
real(kind_real), parameter, public rv
subroutine, public ufo_geovals_reorderzdir(self, varname, zdir)
subroutine, public ufo_geovals_copy(self, other)
Copy one GeoVaLs object into another.
subroutine, public ufo_geovals_get_var(self, varname, geoval)
Fortran module with various useful routines.
logical function, public cmp_strings(str1, str2)
character(len=maxvarlen), parameter, public var_sfc_rough
character(len=maxvarlen), parameter, public var_prsi
character(len=maxvarlen), parameter, public var_sfc_lfrac
character(len=maxvarlen), parameter, public var_prs
character(len=maxvarlen), parameter, public var_q
character(len=maxvarlen), parameter, public var_v
character(len=maxvarlen), parameter, public var_z
character(len=maxvarlen), parameter, public var_ts
character(len=maxvarlen), parameter, public var_u
character(len=maxvarlen), parameter, public var_ps
character(len=maxvarlen), parameter, public var_tv
character(len=maxvarlen), parameter, public var_sfc_z
character(len=maxvarlen), parameter, public var_sfc_t
character(len=maxvarlen), parameter, public var_sfc_fact10
Fortran derived type for the observation type.
type to hold interpolated field for one variable, one observation
type to hold interpolated fields required by the obs operators