@@ -215,11 +215,10 @@ subroutine horiz_interp_read_weights_conserve(Interp, weight_filename, weight_fi
215215 integer , intent (in ) :: isw, iew, jsw, jew
216216 integer , intent (in ), optional :: src_tile
217217
218- integer :: i, j, ncells, mpi_ncells
219- integer :: tile_id(1 ) ! < tile id for saving xgrid for the correct tile
220- integer :: istart(1 ), iend(1 ), i_dst, j_dst, index
221- real (8 ), allocatable :: dst_area2(:,:), dst_area1(:), read1(:), read1_element
222- integer , allocatable :: tile1(:), indices(:), read2(:,:)
218+ integer :: i, j, ncells, domain_ncells
219+ integer :: istart, iend, i_dst, j_dst, index
220+ real (8 ), allocatable :: dst_area2(:,:), dst_area1(:), read1(:), xarea(:)
221+ integer , allocatable :: tile1(:), read2(:,:)
223222 logical , allocatable :: mask(:)
224223
225224 type (FmsNetcdfFile_t) :: weight_fileobj ! < FMS2io fileob for the weight file
@@ -235,91 +234,93 @@ subroutine horiz_interp_read_weights_conserve(Interp, weight_filename, weight_fi
235234 ! get ncells
236235 call get_dimension_size(weight_fileobj, " ncells" , ncells)
237236
237+ istart = 1
238+ iend = ncells
239+
238240 ! get section of xgrid on src_tile
239241 if (present (src_tile)) then
240242 allocate (tile1(ncells))
241243 call read_data(weight_fileobj, " tile1" , tile1)
242- istart = FINDLOC(tile1, src_tile)
243- iend = FINDLOC(tile1, src_tile, back= .true. )
244- ncells = iend(1 ) - istart(1 ) + 1
244+ ! find istart
245+ do i= 1 , ncells
246+ if (tile1(i) == src_tile) then
247+ istart = i
248+ exit
249+ end if
250+ end do
251+ ! find iend
252+ do i= istart, ncells
253+ if (tile1(i) /= src_tile) then
254+ iend = i - 1
255+ exit
256+ end if
257+ end do
258+ ncells = iend - istart + 1
245259 deallocate (tile1)
246- else
247- istart(1 ) = 1
248- iend(1 ) = ncells
249260 end if
250261
251262 ! allocate arrays for reading data
252- allocate (read2(2 , ncells), indices(ncells) )
263+ allocate (read2(2 , ncells))
253264
254265 ! get section of xgrid for the specified window (compute domain) on the tgt grid
255- call read_data(weight_fileobj, " tile2_cell" , read2, corner= [1 ,istart(1 )], edge_lengths= [2 ,iend(1 )])
266+ call read_data(weight_fileobj, " tile2_cell" , read2, corner= [1 ,istart], edge_lengths= [2 ,ncells])
267+
268+ ! get xgrid indices, used copilot for this section of code
256269 allocate (mask(ncells))
257- mpi_ncells = 0
258- mask = (read2(1 ,:) >= isw) .and. (read2(1 ,:) <= iew) .and. (read2(2 ,:) >= jsw) .and. (read2(2 ,:) <= jew)
259- do i = 1 , ncells
260- if (mask(i)) then
261- mpi_ncells = mpi_ncells + 1
262- indices(mpi_ncells) = i
263- end if
264- end do
265- deallocate (mask)
270+ mask = (read2(1 ,:) >= isw .and. read2(1 ,:) <= iew .and. read2(2 ,:) >= jsw .and. read2(2 ,:) <= jew)
271+
272+ domain_ncells = count (mask)
273+
274+ write (* ,* ) istart, iend, ncells, " and" , isw, iew, jsw, jew, domain_ncells
266275
267276 ! allocate data to store xgrid
268- allocate (Interp% i_src(mpi_ncells))
269- allocate (Interp% j_src(mpi_ncells))
270- allocate (Interp% i_dst(mpi_ncells))
271- allocate (Interp% j_dst(mpi_ncells))
272- allocate (Interp% horizInterpReals8_type% area_frac_dst(mpi_ncells))
273-
274- ! save dst parent cell indices on pe domain
275- do i= 1 , mpi_ncells
276- index = indices(i)
277- Interp% i_dst(i) = read2(1 ,index) - isw + 1
278- Interp% j_dst(i) = read2(2 ,index) - jsw + 1
279- end do
277+ allocate (Interp% i_src(domain_ncells))
278+ allocate (Interp% j_src(domain_ncells))
279+ allocate (Interp% i_dst(domain_ncells))
280+ allocate (Interp% j_dst(domain_ncells))
281+ allocate (Interp% horizInterpReals8_type% area_frac_dst(domain_ncells))
282+
283+ Interp% i_dst = pack (read2(1 ,:), mask) - isw + 1
284+ Interp% j_dst = pack (read2(2 ,:), mask) - jsw + 1
280285
281286 ! save src parent cell indices
282- call read_data(weight_fileobj, " tile1_cell" , read2, corner= [1 ,istart(1 )], edge_lengths= [2 ,iend(1 )])
283- do i= 1 , mpi_ncells
284- index = indices(i)
285- Interp% i_src(i) = read2(1 , index)
286- Interp% j_src(i) = read2(2 , index)
287- end do
287+ call read_data(weight_fileobj, " tile1_cell" , read2, corner= [1 ,istart], edge_lengths= [2 ,ncells])
288+ Interp% i_src = pack (read2(1 ,:), mask)
289+ Interp% j_src = pack (read2(2 ,:), mask)
288290
289291 deallocate (read2)
290292
291293 ! allocate arrays to compute weights
292- allocate (read1(ncells), dst_area1(mpi_ncells ), dst_area2(nlon_dst, nlat_dst))
294+ allocate (read1(ncells), dst_area1(domain_ncells ), dst_area2(nlon_dst, nlat_dst), xarea(domain_ncells ))
293295
294296 ! read xgrid area
295- call read_data(weight_fileobj, " xgrid_area" , read1, corner= [istart(1 )], edge_lengths= [iend(1 )])
297+ call read_data(weight_fileobj, " xgrid_area" , read1, corner= [istart], edge_lengths= [ncells])
298+
299+ xarea = pack (read1, mask)
296300
297301 ! sum over xgrid area to get destination grid area
298302 dst_area2 = 0.0
299- do i = 1 , mpi_ncells
300- index = indices(i)
303+ do i = 1 , domain_ncells
301304 i_dst = Interp% i_dst(i)
302305 j_dst = Interp% j_dst(i)
303- read1_element = read1(index)
304- dst_area2(i_dst, j_dst) =+ read1_element
306+ dst_area2(i_dst, j_dst) = dst_area2(i_dst, j_dst) + xarea(i)
305307 dst_area1(i) = dst_area2(i_dst, j_dst)
306- Interp% horizInterpReals8_type% area_frac_dst(i) = read1_element
307308 end do
308309
309- Interp% horizInterpReals8_type% area_frac_dst = dst_area1 / Interp % horizInterpReals8_type % area_frac_dst
310+ Interp% horizInterpReals8_type% area_frac_dst = xarea / dst_area1
310311
311312 deallocate (read1)
312313 deallocate (dst_area1)
313314 deallocate (dst_area2)
314- deallocate (indices )
315+ deallocate (xarea )
315316
316317 call close_file(weight_fileobj)
317318
318319 else
319320 call mpp_error(FATAL, " cannot open weight file" )
320321 end if
321322
322- Interp% nxgrid = mpi_ncells
323+ Interp% nxgrid = domain_ncells
323324 Interp% nlon_src = nlon_src
324325 Interp% nlat_src = nlat_src
325326 Interp% nlon_dst = nlon_dst
0 commit comments