@@ -24,6 +24,7 @@ module m_amr
2424 use m_ibm, only: s_ibm_alloc_fine, s_ibm_setup_fine, s_ibm_swap_to_fine, s_ibm_restore_from_fine, s_ibm_correct_state, &
2525 & s_update_mib, moving_immersed_boundary_flag, num_gps
2626 use m_hypoelastic, only: s_hypoelastic_update_fd_coeffs
27+ use m_acoustic_src, only: acoustic_supp_lo, acoustic_supp_hi
2728
2829 implicit none
2930
@@ -1391,6 +1392,62 @@ contains
13911392 !! amr_buf- padded extents come within buff_size (guaranteeing no fine- fine adjacency: separated boxes stay >= buff_size apart,
13921393 !! nearby ones collapse to a single box == the legacy bounding box). Boxes are the raw tagged extents; the caller pads, clamps
13931394 !! and size- caps each one.
1395+ !> True iff global level-0 cell (gi, gj, gk) lies inside any acoustic source support bbox.
1396+ pure logical function f_in_acoustic_support(gi, gj, gk) result(insup)
1397+
1398+ integer , intent (in ) :: gi, gj, gk
1399+ integer :: s
1400+
1401+ insup = .false.
1402+ do s = 1 , num_source
1403+ if (gi >= acoustic_supp_lo(1 , s) .and. gi <= acoustic_supp_hi(1 , s) .and. (n_glb == 0 .or. (gj >= acoustic_supp_lo(2 , &
1404+ & s) .and. gj <= acoustic_supp_hi(2 , s))) .and. (p_glb == 0 .or. (gk >= acoustic_supp_lo(3 , &
1405+ & s) .and. gk <= acoustic_supp_hi(3 , s)))) then
1406+ insup = .true. ; return
1407+ end if
1408+ end do
1409+
1410+ end function f_in_acoustic_support
1411+
1412+ !> Clip a candidate regrid box (global indices) so it does not overlap any acoustic source support bbox: per overlapping source,
1413+ !! remove the overlap along the single axis/ side that keeps the largest remaining extent (deterministic: lower axis, then begin
1414+ !! side, wins ties). Clipping only shrinks the box and may empty it (hi < lo); the caller drops empties.
1415+ impure subroutine s_amr_clip_box_from_sources (lo , hi )
1416+
1417+ integer , intent (inout ) :: lo(3 ), hi(3 )
1418+ integer :: s, d, best_d, best_side, best_ext, ext_l, ext_r
1419+ logical :: ovl
1420+
1421+ do s = 1 , num_source
1422+ if (hi(1 ) < lo(1 ) .or. hi(2 ) < lo(2 ) .or. hi(3 ) < lo(3 )) return ! emptied by an earlier clip
1423+ ovl = lo(1 ) <= acoustic_supp_hi(1 , s) .and. hi(1 ) >= acoustic_supp_lo(1 , s)
1424+ if (n_glb > 0 ) ovl = ovl .and. lo(2 ) <= acoustic_supp_hi(2 , s) .and. hi(2 ) >= acoustic_supp_lo(2 , s)
1425+ if (p_glb > 0 ) ovl = ovl .and. lo(3 ) <= acoustic_supp_hi(3 , s) .and. hi(3 ) >= acoustic_supp_lo(3 , s)
1426+ if (.not. ovl) cycle
1427+ best_d = 1 ; best_side = 1 ; best_ext = - 1
1428+ do d = 1 , num_dims
1429+ ext_l = acoustic_supp_lo(d, s) - lo(d) ! cells kept by [lo(d), supp_lo-1 ]
1430+ ext_r = hi(d) - acoustic_supp_hi(d, s) ! cells kept by [supp_hi+1 , hi(d)]
1431+ if (ext_l > best_ext) then ; best_ext = ext_l; best_d = d; best_side = 1 ; end if
1432+ if (ext_r > best_ext) then ; best_ext = ext_r; best_d = d; best_side = 2 ; end if
1433+ end do
1434+ if (best_side == 1 ) then
1435+ hi(best_d) = acoustic_supp_lo(best_d, s) - 1
1436+ else
1437+ lo(best_d) = acoustic_supp_hi(best_d, s) + 1
1438+ end if
1439+ end do
1440+ ! safety net: clipping removed every overlap by construction - anything left is a bug
1441+ do s = 1 , num_source
1442+ if (hi(1 ) < lo(1 ) .or. hi(2 ) < lo(2 ) .or. hi(3 ) < lo(3 )) return
1443+ ovl = lo(1 ) <= acoustic_supp_hi(1 , s) .and. hi(1 ) >= acoustic_supp_lo(1 , s)
1444+ if (n_glb > 0 ) ovl = ovl .and. lo(2 ) <= acoustic_supp_hi(2 , s) .and. hi(2 ) >= acoustic_supp_lo(2 , s)
1445+ if (p_glb > 0 ) ovl = ovl .and. lo(3 ) <= acoustic_supp_hi(3 , s) .and. hi(3 ) >= acoustic_supp_lo(3 , s)
1446+ if (ovl) call s_mpi_abort(' amr regrid: acoustic source exclusion clip failed (internal error)' )
1447+ end do
1448+
1449+ end subroutine s_amr_clip_box_from_sources
1450+
13941451 impure subroutine s_amr_cluster (tag_grid , boxes , nboxes )
13951452
13961453 logical , intent (in ) :: tag_grid(0 :,0 :,0 :)
@@ -1541,6 +1598,11 @@ contains
15411598 if (p_glb > 0 ) g = max (g, abs (f_amr_rho_tot(q_cons_base, ci, cj, ck + 1 ) - f_amr_rho_tot(q_cons_base, ci, &
15421599 & cj, ck - 1 )))
15431600 if (g/ (2._wp * r0) > amr_tag_eps) tag_grid(ci, cj, ck) = .true.
1601+ ! the acoustic source support stays coarse (its spatials are coarse cell
1602+ ! indices): suppress tags there so the clusterer splits around the source
1603+ if (acoustic_source .and. tag_grid(ci, cj, ck)) then
1604+ if (f_in_acoustic_support(ci + sidx(1 ), cj + sidx(2 ), ck + sidx(3 ))) tag_grid(ci, cj, ck) = .false.
1605+ end if
15441606 end do
15451607 end do
15461608 end do
@@ -1569,6 +1631,9 @@ contains
15691631 else
15701632 lo(3 ) = 0 ; hi(3 ) = 0
15711633 end if
1634+ ! keep candidate boxes clear of every acoustic source support (the source acts on the
1635+ ! coarse grid only); clipping only shrinks, so boxes stay disjoint - empties drop below
1636+ if (acoustic_source) call s_amr_clip_box_from_sources(lo, hi)
15721637 if (hi(1 ) < lo(1 ) .or. hi(2 ) < lo(2 ) .or. hi(3 ) < lo(3 )) cycle ! confined to the domain margin
15731638 k = k + 1 ; boxes(k)%lo = lo; boxes(k)%hi = hi
15741639 end do
0 commit comments