Skip to content

Commit 288a9d6

Browse files
CopilotRuochun
andcommitted
Fix buildPatchContactMapping to compare normalized (min,max) pairs
The function now compares (min(A,B), max(A,B)) instead of (A,B) directly to correctly match the same physical contact across timesteps regardless of ID ordering. This fixes the issue where contacts were incorrectly mapped to the first patch contact when IDs were in different order. Co-authored-by: Ruochun <24469442+Ruochun@users.noreply.github.com>
1 parent 83e6948 commit 288a9d6

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

src/algorithms/DEMKinematicMisc.cu

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -306,18 +306,24 @@ __global__ void buildPatchContactMapping(deme::bodyID_t* curr_idPatchA,
306306
size_t type_end = left;
307307

308308
// Within this type segment, use binary search to find the matching A/B pair
309-
// The segment is sorted by the combined patch ID pair (A in high bits, B in low bits)
310-
// The encoding ensures that (smaller_A, larger_B) pattern creates a sortable value
309+
// The segment is sorted by the encoded patch ID pair (A in high bits, B in low bits)
310+
// Note: encodeType preserves the order, so arrays are sorted by (A, B) lexicographically
311+
// For matching, we need to normalize to (min, max) since the same physical contact
312+
// could have different A/B ordering between timesteps
313+
deme::bodyID_t curr_min = (curr_A < curr_B) ? curr_A : curr_B;
314+
deme::bodyID_t curr_max = (curr_A < curr_B) ? curr_B : curr_A;
315+
311316
left = type_start;
312317
right = type_end;
313318
while (left < right) {
314319
size_t mid = left + (right - left) / 2;
315320
deme::bodyID_t prev_A = prev_idPatchA[mid];
316321
deme::bodyID_t prev_B = prev_idPatchB[mid];
322+
deme::bodyID_t prev_min = (prev_A < prev_B) ? prev_A : prev_B;
323+
deme::bodyID_t prev_max = (prev_A < prev_B) ? prev_B : prev_A;
317324

318-
// Compare (A, B) pairs lexicographically
319-
// Since they're sorted by patch ID pair where smaller ID is in high bits
320-
if (prev_A < curr_A || (prev_A == curr_A && prev_B < curr_B)) {
325+
// Compare (min, max) pairs lexicographically to find matching physical contact
326+
if (prev_min < curr_min || (prev_min == curr_min && prev_max < curr_max)) {
321327
left = mid + 1;
322328
} else {
323329
right = mid;
@@ -328,7 +334,9 @@ __global__ void buildPatchContactMapping(deme::bodyID_t* curr_idPatchA,
328334
if (left < type_end) {
329335
deme::bodyID_t prev_A = prev_idPatchA[left];
330336
deme::bodyID_t prev_B = prev_idPatchB[left];
331-
if (prev_A == curr_A && prev_B == curr_B) {
337+
deme::bodyID_t prev_min = (prev_A < prev_B) ? prev_A : prev_B;
338+
deme::bodyID_t prev_max = (prev_A < prev_B) ? prev_B : prev_A;
339+
if (prev_min == curr_min && prev_max == curr_max) {
332340
my_partner = left;
333341
}
334342
}

0 commit comments

Comments
 (0)