pure subroutine relax_map_tracer_budget_impl(hTr, h_layer, ref_tracer, it, n_tr, &
idamp_h, budget, nx, ny, nz, dt)
!! `relax_map_tracer_impl` + mirror the per-cell increment into
!! `budget` (salt or heat), the S/T budget-instrumented variant —
!! mirrors `apply_geothermal_src_impl`'s host-shim + flat-impl +
!! budget-mirror shape. `delta` is the ALGEBRAIC increment
!! `hTr_new - hTr_old = (1-decay)*(tgt-hTr_old)`, written once and
!! used for BOTH the state update and the budget mirror so the two
!! stay exactly consistent (no independent recomputation to drift).
integer, intent(in) :: it, n_tr, nx, ny, nz
real(wp), intent(inout) :: hTr(nx, ny, nz)
real(wp), intent(in) :: h_layer(nx, ny, nz)
real(wp), intent(in) :: ref_tracer(nx, ny, nz, n_tr)
real(wp), intent(in) :: idamp_h(nx, ny)
real(wp), intent(inout) :: budget(nx, ny, nz)
real(wp), intent(in) :: dt
integer :: i, j, k
real(wp) :: decay, tgt, delta
do concurrent(k=1:nz, j=1:ny, i=1:nx) local(decay, tgt, delta)
if (idamp_h(i, j) > 0.0_wp) then
decay = exp(-idamp_h(i, j)*dt)
tgt = ref_tracer(i, j, k, it)*h_layer(i, j, k)
delta = (1.0_wp - decay)*(tgt - hTr(i, j, k))
hTr(i, j, k) = hTr(i, j, k) + delta
budget(i, j, k) = budget(i, j, k) + delta
end if
end do
end subroutine relax_map_tracer_budget_impl