@@ -214,11 +214,10 @@ subroutine horiz_interp_read_weights_conserve(Interp, weight_filename, weight_fi
214214 integer , intent (in ) :: isw, iew, jsw, jew
215215 integer , intent (in ), optional :: src_tile
216216
217- integer :: i, j, ncells, mpi_ncells
218- integer :: tile_id(1 ) ! < tile id for saving xgrid for the correct tile
219- integer :: istart(1 ), iend(1 ), i_dst, j_dst, index
220- real (8 ), allocatable :: dst_area2(:,:), dst_area1(:), read1(:), read1_element
221- integer , allocatable :: tile1(:), indices(:), read2(:,:)
217+ integer :: i, j, ncells, domain_ncells
218+ integer :: istart, iend, i_dst, j_dst, index
219+ real (8 ), allocatable :: dst_area2(:,:), dst_area1(:), read1(:), xarea(:)
220+ integer , allocatable :: tile1(:), read2(:,:)
222221 logical , allocatable :: mask(:)
223222
224223 type (FmsNetcdfFile_t) :: weight_fileobj ! < FMS2io fileob for the weight file
@@ -234,91 +233,91 @@ subroutine horiz_interp_read_weights_conserve(Interp, weight_filename, weight_fi
234233 ! get ncells
235234 call get_dimension_size(weight_fileobj, " ncells" , ncells)
236235
236+ istart = 1
237+ iend = ncells
238+
237239 ! get section of xgrid on src_tile
238240 if (present (src_tile)) then
239241 allocate (tile1(ncells))
240242 call read_data(weight_fileobj, " tile1" , tile1)
241- istart = FINDLOC(tile1, src_tile)
242- iend = FINDLOC(tile1, src_tile, back= .true. )
243- ncells = iend(1 ) - istart(1 ) + 1
243+ ! find istart
244+ do i= 1 , ncells
245+ if (tile1(i) == src_tile) then
246+ istart = i
247+ exit
248+ end if
249+ end do
250+ ! find iend
251+ do i= istart, ncells
252+ if (tile1(i) /= src_tile) then
253+ iend = i
254+ exit
255+ end if
256+ end do
257+ ncells = iend - istart + 1
244258 deallocate (tile1)
245- else
246- istart(1 ) = 1
247- iend(1 ) = ncells
248259 end if
249260
250261 ! allocate arrays for reading data
251- allocate (read2(2 , ncells), indices(ncells) )
262+ allocate (read2(2 , ncells))
252263
253264 ! get section of xgrid for the specified window (compute domain) on the tgt grid
254- call read_data(weight_fileobj, " tile2_cell" , read2, corner= [1 ,istart(1 )], edge_lengths= [2 ,iend(1 )])
265+ call read_data(weight_fileobj, " tile2_cell" , read2, corner= [1 ,istart], edge_lengths= [2 ,ncells])
266+
267+ ! get xgrid indices, used copilot for this section of code
255268 allocate (mask(ncells))
256- mpi_ncells = 0
257- mask = (read2(1 ,:) >= isw) .and. (read2(1 ,:) <= iew) .and. (read2(2 ,:) >= jsw) .and. (read2(2 ,:) <= jew)
258- do i = 1 , ncells
259- if (mask(i)) then
260- mpi_ncells = mpi_ncells + 1
261- indices(mpi_ncells) = i
262- end if
263- end do
264- deallocate (mask)
269+ mask = (read2(1 ,:) >= isw .and. read2(1 ,:) <= iew .and. read2(2 ,:) >= jsw .and. read2(2 ,:) <= jew)
270+
271+ domain_ncells = count (mask)
265272
266273 ! allocate data to store xgrid
267- allocate (Interp% i_src(mpi_ncells))
268- allocate (Interp% j_src(mpi_ncells))
269- allocate (Interp% i_dst(mpi_ncells))
270- allocate (Interp% j_dst(mpi_ncells))
271- allocate (Interp% horizInterpReals8_type% area_frac_dst(mpi_ncells))
272-
273- ! save dst parent cell indices on pe domain
274- do i= 1 , mpi_ncells
275- index = indices(i)
276- Interp% i_dst(i) = read2(1 ,index) - isw + 1
277- Interp% j_dst(i) = read2(2 ,index) - jsw + 1
278- end do
274+ allocate (Interp% i_src(domain_ncells))
275+ allocate (Interp% j_src(domain_ncells))
276+ allocate (Interp% i_dst(domain_ncells))
277+ allocate (Interp% j_dst(domain_ncells))
278+ allocate (Interp% horizInterpReals8_type% area_frac_dst(domain_ncells))
279+
280+ Interp% i_dst = pack (read2(1 ,:), mask) - isw + 1
281+ Interp% j_dst = pack (read2(2 ,:), mask) - jsw + 1
279282
280283 ! save src parent cell indices
281- call read_data(weight_fileobj, " tile1_cell" , read2, corner= [1 ,istart(1 )], edge_lengths= [2 ,iend(1 )])
282- do i= 1 , mpi_ncells
283- index = indices(i)
284- Interp% i_src(i) = read2(1 , index)
285- Interp% j_src(i) = read2(2 , index)
286- end do
284+ call read_data(weight_fileobj, " tile1_cell" , read2, corner= [1 ,istart], edge_lengths= [2 ,ncells])
285+ Interp% i_src = pack (read2(1 ,:), mask)
286+ Interp% j_src = pack (read2(2 ,:), mask)
287287
288288 deallocate (read2)
289289
290290 ! allocate arrays to compute weights
291- allocate (read1(ncells), dst_area1(mpi_ncells ), dst_area2(nlon_dst, nlat_dst))
291+ allocate (read1(ncells), dst_area1(domain_ncells ), dst_area2(nlon_dst, nlat_dst), xarea(domain_ncells ))
292292
293293 ! read xgrid area
294- call read_data(weight_fileobj, " xgrid_area" , read1, corner= [istart(1 )], edge_lengths= [iend(1 )])
294+ call read_data(weight_fileobj, " xgrid_area" , read1, corner= [istart], edge_lengths= [ncells])
295+
296+ xarea = pack (read1, mask)
295297
296298 ! sum over xgrid area to get destination grid area
297299 dst_area2 = 0.0
298- do i = 1 , mpi_ncells
299- index = indices(i)
300+ do i = 1 , domain_ncells
300301 i_dst = Interp% i_dst(i)
301302 j_dst = Interp% j_dst(i)
302- read1_element = read1(index)
303- dst_area2(i_dst, j_dst) =+ read1_element
303+ dst_area2(i_dst, j_dst) = dst_area2(i_dst, j_dst) + xarea(i)
304304 dst_area1(i) = dst_area2(i_dst, j_dst)
305- Interp% horizInterpReals8_type% area_frac_dst(i) = read1_element
306305 end do
307306
308- Interp% horizInterpReals8_type% area_frac_dst = dst_area1 / Interp % horizInterpReals8_type % area_frac_dst
307+ Interp% horizInterpReals8_type% area_frac_dst = xarea / dst_area1
309308
310309 deallocate (read1)
311310 deallocate (dst_area1)
312311 deallocate (dst_area2)
313- deallocate (indices )
312+ deallocate (xarea )
314313
315314 call close_file(weight_fileobj)
316315
317316 else
318317 call mpp_error(FATAL, " cannot open weight file" )
319318 end if
320319
321- Interp% nxgrid = mpi_ncells
320+ Interp% nxgrid = domain_ncells
322321 Interp% nlon_src = nlon_src
323322 Interp% nlat_src = nlat_src
324323 Interp% nlon_dst = nlon_dst
0 commit comments