9 use fckit_mpi_module,
only: fckit_mpi_comm, fckit_mpi_max, fckit_mpi_min
12 use unstructured_interpolation_mod,
only: unstrc_interp
30 character(len=32) :: interp_type
32 type(unstrc_interp) :: unsinterp
33 logical :: need_bump, need_bary
48 subroutine create(self, interp_type_in, integer_interp, geom_in, geom_ou)
51 character(len=*),
intent(in) :: interp_type_in
52 logical,
intent(in) :: integer_interp
58 character(len=32) :: us_interp_type
60 self%need_bump = .false.
61 self%need_bary = .false.
63 self%interp_type = trim(interp_type_in)
66 if (trim(self%interp_type) ==
'bump')
then
67 self%need_bump = .true.
68 elseif (trim(self%interp_type) ==
'barycent')
then
69 self%need_bary = .true.
70 us_interp_type = trim(self%interp_type)
72 call abor1_ftn(
"In fv3jedi_interpolation_mod.create: interp_type should be bump or barycent")
75 if (integer_interp)
then
76 self%need_bary = .true.
77 if (us_interp_type ==
'') us_interp_type =
'barycent'
82 if (self%need_bump)
then
83 call self%bump%setup(geom_in%f_comm, geom_in%isc, geom_in%iec, geom_in%jsc, geom_in%jec, geom_in%npz, &
84 geom_in%grid_lon(geom_in%isc:geom_in%iec, geom_in%jsc:geom_in%jec), &
85 geom_in%grid_lat(geom_in%isc:geom_in%iec, geom_in%jsc:geom_in%jec), &
92 if (self%need_bary)
then
93 call self%unsinterp%create( geom_in%f_comm, self%nnearest, trim(us_interp_type), &
106 if (self%need_bump)
call self%bump%delete()
107 if (self%need_bary)
call self%unsinterp%delete()
113 subroutine apply(self, nf, geom_in, fields_in, geom_ou, fields_ou)
116 integer,
intent(in) :: nf
123 integer :: var, i, j, k, n
124 real(kind=
kind_real),
allocatable :: field_in(:), field_ou(:), field_ou_2d(:,:)
127 real(kind=
kind_real),
allocatable :: ua(:,:,:)
128 real(kind=
kind_real),
allocatable :: va(:,:,:)
129 real(kind=
kind_real),
allocatable :: ud(:,:,:)
130 real(kind=
kind_real),
allocatable :: vd(:,:,:)
146 allocate(ua(geom_in%isc:geom_in%iec,geom_in%jsc:geom_in%jec,geom_in%npz))
147 allocate(va(geom_in%isc:geom_in%iec,geom_in%jsc:geom_in%jec,geom_in%npz))
149 call d2a(geom_in, u_in%array, v_in%array, ua, va)
152 deallocate(u_in%array)
153 deallocate(v_in%array)
154 allocate(u_in%array(geom_in%isc:geom_in%iec,geom_in%jsc:geom_in%jec,1:geom_in%npz))
155 allocate(v_in%array(geom_in%isc:geom_in%iec,geom_in%jsc:geom_in%jec,1:geom_in%npz))
160 deallocate(u_ou%array)
161 deallocate(v_ou%array)
162 allocate(u_ou%array(geom_ou%isc:geom_ou%iec,geom_ou%jsc:geom_ou%jec,1:geom_ou%npz))
163 allocate(v_ou%array(geom_ou%isc:geom_ou%iec,geom_ou%jsc:geom_ou%jec,1:geom_ou%npz))
170 u_in%space =
'magnitude'
171 v_in%space =
'magnitude'
181 if (.not. fields_in(var)%integerfield .and. trim(fields_in(var)%space) ==
'magnitude' .and. &
182 trim(self%interp_type) ==
'bump')
then
185 allocate(field_ou_2d(geom_ou%ngrid,1:fields_ou(var)%npz))
188 call self%bump%apply(fields_ou(var)%npz, fields_in(var)%array, geom_ou%ngrid, field_ou_2d)
192 do j = geom_ou%jsc,geom_ou%jec
193 do i = geom_ou%isc,geom_ou%iec
195 fields_ou(var)%array(i,j,1:fields_ou(var)%npz) = field_ou_2d(n,1:fields_ou(var)%npz)
200 deallocate(field_ou_2d)
205 allocate(field_in(geom_in%ngrid))
206 allocate(field_ou(geom_ou%ngrid))
208 do k = 1, fields_ou(var)%npz
212 do j = geom_in%jsc,geom_in%jec
213 do i = geom_in%isc,geom_in%iec
215 field_in(n) = fields_in(var)%array(i,j,k)
220 if (.not. fields_in(var)%integerfield .and. trim(fields_in(var)%space) ==
'magnitude' .and. &
221 trim(self%interp_type) ==
'barycent')
then
223 call self%unsinterp%apply(field_in, field_ou)
225 elseif (fields_in(var)%integerfield)
then
229 elseif (trim(fields_in(var)%space) ==
'direction')
then
237 do j = geom_ou%jsc,geom_ou%jec
238 do i = geom_ou%isc,geom_ou%iec
240 fields_ou(var)%array(i,j,k) = field_ou(n)
262 allocate(ud(geom_ou%isc:geom_ou%iec ,geom_ou%jsc:geom_ou%jec+1,geom_ou%npz))
263 allocate(vd(geom_ou%isc:geom_ou%iec+1,geom_ou%jsc:geom_ou%jec ,geom_ou%npz))
265 call a2d(geom_ou, u_ou%array, v_ou%array, ud, vd)
268 deallocate(u_ou%array)
269 deallocate(v_ou%array)
270 allocate(u_ou%array(geom_ou%isc:geom_ou%iec ,geom_ou%jsc:geom_ou%jec+1,1:geom_ou%npz))
271 allocate(v_ou%array(geom_ou%isc:geom_ou%iec+1,geom_ou%jsc:geom_ou%jec ,1:geom_ou%npz))
277 u_ou%space =
'vector'
278 v_ou%space =
'vector'
290 type(unstrc_interp),
intent(in) :: unsinterp
291 real(kind=
kind_real),
intent(in) :: field_in(:)
292 real(kind=
kind_real),
intent(inout) :: field_ou(:)
295 integer :: maxtypel, mintypel, maxtype, mintype, ngrid_ou
296 integer :: i, j, k, n, index
297 real(kind=
kind_real),
allocatable :: interp_w(:,:)
298 real(kind=
kind_real),
allocatable :: field_ou_tmp(:)
299 real(kind=
kind_real),
allocatable :: field_neighbours(:,:)
300 real(kind=
kind_real),
allocatable :: field_types(:)
306 ngrid_ou =
size(field_ou)
310 allocate(field_neighbours(unsinterp%nn,ngrid_ou))
311 allocate(field_ou_tmp(ngrid_ou))
312 call unsinterp%apply(field_in, field_ou_tmp, field_neighbours)
316 maxtypel = int(maxval(field_in))
317 mintypel = int(minval(field_in))
318 call unsinterp%comm%allreduce(maxtypel,maxtype,fckit_mpi_max())
319 call unsinterp%comm%allreduce(mintypel,mintype,fckit_mpi_min())
324 allocate(field_types(mintype:maxtype))
326 field_ou = 0.0_kind_real
329 do n = 1, unsinterp%nn
330 index = int(field_neighbours(n,i))
331 field_types(index) = field_types(index) + unsinterp%interp_w(n,i)
333 field_ou(i) = real(maxloc(field_types,1)+(mintype-1),
kind_real)
342 type(unstrc_interp),
intent(in) :: unsinterp
343 real(kind=
kind_real),
intent(in) :: field_in(:)
344 real(kind=
kind_real),
intent(inout) :: field_ou(:)
346 integer :: n, ngrid_ou
347 real(kind=
kind_real),
allocatable :: field_ou_tmp(:)
348 real(kind=
kind_real),
allocatable :: field_neighbours(:,:)
354 ngrid_ou =
size(field_ou)
358 allocate(field_neighbours(unsinterp%nn,ngrid_ou))
359 allocate(field_ou_tmp(ngrid_ou))
360 call unsinterp%apply(field_in, field_ou_tmp, field_neighbours)
365 field_ou(n) = field_neighbours(minloc(unsinterp%interp_w(:,n),1),n)