| 1364 | template <typename ParticleType, int NArrayReal, int NArrayInt, |
| 1365 | template<class> class Allocator, class CellAssignor> |
| 1366 | void |
| 1367 | ParticleContainer_impl<ParticleType, NArrayReal, NArrayInt, Allocator, CellAssignor> |
| 1368 | ::InitRandomPerBox (Long icount_per_box, |
| 1369 | ULong iseed, |
| 1370 | const ParticleInitData& pdata) |
| 1371 | { |
| 1372 | BL_PROFILE("ParticleContainer<NSR, NSI, NAR, NAI>::InitRandomPerBox()"); |
| 1373 | AMREX_ASSERT(iseed > 0); |
| 1374 | AMREX_ASSERT(icount_per_box > 0); |
| 1375 | |
| 1376 | AMREX_ASSERT(m_gdb != nullptr); |
| 1377 | |
| 1378 | const int IOProc = ParallelDescriptor::IOProcessorNumber(); |
| 1379 | const auto strttime = amrex::second(); |
| 1380 | const Geometry& geom = Geom(0); |
| 1381 | |
| 1382 | ParticleLocData pld; |
| 1383 | ParticleType p; |
| 1384 | |
| 1385 | // This assumes level 0 since geom = m_gdb->Geom(0) |
| 1386 | const Real* dx = geom.CellSize(); |
| 1387 | |
| 1388 | // We use exactly the same seed for every grid |
| 1389 | std::mt19937 mt(iseed); |
| 1390 | std::uniform_real_distribution<double> dist(0.0, 1.0); |
| 1391 | |
| 1392 | m_particles.resize(m_gdb->finestLevel()+1); |
| 1393 | |
| 1394 | for (int lev = 0; lev < std::ssize(m_particles); lev++) |
| 1395 | { |
| 1396 | AMREX_ASSERT(m_particles[lev].empty()); |
| 1397 | } |
| 1398 | |
| 1399 | // We'll generate the particles in parallel -- but no tiling here. |
| 1400 | for (MFIter mfi(*m_dummy_mf[0], false); mfi.isValid(); ++mfi) |
| 1401 | { |
| 1402 | Box grid = m_gdb->ParticleBoxArray(0)[mfi.index()]; |
| 1403 | RealBox grid_box = RealBox(grid,dx,geom.ProbLo()); |
| 1404 | |
| 1405 | for (Long icnt = 0; icnt < icount_per_box; icnt++) { |
| 1406 | for (Long jcnt = 0; jcnt < icount_per_box; jcnt++) { |
| 1407 | for (Long kcnt = 0; kcnt < icount_per_box; kcnt++) |
| 1408 | { |
| 1409 | AMREX_D_TERM( |
| 1410 | p.pos(0) = static_cast<ParticleReal>(grid_box.lo(0) + (dist(mt) + double(icnt)) / double(icount_per_box) * grid_box.length(0));, |
| 1411 | p.pos(1) = static_cast<ParticleReal>(grid_box.lo(1) + (dist(mt) + double(jcnt)) / double(icount_per_box) * grid_box.length(1));, |
| 1412 | p.pos(2) = static_cast<ParticleReal>(grid_box.lo(2) + (dist(mt) + double(kcnt)) / double(icount_per_box) * grid_box.length(2)); |
| 1413 | ); |
| 1414 | |
| 1415 | for (int i = 0; i < AMREX_SPACEDIM; i++) { |
| 1416 | AMREX_ASSERT(p.pos(i) < grid_box.hi(i)); |
| 1417 | } |
| 1418 | |
| 1419 | // the real struct data |
| 1420 | for (int i = 0; i < NStructReal; i++) { |
| 1421 | p.rdata(i) = static_cast<ParticleReal>(pdata.real_struct_data[i]); |
| 1422 | } |
| 1423 | |