1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
#ifndef COPYPARTICLE_H_
#define COPYPARTICLE_H_
#include "WarpXParticleContainer.H"
/**
* \brief Functor to copy one particle
*
* This is meant to be a very small class captured by value in kernel launches,
* that can be initialized on the host and copied to the device at each
* iteration. It should be general enough to be used by all processes.
*
* Pointers to SoA data are saved when constructor is called.
* AoS data is passed as argument of operator ().
*/
class CopyParticle
{
public:
// ID of MPI rank
int m_cpuid;
// If true, will copy old attribs for back-transforme diagnostics
bool m_do_back_transformed_product;
// Source old (runtime) attribs for back-transformed diagnostics
amrex::GpuArray<amrex::ParticleReal*,3> m_runtime_uold_source;
// Source attribs
amrex::GpuArray<amrex::ParticleReal*,PIdx::nattribs> m_attribs_source;
// Product attribs
amrex::GpuArray<amrex::ParticleReal*,PIdx::nattribs> m_attribs_product;
// Product runtime attribs
amrex::GpuArray<amrex::ParticleReal*,6> m_runtime_attribs_product;
// Simple constructor
AMREX_GPU_HOST_DEVICE
CopyParticle(
const int cpuid, const int do_back_transformed_product,
const amrex::GpuArray<amrex::ParticleReal*,3> runtime_uold_source,
const amrex::GpuArray<amrex::ParticleReal*,PIdx::nattribs> attribs_source,
const amrex::GpuArray<amrex::ParticleReal*,PIdx::nattribs> attribs_product,
const amrex::GpuArray<amrex::ParticleReal*,6> runtime_attribs_product)
:
m_cpuid(cpuid),
m_do_back_transformed_product(do_back_transformed_product),
m_runtime_uold_source(runtime_uold_source),
m_attribs_source(attribs_source),
m_attribs_product(attribs_product),
m_runtime_attribs_product(runtime_attribs_product){}
/**
* \brief Overload operator () to do the copy of 1 particle
*
* \param is index of source particle
* \param ip index of product particle
* \param pid_product ID of first product particle
* \param p_source Struct with data for 1 source particle (position etc.)
* \param p_product Struct with data for 1 product particle (position etc.)
*/
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
void operator () (int is, int ip, int pid_product,
WarpXParticleContainer::ParticleType& p_source,
WarpXParticleContainer::ParticleType& p_product) const noexcept
{
// Copy particle from source to product: AoS
p_product.id() = pid_product + ip;
p_product.cpu() = m_cpuid;
p_product.pos(0) = p_source.pos(0);
p_product.pos(1) = p_source.pos(1);
#if (AMREX_SPACEDIM == 3)
p_product.pos(2) = p_source.pos(2);
#endif
// Copy particle from source to product: SoA
for (int ia = 0; ia < PIdx::nattribs; ++ia) {
m_attribs_product[ia][ip] = m_attribs_source[ia][is];
}
// Update xold etc. if boosted frame diagnostics required
// for product species. Fill runtime attribs with a copy of
// current properties (xold = x etc.).
if (m_do_back_transformed_product) {
m_runtime_attribs_product[0][ip] = p_source.pos(0);
m_runtime_attribs_product[1][ip] = p_source.pos(1);
m_runtime_attribs_product[2][ip] = p_source.pos(2);
m_runtime_attribs_product[3][ip] = m_runtime_uold_source[0][ip];
m_runtime_attribs_product[4][ip] = m_runtime_uold_source[1][ip];
m_runtime_attribs_product[5][ip] = m_runtime_uold_source[2][ip];
}
}
};
#endif // COPYPARTICLE_H_
|