WarpX
ScalarFieldGather.H
Go to the documentation of this file.
1 /* Copyright 2021 Modern Electron
2  *
3  * This file is part of WarpX.
4  *
5  * License: BSD-3-Clause-LBNL
6  */
7 #ifndef SCALARFIELDGATHER_H_
8 #define SCALARFIELDGATHER_H_
9 
21 AMREX_GPU_HOST_DEVICE AMREX_INLINE
22 void compute_weights_nodal (const amrex::ParticleReal xp,
23  const amrex::ParticleReal yp,
24  const amrex::ParticleReal zp,
25  amrex::GpuArray<amrex::Real,AMREX_SPACEDIM> const& plo,
26  amrex::GpuArray<amrex::Real,AMREX_SPACEDIM> const& dxi,
27  int& i, int& j, int& k, amrex::Real W[AMREX_SPACEDIM][2]) noexcept
28 {
29 #if (defined WARPX_DIM_3D)
30  amrex::Real x = (xp - plo[0]) * dxi[0];
31  amrex::Real y = (yp - plo[1]) * dxi[1];
32  amrex::Real z = (zp - plo[2]) * dxi[2];
33 
34  i = static_cast<int>(amrex::Math::floor(x));
35  j = static_cast<int>(amrex::Math::floor(y));
36  k = static_cast<int>(amrex::Math::floor(z));
37 
38  W[0][1] = x - i;
39  W[1][1] = y - j;
40  W[2][1] = z - k;
41 
42  W[0][0] = 1.0 - W[0][1];
43  W[1][0] = 1.0 - W[1][1];
44  W[2][0] = 1.0 - W[2][1];
45 #elif (defined WARPX_DIM_XZ)
46  amrex::Real x = (xp - plo[0]) * dxi[0];
47  amrex::Real z = (zp - plo[1]) * dxi[1];
48 
49  i = static_cast<int>(amrex::Math::floor(x));
50  j = static_cast<int>(amrex::Math::floor(z));
51  k = 0;
52 
53  W[0][1] = x - i;
54  W[1][1] = z - j;
55 
56  W[0][0] = 1.0 - W[0][1];
57  W[1][0] = 1.0 - W[1][1];
58 
59  amrex::ignore_unused(yp);
60 #else
61  amrex::ignore_unused(xp, yp, zp, plo, dxi, i, j, k, W);
62  amrex::Abort("Error: compute_weights not yet implemented in RZ");
63 #endif
64 }
65 
73 AMREX_GPU_HOST_DEVICE AMREX_INLINE
74 amrex::Real interp_field_nodal (int i, int j, int k,
75  const amrex::Real W[AMREX_SPACEDIM][2],
76  amrex::Array4<const amrex::Real> const& scalar_field) noexcept
77 {
78  amrex::Real value = 0;
79 #if (defined WARPX_DIM_3D)
80  value += scalar_field(i, j , k ) * W[0][0] * W[1][0] * W[2][0];
81  value += scalar_field(i+1, j , k ) * W[0][1] * W[1][0] * W[2][0];
82  value += scalar_field(i, j+1, k ) * W[0][0] * W[1][1] * W[2][0];
83  value += scalar_field(i+1, j+1, k ) * W[0][1] * W[1][1] * W[2][0];
84  value += scalar_field(i, j , k+1) * W[0][0] * W[1][0] * W[2][1];
85  value += scalar_field(i+1, j , k+1) * W[0][1] * W[1][0] * W[2][1];
86  value += scalar_field(i , j+1, k+1) * W[0][0] * W[1][1] * W[2][1];
87  value += scalar_field(i+1, j+1, k+1) * W[0][1] * W[1][1] * W[2][1];
88 #elif (defined WARPX_DIM_XZ)
89  value += scalar_field(i, j , k) * W[0][0] * W[1][0];
90  value += scalar_field(i+1, j , k) * W[0][1] * W[1][0];
91  value += scalar_field(i, j+1, k) * W[0][0] * W[1][1];
92  value += scalar_field(i+1, j+1, k) * W[0][1] * W[1][1];
93 #else
94  amrex::ignore_unused(i, j, k, W, scalar_field);
95  amrex::Abort("Error: interp_field not yet implemented in RZ");
96 #endif
97  return value;
98 }
99 
109 AMREX_GPU_HOST_DEVICE AMREX_INLINE
110 amrex::Real doGatherScalarFieldNodal (const amrex::ParticleReal xp,
111  const amrex::ParticleReal yp,
112  const amrex::ParticleReal zp,
113  amrex::Array4<const amrex::Real> const& scalar_field,
114  amrex::GpuArray<amrex::Real,AMREX_SPACEDIM> const& dxi,
115  amrex::GpuArray<amrex::Real,AMREX_SPACEDIM> const& lo) noexcept
116 {
117  // first find the weight of surrounding nodes to use during interpolation
118  int ii, jj, kk;
119  amrex::Real W[AMREX_SPACEDIM][2];
120  compute_weights_nodal(xp, yp, zp, lo, dxi, ii, jj, kk, W);
121 
122  return interp_field_nodal(ii, jj, kk, W, scalar_field);
123 }
124 #endif // SCALARFIELDGATHER_H_
def x
Definition: read_lab_particles.py:25
def z
Definition: read_lab_particles.py:26
AMREX_GPU_HOST_DEVICE AMREX_INLINE amrex::Real doGatherScalarFieldNodal(const amrex::ParticleReal xp, const amrex::ParticleReal yp, const amrex::ParticleReal zp, amrex::Array4< const amrex::Real > const &scalar_field, amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > const &dxi, amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > const &lo) noexcept
Scalar field gather for a single particle. The field has to be defined at the cell nodes (see https:/...
Definition: ScalarFieldGather.H:110
ii
Definition: check_interp_points_and_weights.py:145
i
Definition: check_interp_points_and_weights.py:171
AMREX_GPU_HOST_DEVICE AMREX_INLINE amrex::Real interp_field_nodal(int i, int j, int k, const amrex::Real W[AMREX_SPACEDIM][2], amrex::Array4< const amrex::Real > const &scalar_field) noexcept
Interpolate nodal field value based on surrounding indices and weights.
Definition: ScalarFieldGather.H:74
AMREX_GPU_HOST_DEVICE AMREX_INLINE void compute_weights_nodal(const amrex::ParticleReal xp, const amrex::ParticleReal yp, const amrex::ParticleReal zp, amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > const &plo, amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > const &dxi, int &i, int &j, int &k, amrex::Real W[AMREX_SPACEDIM][2]) noexcept
Compute weight of each surrounding node in interpolating a nodal field to the given coordinates...
Definition: ScalarFieldGather.H:22
jj
Definition: check_interp_points_and_weights.py:157
value
Definition: updateAMReX.py:125