Block-Structured AMR Software Framework
Loading...
Searching...
No Matches
AMReX_ParticleTile.H
Go to the documentation of this file.
1#ifndef AMREX_PARTICLETILE_H_
2#define AMREX_PARTICLETILE_H_
3#include <AMReX_Config.H>
4
5#include <AMReX_Extension.H>
6#include <AMReX_Particle.H>
9#include <AMReX_Vector.H>
10#include <AMReX_REAL.H>
11#include <AMReX_RealVect.H>
12
13#include <array>
14#include <string>
15#include <type_traits>
16#include <vector>
17
18
19namespace amrex {
20
21// Forward Declaration
22template <int NArrayReal, int NArrayInt>
23struct ConstSoAParticle;
24template <int NArrayReal, int NArrayInt>
25struct SoAParticle;
26
27template <typename T_ParticleType, int NArrayReal, int NArrayInt>
28struct ConstParticleTileData;
29
31template <typename T_ParticleType, int NArrayReal, int NArrayInt>
33{
34 static constexpr int NAR = NArrayReal;
35 static constexpr int NAI = NArrayInt;
36
37 using ParticleType = T_ParticleType;
38 using ParticleRefType = T_ParticleType&;
41 using IntType = int;
42
43 static constexpr int NStructReal = ParticleType::NReal;
44 static constexpr int NStructInt = ParticleType::NInt;
45
47
48 static constexpr bool is_particle_tile_data = true;
49
51
52 using AOS_PTR = std::conditional_t<T_ParticleType::is_soa_particle,
55
56 uint64_t* m_idcpu;
59
64
66 decltype(auto) pos (const int dir, const int index) const &
67 {
68 if constexpr(!ParticleType::is_soa_particle) {
69 return this->m_aos[index].pos(dir);
70 } else {
71 return this->m_rdata[dir][index];
72 }
73 }
74
76 decltype(auto) id (const int index) const &
77 {
78 if constexpr(!ParticleType::is_soa_particle) {
79 return this->m_aos[index].id();
80 } else {
81 return ParticleIDWrapper(this->m_idcpu[index]);
82 }
83 }
84
86 decltype(auto) cpu (const int index) const &
87 {
88 if constexpr(!ParticleType::is_soa_particle) {
89 return this->m_aos[index].cpu();
90 } else {
91 return ParticleCPUWrapper(this->m_idcpu[index]);
92 }
93 }
94
96 decltype(auto) idcpu (const int index) const &
97 {
98 if constexpr(ParticleType::is_soa_particle) {
99 return this->m_idcpu[index];
100 } else {
101 return this->m_aos[index].idcpu();
102 }
103 }
104
106 ParticleReal * rdata (const int attribute_index) const
107 {
108 return this->m_rdata[attribute_index];
109 }
110
112 int * idata (const int attribute_index) const
113 {
114 return this->m_idata[attribute_index];
115 }
116
118 decltype(auto) operator[] (const int index) const
119 {
120 if constexpr (!ParticleType::is_soa_particle) {
121 return m_aos[index];
122 } else {
123 return SoAParticle<NAR, NAI>(*this, index);
124 }
125 }
126
128 void packParticleData (char* buffer, int src_index, std::size_t dst_offset,
129 const int* comm_real, const int * comm_int) const noexcept
130 {
131 AMREX_ASSERT(src_index < m_size);
132 auto* dst = buffer + dst_offset;
133 if constexpr (!ParticleType::is_soa_particle) {
134 memcpy(dst, m_aos + src_index, sizeof(ParticleType));
135 dst += sizeof(ParticleType);
136 } else {
137 memcpy(dst, m_idcpu + src_index, sizeof(uint64_t));
138 dst += sizeof(uint64_t);
139 }
140 int array_start_index = 0;
141 if constexpr (!ParticleType::is_soa_particle) {
142 array_start_index = AMREX_SPACEDIM + NStructReal;
143 }
144 for (int i = 0; i < NAR; ++i)
145 {
146 if (comm_real[array_start_index + i])
147 {
148 memcpy(dst, m_rdata[i] + src_index, sizeof(ParticleReal));
149 dst += sizeof(ParticleReal);
150 }
151 }
152 int runtime_start_index = array_start_index + NAR;
153 for (int i = 0; i < m_num_runtime_real; ++i)
154 {
155 if (comm_real[runtime_start_index + i])
156 {
157 memcpy(dst, m_runtime_rdata[i] + src_index, sizeof(ParticleReal));
158 dst += sizeof(ParticleReal);
159 }
160 }
161 array_start_index = 2 + NStructInt;
162 for (int i = 0; i < NAI; ++i)
163 {
164 if (comm_int[array_start_index + i])
165 {
166 memcpy(dst, m_idata[i] + src_index, sizeof(int));
167 dst += sizeof(int);
168 }
169 }
170 runtime_start_index = 2 + NStructInt + NAI;
171 for (int i = 0; i < m_num_runtime_int; ++i)
172 {
173 if (comm_int[runtime_start_index + i])
174 {
175 memcpy(dst, m_runtime_idata[i] + src_index, sizeof(int));
176 dst += sizeof(int);
177 }
178 }
179 }
180
182 void unpackParticleData (const char* buffer, Long src_offset, int dst_index,
183 const int* comm_real, const int* comm_int) const noexcept
184 {
185 AMREX_ASSERT(dst_index < m_size);
186 const auto* src = buffer + src_offset;
187 if constexpr (!ParticleType::is_soa_particle) {
188 memcpy(m_aos + dst_index, src, sizeof(ParticleType));
189 src += sizeof(ParticleType);
190 } else {
191 memcpy(m_idcpu + dst_index, src, sizeof(uint64_t));
192 src += sizeof(uint64_t);
193 }
194 int array_start_index = 0;
195 if constexpr (!ParticleType::is_soa_particle) {
196 array_start_index = AMREX_SPACEDIM + NStructReal;
197 }
198 if constexpr (NAR > 0) {
199 for (int i = 0; i < NAR; ++i)
200 {
201 if (comm_real[array_start_index + i])
202 {
203 memcpy(m_rdata[i] + dst_index, src, sizeof(ParticleReal));
204 src += sizeof(ParticleReal);
205 }
206 }
207 }
208 int runtime_start_index = array_start_index + NAR;
209 for (int i = 0; i < m_num_runtime_real; ++i)
210 {
211 if (comm_real[runtime_start_index + i])
212 {
213 memcpy(m_runtime_rdata[i] + dst_index, src, sizeof(ParticleReal));
214 src += sizeof(ParticleReal);
215 }
216 }
217 array_start_index = 2 + NStructInt;
218 if constexpr (NAI > 0) {
219 for (int i = 0; i < NAI; ++i)
220 {
221 if (comm_int[array_start_index + i])
222 {
223 memcpy(m_idata[i] + dst_index, src, sizeof(int));
224 src += sizeof(int);
225 }
226 }
227 }
228 runtime_start_index = 2 + NStructInt + NAI;
229 for (int i = 0; i < m_num_runtime_int; ++i)
230 {
231 if (comm_int[runtime_start_index + i])
232 {
233 memcpy(m_runtime_idata[i] + dst_index, src, sizeof(int));
234 src += sizeof(int);
235 }
236 }
237 }
238
239 template <typename T = ParticleType, std::enable_if_t<!T::is_soa_particle, int> = 0>
241 SuperParticleType getSuperParticle (int index) const noexcept
242 {
243 AMREX_ASSERT(index < m_size);
245 for (int i = 0; i < AMREX_SPACEDIM; ++i) {
246 sp.pos(i) = m_aos[index].pos(i);
247 }
248 for (int i = 0; i < NStructReal; ++i) {
249 sp.rdata(i) = m_aos[index].rdata(i);
250 }
251 if constexpr (NAR >0) {
252 for (int i = 0; i < NAR; ++i) {
253 sp.rdata(NStructReal+i) = m_rdata[i][index];
254 }
255 }
256 sp.id() = m_aos[index].id();
257 sp.cpu() = m_aos[index].cpu();
258 for (int i = 0; i < NStructInt; ++i) {
259 sp.idata(i) = m_aos[index].idata(i);
260 }
261 if constexpr (NAI > 0) {
262 for (int i = 0; i < NAI; ++i) {
263 sp.idata(NStructInt+i) = m_idata[i][index];
264 }
265 }
266 return sp;
267 }
268
269 template <typename T = ParticleType, std::enable_if_t<T::is_soa_particle, int> = 0>
271 SuperParticleType getSuperParticle (int index) const noexcept
272 {
273 AMREX_ASSERT(index < m_size);
275 sp.m_idcpu = m_idcpu[index];
276 for (int i = 0; i < AMREX_SPACEDIM; ++i) {sp.pos(i) = m_rdata[i][index];}
277 for (int i = 0; i < NAR; ++i) {
278 sp.rdata(i) = m_rdata[i][index];
279 }
280 for (int i = 0; i < NAI; ++i) {
281 sp.idata(i) = m_idata[i][index];
282 }
283 return sp;
284 }
285
286 template <typename T = ParticleType, std::enable_if_t<!T::is_soa_particle, int> = 0>
288 void setSuperParticle (const SuperParticleType& sp, int index) const noexcept
289 {
290 for (int i = 0; i < AMREX_SPACEDIM; ++i) {
291 m_aos[index].pos(i) = sp.pos(i);
292 }
293 for (int i = 0; i < NStructReal; ++i) {
294 m_aos[index].rdata(i) = sp.rdata(i);
295 }
296 for (int i = 0; i < NAR; ++i) {
297 m_rdata[i][index] = sp.rdata(NStructReal+i);
298 }
299 m_aos[index].id() = sp.id();
300 m_aos[index].cpu() = sp.cpu();
301 for (int i = 0; i < NStructInt; ++i) {
302 m_aos[index].idata(i) = sp.idata(i);
303 }
304 for (int i = 0; i < NAI; ++i) {
305 m_idata[i][index] = sp.idata(NStructInt+i);
306 }
307 }
308
309 template <typename T = ParticleType, std::enable_if_t<T::is_soa_particle, int> = 0>
311 void setSuperParticle (const SuperParticleType& sp, int index) const noexcept
312 {
313 m_idcpu[index] = sp.m_idcpu;
314 for (int i = 0; i < NAR; ++i) {
315 m_rdata[i][index] = sp.rdata(i);
316 }
317 for (int i = 0; i < NAI; ++i) {
318 m_idata[i][index] = sp.idata(i);
319 }
320 }
321};
322
323// SOA Particle Structure
324template <int T_NArrayReal, int T_NArrayInt>
325struct alignas(sizeof(double)) ConstSoAParticle : SoAParticleBase
326{
327 static constexpr int NArrayReal = T_NArrayReal;
328 static constexpr int NArrayInt = T_NArrayInt;
331 static constexpr bool is_soa_particle = true;
332 static constexpr bool is_rtsoa_particle = false;
333 static constexpr bool is_constsoa_particle = true;
334
336 using IntType = int;
337
339 ConstSoAParticle (ConstPTD const& ptd, long i) : // Note: should this be int instead?
340 m_constparticle_tile_data(ptd), m_index(int(i))
341 {
342 }
343
344 //static Long the_next_id;
345
346 //functions to get id and cpu in the SOA data
347
349 ConstParticleCPUWrapper cpu () const { return this->m_constparticle_tile_data.m_idcpu[m_index]; }
350
352 ConstParticleIDWrapper id () const { return this->m_constparticle_tile_data.m_idcpu[m_index]; }
353
354 //functions to get positions of the particle in the SOA data
355
357 RealVect pos () const & {return RealVect(AMREX_D_DECL(this->m_constparticle_tile_data.m_rdata[0][m_index], this->m_constparticle_tile_data.m_rdata[1][m_index], this->m_constparticle_tile_data.m_rdata[2][m_index]));}
358
360 const RealType& pos (int position_index) const &
361 {
362 AMREX_ASSERT(position_index < AMREX_SPACEDIM);
363 return this->m_constparticle_tile_data.m_rdata[position_index][m_index];
364 }
365
366 static Long NextID ();
367
372
378 static void NextID (Long nextid);
379
380 private :
381
382 static_assert(std::is_trivially_copyable<ConstPTD>(), "ParticleTileData is not trivially copyable");
383
384 ConstPTD m_constparticle_tile_data;
385 int m_index;
386};
387
388template <int T_NArrayReal, int T_NArrayInt>
389struct alignas(sizeof(double)) SoAParticle : SoAParticleBase
390{
391 static constexpr int NArrayReal = T_NArrayReal;
392 static constexpr int NArrayInt = T_NArrayInt;
395 static constexpr bool is_soa_particle = true;
396 static constexpr bool is_rtsoa_particle = false;
397 static constexpr bool is_constsoa_particle = false;
398
401 using IntType = int;
402
404 SoAParticle (PTD const& ptd, long i) : // Note: should this be int instead?
405 m_particle_tile_data(ptd), m_index(int(i))
406 {
407 }
408
410
411 //functions to get id and cpu in the SOA data
412
414 ParticleCPUWrapper cpu () & { return this->m_particle_tile_data.m_idcpu[m_index]; }
415
417 ParticleIDWrapper<> id () & { return this->m_particle_tile_data.m_idcpu[m_index]; }
418
420 uint64_t& idcpu () & { return this->m_particle_tile_data.m_idcpu[m_index]; }
421
423 ConstParticleCPUWrapper cpu () const & { return this->m_particle_tile_data.m_idcpu[m_index]; }
424
426 ConstParticleIDWrapper id () const & { return this->m_particle_tile_data.m_idcpu[m_index]; }
427
429 const uint64_t& idcpu () const & { return this->m_particle_tile_data.m_idcpu[m_index]; }
430
431 //functions to get positions of the particle in the SOA data
432
434 RealVect pos () const & {return RealVect(AMREX_D_DECL(this->m_particle_tile_data.m_rdata[0][m_index], this->m_particle_tile_data.m_rdata[1][m_index], this->m_particle_tile_data.m_rdata[2][m_index]));}
435
437 RealType& pos (int position_index) &
438 {
439 AMREX_ASSERT(position_index < AMREX_SPACEDIM);
440 return this->m_particle_tile_data.m_rdata[position_index][m_index];
441 }
442
444 RealType pos (int position_index) const &
445 {
446 AMREX_ASSERT(position_index < AMREX_SPACEDIM);
447 return this->m_particle_tile_data.m_rdata[position_index][m_index];
448 }
449
450 static Long NextID ();
451
455 static Long UnprotectedNextID ();
456
462 static void NextID (Long nextid);
463
464private :
465
466 static_assert(std::is_trivially_copyable<PTD>(), "ParticleTileData is not trivially copyable");
467
468 PTD m_particle_tile_data;
469 int m_index;
470};
471
472//template <int NArrayReal, int NArrayInt> Long ConstSoAParticle<NArrayReal, NArrayInt>::the_next_id = 1;
473template <int NArrayReal, int NArrayInt> Long SoAParticle<NArrayReal, NArrayInt>::the_next_id = 1;
474
475template <int NArrayReal, int NArrayInt>
476Long
478{
479 Long next;
480// we should be able to test on _OPENMP < 201107 for capture (version 3.1)
481// but we must work around a bug in gcc < 4.9
482#if defined(AMREX_USE_OMP) && defined(_OPENMP) && _OPENMP < 201307
483#pragma omp critical (amrex_particle_nextid)
484#elif defined(AMREX_USE_OMP)
485#pragma omp atomic capture
486#endif
487 next = the_next_id++;
488
490 amrex::Abort("SoAParticle<NArrayReal, NArrayInt>::NextID() -- too many particles");
491 }
492
493 return next;
494}
495
496template <int NArrayReal, int NArrayInt>
497Long
499{
500 Long next = the_next_id++;
502 amrex::Abort("SoAParticle<NArrayReal, NArrayInt>::NextID() -- too many particles");
503 }
504 return next;
505}
506
507template <int NArrayReal, int NArrayInt>
508void
510{
511 the_next_id = nextid;
512}
513
514template <typename T_ParticleType, int NArrayReal, int NArrayInt>
516{
517 static constexpr int NAR = NArrayReal;
518 static constexpr int NAI = NArrayInt;
519 using ParticleType = T_ParticleType;
520 using ParticleRefType = T_ParticleType const&;
522 using IntType = int;
523
524 static constexpr int NStructReal = ParticleType::NReal;
525 static constexpr int NStructInt = ParticleType::NInt;
526
528
529 static constexpr bool is_particle_tile_data = true;
530
532
533 using AOS_PTR = std::conditional_t<T_ParticleType::is_soa_particle,
534 void const * AMREX_RESTRICT, ParticleType const * AMREX_RESTRICT>;
536
537 const uint64_t* m_idcpu;
540
542 decltype(auto) pos (const int dir, const int index) const &
543 {
544 if constexpr(!ParticleType::is_soa_particle) {
545 return this->m_aos[index].pos(dir);
546 } else {
547 return this->m_rdata[dir][index];
548 }
549 }
550
552 decltype(auto) id (const int index) const &
553 {
554 if constexpr(!ParticleType::is_soa_particle) {
555 return this->m_aos[index].id();
556 } else {
557 return ConstParticleIDWrapper(this->m_idcpu[index]);
558 }
559 }
560
562 decltype(auto) cpu (const int index) const &
563 {
564 if constexpr(!ParticleType::is_soa_particle) {
565 return this->m_aos[index].cpu();
566 } else {
567 return ConstParticleCPUWrapper(this->m_idcpu[index]);
568 }
569 }
570
572 decltype(auto) idcpu (const int index) const &
573 {
574 if constexpr(ParticleType::is_soa_particle) {
575 return this->m_idcpu[index];
576 } else {
577 return this->m_aos[index].idcpu();
578 }
579 }
580
582 const ParticleReal * rdata (const int attribute_index) const
583 {
584 return this->m_rdata[attribute_index];
585 }
586
588 const int * idata (const int attribute_index) const
589 {
590 return this->m_idata[attribute_index];
591 }
592
594 decltype(auto) operator[] (const int index) const
595 {
596 if constexpr (!ParticleType::is_soa_particle) {
597 return m_aos[index];
598 } else {
599 return ConstSoAParticle<NAR, NAI>(*this, index);
600 }
601 }
602
607
609 void packParticleData(char* buffer, int src_index, Long dst_offset,
610 const int* comm_real, const int * comm_int) const noexcept
611 {
612 AMREX_ASSERT(src_index < m_size);
613 auto* dst = buffer + dst_offset;
614 if constexpr (!ParticleType::is_soa_particle) {
615 memcpy(dst, m_aos + src_index, sizeof(ParticleType));
616 dst += sizeof(ParticleType);
617 } else {
618 memcpy(dst, m_idcpu + src_index, sizeof(uint64_t));
619 dst += sizeof(uint64_t);
620 }
621 int array_start_index = 0;
622 if constexpr (!ParticleType::is_soa_particle) {
623 array_start_index = AMREX_SPACEDIM + NStructReal;
624 }
625 if constexpr (NArrayReal > 0) {
626 for (int i = 0; i < NArrayReal; ++i)
627 {
628 if (comm_real[array_start_index + i])
629 {
630 memcpy(dst, m_rdata[i] + src_index, sizeof(ParticleReal));
631 dst += sizeof(ParticleReal);
632 }
633 }
634 }
635 int runtime_start_index = array_start_index + NArrayReal;
636 for (int i = 0; i < m_num_runtime_real; ++i)
637 {
638 if (comm_real[runtime_start_index + i])
639 {
640 memcpy(dst, m_runtime_rdata[i] + src_index, sizeof(ParticleReal));
641 dst += sizeof(ParticleReal);
642 }
643 }
644 array_start_index = 2 + NStructInt;
645 if constexpr (NArrayInt > 0) {
646 for (int i = 0; i < NArrayInt; ++i)
647 {
648 if (comm_int[array_start_index + i])
649 {
650 memcpy(dst, m_idata[i] + src_index, sizeof(int));
651 dst += sizeof(int);
652 }
653 }
654 }
655 runtime_start_index = 2 + NStructInt + NArrayInt;
656 for (int i = 0; i < m_num_runtime_int; ++i)
657 {
658 if (comm_int[runtime_start_index + i])
659 {
660 memcpy(dst, m_runtime_idata[i] + src_index, sizeof(int));
661 dst += sizeof(int);
662 }
663 }
664 }
665
666 template <typename T = ParticleType, std::enable_if_t<!T::is_soa_particle, int> = 0>
668 SuperParticleType getSuperParticle (int index) const noexcept
669 {
670 AMREX_ASSERT(index < m_size);
672 for (int i = 0; i < AMREX_SPACEDIM; ++i) {
673 sp.pos(i) = m_aos[index].pos(i);
674 }
675 for (int i = 0; i < NStructReal; ++i) {
676 sp.rdata(i) = m_aos[index].rdata(i);
677 }
678 if constexpr(NArrayReal > 0) {
679 for (int i = 0; i < NArrayReal; ++i) {
680 sp.rdata(NStructReal+i) = m_rdata[i][index];
681 }
682 }
683 sp.id() = m_aos[index].id();
684 sp.cpu() = m_aos[index].cpu();
685 for (int i = 0; i < NStructInt; ++i) {
686 sp.idata(i) = m_aos[index].idata(i);
687 }
688 if constexpr(NArrayInt > 0) {
689 for (int i = 0; i < NArrayInt; ++i) {
690 sp.idata(NStructInt+i) = m_idata[i][index];
691 }
692 }
693 return sp;
694 }
695
696 template <typename T = ParticleType, std::enable_if_t<T::is_soa_particle, int> = 0>
698 SuperParticleType getSuperParticle (int index) const noexcept
699 {
700 AMREX_ASSERT(index < m_size);
702 for (int i = 0; i < AMREX_SPACEDIM; ++i) {sp.pos(i) = m_rdata[i][index];}
703 sp.m_idcpu = m_idcpu[index];
704 for (int i = 0; i < NAR; ++i) {
705 sp.rdata(i) = m_rdata[i][index];
706 }
707 for (int i = 0; i < NAI; ++i) {
708 sp.idata(i) = m_idata[i][index];
709 }
710 return sp;
711 }
712};
713
715
719
720template <typename T_ParticleType, int NArrayReal, int NArrayInt,
721 template<class> class Allocator=DefaultAllocator>
723{
724 template <typename T>
725 using AllocatorType = Allocator<T>;
726
727 using ParticleType = T_ParticleType;
728 static constexpr int NAR = NArrayReal;
729 static constexpr int NAI = NArrayInt;
730 using RealType = typename ParticleType::RealType;
731
732 static constexpr int NStructReal = ParticleType::NReal;
733 static constexpr int NStructInt = ParticleType::NInt;
734
736
737 using AoS = std::conditional_t<
738 ParticleType::is_soa_particle,
741 using ParticleVector = typename AoS::ParticleVector;
742
743 using SoA = std::conditional_t<
744 ParticleType::is_soa_particle,
747 using RealVector = typename SoA::RealVector;
748 using IntVector = typename SoA::IntVector;
749 using StorageParticleType = typename ParticleType::StorageParticleType;
750
753
754 static constexpr bool has_polymorphic_allocator =
756
757 ParticleTile () = default;
758
759#ifndef _WIN32 // workaround windows compiler bug
760 ~ParticleTile () = default;
761
762 ParticleTile (ParticleTile const&) = delete;
763 ParticleTile (ParticleTile &&) noexcept = default;
764
765 ParticleTile& operator= (ParticleTile const&) = delete;
766 ParticleTile& operator= (ParticleTile &&) noexcept = default;
767#endif
768
769 void define (
770 int a_num_runtime_real,
771 int a_num_runtime_int,
772 std::vector<std::string>* soa_rdata_names=nullptr,
773 std::vector<std::string>* soa_idata_names=nullptr,
774 Arena* a_arena=nullptr
775 )
776 {
777 GetStructOfArrays().define(a_num_runtime_real, a_num_runtime_int, soa_rdata_names, soa_idata_names);
778 m_runtime_r_ptrs.resize(a_num_runtime_real);
779 m_runtime_i_ptrs.resize(a_num_runtime_int);
780 m_runtime_r_cptrs.resize(a_num_runtime_real);
781 m_runtime_i_cptrs.resize(a_num_runtime_int);
782
783 if constexpr (has_polymorphic_allocator) {
784 if (m_defined) {
785 // it is not allowed to change the arena after the tile has been defined
786 if constexpr (ParticleType::is_soa_particle) {
788 a_arena == GetStructOfArrays().GetIdCPUData().arena(),
789 "ParticleTile with PolymorphicArenaAllocator redefined with "
790 "different memory arena");
791 } else {
793 a_arena == m_aos_tile().arena(),
794 "ParticleTile with PolymorphicArenaAllocator redefined with "
795 "different memory arena");
796 }
797 }
798
799 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(a_arena != nullptr,
800 "ParticleTile with PolymorphicArenaAllocator defined with no memory arena! "
801 "Make sure to call setArena() on the ParticleContainer before initialization or "
802 "to pass an Arena to ParticleTile::define()");
803
804 if constexpr (ParticleType::is_soa_particle) {
805 GetStructOfArrays().GetIdCPUData().setArena(a_arena);
806 } else {
807 m_aos_tile().setArena(a_arena);
808 }
809 for (int j = 0; j < NumRealComps(); ++j) {
810 GetStructOfArrays().GetRealData(j).setArena(a_arena);
811 }
812 for (int j = 0; j < NumIntComps(); ++j) {
813 GetStructOfArrays().GetIntData(j).setArena(a_arena);
814 }
815 }
816
817 m_defined = true;
818 }
819
820 // Get id data
821 decltype(auto) id (int index) & {
822 if constexpr (!ParticleType::is_soa_particle) {
823 return m_aos_tile[index].id();
824 } else {
825 return ParticleIDWrapper(m_soa_tile.GetIdCPUData()[index]);
826 }
827 }
828
829 // const
830 decltype(auto) id (int index) const & {
831 if constexpr (!ParticleType::is_soa_particle) {
832 return m_aos_tile[index].id();
833 } else {
834 return ConstParticleIDWrapper(m_soa_tile.GetIdCPUData()[index]);
835 }
836 }
837
838 // Get cpu data
839 decltype(auto) cpu (int index) & {
840 if constexpr (!ParticleType::is_soa_particle) {
841 return m_aos_tile[index].cpu();
842 } else {
843 return ParticleCPUWrapper(m_soa_tile.GetIdCPUData()[index]);
844 }
845 }
846
847 // const
848 decltype(auto) cpu (int index) const & {
849 if constexpr (!ParticleType::is_soa_particle) {
850 return m_aos_tile[index].cpu();
851 } else {
852 return ConstParticleCPUWrapper(m_soa_tile.GetIdCPUData()[index]);
853 }
854 }
855
856 // Get positions data
857 RealType& pos (int index, int position_index) & {
858 if constexpr (!ParticleType::is_soa_particle) {
859 return m_aos_tile[index].pos(position_index);
860 } else {
861 static_assert(NArrayReal == ParticleType::PTD::NAR, "ParticleTile mismatch in R");
862 static_assert(NArrayInt == ParticleType::PTD::NAI, "ParticleTile mismatch in I");
863 static_assert(0 == ParticleType::StorageParticleType::NReal, "ParticleTile 2 mismatch in R");
864 static_assert(0 == ParticleType::StorageParticleType::NInt, "ParticleTile 2 mismatch in I");
865
866 return m_soa_tile.GetRealData(position_index)[index];
867 }
868 }
869
870 // const
871 RealType pos (int index, int position_index) const &
872 {
873 if constexpr (!ParticleType::is_soa_particle) {
874 return m_aos_tile[index].pos(position_index);
875 } else {
876 return m_soa_tile.GetRealData(position_index)[index];
877 }
878 }
879
880 AoS& GetArrayOfStructs () { return m_aos_tile; }
881 const AoS& GetArrayOfStructs () const { return m_aos_tile; }
882
883 SoA& GetStructOfArrays () { return m_soa_tile; }
884 const SoA& GetStructOfArrays () const { return m_soa_tile; }
885
886 bool empty () const { return size() == 0; }
887
892 std::size_t size () const
893 {
894 if constexpr (!ParticleType::is_soa_particle) {
895 return m_aos_tile.size();
896 } else {
897 return m_soa_tile.size();
898 }
899 }
900
905 int numParticles () const
906 {
907 if constexpr (!ParticleType::is_soa_particle) {
908 return m_aos_tile.numParticles();
909 } else {
910 return m_soa_tile.numParticles();
911 }
912 }
913
918 int numRealParticles () const
919 {
920 if constexpr (!ParticleType::is_soa_particle) {
921 return m_aos_tile.numRealParticles();
922 } else {
923 return m_soa_tile.numRealParticles();
924 }
925 }
926
932 {
933 if constexpr (!ParticleType::is_soa_particle) {
934 return m_aos_tile.numNeighborParticles();
935 } else {
936 return m_soa_tile.numNeighborParticles();
937 }
938 }
939
944 int numTotalParticles () const
945 {
946 if constexpr (!ParticleType::is_soa_particle) {
947 return m_aos_tile.numTotalParticles();
948 } else {
949 return m_soa_tile.numTotalParticles();
950 }
951 }
952
953 void setNumNeighbors (int num_neighbors)
954 {
955 if constexpr(!ParticleType::is_soa_particle) {
956 m_aos_tile.setNumNeighbors(num_neighbors);
957 }
958 m_soa_tile.setNumNeighbors(num_neighbors);
959 }
960
961 int getNumNeighbors () const
962 {
963 if constexpr (!ParticleType::is_soa_particle) {
964 AMREX_ASSERT( m_soa_tile.getNumNeighbors() == m_aos_tile.getNumNeighbors() );
965 return m_aos_tile.getNumNeighbors();
966 } else {
967 return m_soa_tile.getNumNeighbors();
968 }
969 }
970
971 void resize (std::size_t count, GrowthStrategy strategy = GrowthStrategy::Poisson)
972 {
973 if constexpr (!ParticleType::is_soa_particle) {
974 m_aos_tile.resize(count, strategy);
975 }
976 m_soa_tile.resize(count, strategy);
977 }
978
980 {
981 if constexpr (!ParticleType::is_soa_particle) {
982 m_aos_tile.reserve(capacity, strategy);
983 }
984 m_soa_tile.reserve(capacity, strategy);
985 }
986
990 template <typename T = ParticleType, std::enable_if_t<!T::is_soa_particle, int> = 0>
991 void push_back (const ParticleType& p) { m_aos_tile().push_back(p); }
992
996 template < int NR = NArrayReal, int NI = NArrayInt,
997 std::enable_if_t<NR != 0 || NI != 0, int> foo = 0>
999 {
1000 auto np = numParticles();
1001
1002 if constexpr (!ParticleType::is_soa_particle) {
1003 m_aos_tile.resize(np+1);
1004 for (int i = 0; i < AMREX_SPACEDIM; ++i) {
1005 m_aos_tile[np].pos(i) = sp.pos(i);
1006 }
1007 for (int i = 0; i < NStructReal; ++i) {
1008 m_aos_tile[np].rdata(i) = sp.rdata(i);
1009 }
1010 m_aos_tile[np].id() = sp.id();
1011 m_aos_tile[np].cpu() = sp.cpu();
1012 for (int i = 0; i < NStructInt; ++i) {
1013 m_aos_tile[np].idata(i) = sp.idata(i);
1014 }
1015 }
1016
1017 m_soa_tile.resize(np+1);
1018 if constexpr (ParticleType::is_soa_particle) {
1019 m_soa_tile.GetIdCPUData()[np] = sp.m_idcpu;
1020 }
1021 auto& arr_rdata = m_soa_tile.GetRealData();
1022 auto& arr_idata = m_soa_tile.GetIntData();
1023 for (int i = 0; i < NArrayReal; ++i) {
1024 arr_rdata[i][np] = sp.rdata(NStructReal+i);
1025 }
1026 for (int i = 0; i < NArrayInt; ++i) {
1027 arr_idata[i][np] = sp.idata(NStructInt+i);
1028 }
1029 }
1030
1035 void push_back_real (int comp, ParticleReal v) {
1036 m_soa_tile.GetRealData(comp).push_back(v);
1037 }
1038
1043 void push_back_real (const std::array<ParticleReal, NArrayReal>& v) {
1044 for (int i = 0; i < NArrayReal; ++i) {
1045 m_soa_tile.GetRealData(i).push_back(v[i]);
1046 }
1047 }
1048
1053 void push_back_real (int comp, const ParticleReal* beg, const ParticleReal* end) {
1054 auto it = m_soa_tile.GetRealData(comp).end();
1055 m_soa_tile.GetRealData(comp).insert(it, beg, end);
1056 }
1057
1065
1071 push_back_real(comp, vec.cbegin(), vec.cend());
1072 }
1073
1078 void push_back_real (int comp, std::size_t npar, ParticleReal v) {
1079 auto new_size = m_soa_tile.GetRealData(comp).size() + npar;
1080 m_soa_tile.GetRealData(comp).resize(new_size, v);
1081 }
1082
1087 void push_back_int (int comp, int v) {
1088 m_soa_tile.GetIntData(comp).push_back(v);
1089 }
1090
1095 void push_back_int (const std::array<int, NArrayInt>& v) {
1096 for (int i = 0; i < NArrayInt; ++i) {
1097 m_soa_tile.GetIntData(i).push_back(v[i]);
1098 }
1099 }
1100
1105 void push_back_int (int comp, const int* beg, const int* end) {
1106 auto it = m_soa_tile.GetIntData(comp).end();
1107 m_soa_tile.GetIntData(comp).insert(it, beg, end);
1108 }
1109
1117
1122 void push_back_int (int comp, amrex::Vector<int> const & vec) {
1123 push_back_int(comp, vec.cbegin(), vec.cend());
1124 }
1125
1130 void push_back_int (int comp, std::size_t npar, int v) {
1131 auto new_size = m_soa_tile.GetIntData(comp).size() + npar;
1132 m_soa_tile.GetIntData(comp).resize(new_size, v);
1133 }
1134
1135 int NumRealComps () const noexcept { return m_soa_tile.NumRealComps(); }
1136
1137 int NumIntComps () const noexcept { return m_soa_tile.NumIntComps(); }
1138
1139 int NumRuntimeRealComps () const noexcept { return m_runtime_r_ptrs.size(); }
1140
1141 int NumRuntimeIntComps () const noexcept { return m_runtime_i_ptrs.size(); }
1142
1144 {
1145 if constexpr (ParticleType::is_soa_particle) {
1146 GetStructOfArrays().GetIdCPUData().shrink_to_fit();
1147 } else {
1148 m_aos_tile().shrink_to_fit();
1149 }
1150 for (int j = 0; j < NumRealComps(); ++j)
1151 {
1152 auto& rdata = GetStructOfArrays().GetRealData(j);
1153 rdata.shrink_to_fit();
1154 }
1155
1156 for (int j = 0; j < NumIntComps(); ++j)
1157 {
1158 auto& idata = GetStructOfArrays().GetIntData(j);
1159 idata.shrink_to_fit();
1160 }
1161 }
1162
1164 {
1165 Long nbytes = 0;
1166 if constexpr (ParticleType::is_soa_particle) {
1167 nbytes += GetStructOfArrays().GetIdCPUData().capacity() * sizeof(uint64_t);
1168 } else {
1169 nbytes += m_aos_tile().capacity() * sizeof(ParticleType);
1170 }
1171 for (int j = 0; j < NumRealComps(); ++j)
1172 {
1173 auto& rdata = GetStructOfArrays().GetRealData(j);
1174 nbytes += rdata.capacity() * sizeof(ParticleReal);
1175 }
1176
1177 for (int j = 0; j < NumIntComps(); ++j)
1178 {
1179 auto& idata = GetStructOfArrays().GetIntData(j);
1180 nbytes += idata.capacity()*sizeof(int);
1181 }
1182 return nbytes;
1183 }
1184
1186 {
1187 if constexpr (ParticleType::is_soa_particle) {
1188 GetStructOfArrays().GetIdCPUData().swap(other.GetStructOfArrays().GetIdCPUData());
1189 } else {
1190 m_aos_tile().swap(other.GetArrayOfStructs()());
1191 }
1192 for (int j = 0; j < NumRealComps(); ++j)
1193 {
1194 auto& rdata = GetStructOfArrays().GetRealData(j);
1195 rdata.swap(other.GetStructOfArrays().GetRealData(j));
1196 }
1197
1198 for (int j = 0; j < NumIntComps(); ++j)
1199 {
1200 auto& idata = GetStructOfArrays().GetIntData(j);
1201 idata.swap(other.GetStructOfArrays().GetIntData(j));
1202 }
1203 }
1204
1206 {
1207 m_runtime_r_ptrs.resize(m_soa_tile.NumRealComps() - NArrayReal);
1208 m_runtime_i_ptrs.resize(m_soa_tile.NumIntComps() - NArrayInt);
1209#ifdef AMREX_USE_GPU
1210 bool copy_real = false;
1211 m_h_runtime_r_ptrs.resize(m_soa_tile.NumRealComps() - NArrayReal, nullptr);
1212 for (std::size_t i = 0; i < m_h_runtime_r_ptrs.size(); ++i) {
1213 if (m_h_runtime_r_ptrs[i] != m_soa_tile.GetRealData(i + NArrayReal).dataPtr()) {
1214 m_h_runtime_r_ptrs[i] = m_soa_tile.GetRealData(i + NArrayReal).dataPtr();
1215 copy_real = true;
1216 }
1217 }
1218 if (copy_real) {
1219 Gpu::htod_memcpy_async(m_runtime_r_ptrs.data(), m_h_runtime_r_ptrs.data(),
1220 m_h_runtime_r_ptrs.size()*sizeof(ParticleReal*));
1221 }
1222
1223 bool copy_int = false;
1224 m_h_runtime_i_ptrs.resize(m_soa_tile.NumIntComps() - NArrayInt, nullptr);
1225 for (std::size_t i = 0; i < m_h_runtime_i_ptrs.size(); ++i) {
1226 if (m_h_runtime_i_ptrs[i] != m_soa_tile.GetIntData(i + NArrayInt).dataPtr()) {
1227 m_h_runtime_i_ptrs[i] = m_soa_tile.GetIntData(i + NArrayInt).dataPtr();
1228 copy_int = true;
1229 }
1230 }
1231 if (copy_int) {
1232 Gpu::htod_memcpy_async(m_runtime_i_ptrs.data(), m_h_runtime_i_ptrs.data(),
1233 m_h_runtime_i_ptrs.size()*sizeof(int*));
1234 }
1235#else
1236 for (std::size_t i = 0; i < m_runtime_r_ptrs.size(); ++i) {
1237 m_runtime_r_ptrs[i] = m_soa_tile.GetRealData(i + NArrayReal).dataPtr();
1238 }
1239
1240 for (std::size_t i = 0; i < m_runtime_i_ptrs.size(); ++i) {
1241 m_runtime_i_ptrs[i] = m_soa_tile.GetIntData(i + NArrayInt).dataPtr();
1242 }
1243#endif
1244
1246 if constexpr (!ParticleType::is_soa_particle) {
1247 ptd.m_aos = m_aos_tile().dataPtr();
1248 } else {
1249 ptd.m_aos = nullptr;
1250 }
1251 if constexpr (ParticleType::is_soa_particle) {
1252 ptd.m_idcpu = m_soa_tile.GetIdCPUData().dataPtr();
1253 } else {
1254 ptd.m_idcpu = nullptr;
1255 }
1256 if constexpr(NArrayReal > 0) {
1257 for (int i = 0; i < NArrayReal; ++i) {
1258 ptd.m_rdata[i] = m_soa_tile.GetRealData(i).dataPtr();
1259 }
1260 }
1261 if constexpr(NArrayInt > 0) {
1262 for (int i = 0; i < NArrayInt; ++i) {
1263 ptd.m_idata[i] = m_soa_tile.GetIntData(i).dataPtr();
1264 }
1265 }
1266 ptd.m_size = size();
1267 ptd.m_num_runtime_real = m_runtime_r_ptrs.size();
1268 ptd.m_num_runtime_int = m_runtime_i_ptrs.size();
1269 ptd.m_runtime_rdata = m_runtime_r_ptrs.dataPtr();
1270 ptd.m_runtime_idata = m_runtime_i_ptrs.dataPtr();
1271
1272#ifdef AMREX_USE_GPU
1273 if (copy_real || copy_int) {
1275 }
1276#endif
1277
1278 return ptd;
1279 }
1280
1282 {
1283 m_runtime_r_cptrs.resize(m_soa_tile.NumRealComps() - NArrayReal);
1284 m_runtime_i_cptrs.resize(m_soa_tile.NumIntComps() - NArrayInt);
1285#ifdef AMREX_USE_GPU
1286 bool copy_real = false;
1287 m_h_runtime_r_cptrs.resize(m_soa_tile.NumRealComps() - NArrayReal, nullptr);
1288 for (std::size_t i = 0; i < m_h_runtime_r_cptrs.size(); ++i) {
1289 if (m_h_runtime_r_cptrs[i] != m_soa_tile.GetRealData(i + NArrayReal).dataPtr()) {
1290 m_h_runtime_r_cptrs[i] = m_soa_tile.GetRealData(i + NArrayReal).dataPtr();
1291 copy_real = true;
1292 }
1293 }
1294 if (copy_real) {
1295 Gpu::htod_memcpy_async(m_runtime_r_cptrs.data(), m_h_runtime_r_cptrs.data(),
1296 m_h_runtime_r_cptrs.size()*sizeof(ParticleReal*));
1297 }
1298
1299 bool copy_int = false;
1300 m_h_runtime_i_cptrs.resize(m_soa_tile.NumIntComps() - NArrayInt, nullptr);
1301 for (std::size_t i = 0; i < m_h_runtime_i_cptrs.size(); ++i) {
1302 if (m_h_runtime_i_cptrs[i] != m_soa_tile.GetIntData(i + NArrayInt).dataPtr()) {
1303 m_h_runtime_i_cptrs[i] = m_soa_tile.GetIntData(i + NArrayInt).dataPtr();
1304 copy_int = true;
1305 }
1306 }
1307 if (copy_int) {
1308 Gpu::htod_memcpy_async(m_runtime_i_cptrs.data(), m_h_runtime_i_cptrs.data(),
1309 m_h_runtime_i_cptrs.size()*sizeof(int*));
1310 }
1311#else
1312 for (std::size_t i = 0; i < m_runtime_r_cptrs.size(); ++i) {
1313 m_runtime_r_cptrs[i] = m_soa_tile.GetRealData(i + NArrayReal).dataPtr();
1314 }
1315
1316 for (std::size_t i = 0; i < m_runtime_i_cptrs.size(); ++i) {
1317 m_runtime_i_cptrs[i] = m_soa_tile.GetIntData(i + NArrayInt).dataPtr();
1318 }
1319#endif
1320
1322 if constexpr (!ParticleType::is_soa_particle) {
1323 ptd.m_aos = m_aos_tile().dataPtr();
1324 } else {
1325 ptd.m_aos = nullptr;
1326 }
1327 if constexpr (ParticleType::is_soa_particle) {
1328 ptd.m_idcpu = m_soa_tile.GetIdCPUData().dataPtr();
1329 } else {
1330 ptd.m_idcpu = nullptr;
1331 }
1332 if constexpr(NArrayReal > 0) {
1333 for (int i = 0; i < NArrayReal; ++i) {
1334 ptd.m_rdata[i] = m_soa_tile.GetRealData(i).dataPtr();
1335 }
1336 }
1337 if constexpr(NArrayInt > 0) {
1338 for (int i = 0; i < NArrayInt; ++i) {
1339 ptd.m_idata[i] = m_soa_tile.GetIntData(i).dataPtr();
1340 }
1341 }
1342 ptd.m_size = size();
1343 ptd.m_num_runtime_real = m_runtime_r_cptrs.size();
1344 ptd.m_num_runtime_int = m_runtime_i_cptrs.size();
1345 ptd.m_runtime_rdata = m_runtime_r_cptrs.dataPtr();
1346 ptd.m_runtime_idata = m_runtime_i_cptrs.dataPtr();
1347
1348#ifdef AMREX_USE_GPU
1349 if (copy_real || copy_int) {
1351 }
1352#endif
1353
1354 return ptd;
1355 }
1356
1360 {
1361 if constexpr (!ParticleType::is_soa_particle) {
1362 m_aos_tile.collectVectors(pv);
1363 } else {
1365 }
1366 m_soa_tile.collectVectors(idcpuv, rv, iv);
1367 }
1368
1369 static void reserve (std::map<ParticleTile<T_ParticleType,NArrayReal,NArrayInt,Allocator>*, int> const& addsizes)
1370 {
1371 if constexpr (!IsArenaAllocator<Allocator<int>>::value) {
1372 for (auto [p,s] : addsizes) {
1373 p->reserve(p->size()+s);
1374 }
1375 } else {
1376 using PV = std::conditional_t<ParticleType::is_soa_particle,
1382 for (auto [p,s] : addsizes) {
1383 if (s > 0) {
1388 p->collectVectors(pv, idcpuv, rv, iv);
1389 if constexpr (!ParticleType::is_soa_particle) {
1390 for (auto* v : pv) {
1391 pvs.emplace_back(v, s);
1392 }
1393 }
1394 for (auto* v : idcpuv) {
1395 ids.emplace_back(v, s);
1396 }
1397 for (auto* v : rv) {
1398 rvs.emplace_back(v, s);
1399 }
1400 for (auto* v : iv) {
1401 ivs.emplace_back(v, s);
1402 }
1403 }
1404 }
1405
1406 std::sort(pvs.begin(), pvs.end(), [] (auto const& a, auto const& b) {
1407 return (a.first->size() + a.second) >
1408 (b.first->size() + b.second);
1409 });
1410 std::sort(ids.begin(), ids.end(), [] (auto const& a, auto const& b) {
1411 return (a.first->size() + a.second) >
1412 (b.first->size() + b.second);
1413 });
1414 std::sort(rvs.begin(), rvs.end(), [] (auto const& a, auto const& b) {
1415 return (a.first->size() + a.second) >
1416 (b.first->size() + b.second);
1417 });
1418 std::sort(ivs.begin(), ivs.end(), [] (auto const& a, auto const& b) {
1419 return (a.first->size() + a.second) >
1420 (b.first->size() + b.second);
1421 });
1422
1423 // Handle big vectors first
1424 {
1425 int i_pvs = 0, i_ids = 0, i_rvs = 0, i_ivs = 0;
1426 auto n_pvs = int(pvs.size());
1427 auto n_ids = int(ids.size());
1428 auto n_rvs = int(rvs.size());
1429 auto n_ivs = int(ivs.size());
1430 while ((i_pvs < n_pvs) || (i_ids < n_ids) || (i_rvs < n_rvs) ||
1431 (i_ivs < n_ivs)) {
1432 std::size_t nbytes = 0;
1433 int ii = -1;
1434 if (i_pvs < n_pvs) {
1435 std::size_t my_bytes = (pvs[i_pvs].first->size()
1436 + pvs[i_pvs].second) * sizeof(typename PV::value_type);
1437 if (my_bytes > nbytes) {
1438 nbytes = my_bytes;
1439 ii = 0;
1440 }
1441 }
1442 if (i_ids < n_ids) {
1443 std::size_t my_bytes = (ids[i_ids].first->size()
1444 + ids[i_ids].second) * sizeof(typename SoA::IdCPU::value_type);
1445 if (my_bytes > nbytes) {
1446 nbytes = my_bytes;
1447 ii = 1;
1448 }
1449 }
1450 if (i_rvs < n_rvs) {
1451 std::size_t my_bytes = (rvs[i_rvs].first->size()
1452 + rvs[i_rvs].second) * sizeof(typename RealVector::value_type);
1453 if (my_bytes > nbytes) {
1454 nbytes = my_bytes;
1455 ii = 2;
1456 }
1457 }
1458 if (i_ivs < n_ivs) {
1459 std::size_t my_bytes = (ivs[i_ivs].first->size()
1460 + ivs[i_ivs].second) * sizeof(typename IntVector::value_type);
1461 if (my_bytes > nbytes) {
1462 nbytes = my_bytes;
1463 ii = 3;
1464 }
1465 }
1466 if (ii == 0) {
1467 auto [p,s] = pvs[i_pvs++];
1468 p->reserve(p->size() + s);
1469 } else if (ii == 1) {
1470 auto [p,s] = ids[i_ids++];
1471 p->reserve(p->size() + s);
1472 } else if (ii == 2) {
1473 auto [p,s] = rvs[i_rvs++];
1474 p->reserve(p->size() + s);
1475 } else {
1476 auto [p,s] = ivs[i_ivs++];
1477 p->reserve(p->size() + s);
1478 }
1479 }
1480 }
1481 }
1482 }
1483
1484private:
1485
1486 AoS m_aos_tile;
1487 SoA m_soa_tile;
1488
1489 bool m_defined = false;
1490
1492 amrex::PODVector<int*, Allocator<int*> > m_runtime_i_ptrs;
1493
1495 mutable amrex::PODVector<const int*, Allocator<const int*> >m_runtime_i_cptrs;
1496
1497 amrex::Gpu::HostVector<ParticleReal*> m_h_runtime_r_ptrs;
1498 amrex::Gpu::HostVector<int*> m_h_runtime_i_ptrs;
1499
1500 mutable amrex::Gpu::HostVector<const ParticleReal*> m_h_runtime_r_cptrs;
1501 mutable amrex::Gpu::HostVector<const int*> m_h_runtime_i_cptrs;
1502};
1503
1504} // namespace amrex
1505
1506#endif // AMREX_PARTICLETILE_H_
#define AMREX_ALWAYS_ASSERT_WITH_MESSAGE(EX, MSG)
Definition AMReX_BLassert.H:49
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:119
#define AMREX_RESTRICT
Definition AMReX_Extension.H:32
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
#define AMREX_D_DECL(a, b, c)
Definition AMReX_SPACE.H:171
Definition AMReX_GpuAllocators.H:121
A virtual base class for objects that manage their own dynamic memory allocation.
Definition AMReX_Arena.H:132
Definition AMReX_ArrayOfStructs.H:13
Dynamically allocated vector for trivially copyable data.
Definition AMReX_PODVector.H:308
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
amrex_particle_real ParticleReal
Floating Point Type for Particles.
Definition AMReX_REAL.H:90
amrex_long Long
Definition AMReX_INT.H:30
void streamSynchronize() noexcept
Definition AMReX_GpuDevice.H:310
void htod_memcpy_async(void *p_d, const void *p_h, const std::size_t sz) noexcept
Definition AMReX_GpuDevice.H:421
constexpr Long LastParticleID
Definition AMReX_Particle.H:21
Definition AMReX_Amr.cpp:49
__host__ __device__ void ignore_unused(const Ts &...)
This shuts up the compiler about unused variables.
Definition AMReX.H:139
GrowthStrategy
Definition AMReX_PODVector.H:250
RealVectND< 3 > RealVect
Definition AMReX_ParmParse.H:35
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition AMReX.cpp:240
const int[]
Definition AMReX_BLProfiler.cpp:1664
__host__ __device__ Dim3 end(BoxND< dim > const &box) noexcept
Definition AMReX_Box.H:2015
Definition AMReX_Particle.H:327
Definition AMReX_Particle.H:301
static constexpr bool is_particle_tile_data
Definition AMReX_ParticleTile.H:529
static constexpr int NAI
Definition AMReX_ParticleTile.H:518
int IntType
Definition AMReX_ParticleTile.H:522
GpuArray< const int *, NArrayInt > m_idata
Definition AMReX_ParticleTile.H:539
__host__ __device__ decltype(auto) idcpu(const int index) const &
Definition AMReX_ParticleTile.H:572
__host__ __device__ const int * idata(const int attribute_index) const
Definition AMReX_ParticleTile.H:588
Long m_size
Definition AMReX_ParticleTile.H:531
T_ParticleType ParticleType
Definition AMReX_ParticleTile.H:519
static constexpr int NStructReal
Definition AMReX_ParticleTile.H:524
__host__ __device__ void packParticleData(char *buffer, int src_index, Long dst_offset, const int *comm_real, const int *comm_int) const noexcept
Definition AMReX_ParticleTile.H:609
int m_num_runtime_real
Definition AMReX_ParticleTile.H:603
static constexpr int NStructInt
Definition AMReX_ParticleTile.H:525
const int *__restrict__ *__restrict__ m_runtime_idata
Definition AMReX_ParticleTile.H:606
ParticleReal RealType
Definition AMReX_ParticleTile.H:521
__host__ __device__ decltype(auto) pos(const int dir, const int index) const &
Definition AMReX_ParticleTile.H:542
__host__ __device__ decltype(auto) cpu(const int index) const &
Definition AMReX_ParticleTile.H:562
int m_num_runtime_int
Definition AMReX_ParticleTile.H:604
std::conditional_t< T_ParticleType::is_soa_particle, void const *__restrict__, ParticleType const *__restrict__ > AOS_PTR
Definition AMReX_ParticleTile.H:534
T_ParticleType const & ParticleRefType
Definition AMReX_ParticleTile.H:520
static constexpr int NAR
Definition AMReX_ParticleTile.H:517
AOS_PTR m_aos
Definition AMReX_ParticleTile.H:535
const uint64_t * m_idcpu
Definition AMReX_ParticleTile.H:537
__host__ __device__ SuperParticleType getSuperParticle(int index) const noexcept
Definition AMReX_ParticleTile.H:668
__host__ __device__ const ParticleReal * rdata(const int attribute_index) const
Definition AMReX_ParticleTile.H:582
GpuArray< const ParticleReal *, NArrayReal > m_rdata
Definition AMReX_ParticleTile.H:538
const ParticleReal *__restrict__ *__restrict__ m_runtime_rdata
Definition AMReX_ParticleTile.H:605
Definition AMReX_ParticleTile.H:326
__host__ __device__ ConstParticleIDWrapper id() const
Definition AMReX_ParticleTile.H:352
static constexpr int NArrayReal
Definition AMReX_ParticleTile.H:327
ParticleReal RealType
Definition AMReX_ParticleTile.H:335
__host__ __device__ ConstSoAParticle(ConstPTD const &ptd, long i)
Definition AMReX_ParticleTile.H:339
static constexpr int NArrayInt
Definition AMReX_ParticleTile.H:328
static constexpr bool is_rtsoa_particle
Definition AMReX_ParticleTile.H:332
static void NextID(Long nextid)
Reset on restart.
static constexpr bool is_constsoa_particle
Definition AMReX_ParticleTile.H:333
static Long UnprotectedNextID()
This version can only be used inside omp critical.
__host__ __device__ const RealType & pos(int position_index) const &
Definition AMReX_ParticleTile.H:360
__host__ __device__ RealVect pos() const &
Definition AMReX_ParticleTile.H:357
__host__ __device__ ConstParticleCPUWrapper cpu() const
Definition AMReX_ParticleTile.H:349
int IntType
Definition AMReX_ParticleTile.H:336
Fixed-size array that can be used on GPU.
Definition AMReX_Array.H:43
Definition AMReX_GpuAllocators.H:173
Definition AMReX_GpuAllocators.H:184
uint64_t m_idcpu
Definition AMReX_Particle.H:359
Definition AMReX_Particle.H:259
Definition AMReX_Particle.H:154
Definition AMReX_ParticleTile.H:33
__host__ __device__ SuperParticleType getSuperParticle(int index) const noexcept
Definition AMReX_ParticleTile.H:241
T_ParticleType & ParticleRefType
Definition AMReX_ParticleTile.H:38
__host__ __device__ decltype(auto) cpu(const int index) const &
Definition AMReX_ParticleTile.H:86
uint64_t * m_idcpu
Definition AMReX_ParticleTile.H:56
GpuArray< ParticleReal *, NAR > m_rdata
Definition AMReX_ParticleTile.H:57
__host__ __device__ void unpackParticleData(const char *buffer, Long src_offset, int dst_index, const int *comm_real, const int *comm_int) const noexcept
Definition AMReX_ParticleTile.H:182
__host__ __device__ decltype(auto) idcpu(const int index) const &
Definition AMReX_ParticleTile.H:96
__host__ __device__ ParticleReal * rdata(const int attribute_index) const
Definition AMReX_ParticleTile.H:106
__host__ __device__ void packParticleData(char *buffer, int src_index, std::size_t dst_offset, const int *comm_real, const int *comm_int) const noexcept
Definition AMReX_ParticleTile.H:128
static constexpr int NStructInt
Definition AMReX_ParticleTile.H:44
GpuArray< int *, NAI > m_idata
Definition AMReX_ParticleTile.H:58
ParticleReal RealType
Definition AMReX_ParticleTile.H:40
__host__ __device__ decltype(auto) pos(const int dir, const int index) const &
Definition AMReX_ParticleTile.H:66
T_ParticleType ParticleType
Definition AMReX_ParticleTile.H:37
std::conditional_t< T_ParticleType::is_soa_particle, void *__restrict__, ParticleType *__restrict__ > AOS_PTR
Definition AMReX_ParticleTile.H:53
int m_num_runtime_int
Definition AMReX_ParticleTile.H:61
Long m_size
Definition AMReX_ParticleTile.H:50
static constexpr int NAR
Definition AMReX_ParticleTile.H:34
int IntType
Definition AMReX_ParticleTile.H:41
ParticleReal *__restrict__ *__restrict__ m_runtime_rdata
Definition AMReX_ParticleTile.H:62
int m_num_runtime_real
Definition AMReX_ParticleTile.H:60
static constexpr bool is_particle_tile_data
Definition AMReX_ParticleTile.H:48
__host__ __device__ int * idata(const int attribute_index) const
Definition AMReX_ParticleTile.H:112
AOS_PTR m_aos
Definition AMReX_ParticleTile.H:54
static constexpr int NAI
Definition AMReX_ParticleTile.H:35
int *__restrict__ *__restrict__ m_runtime_idata
Definition AMReX_ParticleTile.H:63
__host__ __device__ void setSuperParticle(const SuperParticleType &sp, int index) const noexcept
Definition AMReX_ParticleTile.H:288
static constexpr int NStructReal
Definition AMReX_ParticleTile.H:43
Definition AMReX_ParticleTile.H:723
typename ParticleType::StorageParticleType StorageParticleType
Definition AMReX_ParticleTile.H:749
int NumRealComps() const noexcept
Definition AMReX_ParticleTile.H:1135
void push_back_real(int comp, amrex::Vector< amrex::ParticleReal > const &vec)
Definition AMReX_ParticleTile.H:1070
int NumIntComps() const noexcept
Definition AMReX_ParticleTile.H:1137
typename ParticleType::RealType RealType
Definition AMReX_ParticleTile.H:730
ParticleTile()=default
int getNumNeighbors() const
Definition AMReX_ParticleTile.H:961
typename AoS::ParticleVector ParticleVector
Definition AMReX_ParticleTile.H:741
void push_back(const ParticleType &p)
Definition AMReX_ParticleTile.H:991
ParticleTile(ParticleTile const &)=delete
std::conditional_t< ParticleType::is_soa_particle, StructOfArrays< NArrayReal, NArrayInt, Allocator, true >, StructOfArrays< NArrayReal, NArrayInt, Allocator, false > > SoA
Definition AMReX_ParticleTile.H:746
const SoA & GetStructOfArrays() const
Definition AMReX_ParticleTile.H:884
static constexpr int NAI
Definition AMReX_ParticleTile.H:729
ParticleTile(ParticleTile &&) noexcept=default
void push_back_real(int comp, const ParticleReal *beg, const ParticleReal *end)
Definition AMReX_ParticleTile.H:1053
static constexpr int NStructInt
Definition AMReX_ParticleTile.H:733
void setNumNeighbors(int num_neighbors)
Definition AMReX_ParticleTile.H:953
Long capacity() const
Definition AMReX_ParticleTile.H:1163
int numTotalParticles() const
Returns the total number of particles, real and neighbor.
Definition AMReX_ParticleTile.H:944
std::size_t size() const
Returns the total number of particles (real and neighbor)
Definition AMReX_ParticleTile.H:892
static constexpr bool has_polymorphic_allocator
Definition AMReX_ParticleTile.H:754
ParticleTileDataType getParticleTileData()
Definition AMReX_ParticleTile.H:1205
void reserve(std::size_t capacity, GrowthStrategy strategy=GrowthStrategy::Poisson)
Definition AMReX_ParticleTile.H:979
void push_back(const SuperParticleType &sp)
Definition AMReX_ParticleTile.H:998
int numNeighborParticles() const
Returns the number of neighbor particles (excluding reals)
Definition AMReX_ParticleTile.H:931
~ParticleTile()=default
const AoS & GetArrayOfStructs() const
Definition AMReX_ParticleTile.H:881
static constexpr int NAR
Definition AMReX_ParticleTile.H:728
ConstParticleTileDataType getConstParticleTileData() const
Definition AMReX_ParticleTile.H:1281
void shrink_to_fit()
Definition AMReX_ParticleTile.H:1143
T_ParticleType ParticleType
Definition AMReX_ParticleTile.H:727
int numParticles() const
Returns the number of real particles (excluding neighbors)
Definition AMReX_ParticleTile.H:905
void push_back_int(int comp, amrex::Vector< int > const &vec)
Definition AMReX_ParticleTile.H:1122
void resize(std::size_t count, GrowthStrategy strategy=GrowthStrategy::Poisson)
Definition AMReX_ParticleTile.H:971
void swap(ParticleTile< ParticleType, NArrayReal, NArrayInt, Allocator > &other) noexcept
Definition AMReX_ParticleTile.H:1185
void push_back_int(int comp, amrex::Vector< int >::const_iterator beg, amrex::Vector< int >::const_iterator end)
Definition AMReX_ParticleTile.H:1114
void push_back_real(const std::array< ParticleReal, NArrayReal > &v)
Definition AMReX_ParticleTile.H:1043
int NumRuntimeRealComps() const noexcept
Definition AMReX_ParticleTile.H:1139
void collectVectors(Vector< ParticleVector * > &pv, Vector< typename SoA::IdCPU * > &idcpuv, Vector< RealVector * > &rv, Vector< IntVector * > &iv)
Definition AMReX_ParticleTile.H:1357
AoS & GetArrayOfStructs()
Definition AMReX_ParticleTile.H:880
RealType & pos(int index, int position_index) &
Definition AMReX_ParticleTile.H:857
typename SoA::IntVector IntVector
Definition AMReX_ParticleTile.H:748
void push_back_int(const std::array< int, NArrayInt > &v)
Definition AMReX_ParticleTile.H:1095
void push_back_real(int comp, amrex::Vector< amrex::ParticleReal >::const_iterator beg, amrex::Vector< amrex::ParticleReal >::const_iterator end)
Definition AMReX_ParticleTile.H:1062
Allocator< T > AllocatorType
Definition AMReX_ParticleTile.H:725
int NumRuntimeIntComps() const noexcept
Definition AMReX_ParticleTile.H:1141
bool empty() const
Definition AMReX_ParticleTile.H:886
void push_back_int(int comp, int v)
Definition AMReX_ParticleTile.H:1087
RealType pos(int index, int position_index) const &
Definition AMReX_ParticleTile.H:871
decltype(auto) cpu(int index) &
Definition AMReX_ParticleTile.H:839
void define(int a_num_runtime_real, int a_num_runtime_int, std::vector< std::string > *soa_rdata_names=nullptr, std::vector< std::string > *soa_idata_names=nullptr, Arena *a_arena=nullptr)
Definition AMReX_ParticleTile.H:769
SoA & GetStructOfArrays()
Definition AMReX_ParticleTile.H:883
void push_back_int(int comp, std::size_t npar, int v)
Definition AMReX_ParticleTile.H:1130
void push_back_real(int comp, std::size_t npar, ParticleReal v)
Definition AMReX_ParticleTile.H:1078
void push_back_int(int comp, const int *beg, const int *end)
Definition AMReX_ParticleTile.H:1105
typename SoA::RealVector RealVector
Definition AMReX_ParticleTile.H:747
int numRealParticles() const
Returns the number of real particles (excluding neighbors)
Definition AMReX_ParticleTile.H:918
std::conditional_t< ParticleType::is_soa_particle, ThisParticleTileHasNoAoS, ArrayOfStructs< ParticleType, Allocator > > AoS
Definition AMReX_ParticleTile.H:740
static constexpr int NStructReal
Definition AMReX_ParticleTile.H:732
void push_back_real(int comp, ParticleReal v)
Definition AMReX_ParticleTile.H:1035
static void reserve(std::map< ParticleTile< T_ParticleType, NArrayReal, NArrayInt, Allocator > *, int > const &addsizes)
Definition AMReX_ParticleTile.H:1369
The struct used to store particles.
Definition AMReX_Particle.H:405
__host__ __device__ RealVect pos() const &
Definition AMReX_Particle.H:456
__host__ __device__ int & idata(int index) &
Definition AMReX_Particle.H:545
__host__ __device__ ParticleCPUWrapper cpu() &
Definition AMReX_Particle.H:424
__host__ __device__ ParticleIDWrapper id() &
Definition AMReX_Particle.H:427
__host__ __device__ RealType & rdata(int index) &
Definition AMReX_Particle.H:474
Definition AMReX_Particle.H:388
Definition AMReX_ParticleTile.H:390
static constexpr int NArrayReal
Definition AMReX_ParticleTile.H:391
ParticleTileData< SoAParticleBase, NArrayReal, NArrayInt > PTD
Definition AMReX_ParticleTile.H:394
__host__ __device__ uint64_t & idcpu() &
Definition AMReX_ParticleTile.H:420
static Long UnprotectedNextID()
This version can only be used inside omp critical.
Definition AMReX_ParticleTile.H:498
__host__ __device__ ConstParticleCPUWrapper cpu() const &
Definition AMReX_ParticleTile.H:423
static Long the_next_id
Definition AMReX_ParticleTile.H:409
static constexpr int NArrayInt
Definition AMReX_ParticleTile.H:392
__host__ __device__ const uint64_t & idcpu() const &
Definition AMReX_ParticleTile.H:429
__host__ __device__ RealVect pos() const &
Definition AMReX_ParticleTile.H:434
ParticleReal RealType
Definition AMReX_ParticleTile.H:400
__host__ __device__ ParticleCPUWrapper cpu() &
Definition AMReX_ParticleTile.H:414
__host__ __device__ ParticleIDWrapper id() &
Definition AMReX_ParticleTile.H:417
static constexpr bool is_constsoa_particle
Definition AMReX_ParticleTile.H:397
__host__ __device__ RealType & pos(int position_index) &
Definition AMReX_ParticleTile.H:437
static constexpr bool is_rtsoa_particle
Definition AMReX_ParticleTile.H:396
int IntType
Definition AMReX_ParticleTile.H:401
__host__ __device__ SoAParticle(PTD const &ptd, long i)
Definition AMReX_ParticleTile.H:404
__host__ __device__ ConstParticleIDWrapper id() const &
Definition AMReX_ParticleTile.H:426
static Long NextID()
Definition AMReX_ParticleTile.H:477
__host__ __device__ RealType pos(int position_index) const &
Definition AMReX_ParticleTile.H:444
Definition AMReX_StructOfArrays.H:20
Definition AMReX_ParticleTile.H:716
Definition AMReX_ParticleTile.H:714
Definition AMReX_MakeParticle.H:13