Skip to content

Commit de6add6

Browse files
committed
fix: use MOVE_ALLOC for 1-rank/no-MPI to avoid patch_ib truncation
For single-rank and no-MPI cases every IB patch is local, so shrinking patch_ib to num_aware_ibs (e.g. 54k for 3D) and then keeping num_ibs at num_gbl_ibs was a latent out-of-bounds: IBM loops over num_ibs would access patch_ib beyond its capacity. MOVE_ALLOC transfers patch_ib_gbl (sized exactly num_gbl_ibs) directly into patch_ib — no copy, no truncation, patch_ib size matches num_ibs. The num_aware_ibs resize is still done for multi-rank cases where each rank genuinely only needs its local neighbourhood subset.
1 parent 0af6cb9 commit de6add6

1 file changed

Lines changed: 13 additions & 16 deletions

File tree

src/simulation/m_start_up.fpp

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,7 +1212,7 @@ contains
12121212

12131213
type(ib_patch_parameters), allocatable :: patch_ib_gbl(:)
12141214
real(wp), dimension(3) :: centroid
1215-
integer :: i, j, n_copy
1215+
integer :: i, j
12161216
integer :: num_aware_ibs
12171217
logical :: is_in_neighborhood, is_local
12181218

@@ -1231,25 +1231,23 @@ contains
12311231
call get_neighbor_bounds() ! make sure the bounds of the neighbors are correctly set up
12321232
call s_compute_ib_neighbor_ranks() ! build lookup of all neighbor MPI ranks
12331233

1234-
deallocate (patch_ib)
1235-
num_aware_ibs = min(num_local_ibs_max*(2*ib_neighborhood_radius + 1)**num_dims, num_ib_patches_max)
1236-
allocate (patch_ib(num_aware_ibs))
1237-
1238-
! assign defaults to all values
12391234
num_gbl_ibs = num_ibs
12401235
num_local_ibs = num_ibs
12411236
do i = 1, num_local_ibs_max
12421237
local_ib_patch_ids(i) = i
12431238
end do
12441239

1240+
deallocate (patch_ib)
1241+
12451242
#ifdef MFC_MPI
1246-
! fallback for 1-rank case: patch_ib has num_aware_ibs slots; clamp copy to avoid out-of-bounds
1247-
! when num_gbl_ibs > num_aware_ibs (large particle beds on a single rank)
12481243
if (num_procs == 1) then
1249-
n_copy = min(num_gbl_ibs, num_aware_ibs)
1250-
patch_ib(1:n_copy) = patch_ib_gbl(1:n_copy)
1244+
! single-rank: every patch is local - transfer ownership directly to avoid truncation
1245+
call move_alloc(patch_ib_gbl, patch_ib)
12511246
else
1252-
! determine the set of patches owned by local rank
1247+
! multi-rank: carve out the local neighbourhood subset
1248+
num_aware_ibs = min(num_local_ibs_max*(2*ib_neighborhood_radius + 1)**num_dims, num_ib_patches_max)
1249+
allocate (patch_ib(num_aware_ibs))
1250+
12531251
num_local_ibs = 0
12541252
num_ibs = 0
12551253
do i = 1, num_gbl_ibs
@@ -1269,15 +1267,14 @@ contains
12691267
end if
12701268
end if
12711269
end do
1270+
1271+
deallocate (patch_ib_gbl)
12721272
end if
12731273
#else
1274-
! reduce the size of the array for local simulation in no-MPI case
1275-
n_copy = min(num_gbl_ibs, num_aware_ibs)
1276-
patch_ib(1:n_copy) = patch_ib_gbl(1:n_copy)
1274+
! no-MPI: every patch is local - transfer ownership directly to avoid truncation
1275+
call move_alloc(patch_ib_gbl, patch_ib)
12771276
#endif
12781277

1279-
deallocate (patch_ib_gbl)
1280-
12811278
@:ALLOCATE(ib_gbl_idx_lookup(1:num_gbl_ibs))
12821279

12831280
end subroutine s_reduce_ib_patch_array

0 commit comments

Comments
 (0)