WarpX
Loading...
Searching...
No Matches
LatticeElementFinder.H
Go to the documentation of this file.
1/* Copyright 2022 David Grote
2 *
3 * This file is part of WarpX.
4 *
5 * License: BSD-3-Clause-LBNL
6 */
7#ifndef WARPX_ACCELERATORLATTICE_LATTICEELEMENTS_LATTICEELEMENTFINDER_H_
8#define WARPX_ACCELERATORLATTICE_LATTICEELEMENTS_LATTICEELEMENTFINDER_H_
9
14
15#include <AMReX_REAL.H>
16#include <AMReX_GpuContainers.H>
17
20
21// Instances of the LatticeElementFinder class are saved in the AcceleratorLattice class
22// as the objects in a LayoutData.
23// The LatticeElementFinder handles the lookup needed to find the lattice elements at
24// particle locations.
25
27{
28
38 void InitElementFinder (int lev, amrex::Real gamma_boost,
40 amrex::MFIter const& a_mfi,
41 AcceleratorLattice const& accelerator_lattice);
42
48 void AllocateIndices (AcceleratorLattice const& accelerator_lattice);
49
58 void UpdateIndices (int lev, amrex::MFIter const& a_mfi,
59 AcceleratorLattice const& accelerator_lattice,
60 const amrex::Vector<amrex::Real>& time);
61
62 /* Define the location and size of the index lookup table */
63 /* Use the type Real to be consistent with the way the main grid is defined */
64 int m_nz;
67
68 /* Parameters needed for the Lorentz transforms into and out of the boosted frame */
69 /* The time for m_time is consistent with the main time variable */
73
83 WarpXParIter const& a_pti, int a_offset, AcceleratorLattice const& accelerator_lattice,
84 const amrex::Vector<amrex::Real>& dts) const;
85
86 /* The index lookup tables for each lattice element type */
89
100 amrex::Gpu::DeviceVector<int> & indices) const;
101};
102
108{
109
119 void
120 InitLatticeElementFinderDevice (WarpXParIter const& a_pti, int a_offset,
121 AcceleratorLattice const& accelerator_lattice,
122 LatticeElementFinder const & h_finder,
123 const amrex::Vector<amrex::Real>& dts);
124
125 /* Whether the class has been initialized */
126 bool m_initialized = false;
127
128 /* Size and location of the index lookup table */
129 int m_nz;
133
134 /* Parameters needed for the Lorentz transforms into and out of the boosted frame */
138
143
144 /* Device level instances for each lattice element type */
147
148 /* Device level index lookup tables for each element type */
149 int const* d_quad_indices_arr = nullptr;
150 int const* d_plasmalens_indices_arr = nullptr;
151
159 void operator () (const long i,
160 amrex::ParticleReal& field_Ex,
161 amrex::ParticleReal& field_Ey,
162 amrex::ParticleReal& field_Ez,
163 amrex::ParticleReal& field_Bx,
164 amrex::ParticleReal& field_By,
165 amrex::ParticleReal& field_Bz) const noexcept
166 {
167
168 using namespace amrex::literals;
169
170 amrex::ParticleReal x, y, z;
171 m_get_position(i, x, y, z);
172
173 // Find location of partice in the indices grid
174 // (which is in the boosted frame)
175 const int iz = static_cast<int>((z - m_zmin)/m_dz);
176
177 // This check shouldn't be needed since the particle should always
178 // be within the grid, but it is added for safety.
179 if (iz < 0 || iz >= m_nz) { return; }
180
181 constexpr auto inv_c2 = PhysConst::inv_c2_v<amrex::ParticleReal>;
182 amrex::ParticleReal const gamma = std::sqrt(1._prt + (m_ux[i]*m_ux[i] + m_uy[i]*m_uy[i] + m_uz[i]*m_uz[i])*inv_c2);
183 amrex::ParticleReal const vzp = m_uz[i]/gamma;
184
185 amrex::ParticleReal zpvdt = z + vzp*m_dt;
186
187 // The position passed to the get_field methods needs to be in the lab frame.
188 if (m_gamma_boost > 1._prt) {
190 zpvdt = m_gamma_boost*zpvdt + m_uz_boost*(m_time + m_dt);
191 }
192
193 amrex::ParticleReal Ex_sum = 0._prt;
194 amrex::ParticleReal Ey_sum = 0._prt;
195 const amrex::ParticleReal Ez_sum = 0._prt;
196 amrex::ParticleReal Bx_sum = 0._prt;
197 amrex::ParticleReal By_sum = 0._prt;
198 const amrex::ParticleReal Bz_sum = 0._prt;
199
200 if (d_quad.nelements > 0) {
201 if (d_quad_indices_arr[iz] > -1) {
202 const auto ielement = d_quad_indices_arr[iz];
203 amrex::ParticleReal Ex, Ey, Bx, By;
204 d_quad.get_field(ielement, x, y, z, zpvdt, Ex, Ey, Bx, By);
205 Ex_sum += Ex;
206 Ey_sum += Ey;
207 Bx_sum += Bx;
208 By_sum += By;
209 }
210 }
211
212 if (d_plasmalens.nelements > 0) {
213 if (d_plasmalens_indices_arr[iz] > -1) {
214 const auto ielement = d_plasmalens_indices_arr[iz];
215 amrex::ParticleReal Ex, Ey, Bx, By;
216 d_plasmalens.get_field(ielement, x, y, z, zpvdt, Ex, Ey, Bx, By);
217 Ex_sum += Ex;
218 Ey_sum += Ey;
219 Bx_sum += Bx;
220 By_sum += By;
221 }
222 }
223
224 if (m_gamma_boost > 1._prt) {
225 // The fields returned from get_field is in the lab frame
226 // Transform the fields to the boosted frame
227 const amrex::ParticleReal Ex_boost = m_gamma_boost*Ex_sum - m_uz_boost*By_sum;
228 const amrex::ParticleReal Ey_boost = m_gamma_boost*Ey_sum + m_uz_boost*Bx_sum;
229 const amrex::ParticleReal Bx_boost = m_gamma_boost*Bx_sum + m_uz_boost*Ey_sum*inv_c2;
230 const amrex::ParticleReal By_boost = m_gamma_boost*By_sum - m_uz_boost*Ex_sum*inv_c2;
231 Ex_sum = Ex_boost;
232 Ey_sum = Ey_boost;
233 Bx_sum = Bx_boost;
234 By_sum = By_boost;
235 }
236
237 field_Ex += Ex_sum;
238 field_Ey += Ey_sum;
239 field_Ez += Ez_sum;
240 field_Bx += Bx_sum;
241 field_By += By_sum;
242 field_Bz += Bz_sum;
243
244 }
245
246};
247
248#endif // WARPX_ACCELERATORLATTICE_LATTICEELEMENTS_LATTICEELEMENTFINDER_H_
#define AMREX_FORCE_INLINE
#define AMREX_RESTRICT
#define AMREX_GPU_HOST_DEVICE
Definition AcceleratorLattice.H:21
Definition WarpXParticleContainer.H:112
amrex_real Real
amrex_particle_real ParticleReal
PODVector< T, ArenaAllocator< T > > DeviceVector
constexpr auto inv_c2_v
inverse of the square of the vacuum speed of light [s^2/m^2] (variable template)
Definition constant.H:146
Functor that can be used to extract the positions of the macroparticles inside a ParallelFor kernel.
Definition GetAndSetPosition.H:75
Definition HardEdgedPlasmaLens.H:64
Definition HardEdgedQuadrupole.H:64
The lattice element finder class that can be trivially copied to the device. This only has simple dat...
Definition LatticeElementFinder.H:108
const amrex::ParticleReal *AMREX_RESTRICT m_ux
Definition LatticeElementFinder.H:140
const amrex::ParticleReal *AMREX_RESTRICT m_uy
Definition LatticeElementFinder.H:141
int const * d_plasmalens_indices_arr
Definition LatticeElementFinder.H:150
int m_nz
Definition LatticeElementFinder.H:129
amrex::Real m_time
Definition LatticeElementFinder.H:137
HardEdgedPlasmaLensDevice d_plasmalens
Definition LatticeElementFinder.H:146
amrex::Real m_dt
Definition LatticeElementFinder.H:132
bool m_initialized
Definition LatticeElementFinder.H:126
void InitLatticeElementFinderDevice(WarpXParIter const &a_pti, int a_offset, AcceleratorLattice const &accelerator_lattice, LatticeElementFinder const &h_finder, const amrex::Vector< amrex::Real > &dts)
Initialize the data needed to do the lookups.
Definition LatticeElementFinder.cpp:96
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void operator()(const long i, amrex::ParticleReal &field_Ex, amrex::ParticleReal &field_Ey, amrex::ParticleReal &field_Ez, amrex::ParticleReal &field_Bx, amrex::ParticleReal &field_By, amrex::ParticleReal &field_Bz) const noexcept
Gather the field for the particle from the lattice elements.
Definition LatticeElementFinder.H:159
amrex::Real m_dz
Definition LatticeElementFinder.H:131
int const * d_quad_indices_arr
Definition LatticeElementFinder.H:149
amrex::ParticleReal m_uz_boost
Definition LatticeElementFinder.H:136
const amrex::ParticleReal *AMREX_RESTRICT m_uz
Definition LatticeElementFinder.H:142
amrex::Real m_zmin
Definition LatticeElementFinder.H:130
HardEdgedQuadrupoleDevice d_quad
Definition LatticeElementFinder.H:145
GetParticlePosition< PIdx > m_get_position
Definition LatticeElementFinder.H:139
amrex::ParticleReal m_gamma_boost
Definition LatticeElementFinder.H:135
Definition LatticeElementFinder.H:27
void setup_lattice_indices(amrex::Gpu::DeviceVector< amrex::ParticleReal > const &zs, amrex::Gpu::DeviceVector< amrex::ParticleReal > const &ze, amrex::Gpu::DeviceVector< int > &indices) const
Fill in the index lookup tables This loops over the grid (in z) and finds the lattice element closest...
Definition LatticeElementFinder.cpp:134
amrex::Gpu::DeviceVector< int > d_quad_indices
Definition LatticeElementFinder.H:87
int m_nz
Definition LatticeElementFinder.H:64
amrex::Real m_zmin
Definition LatticeElementFinder.H:65
LatticeElementFinderDevice GetFinderDeviceInstance(WarpXParIter const &a_pti, int a_offset, AcceleratorLattice const &accelerator_lattice, const amrex::Vector< amrex::Real > &dts) const
Get the device level instance associated with this instance.
Definition LatticeElementFinder.cpp:86
amrex::Gpu::DeviceVector< int > d_plasmalens_indices
Definition LatticeElementFinder.H:88
amrex::ParticleReal m_gamma_boost
Definition LatticeElementFinder.H:70
amrex::Real m_time
Definition LatticeElementFinder.H:72
void UpdateIndices(int lev, amrex::MFIter const &a_mfi, AcceleratorLattice const &accelerator_lattice, const amrex::Vector< amrex::Real > &time)
Update the index lookup tables for each element type, filling in the values.
Definition LatticeElementFinder.cpp:61
amrex::Real m_dz
Definition LatticeElementFinder.H:66
amrex::ParticleReal m_uz_boost
Definition LatticeElementFinder.H:71
void InitElementFinder(int lev, amrex::Real gamma_boost, const amrex::Vector< amrex::Real > &time, amrex::MFIter const &a_mfi, AcceleratorLattice const &accelerator_lattice)
Initialize the element finder at the level and grid.
Definition LatticeElementFinder.cpp:18
void AllocateIndices(AcceleratorLattice const &accelerator_lattice)
Allocate the index lookup tables for each element type.
Definition LatticeElementFinder.cpp:46