Skip to content

Commit a6add01

Browse files
authored
Abort on a fluid cell with no valid time step instead of dropping it from the dt reduction (#1952)
1 parent 078f9d3 commit a6add01

1 file changed

Lines changed: 30 additions & 1 deletion

File tree

‎src/simulation/m_time_steppers.fpp‎

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,7 @@ contains
684684
real(wp), dimension(5) :: dt_candidates_glb !< Global dt candidates (ICFL, VCFL, CCFL, TCFL, collision cap)
685685
real(wp) :: dt_prev
686686
logical :: is_fluid_cell !< Cell lies outside every immersed boundary
687+
integer :: bad_cell !< 1 + linear index of a fluid cell with no valid dt, 0 if none
687688
integer :: j, k, l !< Generic loop iterators
688689
integer :: fl !< Fluid loop iterator
689690

@@ -697,9 +698,10 @@ contains
697698
ccfl_dt_local = huge(1.0_wp)
698699
tcfl_dt_local = huge(1.0_wp)
699700
coll_dt_local = huge(1.0_wp)
701+
bad_cell = 0
700702
$:GPU_PARALLEL_LOOP(collapse=3, private='[vel, alpha, alpha_rho, Re, rho, vel_sum, pres, gamma, pi_inf, c, qv, fl, &
701703
& max_dt, is_fluid_cell]', reduction='[[icfl_dt_local, vcfl_dt_local, ccfl_dt_local, &
702-
& tcfl_dt_local]]', reductionOp='[min]')
704+
& tcfl_dt_local], [bad_cell]]', reductionOp='[min, max]')
703705
do l = 0, p
704706
do k = 0, n
705707
do j = 0, m
@@ -733,6 +735,10 @@ contains
733735

734736
call s_compute_dt_from_cfl(vel, c, max_dt, rho, Re, alpha, alpha_rho, j, k, l)
735737

738+
! min() drops a NaN candidate, so a cell with a NaN or non-positive dt would otherwise vanish from
739+
! the reduction and dt would come from the cells still valid.
740+
if (.not. (max_dt(1) > 0._wp)) bad_cell = max(bad_cell, 1 + j + (m + 1)*(k + (n + 1)*l))
741+
736742
icfl_dt_local = min(icfl_dt_local, max_dt(1))
737743
vcfl_dt_local = min(vcfl_dt_local, max_dt(2))
738744
ccfl_dt_local = min(ccfl_dt_local, max_dt(3))
@@ -743,6 +749,8 @@ contains
743749
end do
744750
$:END_GPU_PARALLEL_LOOP()
745751

752+
if (bad_cell > 0) call s_abort_on_bad_dt_cell(bad_cell - 1)
753+
746754
! restrict the time step so an ongoing collision spans at least collision_temporal_resolution time steps; the collision
747755
! flag is rank-local, so the cap enters as a candidate before the global elementwise min propagates it to all ranks
748756
if (collision_model > 0 .and. collision_temporal_resolution > 0) then
@@ -775,6 +783,27 @@ contains
775783

776784
end subroutine s_compute_dt
777785

786+
!> Abort with the location of a fluid cell whose state admits no valid time step (NaN or non-positive inviscid dt).
787+
impure subroutine s_abort_on_bad_dt_cell(idx)
788+
789+
integer, intent(in) :: idx !< Rank-local linear index j + (m+1)*(k + (n+1)*l)
790+
integer :: j, k, l
791+
real(wp) :: loc(3)
792+
character(len=256) :: msg
793+
794+
j = mod(idx, m + 1)
795+
k = mod(idx/(m + 1), n + 1)
796+
l = idx/((m + 1)*(n + 1))
797+
loc = 0._wp
798+
loc(1) = x_cc(j)
799+
if (n > 0) loc(2) = y_cc(k)
800+
if (p > 0) loc(3) = z_cc(l)
801+
write (msg, '(A,I0,A,3(I0,1X),A,3(ES12.4,1X),A)') 'No valid time step: rank ', proc_rank, ', local cell (j,k,l) = ', j, &
802+
& k, l, ', x = ', loc, '. Its state is NaN or unphysical.'
803+
call s_mpi_abort(trim(msg))
804+
805+
end subroutine s_abort_on_bad_dt_cell
806+
778807
!> Apply the body forces source term at each Runge-Kutta stage
779808
subroutine s_apply_bodyforces(q_cons_vf, q_prim_vf_in, rhs_vf_in, ldt)
780809

0 commit comments

Comments
 (0)