chombo-discharge
CD_TracerParticleStepperImplem.H
Go to the documentation of this file.
1 /* chombo-discharge
2  * Copyright © 2022 SINTEF Energy Research.
3  * Please refer to Copyright.txt and LICENSE in the chombo-discharge root directory.
4  */
5 
12 #ifndef CD_TracerParticleStepperImplem_H
13 #define CD_TracerParticleStepperImplem_H
14 
15 // Chombo includes
16 #include <CH_Timer.H>
17 
18 // Our includes
19 #include <CD_ParticleManagement.H>
20 #include <CD_Random.H>
22 #include <CD_NamespaceHeader.H>
23 
24 using namespace Physics::TracerParticle;
25 
26 template <typename P>
28 {
29  CH_TIME("TracerParticleStepper::TracerParticleStepper");
30 
31  m_realm = Realm::Primal;
32  m_phase = phase::gas;
33 
34  this->parseOptions();
35 }
36 
37 template <typename P>
39 {
40  CH_TIME("TracerParticleStepper::~TracerParticleStepper");
41  if (m_verbosity > 5) {
42  pout() << "TracerParticleStepper::~TracerParticleStepper" << endl;
43  }
44 }
45 
46 template <typename P>
47 inline void
49 {
50  CH_TIME("TracerParticleStepper::setupSolvers()");
51  if (m_verbosity > 5) {
52  pout() << "TracerParticleStepper::setupSolvers()" << endl;
53  }
54 
55  m_solver = RefCountedPtr<TracerParticleSolver<P>>(new TracerParticleSolver<P>(m_amr, m_computationalGeometry));
56 
57  m_solver->setPhase(m_phase);
58  m_solver->setRealm(m_realm);
59  m_solver->parseOptions();
60 }
61 
62 template <typename P>
63 inline void
65 {
66  CH_TIME("TracerParticleStepper::allocate()");
67  if (m_verbosity > 5) {
68  pout() << "TracerParticleStepper::allocate()" << endl;
69  }
70 
71  m_amr->allocate(m_velocity, m_realm, m_phase, SpaceDim);
72  m_solver->allocate();
73 }
74 
75 template <typename P>
76 inline void
78 {
79  CH_TIME("TracerParticleStepper::initialData()");
80  if (m_verbosity > 5) {
81  pout() << "TracerParticleStepper::initialData()" << endl;
82  }
83 
84  this->setVelocity();
85  this->initialParticles();
86 
87  m_solver->setVelocity(m_velocity);
88  m_solver->interpolateVelocities();
89 }
90 
91 template <typename P>
92 inline void
94 {
95  CH_TIME("TracerParticleStepper::registerRealms()");
96  if (m_verbosity > 5) {
97  pout() << "TracerParticleStepper::registerRealms()" << endl;
98  }
99 
100  m_amr->registerRealm(m_realm);
101 }
102 
103 template <typename P>
104 inline void
106 {
107  CH_TIME("TracerParticleStepper::registerOperators()");
108  if (m_verbosity > 5) {
109  pout() << "TracerParticleStepper::registerOperators()" << endl;
110  }
111 
112  m_solver->registerOperators();
113 }
114 
115 template <typename P>
116 inline void
118 {
119  CH_TIME("TracerParticleStepper::parseOptions()");
120  if (m_verbosity > 5) {
121  pout() << "TracerParticleStepper::parseOptions()" << endl;
122  }
123 
124  this->parseIntegrator();
125  this->parseVelocityField();
126  this->parseInitialConditions();
127 }
128 
129 template <typename P>
130 inline void
132 {
133  CH_TIME("TracerParticleStepper::parseRuntimeOptions()");
134  if (m_verbosity > 5) {
135  pout() << "TracerParticleStepper::parseRuntimeOptions()" << endl;
136  }
137 
138  this->parseIntegrator();
139 
140  m_solver->parseRuntimeOptions();
141 }
142 
143 template <typename P>
144 inline void
146 {
147  CH_TIME("TracerParticleStepper::parseIntegrator()");
148  if (m_verbosity > 5) {
149  pout() << "TracerParticleStepper::parseIntegrator()" << endl;
150  }
151 
152  ParmParse pp("TracerParticleStepper");
153 
154  std::string str;
155 
156  pp.get("verbosity", m_verbosity);
157  pp.get("cfl", m_cfl);
158  pp.get("integration", str);
159  if (str == "euler") {
160  m_algorithm = IntegrationAlgorithm::Euler;
161  }
162  else if (str == "rk2") {
163  m_algorithm = IntegrationAlgorithm::RK2;
164  }
165  else if (str == "rk4") {
166  m_algorithm = IntegrationAlgorithm::RK4;
167  }
168  else {
169  MayDay::Error("TracerParticleStepper::parseIntegrator -- logic bust");
170  }
171 }
172 
173 template <typename P>
174 inline void
176 {
177  CH_TIME("TracerParticleStepper::parseVelocityField()");
178  if (m_verbosity > 5) {
179  pout() << "TracerParticleStepper::parseVelocityField()" << endl;
180  }
181 
182  ParmParse pp("TracerParticleStepper");
183 
184  int v;
185  pp.get("velocity_field", v);
186 
187  if (v == 0) {
188  m_velocityField = VelocityField::Diagonal;
189  }
190  else if (v == 1) {
191  m_velocityField = VelocityField::Rotational;
192  }
193  else {
194  MayDay::Error("TracerParticleStepper::parseVelocityField -- logic bust");
195  }
196 }
197 
198 template <typename P>
199 inline void
201 {
202  CH_TIME("TracerParticleStepper::parseInitialConditions()");
203  if (m_verbosity > 5) {
204  pout() << "TracerParticleStepper::parseInitialConditions()" << endl;
205  }
206 
207  ParmParse pp("TracerParticleStepper");
208 
209  Real numParticles;
210  pp.get("initial_particles", numParticles);
211 
212  m_numInitialParticles = size_t(std::max(0.0, numParticles));
213 }
214 
215 #ifdef CH_USE_HDF5
216 template <typename P>
217 inline void
218 TracerParticleStepper<P>::writeCheckpointData(HDF5Handle& a_handle, const int a_lvl) const
219 {
220  CH_TIME("TracerParticleStepper::writeCheckpointData(HDF5Handle, int)");
221  if (m_verbosity > 5) {
222  pout() << "TracerParticleStepper::writeCheckpointData(HDF5Handle, int)" << endl;
223  }
224 
225  m_solver->writeCheckpointLevel(a_handle, a_lvl);
226 }
227 #endif
228 
229 #ifdef CH_USE_HDF5
230 template <typename P>
231 inline void
232 TracerParticleStepper<P>::readCheckpointData(HDF5Handle& a_handle, const int a_lvl)
233 {
234  CH_TIME("TracerParticleStepper::readCheckpointData(HDF5Handle, int)");
235  if (m_verbosity > 5) {
236  pout() << "TracerParticleStepper::readCheckpointData(HDF5Handle, int)" << endl;
237  }
238 
239  m_solver->readCheckpointLevel(a_handle, a_lvl);
240 }
241 #endif
242 
243 template <typename P>
244 inline int
246 {
247  CH_TIME("TracerParticleStepper::getNumberOfPlotVariables()");
248  if (m_verbosity > 5) {
249  pout() << "TracerParticleStepper::getNumberOfPlotVariables()" << endl;
250  }
251 
252  return m_solver->getNumberOfPlotVariables();
253 }
254 
255 template <typename P>
256 inline Vector<std::string>
258 {
259  CH_TIME("TracerParticleStepper::getPlotVariableNames()");
260  if (m_verbosity > 5) {
261  pout() << "TracerParticleStepper::getPlotVariableNames()" << endl;
262  }
263 
264  return m_solver->getPlotVariableNames();
265 }
266 
267 template <typename P>
268 inline void
269 TracerParticleStepper<P>::writePlotData(LevelData<EBCellFAB>& a_output,
270  int& a_icomp,
271  const std::string a_outputRealm,
272  const int a_level) const
273 {
274  CH_TIME("TracerParticleStepper::writePlotData(EBAMRCellData, Vector<std::string>, int)");
275  if (m_verbosity > 5) {
276  pout() << "TracerParticleStepper::writePlotData(EBAMRCellData, Vector<std::string>, int)" << endl;
277  }
278 
279  CH_assert(a_level >= 0);
280  CH_assert(a_level <= m_amr->getFinestLevel());
281 
282  m_solver->writePlotData(a_output, a_icomp, a_outputRealm, a_level);
283 }
284 
285 template <typename P>
286 inline Real
288 {
289  CH_TIME("TracerParticleStepper::computeDt()");
290  if (m_verbosity > 5) {
291  pout() << "TracerParticleStepper::computeDt()" << endl;
292  }
293 
294  return m_cfl * m_solver->computeDt();
295 }
296 
297 template <typename P>
298 inline Real
300 {
301  CH_TIME("TracerParticleStepper::advance(Real)");
302  if (m_verbosity > 5) {
303  pout() << "TracerParticleStepper::advance(Real)" << endl;
304  }
305 
306  switch (m_algorithm) {
307  case IntegrationAlgorithm::Euler: {
308  this->advanceParticlesEuler(a_dt);
309 
310  break;
311  }
312  case IntegrationAlgorithm::RK2: {
313  this->advanceParticlesRK2(a_dt);
314 
315  break;
316  }
317  case IntegrationAlgorithm::RK4: {
318  this->advanceParticlesRK4(a_dt);
319 
320  break;
321  }
322  default: {
323  MayDay::Error("TracerParticleStepper::advance -- logic bust");
324  }
325  }
326 
327  return a_dt;
328 }
329 
330 template <typename P>
331 inline void
332 TracerParticleStepper<P>::synchronizeSolverTimes(const int a_step, const Real a_time, const Real a_dt)
333 {
334  CH_TIME("TracerParticleStepper::synchronizeSolverTimes");
335  if (m_verbosity > 5) {
336  pout() << "TracerParticleStepper::synchronizeSolverTimes" << endl;
337  }
338 
339  m_timeStep = a_step;
340  m_time = a_time;
341  m_dt = a_dt;
342 
343  m_solver->setTime(a_step, a_time, a_dt);
344 }
345 
346 template <typename P>
347 inline void
348 TracerParticleStepper<P>::preRegrid(const int a_lmin, const int a_oldFinestLevel)
349 {
350  CH_TIME("TracerParticleStepper::preRegrid(int, int)");
351  if (m_verbosity > 5) {
352  pout() << "TracerParticleStepper::preRegrid(int, int)" << endl;
353  }
354 
355  m_solver->preRegrid(a_lmin, a_oldFinestLevel);
356 }
357 
358 template <typename P>
359 inline void
360 TracerParticleStepper<P>::regrid(const int a_lmin, const int a_oldFinestLevel, const int a_newFinestLevel)
361 {
362  CH_TIME("TracerParticleStepper::regrid(int, int, int)");
363  if (m_verbosity > 5) {
364  pout() << "TracerParticleStepper::regrid(int, int, int)" << endl;
365  }
366 
367  // Define velocity field on the new mesh.
368  m_amr->reallocate(m_velocity, m_phase, a_lmin);
369  DataOps::setValue(m_velocity, 0.0);
370 
371  // Regrid tracer particles.
372  m_solver->regrid(a_lmin, a_oldFinestLevel, a_newFinestLevel);
373 }
374 
375 template <typename P>
376 inline void
378 {
379  CH_TIME("TracerParticleStepper::postRegrid()");
380  if (m_verbosity > 5) {
381  pout() << "TracerParticleStepper::postRegrid()" << endl;
382  }
383 
384  // Update particle velocities.
385  this->setVelocity();
386  m_solver->interpolateVelocities();
387 }
388 
389 template <typename P>
390 inline void
392 {
393  CH_TIME("TracerParticleStepper::setVelocity()");
394  if (m_verbosity > 5) {
395  pout() << "TracerParticleStepper::setVelocity()" << endl;
396  }
397 
398  std::function<RealVect(const RealVect a_position)> velFunc;
399 
400  switch (m_velocityField) {
401  case VelocityField::Diagonal: {
402  velFunc = [](const RealVect& a_position) -> RealVect {
403  return RealVect::Unit;
404  };
405 
406  break;
407  }
408  case VelocityField::Rotational: {
409  velFunc = [](const RealVect pos) -> RealVect {
410  const Real r = pos.vectorLength();
411  const Real theta = atan2(pos[1], pos[0]);
412 
413  return RealVect(D_DECL(-r * sin(theta), r * cos(theta), 0.));
414  };
415 
416  break;
417  }
418  }
419 
420  DataOps::setValue(m_velocity, velFunc, m_amr->getProbLo(), m_amr->getDx());
421 
422  m_amr->conservativeAverage(m_velocity, m_realm, m_phase);
423  m_amr->interpGhost(m_velocity, m_realm, m_phase);
424 }
425 
426 template <typename P>
427 inline void
429 {
430  CH_TIME("TracerParticleStepper::initialParticles()");
431  if (m_verbosity > 5) {
432  pout() << "TracerParticleStepper::initialParticles()" << endl;
433  }
434 
435  // TLDR: This code draws distributed particles. Thanks to our nifty ParticleManagement and Random static classes this is just
436  // a matter of defining a distribution function. We define this as a lambda that draws particles uniformly distributed
437  // inside a box.
438  //
439  // After creating the distribution we draw the particles (MPI rank distribution being taken care of under the hood) and
440  // set their weight to one. Finally, we add these particles to the ParticleContainer and remove the particles that lie inside
441  // the EB.
442 
443  // Create a random distribution which draw particles uniformly distributed in the domain.
444  const RealVect probLo = m_amr->getProbLo();
445  const RealVect probHi = m_amr->getProbHi();
446 
447  auto uniformDistribution = [probLo, probHi]() -> RealVect {
448  RealVect ret = probLo;
449 
450  for (int dir = 0; dir < SpaceDim; dir++) {
451  ret[dir] += (probHi - probLo)[dir] * Random::getUniformReal01();
452  }
453 
454  return ret;
455  };
456 
457  // Draw particles using the distribution above. Set their weight to one.
458  List<P> initialParticles;
459 
460  ParticleManagement::drawRandomParticles(initialParticles, m_numInitialParticles, uniformDistribution);
461  for (ListIterator<P> lit(initialParticles); lit.ok(); ++lit) {
462  lit().weight() = 1.0;
463  }
464 
465  // Put the particles in the solver particle data holder.
466  ParticleContainer<P>& solverParticles = m_solver->getParticles();
467  solverParticles.clearParticles();
468  solverParticles.addParticlesDestructive(initialParticles);
469 
470  // Remove particles inside the EB.
471  pout() << "removing particles" << endl;
472  m_amr->removeCoveredParticlesIF(solverParticles, m_phase);
473  pout() << "done initial particles" << endl;
474 }
475 
476 template <typename P>
477 inline void
479 {
480  CH_TIME("TracerParticleStepper::advanceParticlesEuler()");
481  if (m_verbosity > 5) {
482  pout() << "TracerParticleStepper::advanceParticlesEuler()" << endl;
483  }
484 
485  // TLDR: The new position is just x^(k+1) = x^k + dt*v^k
486 
487  ParticleContainer<P>& amrParticles = m_solver->getParticles();
488 
489  for (int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
490  const DisjointBoxLayout& dbl = m_amr->getGrids(m_realm)[lvl];
491  const DataIterator& dit = dbl.dataIterator();
492 
493  const int nbox = dit.size();
494 
495 #pragma omp parallel for schedule(runtime)
496  for (int mybox = 0; mybox < nbox; mybox++) {
497  const DataIndex& din = dit[mybox];
498 
499  List<P>& particles = amrParticles[lvl][din].listItems();
500 
501  for (ListIterator<P> lit(particles); lit.ok(); ++lit) {
502  P& p = lit();
503 
504  p.position() += p.velocity() * a_dt;
505  }
506  }
507  }
508 
509  amrParticles.remap();
510  m_amr->removeCoveredParticlesIF(amrParticles, m_phase);
511 
512  m_solver->interpolateVelocities();
513 }
514 
515 template <typename P>
516 inline void
518 {
519  CH_TIME("TracerParticleStepper::advanceParticlesRK2()");
520  if (m_verbosity > 5) {
521  pout() << "TracerParticleStepper::advanceParticlesRK2()" << endl;
522  }
523 
524  // TLDR: The new positions are x^(k+1) = x^k + 0.5*dt*[ v(x^k) + v(x^*) ] where x^* = x^k + dt*v^k.
525 
526  ParticleContainer<P>& amrParticles = m_solver->getParticles();
527 
528  // First step. Store old position and velocity and do the Euler advance.
529  for (int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
530  const DisjointBoxLayout& dbl = m_amr->getGrids(m_realm)[lvl];
531  const DataIterator& dit = dbl.dataIterator();
532 
533  const int nbox = dit.size();
534 
535 #pragma omp parallel for schedule(runtime)
536  for (int mybox = 0; mybox < nbox; mybox++) {
537  const DataIndex& din = dit[mybox];
538 
539  List<P>& particles = amrParticles[lvl][din].listItems();
540 
541  for (ListIterator<P> lit(particles); lit.ok(); ++lit) {
542  P& p = lit();
543 
544  p.template vect<0>() = p.position();
545  p.template vect<1>() = p.velocity();
546 
547  p.position() += p.velocity() * a_dt;
548  }
549  }
550  }
551 
552  // Remap and interpolate the velocities again. This puts the velocity v = v(x^*) into the particles
553  amrParticles.remap();
554  m_amr->removeCoveredParticlesIF(amrParticles, m_phase);
555  m_solver->interpolateVelocities();
556 
557  // Do the second RK2 stage.
558  for (int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
559  const DisjointBoxLayout& dbl = m_amr->getGrids(m_realm)[lvl];
560  const DataIterator& dit = dbl.dataIterator();
561 
562  const int nbox = dit.size();
563 
564 #pragma omp parallel for schedule(runtime)
565  for (int mybox = 0; mybox < nbox; mybox++) {
566  const DataIndex& din = dit[mybox];
567 
568  List<P>& particles = amrParticles[lvl][din].listItems();
569 
570  for (ListIterator<P> lit(particles); lit.ok(); ++lit) {
571  P& p = lit();
572 
573  // x^k+1 = x^k + dt/2 * [v(x^k) + v(x^*) ]
574  p.position() = p.template vect<0>() + 0.5 * a_dt * (p.template vect<1>() + p.velocity());
575  }
576  }
577  }
578 
579  // Remap and interpolate the velocities again
580  amrParticles.remap();
581  m_amr->removeCoveredParticlesIF(amrParticles, m_phase);
582  m_solver->interpolateVelocities();
583 }
584 
585 template <typename P>
586 inline void
588 {
589  CH_TIME("TracerParticleStepper::advanceParticlesRK4()");
590  if (m_verbosity > 5) {
591  pout() << "TracerParticleStepper::advanceParticlesRK4()" << endl;
592  }
593 
594  // TLDR: Just the standard RK4 method.
595 
596  ParticleContainer<P>& amrParticles = m_solver->getParticles();
597 
598  const Real dtHalf = a_dt / 2.0;
599  const Real dtThird = a_dt / 3.0;
600  const Real dtSixth = a_dt / 6.0;
601 
602  // k1 step.
603  {
604  for (int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
605  const DisjointBoxLayout& dbl = m_amr->getGrids(m_realm)[lvl];
606  const DataIterator& dit = dbl.dataIterator();
607 
608  const int nbox = dit.size();
609 
610 #pragma omp parallel for schedule(runtime)
611  for (int mybox = 0; mybox < nbox; mybox++) {
612  const DataIndex& din = dit[mybox];
613 
614  for (ListIterator<P> lit(amrParticles[lvl][din].listItems()); lit.ok(); ++lit) {
615  P& p = lit();
616 
617  // Store old position.
618  p.template vect<0>() = p.position();
619 
620  p.template vect<1>() = p.velocity(); // k1 = v(x^k)
621  p.position() = p.template vect<0>() + dtHalf * p.velocity(); // x = x^k + 0.5*dt*k1
622  }
623  }
624  }
625 
626  // Remap and compute v = v(x)
627  amrParticles.remap();
628  m_solver->interpolateVelocities();
629  }
630 
631  // k2 step.
632  {
633  for (int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
634  const DisjointBoxLayout& dbl = m_amr->getGrids(m_realm)[lvl];
635  const DataIterator& dit = dbl.dataIterator();
636 
637  const int nbox = dit.size();
638 
639 #pragma omp parallel for schedule(runtime)
640  for (int mybox = 0; mybox < nbox; mybox++) {
641  const DataIndex& din = dit[mybox];
642 
643  for (ListIterator<P> lit(amrParticles[lvl][din].listItems()); lit.ok(); ++lit) {
644  P& p = lit();
645 
646  p.template vect<2>() = p.velocity(); // k2 = v(x^k + 0.5 * k1 * dt)
647  p.position() = p.template vect<0>() + dtHalf * p.velocity(); // x = x^k + 0.5*dt*k2
648  }
649  }
650  }
651 
652  // Remap and compute v = v(x)
653  amrParticles.remap();
654  m_solver->interpolateVelocities();
655  }
656 
657  // k3 step.
658  {
659  for (int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
660  const DisjointBoxLayout& dbl = m_amr->getGrids(m_realm)[lvl];
661  const DataIterator& dit = dbl.dataIterator();
662 
663  const int nbox = dit.size();
664 
665 #pragma omp parallel for schedule(runtime)
666  for (int mybox = 0; mybox < nbox; mybox++) {
667  const DataIndex& din = dit[mybox];
668 
669  for (ListIterator<P> lit(amrParticles[lvl][din].listItems()); lit.ok(); ++lit) {
670  P& p = lit();
671 
672  p.template vect<3>() = p.velocity(); // k3 = v(x^k + 0.5 * k2 * dt)
673  p.position() = p.template vect<0>() + a_dt * p.velocity(); // x^k + k3*a_dt
674  }
675  }
676  }
677 
678  // Remap and compute v = v(x)
679  amrParticles.remap();
680  m_solver->interpolateVelocities();
681  }
682 
683  // Final step.
684  {
685  for (int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
686  const DisjointBoxLayout& dbl = m_amr->getGrids(m_realm)[lvl];
687  const DataIterator& dit = dbl.dataIterator();
688 
689  const int nbox = dit.size();
690 
691 #pragma omp parallel for schedule(runtime)
692  for (int mybox = 0; mybox < nbox; mybox++) {
693  const DataIndex& din = dit[mybox];
694 
695  for (ListIterator<P> lit(amrParticles[lvl][din].listItems()); lit.ok(); ++lit) {
696  P& p = lit();
697 
698  p.position() = p.template vect<0>() + dtSixth * p.template vect<1>() + dtHalf * p.template vect<2>() +
699  dtHalf * p.template vect<3>() + dtSixth * p.velocity();
700  }
701  }
702  }
703 
704  // Remap and compute v = v(x)
705  amrParticles.remap();
706  m_solver->interpolateVelocities();
707  }
708 
709  m_amr->removeCoveredParticlesIF(amrParticles, m_phase);
710 }
711 
712 #include <CD_NamespaceFooter.H>
713 
714 #endif
Namespace containing various particle management utilities.
File containing some useful static methods related to random number generation.
Declaration of a TimeStepper implementation for advancing a tracer particle solver.
static void setValue(LevelData< MFInterfaceFAB< T >> &a_lhs, const T &a_value)
Set value in an MFInterfaceFAB data holder.
Definition: CD_DataOpsImplem.H:23
Templated class for holding particles on an AMR hierarchy with particle remapping.
Definition: CD_ParticleContainer.H:50
void remap()
Remap over the entire AMR hierarchy.
Definition: CD_ParticleContainerImplem.H:973
void clearParticles()
Clear all particles.
Definition: CD_ParticleContainerImplem.H:1670
void addParticlesDestructive(List< P > &a_particles)
Add particles to container. The input particles are destroyed by this routine.
Definition: CD_ParticleContainerImplem.H:617
AMRParticles< P > & getParticles()
Get all particles on all levels.
Definition: CD_ParticleContainerImplem.H:270
Implementation of TimeStepper for advancing tracer particles in a fixed velocity field.
Definition: CD_TracerParticleStepper.H:51
void registerRealms() override
Register realms. Primal is the only realm we need.
Definition: CD_TracerParticleStepperImplem.H:93
virtual void parseInitialConditions()
Parse initial conditions.
Definition: CD_TracerParticleStepperImplem.H:200
void parseRuntimeOptions() override
Parse runtime options.
Definition: CD_TracerParticleStepperImplem.H:131
void initialData() override
Fill problem with initial data.
Definition: CD_TracerParticleStepperImplem.H:77
void registerOperators() override
Register operators.
Definition: CD_TracerParticleStepperImplem.H:105
virtual Real computeDt() override
Compute a time step to be used by Driver.
Definition: CD_TracerParticleStepperImplem.H:287
void writePlotData(LevelData< EBCellFAB > &a_output, int &a_icomp, const std::string a_realm, const int a_level) const override
Write plot data to output holder.
Definition: CD_TracerParticleStepperImplem.H:269
int getNumberOfPlotVariables() const override
Get number of plot variables for this physics module.
Definition: CD_TracerParticleStepperImplem.H:245
virtual void advanceParticlesEuler(const Real a_dt)
Advance particles using explicit Euler rule.
Definition: CD_TracerParticleStepperImplem.H:478
virtual void preRegrid(const int a_lmin, const int a_oldFinestLevel) override
Perform pre-regrid operations.
Definition: CD_TracerParticleStepperImplem.H:348
void allocate() override
Allocate storage for solvers and time stepper.
Definition: CD_TracerParticleStepperImplem.H:64
virtual void regrid(const int a_lmin, const int a_oldFinestLevel, const int a_newFinestLevel) override
Time stepper regrid method.
Definition: CD_TracerParticleStepperImplem.H:360
virtual Real advance(const Real a_dt) override
Advancement method. Swaps between various kernels.
Definition: CD_TracerParticleStepperImplem.H:299
void parseOptions()
Parse options.
Definition: CD_TracerParticleStepperImplem.H:117
virtual void synchronizeSolverTimes(const int a_step, const Real a_time, const Real a_dt) override
Synchronize solver times and time steps.
Definition: CD_TracerParticleStepperImplem.H:332
virtual void advanceParticlesRK2(const Real a_dt)
Advance particles using second order Runge-Kutta.
Definition: CD_TracerParticleStepperImplem.H:517
void setupSolvers() override
Instantiate the tracer particle solver.
Definition: CD_TracerParticleStepperImplem.H:48
virtual ~TracerParticleStepper()
Destructor.
Definition: CD_TracerParticleStepperImplem.H:38
virtual void advanceParticlesRK4(const Real a_dt)
Advance particles using fourth order Runge-Kutta.
Definition: CD_TracerParticleStepperImplem.H:587
Vector< std::string > getPlotVariableNames() const override
Get plot variable names.
Definition: CD_TracerParticleStepperImplem.H:257
virtual void parseVelocityField()
Parse velocity field.
Definition: CD_TracerParticleStepperImplem.H:175
virtual void parseIntegrator()
Parse reactive integrator.
Definition: CD_TracerParticleStepperImplem.H:145
virtual void postRegrid() override
Perform post-regrid operations.
Definition: CD_TracerParticleStepperImplem.H:377
virtual void initialParticles()
Fill initial particles.
Definition: CD_TracerParticleStepperImplem.H:428
TracerParticleStepper()
Constructor. Does nothing.
Definition: CD_TracerParticleStepperImplem.H:27
virtual void setVelocity()
Set the velocity on the mesh.
Definition: CD_TracerParticleStepperImplem.H:391
static Real getUniformReal01()
Get a uniform real number on the interval [0,1].
Definition: CD_RandomImplem.H:147
static const std::string Primal
Identifier for perimal realm.
Definition: CD_Realm.H:47
Base class for a tracer particle solver. This solver can advance particles in a pre-defined velocity ...
Definition: CD_TracerParticleSolver.H:37
Real max(const Real &a_input) noexcept
Get the maximum of the input, reduced over MPI ranks (in the Chombo communicator)
Definition: CD_ParallelOpsImplem.H:176
Namespace for encapsulating physics code for tracer particles.
Definition: CD_TracerParticlePhysics.H:21