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