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)