OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
AmrBoxLib.cpp
Go to the documentation of this file.
1 #include "AmrBoxLib.h"
2 
6 
7 #include "Amr/AmrYtWriter.h"
8 
9 #include <AMReX_MultiFabUtil.H>
10 
11 #include <AMReX_ParmParse.H> // used in initialize function
12 #include <AMReX_BCUtil.H>
13 
14 #include <map>
15 
16 extern Inform* gmsg;
17 
18 
20  const AmrIntArray_t& nGridPts,
21  int maxLevel,
22  AmrPartBunch* bunch_p)
23  : AmrObject()
24  , amrex::AmrMesh(&domain, maxLevel, nGridPts, 0 /* cartesian */)
25  , bunch_mp(bunch_p)
26  , layout_mp(static_cast<AmrLayout_t*>(&bunch_p->getLayout()))
27  , rho_m(maxLevel + 1)
28  , phi_m(maxLevel + 1)
29  , efield_m(maxLevel + 1)
30  , meshScaling_m(Vector_t(1.0, 1.0, 1.0))
31  , isFirstTagging_m(maxLevel + 1, true)
32  , isPoissonSolved_m(false)
33 {
34  /*
35  * The layout needs to know how many levels we can make.
36  */
37  layout_mp->resize(maxLevel);
38 
39  initBaseLevel_m(nGridPts);
40 
41  // set mesh spacing of bunch
42  updateMesh();
43 }
44 
45 
46 std::unique_ptr<AmrBoxLib> AmrBoxLib::create(const AmrInfo& info,
47  AmrPartBunch* bunch_p)
48 {
49  /* The bunch is initialized first with a Geometry,
50  * BoxArray and DistributionMapping on
51  * the base level (level = 0). Thus, we take the domain specified there in
52  * order to create the Amr object.
53  */
54  AmrLayout_t* layout_p = static_cast<AmrLayout_t*>(&bunch_p->getLayout());
55  AmrDomain_t domain = layout_p->Geom(0).ProbDomain();
56 
57  AmrIntArray_t nGridPts = {
58  info.grid[0],
59  info.grid[1],
60  info.grid[2]
61  };
62 
63  int maxlevel = info.maxlevel;
64 
65  /*
66  * further attributes are given by the BoxLib's ParmParse class.
67  */
68  initParmParse_m(info, layout_p);
69 
70  return std::unique_ptr<AmrBoxLib>(new AmrBoxLib(domain,
71  nGridPts,
72  maxlevel,
73  bunch_p
74  )
75  );
76 }
77 
78 
79 void AmrBoxLib::regrid(double time) {
81 
82  *gmsg << "* Start regriding:" << endl
83  << "* Old finest level: "
84  << finest_level << endl;
85 
86  /* ATTENTION: The bunch might be updated during
87  * the regrid process!
88  * We regrid from base level 0 up to the finest level.
89  */
90  int old_finest = finest_level;
91 
92  int lev_top = std::min(finest_level, max_level - 1);
93  for (int i = 0; i <= lev_top; ++i) {
94  this->doRegrid_m(i, time);
95  lev_top = std::min(finest_level, max_level - 1);
96  }
97 
98  this->postRegrid_m(old_finest);
99 
100  *gmsg << "* New finest level: "
101  << finest_level << endl
102  << "* Finished regriding" << endl;
103 
105 }
106 
107 
108 void AmrBoxLib::getGridStatistics(std::map<int, long>& gridPtsPerCore,
109  std::vector<int>& gridsPerLevel) const
110 {
111  typedef std::vector<int> container_t;
112 
113  gridPtsPerCore.clear();
114  gridsPerLevel.clear();
115 
116  gridsPerLevel.resize(max_level + 1);
117 
118  for (int lev = 0; lev <= finest_level; ++lev) {
119  /* container index: box
120  * container value: cores that owns box
121  */
122  const container_t& pmap = this->dmap[lev].ProcessorMap();
123  const AmrGrid_t& ba = this->grids[lev];
124 
125  gridsPerLevel[lev] = pmap.size();
126 
127  // iterate over all boxes
128  for (unsigned int i = 0; i < ba.size(); ++i) {
129  gridPtsPerCore[pmap[i]] += ba[i].numPts();
130  }
131  }
132 }
133 
134 
136  if ( bunch_mp->getNumBunch() > 1 && !refined_m ) {
137  *gmsg << "* Initialization of all levels" << endl;
138 
140 
141  /* we do an explicit domain mapping of the particles and then
142  * forbid it during the regrid process, this way it's only
143  * executed ones --> saves computation
144  */
145  bool isForbidTransform = amrpbase_p->isForbidTransform();
146 
147  if ( !isForbidTransform ) {
148  amrpbase_p->domainMapping();
149  amrpbase_p->setForbidTransform(true);
150  }
151 
152  if ( max_level > 0 ) {
153  this->regrid(bunch_mp->getT() * 1.0e9 /*time [ns] */);
154  }
155 
156  if ( !isForbidTransform ) {
157  amrpbase_p->setForbidTransform(false);
158  // map particles back
159  amrpbase_p->domainMapping(true);
160  }
161 
162  *gmsg << "* Initialization done." << endl;
163 
164  refined_m = true;
165  }
166 }
167 
168 
170  Vector_t maxE = Vector_t(0, 0, 0), minE = Vector_t(0, 0, 0);
171  /* check for maximum / minimum values over all levels
172  * and all components, i.e. Ex, Ey, Ez
173  */
174  for (unsigned int lev = 0; lev < efield_m.size(); ++lev) {
175  for (std::size_t i = 0; i < bunch_mp->Dimension; ++i) {
176  /* calls:
177  * - max(comp, nghost (to search), local)
178  * - min(cmop, nghost, local)
179  */
180  double max = efield_m[lev][i]->max(0, false);
181  maxE[i] = (maxE[i] < max) ? max : maxE[i];
182 
183  double min = efield_m[lev][i]->min(0, false);
184  minE[i] = (minE[i] > min) ? min : minE[i];
185  }
186  }
187 
188  return VectorPair_t(maxE, minE);
189 }
190 
191 
192 double AmrBoxLib::getRho(int x, int y, int z) {
193  //TODO
194  throw OpalException("AmrBoxLib::getRho(x, y, z)", "Not yet Implemented.");
195  return 0.0;
196 }
197 
198 
200  //TODO
201  throw OpalException("AmrBoxLib::computeSelfFields", "Not yet Implemented.");
202 }
203 
204 
206  //TODO
207  throw OpalException("AmrBoxLib::computeSelfFields(int bin)", "Not yet Implemented.");
208 }
209 
210 
212  /*
213  * The potential is not scaled according to domain modification.
214  *
215  */
216  if ( !bunch_mp->hasFieldSolver() )
217  return;
218 
219  /*
220  * scatter charges onto grid
221  */
223 
227 
228  // map on Amr domain + Lorentz transform
229  double scalefactor = amrpbase_p->domainMapping();
230 
231  amrpbase_p->setForbidTransform(true);
232  amrpbase_p->update();
233  amrpbase_p->setForbidTransform(false);
234 
236  amrpbase_p->scatter(bunch_mp->Q, this->rho_m, bunch_mp->R, 0, finest_level, bunch_mp->Bin);
237 
238  int baseLevel = 0;
239  int nLevel = finest_level + 1;
240  double invGamma = 1.0 / gamma;
241 
242 
243  // mesh scaling for solver
244  meshScaling_m = Vector_t(1.0, 1.0, 1.0);
245 
246  // charge density is in rho_m
247  // calculate Possion equation (with coefficient: -1/(eps))
248  for (int i = 0; i <= finest_level; ++i) {
249  if ( this->rho_m[i]->contains_nan(false) )
250  throw OpalException("AmrBoxLib::computeSelfFields_cycl(double gamma) ",
251  "NANs at level " + std::to_string(i) + ".");
252  this->rho_m[i]->mult(-1.0 / Physics::epsilon_0, 0, 1);
253  }
254 
255  // find maximum and normalize each level (faster convergence)
256  double l0norm = 1.0;
257  for (int i = 0; i <= finest_level; ++i)
258  l0norm = std::max(l0norm, this->rho_m[i]->norm0(0));
259 
260  for (int i = 0; i <= finest_level; ++i) {
261  this->rho_m[i]->mult(1.0 / l0norm, 0, 1);
262  }
263 
265 
267  solver->solve(rho_m, phi_m, efield_m, baseLevel, finest_level);
269 
270  // make sure ghost cells are filled
271  for (int i = 0; i <= finest_level; ++i) {
272  phi_m[i]->FillBoundary(geom[i].periodicity());
273  for (int j = 0; j < AMREX_SPACEDIM; ++j) {
274  efield_m[i][j]->FillBoundary(geom[i].periodicity());
275  }
276  }
277 
278  this->fillPhysbc_m(*(this->phi_m[0]), 0);
279 
280  /* apply scale of electric-field in order to undo the transformation
281  * + undo normalization
282  */
283  for (int i = 0; i <= finestLevel(); ++i) {
284  this->phi_m[i]->mult(scalefactor * l0norm, 0, 1);
285  for (int j = 0; j < AMREX_SPACEDIM; ++j) {
286  this->efield_m[i][j]->mult(scalefactor * scalefactor * l0norm, 0, 1);
287  }
288  }
289 
290  for (int i = 0; i <= finest_level; ++i) {
291  for (int j = 0; j < AMREX_SPACEDIM; ++j) {
292  if ( this->efield_m[i][j]->contains_nan(false) )
293  throw OpalException("AmrBoxLib::computeSelfFields_cycl(double gamma) ",
294  "Ef: NANs at level " + std::to_string(i) + ".");
295  }
296  }
297 
298 
299  amrpbase_p->gather(bunch_mp->Ef, this->efield_m, bunch_mp->R, 0, finest_level);
300 
301  // undo domain change + undo Lorentz transform
302  amrpbase_p->domainMapping(true);
303 
305  bunch_mp->Ef *= Vector_t(gamma,
306  1.0,
307  gamma);
308 
310  // Relativistic E&M says gamma*v/c^2 = gamma*beta/c = sqrt(gamma*gamma-1)/c
311  // but because we already transformed E_trans into the moving frame we have to
312  // add 1/gamma so we are using the E_trans from the rest frame -DW
313  double betaC = std::sqrt(gamma * gamma - 1.0) * invGamma / Physics::c;
314 
316  bunch_mp->Bf(0) = betaC * bunch_mp->Ef(2);
317  bunch_mp->Bf(2) = -betaC * bunch_mp->Ef(0);
318 
319  /*
320  * dumping only
321  */
322 
325 
326  AmrIntArray_t rr(finest_level);
327  for (int i = 0; i < finest_level; ++i)
328  rr[i] = this->MaxRefRatio(i);
329 
330  double time = bunch_mp->getT(); // in seconds
331 
332  // we need to undo coefficient when writing charge density
333  for (int i = 0; i <= finest_level; ++i)
334  this->rho_m[i]->mult(- Physics::epsilon_0 * l0norm, 0, 1);
335 
336 
337  ytWriter.writeFields(rho_m, phi_m, efield_m, rr, this->geom,
338  nLevel, time, scalefactor);
339 
340  ytWriter.writeBunch(bunch_mp, time, gamma);
341  }
342 }
343 
344 
346 
347  if ( !bunch_mp->hasFieldSolver() )
348  return;
349 
351  double gamma = bunch_mp->getBinGamma(bin);
352 
353  /* relativistic factor is always gamma >= 1
354  * --> if no particle --> gamma = 0 --> leave computation
355  */
356  if ( gamma < 1.0 )
357  return;
358 
359  /*
360  * scatter charges onto grid
361  */
363 
364  // Lorentz transformation: apply Lorentz factor of that particle bin
366 
367  // map on Amr domain + Lorentz transform
368  double scalefactor = amrpbase_p->domainMapping();
369 
370  amrpbase_p->setForbidTransform(true);
371 
372  amrpbase_p->update();
373 
375  this->regrid(bunch_mp->getT() * 1.0e9 /*time [ns] */);
376  }
377 
378  amrpbase_p->setForbidTransform(false);
379 
382  amrpbase_p->scatter(bunch_mp->Q, this->rho_m, bunch_mp->R, 0, finest_level, bunch_mp->Bin, bin);
383 
385  // In particle rest frame, the longitudinal length (y for cyclotron) enlarged
386  // calculate Possion equation (with coefficient: -1/(eps))
387  for (int i = 0; i <= finest_level; ++i) {
388  this->rho_m[i]->mult(-1.0 / (Physics::epsilon_0), 0 /*comp*/, 1 /*ncomp*/);
389 
390  if ( this->rho_m[i]->contains_nan(false) )
391  throw OpalException("AmrBoxLib::computeSelfFields_cycl(int bin) ",
392  "NANs at level " + std::to_string(i) + ".");
393  }
394 
395  // find maximum and normalize each level (faster convergence)
396  double l0norm = 1.0;
397  for (int i = 0; i <= finest_level; ++i)
398  l0norm = std::max(l0norm, this->rho_m[i]->norm0(0));
399 
400  for (int i = 0; i <= finest_level; ++i) {
401  this->rho_m[i]->mult(1.0 / l0norm, 0, 1);
402  }
403 
404  // mesh scaling for solver
405  meshScaling_m = Vector_t(1.0, 1.0, 1.0);
406 
408 
410 
411  for (int i = 0; i <= finest_level; ++i) {
412  phi_m[i]->setVal(0.0, 0, phi_m[i]->nComp(), phi_m[i]->nGrow());
413  for (int j = 0; j < AMREX_SPACEDIM; ++j) {
414  efield_m[i][j]->setVal(0.0, 0, efield_m[i][j]->nComp(), efield_m[i][j]->nGrow());
415  }
416  }
417 
418  // in case of binning we reset phi every time
419  solver->solve(rho_m, phi_m, efield_m, 0, finest_level, false);
420 
422 
423  // make sure ghost cells are filled
424  for (int i = 0; i <= finest_level; ++i) {
425  phi_m[i]->FillBoundary(geom[i].periodicity());
426  for (int j = 0; j < AMREX_SPACEDIM; ++j) {
427  efield_m[i][j]->FillBoundary(geom[i].periodicity());
428  }
429  }
430 
431  this->fillPhysbc_m(*(this->phi_m[0]), 0);
432 
433 
434  /* apply scale of electric-field in order to undo the transformation
435  * + undo normalization
436  */
437  for (int i = 0; i <= finestLevel(); ++i) {
438  this->phi_m[i]->mult(scalefactor * l0norm, 0, 1);
439  for (int j = 0; j < AMREX_SPACEDIM; ++j) {
440  this->efield_m[i][j]->mult(scalefactor * scalefactor * l0norm, 0, 1);
441  }
442  }
443 
444  for (int i = 0; i <= finest_level; ++i) {
445  for (int j = 0; j < AMREX_SPACEDIM; ++j) {
446  if ( this->efield_m[i][j]->contains_nan(false) )
447  throw OpalException("AmrBoxLib::computeSelfFields_cycl(double gamma) ",
448  "Ef: NANs at level " + std::to_string(i) + ".");
449  }
450  }
451 
452  amrpbase_p->gather(bunch_mp->Eftmp, this->efield_m, bunch_mp->R, 0, finest_level);
453 
454  // undo domain change + undo Lorentz transform
455  amrpbase_p->domainMapping(true);
456 
458  bunch_mp->Eftmp *= Vector_t(gamma, 1.0, gamma);
459 
461  double betaC = std::sqrt(gamma * gamma - 1.0) / gamma / Physics::c;
462 
464  bunch_mp->Bf(0) += betaC * bunch_mp->Eftmp(2);
465  bunch_mp->Bf(2) -= betaC * bunch_mp->Eftmp(0);
466 
467  bunch_mp->Ef += bunch_mp->Eftmp;
468 
469  /*
470  * dumping only
471  */
473  AmrYtWriter ytWriter(bunch_mp->getLocalTrackStep(), bin);
474 
475  int nLevel = finest_level + 1;
476 
477  AmrIntArray_t rr(finest_level);
478  for (int i = 0; i < finest_level; ++i)
479  rr[i] = this->MaxRefRatio(i);
480 
481  double time = bunch_mp->getT(); // in seconds
482 
483  // we need to undo coefficient when writing charge density
484  for (int i = 0; i <= finest_level; ++i)
485  this->rho_m[i]->mult(- Physics::epsilon_0 * l0norm, 0, 1);
486 
487 
488  ytWriter.writeFields(rho_m, phi_m, efield_m, rr, this->geom,
489  nLevel, time, scalefactor);
490 
491  ytWriter.writeBunch(bunch_mp, time, gamma);
492  }
493 
494  isPoissonSolved_m = true;
495 }
496 
497 
499  //FIXME What about resizing mesh, i.e. geometry?
500  const AmrReal_t* tmp = this->geom[0].CellSize();
501 
502  Vector_t hr;
503  for (int i = 0; i < 3; ++i)
504  hr[i] = tmp[i];
505 
507 }
508 
509 
511  return meshScaling_m;
512 }
513 
514 
516  const Box_t& bx = this->geom[0].Domain();
517 
518  const AmrIntVect_t& low = bx.smallEnd();
519  const AmrIntVect_t& high = bx.bigEnd();
520 
521  return Vektor<int, 3>(high[0] - low[0] + 1,
522  high[1] - low[1] + 1,
523  high[2] - low[2] + 1);
524 }
525 
526 
527 inline const int& AmrBoxLib::maxLevel() const {
528  return this->max_level;
529 }
530 
531 
532 inline const int& AmrBoxLib::finestLevel() const {
533  return this->finest_level;
534 }
535 
536 
537 inline double AmrBoxLib::getT() const {
538  return bunch_mp->getT();
539 }
540 
541 
543 //
544 // // copied + modified version of AMReX_Amr.cpp
545 // AmrProcMap_t::InitProximityMap();
547 //
548 // AmrGridContainer_t allBoxes(finest_level + 1);
549 // for(unsigned int ilev = 0; ilev < allBoxes.size(); ++ilev) {
550 // allBoxes[ilev] = boxArray(ilev);
551 // }
552 // amrex::Vector<AmrIntArray_t> mLDM;
553 //
554 // switch ( how ) {
555 // case RANK_ZERO:
556 // mLDM = AmrProcMap_t::MultiLevelMapRandom(this->ref_ratio,
557 // allBoxes,
558 // maxGridSize(0),
559 // 0/*maxRank*/,
560 // 0/*minRank*/);
561 // break;
562 // case PFC:
563 // mLDM = AmrProcMap_t::MultiLevelMapPFC(this->ref_ratio,
564 // allBoxes,
565 // maxGridSize(0));
566 // break;
567 // case RANDOM:
568 // mLDM = AmrProcMap_t::MultiLevelMapRandom(this->ref_ratio,
569 // allBoxes,
570 // maxGridSize(0));
571 // break;
572 // case KNAPSACK:
573 // mLDM = AmrProcMap_t::MultiLevelMapKnapSack(this->ref_ratio,
574 // allBoxes,
575 // maxGridSize(0));
576 // break;
577 // default:
578 // *gmsg << "We didn't redistribute the grids." << endl;
579 // return;
580 // }
581 //
582 // for(unsigned int iMap = 0; iMap < mLDM.size(); ++iMap) {
583 // AmrField_t::MoveAllFabs(mLDM[iMap]);
584 // }
585 //
586 // /*
587 // * particles need to know the BoxArray
588 // * and DistributionMapping
589 // */
590 // for(unsigned int ilev = 0; ilev < allBoxes.size(); ++ilev) {
591 // layout_mp->SetParticleBoxArray(ilev, this->grids[ilev]);
592 // layout_mp->SetParticleDistributionMap(ilev, this->dmap[ilev]);
593 // }
594 //
595 // for(unsigned int iMap = 0; iMap < mLDM.size(); ++iMap) {
596 // rho_m[iMap]->MoveFabs(mLDM[iMap]);
597 // phi_m[iMap]->MoveFabs(mLDM[iMap]);
598 // efield_m[iMap]->MoveFabs(mLDM[iMap]);
599 // }
600 }
601 
602 
603 void AmrBoxLib::RemakeLevel (int lev, AmrReal_t time,
604  const AmrGrid_t& new_grids,
605  const AmrProcMap_t& new_dmap)
606 {
607  SetBoxArray(lev, new_grids);
608  SetDistributionMap(lev, new_dmap);
609 
610  // #comp #ghosts cells
611  rho_m[lev].reset(new AmrField_t(new_grids, new_dmap, 1, 0));
612  phi_m[lev].reset(new AmrField_t(new_grids, new_dmap, 1, 1));
613  for (int j = 0; j < AMREX_SPACEDIM; ++j) {
614  efield_m[lev][j].reset(new AmrField_t(new_grids, new_dmap, 1, 1));
615  }
616 
617  // including nghost = 1
618  rho_m[lev]->setVal(0.0, 0);
619  phi_m[lev]->setVal(0.0, 1);
620 
621  for (int j = 0; j < AMREX_SPACEDIM; ++j) {
622  efield_m[lev][j]->setVal(0.0, 1);
623  }
624 
625  /*
626  * particles need to know the BoxArray
627  * and DistributionMapping
628  */
629  layout_mp->SetParticleBoxArray(lev, new_grids);
630  layout_mp->SetParticleDistributionMap(lev, new_dmap);
631 
632  layout_mp->buildLevelMask(lev, this->nErrorBuf(lev));
633 }
634 
635 
636 void AmrBoxLib::MakeNewLevel (int lev, AmrReal_t time,
637  const AmrGrid_t& new_grids,
638  const AmrProcMap_t& new_dmap)
639 {
640  SetBoxArray(lev, new_grids);
641  SetDistributionMap(lev, new_dmap);
642 
643  // #comp #ghosts cells
644  rho_m[lev].reset(new AmrField_t(new_grids, new_dmap, 1, 0));
645  phi_m[lev].reset(new AmrField_t(new_grids, new_dmap, 1, 1));
646 
647  for (int j = 0; j < AMREX_SPACEDIM; ++j) {
648  efield_m[lev][j].reset(new AmrField_t(new_grids, new_dmap, 1, 1));
649  }
650 
651  // including nghost = 1
652  rho_m[lev]->setVal(0.0, 0);
653  phi_m[lev]->setVal(0.0, 1);
654  for (int j = 0; j < AMREX_SPACEDIM; ++j) {
655  efield_m[lev][j]->setVal(0.0, 1);
656  }
657 
658 
659 
660  /*
661  * particles need to know the BoxArray
662  * and DistributionMapping
663  */
664  layout_mp->SetParticleBoxArray(lev, new_grids);
665  layout_mp->SetParticleDistributionMap(lev, new_dmap);
666 
667  layout_mp->buildLevelMask(lev, this->nErrorBuf(lev));
668 }
669 
670 
671 void AmrBoxLib::ClearLevel(int lev) {
672  rho_m[lev].reset(nullptr);
673  phi_m[lev].reset(nullptr);
674  for (int j = 0; j < AMREX_SPACEDIM; ++j) {
675  efield_m[lev][j].reset(nullptr);
676  }
677  ClearBoxArray(lev);
678  ClearDistributionMap(lev);
679 
680  this->isFirstTagging_m[lev] = true;
681 }
682 
683 
684 void AmrBoxLib::ErrorEst(int lev, TagBoxArray_t& tags,
685  AmrReal_t time, int ngrow)
686 {
687  *gmsg << level2 << "* Start tagging of level " << lev << endl;
688 
689  switch ( tagging_m ) {
690  case CHARGE_DENSITY:
691  tagForChargeDensity_m(lev, tags, time, ngrow);
692  break;
693  case POTENTIAL:
694  tagForPotentialStrength_m(lev, tags, time, ngrow);
695  break;
696  case EFIELD:
697  tagForEfield_m(lev, tags, time, ngrow);
698  break;
699  case MOMENTA:
700  tagForMomenta_m(lev, tags, time, ngrow);
701  break;
702  case MAX_NUM_PARTICLES:
703  tagForMaxNumParticles_m(lev, tags, time, ngrow);
704  break;
705  case MIN_NUM_PARTICLES:
706  tagForMinNumParticles_m(lev, tags, time, ngrow);
707  break;
708  default:
709  tagForChargeDensity_m(lev, tags, time, ngrow);
710  break;
711  }
712 
713  *gmsg << level2 << "* Finished tagging of level " << lev << endl;
714 }
715 
716 
718  const AmrGrid_t& ba,
719  const AmrProcMap_t& dm)
720 {
721  throw OpalException("AmrBoxLib::MakeNewLevelFromScratch()", "Shouldn't be called.");
722 }
723 
724 
726  const AmrGrid_t& ba,
727  const AmrProcMap_t& dm)
728 {
729  throw OpalException("AmrBoxLib::MakeNewLevelFromCoarse()", "Shouldn't be called.");
730 }
731 
732 
733 void AmrBoxLib::doRegrid_m(int lbase, double time) {
734  int new_finest = 0;
735  AmrGridContainer_t new_grids(finest_level+2);
736 
737  MakeNewGrids(lbase, time, new_finest, new_grids);
738 
739  BL_ASSERT(new_finest <= finest_level+1);
740 
741  for (int lev = lbase+1; lev <= new_finest; ++lev)
742  {
743  if (lev <= finest_level) // an old level
744  {
745  if (new_grids[lev] != grids[lev]) // otherwise nothing
746  {
747  AmrProcMap_t new_dmap(new_grids[lev]);
748  RemakeLevel(lev, time, new_grids[lev], new_dmap);
749  }
750  }
751  else // a new level
752  {
753  AmrProcMap_t new_dmap(new_grids[lev]);
754  MakeNewLevel(lev, time, new_grids[lev], new_dmap);
755  }
756 
757  layout_mp->setFinestLevel(new_finest);
758  }
759 
760  // now we are safe to delete deprecated levels
761  for (int lev = new_finest+1; lev <= finest_level; ++lev) {
762  ClearLevel(lev);
763  }
764 
765  finest_level = new_finest;
766 }
767 
768 
769 void AmrBoxLib::postRegrid_m(int old_finest) {
770  /* ATTENTION: In this call the bunch has to be updated
771  * since each particle needs to be assigned to its latest
772  * grid and sent to the corresponding MPI-process.
773  *
774  * We need to update the bunch before we clear
775  * levels, otherwise the particle level counter
776  * is invalidated.
777  */
778 
779  // redistribute particles and assign correct grid and level
781  amrpbase_p->update(0, finest_level, true);
782 
783  // check if no particles left on higher levels
784  const auto& LocalNumPerLevel = amrpbase_p->getLocalNumPerLevel();
785 
786  for (int lev = finest_level+1; lev <= old_finest; ++lev) {
787  if ( LocalNumPerLevel.getLocalNumAtLevel(lev) != 0 ) {
788  throw OpalException("AmrBoxLib::postRegrid_m()",
789  "Still particles on level " + std::to_string(lev) + "!");
790  }
791  layout_mp->ClearParticleBoxArray(lev);
792  layout_mp->ClearParticleDistributionMap(lev);
794  }
795 
796  if ( bunch_mp->getLocalNum() != LocalNumPerLevel.getLocalNumUpToLevel(finest_level) ) {
797  std::string localnum = std::to_string(bunch_mp->getLocalNum());
798  std::string levelnum = std::to_string(LocalNumPerLevel.getLocalNumUpToLevel(finest_level));
799  throw OpalException("AmrBoxLib::postRegrid_m()",
800  "Number of particles do not agree: " + localnum + " != " + levelnum);
801  }
802 
804  solver->hasToRegrid();
805 }
806 
807 
809  AmrReal_t time, int ngrow)
810 {
811  // we need to update first
813  amrpbase_p->update(0, lev, true);
814 
815  for (int i = lev; i <= finest_level; ++i)
816  rho_m[i]->setVal(0.0, rho_m[i]->nGrow());
817 
818  // the new scatter function averages the value also down to the coarsest level
819  amrpbase_p->scatter(bunch_mp->Q, rho_m,
820  bunch_mp->R, 0, lev, bunch_mp->Bin);
821 
822  const double& scalefactor = amrpbase_p->getScalingFactor();
823 
824  for (int i = lev; i <= finest_level; ++i)
825  rho_m[i]->mult(scalefactor, 0, 1);
826 
827  const int clearval = TagBox_t::CLEAR;
828  const int tagval = TagBox_t::SET;
829 
830 #ifdef _OPENMP
831 #pragma omp parallel
832 #endif
833  {
834  for (MFIter_t mfi(*rho_m[lev], true); mfi.isValid(); ++mfi) {
835  const Box_t& tilebx = mfi.tilebox();
836 
837  TagBox_t& tagfab = tags[mfi];
838  FArrayBox_t& fab = (*rho_m[lev])[mfi];
839 
840  const int* tlo = tilebx.loVect();
841  const int* thi = tilebx.hiVect();
842 
843  for (int i = tlo[0]; i <= thi[0]; ++i) {
844  for (int j = tlo[1]; j <= thi[1]; ++j) {
845  for (int k = tlo[2]; k <= thi[2]; ++k) {
846 
847  amrex::IntVect iv(D_DECL(i,j,k));
848 
849  if ( std::abs( fab(iv) ) >= chargedensity_m )
850  tagfab(iv) = tagval;
851  else
852  tagfab(iv) = clearval;
853  }
854  }
855  }
856  }
857  }
858 }
859 
860 
862  AmrReal_t time, int ngrow)
863 {
864  /* Tag all cells for refinement
865  * where the value of the potential is higher than 75 percent of the maximum potential
866  * value of this level.
867  */
868  if ( !isPoissonSolved_m || !phi_m[lev]->ok() || this->isFirstTagging_m[lev] ) {
869  *gmsg << level2 << "* Level " << lev << ": We need to perform "
870  << "charge tagging if a new level is created." << endl;
871  this->tagForChargeDensity_m(lev, tags, time, ngrow);
872  this->isFirstTagging_m[lev] = false;
873  return;
874  }
875 
876  // tag cells for refinement
877  const int clearval = TagBox_t::CLEAR;
878  const int tagval = TagBox_t::SET;
879 
880  AmrReal_t threshold = phi_m[lev]->norm0(0, 0 /*nghost*/, false /*local*/);
881 
882  threshold *= scaling_m;
883 
884 #ifdef _OPENMP
885 #pragma omp parallel
886 #endif
887  {
888  for (MFIter_t mfi(*phi_m[lev], true); mfi.isValid(); ++mfi) {
889 
890  const Box_t& tilebx = mfi.tilebox();
891  TagBox_t& tagfab = tags[mfi];
892  FArrayBox_t& fab = (*phi_m[lev])[mfi];
893 
894  const int* tlo = tilebx.loVect();
895  const int* thi = tilebx.hiVect();
896 
897  for (int i = tlo[0]; i <= thi[0]; ++i) {
898  for (int j = tlo[1]; j <= thi[1]; ++j) {
899  for (int k = tlo[2]; k <= thi[2]; ++k) {
900 
901  amrex::IntVect iv(D_DECL(i,j,k));
902 
903  if ( std::abs( fab(iv) ) >= threshold )
904  tagfab(iv) = tagval;
905  else
906  tagfab(iv) = clearval;
907  }
908  }
909  }
910  }
911  }
912 }
913 
914 
916  AmrReal_t time, int ngrow)
917 {
918  /* Tag all cells for refinement
919  * where the value of the efield is higher than 75 percent of the maximum efield
920  * value of this level.
921  */
922  if ( !isPoissonSolved_m || !efield_m[lev][0]->ok() || this->isFirstTagging_m[lev] ) {
923  *gmsg << level2 << "* Level " << lev << ": We need to perform "
924  << "charge tagging if a new level is created." << endl;
925  this->tagForChargeDensity_m(lev, tags, time, ngrow);
926  this->isFirstTagging_m[lev] = false;
927  return;
928  }
929 
930  // tag cells for refinement
931  const int clearval = TagBox_t::CLEAR;
932  const int tagval = TagBox_t::SET;
933 
934  // obtain maximum absolute value
935  amrex::Vector<AmrReal_t> threshold(AMREX_SPACEDIM);
936 
937  for (int i = 0; i < 3; ++i) {
938  threshold[i] = efield_m[lev][i]->norm0(0,
939  0 /*nghosts*/,
940  false /*local*/);
941 
942  threshold[i] *= scaling_m;
943  }
944 
945 #ifdef _OPENMP
946 #pragma omp parallel
947 #endif
948  {
949  for (MFIter_t mfi(this->grids[lev], this->dmap[lev], true); mfi.isValid(); ++mfi) {
950 
951  const Box_t& tilebx = mfi.tilebox();
952  TagBox_t& tagfab = tags[mfi];
953  FArrayBox_t& xfab = (*efield_m[lev][0])[mfi];
954  FArrayBox_t& yfab = (*efield_m[lev][1])[mfi];
955  FArrayBox_t& zfab = (*efield_m[lev][2])[mfi];
956 
957  const int* tlo = tilebx.loVect();
958  const int* thi = tilebx.hiVect();
959 
960  for (int i = tlo[0]; i <= thi[0]; ++i) {
961  for (int j = tlo[1]; j <= thi[1]; ++j) {
962  for (int k = tlo[2]; k <= thi[2]; ++k) {
963  AmrIntVect_t iv(i,j,k);
964  if (std::abs(xfab(iv)) >= threshold[0])
965  tagfab(iv) = tagval;
966  else if (std::abs(yfab(iv)) >= threshold[1])
967  tagfab(iv) = tagval;
968  else if (std::abs(zfab(iv)) >= threshold[2])
969  tagfab(iv) = tagval;
970  else
971  tagfab(iv) = clearval;
972  }
973  }
974  }
975  }
976  }
977 }
978 
979 
981  AmrReal_t time, int ngrow)
982 {
984  // we need to update first
985  amrpbase_p->update(0, lev, true);
986  const auto& LocalNumPerLevel = amrpbase_p->getLocalNumPerLevel();
987 
988  size_t lBegin = LocalNumPerLevel.begin(lev);
989  size_t lEnd = LocalNumPerLevel.end(lev);
990 
991  Vector_t pmax = Vector_t(0.0, 0.0, 0.0);
992  for (size_t i = lBegin; i < lEnd; ++i) {
993  const Vector_t& tmp = bunch_mp->P[i];
994  pmax = ( dot(tmp, tmp) > dot(pmax, pmax) ) ? tmp : pmax;
995  }
996 
997  double momentum2 = scaling_m * dot(pmax, pmax);
998 
999  std::map<AmrIntVect_t, bool> cells;
1000  for (size_t i = lBegin; i < lEnd; ++i) {
1001  if ( dot(bunch_mp->P[i], bunch_mp->P[i]) >= momentum2 ) {
1002  AmrIntVect_t iv = layout_mp->Index(bunch_mp->R[i], lev);
1003  cells[iv] = true;
1004  }
1005  }
1006 
1007  const int clearval = TagBox_t::CLEAR;
1008  const int tagval = TagBox_t::SET;
1009 
1010 
1011 #ifdef _OPENMP
1012 #pragma omp parallel
1013 #endif
1014  {
1015  for (MFIter_t mfi(*rho_m[lev], true); mfi.isValid(); ++mfi) {
1016 
1017  const Box_t& tilebx = mfi.tilebox();
1018  TagBox_t& tagfab = tags[mfi];
1019 
1020  const int* tlo = tilebx.loVect();
1021  const int* thi = tilebx.hiVect();
1022 
1023  for (int i = tlo[0]; i <= thi[0]; ++i) {
1024  for (int j = tlo[1]; j <= thi[1]; ++j) {
1025  for (int k = tlo[2]; k <= thi[2]; ++k) {
1026  AmrIntVect_t iv(i, j, k);
1027  if ( cells.find(iv) != cells.end() )
1028  tagfab(iv) = tagval;
1029  else
1030  tagfab(iv) = clearval;
1031  }
1032  }
1033  }
1034  }
1035  }
1036 }
1037 
1038 
1040  AmrReal_t time, int ngrow)
1041 {
1043  // we need to update first
1044  amrpbase_p->update(0, lev, true);
1045  const auto& LocalNumPerLevel = amrpbase_p->getLocalNumPerLevel();
1046 
1047  size_t lBegin = LocalNumPerLevel.begin(lev);
1048  size_t lEnd = LocalNumPerLevel.end(lev);
1049 
1050  // count particles per cell
1051  std::map<AmrIntVect_t, size_t> cells;
1052  for (size_t i = lBegin; i < lEnd; ++i) {
1053  AmrIntVect_t iv = layout_mp->Index(bunch_mp->R[i], lev);
1054  ++cells[iv];
1055  }
1056 
1057  const int clearval = TagBox_t::CLEAR;
1058  const int tagval = TagBox_t::SET;
1059 
1060 
1061 #ifdef _OPENMP
1062 #pragma omp parallel
1063 #endif
1064  {
1065  for (MFIter_t mfi(*rho_m[lev], true); mfi.isValid(); ++mfi) {
1066 
1067  const Box_t& tilebx = mfi.tilebox();
1068  TagBox_t& tagfab = tags[mfi];
1069 
1070  const int* tlo = tilebx.loVect();
1071  const int* thi = tilebx.hiVect();
1072 
1073  for (int i = tlo[0]; i <= thi[0]; ++i) {
1074  for (int j = tlo[1]; j <= thi[1]; ++j) {
1075  for (int k = tlo[2]; k <= thi[2]; ++k) {
1076  AmrIntVect_t iv(i, j, k);
1077  if ( cells.find(iv) != cells.end() && cells[iv] <= maxNumPart_m )
1078  tagfab(iv) = tagval;
1079  else
1080  tagfab(iv) = clearval;
1081  }
1082  }
1083  }
1084  }
1085  }
1086 }
1087 
1088 
1090  AmrReal_t time, int ngrow)
1091 {
1093  // we need to update first
1094  amrpbase_p->update(0, lev, true);
1095  const auto& LocalNumPerLevel = amrpbase_p->getLocalNumPerLevel();
1096 
1097  size_t lBegin = LocalNumPerLevel.begin(lev);
1098  size_t lEnd = LocalNumPerLevel.end(lev);
1099 
1100  // count particles per cell
1101  std::map<AmrIntVect_t, size_t> cells;
1102  for (size_t i = lBegin; i < lEnd; ++i) {
1103  AmrIntVect_t iv = layout_mp->Index(bunch_mp->R[i], lev);
1104  ++cells[iv];
1105  }
1106 
1107  const int clearval = TagBox_t::CLEAR;
1108  const int tagval = TagBox_t::SET;
1109 
1110 
1111 #ifdef _OPENMP
1112 #pragma omp parallel
1113 #endif
1114  {
1115  for (MFIter_t mfi(*rho_m[lev], true); mfi.isValid(); ++mfi) {
1116 
1117  const Box_t& tilebx = mfi.tilebox();
1118  TagBox_t& tagfab = tags[mfi];
1119 
1120  const int* tlo = tilebx.loVect();
1121  const int* thi = tilebx.hiVect();
1122 
1123  for (int i = tlo[0]; i <= thi[0]; ++i) {
1124  for (int j = tlo[1]; j <= thi[1]; ++j) {
1125  for (int k = tlo[2]; k <= thi[2]; ++k) {
1126  AmrIntVect_t iv(i, j, k);
1127  if ( cells.find(iv) != cells.end() &&
1128  cells[iv] >= minNumPart_m )
1129  {
1130  tagfab(iv) = tagval;
1131  } else
1132  tagfab(iv) = clearval;
1133  }
1134  }
1135  }
1136  }
1137  }
1138 }
1139 
1140 
1142  // we need to set the AmrCore variable
1143  finest_level = 0;
1144 
1145  AmrIntVect_t low(0, 0, 0);
1146  AmrIntVect_t high(nGridPts[0] - 1,
1147  nGridPts[1] - 1,
1148  nGridPts[2] - 1);
1149 
1150  const Box_t bx(low, high);
1151  AmrGrid_t ba(bx);
1152  ba.maxSize( this->maxGridSize(0) );
1153 
1154  // chop grids to guarantee #grids == #procs on base level
1155  ba = this->MakeBaseGrids();
1156 
1157  AmrProcMap_t dmap;
1158  dmap.define(ba, amrex::ParallelDescriptor::NProcs());
1159 
1160  this->RemakeLevel(0, 0.0, ba, dmap);
1161 
1162  layout_mp->define(this->geom);
1163  layout_mp->define(this->ref_ratio);
1164 }
1165 
1166 
1168 
1169  /*
1170  * All parameters that we set with the OPAL input file
1171  */
1172  amrex::ParmParse pAmr("amr");
1173  pAmr.add("max_grid_size_x", info.maxgrid[0]);
1174  pAmr.add("max_grid_size_y", info.maxgrid[1]);
1175  pAmr.add("max_grid_size_z", info.maxgrid[2]);
1176 
1177  pAmr.add("blocking_factor_x", info.bf[0]);
1178  pAmr.add("blocking_factor_y", info.bf[1]);
1179  pAmr.add("blocking_factor_z", info.bf[2]);
1180 
1181  const int nratios_vect = info.maxlevel * AMREX_SPACEDIM;
1182 
1183  AmrIntArray_t refratio(nratios_vect);
1184 
1185  for (int i = 0; i < info.maxlevel; ++i) {
1186  refratio[i * AMREX_SPACEDIM] = info.refratio[0];
1187  refratio[i * AMREX_SPACEDIM + 1] = info.refratio[1];
1188  refratio[i * AMREX_SPACEDIM + 2] = info.refratio[2];
1189  }
1190 
1191  pAmr.addarr("ref_ratio_vect", refratio);
1192 
1193  amrex::ParmParse pGeom("geometry");
1194  AmrIntArray_t isPeriodic = {
1195  layout_p->Geom(0).isPeriodic(0),
1196  layout_p->Geom(0).isPeriodic(1),
1197  layout_p->Geom(0).isPeriodic(2)
1198  };
1199  pGeom.addarr("is_periodic", isPeriodic);
1200 
1201 
1202  /*
1203  * "All" other parameters, we moslty take the
1204  * defaults of the code
1205  *
1206  * ATTENTION Be careful with default values since they might
1207  * be changed by the AMReX developers!
1208  *
1209  * Parmparse parameters not to be set because
1210  * alreday given due to constructor
1211  * ----------------------------------
1212  *
1213  * AMReX_AmrMesh:
1214  * - amr.max_level
1215  *
1216  * AMReX_Geometry:
1217  * - geometry.coord_sys
1218  * - geometry.prob_lo
1219  * - geometry.prob_hi
1220  * - geometry.is_periodic
1221  * - geometry.spherical_origin_fix [default: 0]
1222  * (not set because we're using Cartesian coordinates)
1223  *
1224  *
1225  * ParmParse left out
1226  * ------------------
1227  * AMReX_FabArrayBase:
1228  * - fabarray.mfiter_tile_size [default: IntVect(1024000,8,8)]
1229  * - fabarray.mfghostiter_tile_size [default: IntVect(1024000, 8, 8)]
1230  * - fabarray.comm_tile_size [default: IntVect(1024000, 8, 8)]
1231  * - fabarray.maxcomp [default: 25]
1232  * - fabarray.do_async_sends [default: true]
1233  *
1234  * AMReX_MemPool:
1235  * - fab.init_snan [default: 0, if not BL_TESTING or DEBUG enabled]
1236  *
1237  * AMReX_MemProfiler:
1238  * - amrex.memory.log [default: "memlog"]
1239  *
1240  * AMReX_VisMF:
1241  * - vismf.v [verbose, default: 0]
1242  * - vismf.headerversion [default: VisMF::Header::Version_v1 = 1]
1243  * - vismf.groupsets [default: false]
1244  * - vismf.setbuf [default: true]
1245  * - vismf.usesingleread [default: false]
1246  * - vismf.usesinglewrite [default: false]
1247  * - vismf.checkfilepositions [default: false]
1248  * - vismf.usepersistentifstreams [default: true]
1249  * - vismf.usesynchronousreads [default: false]
1250  * - vismf.usedynamicsetselection [default: true]
1251  * - vismf.iobuffersize [default: VisMF::IO_Buffer_Size = 262144 * 8]
1252  *
1253  * AMReX_ParallelDescriptor:
1254  * Needs change of ParallelDescriptor::SetNProcsSidecars in the function
1255  * ParallelDescriptor::StartParallel()
1256  * - amrex.ncolors [default: m_nCommColors = 1]
1257  * - team.size [default: disabled, enable by BL_USE_UPCXX or BL_USE_MPI3]
1258  * - team.reduce [default: disabled, enable by BL_USE_UPCXX or BL_USE_MPI3]
1259  * - mpi.onesided [default: disabled, enable by BL_USE_UPCXX or BL_USE_MPI3]
1260  *
1261  * AMReX:
1262  * Debugging purposes
1263  * - amrex.v [verbose, default: 0]
1264  * - amrex.verbose [default: 0]
1265  * - amrex.fpe_trap_invalid [invalid, default: 0]
1266  * - amrex.fpe_trap_zero [divbyzero, default: 0]
1267  * - amrex.fpe_trap_overflow [overflow, 0]
1268  *
1269  * AMReX_FArrayBox:
1270  * For output only
1271  * - fab.format [default: FABio::FAB_NATIVE]
1272  * For reading in an old FAB
1273  * - fab.ordering
1274  * - fab.initval [default: quiet_NaN() or max()]
1275  * - fab.do_initval [default: false, if not DEBUG or BL_TESTING enabled]
1276  * - fab.init_snan [default: false, if not DEBUG or BL_TESTING enabled]
1277  *
1278  * AMReX_MCMultiGrid:
1279  * We do NOT use this solver
1280  * - mg.maxiter [default: 40]
1281  * - mg.numiter [default: -1]
1282  * - mg.nu_0 [default: 1]
1283  * - mg.nu_1 [default: 2]
1284  * - mg.nu_2 [default: 2]
1285  * - mg.nu_f [default: 8]
1286  * - mg.v [verbose, default: 0]
1287  * - mg.usecg [default: 1]
1288  * - mg.rtol_b [default: 0.01]
1289  * - mg.bot_atol [default: -1.0]
1290  * - mg.nu_b [default: 0]
1291  * - mg.numLevelsMAX [default: 1024]
1292  *
1293  * AMReX_MCLinOp:
1294  * We do NOT use this solver
1295  * - MCLp.harmavg [default: 0]
1296  * - MCLp.v [verbose, default: 0]
1297  * - MCLp.maxorder [default: 2]
1298  *
1299  * AMReX_MCCGSolver:
1300  * We do NOT use this solver
1301  * - cg.maxiter [default: 40]
1302  * - cg.v [verbose, default: 0]
1303  * - cg.isExpert [default: 0]
1304  * - MCCGSolver::def_unstable_criterion [default: 10]
1305  *
1306  * AMReX_LinOp:
1307  * We do NOT use this class
1308  * - Lp.harmavg [default: 0]
1309  * - Lp.v [verbose, default: 0]
1310  * - Lp.maxorder [default: 2]
1311  * - LinOp::LinOp_grow [default: 1]
1312  *
1313  * AMReX_MultiGrid (single level solver):
1314  * We do NOT use this solver, see BoxLibSolvers/FMGPoissonSolver for
1315  * explanation of parameters
1316  * - mg.v [verbose, default: 0]
1317  * - mg.nu_0 [default: 1]
1318  * - mg.nu_1 [default: 2]
1319  * - mg.nu_2 [default: 2]
1320  * - mg.nu_f [default: 8]
1321  * - mg.nu_b [default: 0]
1322  * - mg.usecg [default: 1]
1323  * - mg.rtol_b [default: 0.0001 or 0.01 (if CG_USE_OLD_CONVERGENCE_CRITERIA enabled)]
1324  * - mg.verbose [default: 0]
1325  * - mg.maxiter [default: 40]
1326  * - mg.bot_atol [default: -1.0]
1327  * - mg.maxiter_b [default: 120]
1328  * - mg.numLevelsMAX [default: 1024]
1329  * - mg.smooth_on_cg_unstable [default: 1]
1330  * - mg.use_Anorm_for_convergence [default: 1]
1331  *
1332  * AMReX_CGSolver (single level solver):
1333  * We do NOT use this solver
1334  * - cg.v [verbose, default: 0]
1335  * - cg.SSS [default: SSS_MAX = 4]
1336  * - cg.maxiter [default: 80]
1337  * - cg.verbose [default: 0]
1338  * - cg.variable_SSS [default: true]
1339  * - cg.use_jbb_precond [default: 0]
1340  * - cg.use_jacobi_precond [default: 0]
1341  * - cg.unstable_criterion [default: 10]
1342  * - CGSolver::def_cg_solver [default: BiCGStab]
1343  * - cg.cg_solver [default: CGSolver::def_cg_solver]
1344  *
1345  * AMReX_Amr:
1346  * We do NOT use this class
1347  * - amr.regrid_on_restart [default: 0]
1348  * - amr.use_efficient_regrid [default: 0]
1349  * - amr.plotfile_on_restart [default: 0]
1350  * - amr.checkpoint_on_restart [default: 0]
1351  * - amr.compute_new_dt_on_regrid [default: 0]
1352  * - amr.mffile_nstreams [default: 1]
1353  * - amr.probinit_natonce [default: 32]
1354  * - amr.file_name_digits [default: 5]
1355  * - amr.initial_grid_file
1356  * - amr.regrid_file
1357  * - amr.message_int [default: 10]
1358  * - amr.run_log [default: not parsed]
1359  * - amr.run_log_terse [default: not parsed]
1360  * - amr.grid_log [default: not parsed]
1361  * - amr.data_log [default: not parsed]
1362  * - amr.probin_file [default: not parsed]
1363  * - amr.restart
1364  * - amr.restart_from_plotfile
1365  * - amr.regrid_int [default: 1 at all levels]
1366  * - amr.rebalance_grids [default: 0]
1367  * - amr.nosub [default: not parsed]
1368  * - amr.subcycling_mode [default: "Auto"]
1369  * - amr.subcycling_iterations [default: 0]
1370  * - amr.checkpoint_files_output
1371  * - amr.plot_files_output
1372  * - amr.plot_nfiles
1373  * - amr.checkpoint_nfiles
1374  * - amr.check_file [default: "chk"]
1375  * - amr.check_int [default: -1]
1376  * - amr.check_per [default: -1.0]
1377  * - amr.plot_file [default: "plt"]
1378  * - amr.plot_int [default: -1]
1379  * - amr.plot_per [default: -1.0]
1380  * - amr.small_plot_file [default: "smallplt"]
1381  * - amr.small_plot_int [default: -1]
1382  * - amr.small_plot_per [default: -1.0]
1383  * - amr.write_plotfile_with_checkpoint [default: 1]
1384  * - amr.stream_max_tries [default: 4]
1385  * - amr.abort_on_stream_retry_failure [default: false]
1386  * - amr.precreateDirectories
1387  * - amr.prereadFAHeaders
1388  * - amr.plot_headerversion
1389  * - amr.checkpoint_headerversion
1390  *
1391  * AMReX_SlabStat:
1392  * We do NOT use this class
1393  * - slabstat.boxes
1394  *
1395  * AMReX_AmrLevel:
1396  * We do NOT use this class
1397  * - amr.plot_vars [default: not parsed]
1398  * - amr.derive_plot_vars [default: not parsed]
1399  * - amr.small_plot_vars [default: not parsed]
1400  *
1401  * AMReX_StationData:
1402  * We do NOT use this class
1403  * - StationData.vars [default: not parsed]
1404  * - StationData.coord [default: not parsed]
1405  */
1406 
1407  // verbosity
1408  pAmr.add("v", 0);
1409 
1410  // # cells required for proper nesting.
1411  pAmr.add("n_proper", 1);
1412 
1413  // Grid efficiency. (default: 0.7)
1414  pAmr.add("grid_eff", 0.95);
1415 
1416  int nlev = info.maxlevel + 1;
1417 
1418  // Buffer cells around each tagged cell.
1419  AmrIntArray_t error_buf(nlev, 4 /*buffer*/);
1420  error_buf[0] = 0;
1421  pAmr.addarr("n_error_buf", error_buf);
1422 
1423  // chop up grids to have more grids than the number of procs
1424  pAmr.add("refine_grid_layout", true);
1425 
1426 
1427  /*
1428  * ParmParse for DistributionMapping
1429  *
1430  * round-robin: FAB i is owned by CPU i%N where N is total number of CPUs
1431  * knapsack: FABs are partitioned across CPUs such that the total volume
1432  * of the Boxes in the underlying BoxArray are as equal across
1433  * CPUs as is possible.
1434  * SFC: Is based on a space filling curve (default)
1435  */
1436  amrex::ParmParse pDmap("DistributionMapping");
1437 
1438  // verbosity
1439  pDmap.add("v", 0);
1440 
1441  // max_efficiency = 0.9
1442  pDmap.add("efficiency", 0.9);
1443 
1444  // SFC = space filling curve
1445  pDmap.add("sfc_threshold", 0);
1446 
1447  /* if > 0:
1448  * nworkers = node_size
1449  * nteams = nprocs / node_size
1450  *
1451  * if nwokers * nteams != nprocs:
1452  * nteams = nprocs
1453  * nworkers = 1
1454  */
1455  pDmap.add("node_size", 0);
1456 
1457  /* Possibilities:
1458  * - ROUNDROBIN
1459  * - KNAPSACK
1460  * - SFC
1461  * - PFC
1462  * - RRSFC
1463  */
1464  pDmap.add("strategy", "SFC");
1465 }
1466 
1467 
1469  /* Copied from one of the miniapps:
1470  *
1471  * amrex/Src/AmrTask/tutorials/MiniApps/HeatEquation/physbc.cpp
1472  *
1473  * AMReX - Revision:
1474  *
1475  * commit 8174212e898677d6413cf5e4db44148a52b4b732
1476  * Author: Weiqun Zhang <weiqunzhang@lbl.gov>
1477  * Date: Mon Jul 2 10:40:21 2018 -0700
1478  */
1479  if (AmrGeometry_t::isAllPeriodic())
1480  return;
1481  // Set up BC; see Src/Base/AMReX_BC_TYPES.H for supported types
1482  amrex::Vector<amrex::BCRec> bc(mf.nComp());
1483  for (int n = 0; n < mf.nComp(); ++n)
1484  {
1485  for (int idim = 0; idim < AMREX_SPACEDIM; ++idim)
1486  {
1487  if (AmrGeometry_t::isPeriodic(idim))
1488  {
1489  bc[n].setLo(idim, amrex::BCType::int_dir); // interior
1490  bc[n].setHi(idim, amrex::BCType::int_dir);
1491  }
1492  else
1493  {
1494  bc[n].setLo(idim, amrex::BCType::foextrap); // first-order extrapolation.
1495  bc[n].setHi(idim, amrex::BCType::foextrap);
1496  }
1497  }
1498  }
1499 
1500  amrex::FillDomainBoundary(mf, this->geom[lev], bc);
1501 }
void RemakeLevel(int lev, AmrReal_t time, const AmrGrid_t &new_grids, const AmrProcMap_t &new_dmap)
Definition: AmrBoxLib.cpp:603
amr::AmrGrid_t AmrGrid_t
Definition: AmrBoxLib.h:32
amr::AmrIntVect_t AmrIntVect_t
Definition: AmrBoxLib.h:35
ParticleAttrib< Vector_t > P
min. #particles per cell
Definition: AmrObject.h:32
void resize(int maxLevel)
Definition: BoxLibLayout.h:224
double getT() const
void tagForChargeDensity_m(int lev, TagBoxArray_t &tags, AmrReal_t time, int ngrow)
Definition: AmrBoxLib.cpp:808
void computeSelfFields()
Definition: AmrBoxLib.cpp:199
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
void initFineLevels()
Definition: AmrBoxLib.cpp:135
static std::unique_ptr< AmrBoxLib > create(const AmrInfo &info, AmrPartBunch *bunch_p)
Definition: AmrBoxLib.cpp:46
amrex::MFIter MFIter_t
Definition: AmrBoxLib.h:41
ParticleAttrib< Vector_t > Ef
ParticleAttrib< Vector_t > Eftmp
std::vector< bool > isFirstTagging_m
Definition: AmrBoxLib.h:377
const double & getScalingFactor() const
long long getLocalTrackStep() const
size_t minNumPart_m
Tagging value for MIN_NUM_PARTICLES.
Definition: AmrObject.h:178
amrex::Box Box_t
Definition: AmrBoxLib.h:38
AmrScalarFieldContainer_t phi_m
scalar potential on the grid for all levels
Definition: AmrBoxLib.h:368
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:123
amr::AmrIntArray_t AmrIntArray_t
Definition: AmrBoxLib.h:30
The base class for all OPAL exceptions.
Definition: OpalException.h:28
ParticleAttrib< double > Q
void doRegrid_m(int lbase, double time)
Definition: AmrBoxLib.cpp:733
TaggingCriteria tagging_m
Tagging strategy.
Definition: AmrObject.h:170
Vektor< int, 3 > getBaseLevelGridPoints() const
Definition: AmrBoxLib.cpp:515
Inform * gmsg
Definition: Main.cpp:21
void tagForMomenta_m(int lev, TagBoxArray_t &tags, AmrReal_t time, int ngrow)
Definition: AmrBoxLib.cpp:980
void tagForMinNumParticles_m(int lev, TagBoxArray_t &tags, AmrReal_t time, int ngrow)
Definition: AmrBoxLib.cpp:1089
const ParticleLevelCounter_t & getLocalNumPerLevel() const
void MakeNewLevel(int lev, AmrReal_t time, const AmrGrid_t &new_grids, const AmrProcMap_t &new_dmap)
Definition: AmrBoxLib.cpp:636
size_t maxNumPart_m
Tagging value for MAX_NUM_PARTICLES.
Definition: AmrObject.h:176
bool isForbidTransform() const
void updateMesh()
Definition: AmrBoxLib.cpp:498
bool info
Info flag.
Definition: Options.cpp:8
PoissonSolver * getFieldSolver()
Definition: AmrPartBunch.h:66
virtual void solve(AmrScalarFieldContainer_t &rho, AmrScalarFieldContainer_t &phi, AmrVectorFieldContainer_t &efield, unsigned short baseLevel, unsigned short finestLevel, bool prevAsGuess=true)
Definition: PoissonSolver.h:32
int refratio[3]
Mesh refinement ratio in x-, y- and z-direction.
Definition: AmrObject.h:47
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition: Vector3D.cpp:118
void tagForEfield_m(int lev, TagBoxArray_t &tags, AmrReal_t time, int ngrow)
Definition: AmrBoxLib.cpp:915
pbase_t * getAmrParticleBase()
Inform & level2(Inform &inf)
Definition: Inform.cpp:46
void getGridStatistics(std::map< int, long > &gridPtsPerCore, std::vector< int > &gridsPerLevel) const
Definition: AmrBoxLib.cpp:108
void regrid(double time)
Definition: AmrBoxLib.cpp:79
int grid[3]
Number of grid points in x-, y- and z-direction.
Definition: AmrObject.h:43
amr::AmrProcMap_t AmrProcMap_t
Definition: AmrBoxLib.h:33
void ClearLevel(int lev)
Definition: AmrBoxLib.cpp:671
ParticleLayout< T, Dim > & getLayout()
amrex::TagBox TagBox_t
Definition: AmrBoxLib.h:39
AmrBoxLib(const AmrDomain_t &domain, const AmrIntArray_t &nGridPts, int maxLevel, AmrPartBunch *bunch_p)
Definition: AmrBoxLib.cpp:19
const int & finestLevel() const
Definition: AmrBoxLib.cpp:532
amrex::FArrayBox FArrayBox_t
Definition: AmrBoxLib.h:37
AmrScalarFieldContainer_t rho_m
charge density on the grid for all levels
Definition: AmrBoxLib.h:365
amr::AmrField_t AmrField_t
Definition: AmrBoxLib.h:23
amr::AmrGridContainer_t AmrGridContainer_t
Definition: AmrBoxLib.h:27
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
void MakeNewLevelFromCoarse(int lev, AmrReal_t time, const AmrGrid_t &ba, const AmrProcMap_t &dm)
Definition: AmrBoxLib.cpp:725
amr::AmrReal_t AmrReal_t
Definition: AmrBoxLib.h:31
void updateLorentzFactor(int bin=0)
double scaling_m
Scaling factor for tagging [0, 1].
Definition: AmrObject.h:172
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)
const int & maxLevel() const
Definition: AmrBoxLib.cpp:527
double getRho(int x, int y, int z)
Definition: AmrBoxLib.cpp:192
static void initParmParse_m(const AmrInfo &info, AmrLayout_t *layout_p)
Definition: AmrBoxLib.cpp:1167
void setForbidTransform(bool forbidTransform)
virtual void ErrorEst(int lev, TagBoxArray_t &tags, AmrReal_t time, int ngrow) override
Definition: AmrBoxLib.cpp:684
void clearLevelMask(int lev)
AmrIntVect_t Index(AmrParticleBase< BoxLibLayout< T, Dim > > &p, const unsigned int ip, int level) const
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6
bool isPoissonSolved_m
Definition: AmrBoxLib.h:379
VectorPair_t getEExtrema()
Definition: AmrBoxLib.cpp:169
size_t getLocalNum() const
void setFinestLevel(int finestLevel)
void buildLevelMask(int lev, const int ncells=1)
amr::AmrDomain_t AmrDomain_t
Definition: AmrBoxLib.h:29
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
Vector_t meshScaling_m
in particle rest frame, the longitudinal length enlarged
Definition: AmrBoxLib.h:374
short getNumBunch() const
void setBaseLevelMeshSpacing(const Vector_t &hr)
Definition: AmrPartBunch.h:74
double getT() const
Definition: AmrBoxLib.cpp:537
void MakeNewLevelFromScratch(int lev, AmrReal_t time, const AmrGrid_t &ba, const AmrProcMap_t &dm)
Definition: AmrBoxLib.cpp:717
void tagForMaxNumParticles_m(int lev, TagBoxArray_t &tags, AmrReal_t time, int ngrow)
Definition: AmrBoxLib.cpp:1039
AmrVectorFieldContainer_t efield_m
vector field on the grid for all levels
Definition: AmrBoxLib.h:371
const double & domainMapping(bool inverse=false)
IpplTimings::TimerRef amrRegridTimer_m
Definition: AmrObject.h:184
void define(const AmrGeomContainer_t &geom)
Definition: BoxLibLayout.h:242
void postRegrid_m(int old_finest)
Definition: AmrBoxLib.cpp:769
void fillPhysbc_m(AmrField_t &mf, int lev=0)
Definition: AmrBoxLib.cpp:1468
static const unsigned Dimension
Definition: PartBunchBase.h:39
double getBinGamma(int bin)
Get gamma of one bin.
void computeSelfFields_cycl(double gamma)
Definition: AmrBoxLib.cpp:211
AmrLayout_t * layout_mp
Definition: AmrBoxLib.h:362
int amrRegridFreq
Definition: Options.cpp:105
ParticleAttrib< int > Bin
amrex::TagBoxArray TagBoxArray_t
Definition: AmrBoxLib.h:40
int amrYtDumpFreq
The frequency to dump AMR grid data and particles into file.
Definition: Options.cpp:103
constexpr double epsilon_0
The permittivity of vacuum in As/Vm.
Definition: Physics.h:58
ParticleAttrib< Vector_t > Bf
std::pair< Vector_t, Vector_t > VectorPair_t
Definition: AmrObject.h:23
ParticlePos_t & R
AmrPartBunch * bunch_mp
bunch used for tagging strategies
Definition: AmrBoxLib.h:359
const Vector_t & getMeshScaling() const
Definition: AmrBoxLib.cpp:510
max. #particles per cell
Definition: AmrObject.h:33
virtual void hasToRegrid()
Definition: PoissonSolver.h:45
static void stopTimer(TimerRef t)
Definition: IpplTimings.h:192
int maxlevel
Maximum level for AMR (0: single-level)
Definition: AmrObject.h:46
Definition: Inform.h:41
double chargedensity_m
Tagging value for CHARGE_DENSITY.
Definition: AmrObject.h:174
void gather(ParticleAttrib< FT > &attrib, AmrVectorFieldContainer_t &f, ParticleAttrib< Vektor< PT, Dim > > &pp, int lbase, int lfine)
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:95
void redistributeGrids(int how)
Definition: AmrBoxLib.cpp:542
IpplTimings::TimerRef amrSolveTimer_m
timer for selfField calculation (used in concrete AmrObject classes)
Definition: AmrObject.h:183
void tagForPotentialStrength_m(int lev, TagBoxArray_t &tags, AmrReal_t time, int ngrow)
Definition: AmrBoxLib.cpp:861
bool refined_m
Only set to true in AmrObject::initFineLevels()
Definition: AmrObject.h:180
int bf[3]
Grid blocking factor in x-, y- and z-direction.
Definition: AmrObject.h:45
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
void initBaseLevel_m(const AmrIntArray_t &nGridPts)
Definition: AmrBoxLib.cpp:1141
int maxgrid[3]
Maximum grid size in x-, y- and z-direction.
Definition: AmrObject.h:44