OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
BoxLibParticle.hpp
Go to the documentation of this file.
1//
2// Class BoxLibParticle
3// Particle class for AMReX. It works together with BoxLibLayout.
4// The class does the scatter and gather operations of attributes
5// to and from the grid. Ippl implements the same functionality in the
6// attribute class.
7//
8// Copyright (c) 2016 - 2020, Matthias Frey, Uldis Locans, Paul Scherrer Institut, Villigen PSI, Switzerland
9// All rights reserved
10//
11// Implemented as part of the PhD thesis
12// "Precise Simulations of Multibunches in High Intensity Cyclotrons"
13//
14// This file is part of OPAL.
15//
16// OPAL is free software: you can redistribute it and/or modify
17// it under the terms of the GNU General Public License as published by
18// the Free Software Foundation, either version 3 of the License, or
19// (at your option) any later version.
20//
21// You should have received a copy of the GNU General Public License
22// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
23//
24#ifndef BOXLIB_PARTICLE_HPP
25#define BOXLIB_PARTICLE_HPP
26
28
29#include <AMReX_BLFort.H>
30#include <AMReX_MultiFabUtil.H>
31#include <AMReX_MultiFabUtil_F.H>
32#include <AMReX_Interpolater.H>
33#include <AMReX_FillPatchUtil.H>
34
35template<class PLayout>
37{
38 AssignDensityTimer_m = IpplTimings::getTimer("AMR AssignDensity");
39}
40
41
42template<class PLayout>
44{
45 AssignDensityTimer_m = IpplTimings::getTimer("AMR AssignDensity");
46}
47
48
49template<class PLayout>
50template<class FT, unsigned Dim, class PT>
53 int lbase, int lfine,
54 const ParticleAttrib<int>& pbin, int bin)
55{
56 if ( lbase == lfine ) {
57 this->scatter(attrib, *(f[lbase].get()), pp, pbin, bin, lbase);
58 return;
59 }
60
61 const PLayout *layout_p = &this->getLayout();
62 int nGrow = layout_p->refRatio(lbase)[0];
63
64 AmrScalarFieldContainer_t tmp(lfine+1);
65 for (int lev = lbase; lev <= lfine; ++lev) {
66
67 f[lev]->setVal(0.0, f[lev]->nGrow());
68
69 const AmrGrid_t& ba = f[lev]->boxArray();
70 const AmrProcMap_t& dm = f[lev]->DistributionMap();
71 tmp[lev].reset(new AmrField_t(ba, dm, 1, nGrow));
72 tmp[lev]->setVal(0.0, nGrow);
73 }
74
75 this->AssignDensityFort(attrib, tmp, lbase, 1, lfine, pbin, bin);
76
77 for (int lev = lbase; lev <= lfine; ++lev)
78 AmrField_t::Copy(*f[lev], *tmp[lev], 0, 0, f[lev]->nComp(), f[lev]->nGrow());
79}
80
81
82template<class PLayout>
83template <class FT, unsigned Dim, class PT>
86 const ParticleAttrib<int>& pbin, int bin,
87 int level)
88{
89 const AmrGrid_t& ba = f.boxArray();
90 const AmrProcMap_t& dmap = f.DistributionMap();
91
92 AmrField_t tmp(ba, dmap, f.nComp(), 1);
93 tmp.setVal(0.0, 1);
94
95 this->AssignCellDensitySingleLevelFort(attrib, tmp, level, pbin, bin);
96
97 f.setVal(0.0, f.nGrow());
98
99 AmrField_t::Copy(f, tmp, 0, 0, f.nComp(), f.nGrow());
100}
101
102
103template<class PLayout>
104template<class FT, unsigned Dim, class PT>
107 int lbase, int lfine)
108{
109 this->InterpolateFort(attrib, f, lbase, lfine);
110}
111
112
113// Function from BoxLib adjusted to work with Ippl BoxLibParticle class
114// Scatter the particle attribute pa on the grid
115template<class PLayout>
116template <class AType>
118 AmrScalarFieldContainer_t& mf_to_be_filled,
119 int lev_min, int ncomp, int finest_level,
120 const ParticleAttrib<int>& pbin, int bin) const
121{
122// BL_PROFILE("AssignDensityFort()");
123 IpplTimings::startTimer(AssignDensityTimer_m);
124 const PLayout *layout_p = &this->getLayout();
125
126 // not done in amrex
127 int rho_index = 0;
128
129 amrex::PhysBCFunct cphysbc, fphysbc;
130 int lo_bc[] = {INT_DIR, INT_DIR, INT_DIR}; // periodic boundaries
131 int hi_bc[] = {INT_DIR, INT_DIR, INT_DIR};
132 amrex::Vector<amrex::BCRec> bcs(1, amrex::BCRec(lo_bc, hi_bc));
133 amrex::PCInterp mapper;
134
135 AmrScalarFieldContainer_t tmp(finest_level+1);
136 for (int lev = lev_min; lev <= finest_level; ++lev) {
137 const AmrGrid_t& ba = mf_to_be_filled[lev]->boxArray();
138 const AmrProcMap_t& dm = mf_to_be_filled[lev]->DistributionMap();
139 tmp[lev].reset(new AmrField_t(ba, dm, 1, 0));
140 tmp[lev]->setVal(0.0);
141 }
142
143 for (int lev = lev_min; lev <= finest_level; ++lev) {
144 AssignCellDensitySingleLevelFort(pa, *mf_to_be_filled[lev], lev, pbin, bin, 1, 0);
145
146 if (lev < finest_level) {
147 amrex::InterpFromCoarseLevel(*tmp[lev+1], 0.0, *mf_to_be_filled[lev],
148 rho_index, rho_index, ncomp,
149 layout_p->Geom(lev), layout_p->Geom(lev+1),
150 cphysbc, fphysbc,
151 layout_p->refRatio(lev), &mapper, bcs);
152 }
153
154 if (lev > lev_min) {
155 // Note - this will double count the mass on the coarse level in
156 // regions covered by the fine level, but this will be corrected
157 // below in the call to average_down.
158 amrex::sum_fine_to_coarse(*mf_to_be_filled[lev],
159 *mf_to_be_filled[lev-1],
160 rho_index, 1, layout_p->refRatio(lev-1),
161 layout_p->Geom(lev-1), layout_p->Geom(lev));
162 }
163
164 mf_to_be_filled[lev]->plus(*tmp[lev], rho_index, ncomp, 0);
165 }
166
167 for (int lev = finest_level - 1; lev >= lev_min; --lev) {
168 amrex::average_down(*mf_to_be_filled[lev+1],
169 *mf_to_be_filled[lev], rho_index, ncomp, layout_p->refRatio(lev));
170 }
171
172 IpplTimings::stopTimer(AssignDensityTimer_m);
173}
174
175
176// This is the single-level version for cell-centered density
177template<class PLayout>
178template <class AType>
180 AmrField_t& mf_to_be_filled,
181 int level,
182 const ParticleAttrib<int>& pbin,
183 int bin,
184 int ncomp,
185 int /*particle_lvl_offset*/) const
186{
187// BL_PROFILE("ParticleContainer<NStructReal, NStructInt, NArrayReal, NArrayInt>::AssignCellDensitySingleLevelFort()");
188
189 const PLayout *layout_p = &this->getLayout();
190
191 AmrField_t* mf_pointer;
192
193 if (layout_p->OnSameGrids(level, mf_to_be_filled)) {
194 // If we are already working with the internal mf defined on the
195 // particle_box_array, then we just work with this.
196 mf_pointer = &mf_to_be_filled;
197 }
198 else {
199 // If mf_to_be_filled is not defined on the particle_box_array, then we need
200 // to make a temporary here and copy into mf_to_be_filled at the end.
201 mf_pointer = new AmrField_t(layout_p->ParticleBoxArray(level),
202 layout_p->ParticleDistributionMap(level),
203 ncomp, mf_to_be_filled.nGrow());
204 }
205
206 // We must have ghost cells for each FAB so that a particle in one grid can spread
207 // its effect to an adjacent grid by first putting the value into ghost cells of its
208 // own grid. The mf->sumBoundary call then adds the value from one grid's ghost cell
209 // to another grid's valid region.
210 if (mf_pointer->nGrow() < 1)
211 throw OpalException("BoxLibParticle::AssignCellDensitySingleLevelFort()",
212 "Must have at least one ghost cell when in AssignCellDensitySingleLevelFort");
213
214 const AmrGeometry_t& gm = layout_p->Geom(level);
215 const AmrReal_t* plo = gm.ProbLo();
216// const AmrReal_t* dx_particle = layout_p->Geom(level + particle_lvl_offset).CellSize();
217 const AmrReal_t* dx = gm.CellSize();
218
219 if (gm.isAnyPeriodic() && ! gm.isAllPeriodic()) {
220 throw OpalException("BoxLibParticle::AssignCellDensitySingleLevelFort()",
221 "Problem must be periodic in no or all directions");
222 }
223
224 for (amrex::MFIter mfi(*mf_pointer); mfi.isValid(); ++mfi) {
225 (*mf_pointer)[mfi].setVal(0);
226 }
227
228 //loop trough particles and distribute values on the grid
229 const ParticleLevelCounter_t& LocalNumPerLevel = this->getLocalNumPerLevel();
230 size_t lBegin = LocalNumPerLevel.begin(level);
231 size_t lEnd = LocalNumPerLevel.end(level);
232
233 AmrReal_t inv_dx[3] = { 1.0 / dx[0], 1.0 / dx[1], 1.0 / dx[2] };
234 double lxyz[3] = { 0.0, 0.0, 0.0 };
235 double wxyz_hi[3] = { 0.0, 0.0, 0.0 };
236 double wxyz_lo[3] = { 0.0, 0.0, 0.0 };
237 int ijk[3] = {0, 0, 0};
238
239 for (size_t ip = lBegin; ip < lEnd; ++ip) {
240
241 if ( bin > -1 && pbin[ip] != bin )
242 continue;
243
244 const int grid = this->Grid[ip];
245 FArrayBox_t& fab = (*mf_pointer)[grid];
246
247 // not callable:
248 // begin amrex_deposit_cic(pbx.data(), nstride, N, fab.dataPtr(), box.loVect(), box.hiVect(), plo, dx);
249 for (int i = 0; i < 3; ++i) {
250 lxyz[i] = ( this->R[ip](i) - plo[i] ) * inv_dx[i] + 0.5;
251 ijk[i] = lxyz[i];
252 wxyz_hi[i] = lxyz[i] - ijk[i];
253 wxyz_lo[i] = 1.0 - wxyz_hi[i];
254 }
255
256 int& i = ijk[0];
257 int& j = ijk[1];
258 int& k = ijk[2];
259
260 AmrIntVect_t i1(i-1, j-1, k-1);
261 AmrIntVect_t i2(i-1, j-1, k);
262 AmrIntVect_t i3(i-1, j, k-1);
263 AmrIntVect_t i4(i-1, j, k);
264 AmrIntVect_t i5(i, j-1, k-1);
265 AmrIntVect_t i6(i, j-1, k);
266 AmrIntVect_t i7(i, j, k-1);
267 AmrIntVect_t i8(i, j, k);
268
269 fab(i1, 0) += wxyz_lo[0]*wxyz_lo[1]*wxyz_lo[2]*pa[ip];
270 fab(i2, 0) += wxyz_lo[0]*wxyz_lo[1]*wxyz_hi[2]*pa[ip];
271 fab(i3, 0) += wxyz_lo[0]*wxyz_hi[1]*wxyz_lo[2]*pa[ip];
272 fab(i4, 0) += wxyz_lo[0]*wxyz_hi[1]*wxyz_hi[2]*pa[ip];
273 fab(i5, 0) += wxyz_hi[0]*wxyz_lo[1]*wxyz_lo[2]*pa[ip];
274 fab(i6, 0) += wxyz_hi[0]*wxyz_lo[1]*wxyz_hi[2]*pa[ip];
275 fab(i7, 0) += wxyz_hi[0]*wxyz_hi[1]*wxyz_lo[2]*pa[ip];
276 fab(i8, 0) += wxyz_hi[0]*wxyz_hi[1]*wxyz_hi[2]*pa[ip];
277 // end of amrex_deposit_cic
278 }
279
280 mf_pointer->SumBoundary(gm.periodicity());
281
282 // Only multiply the first component by (1/vol) because this converts mass
283 // to density. If there are additional components (like velocity), we don't
284 // want to divide those by volume.
285 const AmrReal_t vol = D_TERM(dx[0], *dx[1], *dx[2]);
286
287 mf_pointer->mult(1.0/vol, 0, 1, mf_pointer->nGrow());
288
289 // If mf_to_be_filled is not defined on the particle_box_array, then we need
290 // to copy here from mf_pointer into mf_to_be_filled. I believe that we don't
291 // need any information in ghost cells so we don't copy those.
292 if (mf_pointer != &mf_to_be_filled) {
293 mf_to_be_filled.copy(*mf_pointer,0,0,ncomp);
294 delete mf_pointer;
295 }
296}
297
298
299template<class PLayout>
300template <class AType>
302 AmrVectorFieldContainer_t& mesh_data,
303 int lev_min, int lev_max)
304{
305 for (int lev = lev_min; lev <= lev_max; ++lev) {
306 if ( lev > 0 )
307 InterpolateMultiLevelFort(pa, mesh_data, lev);
308 else
309 InterpolateSingleLevelFort(pa, mesh_data[lev], lev);
310 }
311}
312
313
314template<class PLayout>
315template <class AType>
317 AmrVectorField_t& mesh_data, int lev)
318{
319 for (std::size_t i = 0; i < mesh_data.size(); ++i) {
320 if (mesh_data[i]->nGrow() < 1)
321 throw OpalException("BoxLibParticle::InterpolateSingleLevelFort()",
322 "Must have at least one ghost cell when in InterpolateSingleLevelFort");
323 }
324
325 PLayout *layout_p = &this->getLayout();
326
327 const AmrGeometry_t& gm = layout_p->Geom(lev);
328 const AmrReal_t* plo = gm.ProbLo();
329 const AmrReal_t* dx = gm.CellSize();
330
331 //loop trough particles and distribute values on the grid
332 const ParticleLevelCounter_t& LocalNumPerLevel = this->getLocalNumPerLevel();
333 size_t lBegin = LocalNumPerLevel.begin(lev);
334 size_t lEnd = LocalNumPerLevel.end(lev);
335
336 // make sure that boundaries are filled!
337 for (std::size_t i = 0; i < mesh_data.size(); ++i) {
338 mesh_data[i]->FillBoundary(gm.periodicity());
339 }
340
341 AmrReal_t inv_dx[3] = { 1.0 / dx[0], 1.0 / dx[1], 1.0 / dx[2] };
342 double lxyz[3] = { 0.0, 0.0, 0.0 };
343 double wxyz_hi[3] = { 0.0, 0.0, 0.0 };
344 double wxyz_lo[3] = { 0.0, 0.0, 0.0 };
345 int ijk[3] = {0, 0, 0};
346 for (size_t ip = lBegin; ip < lEnd; ++ip) {
347
348 const int grid = this->Grid[ip];
349 FArrayBox_t& exfab = (*mesh_data[0])[grid];
350 FArrayBox_t& eyfab = (*mesh_data[1])[grid];
351 FArrayBox_t& ezfab = (*mesh_data[2])[grid];
352
353
354 // not callable
355 // begin amrex_interpolate_cic(pbx.data(), nstride, N, fab.dataPtr(), box.loVect(), box.hiVect(), nComp, plo, dx);
356 for (int i = 0; i < 3; ++i) {
357 lxyz[i] = ( this->R[ip](i) - plo[i] ) * inv_dx[i] + 0.5;
358 ijk[i] = lxyz[i];
359 wxyz_hi[i] = lxyz[i] - ijk[i];
360 wxyz_lo[i] = 1.0 - wxyz_hi[i];
361 }
362
363 int& i = ijk[0];
364 int& j = ijk[1];
365 int& k = ijk[2];
366
367 AmrIntVect_t i1(i-1, j-1, k-1);
368 AmrIntVect_t i2(i-1, j-1, k);
369 AmrIntVect_t i3(i-1, j, k-1);
370 AmrIntVect_t i4(i-1, j, k);
371 AmrIntVect_t i5(i, j-1, k-1);
372 AmrIntVect_t i6(i, j-1, k);
373 AmrIntVect_t i7(i, j, k-1);
374 AmrIntVect_t i8(i, j, k);
375
376 pa[ip](0) = wxyz_lo[0]*wxyz_lo[1]*wxyz_lo[2]*exfab(i1) +
377 wxyz_lo[0]*wxyz_lo[1]*wxyz_hi[2]*exfab(i2) +
378 wxyz_lo[0]*wxyz_hi[1]*wxyz_lo[2]*exfab(i3) +
379 wxyz_lo[0]*wxyz_hi[1]*wxyz_hi[2]*exfab(i4) +
380 wxyz_hi[0]*wxyz_lo[1]*wxyz_lo[2]*exfab(i5) +
381 wxyz_hi[0]*wxyz_lo[1]*wxyz_hi[2]*exfab(i6) +
382 wxyz_hi[0]*wxyz_hi[1]*wxyz_lo[2]*exfab(i7) +
383 wxyz_hi[0]*wxyz_hi[1]*wxyz_hi[2]*exfab(i8);
384
385 pa[ip](1) = wxyz_lo[0]*wxyz_lo[1]*wxyz_lo[2]*eyfab(i1) +
386 wxyz_lo[0]*wxyz_lo[1]*wxyz_hi[2]*eyfab(i2) +
387 wxyz_lo[0]*wxyz_hi[1]*wxyz_lo[2]*eyfab(i3) +
388 wxyz_lo[0]*wxyz_hi[1]*wxyz_hi[2]*eyfab(i4) +
389 wxyz_hi[0]*wxyz_lo[1]*wxyz_lo[2]*eyfab(i5) +
390 wxyz_hi[0]*wxyz_lo[1]*wxyz_hi[2]*eyfab(i6) +
391 wxyz_hi[0]*wxyz_hi[1]*wxyz_lo[2]*eyfab(i7) +
392 wxyz_hi[0]*wxyz_hi[1]*wxyz_hi[2]*eyfab(i8);
393
394 pa[ip](2) = wxyz_lo[0]*wxyz_lo[1]*wxyz_lo[2]*ezfab(i1) +
395 wxyz_lo[0]*wxyz_lo[1]*wxyz_hi[2]*ezfab(i2) +
396 wxyz_lo[0]*wxyz_hi[1]*wxyz_lo[2]*ezfab(i3) +
397 wxyz_lo[0]*wxyz_hi[1]*wxyz_hi[2]*ezfab(i4) +
398 wxyz_hi[0]*wxyz_lo[1]*wxyz_lo[2]*ezfab(i5) +
399 wxyz_hi[0]*wxyz_lo[1]*wxyz_hi[2]*ezfab(i6) +
400 wxyz_hi[0]*wxyz_hi[1]*wxyz_lo[2]*ezfab(i7) +
401 wxyz_hi[0]*wxyz_hi[1]*wxyz_hi[2]*ezfab(i8);
402 // end amrex_interpolate_cic
403 }
404}
405
406
407template<class PLayout>
408template <class AType>
410 AmrVectorFieldContainer_t& mesh_data,
411 int lev)
412{
413 for (std::size_t i = 0; i < mesh_data[lev].size(); ++i) {
414 if (mesh_data[lev][i]->nGrow() < 1)
415 throw OpalException("BoxLibParticle::InterpolateMultiLevelFort()",
416 "Must have at least one ghost cell when in InterpolateMultiLevelFort");
417 }
418
419 PLayout *layout_p = &this->getLayout();
420
421 const AmrGeometry_t& gm = layout_p->Geom(lev);
422 const AmrReal_t* plo = gm.ProbLo();
423 const AmrReal_t* fdx = gm.CellSize();
424 const AmrReal_t* cdx = layout_p->Geom(lev-1).CellSize();
425 const AmrReal_t* cplo = layout_p->Geom(lev-1).ProbLo();
426
427 //loop trough particles and distribute values on the grid
428 const ParticleLevelCounter_t& LocalNumPerLevel = this->getLocalNumPerLevel();
429 size_t lBegin = LocalNumPerLevel.begin(lev);
430 size_t lEnd = LocalNumPerLevel.end(lev);
431
432 // make sure that boundaries are filled!
433 for (std::size_t i = 0; i < mesh_data[lev].size(); ++i) {
434 mesh_data[lev][i]->FillBoundary(gm.periodicity());
435 }
436
437 AmrReal_t inv_fdx[3] = { 1.0 / fdx[0], 1.0 / fdx[1], 1.0 / fdx[2] };
438 AmrReal_t inv_cdx[3] = { 1.0 / cdx[0], 1.0 / cdx[1], 1.0 / cdx[2] };
439 double lxyz[3] = { 0.0, 0.0, 0.0 };
440 double wxyz_hi[3] = { 0.0, 0.0, 0.0 };
441 double wxyz_lo[3] = { 0.0, 0.0, 0.0 };
442 int ijk[3] = { 0, 0, 0 };
443
444 const AmrGrid_t& fba = mesh_data[lev][0]->boxArray();
445 const AmrProcMap_t& fdmap = mesh_data[lev][0]->DistributionMap();
446 AmrGrid_t cba = fba;
447 cba.coarsen(AmrIntVect_t(2, 2, 2));
448
449 AmrField_t cmesh_exdata(cba, fdmap,
450 mesh_data[lev][0]->nComp(),
451 mesh_data[lev][0]->nGrow());
452
453 cmesh_exdata.setVal(0.0, 0, 1, mesh_data[lev][0]->nGrow());
454 cmesh_exdata.copy(*mesh_data[lev-1][0], 0, 0, 1, 1, 1);
455 cmesh_exdata.FillBoundary(gm.periodicity());
456
457 AmrField_t cmesh_eydata(cba, fdmap,
458 mesh_data[lev][1]->nComp(),
459 mesh_data[lev][1]->nGrow());
460 cmesh_eydata.setVal(0.0, 0, 1, mesh_data[lev][1]->nGrow());
461 cmesh_eydata.copy(*mesh_data[lev-1][1], 0, 0, 1, 1, 1);
462 cmesh_eydata.FillBoundary(gm.periodicity());
463
464 AmrField_t cmesh_ezdata(cba, fdmap,
465 mesh_data[lev][2]->nComp(),
466 mesh_data[lev][2]->nGrow());
467 cmesh_ezdata.setVal(0.0, 0, 1, mesh_data[lev][2]->nGrow());
468 cmesh_ezdata.copy(*mesh_data[lev-1][2], 0, 0, 1, 1, 1);
469 cmesh_ezdata.FillBoundary(gm.periodicity());
470
471 for (size_t ip = lBegin; ip < lEnd; ++ip) {
472
473 const int grid = this->Grid[ip];
474
475 FArrayBox_t& exfab = (*(mesh_data[lev][0]))[grid];
476 FArrayBox_t& eyfab = (*(mesh_data[lev][1]))[grid];
477 FArrayBox_t& ezfab = (*(mesh_data[lev][2]))[grid];
478
479 FArrayBox_t& cexfab = cmesh_exdata[grid];
480 FArrayBox_t& ceyfab = cmesh_eydata[grid];
481 FArrayBox_t& cezfab = cmesh_ezdata[grid];
482
483 const typename PLayout::basefab_t& mfab = (*layout_p->getLevelMask(lev))[grid];
484
485 // not callable
486 // begin amrex_interpolate_cic(pbx.data(), nstride, N, fab.dataPtr(), box.loVect(), box.hiVect(), nComp, plo, dx);
487 for (int ii = 0; ii < 3; ++ii) {
488 lxyz[ii] = ( this->R[ip](ii) - plo[ii] ) * inv_fdx[ii] + 0.5;
489 ijk[ii] = lxyz[ii];
490 wxyz_hi[ii] = lxyz[ii] - ijk[ii];
491 wxyz_lo[ii] = 1.0 - wxyz_hi[ii];
492 }
493
494 int& i = ijk[0];
495 int& j = ijk[1];
496 int& k = ijk[2];
497
498 bool use_coarse = false;
499
500 // AMReX: electrostatic_pic_3d.f90
501 // use the coarse E near the level boundary
502 if ( mfab(AmrIntVect_t(i-1, j-1, k-1)) == 1 ) {
503
504
505 for (int ii = 0; ii < 3; ++ii) {
506 lxyz[ii] = ( this->R[ip](ii) - cplo[ii] ) * inv_cdx[ii] + 0.5;
507 ijk[ii] = lxyz[ii];
508 wxyz_hi[ii] = lxyz[ii] - ijk[ii];
509 wxyz_lo[ii] = 1.0 - wxyz_hi[ii];
510 }
511 use_coarse = true;
512 }
513
514 AmrIntVect_t i1(i-1, j-1, k-1);
515 AmrIntVect_t i3(i-1, j, k-1);
516 AmrIntVect_t i5(i, j-1, k-1);
517 AmrIntVect_t i7(i, j, k-1);
518
519 AmrIntVect_t i2(i-1, j-1, k);
520 AmrIntVect_t i4(i-1, j, k);
521 AmrIntVect_t i6(i, j-1, k);
522 AmrIntVect_t i8(i, j, k);
523 if ( use_coarse ) {
524 pa[ip](0) = wxyz_lo[0] * wxyz_lo[1] * wxyz_lo[2] * cexfab(i1) +
525 wxyz_lo[0] * wxyz_hi[1] * wxyz_lo[2] * cexfab(i3) +
526 wxyz_hi[0] * wxyz_lo[1] * wxyz_lo[2] * cexfab(i5) +
527 wxyz_hi[0] * wxyz_hi[1] * wxyz_lo[2] * cexfab(i7) +
528 wxyz_lo[0] * wxyz_lo[1] * wxyz_hi[2] * cexfab(i2) +
529 wxyz_lo[0] * wxyz_hi[1] * wxyz_hi[2] * cexfab(i4) +
530 wxyz_hi[0] * wxyz_lo[1] * wxyz_hi[2] * cexfab(i6) +
531 wxyz_hi[0] * wxyz_hi[1] * wxyz_hi[2] * cexfab(i8);
532
533 pa[ip](1) = wxyz_lo[0] * wxyz_lo[1] * wxyz_lo[2] * ceyfab(i1) +
534 wxyz_lo[0] * wxyz_hi[1] * wxyz_lo[2] * ceyfab(i3) +
535 wxyz_hi[0] * wxyz_lo[1] * wxyz_lo[2] * ceyfab(i5) +
536 wxyz_hi[0] * wxyz_hi[1] * wxyz_lo[2] * ceyfab(i7) +
537 wxyz_lo[0] * wxyz_lo[1] * wxyz_hi[2] * ceyfab(i2) +
538 wxyz_lo[0] * wxyz_hi[1] * wxyz_hi[2] * ceyfab(i4) +
539 wxyz_hi[0] * wxyz_lo[1] * wxyz_hi[2] * ceyfab(i6) +
540 wxyz_hi[0] * wxyz_hi[1] * wxyz_hi[2] * ceyfab(i8);
541
542 pa[ip](2) = wxyz_lo[0] * wxyz_lo[1] * wxyz_lo[2] * cezfab(i1) +
543 wxyz_lo[0] * wxyz_hi[1] * wxyz_lo[2] * cezfab(i3) +
544 wxyz_hi[0] * wxyz_lo[1] * wxyz_lo[2] * cezfab(i5) +
545 wxyz_hi[0] * wxyz_hi[1] * wxyz_lo[2] * cezfab(i7) +
546 wxyz_lo[0] * wxyz_lo[1] * wxyz_hi[2] * cezfab(i2) +
547 wxyz_lo[0] * wxyz_hi[1] * wxyz_hi[2] * cezfab(i4) +
548 wxyz_hi[0] * wxyz_lo[1] * wxyz_hi[2] * cezfab(i6) +
549 wxyz_hi[0] * wxyz_hi[1] * wxyz_hi[2] * cezfab(i8);
550 } else {
551 pa[ip](0) = wxyz_lo[0] * wxyz_lo[1] * wxyz_lo[2] * exfab(i1) +
552 wxyz_lo[0] * wxyz_hi[1] * wxyz_lo[2] * exfab(i3) +
553 wxyz_hi[0] * wxyz_lo[1] * wxyz_lo[2] * exfab(i5) +
554 wxyz_hi[0] * wxyz_hi[1] * wxyz_lo[2] * exfab(i7) +
555 wxyz_lo[0] * wxyz_lo[1] * wxyz_hi[2] * exfab(i2) +
556 wxyz_lo[0] * wxyz_hi[1] * wxyz_hi[2] * exfab(i4) +
557 wxyz_hi[0] * wxyz_lo[1] * wxyz_hi[2] * exfab(i6) +
558 wxyz_hi[0] * wxyz_hi[1] * wxyz_hi[2] * exfab(i8);
559
560 pa[ip](1) = wxyz_lo[0] * wxyz_lo[1] * wxyz_lo[2] * eyfab(i1) +
561 wxyz_lo[0] * wxyz_hi[1] * wxyz_lo[2] * eyfab(i3) +
562 wxyz_hi[0] * wxyz_lo[1] * wxyz_lo[2] * eyfab(i5) +
563 wxyz_hi[0] * wxyz_hi[1] * wxyz_lo[2] * eyfab(i7) +
564 wxyz_lo[0] * wxyz_lo[1] * wxyz_hi[2] * eyfab(i2) +
565 wxyz_lo[0] * wxyz_hi[1] * wxyz_hi[2] * eyfab(i4) +
566 wxyz_hi[0] * wxyz_lo[1] * wxyz_hi[2] * eyfab(i6) +
567 wxyz_hi[0] * wxyz_hi[1] * wxyz_hi[2] * eyfab(i8);
568
569 pa[ip](2) = wxyz_lo[0] * wxyz_lo[1] * wxyz_lo[2] * ezfab(i1) +
570 wxyz_lo[0] * wxyz_hi[1] * wxyz_lo[2] * ezfab(i3) +
571 wxyz_hi[0] * wxyz_lo[1] * wxyz_lo[2] * ezfab(i5) +
572 wxyz_hi[0] * wxyz_hi[1] * wxyz_lo[2] * ezfab(i7) +
573 wxyz_lo[0] * wxyz_lo[1] * wxyz_hi[2] * ezfab(i2) +
574 wxyz_lo[0] * wxyz_hi[1] * wxyz_hi[2] * ezfab(i4) +
575 wxyz_hi[0] * wxyz_lo[1] * wxyz_hi[2] * ezfab(i6) +
576 wxyz_hi[0] * wxyz_hi[1] * wxyz_hi[2] * ezfab(i8);
577 }
578 // end amrex_interpolate_cic
579 }
580}
581
582#endif
amr::AmrField_t AmrField_t
Definition: PBunchDefs.h:34
bool scatter(Communicate &, InputIterator, InputIterator, RandomIterator, int *, int *, const ScatterOp &)
Definition: GlobalComm.hpp:353
amrex::IntVect AmrIntVect_t
Definition: AmrDefs.h:48
PLayout::AmrIntVect_t AmrIntVect_t
AmrParticleBase< PLayout >::AmrField_t AmrField_t
PLayout::AmrProcMap_t AmrProcMap_t
void AssignCellDensitySingleLevelFort(ParticleAttrib< AType > &pa, AmrField_t &mf, int level, const ParticleAttrib< int > &pbin, int bin=-1, int ncomp=1, int particle_lvl_offset=0) const
PLayout::AmrGeometry_t AmrGeometry_t
IpplTimings::TimerRef AssignDensityTimer_m
void InterpolateMultiLevelFort(ParticleAttrib< AType > &pa, AmrVectorFieldContainer_t &mesh_data, int lev)
void AssignDensityFort(ParticleAttrib< AType > &pa, AmrScalarFieldContainer_t &mf_to_be_filled, int lev_min, int ncomp, int finest_level, const ParticleAttrib< int > &pbin, int bin=-1) const
AmrParticleBase< PLayout >::AmrVectorField_t AmrVectorField_t
void gather(ParticleAttrib< FT > &attrib, AmrVectorFieldContainer_t &f, ParticleAttrib< Vektor< PT, Dim > > &pp, int lbase, int lfine)
PLayout::AmrGrid_t AmrGrid_t
AmrParticleBase< PLayout >::AmrVectorFieldContainer_t AmrVectorFieldContainer_t
void InterpolateFort(ParticleAttrib< AType > &pa, AmrVectorFieldContainer_t &mesh_data, int lev_min, int lev_max)
amrex::FArrayBox FArrayBox_t
PLayout::AmrReal_t AmrReal_t
void scatter(ParticleAttrib< FT > &attrib, AmrScalarFieldContainer_t &f, ParticleAttrib< Vektor< PT, Dim > > &pp, int lbase, int lfine, const ParticleAttrib< int > &pbin, int bin=-1)
AmrParticleBase< PLayout >::AmrScalarFieldContainer_t AmrScalarFieldContainer_t
void InterpolateSingleLevelFort(ParticleAttrib< AType > &pa, AmrVectorField_t &mesh_data, int lev)
The base class for all OPAL exceptions.
Definition: OpalException.h:28
Definition: Vektor.h:32
static TimerRef getTimer(const char *nm)
Definition: IpplTimings.h:182
static void stopTimer(TimerRef t)
Definition: IpplTimings.h:192
static void startTimer(TimerRef t)
Definition: IpplTimings.h:187