WarpX
FieldGather.H
Go to the documentation of this file.
1 /* Copyright 2019 Axel Huebl, David Grote, Maxence Thevenet
2  * Revathi Jambunathan, Weiqun Zhang
3  *
4  * This file is part of WarpX.
5  *
6  * License: BSD-3-Clause-LBNL
7  */
8 #ifndef FIELDGATHER_H_
9 #define FIELDGATHER_H_
10 
13 #include "Particles/ShapeFactors.H"
14 #include "Utils/WarpX_Complex.H"
15 
16 #include <AMReX.H>
17 
36 template <int depos_order, int galerkin_interpolation>
37 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
38 void doGatherShapeN (const amrex::ParticleReal xp,
39  const amrex::ParticleReal yp,
40  const amrex::ParticleReal zp,
41  amrex::ParticleReal& Exp,
42  amrex::ParticleReal& Eyp,
43  amrex::ParticleReal& Ezp,
44  amrex::ParticleReal& Bxp,
45  amrex::ParticleReal& Byp,
46  amrex::ParticleReal& Bzp,
47  amrex::Array4<amrex::Real const> const& ex_arr,
48  amrex::Array4<amrex::Real const> const& ey_arr,
49  amrex::Array4<amrex::Real const> const& ez_arr,
50  amrex::Array4<amrex::Real const> const& bx_arr,
51  amrex::Array4<amrex::Real const> const& by_arr,
52  amrex::Array4<amrex::Real const> const& bz_arr,
53  const amrex::IndexType ex_type,
54  const amrex::IndexType ey_type,
55  const amrex::IndexType ez_type,
56  const amrex::IndexType bx_type,
57  const amrex::IndexType by_type,
58  const amrex::IndexType bz_type,
59  const amrex::GpuArray<amrex::Real, 3>& dx,
60  const amrex::GpuArray<amrex::Real, 3>& xyzmin,
61  const amrex::Dim3& lo,
62  const int n_rz_azimuthal_modes)
63 {
64  using namespace amrex;
65 
66 #if defined(WARPX_DIM_XZ)
67  amrex::ignore_unused(yp);
68 #endif
69 
70 #ifndef WARPX_DIM_RZ
71  amrex::ignore_unused(n_rz_azimuthal_modes);
72 #endif
73 
74  const amrex::Real dxi = 1.0_rt/dx[0];
75  const amrex::Real dzi = 1.0_rt/dx[2];
76 #if (AMREX_SPACEDIM == 3)
77  const amrex::Real dyi = 1.0_rt/dx[1];
78 #endif
79 
80  const amrex::Real xmin = xyzmin[0];
81 #if (AMREX_SPACEDIM == 3)
82  const amrex::Real ymin = xyzmin[1];
83 #endif
84  const amrex::Real zmin = xyzmin[2];
85 
86  constexpr int zdir = (AMREX_SPACEDIM - 1);
87  constexpr int NODE = amrex::IndexType::NODE;
88  constexpr int CELL = amrex::IndexType::CELL;
89 
90  // --- Compute shape factors
91  // x direction
92  // Get particle position
93 #ifdef WARPX_DIM_RZ
94  const amrex::Real rp = std::sqrt(xp*xp + yp*yp);
95  const amrex::Real x = (rp - xmin)*dxi;
96 #else
97  const amrex::Real x = (xp-xmin)*dxi;
98 #endif
99 
100  // j_[eb][xyz] leftmost grid point in x that the particle touches for the centering of each current
101  // sx_[eb][xyz] shape factor along x for the centering of each current
102  // There are only two possible centerings, node or cell centered, so at most only two shape factor
103  // arrays will be needed.
104  amrex::Real sx_node[depos_order + 1];
105  amrex::Real sx_cell[depos_order + 1];
106  amrex::Real sx_node_galerkin[depos_order + 1 - galerkin_interpolation] = {0._rt};
107  amrex::Real sx_cell_galerkin[depos_order + 1 - galerkin_interpolation] = {0._rt};
108 
109  int j_node = 0;
110  int j_cell = 0;
111  int j_node_v = 0;
112  int j_cell_v = 0;
113  Compute_shape_factor< depos_order > const compute_shape_factor;
114  Compute_shape_factor<depos_order - galerkin_interpolation > const compute_shape_factor_galerkin;
115  if ((ey_type[0] == NODE) || (ez_type[0] == NODE) || (bx_type[0] == NODE)) {
116  j_node = compute_shape_factor(sx_node, x);
117  }
118  if ((ey_type[0] == CELL) || (ez_type[0] == CELL) || (bx_type[0] == CELL)) {
119  j_cell = compute_shape_factor(sx_cell, x - 0.5_rt);
120  }
121  if ((ex_type[0] == NODE) || (by_type[0] == NODE) || (bz_type[0] == NODE)) {
122  j_node_v = compute_shape_factor_galerkin(sx_node_galerkin, x);
123  }
124  if ((ex_type[0] == CELL) || (by_type[0] == CELL) || (bz_type[0] == CELL)) {
125  j_cell_v = compute_shape_factor_galerkin(sx_cell_galerkin, x - 0.5_rt);
126  }
127  const amrex::Real (&sx_ex)[depos_order + 1 - galerkin_interpolation] = ((ex_type[0] == NODE) ? sx_node_galerkin : sx_cell_galerkin);
128  const amrex::Real (&sx_ey)[depos_order + 1 ] = ((ey_type[0] == NODE) ? sx_node : sx_cell );
129  const amrex::Real (&sx_ez)[depos_order + 1 ] = ((ez_type[0] == NODE) ? sx_node : sx_cell );
130  const amrex::Real (&sx_bx)[depos_order + 1 ] = ((bx_type[0] == NODE) ? sx_node : sx_cell );
131  const amrex::Real (&sx_by)[depos_order + 1 - galerkin_interpolation] = ((by_type[0] == NODE) ? sx_node_galerkin : sx_cell_galerkin);
132  const amrex::Real (&sx_bz)[depos_order + 1 - galerkin_interpolation] = ((bz_type[0] == NODE) ? sx_node_galerkin : sx_cell_galerkin);
133  int const j_ex = ((ex_type[0] == NODE) ? j_node_v : j_cell_v);
134  int const j_ey = ((ey_type[0] == NODE) ? j_node : j_cell );
135  int const j_ez = ((ez_type[0] == NODE) ? j_node : j_cell );
136  int const j_bx = ((bx_type[0] == NODE) ? j_node : j_cell );
137  int const j_by = ((by_type[0] == NODE) ? j_node_v : j_cell_v);
138  int const j_bz = ((bz_type[0] == NODE) ? j_node_v : j_cell_v);
139 
140 #if (AMREX_SPACEDIM == 3)
141  // y direction
142  const amrex::Real y = (yp-ymin)*dyi;
143  amrex::Real sy_node[depos_order + 1];
144  amrex::Real sy_cell[depos_order + 1];
145  amrex::Real sy_node_v[depos_order + 1 - galerkin_interpolation];
146  amrex::Real sy_cell_v[depos_order + 1 - galerkin_interpolation];
147  int k_node = 0;
148  int k_cell = 0;
149  int k_node_v = 0;
150  int k_cell_v = 0;
151  if ((ex_type[1] == NODE) || (ez_type[1] == NODE) || (by_type[1] == NODE)) {
152  k_node = compute_shape_factor(sy_node, y);
153  }
154  if ((ex_type[1] == CELL) || (ez_type[1] == CELL) || (by_type[1] == CELL)) {
155  k_cell = compute_shape_factor(sy_cell, y - 0.5_rt);
156  }
157  if ((ey_type[1] == NODE) || (bx_type[1] == NODE) || (bz_type[1] == NODE)) {
158  k_node_v = compute_shape_factor_galerkin(sy_node_v, y);
159  }
160  if ((ey_type[1] == CELL) || (bx_type[1] == CELL) || (bz_type[1] == CELL)) {
161  k_cell_v = compute_shape_factor_galerkin(sy_cell_v, y - 0.5_rt);
162  }
163  const amrex::Real (&sy_ex)[depos_order + 1 ] = ((ex_type[1] == NODE) ? sy_node : sy_cell );
164  const amrex::Real (&sy_ey)[depos_order + 1 - galerkin_interpolation] = ((ey_type[1] == NODE) ? sy_node_v : sy_cell_v);
165  const amrex::Real (&sy_ez)[depos_order + 1 ] = ((ez_type[1] == NODE) ? sy_node : sy_cell );
166  const amrex::Real (&sy_bx)[depos_order + 1 - galerkin_interpolation] = ((bx_type[1] == NODE) ? sy_node_v : sy_cell_v);
167  const amrex::Real (&sy_by)[depos_order + 1 ] = ((by_type[1] == NODE) ? sy_node : sy_cell );
168  const amrex::Real (&sy_bz)[depos_order + 1 - galerkin_interpolation] = ((bz_type[1] == NODE) ? sy_node_v : sy_cell_v);
169  int const k_ex = ((ex_type[1] == NODE) ? k_node : k_cell );
170  int const k_ey = ((ey_type[1] == NODE) ? k_node_v : k_cell_v);
171  int const k_ez = ((ez_type[1] == NODE) ? k_node : k_cell );
172  int const k_bx = ((bx_type[1] == NODE) ? k_node_v : k_cell_v);
173  int const k_by = ((by_type[1] == NODE) ? k_node : k_cell );
174  int const k_bz = ((bz_type[1] == NODE) ? k_node_v : k_cell_v);
175 
176 #endif
177  // z direction
178  const amrex::Real z = (zp-zmin)*dzi;
179  amrex::Real sz_node[depos_order + 1];
180  amrex::Real sz_cell[depos_order + 1];
181  amrex::Real sz_node_v[depos_order + 1 - galerkin_interpolation];
182  amrex::Real sz_cell_v[depos_order + 1 - galerkin_interpolation];
183  int l_node = 0;
184  int l_cell = 0;
185  int l_node_v = 0;
186  int l_cell_v = 0;
187  if ((ex_type[zdir] == NODE) || (ey_type[zdir] == NODE) || (bz_type[zdir] == NODE)) {
188  l_node = compute_shape_factor(sz_node, z);
189  }
190  if ((ex_type[zdir] == CELL) || (ey_type[zdir] == CELL) || (bz_type[zdir] == CELL)) {
191  l_cell = compute_shape_factor(sz_cell, z - 0.5_rt);
192  }
193  if ((ez_type[zdir] == NODE) || (bx_type[zdir] == NODE) || (by_type[zdir] == NODE)) {
194  l_node_v = compute_shape_factor_galerkin(sz_node_v, z);
195  }
196  if ((ez_type[zdir] == CELL) || (bx_type[zdir] == CELL) || (by_type[zdir] == CELL)) {
197  l_cell_v = compute_shape_factor_galerkin(sz_cell_v, z - 0.5_rt);
198  }
199  const amrex::Real (&sz_ex)[depos_order + 1 ] = ((ex_type[zdir] == NODE) ? sz_node : sz_cell );
200  const amrex::Real (&sz_ey)[depos_order + 1 ] = ((ey_type[zdir] == NODE) ? sz_node : sz_cell );
201  const amrex::Real (&sz_ez)[depos_order + 1 - galerkin_interpolation] = ((ez_type[zdir] == NODE) ? sz_node_v : sz_cell_v);
202  const amrex::Real (&sz_bx)[depos_order + 1 - galerkin_interpolation] = ((bx_type[zdir] == NODE) ? sz_node_v : sz_cell_v);
203  const amrex::Real (&sz_by)[depos_order + 1 - galerkin_interpolation] = ((by_type[zdir] == NODE) ? sz_node_v : sz_cell_v);
204  const amrex::Real (&sz_bz)[depos_order + 1 ] = ((bz_type[zdir] == NODE) ? sz_node : sz_cell );
205  int const l_ex = ((ex_type[zdir] == NODE) ? l_node : l_cell );
206  int const l_ey = ((ey_type[zdir] == NODE) ? l_node : l_cell );
207  int const l_ez = ((ez_type[zdir] == NODE) ? l_node_v : l_cell_v);
208  int const l_bx = ((bx_type[zdir] == NODE) ? l_node_v : l_cell_v);
209  int const l_by = ((by_type[zdir] == NODE) ? l_node_v : l_cell_v);
210  int const l_bz = ((bz_type[zdir] == NODE) ? l_node : l_cell );
211 
212 
213  // Each field is gathered in a separate block of
214  // AMREX_SPACEDIM nested loops because the deposition
215  // order can differ for each component of each field
216  // when galerkin_interpolation is set to 1
217 #if (AMREX_SPACEDIM == 2)
218  // Gather field on particle Eyp from field on grid ey_arr
219  for (int iz=0; iz<=depos_order; iz++){
220  for (int ix=0; ix<=depos_order; ix++){
221  Eyp += sx_ey[ix]*sz_ey[iz]*
222  ey_arr(lo.x+j_ey+ix, lo.y+l_ey+iz, 0, 0);
223  }
224  }
225  // Gather field on particle Exp from field on grid ex_arr
226  // Gather field on particle Bzp from field on grid bz_arr
227  for (int iz=0; iz<=depos_order; iz++){
228  for (int ix=0; ix<=depos_order-galerkin_interpolation; ix++){
229  Exp += sx_ex[ix]*sz_ex[iz]*
230  ex_arr(lo.x+j_ex+ix, lo.y+l_ex+iz, 0, 0);
231  Bzp += sx_bz[ix]*sz_bz[iz]*
232  bz_arr(lo.x+j_bz+ix, lo.y+l_bz+iz, 0, 0);
233  }
234  }
235  // Gather field on particle Ezp from field on grid ez_arr
236  // Gather field on particle Bxp from field on grid bx_arr
237  for (int iz=0; iz<=depos_order-galerkin_interpolation; iz++){
238  for (int ix=0; ix<=depos_order; ix++){
239  Ezp += sx_ez[ix]*sz_ez[iz]*
240  ez_arr(lo.x+j_ez+ix, lo.y+l_ez+iz, 0, 0);
241  Bxp += sx_bx[ix]*sz_bx[iz]*
242  bx_arr(lo.x+j_bx+ix, lo.y+l_bx+iz, 0, 0);
243  }
244  }
245  // Gather field on particle Byp from field on grid by_arr
246  for (int iz=0; iz<=depos_order-galerkin_interpolation; iz++){
247  for (int ix=0; ix<=depos_order-galerkin_interpolation; ix++){
248  Byp += sx_by[ix]*sz_by[iz]*
249  by_arr(lo.x+j_by+ix, lo.y+l_by+iz, 0, 0);
250  }
251  }
252 
253 #ifdef WARPX_DIM_RZ
254 
255  amrex::Real costheta;
256  amrex::Real sintheta;
257  if (rp > 0.) {
258  costheta = xp/rp;
259  sintheta = yp/rp;
260  } else {
261  costheta = 1.;
262  sintheta = 0.;
263  }
264  const Complex xy0 = Complex{costheta, -sintheta};
265  Complex xy = xy0;
266 
267  for (int imode=1 ; imode < n_rz_azimuthal_modes ; imode++) {
268 
269  // Gather field on particle Eyp from field on grid ey_arr
270  for (int iz=0; iz<=depos_order; iz++){
271  for (int ix=0; ix<=depos_order; ix++){
272  const amrex::Real dEy = (+ ey_arr(lo.x+j_ey+ix, lo.y+l_ey+iz, 0, 2*imode-1)*xy.real()
273  - ey_arr(lo.x+j_ey+ix, lo.y+l_ey+iz, 0, 2*imode)*xy.imag());
274  Eyp += sx_ey[ix]*sz_ey[iz]*dEy;
275  }
276  }
277  // Gather field on particle Exp from field on grid ex_arr
278  // Gather field on particle Bzp from field on grid bz_arr
279  for (int iz=0; iz<=depos_order; iz++){
280  for (int ix=0; ix<=depos_order-galerkin_interpolation; ix++){
281  const amrex::Real dEx = (+ ex_arr(lo.x+j_ex+ix, lo.y+l_ex+iz, 0, 2*imode-1)*xy.real()
282  - ex_arr(lo.x+j_ex+ix, lo.y+l_ex+iz, 0, 2*imode)*xy.imag());
283  Exp += sx_ex[ix]*sz_ex[iz]*dEx;
284  const amrex::Real dBz = (+ bz_arr(lo.x+j_bz+ix, lo.y+l_bz+iz, 0, 2*imode-1)*xy.real()
285  - bz_arr(lo.x+j_bz+ix, lo.y+l_bz+iz, 0, 2*imode)*xy.imag());
286  Bzp += sx_bz[ix]*sz_bz[iz]*dBz;
287  }
288  }
289  // Gather field on particle Ezp from field on grid ez_arr
290  // Gather field on particle Bxp from field on grid bx_arr
291  for (int iz=0; iz<=depos_order-galerkin_interpolation; iz++){
292  for (int ix=0; ix<=depos_order; ix++){
293  const amrex::Real dEz = (+ ez_arr(lo.x+j_ez+ix, lo.y+l_ez+iz, 0, 2*imode-1)*xy.real()
294  - ez_arr(lo.x+j_ez+ix, lo.y+l_ez+iz, 0, 2*imode)*xy.imag());
295  Ezp += sx_ez[ix]*sz_ez[iz]*dEz;
296  const amrex::Real dBx = (+ bx_arr(lo.x+j_bx+ix, lo.y+l_bx+iz, 0, 2*imode-1)*xy.real()
297  - bx_arr(lo.x+j_bx+ix, lo.y+l_bx+iz, 0, 2*imode)*xy.imag());
298  Bxp += sx_bx[ix]*sz_bx[iz]*dBx;
299  }
300  }
301  // Gather field on particle Byp from field on grid by_arr
302  for (int iz=0; iz<=depos_order-galerkin_interpolation; iz++){
303  for (int ix=0; ix<=depos_order-galerkin_interpolation; ix++){
304  const amrex::Real dBy = (+ by_arr(lo.x+j_by+ix, lo.y+l_by+iz, 0, 2*imode-1)*xy.real()
305  - by_arr(lo.x+j_by+ix, lo.y+l_by+iz, 0, 2*imode)*xy.imag());
306  Byp += sx_by[ix]*sz_by[iz]*dBy;
307  }
308  }
309  xy = xy*xy0;
310  }
311 
312  // Convert Exp and Eyp (which are actually Er and Etheta) to Ex and Ey
313  const amrex::Real Exp_save = Exp;
314  Exp = costheta*Exp - sintheta*Eyp;
315  Eyp = costheta*Eyp + sintheta*Exp_save;
316  const amrex::Real Bxp_save = Bxp;
317  Bxp = costheta*Bxp - sintheta*Byp;
318  Byp = costheta*Byp + sintheta*Bxp_save;
319 #endif
320 
321 #else // (AMREX_SPACEDIM == 3)
322  // Gather field on particle Exp from field on grid ex_arr
323  for (int iz=0; iz<=depos_order; iz++){
324  for (int iy=0; iy<=depos_order; iy++){
325  for (int ix=0; ix<= depos_order - galerkin_interpolation; ix++){
326  Exp += sx_ex[ix]*sy_ex[iy]*sz_ex[iz]*
327  ex_arr(lo.x+j_ex+ix, lo.y+k_ex+iy, lo.z+l_ex+iz);
328  }
329  }
330  }
331  // Gather field on particle Eyp from field on grid ey_arr
332  for (int iz=0; iz<=depos_order; iz++){
333  for (int iy=0; iy<= depos_order - galerkin_interpolation; iy++){
334  for (int ix=0; ix<=depos_order; ix++){
335  Eyp += sx_ey[ix]*sy_ey[iy]*sz_ey[iz]*
336  ey_arr(lo.x+j_ey+ix, lo.y+k_ey+iy, lo.z+l_ey+iz);
337  }
338  }
339  }
340  // Gather field on particle Ezp from field on grid ez_arr
341  for (int iz=0; iz<= depos_order - galerkin_interpolation; iz++){
342  for (int iy=0; iy<=depos_order; iy++){
343  for (int ix=0; ix<=depos_order; ix++){
344  Ezp += sx_ez[ix]*sy_ez[iy]*sz_ez[iz]*
345  ez_arr(lo.x+j_ez+ix, lo.y+k_ez+iy, lo.z+l_ez+iz);
346  }
347  }
348  }
349  // Gather field on particle Bzp from field on grid bz_arr
350  for (int iz=0; iz<=depos_order; iz++){
351  for (int iy=0; iy<= depos_order - galerkin_interpolation; iy++){
352  for (int ix=0; ix<= depos_order - galerkin_interpolation; ix++){
353  Bzp += sx_bz[ix]*sy_bz[iy]*sz_bz[iz]*
354  bz_arr(lo.x+j_bz+ix, lo.y+k_bz+iy, lo.z+l_bz+iz);
355  }
356  }
357  }
358  // Gather field on particle Byp from field on grid by_arr
359  for (int iz=0; iz<= depos_order - galerkin_interpolation; iz++){
360  for (int iy=0; iy<=depos_order; iy++){
361  for (int ix=0; ix<= depos_order - galerkin_interpolation; ix++){
362  Byp += sx_by[ix]*sy_by[iy]*sz_by[iz]*
363  by_arr(lo.x+j_by+ix, lo.y+k_by+iy, lo.z+l_by+iz);
364  }
365  }
366  }
367  // Gather field on particle Bxp from field on grid bx_arr
368  for (int iz=0; iz<= depos_order - galerkin_interpolation; iz++){
369  for (int iy=0; iy<= depos_order - galerkin_interpolation; iy++){
370  for (int ix=0; ix<=depos_order; ix++){
371  Bxp += sx_bx[ix]*sy_bx[iy]*sz_bx[iz]*
372  bx_arr(lo.x+j_bx+ix, lo.y+k_bx+iy, lo.z+l_bx+iz);
373  }
374  }
375  }
376 #endif
377 }
378 
395 template <int depos_order, int lower_in_v>
396 void doGatherShapeN(const GetParticlePosition& getPosition,
397  const GetExternalEField& getExternalE, const GetExternalBField& getExternalB,
398  amrex::ParticleReal * const Exp, amrex::ParticleReal * const Eyp,
399  amrex::ParticleReal * const Ezp, amrex::ParticleReal * const Bxp,
400  amrex::ParticleReal * const Byp, amrex::ParticleReal * const Bzp,
401  amrex::FArrayBox const * const exfab,
402  amrex::FArrayBox const * const eyfab,
403  amrex::FArrayBox const * const ezfab,
404  amrex::FArrayBox const * const bxfab,
405  amrex::FArrayBox const * const byfab,
406  amrex::FArrayBox const * const bzfab,
407  const long np_to_gather,
408  const std::array<amrex::Real, 3>& dx,
409  const std::array<amrex::Real, 3> xyzmin,
410  const amrex::Dim3 lo,
411  const int n_rz_azimuthal_modes)
412 {
413 
414  amrex::GpuArray<amrex::Real, 3> dx_arr = {dx[0], dx[1], dx[2]};
415  amrex::GpuArray<amrex::Real, 3> xyzmin_arr = {xyzmin[0], xyzmin[1], xyzmin[2]};
416 
417  amrex::Array4<const amrex::Real> const& ex_arr = exfab->array();
418  amrex::Array4<const amrex::Real> const& ey_arr = eyfab->array();
419  amrex::Array4<const amrex::Real> const& ez_arr = ezfab->array();
420  amrex::Array4<const amrex::Real> const& bx_arr = bxfab->array();
421  amrex::Array4<const amrex::Real> const& by_arr = byfab->array();
422  amrex::Array4<const amrex::Real> const& bz_arr = bzfab->array();
423 
424  amrex::IndexType const ex_type = exfab->box().ixType();
425  amrex::IndexType const ey_type = eyfab->box().ixType();
426  amrex::IndexType const ez_type = ezfab->box().ixType();
427  amrex::IndexType const bx_type = bxfab->box().ixType();
428  amrex::IndexType const by_type = byfab->box().ixType();
429  amrex::IndexType const bz_type = bzfab->box().ixType();
430 
431  // Loop over particles and gather fields from
432  // {e,b}{x,y,z}_arr to {E,B}{xyz}p.
433  amrex::ParallelFor(
434  np_to_gather,
435  [=] AMREX_GPU_DEVICE (long ip) {
436 
437  amrex::ParticleReal xp, yp, zp;
438  getPosition(ip, xp, yp, zp);
439  getExternalE(ip, Exp[ip], Eyp[ip], Ezp[ip]);
440  getExternalB(ip, Bxp[ip], Byp[ip], Bzp[ip]);
441 
442  doGatherShapeN<depos_order, lower_in_v>(
443  xp, yp, zp, Exp[ip], Eyp[ip], Ezp[ip], Bxp[ip], Byp[ip], Bzp[ip],
444  ex_arr, ey_arr, ez_arr, bx_arr, by_arr, bz_arr,
445  ex_type, ey_type, ez_type, bx_type, by_type, bz_type,
446  dx_arr, xyzmin_arr, lo, n_rz_azimuthal_modes);
447  }
448  );
449 }
450 
468 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
469 void doGatherShapeN (const amrex::ParticleReal xp,
470  const amrex::ParticleReal yp,
471  const amrex::ParticleReal zp,
472  amrex::ParticleReal& Exp,
473  amrex::ParticleReal& Eyp,
474  amrex::ParticleReal& Ezp,
475  amrex::ParticleReal& Bxp,
476  amrex::ParticleReal& Byp,
477  amrex::ParticleReal& Bzp,
478  amrex::Array4<amrex::Real const> const& ex_arr,
479  amrex::Array4<amrex::Real const> const& ey_arr,
480  amrex::Array4<amrex::Real const> const& ez_arr,
481  amrex::Array4<amrex::Real const> const& bx_arr,
482  amrex::Array4<amrex::Real const> const& by_arr,
483  amrex::Array4<amrex::Real const> const& bz_arr,
484  const amrex::IndexType ex_type,
485  const amrex::IndexType ey_type,
486  const amrex::IndexType ez_type,
487  const amrex::IndexType bx_type,
488  const amrex::IndexType by_type,
489  const amrex::IndexType bz_type,
490  const amrex::GpuArray<amrex::Real, 3>& dx_arr,
491  const amrex::GpuArray<amrex::Real, 3>& xyzmin_arr,
492  const amrex::Dim3& lo,
493  const int n_rz_azimuthal_modes,
494  const int nox,
495  const bool galerkin_interpolation)
496 {
497  if (galerkin_interpolation) {
498  if (nox == 1) {
499  doGatherShapeN<1,1>(xp, yp, zp, Exp, Eyp, Ezp, Bxp, Byp, Bzp,
500  ex_arr, ey_arr, ez_arr, bx_arr, by_arr, bz_arr,
501  ex_type, ey_type, ez_type, bx_type, by_type, bz_type,
502  dx_arr, xyzmin_arr, lo, n_rz_azimuthal_modes);
503  } else if (nox == 2) {
504  doGatherShapeN<2,1>(xp, yp, zp, Exp, Eyp, Ezp, Bxp, Byp, Bzp,
505  ex_arr, ey_arr, ez_arr, bx_arr, by_arr, bz_arr,
506  ex_type, ey_type, ez_type, bx_type, by_type, bz_type,
507  dx_arr, xyzmin_arr, lo, n_rz_azimuthal_modes);
508  } else if (nox == 3) {
509  doGatherShapeN<3,1>(xp, yp, zp, Exp, Eyp, Ezp, Bxp, Byp, Bzp,
510  ex_arr, ey_arr, ez_arr, bx_arr, by_arr, bz_arr,
511  ex_type, ey_type, ez_type, bx_type, by_type, bz_type,
512  dx_arr, xyzmin_arr, lo, n_rz_azimuthal_modes);
513  }
514  } else {
515  if (nox == 1) {
516  doGatherShapeN<1,0>(xp, yp, zp, Exp, Eyp, Ezp, Bxp, Byp, Bzp,
517  ex_arr, ey_arr, ez_arr, bx_arr, by_arr, bz_arr,
518  ex_type, ey_type, ez_type, bx_type, by_type, bz_type,
519  dx_arr, xyzmin_arr, lo, n_rz_azimuthal_modes);
520  } else if (nox == 2) {
521  doGatherShapeN<2,0>(xp, yp, zp, Exp, Eyp, Ezp, Bxp, Byp, Bzp,
522  ex_arr, ey_arr, ez_arr, bx_arr, by_arr, bz_arr,
523  ex_type, ey_type, ez_type, bx_type, by_type, bz_type,
524  dx_arr, xyzmin_arr, lo, n_rz_azimuthal_modes);
525  } else if (nox == 3) {
526  doGatherShapeN<3,0>(xp, yp, zp, Exp, Eyp, Ezp, Bxp, Byp, Bzp,
527  ex_arr, ey_arr, ez_arr, bx_arr, by_arr, bz_arr,
528  ex_type, ey_type, ez_type, bx_type, by_type, bz_type,
529  dx_arr, xyzmin_arr, lo, n_rz_azimuthal_modes);
530  }
531  }
532 }
533 
534 #endif // FIELDGATHER_H_
amrex::GpuComplex< amrex::Real > Complex
Definition: WarpX_Complex.H:22
def x
Definition: read_lab_particles.py:25
int dx
Definition: compute_domain.py:35
def z
Definition: read_lab_particles.py:26
Functor that can be used to assign the external B field to a particle inside a ParallelFor kernel...
Definition: GetExternalFields.H:159
Definition: ShapeFactors.H:22
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void doGatherShapeN(const amrex::ParticleReal xp, const amrex::ParticleReal yp, const amrex::ParticleReal zp, amrex::ParticleReal &Exp, amrex::ParticleReal &Eyp, amrex::ParticleReal &Ezp, amrex::ParticleReal &Bxp, amrex::ParticleReal &Byp, amrex::ParticleReal &Bzp, amrex::Array4< amrex::Real const > const &ex_arr, amrex::Array4< amrex::Real const > const &ey_arr, amrex::Array4< amrex::Real const > const &ez_arr, amrex::Array4< amrex::Real const > const &bx_arr, amrex::Array4< amrex::Real const > const &by_arr, amrex::Array4< amrex::Real const > const &bz_arr, const amrex::IndexType ex_type, const amrex::IndexType ey_type, const amrex::IndexType ez_type, const amrex::IndexType bx_type, const amrex::IndexType by_type, const amrex::IndexType bz_type, const amrex::GpuArray< amrex::Real, 3 > &dx, const amrex::GpuArray< amrex::Real, 3 > &xyzmin, const amrex::Dim3 &lo, const int n_rz_azimuthal_modes)
Field gather for a single particle.
Definition: FieldGather.H:38
Functor that can be used to extract the positions of the macroparticles inside a ParallelFor kernel...
Definition: GetAndSetPosition.H:48
Functor that can be used to assign the external E field to a particle inside a ParallelFor kernel...
Definition: GetExternalFields.H:149
Definition: BreitWheelerEngineWrapper.H:35