11 use fckit_mpi_module,
only: fckit_mpi_sum
12 use fckit_configuration_module,
only: fckit_configuration
15 use datetime_mod,
only: datetime
16 use kinds,
only: kind_real
17 use unstructured_interpolation_mod
20 use interpolatorbump_mod,
only: bump_interpolator
24 use ufo_geovals_mod,
only: ufo_geovals
29 use mpas_derived_types
30 use mpas_field_routines
31 use mpas_kind_types,
only: strkind
32 use mpas_pool_routines
33 use mpas_dmpar,
only: mpas_dmpar_exch_halo_field
55 logical,
public :: use_bump_interp
56 type(bump_interpolator),
public :: bumpinterp
57 type(unstrc_interp),
public :: unsinterp
73 #define LISTED_TYPE mpasjedi_getvalues
76 #include <oops/util/linkedList_i.f>
89 #include <oops/util/linkedList_c.f>
103 type(ufo_locations),
intent(in) :: locs
104 type(fckit_configuration),
intent(in) :: f_conf
106 real(kind=kind_real),
allocatable :: lons(:), lats(:)
108 character (len=:),
allocatable :: interp_type
111 allocate(lons(nlocs), lats(nlocs))
112 call locs%get_lons(lons)
113 call locs%get_lats(lats)
115 if (f_conf%get(
"interpolation type", interp_type))
then
116 select case (interp_type)
118 self%use_bump_interp = .true.
119 case (
'unstructured')
120 self%use_bump_interp = .false.
122 write(
message,*)
'--> getvalues_base_create: interpolation type: ',interp_type,
' not implemented'
126 self%use_bump_interp = .true.
129 if (self%use_bump_interp)
then
130 call self%bumpinterp%init(geom%f_comm, afunctionspace_in=geom%afunctionspace, lon_out=lons, lat_out=lats, &
131 & nl=geom%nVertLevels)
136 if (
allocated(interp_type))
deallocate(interp_type)
137 deallocate(lons, lats)
147 subroutine create(self, geom, locs, f_conf)
151 type(ufo_locations),
intent(in) :: locs
152 type(fckit_configuration),
intent(in) :: f_conf
165 if (self%use_bump_interp)
then
166 call self%bumpinterp%delete()
168 call self%unsinterp%delete()
195 type(datetime),
intent(in) :: t1
196 type(datetime),
intent(in) :: t2
197 type(ufo_locations),
intent(in) :: locs
198 type(ufo_geovals),
intent(inout) :: gom
200 logical(c_bool),
allocatable :: time_mask(:)
201 integer :: jvar, jlev, ilev, jloc, ndims
202 integer :: ncells, maxlevels, nlevels, nlocs, nlocsg
203 integer,
allocatable ::obs_field_int(:,:)
204 real(kind=kind_real),
allocatable :: mod_field(:,:), obs_field(:,:)
206 character(len=MAXVARLEN) :: geovar
208 type(mpas_pool_iterator_type) :: poolitr
209 real(kind=kind_real),
pointer :: ptrr1(:)
210 real(kind=kind_real),
pointer :: ptrr2(:,:)
211 integer,
pointer :: ptri1(:)
212 integer,
pointer :: ptri2(:,:)
216 ncells = geom % nCellsSolve
217 nlocs = locs % nlocs()
221 call geom%f_comm%allreduce(nlocs,nlocsg,fckit_mpi_sum())
222 if (nlocsg == 0)
then
228 allocate(time_mask(nlocs))
229 call locs%get_timemask(t1, t2, time_mask)
233 maxlevels = geom%nVertLevelsP1
234 allocate(mod_field(ncells,maxlevels))
235 allocate(obs_field(nlocs,maxlevels))
236 allocate(obs_field_int(nlocs,1))
238 call mpas_pool_begin_iteration(state%subFields)
239 do while ( mpas_pool_get_next_member(state%subFields, poolitr) )
240 if (poolitr % memberType == mpas_pool_field)
then
242 geovar = trim(poolitr % memberName)
243 ndims = poolitr % nDims
245 jvar = ufo_vars_getindex(gom%variables, geovar)
246 if ( jvar < 1 ) cycle
248 if (poolitr % dataType == mpas_pool_real)
then
249 nlevels = gom%geovals(jvar)%nval
252 call state%get(geovar, ptrr1)
253 mod_field(:,1) = ptrr1(1:ncells)
254 else if (ndims == 2)
then
255 call state%get(geovar, ptrr2)
256 mod_field(:,1:nlevels) = transpose(ptrr2(1:nlevels,1:ncells))
258 write(
message,*)
'--> fill_geovals: nDims == ',ndims,
' not handled for reals'
265 if (self%use_bump_interp)
then
266 call self%bumpinterp%apply(mod_field(1:ncells,1:nlevels), &
267 obs_field(:,1:nlevels), &
271 call self%unsinterp%apply(mod_field(:,jlev), &
276 if (time_mask(jloc))
then
279 ilev = nlevels - jlev + 1
280 gom%geovals(jvar)%vals(ilev,jloc) = obs_field(jloc,jlev)
284 else if (poolitr % dataType == mpas_pool_integer)
then
286 call state%get(geovar, ptri1)
287 mod_field(:,1) = real(ptri1(1:ncells), kind_real)
289 write(
message,*)
'--> fill_geovals: nDims == ',ndims,
' not handled for integers'
293 jvar = ufo_vars_getindex(gom%variables, poolitr % memberName)
294 if (self%use_bump_interp)
then
295 call self%integer_interpolation_bump(ncells, nlocs, &
296 ptri1, obs_field_int, gom, jvar, time_mask)
298 call self%integer_interpolation_unstructured(ncells, nlocs, &
299 ptri1, mod_field(:,1), gom, jvar, time_mask)
305 deallocate(mod_field)
306 deallocate(obs_field)
307 deallocate(obs_field_int)
308 deallocate(time_mask)
324 real(kind=kind_real),
allocatable,
intent(in) :: lats_obs(:)
325 real(kind=kind_real),
allocatable,
intent(in) :: lons_obs(:)
327 integer :: nn, ngrid_in
328 character(len=8) :: wtype =
'barycent'
329 real(kind=kind_real),
allocatable :: lats_in(:), lons_in(:)
333 ngrid_in = grid%nCellsSolve
337 allocate( lats_in(ngrid_in) )
338 allocate( lons_in(ngrid_in) )
345 call self%unsinterp%create(grid%f_comm, nn, wtype, &
346 ngrid_in, lats_in, lons_in, &
347 size(lats_obs), lats_obs, lons_obs)
363 data_in, obs_field_int, gom, jvar, time_mask)
367 integer,
intent(in) :: ngrid
368 integer,
intent(in) :: nlocs
369 integer,
dimension(:),
intent(in) :: data_in
370 integer,
allocatable,
intent(inout) :: obs_field_int(:,:)
371 type(ufo_geovals),
intent(inout) :: gom
372 integer,
intent(in) :: jvar
373 logical(c_bool),
intent(in) :: time_mask(nlocs)
380 call self%bumpinterp%apply(data_in(1:ngrid), obs_field_int)
382 if (time_mask(jloc))
then
385 gom%geovals(jvar)%vals(1,jloc) = real(obs_field_int(jloc,1), kind_real)
398 data_in, work_field, gom, jvar, time_mask)
402 integer,
intent(in) :: ngrid
403 integer,
intent(in) :: nlocs
404 integer,
dimension(:),
intent(in) :: data_in
405 real(kind=kind_real),
intent(inout) :: work_field(ngrid)
406 type(ufo_geovals),
intent(inout) :: gom
407 integer,
intent(in) :: jvar
408 logical(c_bool),
intent(in) :: time_mask(nlocs)
411 real(kind=kind_real),
dimension(nlocs) :: interpolated_data
416 work_field = real(data_in(1:ngrid), kind_real)
419 if (time_mask(jloc))
then
420 gom%geovals(jvar)%vals(1,jloc) = interpolated_data(jloc)
real(kind=kind_real), parameter mpas_jedi_rad2deg_kr
subroutine integer_interpolation_bump(self, ngrid, nlocs, data_in, obs_field_int, gom, jvar, time_mask)
Performs interpolation of integer fields using BUMP.
subroutine integer_interpolation_unstructured(self, ngrid, nlocs, data_in, work_field, gom, jvar, time_mask)
Performs interpolation of integer fields using unstructured interpolation.
character(len=1024) message
subroutine create(self, geom, locs, f_conf)
GetValues class 'create' logic.
subroutine, public getvalues_base_create(self, geom, locs, f_conf)
Linked list implementation.
type(registry_t), public mpas_getvalues_registry
Linked list interface - defines registry_t type.
subroutine, public fill_geovals(self, geom, state, t1, t2, locs, gom)
Interpolates from geovar mpas_fields to populate ufo_geovals.
subroutine, public getvalues_base_delete(self)
GetValues base class 'delete' logic.
subroutine delete(self)
GetValues class 'delete' logic.
subroutine initialize_uns_interp(self, grid, lats_obs, lons_obs)
Initializes an unstructured interpolation type.
subroutine, public unsinterp_integer_apply(unsinterp, field_in, field_out)
Fortran derived type to hold MPAS field.
Fortran derived type to hold geometry definition.