9 use datetime_mod,
only: datetime
11 use kinds,
only: kind_real
12 use ufo_geovals_mod,
only: ufo_geovals
13 use ufo_locations_mod,
only: ufo_locations
14 use unstructured_interpolation_mod,
only: unstrc_interp
33 type(unstrc_interp),
allocatable :: horiz_interp(:)
36 logical,
allocatable :: horiz_interp_init(:)
44 procedure :: create => soca_getvalues_create
47 procedure :: delete => soca_getvalues_delete
55 procedure :: get_interp => soca_getvalues_getinterp
58 procedure :: fill_geovals=> soca_getvalues_fillgeovals
61 procedure :: fill_geovals_ad=> soca_getvalues_fillgeovals_ad
77 subroutine soca_getvalues_create(self, geom, locs)
80 type(ufo_locations),
intent(in) :: locs
83 allocate(self%horiz_interp(6))
84 allocate(self%horiz_interp_init(6))
85 self%horiz_interp_init = .false.
87 end subroutine soca_getvalues_create
101 function soca_getvalues_getinterp(self, geom, grid, masked, locs)
result(idx)
103 type(
soca_geom),
target,
intent(in) :: geom
104 character(len=1),
intent(in) :: grid
105 logical,
intent(in) :: masked
106 type(ufo_locations),
intent(in) :: locs
109 integer :: isc, iec, jsc, jec
110 integer :: ngrid_in, ngrid_out
112 real(8),
allocatable,
dimension(:) :: locs_lons, locs_lats
113 real(kind=kind_real),
allocatable :: lats_in(:), lons_in(:)
115 real(kind=kind_real),
pointer :: mask(:,:) => null()
116 real(kind=kind_real),
pointer :: lon(:,:) => null()
117 real(kind=kind_real),
pointer :: lat(:,:) => null()
121 character(len=8) :: wtype =
'barycent'
141 call abor1_ftn(
'error in soca_getvalues_setupinterp. grid: '//grid)
143 if (masked) idx = idx + 1
146 if (self%horiz_interp_init(idx))
return
149 isc = geom%isc ; iec = geom%iec
150 jsc = geom%jsc ; jec = geom%jec
153 ngrid_out = locs%nlocs()
154 allocate(locs_lons(ngrid_out), locs_lats(ngrid_out))
155 call locs%get_lons(locs_lons)
156 call locs%get_lats(locs_lats)
158 if ( .not. masked )
then
160 ngrid_in = (iec - isc + 1) * (jec - jsc + 1)
161 allocate(lats_in(ngrid_in), lons_in(ngrid_in))
162 lons_in = reshape(lon(isc:iec,jsc:jec), (/ngrid_in/))
163 lats_in = reshape(lat(isc:iec,jsc:jec), (/ngrid_in/))
166 ngrid_in = count(mask(isc:iec,jsc:jec) > 0)
167 allocate(lats_in(ngrid_in), lons_in(ngrid_in))
168 lons_in = pack(lon(isc:iec,jsc:jec), mask=mask(isc:iec,jsc:jec) > 0)
169 lats_in = pack(lat(isc:iec,jsc:jec), mask=mask(isc:iec,jsc:jec) > 0)
172 call self%horiz_interp(idx)%create(geom%f_comm, nn, wtype, &
173 ngrid_in, lats_in, lons_in, &
174 ngrid_out, locs_lats, locs_lons)
175 self%horiz_interp_init(idx) = .true.
184 subroutine soca_getvalues_delete(self)
187 deallocate(self%horiz_interp)
188 deallocate(self%horiz_interp_init)
189 end subroutine soca_getvalues_delete
198 subroutine soca_getvalues_fillgeovals(self, geom, fld, t1, t2, locs, geovals)
202 type(datetime),
intent(in) :: t1
203 type(datetime),
intent(in) :: t2
204 type(ufo_locations),
intent(in) :: locs
205 type(ufo_geovals),
intent(inout) :: geovals
207 logical(c_bool),
allocatable :: time_mask(:)
209 integer :: ivar, nlocs, n
210 integer :: ival, nval, indx
211 integer :: isc, iec, jsc, jec
213 real(kind=kind_real),
allocatable :: gom_window(:)
214 real(kind=kind_real),
allocatable :: fld3d(:,:,:), fld3d_un(:)
216 integer :: interp_idx = -1
219 isc = geom%isc ; iec = geom%iec
220 jsc = geom%jsc ; jec = geom%jec
223 allocate(time_mask(locs%nlocs()))
224 call locs%get_timemask(t1,t2,time_mask)
227 do ivar = 1, geovals%nvar
229 call fld%get(geovals%variables(ivar), fldptr)
230 if (fldptr%metadata%dummy_atm) cycle
234 if ( geovals%geovals(ivar)%nlocs == 0 )
return
236 allocate(gom_window(locs%nlocs()))
237 allocate(fld3d(isc:iec,jsc:jec,1:nval))
239 masked = fldptr%metadata%masked
240 fld3d = fldptr%val(isc:iec,jsc:jec,1:nval)
243 interp_idx = self%get_interp(geom, fldptr%metadata%grid, masked, locs)
247 ns = count(fldptr%mask(isc:iec,jsc:jec) > 0 )
248 if (.not.
allocated(fld3d_un))
allocate(fld3d_un(ns))
249 fld3d_un = pack(fld3d(isc:iec,jsc:jec,ival), mask=fldptr%mask(isc:iec,jsc:jec) > 0)
251 ns = (iec - isc + 1) * (jec - jsc + 1)
252 if (.not.
allocated(fld3d_un))
allocate(fld3d_un(ns))
253 fld3d_un = reshape(fld3d(isc:iec,jsc:jec,ival), (/ns/))
255 call self%horiz_interp(interp_idx)%apply(fld3d_un(1:ns), gom_window)
258 do indx = 1, locs%nlocs()
259 if (time_mask(indx))
then
260 geovals%geovals(ivar)%vals(ival, indx) = gom_window(indx)
268 deallocate(gom_window)
272 geovals%linit = .true.
273 end subroutine soca_getvalues_fillgeovals
282 subroutine soca_getvalues_fillgeovals_ad(self, geom, incr, t1, t2, locs, geovals)
286 type(datetime),
intent(in) :: t1
287 type(datetime),
intent(in) :: t2
288 type(ufo_locations),
intent(in) :: locs
289 type(ufo_geovals),
intent(in) :: geovals
291 logical(c_bool),
allocatable :: time_mask(:)
293 integer :: ivar, nlocs, n
294 integer :: ival, nval, indx
296 integer :: isc, iec, jsc, jec
298 real(kind=kind_real),
allocatable :: gom_window(:,:)
299 real(kind=kind_real),
allocatable :: gom_window_ival(:)
300 real(kind=kind_real),
allocatable :: incr3d(:,:,:), incr3d_un(:)
303 integer :: interp_idx = -1
306 isc = geom%isc ; iec = geom%iec
307 jsc = geom%jsc ; jec = geom%jec
310 allocate(time_mask(locs%nlocs()))
311 call locs%get_timemask(t1,t2,time_mask)
312 allocate(gom_window_ival(locs%nlocs()))
314 do ivar = 1, geovals%nvar
315 call incr%get(geovals%variables(ivar), field)
319 allocate(gom_window(nval,locs%nlocs()))
320 allocate(incr3d(isc:iec,jsc:jec,1:nval))
321 incr3d = 0.0_kind_real
322 gom_window = 0.0_kind_real
325 masked = field%metadata%masked
329 ns = count(field%mask(isc:iec,jsc:jec) > 0)
335 if (.not.
allocated(incr3d_un))
allocate(incr3d_un(ns))
337 interp_idx = self%get_interp(geom, field%metadata%grid, masked, locs)
340 do indx = 1, locs%nlocs()
341 if (time_mask(indx))
then
342 gom_window(ival, indx) = geovals%geovals(ivar)%vals(ival, indx)
345 gom_window_ival = gom_window(ival,1:locs%nlocs())
348 incr3d_un = pack(incr3d(isc:iec,jsc:jec,ival), mask = field%mask(isc:iec,jsc:jec) >0)
349 call self%horiz_interp(interp_idx)%apply_ad(incr3d_un, gom_window_ival)
350 incr3d(isc:iec,jsc:jec,ival) = unpack(incr3d_un, &
351 mask = field%mask(isc:iec,jsc:jec) >0, &
352 field = incr3d(isc:iec,jsc:jec,ival))
354 incr3d_un = reshape(incr3d(isc:iec,jsc:jec,ival), (/ns/))
355 call self%horiz_interp(interp_idx)%apply_ad(incr3d_un(1:ns), gom_window_ival)
356 incr3d(isc:iec,jsc:jec,ival) = reshape(incr3d_un(1:ns),(/ni,nj/))
360 field%val(isc:iec, jsc:jec, 1:nval) = field%val(isc:iec, jsc:jec, 1:nval) + &
361 incr3d(isc:iec, jsc:jec, 1:nval)
365 deallocate(gom_window)
369 deallocate(gom_window_ival)
371 end subroutine soca_getvalues_fillgeovals_ad
Handle fields for the model.
Holds all data and metadata related to a single field variable.
A collection of soca_field types representing a collective state or increment.
Interpolation between model and observation locations.