blob: 2240b754c6c2927a5ab8c038cfb62a1ed20e12f3 (
plain) (
blame)
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
91
92
93
94
95
96
97
98
99
100
101
|
/* Copyright 2020 Andrew Myers
*
* This file is part of WarpX.
*
* License: BSD-3-Clause-LBNL
*/
#ifndef WARPX_PARTICLES_PUSHER_COPYPARTICLEATTRIBS_H_
#define WARPX_PARTICLES_PUSHER_COPYPARTICLEATTRIBS_H_
#include "Particles/WarpXParticleContainer.H"
#include <AMReX_REAL.H>
#include <limits>
/** \brief Functor that creates copies of the current particle
* positions and momenta for later use. This is needed
* by the back-transformed diagnostics.
*/
struct CopyParticleAttribs
{
using TmpParticles = WarpXParticleContainer::TmpParticles;
GetParticlePosition m_get_position;
const amrex::ParticleReal* AMREX_RESTRICT uxp = nullptr;
const amrex::ParticleReal* AMREX_RESTRICT uyp = nullptr;
const amrex::ParticleReal* AMREX_RESTRICT uzp = nullptr;
amrex::ParticleReal* AMREX_RESTRICT xpold = nullptr;
amrex::ParticleReal* AMREX_RESTRICT ypold = nullptr;
amrex::ParticleReal* AMREX_RESTRICT zpold = nullptr;
amrex::ParticleReal* AMREX_RESTRICT uxpold = nullptr;
amrex::ParticleReal* AMREX_RESTRICT uypold = nullptr;
amrex::ParticleReal* AMREX_RESTRICT uzpold = nullptr;
/** \brief Construct a new functor
*
* \param a_pti iterator to the tile containing the macroparticles
* \param tmp_particle_data holder for the temporary particle data
* \param a_offset offset to apply when reading / writing particle data
* This is needed because when we use field gather buffers we don't
* always start at the particle with index 0.
*/
CopyParticleAttribs (const WarpXParIter& a_pti, TmpParticles& tmp_particle_data,
int a_offset = 0) noexcept
{
if (tmp_particle_data.size() == 0) return;
auto& attribs = a_pti.GetAttribs();
uxp = attribs[PIdx::ux].dataPtr() + a_offset;
uyp = attribs[PIdx::uy].dataPtr() + a_offset;
uzp = attribs[PIdx::uz].dataPtr() + a_offset;
const auto lev = a_pti.GetLevel();
const auto index = a_pti.GetPairIndex();
xpold = tmp_particle_data[lev].at(index)[TmpIdx::xold ].dataPtr() + a_offset;
ypold = tmp_particle_data[lev].at(index)[TmpIdx::yold ].dataPtr() + a_offset;
zpold = tmp_particle_data[lev].at(index)[TmpIdx::zold ].dataPtr() + a_offset;
uxpold = tmp_particle_data[lev].at(index)[TmpIdx::uxold].dataPtr() + a_offset;
uypold = tmp_particle_data[lev].at(index)[TmpIdx::uyold].dataPtr() + a_offset;
uzpold = tmp_particle_data[lev].at(index)[TmpIdx::uzold].dataPtr() + a_offset;
m_get_position = GetParticlePosition(a_pti, a_offset);
}
/** \brief copy the position and momentum of particle i to the
* temporary data holder
*/
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
void operator() (const int i) const noexcept
{
AMREX_ASSERT(uxp != nullptr);
AMREX_ASSERT(uyp != nullptr);
AMREX_ASSERT(uzp != nullptr);
AMREX_ASSERT(xpold != nullptr);
AMREX_ASSERT(ypold != nullptr);
AMREX_ASSERT(zpold != nullptr);
AMREX_ASSERT(uxpold != nullptr);
AMREX_ASSERT(uypold != nullptr);
AMREX_ASSERT(uzpold != nullptr);
amrex::ParticleReal x, y, z;
m_get_position(i, x, y, z);
xpold[i] = x;
ypold[i] = y;
zpold[i] = z;
uxpold[i] = uxp[i];
uypold[i] = uyp[i];
uzpold[i] = uzp[i];
}
};
#endif // WARPX_PARTICLES_PUSHER_COPYPARTICLEATTRIBS_H_
|