12 #ifndef CD_TracerParticleStepperImplem_H
13 #define CD_TracerParticleStepperImplem_H
22 #include <CD_NamespaceHeader.H>
29 CH_TIME(
"TracerParticleStepper::TracerParticleStepper");
40 CH_TIME(
"TracerParticleStepper::~TracerParticleStepper");
41 if (m_verbosity > 5) {
42 pout() <<
"TracerParticleStepper::~TracerParticleStepper" << endl;
50 CH_TIME(
"TracerParticleStepper::setupSolvers()");
51 if (m_verbosity > 5) {
52 pout() <<
"TracerParticleStepper::setupSolvers()" << endl;
57 m_solver->setPhase(m_phase);
58 m_solver->setRealm(m_realm);
59 m_solver->parseOptions();
66 CH_TIME(
"TracerParticleStepper::allocate()");
67 if (m_verbosity > 5) {
68 pout() <<
"TracerParticleStepper::allocate()" << endl;
71 m_amr->allocate(m_velocity, m_realm, m_phase, SpaceDim);
79 CH_TIME(
"TracerParticleStepper::initialData()");
80 if (m_verbosity > 5) {
81 pout() <<
"TracerParticleStepper::initialData()" << endl;
85 this->initialParticles();
87 m_solver->setVelocity(m_velocity);
88 m_solver->interpolateVelocities();
95 CH_TIME(
"TracerParticleStepper::registerRealms()");
96 if (m_verbosity > 5) {
97 pout() <<
"TracerParticleStepper::registerRealms()" << endl;
100 m_amr->registerRealm(m_realm);
103 template <
typename P>
107 CH_TIME(
"TracerParticleStepper::registerOperators()");
108 if (m_verbosity > 5) {
109 pout() <<
"TracerParticleStepper::registerOperators()" << endl;
112 m_solver->registerOperators();
115 template <
typename P>
119 CH_TIME(
"TracerParticleStepper::parseOptions()");
120 if (m_verbosity > 5) {
121 pout() <<
"TracerParticleStepper::parseOptions()" << endl;
124 this->parseIntegrator();
125 this->parseVelocityField();
126 this->parseInitialConditions();
129 template <
typename P>
133 CH_TIME(
"TracerParticleStepper::parseRuntimeOptions()");
134 if (m_verbosity > 5) {
135 pout() <<
"TracerParticleStepper::parseRuntimeOptions()" << endl;
138 this->parseIntegrator();
140 m_solver->parseRuntimeOptions();
143 template <
typename P>
147 CH_TIME(
"TracerParticleStepper::parseIntegrator()");
148 if (m_verbosity > 5) {
149 pout() <<
"TracerParticleStepper::parseIntegrator()" << endl;
152 ParmParse pp(
"TracerParticleStepper");
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;
162 else if (str ==
"rk2") {
163 m_algorithm = IntegrationAlgorithm::RK2;
165 else if (str ==
"rk4") {
166 m_algorithm = IntegrationAlgorithm::RK4;
169 MayDay::Error(
"TracerParticleStepper::parseIntegrator -- logic bust");
173 template <
typename P>
177 CH_TIME(
"TracerParticleStepper::parseVelocityField()");
178 if (m_verbosity > 5) {
179 pout() <<
"TracerParticleStepper::parseVelocityField()" << endl;
182 ParmParse pp(
"TracerParticleStepper");
185 pp.get(
"velocity_field", v);
188 m_velocityField = VelocityField::Diagonal;
191 m_velocityField = VelocityField::Rotational;
194 MayDay::Error(
"TracerParticleStepper::parseVelocityField -- logic bust");
198 template <
typename P>
202 CH_TIME(
"TracerParticleStepper::parseInitialConditions()");
203 if (m_verbosity > 5) {
204 pout() <<
"TracerParticleStepper::parseInitialConditions()" << endl;
207 ParmParse pp(
"TracerParticleStepper");
210 pp.get(
"initial_particles", numParticles);
212 m_numInitialParticles = size_t(
std::max(0.0, numParticles));
216 template <
typename P>
220 CH_TIME(
"TracerParticleStepper::writeCheckpointData(HDF5Handle, int)");
221 if (m_verbosity > 5) {
222 pout() <<
"TracerParticleStepper::writeCheckpointData(HDF5Handle, int)" << endl;
225 m_solver->writeCheckpointLevel(a_handle, a_lvl);
230 template <
typename P>
234 CH_TIME(
"TracerParticleStepper::readCheckpointData(HDF5Handle, int)");
235 if (m_verbosity > 5) {
236 pout() <<
"TracerParticleStepper::readCheckpointData(HDF5Handle, int)" << endl;
239 m_solver->readCheckpointLevel(a_handle, a_lvl);
243 template <
typename P>
247 CH_TIME(
"TracerParticleStepper::getNumberOfPlotVariables()");
248 if (m_verbosity > 5) {
249 pout() <<
"TracerParticleStepper::getNumberOfPlotVariables()" << endl;
252 return m_solver->getNumberOfPlotVariables();
255 template <
typename P>
256 inline Vector<std::string>
259 CH_TIME(
"TracerParticleStepper::getPlotVariableNames()");
260 if (m_verbosity > 5) {
261 pout() <<
"TracerParticleStepper::getPlotVariableNames()" << endl;
264 return m_solver->getPlotVariableNames();
267 template <
typename P>
271 const std::string a_outputRealm,
272 const int a_level)
const
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;
279 CH_assert(a_level >= 0);
280 CH_assert(a_level <= m_amr->getFinestLevel());
282 m_solver->writePlotData(a_output, a_icomp, a_outputRealm, a_level);
285 template <
typename P>
289 CH_TIME(
"TracerParticleStepper::computeDt()");
290 if (m_verbosity > 5) {
291 pout() <<
"TracerParticleStepper::computeDt()" << endl;
294 return m_cfl * m_solver->computeDt();
297 template <
typename P>
301 CH_TIME(
"TracerParticleStepper::advance(Real)");
302 if (m_verbosity > 5) {
303 pout() <<
"TracerParticleStepper::advance(Real)" << endl;
306 switch (m_algorithm) {
307 case IntegrationAlgorithm::Euler: {
308 this->advanceParticlesEuler(a_dt);
312 case IntegrationAlgorithm::RK2: {
313 this->advanceParticlesRK2(a_dt);
317 case IntegrationAlgorithm::RK4: {
318 this->advanceParticlesRK4(a_dt);
323 MayDay::Error(
"TracerParticleStepper::advance -- logic bust");
330 template <
typename P>
334 CH_TIME(
"TracerParticleStepper::synchronizeSolverTimes");
335 if (m_verbosity > 5) {
336 pout() <<
"TracerParticleStepper::synchronizeSolverTimes" << endl;
343 m_solver->setTime(a_step, a_time, a_dt);
346 template <
typename P>
350 CH_TIME(
"TracerParticleStepper::preRegrid(int, int)");
351 if (m_verbosity > 5) {
352 pout() <<
"TracerParticleStepper::preRegrid(int, int)" << endl;
355 m_solver->preRegrid(a_lmin, a_oldFinestLevel);
358 template <
typename P>
362 CH_TIME(
"TracerParticleStepper::regrid(int, int, int)");
363 if (m_verbosity > 5) {
364 pout() <<
"TracerParticleStepper::regrid(int, int, int)" << endl;
368 m_amr->reallocate(m_velocity, m_phase, a_lmin);
372 m_solver->regrid(a_lmin, a_oldFinestLevel, a_newFinestLevel);
375 template <
typename P>
379 CH_TIME(
"TracerParticleStepper::postRegrid()");
380 if (m_verbosity > 5) {
381 pout() <<
"TracerParticleStepper::postRegrid()" << endl;
386 m_solver->interpolateVelocities();
389 template <
typename P>
393 CH_TIME(
"TracerParticleStepper::setVelocity()");
394 if (m_verbosity > 5) {
395 pout() <<
"TracerParticleStepper::setVelocity()" << endl;
398 std::function<RealVect(
const RealVect a_position)> velFunc;
400 switch (m_velocityField) {
401 case VelocityField::Diagonal: {
402 velFunc = [](
const RealVect& a_position) -> RealVect {
403 return RealVect::Unit;
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]);
413 return RealVect(D_DECL(-r * sin(theta), r * cos(theta), 0.));
422 m_amr->conservativeAverage(m_velocity, m_realm, m_phase);
423 m_amr->interpGhost(m_velocity, m_realm, m_phase);
426 template <
typename P>
430 CH_TIME(
"TracerParticleStepper::initialParticles()");
431 if (m_verbosity > 5) {
432 pout() <<
"TracerParticleStepper::initialParticles()" << endl;
444 const RealVect probLo = m_amr->getProbLo();
445 const RealVect probHi = m_amr->getProbHi();
447 auto uniformDistribution = [probLo, probHi]() -> RealVect {
448 RealVect ret = probLo;
450 for (
int dir = 0; dir < SpaceDim; dir++) {
458 List<P> initialParticles;
460 ParticleManagement::drawRandomParticles(initialParticles, m_numInitialParticles, uniformDistribution);
461 for (ListIterator<P> lit(initialParticles); lit.ok(); ++lit) {
462 lit().weight() = 1.0;
471 pout() <<
"removing particles" << endl;
472 m_amr->removeCoveredParticlesIF(solverParticles, m_phase);
473 pout() <<
"done initial particles" << endl;
476 template <
typename P>
480 CH_TIME(
"TracerParticleStepper::advanceParticlesEuler()");
481 if (m_verbosity > 5) {
482 pout() <<
"TracerParticleStepper::advanceParticlesEuler()" << endl;
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();
493 const int nbox = dit.size();
495 #pragma omp parallel for schedule(runtime)
496 for (
int mybox = 0; mybox < nbox; mybox++) {
497 const DataIndex& din = dit[mybox];
499 List<P>& particles = amrParticles[lvl][din].listItems();
501 for (ListIterator<P> lit(particles); lit.ok(); ++lit) {
504 p.position() += p.velocity() * a_dt;
509 amrParticles.
remap();
510 m_amr->removeCoveredParticlesIF(amrParticles, m_phase);
512 m_solver->interpolateVelocities();
515 template <
typename P>
519 CH_TIME(
"TracerParticleStepper::advanceParticlesRK2()");
520 if (m_verbosity > 5) {
521 pout() <<
"TracerParticleStepper::advanceParticlesRK2()" << endl;
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();
533 const int nbox = dit.size();
535 #pragma omp parallel for schedule(runtime)
536 for (
int mybox = 0; mybox < nbox; mybox++) {
537 const DataIndex& din = dit[mybox];
539 List<P>& particles = amrParticles[lvl][din].listItems();
541 for (ListIterator<P> lit(particles); lit.ok(); ++lit) {
544 p.template vect<0>() = p.position();
545 p.template vect<1>() = p.velocity();
547 p.position() += p.velocity() * a_dt;
553 amrParticles.
remap();
554 m_amr->removeCoveredParticlesIF(amrParticles, m_phase);
555 m_solver->interpolateVelocities();
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();
562 const int nbox = dit.size();
564 #pragma omp parallel for schedule(runtime)
565 for (
int mybox = 0; mybox < nbox; mybox++) {
566 const DataIndex& din = dit[mybox];
568 List<P>& particles = amrParticles[lvl][din].listItems();
570 for (ListIterator<P> lit(particles); lit.ok(); ++lit) {
574 p.position() = p.template vect<0>() + 0.5 * a_dt * (p.template vect<1>() + p.velocity());
580 amrParticles.
remap();
581 m_amr->removeCoveredParticlesIF(amrParticles, m_phase);
582 m_solver->interpolateVelocities();
585 template <
typename P>
589 CH_TIME(
"TracerParticleStepper::advanceParticlesRK4()");
590 if (m_verbosity > 5) {
591 pout() <<
"TracerParticleStepper::advanceParticlesRK4()" << endl;
598 const Real dtHalf = a_dt / 2.0;
599 const Real dtThird = a_dt / 3.0;
600 const Real dtSixth = a_dt / 6.0;
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();
608 const int nbox = dit.size();
610 #pragma omp parallel for schedule(runtime)
611 for (
int mybox = 0; mybox < nbox; mybox++) {
612 const DataIndex& din = dit[mybox];
614 for (ListIterator<P> lit(amrParticles[lvl][din].listItems()); lit.ok(); ++lit) {
618 p.template vect<0>() = p.position();
620 p.template vect<1>() = p.velocity();
621 p.position() = p.template vect<0>() + dtHalf * p.velocity();
627 amrParticles.
remap();
628 m_solver->interpolateVelocities();
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();
637 const int nbox = dit.size();
639 #pragma omp parallel for schedule(runtime)
640 for (
int mybox = 0; mybox < nbox; mybox++) {
641 const DataIndex& din = dit[mybox];
643 for (ListIterator<P> lit(amrParticles[lvl][din].listItems()); lit.ok(); ++lit) {
646 p.template vect<2>() = p.velocity();
647 p.position() = p.template vect<0>() + dtHalf * p.velocity();
653 amrParticles.
remap();
654 m_solver->interpolateVelocities();
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();
663 const int nbox = dit.size();
665 #pragma omp parallel for schedule(runtime)
666 for (
int mybox = 0; mybox < nbox; mybox++) {
667 const DataIndex& din = dit[mybox];
669 for (ListIterator<P> lit(amrParticles[lvl][din].listItems()); lit.ok(); ++lit) {
672 p.template vect<3>() = p.velocity();
673 p.position() = p.template vect<0>() + a_dt * p.velocity();
679 amrParticles.
remap();
680 m_solver->interpolateVelocities();
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();
689 const int nbox = dit.size();
691 #pragma omp parallel for schedule(runtime)
692 for (
int mybox = 0; mybox < nbox; mybox++) {
693 const DataIndex& din = dit[mybox];
695 for (ListIterator<P> lit(amrParticles[lvl][din].listItems()); lit.ok(); ++lit) {
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();
705 amrParticles.
remap();
706 m_solver->interpolateVelocities();
709 m_amr->removeCoveredParticlesIF(amrParticles, m_phase);
712 #include <CD_NamespaceFooter.H>
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