Block-Structured AMR Software Framework
 
Loading...
Searching...
No Matches
AMReX_NeighborParticlesI.H
Go to the documentation of this file.
1
2namespace amrex {
3
4template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
6
7template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
9
10template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
11NeighborParticleContainer<NStructReal, NStructInt, NArrayReal, NArrayInt>
12::NeighborParticleContainer (ParGDBBase* gdb, int ncells)
13 : ParticleContainer<NStructReal, NStructInt, NArrayReal, NArrayInt> (gdb),
14 m_num_neighbor_cells(ncells)
15{
17}
18
19template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
22 const DistributionMapping & dmap,
23 const BoxArray & ba,
24 int nneighbor)
25 : ParticleContainer<NStructReal, NStructInt, NArrayReal, NArrayInt> (geom, dmap, ba),
26 m_num_neighbor_cells(nneighbor)
27{
29}
30
31template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
34 const Vector<DistributionMapping> & dmap,
35 const Vector<BoxArray> & ba,
36 const Vector<int> & rr,
37 int nneighbor)
38 : ParticleContainer<NStructReal, NStructInt, NArrayReal, NArrayInt> (geom, dmap, ba, rr),
39 m_num_neighbor_cells(nneighbor)
40{
42}
43
44template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
45void
48 for (int ii = 0; ii < AMREX_SPACEDIM + NStructReal + this->NumRealComps(); ++ii) {
49 ghost_real_comp.push_back(1);
50 }
51 for (int ii = 0; ii < 2 + NStructInt + this->NumIntComps(); ++ii) {
52 ghost_int_comp.push_back(1);
53 }
54 calcCommSize();
55}
56
57template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
58void
60::setRealCommComp (int i, bool value) {
61 ghost_real_comp[i] = value;
62 calcCommSize();
63}
64
65template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
66void
68::setIntCommComp (int i, bool value) {
69 ghost_int_comp[i] = value;
70 calcCommSize();
71}
72
73template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
74void
77 size_t comm_size = 0;
78 for (int ii = 0; ii < AMREX_SPACEDIM + NStructReal + this->NumRealComps(); ++ii) {
79 if (ghost_real_comp[ii]) {
80 comm_size += sizeof(typename ParticleType::RealType);
81 }
82 }
83 for (int ii = 0; ii < 2 + NStructInt + this->NumIntComps(); ++ii) {
84 if (ghost_int_comp[ii]) {
85 comm_size += sizeof(int);
86 }
87 }
88 if ( enableInverse() ) { comm_size += 4*sizeof(int); }
89 cdata_size = comm_size;
90}
91
92template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
93void
95::Regrid (const DistributionMapping &dmap, const BoxArray &ba ) {
96 const int lev = 0;
97 AMREX_ASSERT(this->finestLevel() == 0);
98 this->SetParticleBoxArray(lev, ba);
99 this->SetParticleDistributionMap(lev, dmap);
100 this->Redistribute();
101}
102
103template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
104void
106::Regrid (const DistributionMapping &dmap, const BoxArray &ba, int lev) {
107 AMREX_ASSERT(lev <= this->finestLevel());
108 this->SetParticleBoxArray(lev, ba);
109 this->SetParticleDistributionMap(lev, dmap);
110 this->Redistribute();
111}
112
113template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
114void
117 AMREX_ASSERT(ba.size() == this->finestLevel()+1);
118 for (int lev = 0; lev < this->numLevels(); ++lev)
119 {
120 this->SetParticleBoxArray(lev, ba[lev]);
121 this->SetParticleDistributionMap(lev, dmap[lev]);
122 }
123 this->Redistribute();
124}
125
126template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
127bool
130
131 BL_PROFILE("NeighborParticleContainer::areMasksValid");
132
133 resizeContainers(this->numLevels());
134
135 for (int lev = 0; lev < this->numLevels(); ++lev)
136 {
137 BoxArray ba = this->ParticleBoxArray(lev);
138 const DistributionMapping& dmap = this->ParticleDistributionMap(lev);
139
140 if (mask_ptr[lev] == nullptr ||
141 ! BoxArray::SameRefs(mask_ptr[lev]->boxArray(), ba) ||
142 ! DistributionMapping::SameRefs(mask_ptr[lev]->DistributionMap(), dmap))
143 {
144 return false;
145 }
146 }
147 return true;
148}
149
150template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
151void
154
155 BL_PROFILE("NeighborParticleContainer::BuildMasks");
156
157 if (this->numLevels() == 1) { use_mask = true; }
158 else { use_mask = false; }
159
160 resizeContainers(this->numLevels());
161
162 for (int lev = 0; lev < this->numLevels(); ++lev)
163 {
164 BoxArray ba = this->ParticleBoxArray(lev);
165 const DistributionMapping& dmap = this->ParticleDistributionMap(lev);
166
167 const Geometry& geom = this->Geom(lev);
168
169 mask_ptr[lev] = std::make_unique<iMultiFab>(ba, dmap, int(num_mask_comps), m_num_neighbor_cells);
170 mask_ptr[lev]->setVal(-1, m_num_neighbor_cells);
171
172#ifdef AMREX_USE_OMP
173#pragma omp parallel
174#endif
175 for (MFIter mfi(*mask_ptr[lev],this->do_tiling ? this->tile_size : IntVect::TheZeroVector());
176 mfi.isValid(); ++mfi) {
177 const Box& box = mfi.tilebox();
178 const int grid_id = mfi.index();
179 const int tile_id = mfi.LocalTileIndex();
180 (*mask_ptr[lev])[mfi].template setVal<RunOn::Host>(grid_id, box, MaskComps::grid, 1);
181 (*mask_ptr[lev])[mfi].template setVal<RunOn::Host>(tile_id, box, MaskComps::tile, 1);
182 (*mask_ptr[lev])[mfi].template setVal<RunOn::Host>(lev , box, MaskComps::level, 1);
183 }
184
185 mask_ptr[lev]->FillBoundary(geom.periodicity());
186 }
187}
188
189template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
190void
193{
194 BL_PROFILE("NeighborParticleContainer::GetNeighborCommTags");
195
196 local_neighbors.clear();
197 neighbor_procs.clear();
198
199 if (use_mask)
200 {
201 AMREX_ASSERT(this->finestLevel() == 0);
202 const int lev = 0;
203 for (MFIter mfi(*mask_ptr[lev],this->do_tiling ? this->tile_size : IntVect::TheZeroVector());
204 mfi.isValid(); ++mfi) {
205 const Box& box = mfi.growntilebox();
206 for (IntVect iv = box.smallEnd(); iv <= box.bigEnd(); box.next(iv)) {
207 const int grid = (*mask_ptr[lev])[mfi](iv, MaskComps::grid);
208 if (grid >= 0) {
209 const int tile = (*mask_ptr[lev])[mfi](iv, MaskComps::tile);
210 const int level = (*mask_ptr[lev])[mfi](iv, MaskComps::level);
211 const int global_proc = this->ParticleDistributionMap(level)[grid];
212 const int proc = ParallelContext::global_to_local_rank(global_proc);
213 NeighborCommTag comm_tag(proc, level, grid, tile);
214 local_neighbors.push_back(comm_tag);
215 if (proc != ParallelContext::MyProcSub()) {
216 neighbor_procs.push_back(proc);
217 }
218 }
219 }
220 }
221 }
222 else
223 {
224 for (int lev = 0; lev < this->numLevels(); ++lev)
225 {
226 for (MFIter mfi(*mask_ptr[lev],this->do_tiling ? this->tile_size : IntVect::TheZeroVector());
227 mfi.isValid(); ++mfi) {
228 const Box& box = mfi.validbox();
229 Vector<NeighborCommTag> comm_tags;
230 GetCommTagsBox(comm_tags, lev, box);
231 for (auto const& tag : comm_tags) {
232 local_neighbors.push_back(tag);
233 if (tag.proc_id != ParallelContext::MyProcSub()) {
234 neighbor_procs.push_back(tag.proc_id);
235 }
236 }
237 }
238 }
239 }
240
241 RemoveDuplicates(local_neighbors);
242 RemoveDuplicates(neighbor_procs);
243}
244
245template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
248::computeRefFac (int src_lev, int lev)
249{
250 IntVect ref_fac(1);
251 if (src_lev < lev) {
252 for (int l = src_lev; l < lev; ++l) {
253 ref_fac *= this->GetParGDB()->refRatio(l);
254 }
255 } else if (src_lev > lev) {
256 for (int l = src_lev; l > lev; --l) {
257 ref_fac *= this->GetParGDB()->refRatio(l-1);
258 }
259 ref_fac *= -1;
260 }
261 return ref_fac;
262}
263
264template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
265void
267::GetCommTagsBox (Vector<NeighborCommTag>& tags, int src_lev, const Box& in_box)
268{
269 std::vector< std::pair<int, Box> > isects;
270 Box tbx;
271
272 for (int lev = 0; lev < this->numLevels(); ++lev) {
273 Box box = in_box;
274 const IntVect& ref_fac = computeRefFac(src_lev, lev);
275 if (ref_fac < IntVect::TheZeroVector())
276 {
277 box.coarsen(-1*ref_fac);
278 }
279 else if (ref_fac > IntVect::TheZeroVector())
280 {
281 box.refine(ref_fac);
282 }
283 box.grow(computeRefFac(0, lev)*m_num_neighbor_cells);
284 const Periodicity& periodicity = this->Geom(lev).periodicity();
285 const std::vector<IntVect>& pshifts = periodicity.shiftIntVect();
286 const BoxArray& ba = this->ParticleBoxArray(lev);
287
288 for (auto const& pshift : pshifts)
289 {
290 const Box& pbox = box + pshift;
291 bool first_only = false;
292 ba.intersections(pbox, isects, first_only, 0);
293 for (const auto& isec : isects) {
294 const int grid = isec.first;
295 const int global_proc = this->ParticleDistributionMap(lev)[grid];
296 const int proc = ParallelContext::global_to_local_rank(global_proc);
297 for (IntVect iv = pbox.smallEnd(); iv <= pbox.bigEnd(); pbox.next(iv))
298 {
299 if (ba[grid].contains(iv))
300 {
301 int tile = getTileIndex(iv, ba[grid],
302 this->do_tiling, this->tile_size, tbx);
303 tags.push_back(NeighborCommTag(proc, lev, grid, tile));
304 }
305 }
306 }
307 }
308 }
309}
310
311template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
312void
315
316 BL_PROFILE("NeighborParticleContainer::cacheNeighborInfo");
317
318 AMREX_ASSERT(this->OK());
319
320 resizeContainers(this->numLevels());
321
322 clearNeighbors();
323
324 AMREX_ASSERT(hasNeighbors() == false);
325
326 const int MyProc = ParallelContext::MyProcSub();
327
329 std::map<NeighborCommTag, Vector<NeighborIndexMap> > remote_map;
330
331 // tmp data structures used for OMP reduction
333 std::map<NeighborCommTag, Vector<Vector<NeighborIndexMap> > > tmp_remote_map;
334
335 local_map.resize(this->numLevels());
336 tmp_local_map.resize(this->numLevels());
337
338 int num_threads = OpenMP::get_max_threads();
339
340 for (int lev = 0; lev < this->numLevels(); ++lev) {
341 // resize our temporaries in serial
342 for (int i = 0; i < static_cast<int>(local_neighbors.size()); ++i) {
343 const NeighborCommTag& comm_tag = local_neighbors[i];
344 tmp_remote_map[comm_tag].resize(num_threads);
345 remote_map[comm_tag];
346 PairIndex index(comm_tag.grid_id, comm_tag.tile_id);
347 tmp_local_map[lev][index].resize(num_threads);
348 local_map[lev][index];
349 buffer_tag_cache[lev][index].resize(num_threads);
350 }
351 }
352
353 for (int lev = 0; lev < this->numLevels(); ++lev) {
354 // First pass - each thread collects the NeighborIndexMaps it owes to other
355 // grids / tiles / procs
356#ifdef AMREX_USE_OMP
357#pragma omp parallel
358#endif
359 {
361 tags.reserve(AMREX_D_TERM(3, *3, *3));
362 for (MyParIter pti(*this, lev); pti.isValid(); ++pti) {
363 int thread_num = OpenMP::get_thread_num();
364 const int& grid = pti.index();
365 const int& tile = pti.LocalTileIndex();
366 PairIndex src_index(grid, tile);
367
368 NeighborCopyTag src_tag(lev, grid, tile);
369
370 auto& cache = buffer_tag_cache[lev][src_index][thread_num];
371
372 auto& particles = pti.GetArrayOfStructs();
373 for (int i = 0; i < pti.numParticles(); ++i) {
374 const ParticleType& p = particles[i];
375
376 getNeighborTags(tags, p, m_num_neighbor_cells, src_tag, pti);
377
378 // Add neighbors to buffers
379 for (int j = 0; j < static_cast<int>(tags.size()); ++j) {
380 NeighborCopyTag& tag = tags[j];
381 PairIndex dst_index(tag.grid, tag.tile);
382 if (tag.grid < 0) { continue; }
383
384 tag.src_index = i;
385 const int cache_index = cache.size();
386 cache.push_back(tag);
387
388 const int global_who = this->ParticleDistributionMap(tag.level)[tag.grid];
389 const int who = ParallelContext::global_to_local_rank(global_who);
390 NeighborIndexMap nim(tag.level, dst_index.first, dst_index.second, -1,
391 lev, src_index.first, src_index.second,
392 cache_index, thread_num);
393 if (who == MyProc) {
394 auto& tmp = tmp_local_map[tag.level][dst_index];
395 Vector<NeighborIndexMap>& buffer = tmp[thread_num];
396 buffer.push_back(nim);
397 } else {
398 NeighborCommTag comm_tag(who, tag.level, tag.grid, tag.tile);
399 Vector<NeighborIndexMap>& buffer = tmp_remote_map[comm_tag][thread_num];
400 buffer.push_back(nim);
401 }
402 }
403 tags.clear();
404 }
405 }
406 }
407 }
408
409 for (int lev = 0; lev < this->numLevels(); ++lev) {
410 // second pass - for each tile, collect the neighbors owed from all threads
411#ifdef AMREX_USE_OMP
412#pragma omp parallel
413#endif
414 for (MFIter mfi = this->MakeMFIter(lev); mfi.isValid(); ++mfi) {
415 const int grid = mfi.index();
416 const int tile = mfi.LocalTileIndex();
417 PairIndex index(grid, tile);
418 for (int i = 0; i < num_threads; ++i) {
419 local_map[lev][index].insert(local_map[lev][index].end(),
420 tmp_local_map[lev][index][i].begin(),
421 tmp_local_map[lev][index][i].end());
422 tmp_local_map[lev][index][i].erase(tmp_local_map[lev][index][i].begin(),
423 tmp_local_map[lev][index][i].end());
424 }
425 }
426 }
427
428 // do the same for the remote neighbors
429 typename std::map<NeighborCommTag, Vector<Vector<NeighborIndexMap> > >::iterator it;
430#ifdef AMREX_USE_OMP
431#pragma omp parallel
432#pragma omp single nowait
433#endif
434 for (it=tmp_remote_map.begin(); it != tmp_remote_map.end(); it++) {
435#ifdef AMREX_USE_OMP
436#pragma omp task firstprivate(it)
437#endif
438 {
439 const NeighborCommTag& tag = it->first;
440 Vector<Vector<NeighborIndexMap> >& tmp = it->second;
441 for (int i = 0; i < num_threads; ++i) {
442 remote_map[tag].insert(remote_map[tag].end(), tmp[i].begin(), tmp[i].end());
443 tmp[i].erase(tmp[i].begin(), tmp[i].end());
444 }
445 }
446 }
447
448 for (int lev = 0; lev < this->numLevels(); ++lev) {
449 // now for the local neighbors, allocate buffers and cache
450 for (MFIter mfi = this->MakeMFIter(lev); mfi.isValid(); ++mfi) {
451 const int grid = mfi.index();
452 const int tile = mfi.LocalTileIndex();
453 PairIndex dst_index(grid, tile);
454 const Vector<NeighborIndexMap>& map = local_map[lev][dst_index];
455 const int num_ghosts = map.size();
456 neighbors[lev][dst_index].define(this->NumRuntimeRealComps(),
457 this->NumRuntimeIntComps(),
458 nullptr, nullptr, this->arena());
459 neighbors[lev][dst_index].resize(num_ghosts);
460 local_neighbor_sizes[lev][dst_index] = neighbors[lev][dst_index].size();
461 }
462 }
463
464 for (int lev = 0; lev < this->numLevels(); ++lev) {
465 for (MFIter mfi = this->MakeMFIter(lev); mfi.isValid(); ++mfi) {
466 const int grid = mfi.index();
467 const int tile = mfi.LocalTileIndex();
468 PairIndex dst_index(grid, tile);
469 const Vector<NeighborIndexMap>& map = local_map[lev][dst_index];
470 const int num_ghosts = map.size();
471#ifdef AMREX_USE_OMP
472#pragma omp parallel for
473#endif
474 for (int i = 0; i < num_ghosts; ++i) {
475 const NeighborIndexMap& nim = map[i];
476 PairIndex src_index(nim.src_grid, nim.src_tile);
477 Vector<NeighborCopyTag>& tags = buffer_tag_cache[nim.src_level][src_index][nim.thread_num];
478 AMREX_ASSERT(nim.src_index < tags.size());
479 tags[nim.src_index].dst_index = i;
480 AMREX_ASSERT(size_t(tags[nim.src_index].dst_index) < neighbors[nim.dst_level][dst_index].size());
481 }
482 }
483 }
484
485 // now we allocate the send buffers and cache the remotes
486 std::map<int, int> tile_counts;
487 for (const auto& kv: remote_map) {
488 tile_counts[kv.first.proc_id] += 1;
489 }
490
491 for (const auto& kv: remote_map) {
492 if (kv.first.proc_id == MyProc) { continue; }
493 Vector<char>& buffer = send_data[kv.first.proc_id];
494 buffer.resize(sizeof(int));
495 std::memcpy(buffer.data(), &tile_counts[kv.first.proc_id], sizeof(int));
496 }
497
498 for (auto& kv : remote_map) {
499 if (kv.first.proc_id == MyProc) { continue; }
500 int np = kv.second.size();
501 int data_size = np * cdata_size;
502 Vector<char>& buffer = send_data[kv.first.proc_id];
503 size_t old_size = buffer.size();
504 size_t new_size = buffer.size() + 4*sizeof(int) + data_size;
505 buffer.resize(new_size);
506 char* dst = &buffer[old_size];
507 std::memcpy(dst, &(kv.first.level_id), sizeof(int)); dst += sizeof(int);
508 std::memcpy(dst, &(kv.first.grid_id ), sizeof(int)); dst += sizeof(int);
509 std::memcpy(dst, &(kv.first.tile_id ), sizeof(int)); dst += sizeof(int);
510 std::memcpy(dst, &data_size, sizeof(int)); dst += sizeof(int);
511 size_t buffer_offset = old_size + 4*sizeof(int);
512#ifdef AMREX_USE_OMP
513#pragma omp parallel for
514#endif
515 for (int i = 0; i < np; ++i) {
516 const NeighborIndexMap& nim = kv.second[i];
517 PairIndex src_index(nim.src_grid, nim.src_tile);
518 Vector<NeighborCopyTag>& tags = buffer_tag_cache[nim.src_level][src_index][nim.thread_num];
519 tags[nim.src_index].dst_index = buffer_offset + i*cdata_size;
520 }
521 }
522
523 if ( enableInverse() )
524 {
525 for (int lev = 0; lev < this->numLevels(); ++lev)
526 {
527 for (const auto& kv : neighbors[lev])
528 {
529 inverse_tags[lev][kv.first].resize(kv.second.size());
530 }
531 }
532 }
533}
534
535template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
536void
539 int nGrow, const NeighborCopyTag& src_tag, const MyParIter& pti)
540{
541 getNeighborTags(tags, p, IntVect(AMREX_D_DECL(nGrow, nGrow, nGrow)), src_tag, pti);
542}
543
544template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
545void
548 const IntVect& nGrow, const NeighborCopyTag& src_tag, const MyParIter& pti)
549{
550 Box shrink_box = pti.tilebox();
551 shrink_box.grow(-nGrow);
552
553 if (use_mask) {
554 const BaseFab<int>& mask = (*mask_ptr[src_tag.level])[src_tag.grid];
555 AMREX_ASSERT(this->finestLevel() == 0);
556 AMREX_ASSERT(src_tag.level == 0);
557
558 const int lev = 0;
559 const IntVect& iv = this->Index(p, lev);
560 if (shrink_box.contains(iv)) { return; }
561
562 const Periodicity& periodicity = this->Geom(lev).periodicity();
563 const Box& domain = this->Geom(lev).Domain();
564 const IntVect& lo = domain.smallEnd();
565 const IntVect& hi = domain.bigEnd();
566
567 // Figure out all our neighbors, removing duplicates
569 for (int ii = -nGrow[0]; ii < nGrow[0] + 1; ii += nGrow[0]) {,
570 for (int jj = -nGrow[1]; jj < nGrow[1] + 1; jj += nGrow[1]) {,
571 for (int kk = -nGrow[2]; kk < nGrow[2] + 1; kk += nGrow[2]) {)
572 if (AMREX_D_TERM((ii == 0), && (jj == 0), && (kk == 0))) { continue; }
573 IntVect shift(AMREX_D_DECL(ii, jj, kk));
574 IntVect neighbor_cell = iv + shift;
575
576 NeighborCopyTag tag;
577 tag.grid = mask(neighbor_cell, MaskComps::grid);
578 tag.tile = mask(neighbor_cell, MaskComps::tile);
579 tag.level = mask(neighbor_cell, MaskComps::level);
580 if (periodicity.isAnyPeriodic()) {
581 for (int dir = 0; dir < AMREX_SPACEDIM; ++dir) {
582 if (! periodicity.isPeriodic(dir)) { continue; }
583 if (neighbor_cell[dir] < lo[dir]) {
584 tag.periodic_shift[dir] = -1;
585 } else if (neighbor_cell[dir] > hi[dir]) {
586 tag.periodic_shift[dir] = 1;
587 }
588 }
589 }
590
591 if (tag != src_tag) { tags.push_back(tag); }
592
594 },
595 },
596 })
597
598 RemoveDuplicates(tags);
599 return;
600 }
601 else
602 {
603 std::vector< std::pair<int, Box> > isects;
604 Box tbx;
605 for (int lev = 0; lev < this->numLevels(); ++lev)
606 {
607 IntVect ref_fac = computeRefFac(0, lev);
608 const Periodicity& periodicity = this->Geom(lev).periodicity();
609 const std::vector<IntVect>& pshifts = periodicity.shiftIntVect();
610 const BoxArray& ba = this->ParticleBoxArray(lev);
611 const IntVect& iv = this->Index(p, lev);
612 for (auto const& pshift : pshifts)
613 {
614 Box pbox = amrex::grow(Box(iv, iv), ref_fac*nGrow) + pshift;
615 bool first_only = false;
616 ba.intersections(pbox, isects, first_only, 0);
617 for (const auto& isec : isects)
618 {
619 const Box& grid_box = ba[isec.first];
620 for (IntVect cell = pbox.smallEnd(); cell <= pbox.bigEnd(); pbox.next(cell)) {
621 if ( !grid_box.contains(cell) ) { continue; }
622 int tile = getTileIndex(cell, grid_box,
623 this->do_tiling, this->tile_size, tbx);
624 auto nbor = NeighborCopyTag(lev, isec.first, tile);
625 nbor.periodic_shift = -pshift;
626 if (src_tag != nbor) { tags.push_back(nbor); }
627 }
628 }
629 }
630 }
631
632 RemoveDuplicates(tags);
633 return;
634 }
635}
636
637template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
638void
641#ifdef AMREX_USE_GPU
642 fillNeighborsGPU();
643#else
644 fillNeighborsCPU();
645#endif
646 m_has_neighbors = true;
647}
648
649template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
650void
652::sumNeighbors (int real_start_comp, int real_num_comp,
653 int int_start_comp, int int_num_comp) {
654#ifdef AMREX_USE_GPU
655 amrex::ignore_unused(real_start_comp,real_num_comp,int_start_comp,int_num_comp);
656 amrex::Abort("Not implemented.");
657#else
658 sumNeighborsCPU(real_start_comp, real_num_comp, int_start_comp, int_num_comp);
659#endif
660}
661
662template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
663void
665::updateNeighbors (bool boundary_neighbors_only)
666{
667
668 AMREX_ASSERT(hasNeighbors());
669
670#ifdef AMREX_USE_GPU
671 updateNeighborsGPU(boundary_neighbors_only);
672#else
673 amrex::ignore_unused(boundary_neighbors_only);
674 updateNeighborsCPU(true);
675#endif
676 m_has_neighbors = true;
677}
678
679template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
680void
683{
684#ifdef AMREX_USE_GPU
685 clearNeighborsGPU();
686#else
687 clearNeighborsCPU();
688#endif
689 m_has_neighbors = false;
690}
691
692template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
693template <class CheckPair>
694void
696buildNeighborList (CheckPair const& check_pair, bool /*sort*/)
697{
698 AMREX_ASSERT(numParticlesOutOfRange(*this, m_num_neighbor_cells) == 0);
699
700 BL_PROFILE("NeighborParticleContainer::buildNeighborList");
701
702 resizeContainers(this->numLevels());
703
704 for (int lev = 0; lev < this->numLevels(); ++lev)
705 {
706 m_neighbor_list[lev].clear();
707
708 for (MyParIter pti(*this, lev); pti.isValid(); ++pti) {
709 PairIndex index(pti.index(), pti.LocalTileIndex());
710 m_neighbor_list[lev][index];
711 }
712
713#ifndef AMREX_USE_GPU
714 neighbor_list[lev].clear();
715 for (MyParIter pti(*this, lev); pti.isValid(); ++pti) {
716 PairIndex index(pti.index(), pti.LocalTileIndex());
717 neighbor_list[lev][index];
718 }
719#endif
720
721 auto& plev = this->GetParticles(lev);
722 const auto& geom = this->Geom(lev);
723
724#ifdef AMREX_USE_OMP
725#pragma omp parallel if (Gpu::notInLaunchRegion())
726#endif
727 for (MyParIter pti(*this, lev); pti.isValid(); ++pti)
728 {
729 int gid = pti.index();
730 int tid = pti.LocalTileIndex();
731 auto index = std::make_pair(gid, tid);
732
733 auto& ptile = plev[index];
734
735 if (ptile.numParticles() == 0) { continue; }
736
737 Box bx = pti.tilebox();
738 int ng = computeRefFac(0, lev).max()*m_num_neighbor_cells;
739 bx.grow(ng);
740
741 Gpu::DeviceVector<int> off_bins_v;
746
747 off_bins_v.push_back(0);
748 off_bins_v.push_back(int(bx.numPts()));
749 lo_v.push_back(lbound(bx));
750 hi_v.push_back(ubound(bx));
751 dxi_v.push_back(geom.InvCellSizeArray());
752 plo_v.push_back(geom.ProbLoArray());
753
754 m_neighbor_list[lev][index].build(ptile,
755 check_pair,
756 off_bins_v, dxi_v, plo_v, lo_v, hi_v, ng);
757
758#ifndef AMREX_USE_GPU
759 const auto& counts = m_neighbor_list[lev][index].GetCounts();
760 const auto& list = m_neighbor_list[lev][index].GetList();
761
762 int li = 0;
763 for (int i = 0; i < ptile.numParticles(); ++i)
764 {
765 auto cnt = counts[i];
766 neighbor_list[lev][index].push_back(cnt);
767 for (size_t j = 0; j < cnt; ++j)
768 {
769 neighbor_list[lev][index].push_back(list[li++]+1);
770 }
771 }
772#endif
773 }
774 }
775}
776
777template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
778template <class CheckPair, class OtherPCType>
779void
781buildNeighborList (CheckPair const& check_pair, OtherPCType& other,
782 Vector<std::map<std::pair<int, int>, amrex::NeighborList<typename OtherPCType::ParticleType> > >& neighbor_lists,
783 bool /*sort*/)
784{
785 BL_PROFILE("NeighborParticleContainer::buildNeighborList");
786
787 AMREX_ASSERT(numParticlesOutOfRange(*this, m_num_neighbor_cells) == 0);
788 AMREX_ASSERT(numParticlesOutOfRange(other, m_num_neighbor_cells) == 0);
789 AMREX_ASSERT(SameIteratorsOK(*this, other));
790
793
794 resizeContainers(this->numLevels());
795 neighbor_lists.resize(this->numLevels());
796
797 for (int lev = 0; lev < this->numLevels(); ++lev)
798 {
799 neighbor_lists[lev].clear();
800
801 for (MyParIter pti(*this, lev); pti.isValid(); ++pti) {
802 PairIndex index(pti.index(), pti.LocalTileIndex());
803 neighbor_lists[lev][index];
804 }
805
806 auto& plev = this->GetParticles(lev);
807 const auto& geom = this->Geom(lev);
808
809#ifdef AMREX_USE_OMP
810#pragma omp parallel if (Gpu::notInLaunchRegion())
811#endif
812 for (MyParIter pti(*this, lev); pti.isValid(); ++pti)
813 {
814 int gid = pti.index();
815 int tid = pti.LocalTileIndex();
816 auto index = std::make_pair(gid, tid);
817
818 const auto& ptile = plev[index];
819 auto& other_ptile = other.ParticlesAt(lev, pti);
820 if (ptile.numParticles() == 0) { continue; }
821
822 Box bx = pti.tilebox();
823 int ng = computeRefFac(0, lev).max()*m_num_neighbor_cells;
824 bx.grow(ng);
825
826 Gpu::DeviceVector<int> off_bins_v;
831
832 off_bins_v.push_back(0);
833 off_bins_v.push_back(int(bx.numPts()));
834 lo_v.push_back(lbound(bx));
835 hi_v.push_back(ubound(bx));
836 dxi_v.push_back(geom.InvCellSizeArray());
837 plo_v.push_back(geom.ProbLoArray());
838
839 neighbor_lists[lev][index].build(ptile, other_ptile,
840 check_pair,
841 off_bins_v, dxi_v, plo_v, lo_v, hi_v, ng);
842 }
843 }
844}
845
846template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
847template <class CheckPair>
848void
850buildNeighborList (CheckPair const& check_pair, int type_ind, int* ref_ratio,
851 int num_bin_types, bool /*sort*/)
852{
853 AMREX_ASSERT(numParticlesOutOfRange(*this, m_num_neighbor_cells) == 0);
854
855 if (num_bin_types == 1) { AMREX_ASSERT(ref_ratio[0] == 1); }
856
857 BL_PROFILE("NeighborParticleContainer::buildNeighborList");
858
859 resizeContainers(this->numLevels());
860
861 for (int lev = 0; lev < this->numLevels(); ++lev)
862 {
863 m_neighbor_list[lev].clear();
864
865 for (MyParIter pti(*this, lev); pti.isValid(); ++pti) {
866 PairIndex index(pti.index(), pti.LocalTileIndex());
867 m_neighbor_list[lev][index];
868 }
869
870#ifndef AMREX_USE_GPU
871 neighbor_list[lev].clear();
872 for (MyParIter pti(*this, lev); pti.isValid(); ++pti) {
873 PairIndex index(pti.index(), pti.LocalTileIndex());
874 neighbor_list[lev][index];
875 }
876#endif
877
878 auto& plev = this->GetParticles(lev);
879 const auto& geom = this->Geom(lev);
880
881#ifdef AMREX_USE_OMP
882#pragma omp parallel if (Gpu::notInLaunchRegion())
883#endif
884 for (MyParIter pti(*this, lev); pti.isValid(); ++pti)
885 {
886 int gid = pti.index();
887 int tid = pti.LocalTileIndex();
888 auto index = std::make_pair(gid, tid);
889 auto& ptile = plev[index];
890
891 if (ptile.numParticles() == 0) { continue; }
892
893 Box bx = pti.tilebox();
894 int ng = 1;
895
896 auto& soa = pti.GetStructOfArrays();
897 auto TypeVec = soa.GetIntData(type_ind);
898 int* bin_type_array = TypeVec.data();
899
900 Gpu::DeviceVector<int> off_bins_v(num_bin_types+1,0);
901 Gpu::DeviceVector<int> nbins_v(num_bin_types+1,0);
902 Gpu::DeviceVector<Dim3> lo_v(num_bin_types);
903 Gpu::DeviceVector<Dim3> hi_v(num_bin_types);
906
907 for (int type(0); type<num_bin_types; ++type) {
908 // Domain, RB, Coord, Per
909 Box dom = geom.Domain();
910 const Real* plo = geom.ProbLo();
911 const Real* phi = geom.ProbHi();
912 auto lcoord = geom.Coord();
913 Array<int,AMREX_SPACEDIM> lper = geom.isPeriodic();
914
915 // Refined tile box and domain
916 Box lbx( bx.smallEnd(), bx.bigEnd(), bx.ixType() );
917 Box ldom( dom.smallEnd(),dom.bigEnd(),dom.ixType() );
918 lbx.refine( ref_ratio[type] );
919 ldom.refine( ref_ratio[type] );
920
921 // Local copy of RB for refined geom
922 RealBox lrb(plo,phi);
923
924 // New geometry with refined domain
925 Geometry lgeom(ldom,lrb,lcoord,lper);
926
927 // Grow for ghost cells
928 int NGhost = ref_ratio[type]*m_num_neighbor_cells;
929 lbx.grow(NGhost);
930
931 // Store for memcpy
932 auto nbins = int(lbx.numPts());
933 Dim3 lo = lbound( lbx );
934 Dim3 hi = ubound( lbx );
935
936 auto dxInv = lgeom.InvCellSizeArray();
937 auto ploa = lgeom.ProbLoArray();
938
939 Gpu::htod_memcpy_async( dxi_v.data() + type, dxInv.data(), sizeof(dxInv) );
940 Gpu::htod_memcpy_async( plo_v.data() + type, ploa.data() , sizeof(ploa) );
941 Gpu::htod_memcpy_async( lo_v.data() + type, &lo , sizeof(lo) );
942 Gpu::htod_memcpy_async( hi_v.data() + type, &hi , sizeof(hi) );
943 Gpu::htod_memcpy_async( nbins_v.data() + type, &nbins , sizeof(nbins) );
944 }
945
946 Gpu::exclusive_scan(nbins_v.begin(), nbins_v.end(), off_bins_v.begin());
947
948 m_neighbor_list[lev][index].build(ptile,
949 check_pair,
950 off_bins_v, dxi_v, plo_v, lo_v, hi_v,
951 ng, num_bin_types, bin_type_array);
952
953#ifndef AMREX_USE_GPU
954 BL_PROFILE_VAR("CPU_CopyNeighborList()",CPUCNL);
955
956 const auto& counts = m_neighbor_list[lev][index].GetCounts();
957 const auto& list = m_neighbor_list[lev][index].GetList();
958
959 int li = 0;
960 for (int i = 0; i < ptile.numParticles(); ++i) {
961 auto cnt = counts[i];
962 neighbor_list[lev][index].push_back(cnt);
963 for (size_t j = 0; j < cnt; ++j) {
964 neighbor_list[lev][index].push_back(list[li++]+1);
965 }
966 }
967
968 BL_PROFILE_VAR_STOP(CPUCNL);
969#endif
970 } //ParIter
971 } //Lev
972}
973
974template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
975template <class CheckPair>
976void
978selectActualNeighbors (CheckPair const& check_pair, int num_cells)
979{
980 BL_PROFILE("NeighborParticleContainer::selectActualNeighbors");
981 const auto& geom_fine = this->Geom(0);
982 const auto& ba_fine = this->ParticleBoxArray(0);
983 if (ba_fine.size() == 1 && !geom_fine.isAnyPeriodic()) {
984 return;
985 }
986
987 for (int lev = 0; lev < this->numLevels(); ++lev)
988 {
989 // clear previous neighbor particle ids
990 if (!m_boundary_particle_ids.empty()) {
991 for (auto& keyval: m_boundary_particle_ids[lev]) {
992 keyval.second.clear();
993 }
994 }
995
996 for (MyParIter pti(*this, lev); pti.isValid(); ++pti) {
997 PairIndex index(pti.index(), pti.LocalTileIndex());
998
999 // id of actual particles that need to be sent
1000 m_boundary_particle_ids[lev][index];
1001 m_boundary_particle_ids[lev][index].resize(pti.numNeighborParticles());
1002 auto* p_boundary_particle_ids = m_boundary_particle_ids[lev][index].dataPtr();
1003
1004 const auto& aos = pti.GetArrayOfStructs();
1005 const auto* pstruct = aos().dataPtr();
1006 const auto ptile_data = this->ParticlesAt(lev, pti).getConstParticleTileData();
1007
1008 Box box = pti.validbox();
1009 Box grownBox = pti.tilebox();
1010 grownBox.grow(computeRefFac(0, lev).max()*m_num_neighbor_cells);
1011 const auto lo = lbound(grownBox);
1012 const auto hi = ubound(grownBox);
1013
1014 const auto& geom = this->Geom(lev);
1015 const auto domain = geom.Domain();
1016 const auto dxi = geom.InvCellSizeArray();
1017 const auto plo = geom.ProbLoArray();
1018
1019 const size_t np_real = pti.numRealParticles();
1020 const size_t np_total = aos().size();
1021
1023 bins.build(np_total, pstruct, grownBox,
1024 [=] AMREX_GPU_DEVICE (const ParticleType& p) noexcept -> IntVect
1025 {
1026 AMREX_D_TERM(int i = static_cast<int>(amrex::Math::floor((p.pos(0)-plo[0])*dxi[0]) - lo.x);,
1027 int j = static_cast<int>(amrex::Math::floor((p.pos(1)-plo[1])*dxi[1]) - lo.y);,
1028 int k = static_cast<int>(amrex::Math::floor((p.pos(2)-plo[2])*dxi[2]) - lo.z));
1029 AMREX_D_TERM(AMREX_ASSERT(i >= 0);, AMREX_ASSERT(j >= 0);, AMREX_ASSERT(k >= 0));
1030
1031 return IntVect(AMREX_D_DECL(i, j, k));
1032 });
1033
1034 auto pperm = bins.permutationPtr();
1035 auto poffset = bins.offsetsPtr();
1036
1037 Gpu::Buffer<unsigned int> np_boundary({0});
1038 unsigned int* p_np_boundary = np_boundary.data();
1039
1040 AMREX_FOR_1D ( np_real, i,
1041 {
1043 static_cast<int>(amrex::Math::floor((pstruct[i].pos(0)-plo[0])*dxi[0])) - lo.x,
1044 static_cast<int>(amrex::Math::floor((pstruct[i].pos(1)-plo[1])*dxi[1])) - lo.y,
1045 static_cast<int>(amrex::Math::floor((pstruct[i].pos(2)-plo[2])*dxi[2])) - lo.z));
1046 auto iv3 = iv.dim3();
1047
1048 int ix = iv3.x;
1049 int iy = iv3.y;
1050 int iz = iv3.z;
1051
1052 int nx = hi.x-lo.x+1;
1053 int ny = hi.y-lo.y+1;
1054 int nz = hi.z-lo.z+1;
1055
1056 bool isActualNeighbor = false;
1057 for (int ii = amrex::max(ix-num_cells, 0); ii <= amrex::min(ix+num_cells, nx-1); ++ii) {
1058 for (int jj = amrex::max(iy-num_cells, 0); jj <= amrex::min(iy+num_cells, ny-1); ++jj) {
1059 for (int kk = amrex::max(iz-num_cells, 0); kk <= amrex::min(iz+num_cells, nz-1); ++kk) {
1060 if (isActualNeighbor) { break; }
1061 int nbr_cell_id = (ii * ny + jj) * nz + kk;
1062 for (auto p = poffset[nbr_cell_id]; p < poffset[nbr_cell_id+1]; ++p) {
1063 if (pperm[p] == int(i)) { continue; }
1064 if (detail::call_check_pair(check_pair, ptile_data, ptile_data, i, pperm[p])) {
1065 IntVect cell_ijk = getParticleCell(pstruct[pperm[p]], plo, dxi, domain);
1066 if (!box.contains(cell_ijk)) {
1067 unsigned int loc = Gpu::Atomic::Add(p_np_boundary, 1U);
1068 p_boundary_particle_ids[loc] = i;
1069 isActualNeighbor = true;
1070 break;
1071 }
1072 }// end if check_pair
1073 }
1074 }
1075 }
1076 }
1077 });// end amrex_for_1d
1078
1079 unsigned int* p_np_boundary_h = np_boundary.copyToHost();
1080 m_boundary_particle_ids[lev][index].resize(*p_np_boundary_h);
1081
1082 }// end mypariter
1083 }// end lev
1084}
1085template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
1086void
1089{
1090 BL_PROFILE("NeighborParticleContainer::printNeighborList");
1091
1092 for (int lev = 0; lev < this->numLevels(); ++lev)
1093 {
1094 for(MFIter mfi = this->MakeMFIter(lev); mfi.isValid(); ++mfi)
1095 {
1096 int gid = mfi.index();
1097 int tid = mfi.LocalTileIndex();
1098 auto index = std::make_pair(gid, tid);
1099 m_neighbor_list[lev][index].print();
1100 }
1101 }
1102}
1103
1104template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
1105void
1107resizeContainers (int num_levels)
1108{
1109 this->reserveData();
1110 this->resizeData();
1111 if ( static_cast<int>(neighbors.size()) <= num_levels )
1112 {
1113 neighbors.resize(num_levels);
1114 m_neighbor_list.resize(num_levels);
1115 neighbor_list.resize(num_levels);
1116 mask_ptr.resize(num_levels);
1117 buffer_tag_cache.resize(num_levels);
1118 local_neighbor_sizes.resize(num_levels);
1119 if ( enableInverse() ) { inverse_tags.resize(num_levels); }
1120 }
1121
1122 AMREX_ASSERT((neighbors.size() == m_neighbor_list.size()) &&
1123 (neighbors.size() == mask_ptr.size() ) );
1124}
1125
1126}
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:551
#define BL_PROFILE_VAR_STOP(vname)
Definition AMReX_BLProfiler.H:563
#define BL_PROFILE_VAR(fname, vname)
Definition AMReX_BLProfiler.H:560
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#define AMREX_FOR_1D(...)
Definition AMReX_GpuLaunchMacrosC.nolint.H:97
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
Array4< int const > mask
Definition AMReX_InterpFaceRegister.cpp:93
#define AMREX_D_TERM(a, b, c)
Definition AMReX_SPACE.H:172
#define AMREX_D_DECL(a, b, c)
Definition AMReX_SPACE.H:171
A FortranArrayBox(FAB)-like object.
Definition AMReX_BaseFab.H:183
A collection of Boxes stored in an Array.
Definition AMReX_BoxArray.H:551
std::vector< std::pair< int, Box > > intersections(const Box &bx) const
Return intersections of Box and BoxArray.
Definition AMReX_BoxArray.cpp:1179
static bool SameRefs(const BoxArray &lhs, const BoxArray &rhs)
whether two BoxArrays share the same data
Definition AMReX_BoxArray.H:824
__host__ __device__ BoxND & grow(int i) noexcept
Definition AMReX_Box.H:630
__host__ __device__ const IntVectND< dim > & bigEnd() const &noexcept
Get the bigend.
Definition AMReX_Box.H:119
__host__ __device__ Long numPts() const noexcept
Returns the number of points contained in the BoxND.
Definition AMReX_Box.H:349
__host__ __device__ bool contains(const IntVectND< dim > &p) const noexcept
Returns true if argument is contained within BoxND.
Definition AMReX_Box.H:207
__host__ __device__ IndexTypeND< dim > ixType() const noexcept
Returns the indexing type.
Definition AMReX_Box.H:130
__host__ __device__ BoxND & coarsen(int ref_ratio) noexcept
Coarsen BoxND by given (positive) refinement ratio. NOTE: if type(dir) = CELL centered: lo <- lo/rati...
Definition AMReX_Box.H:711
__host__ __device__ BoxND & refine(int ref_ratio) noexcept
Refine BoxND by given (positive) refinement ratio. NOTE: if type(dir) = CELL centered: lo <- lo*ratio...
Definition AMReX_Box.H:687
__host__ __device__ Long index(const IntVectND< dim > &v) const noexcept
Returns offset of point from smallend; i.e. index(smallend) -> 0, bigend would return numPts()-1....
Definition AMReX_Box.H:1011
__host__ __device__ void next(IntVectND< dim > &) const noexcept
Step through the rectangle. It is a runtime error to give a point not inside rectangle....
Definition AMReX_Box.H:1077
__host__ __device__ const IntVectND< dim > & smallEnd() const &noexcept
Get the smallend of the BoxND.
Definition AMReX_Box.H:108
GpuArray< Real, 3 > InvCellSizeArray() const noexcept
Definition AMReX_CoordSys.H:87
A container for storing items in a set of bins.
Definition AMReX_DenseBins.H:77
index_type * offsetsPtr() noexcept
returns the pointer to the offsets array
Definition AMReX_DenseBins.H:512
index_type * permutationPtr() noexcept
returns the pointer to the permutation array
Definition AMReX_DenseBins.H:509
void build(N nitems, const_pointer_input_type v, const Box &bx, F &&f)
Populate the bins with a set of items.
Definition AMReX_DenseBins.H:130
Calculates the distribution of FABs to MPI processes.
Definition AMReX_DistributionMapping.H:41
static bool SameRefs(const DistributionMapping &lhs, const DistributionMapping &rhs)
Definition AMReX_DistributionMapping.H:187
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:73
Periodicity periodicity() const noexcept
Definition AMReX_Geometry.H:355
GpuArray< Real, 3 > ProbLoArray() const noexcept
Definition AMReX_Geometry.H:186
Definition AMReX_GpuBuffer.H:18
T const * data() const noexcept
Definition AMReX_GpuBuffer.H:45
__host__ __device__ Dim3 dim3() const noexcept
Definition AMReX_IntVect.H:170
__host__ __device__ int max() const noexcept
maximum (no absolute values) value
Definition AMReX_IntVect.H:219
__host__ static __device__ constexpr IntVectND< dim > TheZeroVector() noexcept
This static member function returns a reference to a constant IntVectND object, all of whose dim argu...
Definition AMReX_IntVect.H:677
Definition AMReX_MFIter.H:57
Box tilebox() const noexcept
Return the tile Box at the current index.
Definition AMReX_MFIter.cpp:386
bool isValid() const noexcept
Is the iterator valid i.e. is it associated with a FAB?
Definition AMReX_MFIter.H:141
Definition AMReX_NeighborList.H:247
Definition AMReX_NeighborParticles.H:35
std::pair< int, int > PairIndex
Definition AMReX_NeighborParticles.H:196
void selectActualNeighbors(CheckPair const &check_pair, int num_cells=1)
Definition AMReX_NeighborParticlesI.H:978
void getNeighborTags(Vector< NeighborCopyTag > &tags, const ParticleType &p, int nGrow, const NeighborCopyTag &src_tag, const MyParIter &pti)
Definition AMReX_NeighborParticlesI.H:538
void printNeighborList()
Definition AMReX_NeighborParticlesI.H:1088
static bool enable_inverse
Definition AMReX_NeighborParticles.H:428
void initializeCommComps()
Definition AMReX_NeighborParticlesI.H:47
void resizeContainers(int num_levels)
Definition AMReX_NeighborParticlesI.H:1107
static bool use_mask
Definition AMReX_NeighborParticles.H:426
void buildNeighborList(CheckPair const &check_pair, bool sort=false)
Definition AMReX_NeighborParticlesI.H:696
typename ParticleContainerType::ParticleType ParticleType
Definition AMReX_NeighborParticles.H:38
Definition AMReX_PODVector.H:297
iterator begin() noexcept
Definition AMReX_PODVector.H:663
iterator end() noexcept
Definition AMReX_PODVector.H:667
T * data() noexcept
Definition AMReX_PODVector.H:655
void push_back(const T &a_value)
Definition AMReX_PODVector.H:618
Definition AMReX_ParGDB.H:13
Definition AMReX_ParIter.H:115
A distributed container for Particles sorted onto the levels, grids, and tiles of a block-structured ...
Definition AMReX_ParticleContainer.H:147
This provides length of period for periodic domains. 0 means it is not periodic in that direction....
Definition AMReX_Periodicity.H:17
std::vector< IntVect > shiftIntVect(IntVect const &nghost=IntVect(0)) const
Definition AMReX_Periodicity.cpp:8
bool isAnyPeriodic() const noexcept
Definition AMReX_Periodicity.H:22
bool isPeriodic(int dir) const noexcept
Definition AMReX_Periodicity.H:26
A Box with real dimensions. A RealBox is OK iff volume >= 0.
Definition AMReX_RealBox.H:21
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:28
Long size() const noexcept
Definition AMReX_Vector.H:53
__host__ __device__ AMREX_FORCE_INLINE T Add(T *sum, T value) noexcept
Definition AMReX_GpuAtomic.H:198
OutIter exclusive_scan(InIter begin, InIter end, OutIter result)
Definition AMReX_Scan.H:1415
void htod_memcpy_async(void *p_d, const void *p_h, const std::size_t sz) noexcept
Definition AMReX_GpuDevice.H:289
constexpr int get_thread_num()
Definition AMReX_OpenMP.H:37
constexpr int get_max_threads()
Definition AMReX_OpenMP.H:36
int MyProcSub() noexcept
my sub-rank in current frame
Definition AMReX_ParallelContext.H:76
int global_to_local_rank(int rank) noexcept
Definition AMReX_ParallelContext.H:98
__host__ __device__ auto call_check_pair(F const &check_pair, const SrcData &src_tile, const DstData &dst_tile, N1 i, N2 j) noexcept -> decltype(check_pair(src_tile.m_aos[i], dst_tile.m_aos[j]))
Definition AMReX_NeighborList.H:19
Definition AMReX_Amr.cpp:49
__host__ __device__ Dim3 ubound(Array4< T > const &a) noexcept
Definition AMReX_Array4.H:319
__host__ __device__ void ignore_unused(const Ts &...)
This shuts up the compiler about unused variables.
Definition AMReX.H:138
__host__ __device__ int getTileIndex(const IntVect &iv, const Box &box, const bool a_do_tiling, const IntVect &a_tile_size, Box &tbx)
Definition AMReX_ParticleUtil.H:184
DistributionMapping const & DistributionMap(FabArrayBase const &fa)
Definition AMReX_FabArrayBase.cpp:2867
void EnsureThreadSafeTiles(PC &pc)
Definition AMReX_ParticleUtil.H:734
BoxND< 3 > Box
Definition AMReX_BaseFwd.H:27
__host__ __device__ constexpr const T & min(const T &a, const T &b) noexcept
Definition AMReX_Algorithm.H:21
__host__ __device__ Dim3 begin(BoxND< dim > const &box) noexcept
Definition AMReX_Box.H:1899
__host__ __device__ BoxND< dim > shift(const BoxND< dim > &b, int dir, int nzones) noexcept
Return a BoxND with indices shifted by nzones in dir direction.
Definition AMReX_Box.H:1390
IntVectND< 3 > IntVect
Definition AMReX_BaseFwd.H:30
__host__ __device__ constexpr const T & max(const T &a, const T &b) noexcept
Definition AMReX_Algorithm.H:35
__host__ __device__ BoxND< dim > grow(const BoxND< dim > &b, int i) noexcept
Grow BoxND in all directions by given amount.
Definition AMReX_Box.H:1229
bool SameIteratorsOK(const PC1 &pc1, const PC2 &pc2)
Definition AMReX_ParticleUtil.H:722
int numParticlesOutOfRange(Iterator const &pti, int nGrow)
Returns the number of particles that are more than nGrow cells from the box correspond to the input i...
Definition AMReX_ParticleUtil.H:34
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition AMReX.cpp:230
IntVect computeRefFac(const ParGDBBase *a_gdb, int src_lev, int lev)
Definition AMReX_ParticleUtil.cpp:6
void RemoveDuplicates(Vector< T > &vec)
Definition AMReX_Vector.H:211
__host__ __device__ Dim3 end(BoxND< dim > const &box) noexcept
Definition AMReX_Box.H:1908
__host__ __device__ IntVect getParticleCell(P const &p, amrex::GpuArray< amrex::Real, 3 > const &plo, amrex::GpuArray< amrex::Real, 3 > const &dxi) noexcept
Returns the cell index for a given particle using the provided lower bounds and cell sizes.
Definition AMReX_ParticleUtil.H:336
BoxArray const & boxArray(FabArrayBase const &fa)
Definition AMReX_FabArrayBase.cpp:2862
__host__ __device__ Dim3 lbound(Array4< T > const &a) noexcept
Definition AMReX_Array4.H:312
std::array< T, N > Array
Definition AMReX_Array.H:24
Definition AMReX_Dim3.H:12
Definition AMReX_NeighborParticles.H:152
int tile_id
Definition AMReX_NeighborParticles.H:161
int grid_id
Definition AMReX_NeighborParticles.H:160
Definition AMReX_NeighborParticles.H:82
int src_index
Definition AMReX_NeighborParticles.H:86
int tile
Definition AMReX_NeighborParticles.H:85
int grid
Definition AMReX_NeighborParticles.H:84
int level
Definition AMReX_NeighborParticles.H:83
IntVect periodic_shift
Definition AMReX_NeighborParticles.H:88
Definition AMReX_NeighborParticles.H:51
int thread_num
Definition AMReX_NeighborParticles.H:60
int src_level
Definition AMReX_NeighborParticles.H:56
int src_index
Definition AMReX_NeighborParticles.H:59
int src_grid
Definition AMReX_NeighborParticles.H:57
int dst_level
Definition AMReX_NeighborParticles.H:52
int src_tile
Definition AMReX_NeighborParticles.H:58