8 #ifndef CURRENTDEPOSITION_H_ 9 #define CURRENTDEPOSITION_H_ 20 #include <AMReX_Arena.H> 21 #include <AMReX_Array4.H> 22 #include <AMReX_REAL.H> 52 template <
int depos_order>
54 const amrex::ParticleReal *
const wp,
55 const amrex::ParticleReal *
const uxp,
56 const amrex::ParticleReal *
const uyp,
57 const amrex::ParticleReal *
const uzp,
58 const int *
const ion_lev,
59 amrex::FArrayBox& jx_fab,
60 amrex::FArrayBox& jy_fab,
61 amrex::FArrayBox& jz_fab,
62 const long np_to_depose,
63 const amrex::Real relative_t,
64 const std::array<amrex::Real,3>&
dx,
65 const std::array<amrex::Real,3>& xyzmin,
68 const int n_rz_azimuthal_modes,
70 const long load_balance_costs_update_algo)
72 #if !defined(WARPX_DIM_RZ) 73 amrex::ignore_unused(n_rz_azimuthal_modes);
76 #if !defined(AMREX_USE_GPU) 77 amrex::ignore_unused(cost, load_balance_costs_update_algo);
82 const bool do_ionization = ion_lev;
83 const amrex::Real dxi = 1.0_rt/dx[0];
84 const amrex::Real dzi = 1.0_rt/dx[2];
85 #if (AMREX_SPACEDIM == 2) 86 const amrex::Real invvol = dxi*dzi;
87 #elif (defined WARPX_DIM_3D) 88 const amrex::Real dyi = 1.0_rt/dx[1];
89 const amrex::Real invvol = dxi*dyi*dzi;
92 const amrex::Real xmin = xyzmin[0];
93 #if (defined WARPX_DIM_3D) 94 const amrex::Real ymin = xyzmin[1];
96 const amrex::Real zmin = xyzmin[2];
98 const amrex::Real clightsq = 1.0_rt/PhysConst::c/PhysConst::c;
100 amrex::Array4<amrex::Real>
const& jx_arr = jx_fab.array();
101 amrex::Array4<amrex::Real>
const& jy_arr = jy_fab.array();
102 amrex::Array4<amrex::Real>
const& jz_arr = jz_fab.array();
103 amrex::IntVect
const jx_type = jx_fab.box().type();
104 amrex::IntVect
const jy_type = jy_fab.box().type();
105 amrex::IntVect
const jz_type = jz_fab.box().type();
107 constexpr
int zdir = (AMREX_SPACEDIM - 1);
108 constexpr
int NODE = amrex::IndexType::NODE;
109 constexpr
int CELL = amrex::IndexType::CELL;
112 #if defined(WARPX_USE_GPUCLOCK) 113 amrex::Real* cost_real =
nullptr;
115 cost_real = (amrex::Real *) amrex::The_Managed_Arena()->alloc(
sizeof(amrex::Real));
121 [=] AMREX_GPU_DEVICE (
long ip) {
122 #if defined(WARPX_USE_GPUCLOCK) 123 KernelTimer kernelTimer(cost && load_balance_costs_update_algo
128 const amrex::Real gaminv = 1.0_rt/std::sqrt(1.0_rt + uxp[ip]*uxp[ip]*clightsq
129 + uyp[ip]*uyp[ip]*clightsq
130 + uzp[ip]*uzp[ip]*clightsq);
131 amrex::Real wq = q*wp[ip];
136 amrex::ParticleReal xp, yp, zp;
137 GetPosition(ip, xp, yp, zp);
139 const amrex::Real vx = uxp[ip]*gaminv;
140 const amrex::Real vy = uyp[ip]*gaminv;
141 const amrex::Real vz = uzp[ip]*gaminv;
143 #if (defined WARPX_DIM_RZ) 146 const amrex::Real xpmid = xp + relative_t*vx;
147 const amrex::Real ypmid = yp + relative_t*vy;
148 const amrex::Real rpmid = std::sqrt(xpmid*xpmid + ypmid*ypmid);
149 amrex::Real costheta;
150 amrex::Real sintheta;
152 costheta = xpmid/rpmid;
153 sintheta = ypmid/rpmid;
159 const amrex::Real wqx = wq*invvol*(+vx*costheta + vy*sintheta);
160 const amrex::Real wqy = wq*invvol*(-vx*sintheta + vy*costheta);
162 const amrex::Real wqx = wq*invvol*vx;
163 const amrex::Real wqy = wq*invvol*vy;
165 const amrex::Real wqz = wq*invvol*vz;
170 #if (defined WARPX_DIM_RZ) 172 const double xmid = (rpmid - xmin)*dxi;
174 const double xmid = ((xp - xmin) + relative_t*vx)*dxi;
181 double sx_node[depos_order + 1] = {0.};
182 double sx_cell[depos_order + 1] = {0.};
186 if (jx_type[0] == NODE || jy_type[0] == NODE || jz_type[0] == NODE) {
187 j_node = compute_shape_factor(sx_node, xmid);
189 if (jx_type[0] == CELL || jy_type[0] == CELL || jz_type[0] == CELL) {
190 j_cell = compute_shape_factor(sx_cell, xmid - 0.5);
193 amrex::Real sx_jx[depos_order + 1] = {0._rt};
194 amrex::Real sx_jy[depos_order + 1] = {0._rt};
195 amrex::Real sx_jz[depos_order + 1] = {0._rt};
196 for (
int ix=0; ix<=depos_order; ix++)
198 sx_jx[ix] = ((jx_type[0] == NODE) ? amrex::Real(sx_node[ix]) : amrex::Real(sx_cell[ix]));
199 sx_jy[ix] = ((jy_type[0] == NODE) ? amrex::Real(sx_node[ix]) : amrex::Real(sx_cell[ix]));
200 sx_jz[ix] = ((jz_type[0] == NODE) ? amrex::Real(sx_node[ix]) : amrex::Real(sx_cell[ix]));
203 int const j_jx = ((jx_type[0] == NODE) ? j_node : j_cell);
204 int const j_jy = ((jy_type[0] == NODE) ? j_node : j_cell);
205 int const j_jz = ((jz_type[0] == NODE) ? j_node : j_cell);
207 #if (defined WARPX_DIM_3D) 210 const double ymid = ( (yp - ymin) + relative_t*vy )*dyi;
211 double sy_node[depos_order + 1] = {0.};
212 double sy_cell[depos_order + 1] = {0.};
215 if (jx_type[1] == NODE || jy_type[1] == NODE || jz_type[1] == NODE) {
216 k_node = compute_shape_factor(sy_node, ymid);
218 if (jx_type[1] == CELL || jy_type[1] == CELL || jz_type[1] == CELL) {
219 k_cell = compute_shape_factor(sy_cell, ymid - 0.5);
221 amrex::Real sy_jx[depos_order + 1] = {0._rt};
222 amrex::Real sy_jy[depos_order + 1] = {0._rt};
223 amrex::Real sy_jz[depos_order + 1] = {0._rt};
224 for (
int iy=0; iy<=depos_order; iy++)
226 sy_jx[iy] = ((jx_type[1] == NODE) ? amrex::Real(sy_node[iy]) : amrex::Real(sy_cell[iy]));
227 sy_jy[iy] = ((jy_type[1] == NODE) ? amrex::Real(sy_node[iy]) : amrex::Real(sy_cell[iy]));
228 sy_jz[iy] = ((jz_type[1] == NODE) ? amrex::Real(sy_node[iy]) : amrex::Real(sy_cell[iy]));
230 int const k_jx = ((jx_type[1] == NODE) ? k_node : k_cell);
231 int const k_jy = ((jy_type[1] == NODE) ? k_node : k_cell);
232 int const k_jz = ((jz_type[1] == NODE) ? k_node : k_cell);
237 const double zmid = ((zp - zmin) + relative_t*vz)*dzi;
238 double sz_node[depos_order + 1] = {0.};
239 double sz_cell[depos_order + 1] = {0.};
242 if (jx_type[zdir] == NODE || jy_type[zdir] == NODE || jz_type[zdir] == NODE) {
243 l_node = compute_shape_factor(sz_node, zmid);
245 if (jx_type[zdir] == CELL || jy_type[zdir] == CELL || jz_type[zdir] == CELL) {
246 l_cell = compute_shape_factor(sz_cell, zmid - 0.5);
248 amrex::Real sz_jx[depos_order + 1] = {0._rt};
249 amrex::Real sz_jy[depos_order + 1] = {0._rt};
250 amrex::Real sz_jz[depos_order + 1] = {0._rt};
251 for (
int iz=0; iz<=depos_order; iz++)
253 sz_jx[iz] = ((jx_type[zdir] == NODE) ? amrex::Real(sz_node[iz]) : amrex::Real(sz_cell[iz]));
254 sz_jy[iz] = ((jy_type[zdir] == NODE) ? amrex::Real(sz_node[iz]) : amrex::Real(sz_cell[iz]));
255 sz_jz[iz] = ((jz_type[zdir] == NODE) ? amrex::Real(sz_node[iz]) : amrex::Real(sz_cell[iz]));
257 int const l_jx = ((jx_type[zdir] == NODE) ? l_node : l_cell);
258 int const l_jy = ((jy_type[zdir] == NODE) ? l_node : l_cell);
259 int const l_jz = ((jz_type[zdir] == NODE) ? l_node : l_cell);
262 #if (defined WARPX_DIM_XZ) || (defined WARPX_DIM_RZ) 263 for (
int iz=0; iz<=depos_order; iz++){
264 for (
int ix=0; ix<=depos_order; ix++){
265 amrex::Gpu::Atomic::AddNoRet(
266 &jx_arr(lo.x+j_jx+ix, lo.y+l_jx+iz, 0, 0),
267 sx_jx[ix]*sz_jx[iz]*wqx);
268 amrex::Gpu::Atomic::AddNoRet(
269 &jy_arr(lo.x+j_jy+ix, lo.y+l_jy+iz, 0, 0),
270 sx_jy[ix]*sz_jy[iz]*wqy);
271 amrex::Gpu::Atomic::AddNoRet(
272 &jz_arr(lo.x+j_jz+ix, lo.y+l_jz+iz, 0, 0),
273 sx_jz[ix]*sz_jz[iz]*wqz);
274 #if (defined WARPX_DIM_RZ) 276 for (
int imode=1 ; imode < n_rz_azimuthal_modes ; imode++) {
278 amrex::Gpu::Atomic::AddNoRet( &jx_arr(lo.x+j_jx+ix, lo.y+l_jx+iz, 0, 2*imode-1), 2._rt*sx_jx[ix]*sz_jx[iz]*wqx*xy.real());
279 amrex::Gpu::Atomic::AddNoRet( &jx_arr(lo.x+j_jx+ix, lo.y+l_jx+iz, 0, 2*imode ), 2._rt*sx_jx[ix]*sz_jx[iz]*wqx*xy.imag());
280 amrex::Gpu::Atomic::AddNoRet( &jy_arr(lo.x+j_jy+ix, lo.y+l_jy+iz, 0, 2*imode-1), 2._rt*sx_jy[ix]*sz_jy[iz]*wqy*xy.real());
281 amrex::Gpu::Atomic::AddNoRet( &jy_arr(lo.x+j_jy+ix, lo.y+l_jy+iz, 0, 2*imode ), 2._rt*sx_jy[ix]*sz_jy[iz]*wqy*xy.imag());
282 amrex::Gpu::Atomic::AddNoRet( &jz_arr(lo.x+j_jz+ix, lo.y+l_jz+iz, 0, 2*imode-1), 2._rt*sx_jz[ix]*sz_jz[iz]*wqz*xy.real());
283 amrex::Gpu::Atomic::AddNoRet( &jz_arr(lo.x+j_jz+ix, lo.y+l_jz+iz, 0, 2*imode ), 2._rt*sx_jz[ix]*sz_jz[iz]*wqz*xy.imag());
289 #elif (defined WARPX_DIM_3D) 290 for (
int iz=0; iz<=depos_order; iz++){
291 for (
int iy=0; iy<=depos_order; iy++){
292 for (
int ix=0; ix<=depos_order; ix++){
293 amrex::Gpu::Atomic::AddNoRet(
294 &jx_arr(lo.x+j_jx+ix, lo.y+k_jx+iy, lo.z+l_jx+iz),
295 sx_jx[ix]*sy_jx[iy]*sz_jx[iz]*wqx);
296 amrex::Gpu::Atomic::AddNoRet(
297 &jy_arr(lo.x+j_jy+ix, lo.y+k_jy+iy, lo.z+l_jy+iz),
298 sx_jy[ix]*sy_jy[iy]*sz_jy[iz]*wqy);
299 amrex::Gpu::Atomic::AddNoRet(
300 &jz_arr(lo.x+j_jz+ix, lo.y+k_jz+iy, lo.z+l_jz+iz),
301 sx_jz[ix]*sy_jz[iy]*sz_jz[iz]*wqz);
308 #if defined(WARPX_USE_GPUCLOCK) 310 amrex::Gpu::streamSynchronize();
312 amrex::The_Managed_Arena()->free(cost_real);
340 template <
int depos_order>
342 const amrex::ParticleReal *
const wp,
343 const amrex::ParticleReal *
const uxp,
344 const amrex::ParticleReal *
const uyp,
345 const amrex::ParticleReal *
const uzp,
346 const int *
const ion_lev,
347 const amrex::Array4<amrex::Real>& Jx_arr,
348 const amrex::Array4<amrex::Real>& Jy_arr,
349 const amrex::Array4<amrex::Real>& Jz_arr,
350 const long np_to_depose,
351 const amrex::Real dt,
352 const std::array<amrex::Real,3>&
dx,
353 const std::array<amrex::Real, 3> xyzmin,
354 const amrex::Dim3 lo,
356 const int n_rz_azimuthal_modes,
357 amrex::Real *
const cost,
358 const long load_balance_costs_update_algo)
360 using namespace amrex;
361 #if !defined(WARPX_DIM_RZ) 362 ignore_unused(n_rz_azimuthal_modes);
365 #if !defined(AMREX_USE_GPU) 366 amrex::ignore_unused(cost, load_balance_costs_update_algo);
371 bool const do_ionization = ion_lev;
372 Real
const dxi = 1.0_rt / dx[0];
373 #if !(defined WARPX_DIM_RZ) 374 Real
const dtsdx0 = dt*dxi;
376 Real
const xmin = xyzmin[0];
377 #if (defined WARPX_DIM_3D) 378 Real
const dyi = 1.0_rt / dx[1];
379 Real
const dtsdy0 = dt*dyi;
380 Real
const ymin = xyzmin[1];
382 Real
const dzi = 1.0_rt / dx[2];
383 Real
const dtsdz0 = dt*dzi;
384 Real
const zmin = xyzmin[2];
386 #if (defined WARPX_DIM_3D) 387 Real
const invdtdx = 1.0_rt / (dt*dx[1]*dx[2]);
388 Real
const invdtdy = 1.0_rt / (dt*dx[0]*dx[2]);
389 Real
const invdtdz = 1.0_rt / (dt*dx[0]*dx[1]);
390 #elif (defined WARPX_DIM_XZ) || (defined WARPX_DIM_RZ) 391 Real
const invdtdx = 1.0_rt / (dt*dx[2]);
392 Real
const invdtdz = 1.0_rt / (dt*dx[0]);
393 Real
const invvol = 1.0_rt / (dx[0]*dx[2]);
396 #if (defined WARPX_DIM_RZ) 400 Real
const clightsq = 1.0_rt / ( PhysConst::c * PhysConst::c );
403 #if defined(WARPX_USE_GPUCLOCK) 404 amrex::Real* cost_real =
nullptr;
406 cost_real = (amrex::Real *) amrex::The_Managed_Arena()->alloc(
sizeof(amrex::Real));
412 [=] AMREX_GPU_DEVICE (
long const ip) {
413 #if defined(WARPX_USE_GPUCLOCK) 414 KernelTimer kernelTimer(cost && load_balance_costs_update_algo
419 Real
const gaminv = 1.0_rt/std::sqrt(1.0_rt + uxp[ip]*uxp[ip]*clightsq
420 + uyp[ip]*uyp[ip]*clightsq
421 + uzp[ip]*uzp[ip]*clightsq);
429 ParticleReal xp, yp, zp;
430 GetPosition(ip, xp, yp, zp);
432 Real
const wqx = wq*invdtdx;
433 #if (defined WARPX_DIM_3D) 434 Real
const wqy = wq*invdtdy;
436 Real
const wqz = wq*invdtdz;
439 #if (defined WARPX_DIM_RZ) 440 Real
const xp_mid = xp - 0.5_rt * dt*uxp[ip]*gaminv;
441 Real
const yp_mid = yp - 0.5_rt * dt*uyp[ip]*gaminv;
442 Real
const xp_old = xp - dt*uxp[ip]*gaminv;
443 Real
const yp_old = yp - dt*uyp[ip]*gaminv;
444 Real
const rp_new = std::sqrt(xp*xp
446 Real
const rp_mid = std::sqrt(xp_mid*xp_mid + yp_mid*yp_mid);
447 Real
const rp_old = std::sqrt(xp_old*xp_old + yp_old*yp_old);
448 Real costheta_new, sintheta_new;
449 if (rp_new > 0._rt) {
450 costheta_new = xp/rp_new;
451 sintheta_new = yp/rp_new;
453 costheta_new = 1._rt;
454 sintheta_new = 0._rt;
456 amrex::Real costheta_mid, sintheta_mid;
457 if (rp_mid > 0._rt) {
458 costheta_mid = xp_mid/rp_mid;
459 sintheta_mid = yp_mid/rp_mid;
461 costheta_mid = 1._rt;
462 sintheta_mid = 0._rt;
464 amrex::Real costheta_old, sintheta_old;
465 if (rp_old > 0._rt) {
466 costheta_old = xp_old/rp_old;
467 sintheta_old = yp_old/rp_old;
469 costheta_old = 1._rt;
470 sintheta_old = 0._rt;
476 double const x_new = (rp_new - xmin)*dxi;
477 double const x_old = (rp_old - xmin)*dxi;
480 double const x_new = (xp - xmin)*dxi;
481 double const x_old = x_new - dtsdx0*uxp[ip]*gaminv;
483 #if (defined WARPX_DIM_3D) 485 double const y_new = (yp - ymin)*dyi;
486 double const y_old = y_new - dtsdy0*uyp[ip]*gaminv;
489 double const z_new = (zp - zmin)*dzi;
490 double const z_old = z_new - dtsdz0*uzp[ip]*gaminv;
492 #if (defined WARPX_DIM_RZ) 493 Real
const vy = (-uxp[ip]*sintheta_mid + uyp[ip]*costheta_mid)*gaminv;
494 #elif (defined WARPX_DIM_XZ) 495 Real
const vy = uyp[ip]*gaminv;
503 double sx_new[depos_order + 3] = {0.};
504 double sx_old[depos_order + 3] = {0.};
505 #if (defined WARPX_DIM_3D) 507 double sy_new[depos_order + 3] = {0.};
508 double sy_old[depos_order + 3] = {0.};
511 double sz_new[depos_order + 3] = {0.};
512 double sz_old[depos_order + 3] = {0.};
520 const int i_new = compute_shape_factor(sx_new+1, x_new);
521 const int i_old = compute_shifted_shape_factor(sx_old, x_old, i_new);
522 #if (defined WARPX_DIM_3D) 523 const int j_new = compute_shape_factor(sy_new+1, y_new);
524 const int j_old = compute_shifted_shape_factor(sy_old, y_old, j_new);
526 const int k_new = compute_shape_factor(sz_new+1, z_new);
527 const int k_old = compute_shifted_shape_factor(sz_old, z_old, k_new);
530 int dil = 1, diu = 1;
531 if (i_old < i_new) dil = 0;
532 if (i_old > i_new) diu = 0;
533 #if (defined WARPX_DIM_3D) 534 int djl = 1, dju = 1;
535 if (j_old < j_new) djl = 0;
536 if (j_old > j_new) dju = 0;
538 int dkl = 1, dku = 1;
539 if (k_old < k_new) dkl = 0;
540 if (k_old > k_new) dku = 0;
542 #if (defined WARPX_DIM_3D) 544 for (
int k=dkl; k<=depos_order+2-dku; k++) {
545 for (
int j=djl; j<=depos_order+2-dju; j++) {
546 amrex::Real sdxi = 0._rt;
547 for (
int i=dil;
i<=depos_order+1-diu;
i++) {
548 sdxi += wqx*(sx_old[
i] - sx_new[
i])*((sy_new[j] + 0.5_rt*(sy_old[j] - sy_new[j]))*sz_new[k] +
549 (0.5_rt*sy_new[j] + 1._rt/3._rt*(sy_old[j] - sy_new[j]))*(sz_old[k] - sz_new[k]));
550 amrex::Gpu::Atomic::AddNoRet( &Jx_arr(lo.x+i_new-1+
i, lo.y+j_new-1+j, lo.z+k_new-1+k), sdxi);
554 for (
int k=dkl; k<=depos_order+2-dku; k++) {
555 for (
int i=dil;
i<=depos_order+2-diu;
i++) {
556 amrex::Real sdyj = 0._rt;
557 for (
int j=djl; j<=depos_order+1-dju; j++) {
558 sdyj += wqy*(sy_old[j] - sy_new[j])*((sz_new[k] + 0.5_rt*(sz_old[k] - sz_new[k]))*sx_new[
i] +
559 (0.5_rt*sz_new[k] + 1._rt/3._rt*(sz_old[k] - sz_new[k]))*(sx_old[
i] - sx_new[
i]));
560 amrex::Gpu::Atomic::AddNoRet( &Jy_arr(lo.x+i_new-1+
i, lo.y+j_new-1+j, lo.z+k_new-1+k), sdyj);
564 for (
int j=djl; j<=depos_order+2-dju; j++) {
565 for (
int i=dil;
i<=depos_order+2-diu;
i++) {
566 amrex::Real sdzk = 0._rt;
567 for (
int k=dkl; k<=depos_order+1-dku; k++) {
568 sdzk += wqz*(sz_old[k] - sz_new[k])*((sx_new[
i] + 0.5_rt*(sx_old[
i] - sx_new[
i]))*sy_new[j] +
569 (0.5_rt*sx_new[
i] + 1._rt/3._rt*(sx_old[
i] - sx_new[
i]))*(sy_old[j] - sy_new[j]));
570 amrex::Gpu::Atomic::AddNoRet( &Jz_arr(lo.x+i_new-1+i, lo.y+j_new-1+j, lo.z+k_new-1+k), sdzk);
575 #elif (defined WARPX_DIM_XZ) || (defined WARPX_DIM_RZ) 577 for (
int k=dkl; k<=depos_order+2-dku; k++) {
578 amrex::Real sdxi = 0._rt;
579 for (
int i=dil;
i<=depos_order+1-diu;
i++) {
580 sdxi += wqx*(sx_old[
i] - sx_new[
i])*(sz_new[k] + 0.5_rt*(sz_old[k] - sz_new[k]));
581 amrex::Gpu::Atomic::AddNoRet( &Jx_arr(lo.x+i_new-1+
i, lo.y+k_new-1+k, 0, 0), sdxi);
582 #if (defined WARPX_DIM_RZ) 584 for (
int imode=1 ; imode < n_rz_azimuthal_modes ; imode++) {
586 const Complex djr_cmplx = 2._rt *sdxi*xy_mid;
587 amrex::Gpu::Atomic::AddNoRet( &Jx_arr(lo.x+i_new-1+
i, lo.y+k_new-1+k, 0, 2*imode-1), djr_cmplx.real());
588 amrex::Gpu::Atomic::AddNoRet( &Jx_arr(lo.x+i_new-1+
i, lo.y+k_new-1+k, 0, 2*imode), djr_cmplx.imag());
589 xy_mid = xy_mid*xy_mid0;
594 for (
int k=dkl; k<=depos_order+2-dku; k++) {
595 for (
int i=dil;
i<=depos_order+2-diu;
i++) {
596 Real
const sdyj = wq*vy*invvol*((sz_new[k] + 0.5_rt * (sz_old[k] - sz_new[k]))*sx_new[
i] +
597 (0.5_rt * sz_new[k] + 1._rt / 3._rt *(sz_old[k] - sz_new[k]))*(sx_old[
i] - sx_new[
i]));
598 amrex::Gpu::Atomic::AddNoRet( &Jy_arr(lo.x+i_new-1+
i, lo.y+k_new-1+k, 0, 0), sdyj);
599 #if (defined WARPX_DIM_RZ) 604 for (
int imode=1 ; imode < n_rz_azimuthal_modes ; imode++) {
607 const Complex djt_cmplx = -2._rt * I*(i_new-1 +
i + xmin*dxi)*wq*invdtdx/(amrex::Real)imode
608 *(
Complex(sx_new[
i]*sz_new[k], 0._rt)*(xy_new - xy_mid)
609 +
Complex(sx_old[
i]*sz_old[k], 0._rt)*(xy_mid - xy_old));
610 amrex::Gpu::Atomic::AddNoRet( &Jy_arr(lo.x+i_new-1+
i, lo.y+k_new-1+k, 0, 2*imode-1), djt_cmplx.real());
611 amrex::Gpu::Atomic::AddNoRet( &Jy_arr(lo.x+i_new-1+
i, lo.y+k_new-1+k, 0, 2*imode), djt_cmplx.imag());
612 xy_new = xy_new*xy_new0;
613 xy_mid = xy_mid*xy_mid0;
614 xy_old = xy_old*xy_old0;
619 for (
int i=dil;
i<=depos_order+2-diu;
i++) {
621 for (
int k=dkl; k<=depos_order+1-dku; k++) {
622 sdzk += wqz*(sz_old[k] - sz_new[k])*(sx_new[
i] + 0.5_rt * (sx_old[
i] - sx_new[
i]));
623 amrex::Gpu::Atomic::AddNoRet( &Jz_arr(lo.x+i_new-1+i, lo.y+k_new-1+k, 0, 0), sdzk);
624 #if (defined WARPX_DIM_RZ) 626 for (
int imode=1 ; imode < n_rz_azimuthal_modes ; imode++) {
628 const Complex djz_cmplx = 2._rt * sdzk * xy_mid;
629 amrex::Gpu::Atomic::AddNoRet( &Jz_arr(lo.x+i_new-1+i, lo.y+k_new-1+k, 0, 2*imode-1), djz_cmplx.real());
630 amrex::Gpu::Atomic::AddNoRet( &Jz_arr(lo.x+i_new-1+i, lo.y+k_new-1+k, 0, 2*imode), djz_cmplx.imag());
631 xy_mid = xy_mid*xy_mid0;
639 #if defined(WARPX_USE_GPUCLOCK) 641 amrex::Gpu::streamSynchronize();
643 amrex::The_Managed_Arena()->free(cost_real);
676 template <
int depos_order>
678 const amrex::ParticleReal*
const wp,
679 const amrex::ParticleReal*
const uxp,
680 const amrex::ParticleReal*
const uyp,
681 const amrex::ParticleReal*
const uzp,
682 const int*
const ion_lev,
683 amrex::FArrayBox& jx_fab,
684 amrex::FArrayBox& jy_fab,
685 amrex::FArrayBox& jz_fab,
686 const long np_to_depose,
687 const amrex::Real dt,
688 const std::array<amrex::Real,3>&
dx,
689 const std::array<amrex::Real,3>& xyzmin,
690 const amrex::Dim3 lo,
692 const int n_rz_azimuthal_modes,
694 const long load_balance_costs_update_algo)
696 #if (defined WARPX_DIM_RZ) 697 amrex::ignore_unused(GetPosition,
698 wp, uxp, uyp, uzp, ion_lev, jx_fab, jy_fab, jz_fab,
699 np_to_depose, dt, dx, xyzmin, lo, q, n_rz_azimuthal_modes);
700 amrex::Abort(
"Vay deposition not implemented in RZ geometry");
703 #if !defined(AMREX_USE_GPU) 704 amrex::ignore_unused(cost, load_balance_costs_update_algo);
707 #if !(defined WARPX_DIM_RZ) 708 amrex::ignore_unused(n_rz_azimuthal_modes);
711 const bool do_ionization = ion_lev;
714 const amrex::Real dxi = 1._rt / dx[0];
715 const amrex::Real dzi = 1._rt / dx[2];
716 #if (defined WARPX_DIM_3D) 717 const amrex::Real dyi = 1._rt / dx[1];
721 const amrex::Real invdt = 1._rt / dt;
724 #if (defined WARPX_DIM_XZ) 725 const amrex::Real invvol = dxi * dzi;
726 #elif (defined WARPX_DIM_3D) 727 const amrex::Real invvol = dxi * dyi * dzi;
731 const amrex::Real xmin = xyzmin[0];
732 const amrex::Real zmin = xyzmin[2];
733 #if (defined WARPX_DIM_3D) 734 const amrex::Real ymin = xyzmin[1];
738 #if (defined WARPX_DIM_3D) 739 const amrex::Real onethird = 1._rt / 3._rt;
740 const amrex::Real onesixth = 1._rt / 6._rt;
744 const amrex::Real invcsq = 1._rt / (PhysConst::c * PhysConst::c);
747 amrex::Array4<amrex::Real>
const& jx_arr = jx_fab.array();
748 amrex::Array4<amrex::Real>
const& jy_arr = jy_fab.array();
749 amrex::Array4<amrex::Real>
const& jz_arr = jz_fab.array();
752 #if defined(WARPX_USE_GPUCLOCK) 753 amrex::Real* cost_real =
nullptr;
755 cost_real = (amrex::Real *) amrex::The_Managed_Arena()->alloc(
sizeof(amrex::Real));
759 amrex::ParallelFor(np_to_depose, [=] AMREX_GPU_DEVICE (
long ip)
761 #if defined(WARPX_USE_GPUCLOCK) 762 KernelTimer kernelTimer(cost && load_balance_costs_update_algo
767 const amrex::Real invgam = 1._rt / std::sqrt(1._rt + uxp[ip] * uxp[ip] * invcsq
768 + uyp[ip] * uyp[ip] * invcsq
769 + uzp[ip] * uzp[ip] * invcsq);
771 amrex::Real wq = q * wp[ip];
772 if (do_ionization) wq *= ion_lev[ip];
775 amrex::ParticleReal xp, yp, zp;
776 GetPosition(ip, xp, yp, zp);
779 const amrex::Real vx = uxp[ip] * invgam;
780 const amrex::Real vy = uyp[ip] * invgam;
781 const amrex::Real vz = uzp[ip] * invgam;
784 #if (defined WARPX_DIM_XZ) 785 const amrex::Real wqy = wq * vy * invvol;
790 double const x_new = (xp - xmin) * dxi;
791 double const x_old = x_new - vx * dt * dxi;
792 #if (defined WARPX_DIM_3D) 794 double const y_new = (yp - ymin) * dyi;
795 double const y_old = y_new - vy * dt * dyi;
798 double const z_new = (zp - zmin) * dzi;
799 double const z_old = z_new - vz * dt * dzi;
803 double sx_new[depos_order+1] = {0.};
804 double sx_old[depos_order+1] = {0.};
805 #if (defined WARPX_DIM_3D) 807 double sy_new[depos_order+1] = {0.};
808 double sy_old[depos_order+1] = {0.};
811 double sz_new[depos_order+1] = {0.};
812 double sz_old[depos_order+1] = {0.};
819 const int i_new = compute_shape_factor(sx_new, x_new);
820 #if (defined WARPX_DIM_3D) 823 const int j_new = compute_shape_factor(sy_new, y_new);
827 const int k_new = compute_shape_factor(sz_new, z_new);
833 const int i_old = compute_shape_factor(sx_old, x_old);
834 #if (defined WARPX_DIM_3D) 837 const int j_old = compute_shape_factor(sy_old, y_old);
841 const int k_old = compute_shape_factor(sz_old, z_old);
844 #if (defined WARPX_DIM_XZ) 846 for (
int k=0; k<=depos_order; k++) {
847 for (
int i=0;
i<=depos_order;
i++) {
851 amrex::Real
const sxn_szn = sx_new[
i] * sz_new[k];
852 amrex::Real
const sxo_szn = sx_old[
i] * sz_new[k];
853 amrex::Real
const sxn_szo = sx_new[
i] * sz_old[k];
854 amrex::Real
const sxo_szo = sx_old[
i] * sz_old[k];
857 amrex::Gpu::Atomic::AddNoRet(&jx_arr(lo.x + i_new +
i, lo.y + k_new + k, 0, 0),
858 wq * invvol * invdt * 0.5_rt * sxn_szn);
860 amrex::Gpu::Atomic::AddNoRet(&jx_arr(lo.x + i_old +
i, lo.y + k_new + k, 0, 0),
861 - wq * invvol * invdt * 0.5_rt * sxo_szn);
863 amrex::Gpu::Atomic::AddNoRet(&jx_arr(lo.x + i_new +
i, lo.y + k_old + k, 0, 0),
864 wq * invvol * invdt * 0.5_rt * sxn_szo);
866 amrex::Gpu::Atomic::AddNoRet(&jx_arr(lo.x + i_old +
i, lo.y + k_old + k, 0, 0),
867 - wq * invvol * invdt * 0.5_rt * sxo_szo);
870 amrex::Gpu::Atomic::AddNoRet(&jy_arr(lo.x + i_new +
i, lo.y + k_new + k, 0, 0),
871 wqy * 0.25_rt * sxn_szn);
873 amrex::Gpu::Atomic::AddNoRet(&jy_arr(lo.x + i_new +
i, lo.y + k_old + k, 0, 0),
874 wqy * 0.25_rt * sxn_szo);
876 amrex::Gpu::Atomic::AddNoRet(&jy_arr(lo.x + i_old +
i, lo.y + k_new + k, 0, 0),
877 wqy * 0.25_rt * sxo_szn);
879 amrex::Gpu::Atomic::AddNoRet(&jy_arr(lo.x + i_old +
i, lo.y + k_old + k, 0, 0),
880 wqy * 0.25_rt * sxo_szo);
883 amrex::Gpu::Atomic::AddNoRet(&jz_arr(lo.x + i_new +
i, lo.y + k_new + k, 0, 0),
884 wq * invvol * invdt * 0.5_rt * sxn_szn);
886 amrex::Gpu::Atomic::AddNoRet(&jz_arr(lo.x+i_new+
i,lo.y+k_old+k,0,0),
887 - wq * invvol * invdt * 0.5_rt * sxn_szo);
889 amrex::Gpu::Atomic::AddNoRet(&jz_arr(lo.x+i_old+
i,lo.y+k_new+k,0,0),
890 wq * invvol * invdt * 0.5_rt * sxo_szn);
892 amrex::Gpu::Atomic::AddNoRet(&jz_arr(lo.x + i_old +
i, lo.y + k_old + k, 0, 0),
893 - wq * invvol * invdt * 0.5_rt * sxo_szo);
897 #elif (defined WARPX_DIM_3D) 899 for (
int k=0; k<=depos_order; k++) {
900 for (
int j=0; j<=depos_order; j++) {
902 amrex::Real
const syn_szn = sy_new[j] * sz_new[k];
903 amrex::Real
const syo_szn = sy_old[j] * sz_new[k];
904 amrex::Real
const syn_szo = sy_new[j] * sz_old[k];
905 amrex::Real
const syo_szo = sy_old[j] * sz_old[k];
907 for (
int i=0;
i<=depos_order;
i++) {
909 amrex::Real
const sxn_syn_szn = sx_new[
i] * syn_szn;
910 amrex::Real
const sxo_syn_szn = sx_old[
i] * syn_szn;
911 amrex::Real
const sxn_syo_szn = sx_new[
i] * syo_szn;
912 amrex::Real
const sxo_syo_szn = sx_old[
i] * syo_szn;
913 amrex::Real
const sxn_syn_szo = sx_new[
i] * syn_szo;
914 amrex::Real
const sxo_syn_szo = sx_old[
i] * syn_szo;
915 amrex::Real
const sxn_syo_szo = sx_new[
i] * syo_szo;
916 amrex::Real
const sxo_syo_szo = sx_old[
i] * syo_szo;
919 amrex::Gpu::Atomic::AddNoRet(&jx_arr(lo.x + i_new +
i, lo.y + j_new + j, lo.z + k_new + k),
920 wq * invvol * invdt * onethird * sxn_syn_szn);
922 amrex::Gpu::Atomic::AddNoRet(&jx_arr(lo.x + i_old +
i, lo.y + j_new + j, lo.z + k_new + k),
923 - wq * invvol * invdt * onethird * sxo_syn_szn);
925 amrex::Gpu::Atomic::AddNoRet(&jx_arr(lo.x + i_new +
i, lo.y + j_old + j, lo.z + k_new + k),
926 wq * invvol * invdt * onesixth * sxn_syo_szn);
928 amrex::Gpu::Atomic::AddNoRet(&jx_arr(lo.x + i_old +
i, lo.y + j_old + j,lo.z + k_new + k),
929 - wq * invvol * invdt * onesixth * sxo_syo_szn);
931 amrex::Gpu::Atomic::AddNoRet(&jx_arr(lo.x + i_new +
i, lo.y + j_new + j, lo.z + k_old + k),
932 wq * invvol * invdt * onesixth * sxn_syn_szo);
934 amrex::Gpu::Atomic::AddNoRet(&jx_arr(lo.x + i_old +
i, lo.y + j_new + j, lo.z + k_old + k),
935 - wq * invvol * invdt * onesixth * sxo_syn_szo);
937 amrex::Gpu::Atomic::AddNoRet(&jx_arr(lo.x + i_new +
i, lo.y + j_old + j, lo.z + k_old + k),
938 wq * invvol * invdt * onethird * sxn_syo_szo);
940 amrex::Gpu::Atomic::AddNoRet(&jx_arr(lo.x + i_old +
i, lo.y + j_old + j, lo.z + k_old + k),
941 - wq * invvol * invdt * onethird * sxo_syo_szo);
944 amrex::Gpu::Atomic::AddNoRet(&jy_arr(lo.x + i_new +
i, lo.y + j_new + j, lo.z + k_new + k),
945 wq * invvol * invdt * onethird * sxn_syn_szn);
947 amrex::Gpu::Atomic::AddNoRet(&jy_arr(lo.x + i_new +
i, lo.y + j_old + j, lo.z + k_new + k),
948 - wq * invvol * invdt * onethird * sxn_syo_szn);
950 amrex::Gpu::Atomic::AddNoRet(&jy_arr(lo.x + i_old +
i, lo.y + j_new + j, lo.z + k_new + k),
951 wq * invvol * invdt * onesixth * sxo_syn_szn);
953 amrex::Gpu::Atomic::AddNoRet(&jy_arr(lo.x + i_old +
i, lo.y + j_old + j, lo.z + k_new + k),
954 - wq * invvol * invdt * onesixth * sxo_syo_szn);
956 amrex::Gpu::Atomic::AddNoRet(&jy_arr(lo.x + i_new +
i, lo.y + j_new + j, lo.z + k_old + k),
957 wq * invvol * invdt * onesixth * sxn_syn_szo);
959 amrex::Gpu::Atomic::AddNoRet(&jy_arr(lo.x + i_new +
i, lo.y + j_old + j, lo.z + k_old + k),
960 - wq * invvol * invdt * onesixth * sxn_syo_szo);
962 amrex::Gpu::Atomic::AddNoRet(&jy_arr(lo.x + i_old +
i, lo.y + j_new + j, lo.z + k_old + k),
963 wq * invvol * invdt * onethird * sxo_syn_szo);
965 amrex::Gpu::Atomic::AddNoRet(&jy_arr(lo.x + i_old +
i, lo.y + j_old + j, lo.z + k_old + k),
966 - wq * invvol * invdt * onethird * sxo_syo_szo);
969 amrex::Gpu::Atomic::AddNoRet(&jz_arr( lo.x + i_new +
i, lo.y + j_new + j, lo.z + k_new + k),
970 wq * invvol * invdt * onethird * sxn_syn_szn);
972 amrex::Gpu::Atomic::AddNoRet(&jz_arr( lo.x + i_new +
i, lo.y + j_new + j, lo.z + k_old + k),
973 - wq * invvol * invdt * onethird * sxn_syn_szo);
975 amrex::Gpu::Atomic::AddNoRet(&jz_arr( lo.x + i_old +
i, lo.y + j_new + j, lo.z + k_new + k),
976 wq * invvol * invdt * onesixth * sxo_syn_szn);
978 amrex::Gpu::Atomic::AddNoRet(&jz_arr( lo.x + i_old +
i, lo.y + j_new + j, lo.z + k_old + k),
979 - wq * invvol * invdt * onesixth * sxo_syn_szo);
981 amrex::Gpu::Atomic::AddNoRet(&jz_arr( lo.x + i_new +
i, lo.y + j_old + j, lo.z + k_new + k),
982 wq * invvol * invdt * onesixth * sxn_syo_szn);
984 amrex::Gpu::Atomic::AddNoRet(&jz_arr( lo.x + i_new +
i, lo.y + j_old + j, lo.z + k_old + k),
985 - wq * invvol * invdt * onesixth * sxn_syo_szo);
987 amrex::Gpu::Atomic::AddNoRet(&jz_arr( lo.x + i_old +
i, lo.y + j_old + j, lo.z + k_new + k),
988 wq * invvol * invdt * onethird * sxo_syo_szn);
990 amrex::Gpu::Atomic::AddNoRet(&jz_arr( lo.x + i_old +
i, lo.y + j_old + j, lo.z + k_old + k),
991 - wq * invvol * invdt * onethird * sxo_syo_szo);
997 # if defined(WARPX_USE_GPUCLOCK) 999 amrex::Gpu::streamSynchronize();
1000 *cost += *cost_real;
1001 amrex::The_Managed_Arena()->free(cost_real);
1004 #endif // #if !(defined WARPX_DIM_RZ) 1006 #endif // CURRENTDEPOSITION_H_ amrex::GpuComplex< amrex::Real > Complex
Definition: WarpX_Complex.H:22
void doDepositionShapeN(const GetParticlePosition &GetPosition, const amrex::ParticleReal *const wp, const amrex::ParticleReal *const uxp, const amrex::ParticleReal *const uyp, const amrex::ParticleReal *const uzp, const int *const ion_lev, amrex::FArrayBox &jx_fab, amrex::FArrayBox &jy_fab, amrex::FArrayBox &jz_fab, const long np_to_depose, const amrex::Real relative_t, const std::array< amrex::Real, 3 > &dx, const std::array< amrex::Real, 3 > &xyzmin, const amrex::Dim3 lo, const amrex::Real q, const int n_rz_azimuthal_modes, amrex::Real *cost, const long load_balance_costs_update_algo)
Current Deposition for thread thread_num.
Definition: CurrentDeposition.H:53
int dx
Definition: compute_domain.py:35
Definition: ShapeFactors.H:118
Definition: ShapeFactors.H:22
void doEsirkepovDepositionShapeN(const GetParticlePosition &GetPosition, const amrex::ParticleReal *const wp, const amrex::ParticleReal *const uxp, const amrex::ParticleReal *const uyp, const amrex::ParticleReal *const uzp, const int *const ion_lev, const amrex::Array4< amrex::Real > &Jx_arr, const amrex::Array4< amrex::Real > &Jy_arr, const amrex::Array4< amrex::Real > &Jz_arr, const long np_to_depose, const amrex::Real dt, const std::array< amrex::Real, 3 > &dx, const std::array< amrex::Real, 3 > xyzmin, const amrex::Dim3 lo, const amrex::Real q, const int n_rz_azimuthal_modes, amrex::Real *const cost, const long load_balance_costs_update_algo)
Esirkepov Current Deposition for thread thread_num.
Definition: CurrentDeposition.H:341
i
Definition: check_interp_points_and_weights.py:171
void doVayDepositionShapeN(const GetParticlePosition &GetPosition, const amrex::ParticleReal *const wp, const amrex::ParticleReal *const uxp, const amrex::ParticleReal *const uyp, const amrex::ParticleReal *const uzp, const int *const ion_lev, amrex::FArrayBox &jx_fab, amrex::FArrayBox &jy_fab, amrex::FArrayBox &jz_fab, const long np_to_depose, const amrex::Real dt, const std::array< amrex::Real, 3 > &dx, const std::array< amrex::Real, 3 > &xyzmin, const amrex::Dim3 lo, const amrex::Real q, const int n_rz_azimuthal_modes, amrex::Real *cost, const long load_balance_costs_update_algo)
Vay current deposition (Vay et al, 2013) for thread thread_num: deposit D in real space and store the...
Definition: CurrentDeposition.H:677
Definition: WarpXAlgorithmSelection.H:93
Functor that can be used to extract the positions of the macroparticles inside a ParallelFor kernel...
Definition: GetAndSetPosition.H:48
Defines a timer object to be used on GPU; measures summed thread cycles.
Definition: KernelTimer.H:19
Definition: BreitWheelerEngineWrapper.H:35