Update the undefined messages.
204{
205 BL_PROFILE("spades::MessageParticleContainer::update_undefined()");
206
207 const auto& plo = Geom(
LEV).ProbLoArray();
208 const auto& dx = Geom(
LEV).CellSizeArray();
209 const auto& dom = Geom(
LEV).Domain();
210 int n_removals = 0;
211
213 m_gdb->Geom(), m_gdb->DistributionMap(), m_gdb->boxArray(),
ngrow());
214 for (amrex::MFIter mfi = MakeMFIter(
LEV); mfi.isValid(); ++mfi) {
215 pc_adds.DefineAndReturnParticleTile(
LEV, mfi);
216 }
217
218 for (amrex::MFIter mfi = MakeMFIter(
LEV); mfi.isValid(); ++mfi) {
219 const amrex::Box& box = mfi.tilebox();
220 const auto index = std::make_pair(mfi.index(), mfi.LocalTileIndex());
221 const auto& cnt_arr =
m_counts.const_array(mfi);
222 const auto& offsets_arr =
m_offsets.const_array(mfi);
223 auto& pti = GetParticles(
LEV)[index];
225
226
227 const auto ncells = static_cast<int>(box.numPts());
228 amrex::Gpu::DeviceVector<int> removals(ncells, 0);
229 auto* p_removals = removals.data();
230 amrex::ParallelFor(ncells, [=] AMREX_GPU_DEVICE(long icell) noexcept {
231 const auto iv = box.atOffset(icell);
233 const int target_count = std::max(2 * msg_count, 2);
235 if (current_count > target_count) {
236 p_removals[icell] = current_count - target_count;
237 }
238 });
239
240 n_removals += amrex::Reduce::Sum(removals.size(), p_removals);
241
242 amrex::ParallelFor(
243 box, [=] AMREX_GPU_DEVICE(
244 int i, int j, int AMREX_D_PICK(, , k)) noexcept {
245 const amrex::IntVect iv(AMREX_D_DECL(i, j, k));
246 const auto idx = box.index(iv);
247 const auto np = p_removals[idx];
248 const auto getter = Get(iv, cnt_arr, offsets_arr, parrs);
249 for (int m = 0; m < np; m++) {
251 parrs.m_aos[pidx].id() = -1;
252 }
253 });
254
255 amrex::Gpu::DeviceVector<int> additions(ncells, 0);
256 auto* p_additions = additions.data();
257 amrex::ParallelFor(ncells, [=] AMREX_GPU_DEVICE(long icell) noexcept {
258 const auto iv = box.atOffset(icell);
260 const int target_count = std::max(2 * msg_count, 2);
262 if (target_count > current_count) {
263 p_additions[icell] = target_count - current_count;
264 }
265#ifdef AMREX_DEBUG
266 if (p_removals[icell] > 0) {
267 AMREX_ASSERT(p_additions[icell] == 0);
268 }
269 if (p_additions[icell] > 0) {
270 AMREX_ASSERT(p_removals[icell] == 0);
271 }
272#endif
273 });
274
275 amrex::Gpu::DeviceVector<int> update_offsets(ncells, 0);
276 auto* p_update_offsets = update_offsets.data();
277 const auto np = amrex::Scan::PrefixSum<int>(
278 ncells,
279 [=] AMREX_GPU_DEVICE(int i) -> int { return p_additions[i]; },
280 [=] AMREX_GPU_DEVICE(int i, int const& xi) {
281 p_update_offsets[i] = xi;
282 },
283 amrex::Scan::Type::exclusive, amrex::Scan::retSum);
284
285 const amrex::Long pid = ParticleType::NextID();
286 ParticleType::NextID(pid + np);
287 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(
288 static_cast<amrex::Long>(pid + np) < amrex::LastParticleID,
289 "Error: overflow on particle id numbers!");
290
291 auto& pti_adds = pc_adds.GetParticles(
LEV)[index];
292 pti_adds.resize(np);
293 const auto my_proc = amrex::ParallelDescriptor::MyProc();
294 const auto parrs_adds = pc_adds.particle_arrays(pti_adds);
295 amrex::ParallelFor(ncells, [=] AMREX_GPU_DEVICE(long icell) noexcept {
296 const int start = p_update_offsets[icell];
297 const auto iv = box.atOffset(icell);
298 for (int n = start; n < start + p_additions[icell]; n++) {
299 auto& p = parrs_adds.m_aos[n];
300 p.id() = pid + n;
301 p.cpu() = my_proc;
302
303 AMREX_D_TERM(
307
308 MarkMessageUndefined()(n, parrs_adds);
310 static_cast<int>(dom.index(iv));
313 static_cast<int>(dom.index(iv));
315
316 AMREX_D_TERM(
320
321 AMREX_D_TERM(parrs_adds.m_idata[CommonIntData::i][n] = iv[0];
322 , parrs_adds.m_idata[CommonIntData::j][n] = iv[1];
323 , parrs_adds.m_idata[CommonIntData::k][n] = iv[2];)
324 }
325 });
326
327
328 amrex::Gpu::streamSynchronize();
329 }
330
331 addParticles(pc_adds, true);
332
333 amrex::ParallelAllReduce::Sum<int>(
334 n_removals, amrex::ParallelContext::CommunicatorSub());
335 if (n_removals > 0) {
336 Redistribute();
337 }
338}
MessageParticleContainer(amrex::AmrParGDB *par_gdb, int ngrow=0)
Constructor.
Definition MessageParticleContainer.cpp:6