Skip to content

Commit 3c6e77d

Browse files
committed
merge: viscous AMR (SP11) + fine-ghost-coordinate fix into the PR branch
2 parents b8a14ae + 6129592 commit 3c6e77d

9 files changed

Lines changed: 344 additions & 9 deletions

File tree

docs/documentation/case.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,7 @@ To restart the simulation from $k$-th time step, see @ref running "Restarting Ca
676676
| `sfc_partition_wrt` | Logical | Report SFC-weighted load-balance partition |
677677
| `rank_time_wrt` | Logical | Report per-rank RHS compute-time imbalance (max/mean) |
678678
| `load_balance` | Logical | (Experimental/diagnostic) Weighted static Cartesian decomposition at init (requires `parallel_io = T`, >1 rank). Measured gain is small on CPU (~5%) and can be slower on GPU due to the occupancy floor; equal decomposition is near-optimal for uniform-cost workloads. |
679-
| `amr` | Logical | (Experimental) Enable block-structured AMR: a 2:1 refined level-1 patch with gradient-based dynamic regrid, optional dt/2 subcycling, and conservative coupling with refluxing. Requires WENO reconstruction, SSP-RK3, model_eqns=2; num_fluids > 1 requires mpp_lim. |
679+
| `amr` | Logical | (Experimental) Enable block-structured AMR: a 2:1 refined level-1 patch with gradient-based dynamic regrid, optional dt/2 subcycling, and conservative coupling with refluxing. Requires WENO reconstruction, SSP-RK3, model_eqns=2; num_fluids > 1 requires mpp_lim; supports physical viscosity. |
680680
| `amr_patch_beg(i)` | Integer | Refined-patch start cell index in direction $i$ (level-0 index space) |
681681
| `amr_patch_end(i)` | Integer | Refined-patch end cell index in direction $i$ (level-0 index space) |
682682
| `amr_regrid_int` | Integer | Steps between AMR regrid events (0 = static patch) |
@@ -787,7 +787,17 @@ Multiple fluids (`num_fluids > 1`) are supported and additionally require `mpp_l
787787
whose volume-fraction clamp+renormalize maintains coarse/fine alpha consistency; the
788788
per-fluid masses are refluxed exactly, and volume fractions are prolonged with a
789789
sum-preserving closure (fine-level volume fractions sum to one by construction).
790-
It is incompatible with viscosity, surface tension, bubble models, phase-change (relax),
790+
Physical viscosity (`viscous = T`) is supported: the viscous stress/work travels through
791+
the momentum- and energy-equation source fluxes, which are captured into the same
792+
coarse–fine flux registers as the advective fluxes, so the interface is refluxed against
793+
the matched *total* (advective + viscous) flux and energy — including viscous work — is
794+
conserved. Fine-ghost velocity gradients at the coarse–fine boundary are taken from the
795+
conservative-linear prolongation of the coarse state (no special gradient reconstruction);
796+
that interface inconsistency is bounded and conservation is enforced by the flux-register
797+
matching. The density-gradient regrid tagger does not sense shear or boundary layers well,
798+
so viscous features may need a static or generously buffered patch (error-estimator taggers
799+
are future work).
800+
It is incompatible with surface tension, bubble models, phase-change (relax),
791801
immersed boundaries, IGR, cylindrical coordinates, MHD, chemistry, `hybrid_weno`,
792802
`hybrid_riemann`, and `acoustic_source`.
793803
Multi-rank runs are supported: the fine level mirrors the base decomposition (each rank

src/simulation/m_amr.fpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,42 @@ contains
637637
z_cc(0:amr_fine%p) = amr_fine%z_cc(0:amr_fine%p)
638638
dz(0:amr_fine%p) = amr_fine%dz(0:amr_fine%p)
639639
end if
640+
! Extend the fine grid into the ghost shell (s_build_level_coords only fills the interior 0:m).
641+
! The viscous velocity gradient divides by ghost cell-center spacings (x_cc(j+-1) - x_cc(j)), so at
642+
! a rank seam the fine subdomain-edge cell would otherwise use a stale coarse spacing and diverge
643+
! from the np=1 (fully-owned) result. Uniform 2:1 continuation of the (locally-uniform) base region.
644+
block
645+
integer :: jg
646+
real(wp) :: sp
647+
sp = amr_fine%dx(amr_fine%m)
648+
do jg = amr_fine%m + 1, amr_fine%m + buff_size
649+
dx(jg) = sp; x_cb(jg) = x_cb(jg - 1) + sp; x_cc(jg) = x_cc(jg - 1) + sp
650+
end do
651+
sp = amr_fine%dx(0)
652+
do jg = -1, -buff_size, -1
653+
dx(jg) = sp; x_cb(jg - 1) = x_cb(jg) - sp; x_cc(jg) = x_cc(jg + 1) - sp
654+
end do
655+
if (n_glb > 0) then
656+
sp = amr_fine%dy(amr_fine%n)
657+
do jg = amr_fine%n + 1, amr_fine%n + buff_size
658+
dy(jg) = sp; y_cb(jg) = y_cb(jg - 1) + sp; y_cc(jg) = y_cc(jg - 1) + sp
659+
end do
660+
sp = amr_fine%dy(0)
661+
do jg = -1, -buff_size, -1
662+
dy(jg) = sp; y_cb(jg - 1) = y_cb(jg) - sp; y_cc(jg) = y_cc(jg + 1) - sp
663+
end do
664+
end if
665+
if (p_glb > 0) then
666+
sp = amr_fine%dz(amr_fine%p)
667+
do jg = amr_fine%p + 1, amr_fine%p + buff_size
668+
dz(jg) = sp; z_cb(jg) = z_cb(jg - 1) + sp; z_cc(jg) = z_cc(jg - 1) + sp
669+
end do
670+
sp = amr_fine%dz(0)
671+
do jg = -1, -buff_size, -1
672+
dz(jg) = sp; z_cb(jg - 1) = z_cb(jg) - sp; z_cc(jg) = z_cc(jg + 1) - sp
673+
end do
674+
end if
675+
end block
640676
! sync the swapped extents/bounds/coordinates to the device: RHS kernels read the
641677
! device copies of these GPU_DECLARE'd globals (stale coarse bounds = OOB kernels)
642678
call s_amr_sync_grid_state_to_device()

src/simulation/m_amr_registers.fpp

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@
1818
!! remainder (the +alpha*d(u_star)/dx compression term m_rhs assembles from flux_src_n = u_star) is deliberately NOT captured:
1919
!! alpha is genuinely non-conservative, so forcing flux-matching on u_star would be wrong; coarse/fine volume-fraction
2020
!! consistency is instead maintained by mpp_lim's clamp+renormalize (required by the checker for amr with num_fluids > 1).
21+
!!
22+
!! Viscous (SP11): the viscous stress/work face fluxes travel through flux_src_n for the momentum and energy equations
23+
!! (m_rhs s_compute_additional_physics_rhs: rhs += (flux_src_n(j-1) - flux_src_n(j))/dx, identical face indexing and sign to the
24+
!! advective flux_n). They are captured into the SAME registers (added on top of the advective flux for mom..E) so the c/f reflux
25+
!! matches the TOTAL advective+viscous flux; energy conservation therefore includes the viscous work. Fine-ghost velocity gradients
26+
!! at the c/f boundary come from the conservative-linear cons prolongation (no special gradient reconstruction) - like the alpha
27+
!! K-term, that inconsistency is bounded, and conservation is enforced by the flux-register matching.
2128
module m_amr_registers
2229
2330
use m_derived_types
@@ -112,10 +119,11 @@ contains
112119
!! call (amr_in_fine_advance false, coarse globals) fills creg at the patch boundary faces; fine call (flag true, globals
113120
!! swapped to the fine patch) fills freg at fine faces -1 and m/n/p. creg uses relative 0-based transverse; freg uses 0-based
114121
!! fine.
115-
impure subroutine s_amr_capture_boundary_flux(id, flux_dir, stage)
122+
impure subroutine s_amr_capture_boundary_flux(id, flux_dir, flux_src, stage)
116123

117124
integer, intent(in) :: id
118125
type(vector_field), intent(in) :: flux_dir
126+
type(vector_field), intent(in) :: flux_src
119127
integer, intent(in) :: stage
120128
integer :: eq, t1, t2, jlo, jhi, t1_hi, t2_hi, o1, o2
121129
integer :: sidx(3), ext(3)
@@ -176,6 +184,30 @@ contains
176184
end do
177185
end do
178186
$:END_GPU_PARALLEL_LOOP()
187+
! total-flux matching: add the viscous momentum/energy face fluxes (flux_src) into the same fine
188+
! registers so the c/f reflux sees advective+viscous. Base coef/accum are applied above; always
189+
! accumulate here. Inviscid path skips this entirely (registers stay byte-identical).
190+
if (viscous) then
191+
$:GPU_PARALLEL_LOOP(collapse=3)
192+
do t2 = 0, t2_hi
193+
do t1 = 0, t1_hi
194+
do eq = eqn_idx%mom%beg, eqn_idx%E
195+
select case (id)
196+
case (1)
197+
freg(1)%lo(eq, t1, t2) = freg(1)%lo(eq, t1, t2) + coef*real(flux_src%vf(eq)%sf(jlo, t1, t2), wp)
198+
freg(1)%hi(eq, t1, t2) = freg(1)%hi(eq, t1, t2) + coef*real(flux_src%vf(eq)%sf(jhi, t1, t2), wp)
199+
case (2)
200+
freg(2)%lo(eq, t1, t2) = freg(2)%lo(eq, t1, t2) + coef*real(flux_src%vf(eq)%sf(t1, jlo, t2), wp)
201+
freg(2)%hi(eq, t1, t2) = freg(2)%hi(eq, t1, t2) + coef*real(flux_src%vf(eq)%sf(t1, jhi, t2), wp)
202+
case (3)
203+
freg(3)%lo(eq, t1, t2) = freg(3)%lo(eq, t1, t2) + coef*real(flux_src%vf(eq)%sf(t1, t2, jlo), wp)
204+
freg(3)%hi(eq, t1, t2) = freg(3)%hi(eq, t1, t2) + coef*real(flux_src%vf(eq)%sf(t1, t2, jhi), wp)
205+
end select
206+
end do
207+
end do
208+
end do
209+
$:END_GPU_PARALLEL_LOOP()
210+
end if
179211
else
180212
! coarse branch: a face's capture runs on the rank owning the coarse cells just OUTSIDE it (its
181213
! flux_n covers that face; at a rank-interior face the same rank also holds the inside cells).
@@ -258,6 +290,35 @@ contains
258290
end do
259291
end do
260292
$:END_GPU_PARALLEL_LOOP()
293+
! total-flux matching (coarse side): add viscous momentum/energy face fluxes into creg, same
294+
! face gating and transverse offsets as the base capture; always accumulate.
295+
if (viscous) then
296+
$:GPU_PARALLEL_LOOP(collapse=3)
297+
do t2 = 0, t2_hi
298+
do t1 = 0, t1_hi
299+
do eq = eqn_idx%mom%beg, eqn_idx%E
300+
select case (id)
301+
case (1)
302+
if (cap_lo) creg(1)%lo(eq, t1, t2) = creg(1)%lo(eq, t1, t2) + coef*real(flux_src%vf(eq)%sf(jlo, &
303+
& o1 + t1, o2 + t2), wp)
304+
if (cap_hi) creg(1)%hi(eq, t1, t2) = creg(1)%hi(eq, t1, t2) + coef*real(flux_src%vf(eq)%sf(jhi, &
305+
& o1 + t1, o2 + t2), wp)
306+
case (2)
307+
if (cap_lo) creg(2)%lo(eq, t1, t2) = creg(2)%lo(eq, t1, &
308+
& t2) + coef*real(flux_src%vf(eq)%sf(o1 + t1, jlo, o2 + t2), wp)
309+
if (cap_hi) creg(2)%hi(eq, t1, t2) = creg(2)%hi(eq, t1, &
310+
& t2) + coef*real(flux_src%vf(eq)%sf(o1 + t1, jhi, o2 + t2), wp)
311+
case (3)
312+
if (cap_lo) creg(3)%lo(eq, t1, t2) = creg(3)%lo(eq, t1, &
313+
& t2) + coef*real(flux_src%vf(eq)%sf(o1 + t1, o2 + t2, jlo), wp)
314+
if (cap_hi) creg(3)%hi(eq, t1, t2) = creg(3)%hi(eq, t1, &
315+
& t2) + coef*real(flux_src%vf(eq)%sf(o1 + t1, o2 + t2, jhi), wp)
316+
end select
317+
end do
318+
end do
319+
end do
320+
$:END_GPU_PARALLEL_LOOP()
321+
end if
261322
end if
262323
263324
end subroutine s_amr_capture_boundary_flux

src/simulation/m_checker.fpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ contains
9595
@:PROHIBIT(model_eqns /= 2, "amr requires model_eqns = 2 (5-equation)")
9696
@:PROHIBIT(num_fluids > 1 .and. .not. mpp_lim, &
9797
& "amr with num_fluids > 1 requires mpp_lim (its volume-fraction clamp+renormalize maintains coarse/fine alpha consistency)")
98-
@:PROHIBIT(viscous .or. surface_tension .or. hypoelasticity .or. hyperelasticity .or. mhd .or. chemistry, &
99-
& "amr does not support viscous/elastic/surface-tension/MHD/chemistry")
98+
@:PROHIBIT(surface_tension .or. hypoelasticity .or. hyperelasticity .or. mhd .or. chemistry, &
99+
& "amr does not support elastic/surface-tension/MHD/chemistry")
100100
@:PROHIBIT(bubbles_euler .or. bubbles_lagrange .or. qbmm .or. relax .or. ib .or. igr .or. cyl_coord, &
101101
& "amr does not support bubbles/phase-change/IB/IGR/cylindrical")
102102
@:PROHIBIT(active_box, "amr is incompatible with active_box (unvalidated combination)")

src/simulation/m_rhs.fpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,7 @@ contains
781781
! AMR refluxing: record the c/f boundary-face fluxes exactly as the assembly above
782782
! used them (after s_cbc may have modified flux_n inside the advection source call);
783783
! must run before the next direction's sweep reuses the aliased flux_n storage
784-
if (amr) call s_amr_capture_boundary_flux(id, flux_n(id), stage)
784+
if (amr) call s_amr_capture_boundary_flux(id, flux_n(id), flux_src_n(id), stage)
785785

786786
! RHS additions for hypoelasticity
787787
call nvtxStartRange("RHS-HYPOELASTICITY")

0 commit comments

Comments
 (0)