Skip to content

Commit e6db7c9

Browse files
avoid NaN in maxParticleVelocity() (#6831)
This PR is an attempt to fix a random job hang that I've experienced recently on Tuolumne. I've tracked the hang down to `mypc->maxParticleVelocity()`, which is called from `UpdateDtFromParticleSpeeds()` when using dynamic time stepping. The code there does not guard against boxes with zero particles, which eventually results in taking the sqrt of an uninitialized value resulting in local `max_v = nan`. This PR avoids NaN values. With this fix, I have not yet observed any random job hanging.
1 parent 6c54afa commit e6db7c9

1 file changed

Lines changed: 10 additions & 3 deletions

File tree

Source/Particles/WarpXParticleContainer.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2331,25 +2331,32 @@ amrex::ParticleReal WarpXParticleContainer::maxParticleVelocity(bool local) {
23312331
ReduceOps<ReduceOpMax> reduce_op;
23322332
ReduceData<ParticleReal> reduce_data(reduce_op);
23332333

2334+
amrex::Long np_total = 0;
2335+
23342336
const int nLevels = finestLevel();
23352337

23362338
#ifdef AMREX_USE_OMP
2337-
#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
2339+
#pragma omp parallel reduction(+:np_total) if (amrex::Gpu::notInLaunchRegion())
23382340
#endif
23392341
for (int lev = 0; lev <= nLevels; ++lev) {
23402342
for (WarpXParIter pti(*this, lev); pti.isValid(); ++pti)
23412343
{
2344+
const amrex::Long np = pti.numParticles();
2345+
if (np == 0) { continue; }
2346+
2347+
np_total += np;
2348+
23422349
auto *const ux = pti.GetAttribs(PIdx::ux).data();
23432350
auto *const uy = pti.GetAttribs(PIdx::uy).data();
23442351
auto *const uz = pti.GetAttribs(PIdx::uz).data();
23452352

2346-
reduce_op.eval(pti.numParticles(), reduce_data,
2353+
reduce_op.eval(np, reduce_data,
23472354
[=] AMREX_GPU_DEVICE (int ip)
23482355
{ return (ux[ip]*ux[ip] + uy[ip]*uy[ip] + uz[ip]*uz[ip]) * inv_c2; });
23492356
}
23502357
}
23512358

2352-
const amrex::ParticleReal max_usq = amrex::get<0>(reduce_data.value());
2359+
const amrex::ParticleReal max_usq = (np_total > 0 ? amrex::get<0>(reduce_data.value()) : 0._prt);
23532360

23542361
const amrex::ParticleReal gaminv = 1.0_prt/std::sqrt(1.0_prt + max_usq);
23552362
amrex::ParticleReal max_v = gaminv * std::sqrt(max_usq) * PhysConst::c;

0 commit comments

Comments
 (0)