13#ifndef CD_ITOKMCSTEPPERIMPLEM_H
14#define CD_ITOKMCSTEPPERIMPLEM_H
22#include <BoxIterator.H>
35#include <CD_NamespaceHeader.H>
37using namespace Physics::ItoKMC;
46template <
typename P,
typename Traits>
52 const RealVect& a_probLo)
noexcept
54 a_leaf.sortByCell(a_box, a_dx * RealVect::Unit, a_probLo);
57 a_cells.resize(a_box.numPts());
58 for (std::size_t c = 0;
c < a_leaf.numCells();
c++) {
59 a_leaf.extractCell(c, a_cells[c]);
64template <
typename P,
typename Traits>
72 std::size_t total = 0;
86template <
typename I,
typename C,
typename R,
typename F>
89 CH_TIME(
"ItoKMCStepper::ItoKMCStepper");
93 m_name =
"ItoKMCStepper";
97 m_maxGrowthDt = 1.E99;
98 m_maxShrinkDt = 1.E99;
102 m_redistributeCDR =
true;
105 m_minParticleAdvectionCFL = 0.0;
106 m_maxParticleAdvectionCFL = 1.0;
107 m_minParticleDiffusionCFL = 0.0;
108 m_physicsDtFactor = 1.0;
109 m_maxParticleDiffusionCFL = std::numeric_limits<Real>::max();
110 m_minParticleAdvectionDiffusionCFL = std::numeric_limits<Real>::max();
111 m_maxParticleAdvectionDiffusionCFL = std::numeric_limits<Real>::max();
112 m_fluidAdvectionDiffusionCFL = 0.5;
113 m_relaxTimeFactor = std::numeric_limits<Real>::max();
114 m_minDt = std::numeric_limits<Real>::min();
115 m_maxDt = std::numeric_limits<Real>::max();
116 m_physicsDt = std::numeric_limits<Real>::max();
117 m_maxReducedField = 0.0;
120template <
typename I,
typename C,
typename R,
typename F>
123 CH_TIME(
"ItoKMCStepper::ItoKMCStepper(RefCountrPtr<ItoKMCPhysics>)");
125 m_physics = a_physics;
127 if (m_physics->getNumPlasmaSpecies() == 0) {
128 MayDay::Abort(
"ItoKMCStepper::ItoKMCStepper -- numPlasmaSpecies = 0, there's no problem to solve here!");
132template <
typename I,
typename C,
typename R,
typename F>
135 CH_TIME(
"ItoKMCStepper::~ItoKMCStepper");
138template <
typename I,
typename C,
typename R,
typename F>
142 CH_TIME(
"ItoKMCStepper::parseOptions");
143 if (m_verbosity > 5) {
144 pout() << m_name +
"::parseOptions" << endl;
147 this->parseVerbosity();
148 this->parseExitOnFailure();
149 this->parseRedistributeCDR();
150 this->parsePlotVariables();
151 this->parseSuperParticles();
152 this->parseDualGrid();
153 this->parseLoadBalance();
154 this->parseTimeStepRestrictions();
155 this->parseParametersEB();
158template <
typename I,
typename C,
typename R,
typename F>
162 CH_TIME(
"ItoKMCStepper::parseRuntimeOptions");
163 if (m_verbosity > 5) {
164 pout() << m_name +
"::parseRuntimeOptions" << endl;
167 this->parseVerbosity();
168 this->parseExitOnFailure();
169 this->parseRedistributeCDR();
170 this->parsePlotVariables();
171 this->parseSuperParticles();
172 this->parseLoadBalance();
173 this->parseTimeStepRestrictions();
174 this->parseParametersEB();
176 m_ito->parseRuntimeOptions();
177 m_cdr->parseRuntimeOptions();
178 m_fieldSolver->parseRuntimeOptions();
179 m_rte->parseRuntimeOptions();
180 m_sigmaSolver->parseRuntimeOptions();
182 m_physics->parseRuntimeOptions();
185template <
typename I,
typename C,
typename R,
typename F>
189 CH_TIME(
"ItoKMCStepper::parseVerbosity");
190 if (m_verbosity > 5) {
191 pout() << m_name +
"::parseVerbosity" << endl;
194 ParmParse pp(m_name.c_str());
196 pp.get(
"verbosity", m_verbosity);
197 pp.get(
"profile", m_profile);
200template <
typename I,
typename C,
typename R,
typename F>
204 CH_TIME(
"ItoKMCStepper::parseExitOnFailure");
205 if (m_verbosity > 5) {
206 pout() << m_name +
"::parseExitOnFailure" << endl;
209 ParmParse pp(m_name.c_str());
211 pp.get(
"abort_on_failure", m_abortOnFailure);
214template <
typename I,
typename C,
typename R,
typename F>
218 CH_TIME(
"ItoKMCStepper::parseRedistributeCDR");
219 if (m_verbosity > 5) {
220 pout() << m_name +
"::parseRedistributeCDR" << endl;
223 ParmParse pp(m_name.c_str());
225 pp.get(
"redistribute_cdr", m_redistributeCDR);
228template <
typename I,
typename C,
typename R,
typename F>
232 CH_TIME(
"ItoKMCStepper::parsePlotVariables");
233 if (m_verbosity > 5) {
234 pout() << m_name +
"::parsePlotVariables" << endl;
237 m_plotConductivity =
false;
238 m_plotCurrentDensity =
false;
239 m_plotParticlesPerPatch =
false;
242 ParmParse pp(m_name.c_str());
243 const int num = pp.countval(
"plt_vars");
246 Vector<std::string> str(num);
247 pp.getarr(
"plt_vars", str, 0, num);
250 for (
int i = 0; i < num; i++) {
251 if (str[i] ==
"conductivity") {
252 m_plotConductivity =
true;
254 else if (str[i] ==
"current_density") {
255 m_plotCurrentDensity =
true;
257 else if (str[i] ==
"particles_per_patch") {
258 m_plotParticlesPerPatch =
true;
264template <
typename I,
typename C,
typename R,
typename F>
268 CH_TIME(
"ItoKMCStepper::parseSuperParticles");
269 if (m_verbosity > 5) {
270 pout() << m_name +
"::parseSuperParticles" << endl;
273 ParmParse pp(m_name.c_str());
278 pp.get(
"merge_interval", m_mergeInterval);
281template <
typename I,
typename C,
typename R,
typename F>
285 CH_TIME(
"ItoKMCStepper::parseDualGrid");
286 if (m_verbosity > 5) {
287 pout() << m_name +
"::parseDualGrid" << endl;
290 ParmParse pp(m_name.c_str());
292 pp.get(
"dual_grid", m_dualGrid);
295 m_particleRealm =
"ParticleRealm";
297 CH_assert(m_particleRealm != m_fluidRealm);
300 m_particleRealm = m_fluidRealm;
304template <
typename I,
typename C,
typename R,
typename F>
308 CH_TIME(
"ItoKMCStepper::parseLoadBalance");
309 if (m_verbosity > 5) {
310 pout() << m_name +
"::parseLoadBalance" << endl;
313 ParmParse pp(m_name.c_str());
317 pp.get(
"load_balance_particles", m_loadBalanceParticles);
318 pp.get(
"load_balance_fluid", m_loadBalanceFluid);
319 pp.get(
"load_per_cell", m_loadPerCell);
322 pp.get(
"box_sorting", str);
324 m_boxSort = BoxSorting::None;
326 else if (str ==
"std") {
327 m_boxSort = BoxSorting::Std;
329 else if (str ==
"shuffle") {
330 m_boxSort = BoxSorting::Shuffle;
332 else if (str ==
"morton") {
333 m_boxSort = BoxSorting::Morton;
335 else if (str ==
"hilbert") {
336 m_boxSort = BoxSorting::Hilbert;
339 const std::string err =
"ItoKMCStepper::parseLoadBalance - 'box_sorting = " + str +
"' not recognized";
341 MayDay::Error(err.c_str());
345 const int numIndices = pp.countval(
"load_indices");
347 if (numIndices > 0) {
348 pp.getarr(
"load_indices", m_loadBalanceIndices, 0, numIndices);
351 const std::string err =
"ItoKMCStepper::parseLoadBalance - 'load_indices' argument has zero entries";
353 MayDay::Error(err.c_str());
357template <
typename I,
typename C,
typename R,
typename F>
361 CH_TIME(
"ItoKMCStepper::parseTimeStepRestrictions");
362 if (m_verbosity > 5) {
363 pout() << m_name +
"::parseTimeStepRestrictions" << endl;
366 ParmParse pp(m_name.c_str());
368 pp.get(
"min_particle_advection_cfl", m_minParticleAdvectionCFL);
369 pp.get(
"max_particle_advection_cfl", m_maxParticleAdvectionCFL);
370 pp.get(
"min_particle_diffusion_cfl", m_minParticleDiffusionCFL);
371 pp.get(
"max_particle_diffusion_cfl", m_maxParticleDiffusionCFL);
372 pp.get(
"min_particle_advection_diffusion_cfl", m_minParticleAdvectionDiffusionCFL);
373 pp.get(
"max_particle_advection_diffusion_cfl", m_maxParticleAdvectionDiffusionCFL);
374 pp.get(
"fluid_advection_diffusion_cfl", m_fluidAdvectionDiffusionCFL);
375 pp.get(
"relax_dt_factor", m_relaxTimeFactor);
376 pp.get(
"min_dt", m_minDt);
377 pp.get(
"max_dt", m_maxDt);
378 pp.get(
"max_growth_dt", m_maxGrowthDt);
379 pp.get(
"max_shrink_dt", m_maxShrinkDt);
380 pp.get(
"physics_dt_factor", m_physicsDtFactor);
382 if (m_maxGrowthDt <= 1.0) {
383 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have max_growth_dt > 1.0");
386 if (m_maxShrinkDt <= 1.0) {
387 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have max_shrink_dt > 1.0");
390 if (m_relaxTimeFactor <= 0.0) {
391 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have relax_dt > 0.0");
395 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have min_dt >= 0.0");
399 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have max_dt >= 0.0");
402 if (m_maxParticleAdvectionCFL <= 0.0) {
403 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have max_particle_advection_cfl > 0.0");
406 if (m_minParticleAdvectionCFL < 0.0) {
407 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have min_particle_advection_cfl >= 0.0");
410 if (m_maxParticleDiffusionCFL <= 0.0) {
411 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have particle_diffusion_cfl > 0.0");
414 if (m_minParticleDiffusionCFL < 0.0) {
415 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have particle_diffusion_cfl >= 0.0");
418 if (m_maxParticleAdvectionDiffusionCFL <= 0.0) {
419 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have particle_advection_diffusion_cfl > 0.0");
422 if (m_minParticleAdvectionDiffusionCFL < 0.0) {
423 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have particle_advection_diffusion_cfl >= 0.0");
426 if (m_fluidAdvectionDiffusionCFL <= 0.0) {
427 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have fluid_advection_diffusion_cfl > 0.0");
430 if (m_physicsDtFactor <= 0.0) {
431 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have physics_dft_factor > 0.0");
435template <
typename I,
typename C,
typename R,
typename F>
439 CH_TIME(
"ItoKMCStepper::parseTimeStepRestrictions");
440 if (m_verbosity > 5) {
441 pout() << m_name +
"::parseTimeStepRestrictions" << endl;
444 ParmParse pp(m_name.c_str());
448 pp.get(
"eb_tolerance", m_toleranceEB);
451template <
typename I,
typename C,
typename R,
typename F>
455 CH_TIME(
"ItoKMCStepper::setupSolver");
456 if (m_verbosity > 5) {
457 pout() << m_name +
"::setupSolvers" << endl;
462 this->setupPoisson();
463 this->setupRadiativeTransfer();
467template <
typename I,
typename C,
typename R,
typename F>
471 CH_TIME(
"ItoKMCStepper::setupIto");
472 if (m_verbosity > 5) {
473 pout() << m_name +
"::setupIto" << endl;
477 m_ito = factory.
newLayout(m_physics->getItoSpecies());
479 m_ito->parseOptions();
480 m_ito->setAmr(m_amr);
481 m_ito->setPhase(m_plasmaPhase);
482 m_ito->setComputationalGeometry(m_computationalGeometry);
483 m_ito->setRealm(m_particleRealm);
486template <
typename I,
typename C,
typename R,
typename F>
490 CH_TIME(
"ItoKMCStepper::setupCdr");
491 if (m_verbosity > 5) {
492 pout() << m_name +
"::setupCdr" << endl;
496 m_cdr = factory.
newLayout(m_physics->getCdrSpecies());
498 m_cdr->parseOptions();
499 m_cdr->setAmr(m_amr);
500 m_cdr->setPhase(m_plasmaPhase);
501 m_cdr->setComputationalGeometry(m_computationalGeometry);
502 m_cdr->setRealm(m_fluidRealm);
505template <
typename I,
typename C,
typename R,
typename F>
509 CH_TIME(
"ItoKMCStepper::setupRadiativeTransfer");
510 if (m_verbosity > 5) {
511 pout() << m_name +
"::setupRadiativeTransfer" << endl;
515 m_rte = factory.
newLayout(m_physics->getRtSpecies());
517 m_rte->parseOptions();
518 m_rte->setPhase(m_plasmaPhase);
519 m_rte->setAmr(m_amr);
520 m_rte->setComputationalGeometry(m_computationalGeometry);
521 m_rte->setRealm(m_particleRealm);
522 m_rte->sanityCheck();
525template <
typename I,
typename C,
typename R,
typename F>
529 CH_TIME(
"ItoKMCStepper::setupPoisson");
530 if (m_verbosity > 5) {
531 pout() << m_name +
"::setupPoisson" << endl;
534 m_fieldSolver = RefCountedPtr<FieldSolver>(
new F());
535 m_fieldSolver->parseOptions();
536 m_fieldSolver->setAmr(m_amr);
537 m_fieldSolver->setComputationalGeometry(m_computationalGeometry);
538 m_fieldSolver->setVoltage(m_voltage);
539 m_fieldSolver->setRealm(m_fluidRealm);
542template <
typename I,
typename C,
typename R,
typename F>
546 CH_TIME(
"ItoKMCStepper::setupSigma");
547 if (m_verbosity > 5) {
548 pout() << m_name +
"::setupSigma" << endl;
552 m_sigmaSolver->parseOptions();
553 m_sigmaSolver->setRealm(m_fluidRealm);
554 m_sigmaSolver->setPhase(m_plasmaPhase);
555 m_sigmaSolver->setName(
"Surface charge");
556 m_sigmaSolver->setTime(0, 0.0, 0.0);
559template <
typename I,
typename C,
typename R,
typename F>
563 CH_TIME(
"ItoKMCStepper::allocate");
564 if (m_verbosity > 5) {
565 pout() << m_name +
"::allocate" << endl;
571 m_fieldSolver->allocate();
572 m_sigmaSolver->allocate();
574 this->allocateInternals();
577template <
typename I,
typename C,
typename R,
typename F>
581 CH_TIME(
"ItoKMCStepper::allocateInternals");
582 if (m_verbosity > 5) {
583 pout() << m_name +
"::allocateInternals" << endl;
586 const int numItoSpecies = m_physics->getNumItoSpecies();
587 const int numCdrSpecies = m_physics->getNumCdrSpecies();
588 const int numPlasmaSpecies = m_physics->getNumPlasmaSpecies();
589 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
591 CH_assert(numPlasmaSpecies > 0);
594 m_amr->allocate(m_fluidScratch1, m_fluidRealm, m_plasmaPhase, 1);
595 m_amr->allocate(m_fluidScratchD, m_fluidRealm, m_plasmaPhase, SpaceDim);
596 m_amr->allocate(m_fluidScratchEB, m_fluidRealm, m_plasmaPhase, 1);
598 m_amr->allocate(m_particleScratch1, m_particleRealm, m_plasmaPhase, 1);
599 m_amr->allocate(m_particleScratchD, m_particleRealm, m_plasmaPhase, SpaceDim);
600 m_amr->allocate(m_particleScratchEB, m_particleRealm, m_plasmaPhase, 1);
603 m_amr->allocate(m_neutralDensity, m_fluidRealm, m_plasmaPhase, 1);
606 m_amr->allocate(m_conductivityCell, m_fluidRealm, m_plasmaPhase, 1);
607 m_amr->allocate(m_conductivityFace, m_fluidRealm, m_plasmaPhase, 1);
608 m_amr->allocate(m_conductivityEB, m_fluidRealm, m_plasmaPhase, 1);
611 m_amr->allocate(m_electricFieldParticle, m_particleRealm, m_plasmaPhase, SpaceDim);
612 m_amr->allocate(m_electricFieldFluid, m_fluidRealm, m_plasmaPhase, SpaceDim);
615 m_cdrMobilities.resize(numCdrSpecies);
616 m_cdrPhotoiProducts.resize(numCdrSpecies);
617 for (
int i = 0; i < numCdrSpecies; i++) {
618 m_amr->allocate(m_cdrMobilities[i], m_fluidRealm, m_plasmaPhase, 1);
621 m_amr->allocate(*m_cdrPhotoiProducts[i], m_particleRealm);
625 m_fluidGradPhiIto.resize(numItoSpecies);
626 m_fluidPhiIto.resize(numItoSpecies);
627 m_fluidGradPhiCDR.resize(numCdrSpecies);
628 for (
int i = 0; i < numItoSpecies; i++) {
629 m_amr->allocate(m_fluidGradPhiIto[i], m_fluidRealm, m_plasmaPhase, SpaceDim);
630 m_amr->allocate(m_fluidPhiIto[i], m_fluidRealm, m_plasmaPhase, 1);
632 for (
int i = 0; i < numCdrSpecies; i++) {
633 m_amr->allocate(m_fluidGradPhiCDR[i], m_fluidRealm, m_plasmaPhase, SpaceDim);
637 m_secondaryParticles.resize(numItoSpecies);
638 m_secondaryPhotons.resize(numPhotonSpecies);
640 m_cdrFluxes.resize(numCdrSpecies);
641 m_cdrFluxesExtrap.resize(numCdrSpecies);
643 for (
int i = 0; i < numItoSpecies; i++) {
645 m_amr->allocate(*m_secondaryParticles[i], m_particleRealm);
648 for (
int i = 0; i < numPhotonSpecies; i++) {
650 m_amr->allocate(*m_secondaryPhotons[i], m_particleRealm);
653 for (
int i = 0; i < numCdrSpecies; i++) {
654 m_amr->allocate(m_cdrFluxes[i], m_particleRealm, m_plasmaPhase, 1);
655 m_amr->allocate(m_cdrFluxesExtrap[i], m_particleRealm, m_plasmaPhase, 1);
659 m_amr->allocate(m_currentDensity, m_fluidRealm, m_plasmaPhase, SpaceDim);
662 m_amr->allocate(m_kmcDt, m_fluidRealm, m_plasmaPhase, 1);
665 m_amr->allocate(m_fluidPPC, m_fluidRealm, m_plasmaPhase, numPlasmaSpecies);
667 if (numItoSpecies > 0) {
668 m_amr->allocate(m_particleItoPPC, m_particleRealm, m_plasmaPhase, numItoSpecies);
669 m_amr->allocate(m_particleOldItoPPC, m_particleRealm, m_plasmaPhase, numItoSpecies);
673 m_amr->allocate(m_particleItoPPC, m_particleRealm, m_plasmaPhase, 1);
674 m_amr->allocate(m_particleOldItoPPC, m_particleRealm, m_plasmaPhase, 1);
677 if (numCdrSpecies > 0) {
678 m_amr->allocate(m_fluidCdrPPC, m_fluidRealm, m_plasmaPhase, numCdrSpecies);
679 m_amr->allocate(m_fluidOldCdrPPC, m_fluidRealm, m_plasmaPhase, numCdrSpecies);
682 m_amr->allocatePointer(m_fluidCdrPPC, m_fluidRealm);
683 m_amr->allocatePointer(m_fluidOldCdrPPC, m_fluidRealm);
686 if (numPhotonSpecies > 0) {
687 m_amr->allocate(m_particleYPC, m_particleRealm, m_plasmaPhase, numPhotonSpecies);
688 m_amr->allocate(m_fluidYPC, m_fluidRealm, m_plasmaPhase, numPhotonSpecies);
692 m_amr->allocate(m_particleYPC, m_particleRealm, m_plasmaPhase, 1);
693 m_amr->allocate(m_fluidYPC, m_fluidRealm, m_plasmaPhase, 1);
699template <
typename I,
typename C,
typename R,
typename F>
703 CH_TIME(
"ItoKMCStepper::postInitialize");
704 if (m_verbosity > 5) {
705 pout() << m_name +
"::postInitialize" << endl;
709template <
typename I,
typename C,
typename R,
typename F>
713 CH_TIME(
"ItoKMCStepper::initialData");
714 if (m_verbosity > 5) {
715 pout() << m_name +
"::initialData" << endl;
718 CH_assert(!(m_cdr.isNull()));
719 CH_assert(!(m_ito.isNull()));
720 CH_assert(!(m_rte.isNull()));
721 CH_assert(!(m_sigmaSolver.isNull()));
722 CH_assert(!(m_fieldSolver.isNull()));
724 m_ito->initialData();
725 m_cdr->initialData();
726 m_rte->initialData();
727 this->initialSigma();
731 m_ito->makeSuperparticles(ItoSolver::WhichContainer::Bulk);
734 m_fieldSolver->setPermittivities();
735 this->computeSpaceChargeDensity();
736 this->solvePoisson();
739 this->computeDriftVelocities();
740 this->computeDiffusionCoefficients();
743 this->fillNeutralDensity();
746template <
typename I,
typename C,
typename R,
typename F>
750 CH_TIME(
"ItoKMCStepper::initialSigma");
751 if (m_verbosity > 5) {
752 pout() << m_name +
"::initialSigma" << endl;
755 const RealVect probLo = m_amr->getProbLo();
757 EBAMRIVData& sigma = m_sigmaSolver->getPhi();
759 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
760 const DisjointBoxLayout& dbl = m_amr->getGrids(m_sigmaSolver->getRealm())[lvl];
761 const DataIterator& dit = dbl.dataIterator();
762 const EBISLayout& ebisl = m_amr->getEBISLayout(m_sigmaSolver->getRealm(), m_sigmaSolver->getPhase())[lvl];
763 const Real dx = m_amr->getDx()[lvl];
765 const int nbox = dit.size();
767#pragma omp parallel for schedule(runtime)
768 for (
int mybox = 0; mybox < nbox; mybox++) {
769 const DataIndex& din = dit[mybox];
771 BaseIVFAB<Real>& phi = (*sigma[lvl])[din];
772 const EBISBox& ebisbox = ebisl[din];
774 CH_assert(phi.nComp() == 1);
776 auto kernel = [&](
const VolIndex& vof) ->
void {
777 const RealVect pos = probLo +
Location::position(Location::Cell::Boundary, vof, ebisbox, dx);
779 phi(vof, 0) = m_physics->initialSigma(m_time, pos);
782 VoFIterator& vofit = (*m_amr->getVofIterator(m_sigmaSolver->getRealm(), m_sigmaSolver->getPhase())[lvl])[din];
789 m_amr->conservativeAverage(sigma, m_fluidRealm, m_sigmaSolver->getPhase());
792 m_sigmaSolver->resetElectrodes(sigma, 0.0);
795template <
typename I,
typename C,
typename R,
typename F>
799 CH_TIME(
"ItoKMCStepper::postCheckpointSetup");
800 if (m_verbosity > 5) {
801 pout() << m_name +
"::postCheckpointSetup" << endl;
807 this->postCheckpointPoisson();
810 this->computeDriftVelocities();
811 this->computeDiffusionCoefficients();
814template <
typename I,
typename C,
typename R,
typename F>
818 CH_TIME(
"ItoKMCStepper::postCheckpointPoisson");
819 if (m_verbosity > 5) {
820 pout() << m_name +
"::postCheckpointPoisson" << endl;
824 m_fieldSolver->postCheckpoint();
827 MFAMRCellData& potential = m_fieldSolver->getPotential();
829 m_amr->conservativeAverage(potential, m_fluidRealm);
830 m_amr->interpGhostMG(potential, m_fluidRealm);
832 m_fieldSolver->computeElectricField();
835 const EBAMRCellData E = m_amr->alias(m_plasmaPhase, m_fieldSolver->getElectricField());
838 m_amr->copyData(m_electricFieldFluid, E);
839 m_amr->conservativeAverage(m_electricFieldFluid, m_fluidRealm, m_plasmaPhase);
840 m_amr->interpGhostPwl(m_electricFieldFluid, m_fluidRealm, m_plasmaPhase);
841 m_amr->interpToCentroids(m_electricFieldFluid, m_fluidRealm, m_plasmaPhase);
844 m_amr->copyData(m_electricFieldParticle, E);
845 m_amr->conservativeAverage(m_electricFieldParticle, m_particleRealm, m_plasmaPhase);
846 m_amr->interpGhostPwl(m_electricFieldParticle, m_particleRealm, m_plasmaPhase);
847 m_amr->interpToCentroids(m_electricFieldParticle, m_particleRealm, m_plasmaPhase);
850 m_fieldSolver->setupSolver();
854template <
typename I,
typename C,
typename R,
typename F>
858 CH_TIME(
"ItoKMCStepper::writeCheckpointHeader");
859 if (m_verbosity > 5) {
860 pout() << m_name +
"::writeCheckpointHeader" << endl;
866template <
typename I,
typename C,
typename R,
typename F>
870 CH_TIME(
"ItoKMCStepper::readCheckpointHeader");
871 if (m_verbosity > 5) {
872 pout() << m_name +
"::readCheckpointHeader" << endl;
878template <
typename I,
typename C,
typename R,
typename F>
882 CH_TIME(
"ItoKMCStepper::writeCheckpointData");
883 if (m_verbosity > 5) {
884 pout() << m_name +
"::writeCheckpointData" << endl;
888 solverIt()->writeCheckpointLevel(a_handle, a_lvl);
892 solverIt()->writeCheckpointLevel(a_handle, a_lvl);
896 solverIt()->writeCheckpointLevel(a_handle, a_lvl);
899 m_fieldSolver->writeCheckpointLevel(a_handle, a_lvl);
900 m_sigmaSolver->writeCheckpointLevel(a_handle, a_lvl);
905template <
typename I,
typename C,
typename R,
typename F>
909 CH_TIME(
"ItoKMCStepper::readCheckpointData");
910 if (m_verbosity > 5) {
911 pout() << m_name +
"::readCheckpointData" << endl;
915 solverIt()->readCheckpointLevel(a_handle, a_lvl);
919 solverIt()->readCheckpointLevel(a_handle, a_lvl);
923 solverIt()->readCheckpointLevel(a_handle, a_lvl);
926 m_fieldSolver->readCheckpointLevel(a_handle, a_lvl);
927 m_sigmaSolver->readCheckpointLevel(a_handle, a_lvl);
931template <
typename I,
typename C,
typename R,
typename F>
935 CH_TIME(
"ItoKMCStepper::getNumberOfPlotVariables");
936 if (m_verbosity > 5) {
937 pout() << m_name +
"::getNumberOfPlotVariables" << endl;
944 numComp += solverIt()->getNumberOfPlotVariables();
948 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
949 numComp += solverIt()->getNumberOfPlotVariables();
954 numComp += solverIt()->getNumberOfPlotVariables();
958 numComp += m_fieldSolver->getNumberOfPlotVariables();
961 numComp += m_sigmaSolver->getNumberOfPlotVariables();
964 if (m_plotConductivity) {
969 if (m_plotCurrentDensity) {
974 if (m_plotParticlesPerPatch) {
979 numComp += m_physics->getNumberOfPlotVariables();
984template <
typename I,
typename C,
typename R,
typename F>
988 CH_TIME(
"ItoKMCStepper::getPlotVariableNames");
989 if (m_verbosity > 5) {
990 pout() << m_name +
"::getPlotVariableNames" << endl;
993 Vector<std::string> plotVarNames;
995 plotVarNames.append(m_fieldSolver->getPlotVariableNames());
996 plotVarNames.append(m_sigmaSolver->getPlotVariableNames());
999 plotVarNames.append(solverIt()->getPlotVariableNames());
1002 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
1003 plotVarNames.append(solverIt()->getPlotVariableNames());
1007 plotVarNames.append(solverIt()->getPlotVariableNames());
1011 if (m_plotConductivity) {
1012 plotVarNames.push_back(
"Conductivity");
1016 if (m_plotCurrentDensity) {
1017 plotVarNames.push_back(
"x-J");
1018 plotVarNames.push_back(
"y-J");
1019 if (SpaceDim == 3) {
1020 plotVarNames.push_back(
"z-J");
1025 if (m_plotParticlesPerPatch) {
1026 plotVarNames.push_back(
"Particles per patch");
1030 plotVarNames.append(m_physics->getPlotVariableNames());
1032 return plotVarNames;
1035template <
typename I,
typename C,
typename R,
typename F>
1039 const std::string& a_outputRealm,
1040 const int a_level)
const noexcept
1042 CH_TIME(
"ItoKMCStepper::writePlotData");
1043 if (m_verbosity > 5) {
1044 pout() << m_name +
"::writePlotData" << endl;
1048 m_fieldSolver->writePlotData(a_output, a_icomp, a_outputRealm, a_level);
1051 m_sigmaSolver->writePlotData(a_output, a_icomp, a_outputRealm, a_level);
1055 solverIt()->writePlotData(a_output, a_icomp, a_outputRealm, a_level);
1059 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
1060 solverIt()->writePlotData(a_output, a_icomp, a_outputRealm, a_level);
1065 solverIt()->writePlotData(a_output, a_icomp, a_outputRealm, a_level);
1069 if (m_plotConductivity) {
1070 this->writeData(a_output, a_icomp, m_conductivityCell, a_outputRealm, a_level,
false,
true);
1074 if (m_plotCurrentDensity) {
1075 this->writeData(a_output, a_icomp, m_currentDensity, a_outputRealm, a_level,
false,
true);
1079 if (m_plotParticlesPerPatch) {
1080 this->writeNumberOfParticlesPerPatch(a_output, a_icomp, a_outputRealm, a_level);
1084 if (m_physics->getNumberOfPlotVariables() > 0) {
1085 this->writeData(a_output, a_icomp, m_physicsPlotVariables, a_outputRealm, a_level,
false,
true);
1089template <
typename I,
typename C,
typename R,
typename F>
1093 const EBAMRCellData& a_data,
1094 const std::string a_outputRealm,
1096 const bool a_interpToCentroids,
1097 const bool a_interpGhost)
const noexcept
1100 CH_TIMERS(
"ItoKMCStepper::writeData");
1101 CH_TIMER(
"ItoKMCStepper::writeData::allocate", t1);
1102 CH_TIMER(
"ItoKMCStepper::writeData::local_copy", t2);
1103 CH_TIMER(
"ItoKMCStepper::writeData::interp_ghost", t3);
1104 CH_TIMER(
"ItoKMCStepper::writeData::interp_centroid", t4);
1105 CH_TIMER(
"ItoKMCStepper::writeData::final_copy", t5);
1106 if (m_verbosity > 5) {
1107 pout() << m_name +
"::writeData" << endl;
1111 const int numComp = a_data[a_level]->nComp();
1114 const Interval srcInterv(0, numComp - 1);
1115 const Interval dstInterv(a_comp, a_comp + numComp - 1);
1118 LevelData<EBCellFAB> scratch;
1119 m_amr->allocate(scratch, a_data.getRealm(), m_plasmaPhase, a_level, numComp);
1123 m_amr->copyData(scratch, *a_data[a_level], a_level, a_data.getRealm(), a_data.getRealm());
1128 if (a_level > 0 && a_interpGhost) {
1129 m_amr->interpGhost(scratch, *a_data[a_level - 1], a_level, a_data.getRealm(), m_plasmaPhase);
1134 if (a_interpToCentroids) {
1135 m_amr->interpToCentroids(scratch, a_data.getRealm(), m_plasmaPhase, a_level);
1142 m_amr->copyData(a_output,
1149 CopyStrategy::ValidGhost,
1150 CopyStrategy::ValidGhost);
1156template <
typename I,
typename C,
typename R,
typename F>
1160 const std::string a_outputRealm,
1161 const int a_level)
const noexcept
1163 CH_TIME(
"ItoKMCStepper::writeNumberOfParticlesPerPatch");
1164 if (m_verbosity > 5) {
1165 pout() << m_name +
"::writeNumberOfParticlesPerPatch" << endl;
1168 CH_assert(a_level >= 0);
1169 CH_assert(a_level <= m_amr->getFinestLevel());
1173 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
1176 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
1177 const DisjointBoxLayout& dbl = m_amr->getGrids(m_particleRealm)[lvl];
1178 const DataIterator& dit = dbl.dataIterator();
1180 const int nbox = dit.size();
1182#pragma omp parallel for schedule(runtime)
1183 for (
int mybox = 0; mybox < nbox; mybox++) {
1184 const DataIndex& din = dit[mybox];
1186 (*m_particleScratch1[lvl])[din] += particles[lvl][din].size();
1191 m_amr->copyData(a_output,
1192 *m_particleScratch1[a_level],
1196 Interval(a_icomp, a_icomp),
1202template <
typename I,
typename C,
typename R,
typename F>
1206 CH_TIME(
"ItoKMCStepper::synchronizeSolverTimes");
1207 if (m_verbosity > 5) {
1208 pout() << m_name +
"::synchronizeSolverTimes" << endl;
1211 m_timeStep = a_step;
1215 m_ito->setTime(a_step, a_time, a_dt);
1216 m_fieldSolver->setTime(a_step, a_time, a_dt);
1217 m_rte->setTime(a_step, a_time, a_dt);
1218 m_sigmaSolver->setTime(a_step, a_time, a_dt);
1221template <
typename I,
typename C,
typename R,
typename F>
1225 CH_TIME(
"ItoKMCStepper::printStepReport");
1226 if (m_verbosity > 5) {
1227 pout() << m_name +
"::printStepReport" << endl;
1230 const unsigned long long localParticlesBulk = m_ito->getNumParticles(ItoSolver::WhichContainer::Bulk,
true);
1231 const unsigned long long globalParticlesBulk = m_ito->getNumParticles(ItoSolver::WhichContainer::Bulk,
false);
1232 const unsigned long long localParticlesEB = m_ito->getNumParticles(ItoSolver::WhichContainer::EB,
true);
1233 const unsigned long long globalParticlesEB = m_ito->getNumParticles(ItoSolver::WhichContainer::EB,
false);
1234 const unsigned long long localParticlesDomain = m_ito->getNumParticles(ItoSolver::WhichContainer::Domain,
true);
1235 const unsigned long long globalParticlesDomain = m_ito->getNumParticles(ItoSolver::WhichContainer::Domain,
false);
1236 const unsigned long long localParticlesSource = m_ito->getNumParticles(ItoSolver::WhichContainer::Source,
true);
1237 const unsigned long long globalParticlesSource = m_ito->getNumParticles(ItoSolver::WhichContainer::Source,
false);
1239 Real avgParticles = 0.0;
1242 Real minParticles = 0.0;
1243 Real maxParticles = 0.0;
1248 this->getParticleStatistics(avgParticles, stdDev, minParticles, maxParticles, minRank, maxRank);
1250 Real maxDensity = -std::numeric_limits<Real>::max();
1251 Real minDensity = +std::numeric_limits<Real>::max();
1253 std::string maxSolver =
"invalid solver";
1254 std::string minSolver =
"invalid solver";
1256 this->getMaxMinRelativeItoDensity(maxDensity, minDensity, maxSolver, minSolver);
1257 this->getMaxMinRelativeCDRDensity(maxDensity, minDensity, maxSolver, minSolver);
1260 switch (m_timeCode) {
1261 case TimeCode::Physics: {
1262 str =
"dt restricted by 'Physics'";
1266 case TimeCode::AdvectionIto: {
1267 str =
"dt restricted by 'Advection (Ito)'";
1271 case TimeCode::DiffusionIto: {
1272 str =
"dt restricted by 'Diffusion (Ito)'";
1276 case TimeCode::AdvectionDiffusionIto: {
1277 str =
"dt restricted by 'AdvectionDiffusion (Ito)'";
1281 case TimeCode::AdvectionDiffusionCDR: {
1282 str =
"dt restricted by 'AdvectionDiffusion (CDR)'";
1286 case TimeCode::RelaxationTime: {
1287 str =
"dt restricted by 'Relaxation time'";
1291 case TimeCode::Hardcap: {
1292 str =
"dt restricted by 'Hardcap'";
1297 str =
"dt restricted by 'Unspecified'";
1304 const Real Qplus = this->computeQplus();
1305 const Real Qminu = this->computeQminu();
1306 const Real Qsurf = this->computeQsurf();
1307 const Real Qtot = Qplus + Qminu + Qsurf;
1312 const std::string whitespace =
" ";
1313 pout() <<
" " + str << endl;
1314 pout() << whitespace +
"Emax = " << m_maxReducedField <<
" (Td)" << endl
1315 << whitespace +
"Max n/N = " << maxDensity <<
" (" << maxSolver <<
")" << endl
1316 << whitespace +
"Qplus = " << Qplus << endl
1317 << whitespace +
"Qminu = " << Qminu << endl
1318 << whitespace +
"Qsurf = " << Qsurf << endl
1319 << whitespace +
"Qtot = " << Qtot << endl
1320 << whitespace +
"CFL (Ito) = " << m_dt / m_particleAdvectionDiffusionDt << endl
1321 << whitespace +
"CFL (CDR) = " << m_dt / m_fluidAdvectionDiffusionDt << endl
1322 << whitespace +
"dt/dt_relax = " << m_dt / m_relaxationTime << endl
1331 << whitespace +
"#Min part. = " << minParticles <<
" (on rank = " << minRank <<
")" << endl
1332 << whitespace +
"#Max part. = " << maxParticles <<
" (on rank = " << maxRank <<
")" << endl
1333 << whitespace +
"#Avg. part. = " << avgParticles << endl
1334 << whitespace +
"#Dev. part. = " << stdDev <<
" (" << 100. * stdDev / avgParticles <<
"%)" << endl;
1338template <
typename I,
typename C,
typename R,
typename F>
1342 std::string& a_maxSolver,
1343 std::string& a_minSolver)
const noexcept
1345 CH_TIME(
"ItoKMCStepper::getMaxMinDensity(Realx2, std::string2x)");
1346 if (m_verbosity > 5) {
1347 pout() << m_name +
"::getMaxMinDensity(Realx2, std::string2x)" << endl;
1352 m_amr->allocate(tmp, m_fluidRealm, m_plasmaPhase, 1);
1355 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
1356 const RefCountedPtr<ItoSolver>& solver = solverIt();
1357 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
1358 const int Z = species->getChargeNumber();
1361 Real curMin = std::numeric_limits<Real>::max();
1362 Real curMax = -std::numeric_limits<Real>::max();
1366 const Interval dstInterv = Interval(0, 0);
1367 const Interval srcInterv = Interval(0, 0);
1369 m_amr->copyData(tmp, solverIt()->getPhi(), dstInterv, srcInterv);
1371 DataOps::divideFallback(tmp, m_neutralDensity, 0.0, m_amr->getMultiCutVofIterator(m_fluidRealm, m_plasmaPhase));
1372 DataOps::getMaxMin(curMax, curMin, tmp, 0, m_amr->getMultiCutVofIterator(m_fluidRealm, m_plasmaPhase));
1374 if (curMax > a_maxDensity) {
1375 a_maxDensity = curMax;
1376 a_maxSolver = solver->getName();
1379 if (curMin < a_minDensity) {
1380 a_minDensity = curMin;
1381 a_minSolver = solver->getName();
1387template <
typename I,
typename C,
typename R,
typename F>
1391 std::string& a_maxSolver,
1392 std::string& a_minSolver)
const noexcept
1394 CH_TIME(
"ItoKMCStepper::getMaxMinRelativeCDRDensity(Realx2, std::string2x)");
1395 if (m_verbosity > 5) {
1396 pout() << m_name +
"::getMaxMinRelativeCDRDensity(Realx2, std::string2x)" << endl;
1400 m_amr->allocate(tmp, m_fluidRealm, m_plasmaPhase, 1);
1403 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
1404 const RefCountedPtr<CdrSolver>& solver = solverIt();
1405 const RefCountedPtr<CdrSpecies>& species = solver->getSpecies();
1406 const int Z = species->getChargeNumber();
1409 Real curMin = std::numeric_limits<Real>::max();
1410 Real curMax = -std::numeric_limits<Real>::max();
1413 const Interval dstInterv = Interval(0, 0);
1414 const Interval srcInterv = Interval(0, 0);
1416 m_amr->copyData(tmp, solverIt()->getPhi(), dstInterv, srcInterv);
1418 DataOps::divideFallback(tmp, m_neutralDensity, 0.0, m_amr->getMultiCutVofIterator(m_fluidRealm, m_plasmaPhase));
1419 DataOps::getMaxMin(curMax, curMin, tmp, 0, m_amr->getMultiCutVofIterator(m_fluidRealm, m_plasmaPhase));
1421 if (curMax > a_maxDensity) {
1422 a_maxDensity = curMax;
1423 a_maxSolver = solver->getName();
1426 if (curMin < a_minDensity) {
1427 a_minDensity = curMin;
1428 a_minSolver = solver->getName();
1434template <
typename I,
typename C,
typename R,
typename F>
1438 Real& a_minParticles,
1439 Real& a_maxParticles,
1443 CH_TIME(
"ItoKMCStepper::getParticleStatistics");
1444 if (m_verbosity > 5) {
1445 pout() << m_name +
"::getParticleStatistics" << endl;
1451 const Real numParticles = 1.0 * m_ito->getNumParticles(ItoSolver::WhichContainer::Bulk,
true);
1459 a_minParticles = minParticles.first;
1460 a_maxParticles = maxParticles.first;
1462 a_minRank = minParticles.second;
1463 a_maxRank = maxParticles.second;
1466template <
typename I,
typename C,
typename R,
typename F>
1470 CH_TIME(
"ItoKMCStepper::computeDt");
1471 if (m_verbosity > 5) {
1472 pout() << m_name +
"::computeDt" << endl;
1475 Timer timer(m_name +
"::computeDt");
1477 Real dt = std::numeric_limits<Real>::max();
1479 const Real maxGrowthDt = m_prevDt > 0.0 ? m_prevDt * m_maxGrowthDt : dt;
1480 const Real minShrinkDt = m_prevDt > 0.0 ? m_prevDt / m_maxShrinkDt : 0.0;
1482 if (m_timeStep == 0) {
1483 this->computeDummyPhysicsDt();
1488 m_particleAdvectionDt = m_ito->computeAdvectiveDt();
1492 m_particleDiffusionDt = m_ito->computeDiffusiveDt();
1495 timer.
startEvent(
"AdvectionDiffusion (Ito)");
1496 m_particleAdvectionDiffusionDt = m_ito->computeDt();
1497 timer.
stopEvent(
"AdvectionDiffusion (Ito)");
1499 timer.
startEvent(
"AdvectionDiffusion (CDR)");
1500 m_fluidAdvectionDiffusionDt = m_cdr->computeAdvectionDiffusionDt();
1504 m_relaxationTime = this->computeRelaxationTime();
1507 const bool hasParticleAdvectionDt = m_particleAdvectionDt < std::numeric_limits<Real>::max();
1508 const bool hasParticleDiffusionDt = m_particleDiffusionDt < std::numeric_limits<Real>::max();
1509 const bool hasParticleAdvectionDiffusionDt = m_particleAdvectionDiffusionDt < std::numeric_limits<Real>::max();
1511 if (m_maxParticleAdvectionCFL * m_particleAdvectionDt < dt) {
1512 dt = m_maxParticleAdvectionCFL * m_particleAdvectionDt;
1513 m_timeCode = TimeCode::AdvectionIto;
1516 if (m_maxParticleDiffusionCFL * m_particleDiffusionDt < dt) {
1517 dt = m_maxParticleDiffusionCFL * m_particleDiffusionDt;
1518 m_timeCode = TimeCode::DiffusionIto;
1521 if (m_maxParticleAdvectionDiffusionCFL * m_particleAdvectionDiffusionDt < dt) {
1522 dt = m_maxParticleAdvectionDiffusionCFL * m_particleAdvectionDiffusionDt;
1523 m_timeCode = TimeCode::AdvectionDiffusionIto;
1526 if (std::min(m_fluidAdvectionDiffusionCFL, 0.9) * m_fluidAdvectionDiffusionDt < dt) {
1527 dt = std::min(m_fluidAdvectionDiffusionCFL, 0.9) * m_fluidAdvectionDiffusionDt;
1528 m_timeCode = TimeCode::AdvectionDiffusionCDR;
1531 if (m_relaxTimeFactor * m_relaxationTime < dt) {
1532 dt = m_relaxTimeFactor * m_relaxationTime;
1533 m_timeCode = TimeCode::RelaxationTime;
1536 if (m_physicsDtFactor * m_physicsDt < dt) {
1537 dt = m_physicsDtFactor * m_physicsDt;
1538 m_timeCode = TimeCode::Physics;
1541 if ((dt < m_minParticleAdvectionCFL * m_particleAdvectionDt) && hasParticleAdvectionDt) {
1542 dt = m_minParticleAdvectionCFL * m_particleAdvectionDt;
1543 m_timeCode = TimeCode::AdvectionIto;
1546 if ((dt < m_minParticleDiffusionCFL * m_particleDiffusionDt) && hasParticleDiffusionDt) {
1547 dt = m_minParticleDiffusionCFL * m_particleDiffusionDt;
1548 m_timeCode = TimeCode::DiffusionIto;
1551 if ((dt < m_minParticleAdvectionDiffusionCFL * m_particleAdvectionDiffusionDt) && hasParticleAdvectionDiffusionDt) {
1552 dt = m_minParticleAdvectionDiffusionCFL * m_particleAdvectionDiffusionDt;
1553 m_timeCode = TimeCode::AdvectionDiffusionIto;
1556 if (dt > maxGrowthDt) {
1560 if (dt < minShrinkDt) {
1566 m_timeCode = TimeCode::Hardcap;
1571 m_timeCode = TimeCode::Hardcap;
1581template <
typename I,
typename C,
typename R,
typename F>
1585 CH_TIME(
"ItoKMCStepper::registerRealms");
1586 if (m_verbosity > 5) {
1587 pout() << m_name +
"::registerRealms" << endl;
1591 m_amr->registerRealm(m_fluidRealm);
1592 m_amr->registerRealm(m_particleRealm);
1595template <
typename I,
typename C,
typename R,
typename F>
1599 CH_TIME(
"ItoKMCStepper::registerOperators");
1600 if (m_verbosity > 5) {
1601 pout() << m_name +
"::registerOperators" << endl;
1604 m_ito->registerOperators();
1605 m_cdr->registerOperators();
1606 m_fieldSolver->registerOperators();
1607 m_rte->registerOperators();
1608 m_sigmaSolver->registerOperators();
1611 m_amr->registerParticleGhostMask(m_particleRealm, 1);
1614template <
typename I,
typename C,
typename R,
typename F>
1618 CH_TIME(
"ItoKMCStepper::prePlot");
1619 if (m_verbosity > 5) {
1620 pout() << m_name +
"::prePlot" << endl;
1623 const int numPhysicsPlotVars = m_physics->getNumberOfPlotVariables();
1625 if (numPhysicsPlotVars > 0) {
1626 m_amr->allocate(m_physicsPlotVariables, m_fluidRealm, m_plasmaPhase, numPhysicsPlotVars);
1628 this->computePhysicsPlotVariables(m_physicsPlotVariables);
1631 this->computeCurrentDensity(this->m_currentDensity);
1632 m_ito->depositParticles();
1635template <
typename I,
typename C,
typename R,
typename F>
1639 CH_TIME(
"ItoKMCStepper::postPlot");
1640 if (m_verbosity > 5) {
1641 pout() << m_name +
"::postPlot" << endl;
1644 m_physicsPlotVariables.clear();
1647template <
typename I,
typename C,
typename R,
typename F>
1651 CH_TIME(
"ItoKMCStepper::preRegrid");
1652 if (m_verbosity > 5) {
1653 pout() << m_name +
"::preRegrid" << endl;
1656 const int numItoSpecies = m_physics->getNumItoSpecies();
1657 const int numCdrSpecies = m_physics->getNumCdrSpecies();
1658 const int numPlasmaSpecies = m_physics->getNumPlasmaSpecies();
1659 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
1668 if (m_loadBalanceParticles) {
1669 Vector<RefCountedPtr<ItoSolver>> lbSolvers = this->getLoadBalanceSolvers();
1671 m_loadBalancePPC.resize(lbSolvers.size());
1674 for (
int i = 0; i < lbSolvers.size(); i++) {
1675 m_amr->allocate(m_loadBalancePPC[i], m_particleRealm, m_plasmaPhase, 1);
1677 EBAMRCellData& compPPC = m_loadBalancePPC[i];
1685 m_fluidScratch1.clear();
1686 m_fluidScratchD.clear();
1687 m_fluidScratchEB.clear();
1689 m_particleScratch1.clear();
1690 m_particleScratchD.clear();
1691 m_particleScratchEB.clear();
1693 m_conductivityCell.clear();
1694 m_conductivityFace.clear();
1695 m_conductivityEB.clear();
1697 m_electricFieldParticle.clear();
1698 m_electricFieldFluid.clear();
1700 m_electricFieldParticle.clear();
1701 m_electricFieldFluid.clear();
1703 for (
int i = 0; i < numCdrSpecies; i++) {
1704 m_cdrMobilities[i].clear();
1705 m_cdrPhotoiProducts[i]->clearParticles();
1708 for (
int i = 0; i < numItoSpecies; i++) {
1709 m_fluidGradPhiIto[i].clear();
1710 m_fluidPhiIto[i].clear();
1712 for (
int i = 0; i < numCdrSpecies; i++) {
1713 m_fluidGradPhiCDR[i].clear();
1716 for (
int i = 0; i < numItoSpecies; i++) {
1717 m_secondaryParticles[i]->clearParticles();
1719 for (
int i = 0; i < numPhotonSpecies; i++) {
1720 m_secondaryPhotons[i]->clearParticles();
1723 for (
int i = 0; i < numCdrSpecies; i++) {
1724 m_cdrFluxes[i].clear();
1725 m_cdrFluxesExtrap[i].clear();
1728 m_currentDensity.clear();
1731 m_particleItoPPC.clear();
1732 m_particleOldItoPPC.clear();
1734 if (numCdrSpecies > 0) {
1735 m_fluidCdrPPC.clear();
1736 m_fluidOldCdrPPC.clear();
1739 m_particleYPC.clear();
1743 m_ito->preRegrid(a_lmin, a_oldFinestLevel);
1744 m_cdr->preRegrid(a_lmin, a_oldFinestLevel);
1745 m_fieldSolver->preRegrid(a_lmin, a_oldFinestLevel);
1746 m_rte->preRegrid(a_lmin, a_oldFinestLevel);
1747 m_sigmaSolver->preRegrid(a_lmin, a_oldFinestLevel);
1750template <
typename I,
typename C,
typename R,
typename F>
1754 CH_TIME(
"ItoKMCStepper::regrid");
1755 if (m_verbosity > 5) {
1756 pout() << m_name +
"::regrid" << endl;
1759 this->allocateInternals();
1761 m_ito->regrid(a_lmin, a_oldFinestLevel, a_newFinestLevel);
1762 m_cdr->regrid(a_lmin, a_oldFinestLevel, a_newFinestLevel);
1763 m_fieldSolver->regrid(a_lmin, a_oldFinestLevel, a_newFinestLevel);
1764 m_rte->regrid(a_lmin, a_oldFinestLevel, a_newFinestLevel);
1765 m_sigmaSolver->regrid(a_lmin, a_oldFinestLevel, a_newFinestLevel);
1772 m_ito->depositParticles();
1774 const bool converged = this->solvePoisson();
1776 const std::string err =
"ItoKMCStepper::regrid - Poisson solve did not converge after regrid!!!";
1778 if (m_abortOnFailure) {
1779 MayDay::Error(err.c_str());
1782 MayDay::Warning(err.c_str());
1786 this->computeDriftVelocities();
1787 this->computeDiffusionCoefficients();
1789 this->fillNeutralDensity();
1792template <
typename I,
typename C,
typename R,
typename F>
1796 CH_TIME(
"ItoKMCStepper::postRegrid");
1798 if (m_loadBalanceParticles) {
1799 for (
int i = 0; i < m_loadBalancePPC.size(); i++) {
1800 m_amr->deallocate(m_loadBalancePPC[i]);
1805template <
typename I,
typename C,
typename R,
typename F>
1809 CH_TIME(
"ItoKMCStepper::setVoltage");
1810 if (m_verbosity > 5) {
1811 pout() << m_name +
"::setVoltage" << endl;
1814 m_voltage = a_voltage;
1817template <
typename I,
typename C,
typename R,
typename F>
1821 CH_TIME(
"ItoKMCStepper::fillNeutralDensity");
1822 if (m_verbosity > 5) {
1823 pout() << m_name +
"::fillNeutralDensity" << endl;
1828 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
1829 const DisjointBoxLayout& dbl = m_amr->getGrids(m_fluidRealm)[lvl];
1830 const EBISLayout& ebisl = m_amr->getEBISLayout(m_fluidRealm, m_plasmaPhase)[lvl];
1831 const DataIterator& dit = dbl.dataIterator();
1832 const Real dx = m_amr->getDx()[lvl];
1833 const RealVect probLo = m_amr->getProbLo();
1835 const int nbox = dit.size();
1837 CH_assert(!(m_neutralDensity[lvl].isNull()));
1838 CH_assert(m_neutralDensity[lvl]->nComp() == 1);
1840#pragma omp parallel for schedule(runtime)
1841 for (
int mybox = 0; mybox < nbox; mybox++) {
1842 const DataIndex& din = dit[mybox];
1843 const Box cellBox = dbl[din];
1844 const EBISBox& ebisbox = ebisl[din];
1846 EBCellFAB& neutralDensity = (*m_neutralDensity[lvl])[din];
1847 FArrayBox& neutralDensityReg = neutralDensity.getFArrayBox();
1849 auto regularKernel = [&](
const IntVect& iv) ->
void {
1850 const RealVect pos = probLo + (0.5 * RealVect::Unit + iv) * dx;
1852 neutralDensityReg(iv, 0) = m_physics->getNeutralDensity(pos);
1855 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
1856 const RealVect pos = probLo +
Location::position(Location::Cell::Centroid, vof, ebisbox, dx);
1858 neutralDensity(vof, 0) = m_physics->getNeutralDensity(pos);
1861 VoFIterator& vofit = (*m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase)[lvl])[din];
1865 BoxLoops::loop<D_DECL(1, 1, 1)>(cellBox, regularKernel);
1870 m_amr->conservativeAverage(m_neutralDensity, m_fluidRealm, m_plasmaPhase);
1871 m_amr->interpGhostPwl(m_neutralDensity, m_fluidRealm, m_plasmaPhase);
1874template <
typename I,
typename C,
typename R,
typename F>
1878 CH_TIME(
"ItoKMCStepper::computeMaxReducedElectricField");
1879 if (m_verbosity > 5) {
1880 pout() << m_name +
"::computeMaxReducedElectricField" << endl;
1884 const EBAMRCellData cellCenteredE = m_amr->alias(a_phase, m_fieldSolver->getElectricField());
1888 m_amr->allocate(tmp, m_fluidRealm, a_phase, 1);
1892 m_amr->getNotCoveredCells(m_fluidRealm, a_phase),
1893 m_amr->getMultiCutVofIterator(m_fluidRealm, a_phase));
1894 m_amr->interpToCentroids(tmp, m_fluidRealm, m_plasmaPhase);
1896 DataOps::divideFallback(tmp, m_neutralDensity, 0.0, m_amr->getMultiCutVofIterator(m_fluidRealm, m_plasmaPhase));
1901 DataOps::getMaxMin(max, min, tmp, 0, m_amr->getMultiCutVofIterator(m_fluidRealm, m_plasmaPhase));
1906template <
typename I,
typename C,
typename R,
typename F>
1911 CH_TIME(
"ItoKMCStepper::computeElectricField(EBAMRCellData, phase)");
1912 if (m_verbosity > 5) {
1913 pout() << m_name +
"::computeElectricField(EBAMRCellData, phase)" << endl;
1916 CH_assert(a_electricField.getRealm() == m_fluidRealm);
1918 m_fieldSolver->computeElectricField(a_electricField, a_phase, m_fieldSolver->getPotential());
1921template <
typename I,
typename C,
typename R,
typename F>
1925 CH_TIME(
"ItoKMCStepper::getTime");
1926 if (m_verbosity > 5) {
1927 pout() << m_name +
"::getTime" << endl;
1933template <
typename I,
typename C,
typename R,
typename F>
1937 CH_TIME(
"ItoKMCStepper::computeSpaceChargeDensity()");
1938 if (m_verbosity > 5) {
1939 pout() << m_name +
"::computeSpaceChargeDensity()" << endl;
1942 this->computeSpaceChargeDensity(m_fieldSolver->getRho(), m_ito->getDensities(), m_cdr->getPhis());
1945template <
typename I,
typename C,
typename R,
typename F>
1948 const Vector<EBAMRCellData*>& a_itoDensities,
1949 const Vector<EBAMRCellData*>& a_cdrDensities)
noexcept
1951 CH_TIME(
"ItoKMCStepper::computeSpaceChargeDensity(rho, densities)");
1952 if (m_verbosity > 5) {
1953 pout() << m_name +
"::computeSpaceChargeDensity(rho, densities)" << endl;
1960 CH_assert(a_rho.getRealm() == m_fluidRealm);
1961 CH_assert(a_itoDensities.size() == 0 || a_itoDensities[0]->getRealm() == m_particleRealm);
1962 CH_assert(a_cdrDensities.size() == 0 || a_cdrDensities[0]->getRealm() == m_fluidRealm);
1969 EBAMRCellData rhoPhase = m_amr->alias(m_plasmaPhase, a_rho);
1971 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
1972 const RefCountedPtr<ItoSolver>& solver = solverIt();
1973 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
1974 const int idx = solverIt.index();
1975 const int Z = species->getChargeNumber();
1978 m_amr->copyData(m_fluidScratch1, *a_itoDensities[idx]);
1984 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
1985 const RefCountedPtr<CdrSolver>& solver = solverIt();
1986 const RefCountedPtr<CdrSpecies>& species = solver->getSpecies();
1987 const int idx = solverIt.index();
1988 const int Z = species->getChargeNumber();
1997 m_amr->arithmeticAverage(a_rho, m_fluidRealm);
1998 m_amr->interpGhostPwl(a_rho, m_fluidRealm);
2001 m_amr->interpToCentroids(rhoPhase, m_fluidRealm, m_plasmaPhase);
2004template <
typename I,
typename C,
typename R,
typename F>
2008 CH_TIME(
"ItoKMCStepper::computeConductivityCell(EBAMRCellData)");
2009 if (m_verbosity > 5) {
2010 pout() << m_name +
"::computeConductivityCell(EBAMRCellData)" << endl;
2013 this->computeConductivityCell(a_conductivity, m_ito->getParticles(ItoSolver::WhichContainer::Bulk));
2016template <
typename I,
typename C,
typename R,
typename F>
2021 CH_TIME(
"ItoKMCStepper::computeConductivityCell(EBAMRCellData, Particles)");
2022 if (m_verbosity > 5) {
2023 pout() << m_name +
"::computeConductivityCell(EBAMRCellData, Particles)" << endl;
2029 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
2030 RefCountedPtr<ItoSolver>& solver = solverIt();
2031 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
2033 const int idx = solverIt.index();
2034 const int Z = species->getChargeNumber();
2036 if (Z != 0 && solver->isMobile()) {
2037 solver->depositConductivity(m_particleScratch1, *a_particles[idx]);
2040 m_amr->copyData(m_fluidScratch1, m_particleScratch1);
2041 DataOps::incr(a_conductivity, m_fluidScratch1, 1.0 * std::abs(Z));
2046 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
2047 const RefCountedPtr<CdrSolver>& solver = solverIt();
2048 const RefCountedPtr<CdrSpecies>& species = solver->getSpecies();
2050 const int idx = solverIt.index();
2051 const int Z = species->getChargeNumber();
2053 if (Z != 0 && solver->isMobile()) {
2054 const EBAMRCellData& phi = solver->getPhi();
2055 const EBAMRCellData& mobility = m_cdrMobilities[idx];
2059 DataOps::incr(a_conductivity, m_fluidScratch1, 1.0 * std::abs(Z));
2065 m_amr->arithmeticAverage(a_conductivity, m_fluidRealm, m_plasmaPhase);
2066 m_amr->interpGhostPwl(a_conductivity, m_fluidRealm, m_plasmaPhase);
2069 m_amr->interpToCentroids(a_conductivity, m_fluidRealm, m_plasmaPhase);
2072template <
typename I,
typename C,
typename R,
typename F>
2076 CH_TIME(
"ItoKMCStepper::computeDensityGradients()");
2077 if (m_verbosity > 5) {
2078 pout() << m_name +
"::computeDensityGradients()" << endl;
2082 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
2083 const RefCountedPtr<ItoSolver>& solver = it();
2085 const int idx = it.index();
2088 m_amr->copyData(m_fluidPhiIto[idx], solver->getPhi());
2090 m_amr->arithmeticAverage(m_fluidPhiIto[idx], m_fluidRealm, m_plasmaPhase);
2091 m_amr->interpGhostPwl(m_fluidPhiIto[idx], m_fluidRealm, m_plasmaPhase);
2093 m_amr->computeGradient(m_fluidGradPhiIto[idx], m_fluidPhiIto[idx], m_fluidRealm, m_plasmaPhase);
2097 for (
auto it = m_cdr->iterator(); it.ok(); ++it) {
2098 const RefCountedPtr<CdrSolver>& solver = it();
2100 const int idx = it.index();
2103 m_amr->copyData(m_fluidScratch1, solver->getPhi());
2105 m_amr->arithmeticAverage(m_fluidScratch1, m_fluidRealm, m_plasmaPhase);
2106 m_amr->interpGhostPwl(m_fluidScratch1, m_fluidRealm, m_plasmaPhase);
2108 m_amr->computeGradient(m_fluidGradPhiCDR[idx], m_fluidScratch1, m_fluidRealm, m_plasmaPhase);
2112template <
typename I,
typename C,
typename R,
typename F>
2116 CH_TIME(
"ItoKMCStepper::computeCurrentDensity(EBAMRCellData)");
2117 if (m_verbosity > 5) {
2118 pout() << m_name +
"::computeCurrentDensity(EBAMRCellData)" << endl;
2121 CH_assert(a_J[0]->nComp() == SpaceDim);
2123 EBAMRCellData conductivity;
2124 m_amr->allocate(conductivity, m_fluidRealm, m_plasmaPhase, 1);
2125 this->computeConductivityCell(conductivity);
2131template <
typename I,
typename C,
typename R,
typename F>
2135 CH_TIME(
"ItoKMCStepper::computeRelaxationTime()");
2136 if (m_verbosity > 5) {
2137 pout() << m_name +
"::computeRelaxationTime()" << endl;
2142 EBAMRCellData conductivity;
2143 EBAMRCellData relaxTime;
2145 m_amr->allocate(conductivity, m_fluidRealm, m_plasmaPhase, 1);
2146 m_amr->allocate(relaxTime, m_fluidRealm, m_plasmaPhase, 1);
2148 this->computeConductivityCell(conductivity);
2153 std::numeric_limits<Real>::max(),
2154 m_amr->getMultiCutVofIterator(m_fluidRealm, m_plasmaPhase));
2156 m_amr->conservativeAverage(relaxTime, m_fluidRealm, m_plasmaPhase);
2158 Real min = std::numeric_limits<Real>::max();
2159 Real max = -std::numeric_limits<Real>::max();
2166template <
typename I,
typename C,
typename R,
typename F>
2170 CH_TIME(
"ItoKMCStepper::solvePoisson()");
2171 if (m_verbosity > 5) {
2172 pout() << m_name +
"::solvePoisson()" << endl;
2176 MFAMRCellData& phi = m_fieldSolver->getPotential();
2177 MFAMRCellData& rho = m_fieldSolver->getRho();
2178 EBAMRIVData& sigma = m_sigmaSolver->getPhi();
2180 const bool converged = m_fieldSolver->solve(phi, rho, sigma,
false);
2182 m_fieldSolver->computeElectricField();
2187 m_amr->allocatePointer(E, m_fluidRealm);
2188 m_amr->alias(E, m_plasmaPhase, m_fieldSolver->getElectricField());
2191 m_amr->copyData(m_electricFieldFluid, E);
2192 m_amr->conservativeAverage(m_electricFieldFluid, m_fluidRealm, m_plasmaPhase);
2193 m_amr->interpGhostPwl(m_electricFieldFluid, m_fluidRealm, m_plasmaPhase);
2194 m_amr->interpToCentroids(m_electricFieldFluid, m_fluidRealm, m_plasmaPhase);
2197 m_amr->copyData(m_electricFieldParticle, E);
2198 m_amr->conservativeAverage(m_electricFieldParticle, m_particleRealm, m_plasmaPhase);
2199 m_amr->interpGhostPwl(m_electricFieldParticle, m_particleRealm, m_plasmaPhase);
2200 m_amr->interpToCentroids(m_electricFieldParticle, m_particleRealm, m_plasmaPhase);
2205template <
typename I,
typename C,
typename R,
typename F>
2209 const bool a_delete,
2212 CH_TIME(
"ItoKMCStepper::intersectParticles(SpeciesSubset, bool, std::function)");
2213 if (m_verbosity > 5) {
2214 pout() << m_name +
"::intersectParticles(SpeciesSubset, bool, std::function)" << endl;
2217 this->intersectParticles(a_speciesSubset,
2218 ItoSolver::WhichContainer::Bulk,
2219 ItoSolver::WhichContainer::EB,
2220 ItoSolver::WhichContainer::Domain,
2222 a_nonDeletionModifier);
2225template <
typename I,
typename C,
typename R,
typename F>
2232 const bool a_delete,
2235 CH_TIME(
"ItoKMCStepper::intersectParticles(SpeciesSubset, Containerx3, bool, std::function)");
2236 if (m_verbosity > 5) {
2237 pout() << m_name +
"::intersectParticles(SpeciesSubset, Containerx3, bool, std::function)" << endl;
2240 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
2241 RefCountedPtr<ItoSolver>& solver = solverIt();
2242 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
2244 const bool mobile = solver->isMobile();
2245 const bool diffusive = solver->isDiffusive();
2246 const bool charged = (species->getChargeNumber() != 0);
2248 const EBIntersection intersectionAlgorithm = solver->getIntersectionAlgorithm();
2250 switch (a_speciesSubset) {
2251 case SpeciesSubset::All: {
2252 solver->intersectParticles(a_containerBulk,
2255 intersectionAlgorithm,
2257 a_nonDeletionModifier);
2261 case SpeciesSubset::AllMobile: {
2263 solver->intersectParticles(a_containerBulk,
2266 intersectionAlgorithm,
2268 a_nonDeletionModifier);
2273 case SpeciesSubset::AllDiffusive: {
2275 solver->intersectParticles(a_containerBulk,
2278 intersectionAlgorithm,
2280 a_nonDeletionModifier);
2285 case SpeciesSubset::AllMobileOrDiffusive: {
2286 if (mobile || diffusive) {
2287 solver->intersectParticles(a_containerBulk,
2290 intersectionAlgorithm,
2292 a_nonDeletionModifier);
2297 case SpeciesSubset::AllMobileAndDiffusive: {
2298 if (mobile && diffusive) {
2299 solver->intersectParticles(a_containerBulk,
2302 intersectionAlgorithm,
2304 a_nonDeletionModifier);
2309 case SpeciesSubset::Charged: {
2311 solver->intersectParticles(a_containerBulk,
2314 intersectionAlgorithm,
2316 a_nonDeletionModifier);
2321 case SpeciesSubset::ChargedMobile: {
2322 if (charged && mobile) {
2323 solver->intersectParticles(a_containerBulk,
2326 intersectionAlgorithm,
2328 a_nonDeletionModifier);
2333 case SpeciesSubset::ChargedDiffusive: {
2334 if (charged && diffusive) {
2335 solver->intersectParticles(a_containerBulk,
2338 intersectionAlgorithm,
2340 a_nonDeletionModifier);
2345 case SpeciesSubset::ChargedMobileOrDiffusive: {
2346 if (charged && (mobile || diffusive)) {
2347 solver->intersectParticles(a_containerBulk,
2350 intersectionAlgorithm,
2352 a_nonDeletionModifier);
2357 case SpeciesSubset::ChargedMobileAndDiffusive: {
2358 if (charged && (mobile && diffusive)) {
2359 solver->intersectParticles(a_containerBulk,
2362 intersectionAlgorithm,
2364 a_nonDeletionModifier);
2369 case SpeciesSubset::Stationary: {
2370 if (!mobile && !diffusive) {
2371 solver->intersectParticles(a_containerBulk,
2374 intersectionAlgorithm,
2376 a_nonDeletionModifier);
2382 MayDay::Abort(
"ItoKMCStepper::intersectParticles - logic bust");
2390template <
typename I,
typename C,
typename R,
typename F>
2394 const Real a_tolerance)
noexcept
2396 CH_TIME(
"ItoKMCStepper::removeCoveredParticles(SpeciesSubset, EBRepresentation, Real)");
2397 if (m_verbosity > 5) {
2398 pout() << m_name +
"::removeCoveredParticles(SpeciesSubset, EBRepresentation, Real)" << endl;
2401 this->removeCoveredParticles(a_speciesSubset, ItoSolver::WhichContainer::Bulk, a_representation, a_tolerance);
2404template <
typename I,
typename C,
typename R,
typename F>
2409 const Real a_tolerance)
noexcept
2411 CH_TIME(
"ItoKMCStepper::removeCoveredParticles(SpeciesSubset, container, EBRepresentation, tolerance)");
2412 if (m_verbosity > 5) {
2413 pout() << m_name +
"::removeCoveredParticles(SpeciesSubset, container, EBRepresentation, tolerance)" << endl;
2416 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
2417 RefCountedPtr<ItoSolver>& solver = solverIt();
2418 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
2420 const bool mobile = solver->isMobile();
2421 const bool diffusive = solver->isDiffusive();
2422 const bool charged = (species->getChargeNumber() != 0);
2425 case SpeciesSubset::All: {
2426 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2430 case SpeciesSubset::AllMobile: {
2432 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2437 case SpeciesSubset::AllDiffusive: {
2439 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2444 case SpeciesSubset::AllMobileOrDiffusive: {
2445 if (mobile || diffusive) {
2446 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2451 case SpeciesSubset::AllMobileAndDiffusive: {
2452 if (mobile && diffusive) {
2453 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2458 case SpeciesSubset::Charged: {
2460 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2465 case SpeciesSubset::ChargedMobile: {
2466 if (charged && mobile) {
2467 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2472 case SpeciesSubset::ChargedDiffusive: {
2473 if (charged && diffusive) {
2474 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2479 case SpeciesSubset::ChargedMobileOrDiffusive: {
2480 if (charged && (mobile || diffusive)) {
2481 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2486 case SpeciesSubset::ChargedMobileAndDiffusive: {
2487 if (charged && (mobile && diffusive)) {
2488 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2493 case SpeciesSubset::Stationary: {
2494 if (!mobile && !diffusive) {
2495 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2501 MayDay::Abort(
"ItoKMCStepper::removeCoveredParticles - logic bust");
2509template <
typename I,
typename C,
typename R,
typename F>
2513 const Real a_tolerance)
noexcept
2515 CH_TIME(
"ItoKMCStepper::transferCoveredParticles(SpeciesSubset, EBRepresentation, Real)");
2516 if (m_verbosity > 5) {
2517 pout() << m_name +
"::transferCoveredParticles(SpeciesSubset, EBRepresentation, Real)" << endl;
2520 this->transferCoveredParticles(a_speciesSubset,
2521 ItoSolver::WhichContainer::Bulk,
2522 ItoSolver::WhichContainer::Covered,
2527template <
typename I,
typename C,
typename R,
typename F>
2533 const Real a_tolerance)
noexcept
2535 CH_TIME(
"ItoKMCStepper::transferCoveredParticles(SpeciesSubset, Containerx2, EBRepresentation, Real)");
2536 if (m_verbosity > 5) {
2537 pout() << m_name +
"::transferCoveredParticles(SpeciesSubset, Containerx2, EBRepresentation, Real)" << endl;
2540 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
2541 RefCountedPtr<ItoSolver>& solver = solverIt();
2542 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
2544 const bool mobile = solver->isMobile();
2545 const bool diffusive = solver->isDiffusive();
2546 const bool charged = (species->getChargeNumber() != 0);
2548 switch (a_speciesSubset) {
2549 case SpeciesSubset::All: {
2550 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2554 case SpeciesSubset::AllMobile: {
2556 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2561 case SpeciesSubset::AllDiffusive: {
2563 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2568 case SpeciesSubset::AllMobileOrDiffusive: {
2569 if (mobile || diffusive) {
2570 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2575 case SpeciesSubset::AllMobileAndDiffusive: {
2576 if (mobile && diffusive) {
2577 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2582 case SpeciesSubset::Charged: {
2584 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2589 case SpeciesSubset::ChargedMobile: {
2590 if (charged && mobile) {
2591 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2596 case SpeciesSubset::ChargedDiffusive: {
2597 if (charged && diffusive) {
2598 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2603 case SpeciesSubset::ChargedMobileOrDiffusive: {
2604 if (charged && (mobile || diffusive)) {
2605 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2610 case SpeciesSubset::ChargedMobileAndDiffusive: {
2611 if (charged && (mobile && diffusive)) {
2612 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2617 case SpeciesSubset::Stationary: {
2618 if (!mobile && !diffusive) {
2619 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2625 MayDay::Abort(
"ItoKMCStepper::transferCoveredParticles - logic bust");
2633template <
typename I,
typename C,
typename R,
typename F>
2637 CH_TIME(
"ItoKMCStepper::remapParticles(SpeciesSubset)");
2638 if (m_verbosity > 5) {
2639 pout() << m_name +
"::remapParticles(SpeciesSubset)" << endl;
2642 this->remapParticles(a_speciesSubset, ItoSolver::WhichContainer::Bulk);
2645template <
typename I,
typename C,
typename R,
typename F>
2650 CH_TIME(
"ItoKMCStepper::remapParticles(SpeciesSubset, WhichContainer)");
2651 if (m_verbosity > 5) {
2652 pout() << m_name +
"::remapParticles(SpeciesSubset, WhichContainer)" << endl;
2655 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
2656 RefCountedPtr<ItoSolver>& solver = solverIt();
2657 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
2659 const bool mobile = solver->isMobile();
2660 const bool diffusive = solver->isDiffusive();
2661 const bool charged = (species->getChargeNumber() != 0);
2663 switch (a_speciesSubset) {
2664 case SpeciesSubset::All: {
2665 solver->remap(a_container);
2669 case SpeciesSubset::AllMobile: {
2671 solver->remap(a_container);
2676 case SpeciesSubset::AllDiffusive: {
2678 solver->remap(a_container);
2683 case SpeciesSubset::AllMobileOrDiffusive: {
2684 if (mobile || diffusive) {
2685 solver->remap(a_container);
2690 case SpeciesSubset::AllMobileAndDiffusive: {
2691 if (mobile && diffusive) {
2692 solver->remap(a_container);
2697 case SpeciesSubset::Charged: {
2699 solver->remap(a_container);
2704 case SpeciesSubset::ChargedMobile: {
2705 if (charged && mobile) {
2706 solver->remap(a_container);
2711 case SpeciesSubset::ChargedDiffusive: {
2712 if (charged && diffusive) {
2713 solver->remap(a_container);
2718 case SpeciesSubset::ChargedMobileOrDiffusive: {
2719 if (charged && (mobile || diffusive)) {
2720 solver->remap(a_container);
2725 case SpeciesSubset::ChargedMobileAndDiffusive: {
2726 if (charged && (mobile && diffusive)) {
2727 solver->remap(a_container);
2732 case SpeciesSubset::Stationary: {
2733 if (!mobile && !diffusive) {
2734 solver->remap(a_container);
2740 MayDay::Abort(
"ItoKMCStepper::remapParticles - logic bust");
2748template <
typename I,
typename C,
typename R,
typename F>
2752 CH_TIME(
"ItoKMCStepper::depositParticles(SpeciesSubset)");
2753 if (m_verbosity > 5) {
2754 pout() << m_name +
"::depositParticles(SpeciesSubset)" << endl;
2757 this->depositParticles(a_speciesSubset, ItoSolver::WhichContainer::Bulk);
2760template <
typename I,
typename C,
typename R,
typename F>
2765 CH_TIME(
"ItoKMCStepper::depositParticles(SpeciesSubset)");
2766 if (m_verbosity > 5) {
2767 pout() << m_name +
"::depositParticles(SpeciesSubset)" << endl;
2770 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
2771 RefCountedPtr<ItoSolver>& solver = solverIt();
2772 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
2774 const bool mobile = solver->isMobile();
2775 const bool diffusive = solver->isDiffusive();
2776 const bool charged = (species->getChargeNumber() != 0);
2778 switch (a_speciesSubset) {
2779 case SpeciesSubset::All: {
2780 solver->depositParticles(a_container);
2784 case SpeciesSubset::AllMobile: {
2786 solver->depositParticles(a_container);
2791 case SpeciesSubset::AllDiffusive: {
2793 solver->depositParticles(a_container);
2798 case SpeciesSubset::AllMobileOrDiffusive: {
2799 if (mobile || diffusive) {
2800 solver->depositParticles(a_container);
2805 case SpeciesSubset::AllMobileAndDiffusive: {
2806 if (mobile && diffusive) {
2807 solver->depositParticles(a_container);
2812 case SpeciesSubset::Charged: {
2814 solver->depositParticles(a_container);
2819 case SpeciesSubset::ChargedMobile: {
2820 if (charged && mobile) {
2821 solver->depositParticles(a_container);
2826 case SpeciesSubset::ChargedDiffusive: {
2827 if (charged && diffusive) {
2828 solver->depositParticles(a_container);
2833 case SpeciesSubset::ChargedMobileOrDiffusive: {
2834 if (charged && (mobile || diffusive)) {
2835 solver->depositParticles(a_container);
2840 case SpeciesSubset::ChargedMobileAndDiffusive: {
2841 if (charged && (mobile && diffusive)) {
2842 solver->depositParticles(a_container);
2847 case SpeciesSubset::Stationary: {
2848 if (!mobile && !diffusive) {
2849 solver->depositParticles(a_container);
2855 MayDay::Abort(
"ItoKMCStepper::depositParticles - logic bust");
2863template <
typename I,
typename C,
typename R,
typename F>
2867 CH_TIME(
"ItoKMCStepper::setItoVelocityFunctions");
2868 if (m_verbosity > 5) {
2869 pout() << m_name +
"::setItoVelocityFunctions" << endl;
2872 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
2873 RefCountedPtr<ItoSolver>& solver = solverIt();
2874 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
2875 const int Z = species->getChargeNumber();
2877 if (solver->isMobile() && Z != 0) {
2878 EBAMRCellData& velocityFunction = solver->getVelocityFunction();
2879 m_amr->copyData(velocityFunction, m_electricFieldParticle);
2881 const int Z = species->getChargeNumber();
2888 m_amr->conservativeAverage(velocityFunction, m_particleRealm, m_plasmaPhase);
2889 m_amr->interpGhostPwl(velocityFunction, m_particleRealm, m_plasmaPhase);
2894template <
typename I,
typename C,
typename R,
typename F>
2898 CH_TIME(
"ItoKMCStepper::setCdrVelocityFunctions");
2899 if (m_verbosity > 5) {
2900 pout() << m_name +
"::setCdrVelocityFunctions" << endl;
2903 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
2904 RefCountedPtr<CdrSolver>& solver = solverIt();
2905 const RefCountedPtr<CdrSpecies>& species = solver->getSpecies();
2906 const int Z = species->getChargeNumber();
2908 if (solver->isMobile() && Z != 0) {
2909 EBAMRCellData& velocity = solver->getCellCenteredVelocity();
2910 m_amr->copyData(velocity, m_electricFieldFluid);
2912 const int Z = species->getChargeNumber();
2919 m_amr->conservativeAverage(velocity, m_fluidRealm, m_plasmaPhase);
2920 m_amr->interpGhostPwl(velocity, m_fluidRealm, m_plasmaPhase);
2922 else if (solver->isMobile() && Z == 0) {
2923 MayDay::Warning(
"ItoKMCStepper::setCdrVelocityFunctions -- how to handle mobile neutral species?");
2928template <
typename I,
typename C,
typename R,
typename F>
2932 CH_TIME(
"ItoKMCStepper::multiplyCdrVelocitiesByMobilities()");
2933 if (m_verbosity > 5) {
2934 pout() << m_name +
"::multiplyCdrVelocitiesByMobilities()" << endl;
2937 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
2938 RefCountedPtr<CdrSolver>& solver = solverIt();
2939 const int idx = solverIt.index();
2941 if (solver->isMobile()) {
2942 EBAMRCellData& velocity = solver->getCellCenteredVelocity();
2943 const EBAMRCellData& mobility = m_cdrMobilities[idx];
2948 m_amr->conservativeAverage(velocity, m_fluidRealm, m_plasmaPhase);
2949 m_amr->interpGhostPwl(velocity, m_fluidRealm, m_plasmaPhase);
2954template <
typename I,
typename C,
typename R,
typename F>
2958 CH_TIME(
"ItoKMCStepper::computeDriftVelocities()");
2959 if (m_verbosity > 5) {
2960 pout() << m_name +
"::computeDriftVelocities()" << endl;
2964 this->setItoVelocityFunctions();
2965 this->setCdrVelocityFunctions();
2968 this->computeMobilities();
2972 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
2973 solverIt()->interpolateVelocities();
2976 this->multiplyCdrVelocitiesByMobilities();
2979template <
typename I,
typename C,
typename R,
typename F>
2983 CH_TIME(
"ItoKMCStepper::computeMobilities()");
2984 if (m_verbosity > 5) {
2985 pout() << m_name +
"::computeMobilities()" << endl;
2988 Vector<EBAMRCellData*> itoMobilities = m_ito->getMobilityFunctions();
2990 this->computeMobilities(itoMobilities, m_cdrMobilities, m_electricFieldFluid, m_time);
2993template <
typename I,
typename C,
typename R,
typename F>
2996 Vector<EBAMRCellData>& a_cdrMobilities,
2997 const EBAMRCellData& a_electricField,
2998 const Real a_time)
noexcept
3000 CH_TIME(
"ItoKMCStepper::computeMobilities(mobilities, E, time)");
3001 if (m_verbosity > 5) {
3002 pout() << m_name +
"::computeMobilities(mobilities, E, time)" << endl;
3005 const int numItoSpecies = m_physics->getNumItoSpecies();
3006 const int numCdrSpecies = m_physics->getNumCdrSpecies();
3008 CH_assert(a_electricField.getRealm() == m_fluidRealm);
3009 CH_assert(a_itoMobilities.size() == numItoSpecies);
3010 CH_assert(a_cdrMobilities.size() == numCdrSpecies);
3014 Vector<EBAMRCellData> fluidScratchMobilities(numItoSpecies);
3015 for (
int i = 0; i < numItoSpecies; i++) {
3016 m_amr->allocate(fluidScratchMobilities[i], m_fluidRealm, m_plasmaPhase, 1);
3021 CH_assert(a_itoMobilities[i]->getRealm() == m_particleRealm);
3025 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
3026 Vector<LevelData<EBCellFAB>*> itoMobilities(numItoSpecies);
3027 Vector<LevelData<EBCellFAB>*> cdrMobilities(numCdrSpecies);
3029 for (
int i = 0; i < numItoSpecies; i++) {
3030 itoMobilities[i] = &(*(fluidScratchMobilities[i])[lvl]);
3033 for (
int i = 0; i < numCdrSpecies; i++) {
3034 cdrMobilities[i] = &(*(a_cdrMobilities[i])[lvl]);
3038 this->computeMobilities(itoMobilities, cdrMobilities, *a_electricField[lvl], lvl, a_time);
3042 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
3043 RefCountedPtr<ItoSolver>& solver = solverIt();
3045 if (solver->isMobile()) {
3046 const int idx = solverIt.index();
3048 m_amr->copyData(*a_itoMobilities[idx], fluidScratchMobilities[idx]);
3049 m_amr->conservativeAverage(*a_itoMobilities[idx], m_particleRealm, m_plasmaPhase);
3050 m_amr->interpGhostPwl(*a_itoMobilities[idx], m_particleRealm, m_plasmaPhase);
3052 solver->interpolateMobilities();
3057template <
typename I,
typename C,
typename R,
typename F>
3060 Vector<LevelData<EBCellFAB>*>& a_cdrMobilities,
3061 const LevelData<EBCellFAB>& a_electricField,
3063 const Real a_time)
noexcept
3065 CH_TIME(
"ItoKMCStepper::computeMobilities(mobilities, E, level, time)");
3066 if (m_verbosity > 5) {
3067 pout() << m_name +
"::computeMobilities(mobilities, E, level, time)" << endl;
3070 const DisjointBoxLayout& dbl = m_amr->getGrids(m_fluidRealm)[a_level];
3071 const DataIterator& dit = dbl.dataIterator();
3073 const int nbox = dit.size();
3075#pragma omp parallel for schedule(runtime)
3076 for (
int mybox = 0; mybox < nbox; mybox++) {
3077 const DataIndex& din = dit[mybox];
3079 const EBCellFAB& E = a_electricField[din];
3080 const Box cellBox = dbl[din];
3082 Vector<EBCellFAB*> itoMobilities;
3083 Vector<EBCellFAB*> cdrMobilities;
3085 for (
int i = 0; i < a_itoMobilities.size(); i++) {
3086 itoMobilities.push_back(&((*a_itoMobilities[i])[din]));
3089 for (
int i = 0; i < a_cdrMobilities.size(); i++) {
3090 cdrMobilities.push_back(&((*a_cdrMobilities[i])[din]));
3093 this->computeMobilities(itoMobilities, cdrMobilities, E, a_level, din, cellBox, a_time);
3097template <
typename I,
typename C,
typename R,
typename F>
3100 Vector<EBCellFAB*>& a_cdrMobilities,
3101 const EBCellFAB& a_electricField,
3103 const DataIndex a_din,
3105 const Real a_time)
noexcept
3107 CH_TIME(
"ItoKMCStepper::computeMobilities(meshMobilities, E, level, dit, box, time)");
3108 if (m_verbosity > 5) {
3109 pout() << m_name +
"::computeMobilities(meshMobilities, E, level, dit, box, time)" << endl;
3114 const int numItoSpecies = m_physics->getNumItoSpecies();
3115 const int numCdrSpecies = m_physics->getNumCdrSpecies();
3116 const int numPlasmaSpecies = m_physics->getNumPlasmaSpecies();
3118 const Real dx = m_amr->getDx()[a_level];
3119 const RealVect probLo = m_amr->getProbLo();
3120 const EBISBox& ebisbox = m_amr->getEBISLayout(m_fluidRealm, m_plasmaPhase)[a_level][a_din];
3123 const FArrayBox& electricFieldReg = a_electricField.getFArrayBox();
3124 Vector<FArrayBox*> itoMobilitiesReg(numItoSpecies);
3125 Vector<FArrayBox*> cdrMobilitiesReg(numCdrSpecies);
3127 for (
int i = 0; i < a_itoMobilities.size(); i++) {
3128 itoMobilitiesReg[i] = (&(a_itoMobilities[i]->getFArrayBox()));
3131 for (
int i = 0; i < a_cdrMobilities.size(); i++) {
3132 cdrMobilitiesReg[i] = (&(a_cdrMobilities[i]->getFArrayBox()));
3136 const std::map<int, std::pair<SpeciesType, int>>& speciesMap = m_physics->getSpeciesMap();
3139 auto regularKernel = [&](
const IntVect& iv) ->
void {
3140 const RealVect pos = m_amr->getProbLo() + dx * (RealVect(iv) + 0.5 * RealVect::Unit);
3141 const RealVect E = RealVect(D_DECL(electricFieldReg(iv, 0), electricFieldReg(iv, 1), electricFieldReg(iv, 2)));
3144 const Vector<Real> mobilities = m_physics->computeMobilities(a_time, pos, E);
3146 CH_assert(mobilities.size() == numPlasmaSpecies);
3149 for (
const auto& s : speciesMap) {
3150 const int& globalIndex = s.first;
3152 const int& localIndex = s.second.second;
3154 if (type == SpeciesType::Ito) {
3155 (*itoMobilitiesReg[localIndex])(iv, 0) = mobilities[globalIndex];
3157 else if (type == SpeciesType::CDR) {
3158 (*cdrMobilitiesReg[localIndex])(iv, 0) = mobilities[globalIndex];
3164 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
3165 const RealVect e = RealVect(D_DECL(a_electricField(vof, 0), a_electricField(vof, 1), a_electricField(vof, 2)));
3166 const RealVect pos = probLo +
Location::position(Location::Cell::Centroid, vof, ebisbox, dx);
3169 const Vector<Real> mobilities = m_physics->computeMobilities(a_time, pos, e);
3171 CH_assert(mobilities.size() == numPlasmaSpecies);
3174 for (
const auto& s : speciesMap) {
3175 const int& globalIndex = s.first;
3177 const int& localIndex = s.second.second;
3179 if (type == SpeciesType::Ito) {
3180 (*a_itoMobilities[localIndex])(vof, 0) = mobilities[globalIndex];
3182 else if (type == SpeciesType::CDR) {
3183 (*a_cdrMobilities[localIndex])(vof, 0) = mobilities[globalIndex];
3188 VoFIterator& vofit = (*m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase)[a_level])[a_din];
3192 BoxLoops::loop<D_DECL(1, 1, 1)>(a_box, regularKernel);
3196 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
3197 a_itoMobilities[solverIt.index()]->setCoveredCellVal(0.0, 0);
3200 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
3201 a_cdrMobilities[solverIt.index()]->setCoveredCellVal(0.0, 0);
3205template <
typename I,
typename C,
typename R,
typename F>
3209 CH_TIME(
"ItoKMCStepper::computeDiffusionCoefficients()");
3210 if (m_verbosity > 5) {
3211 pout() << m_name +
"::computeDiffusionCoefficients()" << endl;
3214 Vector<EBAMRCellData*> itoDiffusionCoefficients = m_ito->getDiffusionFunctions();
3215 Vector<EBAMRCellData*> cdrDiffusionCoefficients = m_cdr->getCellCenteredDiffusionCoefficients();
3217 this->computeDiffusionCoefficients(itoDiffusionCoefficients, cdrDiffusionCoefficients, m_electricFieldFluid, m_time);
3218 this->averageDiffusionCoefficientsCellToFace();
3221template <
typename I,
typename C,
typename R,
typename F>
3224 Vector<EBAMRCellData*>& a_cdrDiffusionCoefficients,
3225 const EBAMRCellData& a_electricField,
3226 const Real a_time)
noexcept
3228 CH_TIME(
"ItoKMCStepper::computeDiffusionCoefficients(Vector<EBAMRCellData*>, EBAMRCellData, Real)");
3229 if (m_verbosity > 5) {
3230 pout() << m_name +
"::computeDiffusionCoefficients(Vector<EBAMRCellData*>, EBAMRCellData, Real)" << endl;
3233 const int numItoSpecies = m_physics->getNumItoSpecies();
3234 const int numCdrSpecies = m_physics->getNumCdrSpecies();
3236 CH_assert(a_electricField.getRealm() == m_fluidRealm);
3237 CH_assert(a_itoDiffusionCoefficients.size() == numItoSpecies);
3238 CH_assert(a_cdrDiffusionCoefficients.size() == numCdrSpecies);
3241 for (
int i = 0; i < numItoSpecies; i++) {
3242 CH_assert(a_itoDiffusionCoefficients[i]->getRealm() == m_particleRealm);
3244 for (
int i = 0; i < numCdrSpecies; i++) {
3245 CH_assert(a_cdrDiffusionCoefficients[i]->getRealm() == m_fluidRealm);
3250 Vector<EBAMRCellData> fluidScratchDiffusion(numItoSpecies);
3251 for (
int i = 0; i < numItoSpecies; i++) {
3252 m_amr->allocate(fluidScratchDiffusion[i], m_fluidRealm, m_plasmaPhase, 1);
3254 CH_assert(a_itoDiffusionCoefficients[i]->getRealm() == m_particleRealm);
3258 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
3259 Vector<LevelData<EBCellFAB>*> itoDiffusionCoefficients(numItoSpecies);
3260 Vector<LevelData<EBCellFAB>*> cdrDiffusionCoefficients(numCdrSpecies);
3262 for (
int i = 0; i < numItoSpecies; i++) {
3263 itoDiffusionCoefficients[i] = &(*(fluidScratchDiffusion[i])[lvl]);
3265 for (
int i = 0; i < numCdrSpecies; i++) {
3266 cdrDiffusionCoefficients[i] = &(*(*a_cdrDiffusionCoefficients[i])[lvl]);
3269 this->computeDiffusionCoefficients(itoDiffusionCoefficients,
3270 cdrDiffusionCoefficients,
3271 *a_electricField[lvl],
3278 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
3279 RefCountedPtr<ItoSolver>& solver = solverIt();
3281 if (solver->isDiffusive()) {
3282 const int idx = solverIt.index();
3284 m_amr->copyData(*a_itoDiffusionCoefficients[idx], fluidScratchDiffusion[idx]);
3285 m_amr->conservativeAverage(*a_itoDiffusionCoefficients[idx], m_particleRealm, m_plasmaPhase);
3286 m_amr->interpGhostPwl(*a_itoDiffusionCoefficients[idx], m_particleRealm, m_plasmaPhase);
3288 solver->interpolateDiffusion();
3293template <
typename I,
typename C,
typename R,
typename F>
3296 Vector<LevelData<EBCellFAB>*>& a_cdrDiffusionCoefficients,
3297 const LevelData<EBCellFAB>& a_electricField,
3299 const Real a_time)
noexcept
3301 CH_TIME(
"ItoKMCStepper::computeDiffusionCoefficients(Vector<LD<EBCellFAB>*>, LD<EBCellFAB>, int, Real)");
3302 if (m_verbosity > 5) {
3303 pout() << m_name +
"::computeDiffusionCoefficients(Vector<LD<EBCellFAB>*>, LD<EBCellFAB>, int, Real)" << endl;
3306 const int numItoSpecies = m_physics->getNumItoSpecies();
3307 const int numCdrSpecies = m_physics->getNumCdrSpecies();
3309 CH_assert(a_itoDiffusionCoefficients.size() == numItoSpecies);
3310 CH_assert(a_cdrDiffusionCoefficients.size() == numCdrSpecies);
3312 const DisjointBoxLayout& dbl = m_amr->getGrids(m_fluidRealm)[a_level];
3313 const DataIterator& dit = dbl.dataIterator();
3315 const int nbox = dit.size();
3317#pragma omp parallel for schedule(runtime)
3318 for (
int mybox = 0; mybox < nbox; mybox++) {
3319 const DataIndex& din = dit[mybox];
3321 Vector<EBCellFAB*> itoDiffusionCoefficients(numItoSpecies);
3322 Vector<EBCellFAB*> cdrDiffusionCoefficients(numCdrSpecies);
3324 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
3325 const int idx = solverIt.index();
3327 if (solverIt()->isDiffusive()) {
3328 itoDiffusionCoefficients[idx] = &(*a_itoDiffusionCoefficients[idx])[din];
3331 itoDiffusionCoefficients[idx] =
nullptr;
3335 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
3336 const int idx = solverIt.index();
3338 if (solverIt()->isDiffusive()) {
3339 cdrDiffusionCoefficients[idx] = &(*a_cdrDiffusionCoefficients[idx])[din];
3342 cdrDiffusionCoefficients[idx] =
nullptr;
3346 this->computeDiffusionCoefficients(itoDiffusionCoefficients,
3347 cdrDiffusionCoefficients,
3348 a_electricField[din],
3356template <
typename I,
typename C,
typename R,
typename F>
3359 Vector<EBCellFAB*>& a_cdrDiffusionCoefficients,
3360 const EBCellFAB& a_electricField,
3362 const DataIndex a_din,
3364 const Real a_time)
noexcept
3366 CH_TIME(
"ItoKMCStepper::computeDiffusionCoefficients(Patch)");
3367 if (m_verbosity > 5) {
3368 pout() << m_name +
"::computeDiffusionCoefficients(Patch)" << endl;
3371 const int numItoSpecies = m_physics->getNumItoSpecies();
3372 const int numCdrSpecies = m_physics->getNumCdrSpecies();
3373 const int numPlasmaSpecies = m_physics->getNumPlasmaSpecies();
3375 CH_assert(a_electricField.nComp() == SpaceDim);
3376 CH_assert(a_itoDiffusionCoefficients.size() == numItoSpecies);
3377 CH_assert(a_cdrDiffusionCoefficients.size() == numCdrSpecies);
3380 const Real dx = m_amr->getDx()[a_level];
3381 const RealVect probLo = m_amr->getProbLo();
3382 const EBISBox& ebisbox = m_amr->getEBISLayout(m_fluidRealm, m_plasmaPhase)[a_level][a_din];
3385 const FArrayBox& electricFieldReg = a_electricField.getFArrayBox();
3387 Vector<FArrayBox*> itoDiffCoReg(numItoSpecies,
nullptr);
3388 Vector<FArrayBox*> cdrDiffCoReg(numCdrSpecies,
nullptr);
3390 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
3391 RefCountedPtr<ItoSolver>& solver = solverIt();
3393 if (solver->isDiffusive()) {
3394 const int i = solverIt.index();
3395 itoDiffCoReg[i] = &(a_itoDiffusionCoefficients[i]->getFArrayBox());
3399 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
3400 RefCountedPtr<CdrSolver>& solver = solverIt();
3402 if (solver->isDiffusive()) {
3403 const int i = solverIt.index();
3404 cdrDiffCoReg[i] = &(a_cdrDiffusionCoefficients[i]->getFArrayBox());
3409 const std::map<int, std::pair<SpeciesType, int>>& speciesMap = m_physics->getSpeciesMap();
3412 auto regularKernel = [&](
const IntVect& iv) ->
void {
3413 const RealVect pos = probLo + dx * (RealVect(iv) + 0.5 * RealVect::Unit);
3414 const RealVect E = RealVect(D_DECL(electricFieldReg(iv, 0), electricFieldReg(iv, 1), electricFieldReg(iv, 2)));
3417 const Vector<Real> diffusionCoefficients = m_physics->computeDiffusionCoefficients(a_time, pos, E);
3419 CH_assert(diffusionCoefficients.size() == numPlasmaSpecies);
3422 for (
const auto& s : speciesMap) {
3423 const int& globalIndex = s.first;
3425 const int& localIndex = s.second.second;
3428 if (type == SpeciesType::Ito) {
3429 if (m_ito->getSolvers()[localIndex]->isDiffusive()) {
3430 (*itoDiffCoReg[localIndex])(iv, 0) = diffusionCoefficients[globalIndex];
3433 else if (type == SpeciesType::CDR) {
3434 if (m_cdr->getSolvers()[localIndex]->isDiffusive()) {
3435 (*cdrDiffCoReg[localIndex])(iv, 0) = diffusionCoefficients[globalIndex];
3442 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
3443 const RealVect E = RealVect(D_DECL(a_electricField(vof, 0), a_electricField(vof, 1), a_electricField(vof, 2)));
3444 const RealVect pos = probLo +
Location::position(Location::Cell::Centroid, vof, ebisbox, dx);
3447 const Vector<Real> diffusionCoefficients = m_physics->computeDiffusionCoefficients(a_time, pos, E);
3450 for (
const auto& s : speciesMap) {
3451 const int& globalIndex = s.first;
3453 const int& localIndex = s.second.second;
3456 if (type == SpeciesType::Ito) {
3457 if (m_ito->getSolvers()[localIndex]->isDiffusive()) {
3458 (*a_itoDiffusionCoefficients[localIndex])(vof, 0) = diffusionCoefficients[globalIndex];
3461 else if (type == SpeciesType::CDR) {
3462 if (m_cdr->getSolvers()[localIndex]->isDiffusive()) {
3463 (*a_cdrDiffusionCoefficients[localIndex])(vof, 0) = diffusionCoefficients[globalIndex];
3470 VoFIterator& vofit = (*m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase)[a_level])[a_din];
3472 BoxLoops::loop<D_DECL(1, 1, 1)>(a_box, regularKernel);
3476 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
3477 if (solverIt()->isDiffusive()) {
3478 a_itoDiffusionCoefficients[solverIt.index()]->setCoveredCellVal(0.0, 0);
3482 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
3483 if (solverIt()->isDiffusive()) {
3484 a_cdrDiffusionCoefficients[solverIt.index()]->setCoveredCellVal(0.0, 0);
3489template <
typename I,
typename C,
typename R,
typename F>
3493 CH_TIME(
"ItoKMCStepper::averageDiffusionCoefficientsCellToFace");
3494 if (m_verbosity > 5) {
3495 pout() << m_name +
"::averageDiffusionCoefficientsCellToFace" << endl;
3498 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
3499 RefCountedPtr<CdrSolver>& solver = solverIt();
3501 if (solver->isDiffusive()) {
3503 EBAMRCellData& cellCenteredDiffusionCoefficient = solver->getCellCenteredDiffusionCoefficient();
3504 EBAMRFluxData& faceCenteredDiffusionCoefficient = solver->getFaceCenteredDiffusionCoefficient();
3506 CH_assert(cellCenteredDiffusionCoefficient.getRealm() == m_fluidRealm);
3507 CH_assert(faceCenteredDiffusionCoefficient.getRealm() == m_fluidRealm);
3509 DataOps::setValue(faceCenteredDiffusionCoefficient, std::numeric_limits<Real>::max());
3512 m_amr->arithmeticAverage(cellCenteredDiffusionCoefficient, m_fluidRealm, m_cdr->getPhase());
3513 m_amr->interpGhostPwl(cellCenteredDiffusionCoefficient, m_fluidRealm, m_cdr->getPhase());
3517 const int tanGhost = 1;
3518 const Interval interv = Interval(0, 0);
3519 const Average average = Average::Arithmetic;
3522 cellCenteredDiffusionCoefficient,
3523 m_amr->getDomains(),
3528 m_amr->getFaceIteratorWithTangentialGhosts(m_fluidRealm, m_cdr->getPhase()));
3533template <
typename I,
typename C,
typename R,
typename F>
3537 CH_TIME(
"ItoKMCStepper::getPhysicalParticlesPerCell(EBAMRCellData)");
3538 if (m_verbosity > 5) {
3539 pout() << m_name +
"::getPhysicaParticlesPerCell(EBAMRCellData)" << endl;
3542 CH_assert(a_ppc.getRealm() == m_particleRealm);
3544 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
3545 const int idx = it.index();
3547 EBAMRCellData ppc = m_amr->slice(a_ppc, Interval(idx, idx));
3555template <
typename I,
typename C,
typename R,
typename F>
3559 CH_TIME(
"ItoKMCStepper::computeReactiveItoParticlesPerCell(EBAMRCellData)");
3560 if (m_verbosity > 5) {
3561 pout() << m_name +
"::computeReactiveItoParticlesPerCell(EBAMRCellData)" << endl;
3564 CH_assert(a_ppc.getRealm() == m_particleRealm);
3568 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
3569 this->computeReactiveItoParticlesPerCell(*a_ppc[lvl], lvl);
3573template <
typename I,
typename C,
typename R,
typename F>
3577 CH_TIME(
"ItoKMCStepper::computeReactiveItoParticlesPerCell(LD<EBCellFAB>, int)");
3578 if (m_verbosity > 5) {
3579 pout() << m_name +
"::computeReactiveItoParticlesPerCell(LD<EBCellFAB>, int)" << endl;
3582 const int numItoSpecies = m_physics->getNumItoSpecies();
3584 CH_assert(a_ppc.nComp() == numItoSpecies);
3586 const DisjointBoxLayout& dbl = m_amr->getGrids(m_particleRealm)[a_level];
3587 const EBISLayout& ebisl = m_amr->getEBISLayout(m_particleRealm, m_plasmaPhase)[a_level];
3588 const DataIterator& dit = dbl.dataIterator();
3590 const int nbox = dit.size();
3592#pragma omp parallel for schedule(runtime)
3593 for (
int mybox = 0; mybox < nbox; mybox++) {
3594 const DataIndex& din = dit[mybox];
3596 const Box box = dbl[din];
3597 const EBISBox& ebisbox = ebisl[din];
3599 this->computeReactiveItoParticlesPerCell(a_ppc[din], a_level, din, box, ebisbox);
3603template <
typename I,
typename C,
typename R,
typename F>
3607 const DataIndex a_din,
3609 const EBISBox& a_ebisbox)
noexcept
3611 CH_TIME(
"ItoKMCStepper::computeReactiveItoParticlesPerCell(EBCellFAB, int, DataIndex, Box, EBISBox)");
3612 if (m_verbosity > 5) {
3613 pout() << m_name +
"::computeReactiveItoParticlesPerCell(EBCellFAB, int, DataIndex, Box, EBISBox)" << endl;
3616 const int numItoSpecies = m_physics->getNumItoSpecies();
3618 CH_assert(a_ppc.nComp() == numItoSpecies);
3620 const Real dx = m_amr->getDx()[a_level];
3621 const RealVect probLo = m_amr->getProbLo();
3625 FArrayBox& ppcRegular = a_ppc.getFArrayBox();
3627 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
3628 RefCountedPtr<ItoSolver>& solver = solverIt();
3629 const int idx = solverIt.index();
3636 leaf.
sortByCell(a_box, dx * RealVect::Unit, probLo);
3639 auto regularKernel = [&](
const IntVect& iv) ->
void {
3642 if (a_ebisbox.isRegular(iv)) {
3643 const std::pair<std::size_t, std::size_t> range = leaf.
cellRange(a_box.index(iv));
3644 for (std::size_t i = range.first; i < range.second; i++) {
3649 ppcRegular(iv, idx) = num;
3653 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
3654 const IntVect iv = vof.gridIndex();
3655 const RealVect normal = a_ebisbox.normal(vof);
3656 const RealVect physCentroid = probLo +
Location::position(Location::Cell::Boundary, vof, a_ebisbox, dx);
3660 const std::pair<std::size_t, std::size_t> range = leaf.
cellRange(a_box.index(iv));
3661 for (std::size_t i = range.first; i < range.second; i++) {
3662 const RealVect pos = leaf.
position(i);
3663 if ((pos - physCentroid).dotProduct(normal) >= 0.0) {
3668 a_ppc(vof, idx) = num;
3672 VoFIterator& vofit = (*m_amr->getVofIterator(m_particleRealm, m_plasmaPhase)[a_level])[a_din];
3674 BoxLoops::loop<D_DECL(1, 1, 1)>(a_box, regularKernel);
3679template <
typename I,
typename C,
typename R,
typename F>
3683 CH_TIME(
"ItoKMCStepper::computeReactiveCdrParticlesPerCell(EBAMRCellData)");
3684 if (m_verbosity > 5) {
3685 pout() << m_name +
"::computeReactiveCdrParticlesPerCell(EBAMRCellData)" << endl;
3688 CH_assert(a_ppc.getRealm() == m_fluidRealm);
3692 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
3693 this->computeReactiveCdrParticlesPerCell(*a_ppc[lvl], lvl);
3697template <
typename I,
typename C,
typename R,
typename F>
3701 CH_TIME(
"ItoKMCStepper::computeReactiveCdrParticlesPerCell(LD<EBCellFAB>, int)");
3702 if (m_verbosity > 5) {
3703 pout() << m_name +
"::computeReactiveCdrParticlesPerCell(LD<EBCellFAB>, int)" << endl;
3706 const int numCdrSpecies = m_physics->getNumCdrSpecies();
3708 CH_assert(a_ppc.nComp() == numCdrSpecies);
3710 if (numCdrSpecies > 0) {
3711 const DisjointBoxLayout& dbl = m_amr->getGrids(m_fluidRealm)[a_level];
3712 const EBISLayout& ebisl = m_amr->getEBISLayout(m_fluidRealm, m_plasmaPhase)[a_level];
3713 const DataIterator& dit = dbl.dataIterator();
3715 const int nbox = dit.size();
3717#pragma omp parallel for schedule(runtime)
3718 for (
int mybox = 0; mybox < nbox; mybox++) {
3719 const DataIndex& din = dit[mybox];
3721 const Box box = dbl[din];
3722 const EBISBox& ebisbox = ebisl[din];
3724 this->computeReactiveCdrParticlesPerCell(a_ppc[din], a_level, din, box, ebisbox);
3729template <
typename I,
typename C,
typename R,
typename F>
3733 const DataIndex a_din,
3735 const EBISBox& a_ebisbox)
noexcept
3737 CH_TIME(
"ItoKMCStepper::computeReactiveCdrParticlesPerCell(EBCellFAB, int, DataIndex, Box, EBISBox)");
3738 if (m_verbosity > 5) {
3739 pout() << m_name +
"::computeReactiveCdrParticlesPerCell(EBCellFAB, int, DataIndex, Box, EBISBox)" << endl;
3742 constexpr Real zero = 0.0;
3744 const int numCdrSpecies = m_physics->getNumCdrSpecies();
3746 CH_assert(a_ppc.nComp() == numCdrSpecies);
3748 const Real dx = m_amr->getDx()[a_level];
3749 const Real vol = std::pow(dx, SpaceDim);
3750 const RealVect probLo = m_amr->getProbLo();
3753 FArrayBox& ppcRegular = a_ppc.getFArrayBox();
3755 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
3756 RefCountedPtr<CdrSolver>& solver = solverIt();
3757 const int idx = solverIt.index();
3759 const EBCellFAB& phi = (*(solver->getPhi())[a_level])[a_din];
3760 const FArrayBox& phiReg = phi.getFArrayBox();
3765 auto regularKernel = [&](
const IntVect& iv) ->
void {
3766 if (a_ebisbox.isRegular(iv)) {
3767 ppcRegular(iv, idx) = std::max(zero, std::floor(phiReg(iv, 0) * vol));
3772 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
3773 const Real kappa = a_ebisbox.volFrac(vof);
3775 a_ppc(vof, idx) = std::max(zero, std::floor(kappa * phi(vof, 0) * vol));
3779 VoFIterator& vofit = (*m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase)[a_level])[a_din];
3781 BoxLoops::loop<D_DECL(1, 1, 1)>(a_box, regularKernel);
3786template <
typename I,
typename C,
typename R,
typename F>
3790 CH_TIME(
"ItoKMCStepper::computeReactiveMaeanEnergiesPerCell(EBAMRCellData)");
3791 if (m_verbosity > 5) {
3792 pout() << m_name +
"::computeReactiveMaeanEnergiesPerCell(EBAMRCellData)" << endl;
3795 CH_assert(a_meanEnergies.getRealm() == m_particleRealm);
3799 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
3800 this->computeReactiveMeanEnergiesPerCell(*a_meanEnergies[lvl], lvl);
3804template <
typename I,
typename C,
typename R,
typename F>
3807 const int a_level)
noexcept
3809 CH_TIME(
"ItoKMCStepper::computeReactiveMeanEnergiesPerCell(LD<EBCellFAB>, int)");
3810 if (m_verbosity > 5) {
3811 pout() << m_name +
"::computeReactiveMeanEnergiesPerCell(LD<EBCellFAB>, int)" << endl;
3814 const int numPlasmaSpecies = m_physics->getNumItoSpecies();
3816 CH_assert(a_meanEnergies.nComp() == numPlasmaSpecies);
3818 const DisjointBoxLayout& dbl = m_amr->getGrids(m_particleRealm)[a_level];
3819 const EBISLayout& ebisl = m_amr->getEBISLayout(m_particleRealm, m_plasmaPhase)[a_level];
3820 const DataIterator& dit = dbl.dataIterator();
3822 const int nbox = dit.size();
3824#pragma omp parallel for schedule(runtime)
3825 for (
int mybox = 0; mybox < nbox; mybox++) {
3826 const DataIndex& din = dit[mybox];
3828 const Box box = dbl[din];
3829 const EBISBox& ebisbox = ebisl[din];
3831 this->computeReactiveMeanEnergiesPerCell(a_meanEnergies[din], a_level, din, box, ebisbox);
3835template <
typename I,
typename C,
typename R,
typename F>
3839 const DataIndex a_din,
3841 const EBISBox& a_ebisbox)
noexcept
3843 CH_TIME(
"ItoKMCStepper::computeReactiveMeanEnergiesPerCell(EBCellFABint, DataIndex, Box, EBISBox)");
3844 if (m_verbosity > 5) {
3845 pout() << m_name +
"::computeReactiveMeanEnergiesPerCell(EBCellFABint, DataIndex, Box, EBISBox))" << endl;
3848 const int numPlasmaSpecies = m_physics->getNumItoSpecies();
3850 CH_assert(a_meanEnergies.nComp() == numPlasmaSpecies);
3852 const Real dx = m_amr->getDx()[a_level];
3853 const RealVect probLo = m_amr->getProbLo();
3856 FArrayBox& meanEnergiesReg = a_meanEnergies.getFArrayBox();
3858 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
3859 RefCountedPtr<ItoSolver>& solver = solverIt();
3860 const int idx = solverIt.index();
3867 leaf.
sortByCell(a_box, dx * RealVect::Unit, probLo);
3870 auto regularKernel = [&](
const IntVect& iv) ->
void {
3871 if (a_ebisbox.isRegular(iv)) {
3872 Real totalWeight = 0.0;
3873 Real totalEnergy = 0.0;
3875 const std::pair<std::size_t, std::size_t> range = leaf.
cellRange(a_box.index(iv));
3876 for (std::size_t i = range.first; i < range.second; i++) {
3877 const Real w = leaf.
weight(i);
3879 totalEnergy += w * leaf.template get<&ItoParticle::energy>(i);
3882 if (totalWeight > 0.0) {
3883 meanEnergiesReg(iv, idx) = totalEnergy / totalWeight;
3886 meanEnergiesReg(iv, idx) = 0.0;
3892 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
3893 const IntVect iv = vof.gridIndex();
3894 const RealVect normal = a_ebisbox.normal(vof);
3895 const RealVect ebCentroid = probLo +
Location::position(Location::Cell::Boundary, vof, a_ebisbox, dx);
3897 Real totalWeight = 0.0;
3898 Real totalEnergy = 0.0;
3900 const std::pair<std::size_t, std::size_t> range = leaf.
cellRange(a_box.index(iv));
3901 for (std::size_t i = range.first; i < range.second; i++) {
3902 const RealVect pos = leaf.
position(i);
3904 if ((pos - ebCentroid).dotProduct(normal) >= 0.0) {
3905 const Real w = leaf.
weight(i);
3907 totalEnergy += w * leaf.template get<&ItoParticle::energy>(i);
3911 if (totalWeight > 0.0) {
3912 meanEnergiesReg(iv, idx) = totalEnergy / totalWeight;
3915 meanEnergiesReg(iv, idx) = 0.0;
3920 VoFIterator& vofit = (*m_amr->getVofIterator(m_particleRealm, m_plasmaPhase)[a_level])[a_din];
3922 BoxLoops::loop<D_DECL(1, 1, 1)>(a_box, regularKernel);
3927template <
typename I,
typename C,
typename R,
typename F>
3931 CH_TIME(
"ItoKMCStepper::advanceReactionNetwork(dt)");
3932 if (m_verbosity > 5) {
3933 pout() << m_name +
"::advanceReactionNetwork(dt)" << endl;
3936 CH_assert(a_dt > 0.0);
3938 this->advanceReactionNetwork(m_electricFieldFluid, a_dt);
3945template <
typename I,
typename C,
typename R,
typename F>
3949 CH_TIMERS(
"ItoKMCStepper::advanceReactionNetwork");
3950 CH_TIMER(
"ItoKMCStepper::advanceReactionNetwork::compute_ppc", t1);
3951 CH_TIMER(
"ItoKMCStepper::advanceReactionNetwork::integrate_network", t2);
3952 CH_TIMER(
"ItoKMCStepper::advanceReactionNetwork::copies", t3);
3953 CH_TIMER(
"ItoKMCStepper::advanceReactionNetwork::reconcile_particles", t4);
3954 CH_TIMER(
"ItoKMCStepper::advanceReactionNetwork::reconcile_cdr", t5);
3955 if (m_verbosity > 5) {
3956 pout() << m_name +
"::advanceReactionNetwork" << endl;
3959 const int numItoSpecies = m_physics->getNumItoSpecies();
3960 const int numCdrSpecies = m_physics->getNumCdrSpecies();
3961 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
3963 CH_assert(a_electricField.getRealm() == m_fluidRealm);
3964 CH_assert(a_dt > 0.0);
3969 if (numItoSpecies > 0) {
3970 this->computeReactiveItoParticlesPerCell(m_particleItoPPC);
3972 const Interval srcInterv(0, numItoSpecies - 1);
3973 const Interval dstInterv(0, numItoSpecies - 1);
3975 m_amr->copyData(m_fluidPPC, m_particleItoPPC, dstInterv, srcInterv);
3979 if (numCdrSpecies > 0) {
3980 this->computeReactiveCdrParticlesPerCell(m_fluidCdrPPC);
3982 const Interval srcInterv(0, numCdrSpecies - 1);
3983 const Interval dstInterv(numItoSpecies, numItoSpecies + numCdrSpecies - 1);
3985 m_amr->copyData(m_fluidPPC, m_fluidCdrPPC, dstInterv, srcInterv);
3997 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
3998 this->advanceReactionNetwork(*m_fluidPPC[lvl], *m_fluidYPC[lvl], *a_electricField[lvl], lvl, a_dt);
4004 if (numItoSpecies > 0) {
4005 const Interval srcInterv(0, numItoSpecies - 1);
4006 const Interval dstInterv(0, numItoSpecies - 1);
4008 m_amr->copyData(m_particleItoPPC, m_fluidPPC, dstInterv, srcInterv);
4010 if (numCdrSpecies > 0) {
4011 const Interval srcInterv(numItoSpecies, numItoSpecies + numCdrSpecies - 1);
4012 const Interval dstInterv(0, numCdrSpecies - 1);
4014 m_amr->copyData(m_fluidCdrPPC, m_fluidPPC, dstInterv, srcInterv);
4016 if (numPhotonSpecies > 0) {
4017 m_amr->copyData(m_particleYPC, m_fluidYPC);
4024 for (
int i = 0; i < m_cdrPhotoiProducts.size(); i++) {
4025 m_cdrPhotoiProducts[i]->clearParticles();
4026 m_cdrPhotoiProducts[i]->organizeParticlesByCell();
4031 this->reconcileParticles(m_particleItoPPC, m_particleOldItoPPC, m_particleYPC, m_electricFieldParticle);
4038 for (
int i = 0; i < m_cdrPhotoiProducts.size(); i++) {
4039 m_cdrPhotoiProducts[i]->organizeParticlesByPatch();
4041 m_amr->depositWeight(m_particleScratch1,
4044 *m_cdrPhotoiProducts[i],
4045 DepositionType::NGP,
4046 CoarseFineDeposition::Halo,
4049 m_amr->copyData(m_fluidScratch1, m_particleScratch1);
4052 EBAMRCellData fluidCdrPPC = m_amr->slice(m_fluidCdrPPC, Interval(i, i));
4056 m_cdrPhotoiProducts[i]->clearParticles();
4059 this->reconcileCdrDensities(m_fluidCdrPPC, m_fluidOldCdrPPC, a_dt);
4063template <
typename I,
typename C,
typename R,
typename F>
4066 LevelData<EBCellFAB>& a_newPhotonsPerCell,
4067 const LevelData<EBCellFAB>& a_electricField,
4069 const Real a_dt)
const noexcept
4071 CH_TIME(
"ItoKMCStepper::advanceReactionNetwork(LD<EBCellFAB>x3, int, Real)");
4072 if (m_verbosity > 5) {
4073 pout() << m_name +
"::advanceReactionNetwork(LD<EBCellFAB>x3, int, Real)" << endl;
4076 const int numPlasmaSpecies = m_physics->getNumPlasmaSpecies();
4077 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
4079 CH_assert(a_particlesPerCell.nComp() == numPlasmaSpecies);
4080 CH_assert(a_newPhotonsPerCell.nComp() == numPhotonSpecies);
4081 CH_assert(a_electricField.nComp() == SpaceDim);
4083 const DisjointBoxLayout& dbl = m_amr->getGrids(m_fluidRealm)[a_level];
4084 const DataIterator& dit = dbl.dataIterator();
4086 const int nbox = dit.size();
4090 m_physics->defineKMC();
4092#pragma omp for schedule(runtime)
4093 for (
int mybox = 0; mybox < nbox; mybox++) {
4094 const DataIndex& din = dit[mybox];
4096 this->advanceReactionNetwork(a_particlesPerCell[din],
4097 a_newPhotonsPerCell[din],
4098 a_electricField[din],
4102 m_amr->getDx()[a_level],
4106 m_physics->killKMC();
4110template <
typename I,
typename C,
typename R,
typename F>
4113 EBCellFAB& a_newPhotonsPerCell,
4114 const EBCellFAB& a_electricField,
4116 const DataIndex a_din,
4119 const Real a_dt)
const noexcept
4121 CH_TIME(
"ItoKMCStepper::advanceReactionNetwork(EBCellFABx3, int, DataIndex, Box, Realx2)");
4122 if (m_verbosity > 5) {
4123 pout() << m_name +
"::advanceReactionNetwork(EBCellFABx3, int, DataIndex, Box, Realx2)" << endl;
4126 const int numCdrSpecies = m_physics->getNumCdrSpecies();
4127 const int numItoSpecies = m_physics->getNumItoSpecies();
4128 const int numPlasmaSpecies = m_physics->getNumPlasmaSpecies();
4129 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
4131 CH_assert(a_particlesPerCell.nComp() == numPlasmaSpecies);
4132 CH_assert(a_newPhotonsPerCell.nComp() == numPhotonSpecies);
4133 CH_assert(a_electricField.nComp() == SpaceDim);
4136 const RealVect probLo = m_amr->getProbLo();
4137 const EBISBox& ebisbox = m_amr->getEBISLayout(m_fluidRealm, m_plasmaPhase)[a_level][a_din];
4139 const FArrayBox& electricFieldReg = a_electricField.getFArrayBox();
4142 Vector<Physics::ItoKMC::FPR> particles(numPlasmaSpecies);
4143 Vector<Physics::ItoKMC::FPR> newPhotons(numPhotonSpecies);
4144 Vector<Real> meanEnergies(numPlasmaSpecies);
4145 Vector<Real> energySources(numPlasmaSpecies);
4146 Vector<Real> densities(numPlasmaSpecies, 0.0);
4147 Vector<RealVect> densityGradients(numPlasmaSpecies, RealVect::Zero);
4150 FArrayBox& particlesPerCellReg = a_particlesPerCell.getFArrayBox();
4151 FArrayBox& newPhotonsReg = a_newPhotonsPerCell.getFArrayBox();
4154 Vector<const EBCellFAB*> densitiesIto(numItoSpecies);
4155 Vector<const EBCellFAB*> densityGradientsIto(numItoSpecies);
4156 Vector<const FArrayBox*> densitiesItoReg(numItoSpecies);
4157 Vector<const FArrayBox*> densityGradientsItoReg(numItoSpecies);
4159 Vector<const EBCellFAB*> densitiesCDR(numCdrSpecies);
4160 Vector<const EBCellFAB*> densityGradientsCDR(numCdrSpecies);
4161 Vector<const FArrayBox*> densitiesCDRReg(numCdrSpecies);
4162 Vector<const FArrayBox*> densityGradientsCDRReg(numCdrSpecies);
4165 EBCellFAB& physicsDt = (*m_kmcDt[a_level])[a_din];
4167 FArrayBox& physicsDtReg = physicsDt.getFArrayBox();
4169 physicsDt.setVal(std::numeric_limits<Real>::max());
4171 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
4172 const RefCountedPtr<ItoSolver>& solver = it();
4174 const int i = it.index();
4176 densitiesIto[i] = &(*(m_fluidPhiIto[i])[a_level])[a_din];
4177 densitiesItoReg[i] = &(densitiesIto[i]->getFArrayBox());
4178 densityGradientsIto[i] = &(*m_fluidGradPhiIto[i][a_level])[a_din];
4179 densityGradientsItoReg[i] = &(densityGradientsIto[i]->getFArrayBox());
4182 for (
auto it = m_cdr->iterator(); it.ok(); ++it) {
4183 const RefCountedPtr<CdrSolver>& solver = it();
4184 const EBAMRCellData& phi = solver->getPhi();
4186 const int i = it.index();
4188 densitiesCDR[i] = &(*phi[a_level])[a_din];
4189 densitiesCDRReg[i] = &(densitiesCDR[i]->getFArrayBox());
4190 densityGradientsCDR[i] = &(*m_fluidGradPhiCDR[i][a_level])[a_din];
4191 densityGradientsCDRReg[i] = &(densityGradientsCDR[i]->getFArrayBox());
4195 const BaseFab<bool>& validCells = (*m_amr->getValidCells(m_fluidRealm)[a_level])[a_din];
4198 auto regularKernel = [&](
const IntVect& iv) ->
void {
4199 if (ebisbox.isRegular(iv) && validCells(iv, 0)) {
4200 const RealVect pos = probLo + a_dx * (RealVect(iv) + 0.5 * RealVect::Unit);
4201 const RealVect E = RealVect(D_DECL(electricFieldReg(iv, 0), electricFieldReg(iv, 1), electricFieldReg(iv, 2)));
4204 for (
int i = 0; i < numPlasmaSpecies; i++) {
4205 particles[i] = llround(particlesPerCellReg(iv, i));
4208 for (
int i = 0; i < numPhotonSpecies; i++) {
4209 newPhotons[i] = 0LL;
4213 for (
int i = 0; i < numItoSpecies; i++) {
4214 densities[i] = (*densitiesItoReg[i])(iv, 0);
4215 densityGradients[i] = RealVect(D_DECL((*densityGradientsItoReg[i])(iv, 0),
4216 (*densityGradientsItoReg[i])(iv, 1),
4217 (*densityGradientsItoReg[i])(iv, 2)));
4220 for (
int i = 0; i < numCdrSpecies; i++) {
4221 densities[numItoSpecies + i] = (*densitiesCDRReg[i])(iv, 0);
4222 densityGradients[numItoSpecies + i] = RealVect(D_DECL((*densityGradientsCDRReg[i])(iv, 0),
4223 (*densityGradientsCDRReg[i])(iv, 1),
4224 (*densityGradientsCDRReg[i])(iv, 2)));
4228 Real physDt = std::numeric_limits<Real>::max();
4230 m_physics->advanceKMC(particles, newPhotons, physDt, densities, densityGradients, a_dt, E, pos, a_dx, 1.0);
4233 for (
int i = 0; i < numPlasmaSpecies; i++) {
4234 particlesPerCellReg(iv, i) = 1.0 * particles[i];
4237 for (
int i = 0; i < numPhotonSpecies; i++) {
4238 newPhotonsReg(iv, i) = 1.0 * newPhotons[i];
4241 physicsDtReg(iv, 0) = physDt;
4246 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
4247 const IntVect iv = vof.gridIndex();
4249 if (ebisbox.isIrregular(iv) && validCells(iv, 0)) {
4250 const Real kappa = ebisbox.volFrac(vof);
4251 const RealVect pos = probLo +
Location::position(Location::Cell::Centroid, vof, ebisbox, a_dx);
4252 const RealVect E = RealVect(D_DECL(a_electricField(vof, 0), a_electricField(vof, 1), a_electricField(vof, 2)));
4255 for (
int i = 0; i < numPlasmaSpecies; i++) {
4256 particles[i] = llround(a_particlesPerCell(vof, i));
4259 for (
int i = 0; i < numPhotonSpecies; i++) {
4260 newPhotons[i] = 0LL;
4264 for (
int i = 0; i < numItoSpecies; i++) {
4265 densities[i] = (*densitiesIto[i])(vof, 0);
4266 densityGradients[i] = RealVect(D_DECL((*densityGradientsIto[i])(vof, 0),
4267 (*densityGradientsIto[i])(vof, 1),
4268 (*densityGradientsIto[i])(vof, 2)));
4271 for (
int i = 0; i < numCdrSpecies; i++) {
4272 densities[numItoSpecies + i] = (*densitiesCDR[i])(vof, 0);
4273 densityGradients[numItoSpecies + i] = RealVect(D_DECL((*densityGradientsCDR[i])(vof, 0),
4274 (*densityGradientsCDR[i])(vof, 1),
4275 (*densityGradientsCDR[i])(vof, 2)));
4279 Real physDt = std::numeric_limits<Real>::max();
4281 m_physics->advanceKMC(particles, newPhotons, physDt, densities, densityGradients, a_dt, E, pos, a_dx, kappa);
4284 for (
int i = 0; i < numPlasmaSpecies; i++) {
4285 a_particlesPerCell(vof, i) = 1.0 * particles[i];
4288 for (
int i = 0; i < numPhotonSpecies; i++) {
4289 a_newPhotonsPerCell(vof, i) = 1.0 * newPhotons[i];
4292 physicsDt(vof, 0) = physDt;
4299 VoFIterator& vofit = (*m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase)[a_level])[a_din];
4301 BoxLoops::loop<D_DECL(1, 1, 1)>(a_box, regularKernel);
4305template <
typename I,
typename C,
typename R,
typename F>
4308 const EBAMRCellData& a_oldParticlesPerCell,
4309 const EBAMRCellData& a_newPhotonsPerCell,
4310 const EBAMRCellData& a_electricField)
const noexcept
4312 CH_TIME(
"ItoKMCStepper::reconcileParticles(EBAMRCellDatax3)");
4313 if (m_verbosity > 5) {
4314 pout() << m_name +
"::reconcileParticles(EBAMRCellDatax3)";
4317 CH_assert(a_newParticlesPerCell.getRealm() == m_particleRealm);
4318 CH_assert(a_oldParticlesPerCell.getRealm() == m_particleRealm);
4319 CH_assert(a_newPhotonsPerCell.getRealm() == m_particleRealm);
4320 CH_assert(a_electricField.getRealm() == m_particleRealm);
4322 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
4323 this->reconcileParticles(*a_newParticlesPerCell[lvl],
4324 *a_oldParticlesPerCell[lvl],
4325 *a_newPhotonsPerCell[lvl],
4326 *a_electricField[lvl],
4331template <
typename I,
typename C,
typename R,
typename F>
4334 const LevelData<EBCellFAB>& a_oldParticlesPerCell,
4335 const LevelData<EBCellFAB>& a_newPhotonsPerCell,
4336 const LevelData<EBCellFAB>& a_electricField,
4337 const int a_level)
const noexcept
4339 CH_TIME(
"ItoKMCStepper::reconcileParticles(LevelData<EBCellFAB>x3, int)");
4340 if (m_verbosity > 5) {
4341 pout() << m_name +
"::reconcileParticles(LevelData<EBCellFAB>x3, int)" << endl;
4344 const int numItoSpecies = m_physics->getNumItoSpecies();
4345 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
4347 CH_assert(a_newParticlesPerCell.nComp() == numItoSpecies);
4348 CH_assert(a_oldParticlesPerCell.nComp() == numItoSpecies);
4349 CH_assert(a_newPhotonsPerCell.nComp() == numPhotonSpecies);
4350 CH_assert(a_electricField.nComp() == SpaceDim);
4352 const DisjointBoxLayout& dbl = m_amr->getGrids(m_particleRealm)[a_level];
4353 const DataIterator& dit = dbl.dataIterator();
4355 const int nbox = dit.size();
4357#pragma omp parallel for schedule(runtime)
4358 for (
int mybox = 0; mybox < nbox; mybox++) {
4359 const DataIndex& din = dit[mybox];
4361 this->reconcileParticles(a_newParticlesPerCell[din],
4362 a_oldParticlesPerCell[din],
4363 a_newPhotonsPerCell[din],
4364 a_electricField[din],
4368 m_amr->getDx()[a_level]);
4372template <
typename I,
typename C,
typename R,
typename F>
4375 const EBCellFAB& a_oldParticlesPerCell,
4376 const EBCellFAB& a_newPhotonsPerCell,
4377 const EBCellFAB& a_electricField,
4379 const DataIndex a_din,
4381 const Real a_dx)
const noexcept
4383 CH_TIMERS(
"ItoKMCStepper::reconcileParticles(patch)");
4384 CH_TIMER(
"ItoKMCStepper::reconcileParticles(patch)::collect_ptr", t1);
4385 CH_TIMER(
"ItoKMCStepper::reconcileParticles(patch)::regular_cells", t2);
4386 CH_TIMER(
"ItoKMCStepper::reconcileParticles(patch)::irregular_cells", t3);
4387 if (m_verbosity > 5) {
4388 pout() << m_name +
"::reconcileParticles(patch)" << endl;
4398 const int numItoSpecies = m_physics->getNumItoSpecies();
4399 const int numCdrSpecies = m_physics->getNumCdrSpecies();
4400 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
4402 CH_assert(a_newParticlesPerCell.nComp() == numItoSpecies);
4403 CH_assert(a_oldParticlesPerCell.nComp() == numItoSpecies);
4404 CH_assert(a_newPhotonsPerCell.nComp() == numPhotonSpecies);
4405 CH_assert(a_electricField.nComp() == SpaceDim);
4408 const RealVect probLo = m_amr->getProbLo();
4409 const EBISBox& ebisbox = m_amr->getEBISLayout(m_particleRealm, m_plasmaPhase)[a_level][a_din];
4413 const BaseFab<bool>& validCells = (*m_amr->getValidCells(m_particleRealm)[a_level])[a_din];
4416 const FArrayBox& electricFieldReg = a_electricField.getFArrayBox();
4421 std::vector<std::vector<ParticleSoA<ItoParticle>>> itoCells(numItoSpecies);
4422 std::vector<std::vector<ParticleSoA<Photon>>> bulkPhotonCells(numPhotonSpecies);
4423 std::vector<std::vector<ParticleSoA<Photon>>> sourcePhotonCells(numPhotonSpecies);
4424 std::vector<std::vector<ParticleSoA<NoPayload>>> cdrCells(numCdrSpecies);
4427 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
4428 const int idx = solverIt.index();
4432 binLeafToCells(itoCells[idx], solverParticles[a_level][a_din], a_box, a_dx, probLo);
4436 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
4437 const int idx = solverIt.index();
4439 binLeafToCells(cdrCells[idx], (*m_cdrPhotoiProducts[idx])[a_level][a_din], a_box, a_dx, probLo);
4443 for (
auto solverIt = m_rte->iterator(); solverIt.ok(); ++solverIt) {
4444 const int idx = solverIt.index();
4449 binLeafToCells(bulkPhotonCells[idx], solverBulkPhotons[a_level][a_din], a_box, a_dx, probLo);
4450 binLeafToCells(sourcePhotonCells[idx], solverSourcePhotons[a_level][a_din], a_box, a_dx, probLo);
4456 Vector<Physics::ItoKMC::FPR> numNewParticles(numItoSpecies);
4457 Vector<Physics::ItoKMC::FPR> numOldParticles(numItoSpecies);
4458 Vector<Physics::ItoKMC::FPR> numNewPhotons(numPhotonSpecies);
4463 Vector<ParticleSoA<ItoParticle>*> itoParticles(numItoSpecies);
4464 Vector<ParticleSoA<NoPayload>*> cdrParticles(numCdrSpecies);
4465 Vector<ParticleSoA<Photon>*> bulkPhotons(numPhotonSpecies);
4466 Vector<ParticleSoA<Photon>*> sourcePhotons(numPhotonSpecies);
4470 auto regularKernel = [&](
const IntVect& iv) ->
void {
4471 if (ebisbox.isRegular(iv) && validCells(iv)) {
4472 const RealVect electricField = RealVect(
4473 D_DECL(electricFieldReg(iv, 0), electricFieldReg(iv, 1), electricFieldReg(iv, 2)));
4474 const RealVect cellPos = probLo + a_dx * (RealVect(iv) + 0.5 * RealVect::Unit);
4475 const RealVect centroidPos = RealVect::Zero;
4476 const RealVect lo = -0.5 * RealVect::Unit;
4477 const RealVect hi = 0.5 * RealVect::Unit;
4478 const RealVect bndryCentroid = RealVect::Zero;
4479 const RealVect bndryNormal = RealVect::Zero;
4480 const Real kappa = 1.0;
4483 for (
int i = 0; i < numItoSpecies; i++) {
4484 itoParticles[i] = &itoCells[i][a_box.index(iv)];
4485 numNewParticles[i] = llround(a_newParticlesPerCell.getSingleValuedFAB()(iv, i));
4486 numOldParticles[i] = llround(a_oldParticlesPerCell.getSingleValuedFAB()(iv, i));
4490 for (
int i = 0; i < numCdrSpecies; i++) {
4491 cdrParticles[i] = &cdrCells[i][a_box.index(iv)];
4495 for (
int i = 0; i < numPhotonSpecies; i++) {
4496 bulkPhotons[i] = &bulkPhotonCells[i][a_box.index(iv)];
4497 sourcePhotons[i] = &sourcePhotonCells[i][a_box.index(iv)];
4499 numNewPhotons[i] = llround(a_newPhotonsPerCell.getSingleValuedFAB()(iv, i));
4503 sourcePhotons[i]->clear();
4508 m_physics->reconcileParticles(itoParticles,
4523 m_physics->reconcilePhotons(sourcePhotons,
4535 m_physics->reconcilePhotoionization(itoParticles, cdrParticles, bulkPhotons);
4546 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
4547 const IntVect iv = vof.gridIndex();
4548 if (ebisbox.isIrregular(iv) && validCells(iv, 0)) {
4549 const RealVect electricField = RealVect(
4550 D_DECL(a_electricField(vof, 0), a_electricField(vof, 1), a_electricField(vof, 2)));
4551 const RealVect cellPos = probLo +
Location::position(Location::Cell::Center, vof, ebisbox, a_dx);
4552 const RealVect centroidPos = ebisbox.centroid(vof);
4553 const RealVect bndryCentroid = ebisbox.bndryCentroid(vof);
4554 const RealVect bndryNormal = ebisbox.normal(vof);
4555 const Real kappa = ebisbox.volFrac(vof);
4558 RealVect lo = -0.5 * RealVect::Unit;
4559 RealVect hi = 0.5 * RealVect::Unit;
4565 for (
int i = 0; i < numItoSpecies; i++) {
4566 itoParticles[i] = &itoCells[i][a_box.index(iv)];
4567 numNewParticles[i] = llround(a_newParticlesPerCell(vof, i));
4568 numOldParticles[i] = llround(a_oldParticlesPerCell(vof, i));
4572 for (
int i = 0; i < numCdrSpecies; i++) {
4573 cdrParticles[i] = &cdrCells[i][a_box.index(iv)];
4577 for (
int i = 0; i < numPhotonSpecies; i++) {
4578 bulkPhotons[i] = &bulkPhotonCells[i][a_box.index(iv)];
4579 sourcePhotons[i] = &sourcePhotonCells[i][a_box.index(iv)];
4581 numNewPhotons[i] = llround(a_newPhotonsPerCell(vof, i));
4585 sourcePhotons[i]->clear();
4590 m_physics->reconcileParticles(itoParticles,
4605 m_physics->reconcilePhotons(sourcePhotons,
4617 m_physics->reconcilePhotoionization(itoParticles, cdrParticles, bulkPhotons);
4625 VoFIterator& vofit = (*m_amr->getVofIterator(m_particleRealm, m_plasmaPhase)[a_level])[a_din];
4628 BoxLoops::loop<D_DECL(1, 1, 1)>(a_box, regularKernel);
4638 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
4639 const int idx = solverIt.index();
4643 rebuildLeafFromCells(solverParticles[a_level][a_din], itoCells[idx]);
4646 for (
auto solverIt = m_rte->iterator(); solverIt.ok(); ++solverIt) {
4647 const int idx = solverIt.index();
4651 rebuildLeafFromCells(solverSourcePhotons[a_level][a_din], sourcePhotonCells[idx]);
4655 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
4656 const int idx = solverIt.index();
4658 rebuildLeafFromCells((*m_cdrPhotoiProducts[idx])[a_level][a_din], cdrCells[idx]);
4662template <
typename I,
typename C,
typename R,
typename F>
4666 CH_TIME(
"ItoKMCStepper::reconcilePhotoionization()");
4667 if (m_verbosity > 5) {
4668 pout() << m_name +
"::reconcilePhotoionization()" << endl;
4671 const int numItoSpecies = m_physics->getNumItoSpecies();
4672 const int numCdrSpecies = m_physics->getNumCdrSpecies();
4673 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
4675 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
4676 const DisjointBoxLayout& dbl = m_amr->getGrids(m_particleRealm)[lvl];
4677 const DataIterator& dit = dbl.dataIterator();
4679 const int nbox = dit.size();
4681#pragma omp parallel for schedule(runtime)
4682 for (
int mybox = 0; mybox < nbox; mybox++) {
4683 const DataIndex& din = dit[mybox];
4689 Vector<ParticleSoA<ItoParticle>> itoProducts(numItoSpecies);
4691 Vector<ParticleSoA<ItoParticle>*> itoParticles(numItoSpecies);
4692 Vector<ParticleSoA<NoPayload>*> cdrParticles(numCdrSpecies);
4693 Vector<ParticleSoA<Photon>*> photonParticles(numPhotonSpecies);
4695 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
4696 itoParticles[solverIt.index()] = &itoProducts[solverIt.index()];
4699 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
4700 cdrParticles[solverIt.index()] = &((*m_cdrPhotoiProducts[solverIt.index()])[lvl][din]);
4703 for (
auto solverIt = m_rte->iterator(); solverIt.ok(); ++solverIt) {
4704 photonParticles[solverIt.index()] = &(solverIt()->getBulkPhotons()[lvl][din]);
4707 m_physics->reconcilePhotoionization(itoParticles, cdrParticles, photonParticles);
4710 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
4711 const int idx = solverIt.index();
4714 leaf.
append(itoProducts[idx]);
4720template <
typename I,
typename C,
typename R,
typename F>
4723 const EBAMRCellData& a_oldParticlesPerCell,
4724 const Real a_dt)
noexcept
4726 CH_TIME(
"ItoKMCStepper::reconcileCdrDensities(EBAMRCellDatax2, Real)");
4727 if (m_verbosity > 5) {
4728 pout() << m_name +
"::reconcileCdrDensities(EBAMRCellDatax2, Real)" << endl;
4731 const int numCdrSpecies = m_physics->getNumCdrSpecies();
4733 CH_assert(a_newParticlesPerCell.getRealm() == m_fluidRealm);
4734 CH_assert(a_oldParticlesPerCell.getRealm() == m_fluidRealm);
4735 CH_assert(a_dt > 0.0);
4737 if (numCdrSpecies > 0) {
4740 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
4741 this->reconcileCdrDensities(*a_newParticlesPerCell[lvl], *a_oldParticlesPerCell[lvl], lvl, a_dt);
4745 if (m_redistributeCDR) {
4746 for (
auto it = m_cdr->iterator(); it.ok(); ++it) {
4747 const int idx = it.index();
4749 const EBAMRCellData newPPC = m_amr->slice(a_newParticlesPerCell, Interval(idx, idx));
4750 const EBAMRCellData oldPPC = m_amr->slice(a_oldParticlesPerCell, Interval(idx, idx));
4752 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
4753 const DisjointBoxLayout& dbl = m_amr->getGrids(m_fluidRealm)[lvl];
4754 const DataIterator& dit = dbl.dataIterator();
4755 const EBISLayout& ebisl = m_amr->getEBISLayout(m_fluidRealm, m_plasmaPhase)[lvl];
4756 const Real dx = m_amr->getDx()[lvl];
4758 const int nbox = dit.size();
4760#pragma omp parallel for schedule(runtime)
4761 for (
int mybox = 0; mybox < nbox; mybox++) {
4762 const DataIndex& din = dit[mybox];
4763 const EBISBox& ebisbox = ebisl[din];
4765 BaseIVFAB<Real>& deltaMass = (*m_fluidScratchEB[lvl])[din];
4767 deltaMass.setVal(0.0);
4769 const EBCellFAB& newPPC = (*a_newParticlesPerCell[lvl])[din];
4770 const EBCellFAB& oldPPC = (*a_oldParticlesPerCell[lvl])[din];
4772 auto kernel = [&](
const VolIndex& vof) ->
void {
4773 const Real kappa = ebisbox.volFrac(vof);
4775 deltaMass(vof, 0) = (newPPC(vof, idx) - oldPPC(vof, idx)) * (1.0 - kappa) / std::pow(dx, SpaceDim);
4778 VoFIterator& vofit = (*m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase)[lvl])[din];
4784 const RefCountedPtr<CdrSolver>& solver = it();
4786 solver->redistribute(solver->getPhi(), m_fluidScratchEB);
4790 this->coarsenCDRSolvers();
4794template <
typename I,
typename C,
typename R,
typename F>
4797 const LevelData<EBCellFAB>& a_oldParticlesPerCell,
4799 const Real a_dt)
noexcept
4801 CH_TIME(
"ItoKMCStepper::reconcileCdrDensities(LD<EBCellFAB>x2, int, Real)");
4802 if (m_verbosity > 5) {
4803 pout() << m_name +
"::reconcileCdrDensities(LD<EBCellFAB>x2, int, Real)" << endl;
4806 const int numCdrSpecies = m_physics->getNumCdrSpecies();
4808 CH_assert(a_newParticlesPerCell.nComp() == numCdrSpecies);
4809 CH_assert(a_oldParticlesPerCell.nComp() == numCdrSpecies);
4811 const DisjointBoxLayout& dbl = m_amr->getGrids(m_fluidRealm)[a_level];
4812 const DataIterator& dit = dbl.dataIterator();
4813 const Real dx = m_amr->getDx()[a_level];
4815 const int nbox = dit.size();
4817#pragma omp parallel for schedule(runtime)
4818 for (
int mybox = 0; mybox < nbox; mybox++) {
4819 const DataIndex& din = dit[mybox];
4822 ->reconcileCdrDensities(a_newParticlesPerCell[din], a_oldParticlesPerCell[din], a_level, din, dbl[din], dx, a_dt);
4826template <
typename I,
typename C,
typename R,
typename F>
4829 const EBCellFAB& a_oldParticlesPerCell,
4831 const DataIndex a_din,
4834 const Real a_dt)
noexcept
4836 CH_TIME(
"ItoKMCStepper::reconcileCdrDensities(EBCellFABx2, int, DataIndex, Box, Realx2)");
4837 if (m_verbosity > 5) {
4838 pout() << m_name +
"::reconcileCdrDensities(EBCellFABx2, int, DataIndex, Box, Realx2)" << endl;
4841 const int numCdrSpecies = m_physics->getNumCdrSpecies();
4843 CH_assert(a_newParticlesPerCell.nComp() == numCdrSpecies);
4844 CH_assert(a_oldParticlesPerCell.nComp() == numCdrSpecies);
4846 const Real volume = std::pow(a_dx, SpaceDim);
4848 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
4849 RefCountedPtr<CdrSolver>& solver = solverIt();
4850 const int index = solverIt.index();
4852 EBCellFAB& phi = (*(solver->getPhi()[a_level]))[a_din];
4853 EBCellFAB& src = (*(solver->getSource()[a_level]))[a_din];
4857 src.plus(a_newParticlesPerCell, index, 0, 1);
4858 src.minus(a_oldParticlesPerCell, index, 0, 1);
4869template <
typename I,
typename C,
typename R,
typename F>
4873 CH_TIME(
"ItoKMCStepper::coarsenCDRSolvers");
4874 if (m_verbosity > 5) {
4875 pout() << m_name +
"::coarsenCDRSolvers" << endl;
4878 for (
auto solverIt = this->m_cdr->iterator(); solverIt.ok(); ++solverIt) {
4879 auto& solver = solverIt();
4881 EBAMRCellData& phi = solver->getPhi();
4882 EBAMRCellData& src = solver->getSource();
4884 this->m_amr->conservativeAverage(phi, phi.getRealm(), this->m_plasmaPhase);
4885 this->m_amr->conservativeAverage(src, src.getRealm(), this->m_plasmaPhase);
4887 this->m_amr->interpGhostPwl(phi, phi.getRealm(), this->m_plasmaPhase);
4888 this->m_amr->interpGhostPwl(src, src.getRealm(), this->m_plasmaPhase);
4895template <
typename I,
typename C,
typename R,
typename F>
4899 CH_TIME(
"ItoKMCStepper::fillSecondaryEmissionEB(Real)");
4900 if (m_verbosity > 5) {
4901 pout() << m_name +
"::fillSecondaryEmissionEB(Real)" << endl;
4905 Vector<ParticleContainer<ItoParticle>*> primaryParticles;
4906 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
4909 primaryParticles.push_back(&intersectedParticles);
4915 m_amr->allocate(tmp, m_fluidRealm, m_plasmaPhase, 1);
4917 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
4918 const int idx = solverIt.index();
4919 const RefCountedPtr<CdrSolver>& solver = solverIt();
4921 EBAMRIVData& extrapFlux = m_cdrFluxesExtrap[idx];
4923 if (solver->isMobile()) {
4924 solver->extrapolateAdvectiveFluxToEB(tmp);
4926 m_amr->copyData(extrapFlux, tmp);
4934 Vector<ParticleContainer<Photon>*> primaryPhotons;
4935 for (
auto it = m_rte->iterator(); it.ok(); ++it) {
4938 primaryPhotons.push_back(&intersectedPhotons);
4942 this->fillSecondaryEmissionEB(m_secondaryParticles,
4948 m_electricFieldParticle,
4952template <
typename I,
typename C,
typename R,
typename F>
4956 Vector<EBAMRIVData>& a_cdrFluxes,
4959 Vector<EBAMRIVData>& a_cdrFluxesExtrap,
4961 const EBAMRCellData& a_electricField,
4962 const Real a_dt)
noexcept
4964 CH_TIME(
"ItoKMCStepper::fillSecondaryEmissionEB(full)");
4965 if (m_verbosity > 5) {
4966 pout() << m_name +
"::fillSecondaryEmissionEB(full)" << endl;
4969 const int numItoSpecies = m_physics->getNumItoSpecies();
4970 const int numCdrSpecies = m_physics->getNumCdrSpecies();
4971 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
4973 CH_assert(a_secondaryParticles.size() == numItoSpecies);
4974 CH_assert(a_cdrFluxes.size() == numCdrSpecies);
4975 CH_assert(a_secondaryPhotons.size() == numPhotonSpecies);
4976 CH_assert(a_primaryParticles.size() == numItoSpecies);
4977 CH_assert(a_cdrFluxesExtrap.size() == numCdrSpecies);
4978 CH_assert(a_primaryPhotons.size() == numPhotonSpecies);
4979 CH_assert(a_electricField.getRealm() == m_particleRealm);
4980 CH_assert(a_dt >= 0.0);
4983 for (
int i = 0; i < numItoSpecies; i++) {
4984 CH_assert(a_secondaryParticles[i]->getRealm() == m_particleRealm);
4985 CH_assert(a_primaryParticles[i]->getRealm() == m_particleRealm);
4987 a_secondaryParticles[i]->clearParticles();
4988 a_secondaryParticles[i]->organizeParticlesByCell();
4990 a_primaryParticles[i]->organizeParticlesByCell();
4993 for (
int i = 0; i < numCdrSpecies; i++) {
4994 CH_assert(a_cdrFluxes[i].getRealm() == m_particleRealm);
4995 CH_assert(a_cdrFluxesExtrap[i].getRealm() == m_particleRealm);
5001 for (
int i = 0; i < numPhotonSpecies; i++) {
5002 CH_assert(a_secondaryPhotons[i]->getRealm() == m_particleRealm);
5003 CH_assert(a_primaryPhotons[i]->getRealm() == m_particleRealm);
5005 a_secondaryPhotons[i]->clearParticles();
5007 a_secondaryPhotons[i]->organizeParticlesByCell();
5008 a_primaryPhotons[i]->organizeParticlesByCell();
5011 const RealVect probLo = m_amr->getProbLo();
5013 const Vector<Electrode>& electrodes = m_computationalGeometry->getElectrodes();
5014 const Vector<Dielectric>& dielectrics = m_computationalGeometry->getDielectrics();
5016 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
5017 const DisjointBoxLayout& dbl = m_amr->getGrids(m_particleRealm)[lvl];
5018 const DataIterator& dit = dbl.dataIterator();
5019 const EBISLayout& ebisl = m_amr->getEBISLayout(m_particleRealm, m_plasmaPhase)[lvl];
5020 const Real dx = m_amr->getDx()[lvl];
5022 const int nbox = dit.size();
5024#pragma omp parallel for schedule(runtime)
5025 for (
int mybox = 0; mybox < nbox; mybox++) {
5026 const DataIndex& din = dit[mybox];
5033 VoFIterator& vofit = (*m_amr->getVofIterator(m_particleRealm, m_plasmaPhase)[lvl])[din];
5035 if (vofit.size() == 0) {
5039 const EBISBox& ebisbox = ebisl[din];
5040 const EBCellFAB& electricField = (*a_electricField[lvl])[din];
5041 const BaseFab<bool>& validCells = (*m_amr->getValidCells(m_particleRealm)[lvl])[din];
5042 const Box box = dbl[din];
5044 bool isDielectric =
false;
5048 std::vector<std::vector<ParticleSoA<ItoParticle>>> primaryItoCells(numItoSpecies);
5049 std::vector<std::vector<ParticleSoA<ItoParticle>>> secondaryItoCells(numItoSpecies);
5050 std::vector<std::vector<ParticleSoA<Photon>>> primaryPhotonCells(numPhotonSpecies);
5051 std::vector<std::vector<ParticleSoA<Photon>>> secondaryPhotonCells(numPhotonSpecies);
5053 Vector<BaseIVFAB<Real>*> cdrFluxesFAB;
5054 Vector<BaseIVFAB<Real>*> cdrFluxesExtrapFAB;
5056 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
5057 const int idx = it.index();
5059 binLeafToCells(primaryItoCells[idx], (*a_primaryParticles[idx])[lvl][din], box, dx, probLo);
5060 secondaryItoCells[idx].resize(box.numPts());
5063 for (
auto it = m_cdr->iterator(); it.ok(); ++it) {
5064 cdrFluxesFAB.push_back(&((*(a_cdrFluxes[it.index()])[lvl])[din]));
5065 cdrFluxesExtrapFAB.push_back(&((*(a_cdrFluxesExtrap[it.index()])[lvl])[din]));
5068 for (
auto it = m_rte->iterator(); it.ok(); ++it) {
5069 const int idx = it.index();
5071 binLeafToCells(primaryPhotonCells[idx], (*a_primaryPhotons[idx])[lvl][din], box, dx, probLo);
5072 secondaryPhotonCells[idx].resize(box.numPts());
5076 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
5077 const IntVect iv = vof.gridIndex();
5079 if (validCells(iv)) {
5080 const RealVect E = RealVect(D_DECL(electricField(vof, 0), electricField(vof, 1), electricField(vof, 2)));
5081 const RealVect bndryNormal = ebisbox.normal(vof);
5082 const RealVect bndryCentroid = ebisbox.bndryCentroid(vof);
5083 const RealVect cellCentroid = ebisbox.centroid(vof);
5084 const RealVect cellCenter = probLo +
Location::position(Location::Cell::Center, vof, ebisbox, dx);
5085 const RealVect physPos = cellCenter + bndryCentroid * dx;
5086 const Real bndryArea = ebisbox.bndryArea(vof);
5088 const long cellIdx = box.index(iv);
5092 Vector<ParticleSoA<ItoParticle>> secondaryParticles(numItoSpecies);
5093 Vector<ParticleSoA<ItoParticle>> primaryParticles(numItoSpecies);
5095 Vector<Real> cdrFluxes(numCdrSpecies, 0.0);
5096 Vector<Real> cdrFluxesExtrap(numCdrSpecies, 0.0);
5098 Vector<ParticleSoA<Photon>> secondaryPhotons(numPhotonSpecies);
5099 Vector<ParticleSoA<Photon>> primaryPhotons(numPhotonSpecies);
5101 for (
int i = 0; i < numItoSpecies; i++) {
5102 primaryParticles[i] = std::move(primaryItoCells[i][cellIdx]);
5106 for (
int i = 0; i < numCdrSpecies; i++) {
5108 cdrFluxesExtrap[i] = (*cdrFluxesExtrapFAB[i])(vof, 0);
5111 for (
int i = 0; i < numPhotonSpecies; i++) {
5112 primaryPhotons[i] = std::move(primaryPhotonCells[i][cellIdx]);
5117 Real minDist = std::numeric_limits<Real>::max();
5119 for (
int i = 0; i < electrodes.size(); i++) {
5120 const Real curDist = electrodes[i].getImplicitFunction()->value(physPos);
5122 if (std::abs(curDist) < std::abs(minDist)) {
5128 for (
int i = 0; i < dielectrics.size(); i++) {
5129 const Real curDist = dielectrics[i].getImplicitFunction()->value(physPos);
5131 if (std::abs(curDist) < std::abs(minDist)) {
5134 isDielectric =
true;
5139 m_physics->secondaryEmissionEB(secondaryParticles,
5157 for (
int i = 0; i < numItoSpecies; i++) {
5158 secondaryItoCells[i][cellIdx] = std::move(secondaryParticles[i]);
5161 for (
int i = 0; i < numCdrSpecies; i++) {
5162 (*cdrFluxesFAB[i])(vof, 0) = cdrFluxes[i];
5165 for (
int i = 0; i < numPhotonSpecies; i++) {
5166 secondaryPhotonCells[i][cellIdx] = std::move(secondaryPhotons[i]);
5176 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
5177 const int idx = it.index();
5178 rebuildLeafFromCells((*a_secondaryParticles[idx])[lvl][din], secondaryItoCells[idx]);
5180 for (
auto it = m_rte->iterator(); it.ok(); ++it) {
5181 const int idx = it.index();
5182 rebuildLeafFromCells((*a_secondaryPhotons[idx])[lvl][din], secondaryPhotonCells[idx]);
5188 for (
int i = 0; i < numItoSpecies; i++) {
5189 a_secondaryParticles[i]->organizeParticlesByPatch();
5190 a_primaryParticles[i]->organizeParticlesByPatch();
5193 for (
int i = 0; i < numPhotonSpecies; i++) {
5194 a_secondaryPhotons[i]->organizeParticlesByPatch();
5195 a_primaryPhotons[i]->organizeParticlesByPatch();
5199template <
typename I,
typename C,
typename R,
typename F>
5203 CH_TIME(
"ItoKMCStepper::resolveSecondaryEmissionEB(short)");
5204 if (m_verbosity > 5) {
5205 pout() << m_name +
"::resolveSecondaryEmissionEB(short)" << endl;
5208 Vector<ParticleContainer<ItoParticle>*> secondaryParticles;
5209 Vector<ParticleContainer<ItoParticle>*> primaryParticles;
5211 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
5212 const int idx = it.index();
5214 primaryParticles.push_back(&(it()->getParticles(ItoSolver::WhichContainer::EB)));
5215 secondaryParticles.push_back(&(*m_secondaryParticles[idx]));
5219 Vector<EBAMRIVData*> cdrFluxes;
5220 for (
auto it = m_cdr->iterator(); it.ok(); ++it) {
5221 const RefCountedPtr<CdrSolver>& solver = it();
5222 const int idx = it.index();
5224 EBAMRIVData& ebFlux = solver->getEbFlux();
5226 m_amr->copyData(ebFlux, m_cdrFluxes[idx]);
5228 m_amr->arithmeticAverage(ebFlux, m_fluidRealm, m_plasmaPhase);
5230 cdrFluxes.push_back(&ebFlux);
5234 EBAMRIVData& surfaceChargeDensity = m_sigmaSolver->getPhi();
5236 this->resolveSecondaryEmissionEB(secondaryParticles, primaryParticles, cdrFluxes, surfaceChargeDensity, a_dt);
5238 m_sigmaSolver->resetElectrodes(0.0);
5239 m_amr->arithmeticAverage(surfaceChargeDensity, m_fluidRealm, m_plasmaPhase);
5242template <
typename I,
typename C,
typename R,
typename F>
5246 Vector<EBAMRIVData*>& a_cdrFluxes,
5247 EBAMRIVData& a_surfaceChargeDensity,
5248 const Real a_dt)
noexcept
5250 CH_TIME(
"ItoKMCStepper::resolveSecondaryEmissionEB(full)");
5251 if (m_verbosity > 5) {
5252 pout() << m_name +
"::resolveSecondaryEmissionEB(full)" << endl;
5255 const int numItoSpecies = m_physics->getNumItoSpecies();
5256 const int numCdrSpecies = m_physics->getNumCdrSpecies();
5258 CH_assert(a_secondaryParticles.size() == numItoSpecies);
5259 CH_assert(a_primaryParticles.size() == numItoSpecies);
5260 CH_assert(a_cdrFluxes.size() == numCdrSpecies);
5261 CH_assert(a_surfaceChargeDensity.getRealm() == m_fluidRealm);
5263 for (
int i = 0; i < numItoSpecies; i++) {
5264 CH_assert(a_secondaryParticles[i]->getRealm() == m_particleRealm);
5265 CH_assert(a_primaryParticles[i]->getRealm() == m_particleRealm);
5268 for (
int i = 0; i < numCdrSpecies; i++) {
5269 CH_assert(a_secondaryParticles[i]->getRealm() == m_particleRealm);
5270 CH_assert(a_primaryParticles[i]->getRealm() == m_particleRealm);
5274 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
5275 const RefCountedPtr<ItoSolver>& solver = it();
5276 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
5278 const int idx = it.index();
5279 const int Z = species->getChargeNumber();
5284 m_amr->depositParticles(m_particleScratchEB, m_particleRealm, m_plasmaPhase, *a_primaryParticles[idx]);
5286 m_amr->copyData(m_fluidScratchEB, m_particleScratchEB);
5290 m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase));
5293 m_amr->depositParticles(m_particleScratchEB, m_particleRealm, m_plasmaPhase, *a_secondaryParticles[idx]);
5295 m_amr->copyData(m_fluidScratchEB, m_particleScratchEB);
5299 m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase));
5306 a_primaryParticles[idx]->clearParticles();
5308 if (a_secondaryParticles[idx]->getNumberOfValidParticlesGlobal() > 0) {
5309 MayDay::Abort(
"logic bust");
5314 for (
auto it = m_cdr->iterator(); it.ok(); ++it) {
5315 const RefCountedPtr<CdrSolver>& solver = it();
5316 const RefCountedPtr<CdrSpecies>& species = solver->getSpecies();
5318 const int idx = it.index();
5319 const int Z = species->getChargeNumber();
5325 m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase));
5333 m_amr->allocate(divG, m_fluidRealm, m_plasmaPhase, 1);
5334 m_amr->allocate(G, m_fluidRealm, m_plasmaPhase, 1);
5338 solver->computeDivG(divG, G, *a_cdrFluxes[idx],
false);
5340 EBAMRCellData& phi = solver->getPhi();
5343 m_amr->conservativeAverage(phi, m_fluidRealm, m_plasmaPhase);
5344 m_amr->interpGhostPwl(phi, m_fluidRealm, m_plasmaPhase);
5347 DataOps::floor(phi, 0.0, m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase));
5351 m_amr->conservativeAverage(a_surfaceChargeDensity, m_fluidRealm, m_plasmaPhase);
5354template <
typename I,
typename C,
typename R,
typename F>
5358 CH_TIME(
"ItoKMCStepper::computePhysicsDt()");
5359 if (m_verbosity > 5) {
5360 pout() << m_name +
"::computePhysicsDt()" << endl;
5363 Real maxDt = std::numeric_limits<Real>::max();
5364 Real minDt = std::numeric_limits<Real>::max();
5366 DataOps::getMaxMin(maxDt, minDt, m_kmcDt, 0, m_amr->getMultiCutVofIterator(m_fluidRealm, m_plasmaPhase));
5368 m_physicsDt = minDt;
5371template <
typename I,
typename C,
typename R,
typename F>
5375 CH_TIME(
"ItoKMCStepper::computeDummyPhysicsDt()");
5376 if (m_verbosity > 5) {
5377 pout() << m_name +
"::computeDummyPhysicsDt()" << endl;
5380 const int numItoSpecies = m_physics->getNumItoSpecies();
5381 const int numCdrSpecies = m_physics->getNumCdrSpecies();
5382 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
5385 (this->m_ito)->organizeParticlesByCell(ItoSolver::WhichContainer::Bulk);
5386 this->sortPhotonsByCell(McPhoto::WhichContainer::Bulk);
5387 this->sortPhotonsByCell(McPhoto::WhichContainer::Source);
5391 if (numItoSpecies > 0) {
5392 this->computeReactiveItoParticlesPerCell(m_particleItoPPC);
5394 const Interval srcInterv(0, numItoSpecies - 1);
5395 const Interval dstInterv(0, numItoSpecies - 1);
5397 m_amr->copyData(m_fluidPPC, m_particleItoPPC, dstInterv, srcInterv);
5401 if (numCdrSpecies > 0) {
5402 this->computeReactiveCdrParticlesPerCell(m_fluidCdrPPC);
5404 const Interval srcInterv(0, numCdrSpecies - 1);
5405 const Interval dstInterv(numItoSpecies, numItoSpecies + numCdrSpecies - 1);
5407 m_amr->copyData(m_fluidPPC, m_fluidCdrPPC, dstInterv, srcInterv);
5416 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
5417 this->advanceReactionNetwork(*m_fluidPPC[lvl], *m_fluidYPC[lvl], *m_electricFieldFluid[lvl], lvl, 0.0);
5421 (this->m_ito)->organizeParticlesByPatch(ItoSolver::WhichContainer::Bulk);
5422 this->sortPhotonsByPatch(McPhoto::WhichContainer::Bulk);
5423 this->sortPhotonsByPatch(McPhoto::WhichContainer::Source);
5425 this->computePhysicsDt();
5428template <
typename I,
typename C,
typename R,
typename F>
5432 CH_TIME(
"ItoKMCStepper::computeTotalCharge()");
5433 if (m_verbosity > 5) {
5434 pout() << m_name +
"::computeTotalCharge()" << endl;
5437 const bool kappaScale =
true;
5439 Real totalCharge = 0.0;
5441 totalCharge += this->computeQplus();
5442 totalCharge += this->computeQminu();
5443 totalCharge += this->computeQsurf();
5448template <
typename I,
typename C,
typename R,
typename F>
5452 CH_TIME(
"ItoKMCStepper::computeQplus()");
5453 if (m_verbosity > 5) {
5454 pout() << m_name +
"::computeQplus()" << endl;
5457 const bool kappaScale =
true;
5459 Real totalCharge = 0.0;
5462 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
5463 const RefCountedPtr<ItoSolver>& solver = it();
5464 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
5466 const int Z = species->getChargeNumber();
5476 for (
auto it = m_cdr->iterator(); it.ok(); ++it) {
5477 const RefCountedPtr<CdrSolver>& solver = it();
5478 const RefCountedPtr<CdrSpecies>& species = solver->getSpecies();
5480 const int Z = species->getChargeNumber();
5483 const EBAMRCellData& phi = solver->getPhi();
5485 totalCharge += Z * solver->computeMass(phi, kappaScale);
5492template <
typename I,
typename C,
typename R,
typename F>
5496 CH_TIME(
"ItoKMCStepper::computeQminu()");
5497 if (m_verbosity > 5) {
5498 pout() << m_name +
"::computeQminu()" << endl;
5501 const bool kappaScale =
true;
5503 Real totalCharge = 0.0;
5506 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
5507 const RefCountedPtr<ItoSolver>& solver = it();
5508 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
5510 const int Z = species->getChargeNumber();
5520 for (
auto it = m_cdr->iterator(); it.ok(); ++it) {
5521 const RefCountedPtr<CdrSolver>& solver = it();
5522 const RefCountedPtr<CdrSpecies>& species = solver->getSpecies();
5524 const int Z = species->getChargeNumber();
5527 const EBAMRCellData& phi = solver->getPhi();
5529 totalCharge += Z * solver->computeMass(phi, kappaScale);
5536template <
typename I,
typename C,
typename R,
typename F>
5540 CH_TIME(
"ItoKMCStepper::computeQsurf()");
5541 if (m_verbosity > 5) {
5542 pout() << m_name +
"::computeQsurf()" << endl;
5545 return m_sigmaSolver->computeMass();
5548template <
typename I,
typename C,
typename R,
typename F>
5552 CH_TIME(
"ItoKMCStepper::advancePhotons(Real)");
5553 if (m_verbosity > 5) {
5554 pout() << m_name +
"::advancePhotons(Real)" << endl;
5562 for (
auto solverIt = m_rte->iterator(); solverIt.ok(); ++solverIt) {
5563 RefCountedPtr<McPhoto>& solver = solverIt();
5574 solver->clear(bulkPhotons);
5575 solver->clear(ebPhotons);
5576 solver->clear(domainPhotons);
5578 if (solver->isInstantaneous()) {
5579 solver->clear(photons);
5583 solver->clear(sourcePhotons);
5586 solver->advancePhotonsInstantaneous(bulkPhotons, ebPhotons, domainPhotons, photons);
5591 solver->clear(sourcePhotons);
5594 solver->advancePhotonsTransient(bulkPhotons, ebPhotons, domainPhotons, photons, a_dt);
5599template <
typename I,
typename C,
typename R,
typename F>
5603 CH_TIME(
"ItoKMCStepper::sortPhotonsByCell(McPhoto::WhichContainer)");
5604 if (m_verbosity > 5) {
5605 pout() << m_name +
"::sortPhotonsByCell(McPhoto::WhichContainer)" << endl;
5608 for (
auto solverIt = m_rte->iterator(); solverIt.ok(); ++solverIt) {
5609 solverIt()->sortPhotonsByCell(a_which);
5613template <
typename I,
typename C,
typename R,
typename F>
5617 CH_TIME(
"ItoKMCStepper::sortPhotonsByPatch(McPhoto::WhichContainer)");
5618 if (m_verbosity > 5) {
5619 pout() << m_name +
"::sortPhotonsByPatch(McPhoto::WhichContainer)" << endl;
5622 for (
auto solverIt = m_rte->iterator(); solverIt.ok(); ++solverIt) {
5623 solverIt()->sortPhotonsByPatch(a_which);
5627template <
typename I,
typename C,
typename R,
typename F>
5628Vector<RefCountedPtr<ItoSolver>>
5631 CH_TIME(
"ItoKMCStepper::getLoadBalanceSolvers()");
5632 if (m_verbosity > 5) {
5633 pout() << m_name +
"::getLoadBalanceSolvers()" << endl;
5636 Vector<RefCountedPtr<ItoSolver>> lbSolvers;
5639 bool loadBalanceAll =
false;
5640 for (
int i = 0; i < m_loadBalanceIndices.size(); i++) {
5641 if (m_loadBalanceIndices[i] < 0) {
5642 loadBalanceAll =
true;
5646 if (loadBalanceAll) {
5647 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
5648 lbSolvers.push_back(solverIt());
5652 for (
int i = 0; i < m_loadBalanceIndices.size(); i++) {
5653 RefCountedPtr<ItoSolver>& solver = m_ito->getSolvers()[i];
5655 lbSolvers.push_back(solver);
5662template <
typename I,
typename C,
typename R,
typename F>
5666 CH_TIME(
"TimeStepper::loadBalanceThisRealm");
5667 if (m_verbosity > 5) {
5668 pout() <<
"TimeStepper::loadBalanceThisRealm" << endl;
5673 if (a_realm == m_particleRealm && m_loadBalanceParticles) {
5676 else if (a_realm == m_fluidRealm && m_loadBalanceFluid) {
5683template <
typename I,
typename C,
typename R,
typename F>
5686 Vector<Vector<Box>>& a_boxes,
5687 const std::string& a_realm,
5688 const Vector<DisjointBoxLayout>& a_grids,
5690 const int a_finestLevel)
5692 CH_TIME(
"ItoKMCStepper::loadBalanceBoxes");
5693 if (m_verbosity > 5) {
5694 pout() << m_name +
"::loadBalanceBoxes" << endl;
5697 if (m_loadBalanceParticles && a_realm == m_particleRealm) {
5698 this->loadBalanceParticleRealm(a_procs, a_boxes, a_realm, a_grids, a_lmin, a_finestLevel);
5700 else if (m_loadBalanceFluid && a_realm == m_fluidRealm) {
5701 this->loadBalanceFluidRealm(a_procs, a_boxes, a_realm, a_grids, a_lmin, a_finestLevel);
5705template <
typename I,
typename C,
typename R,
typename F>
5708 Vector<Vector<Box>>& a_boxes,
5709 const std::string a_realm,
5710 const Vector<DisjointBoxLayout>& a_grids,
5712 const int a_finestLevel)
noexcept
5714 CH_TIME(
"ItoKMCStepper::loadBalanceParticleRealm(...)");
5715 if (m_verbosity > 5) {
5716 pout() << m_name +
"::loadBalanceParticleRealm(...)" << endl;
5735 if (!m_loadBalanceParticles) {
5736 MayDay::Error(
"ItoKMCStepper::loadBalanceParticleRealm -- logic bust, should not have been called!");
5740 Vector<RefCountedPtr<ItoSolver>> lbSolvers = this->getLoadBalanceSolvers();
5743 a_procs.resize(1 + a_finestLevel);
5744 a_boxes.resize(1 + a_finestLevel);
5746 for (
int lvl = a_lmin; lvl <= a_finestLevel; lvl++) {
5747 a_procs[lvl] = a_grids[lvl].procIDs();
5748 a_boxes[lvl] = a_grids[lvl].boxArray();
5753 EBAMRCellData totalPPC;
5754 EBAMRCellData speciesPPC;
5756 m_amr->allocate(totalPPC, m_particleRealm, m_plasmaPhase, 1);
5757 m_amr->allocate(speciesPPC, m_particleRealm, m_plasmaPhase, 1);
5764 Vector<RefCountedPtr<EBCoarseToFineInterp>> interpOp(1 + a_finestLevel);
5765 for (
int lvl = 1; lvl <= a_finestLevel; lvl++) {
5766 const EBLevelGrid& eblgFine = *m_amr->getEBLevelGrid(m_particleRealm, m_plasmaPhase)[lvl];
5767 const EBLevelGrid& eblgCoFi = *m_amr->getEBLevelGridCoFi(m_particleRealm, m_plasmaPhase)[lvl - 1];
5768 const EBLevelGrid& eblgCoar = *m_amr->getEBLevelGrid(m_particleRealm, m_plasmaPhase)[lvl - 1];
5769 const int refRat = m_amr->getRefinementRatios()[lvl - 1];
5771 interpOp[lvl] = RefCountedPtr<EBCoarseToFineInterp>(
new EBCoarseToFineInterp(eblgFine, eblgCoFi, eblgCoar, refRat));
5776 for (
int i = 0; i < lbSolvers.size(); i++) {
5777 const EBAMRCellData& oldData = m_loadBalancePPC[i];
5778 const int oldFinestLevel = oldData.size() - 1;
5781 for (
int lvl = 0; lvl <= std::max(0, a_lmin - 1); lvl++) {
5782 oldData[lvl]->copyTo(*speciesPPC[lvl]);
5786 for (
int lvl = std::max(1, a_lmin); lvl <= a_finestLevel; lvl++) {
5787 RefCountedPtr<EBCoarseToFineInterp>& interpolator = interpOp[lvl];
5789 interpolator->interpolate(*speciesPPC[lvl],
5790 *speciesPPC[lvl - 1],
5792 EBCoarseToFineInterp::Type::ConservativePWC);
5796 if (lvl <= std::min(oldFinestLevel, a_finestLevel)) {
5797 oldData[lvl]->copyTo(*speciesPPC[lvl]);
5807 Vector<Vector<long int>> loads(1 + a_finestLevel, 0L);
5808 for (
int lvl = 0; lvl <= a_finestLevel; lvl++) {
5809 const DisjointBoxLayout& dbl = a_grids[lvl];
5810 const DataIterator& dit = dbl.dataIterator();
5812 Vector<long int>& levelLoads = loads[lvl];
5814 levelLoads.resize(dbl.size());
5816 const int nbox = dit.size();
5818#pragma omp parallel for schedule(runtime)
5819 for (
int mybox = 0; mybox < nbox; mybox++) {
5820 const DataIndex& din = dit[mybox];
5822 const Box cellBox = dbl[din];
5823 const EBCellFAB& PPC = (*totalPPC[lvl])[din];
5824 const EBISBox& ebisbox = PPC.getEBISBox();
5825 const BaseFab<bool>& validCells = (*m_amr->getValidCells(m_particleRealm)[lvl])[din];
5826 const FArrayBox& regPPC = PPC.getFArrayBox();
5828 auto regularKernel = [&](
const IntVect& iv) ->
void {
5829 if (validCells(iv, 0) && ebisbox.isRegular(iv)) {
5830 levelLoads[din.intCode()] += (
long int)regPPC(iv, 0);
5834 BoxLoops::loop<D_DECL(1, 1, 1)>(cellBox, regularKernel);
5840 for (LayoutIterator lit = dbl.layoutIterator(); lit.ok(); ++lit) {
5841 const Box cellBox = dbl[lit()];
5843 levelLoads[lit().intCode()] += (
long int)m_loadPerCell * cellBox.numPts();
5853 for (
int lvl = 0; lvl <= a_finestLevel; lvl++) {
5858template <
typename I,
typename C,
typename R,
typename F>
5861 Vector<Vector<Box>>& a_boxes,
5862 const std::string a_realm,
5863 const Vector<DisjointBoxLayout>& a_grids,
5865 const int a_finestLevel)
noexcept
5867 CH_TIME(
"ItoKMCStepper::loadBalanceFluidRealm(...)");
5868 if (m_verbosity > 5) {
5869 pout() << m_name +
"::loadBalanceFluidRealm(...)" << endl;
5872 CH_assert(m_loadBalanceFluid);
5873 CH_assert(a_realm == m_fluidRealm);
5881 a_procs.resize(1 + a_finestLevel);
5882 a_boxes.resize(1 + a_finestLevel);
5887 m_amr->regridOperators(m_fluidRealm, a_lmin);
5890 m_fieldSolver->allocate();
5891 m_fieldSolver->setupSolver();
5898 for (
int lvl = 0; lvl <= a_finestLevel; lvl++) {
5899 Vector<long long> boxLoads = m_fieldSolver->computeLoads(a_grids[lvl], lvl);
5902 a_boxes[lvl] = a_grids[lvl].boxArray();
5909template <
typename I,
typename C,
typename R,
typename F>
5913 CH_TIME(
"ItoKMCStepper::getCheckpointLoads(...)");
5914 if (m_verbosity > 5) {
5915 pout() << m_name +
"::getCheckpointLoads(...)" << endl;
5918 const DisjointBoxLayout& dbl = m_amr->getGrids(a_realm)[a_level];
5919 const int nbox = dbl.size();
5921 Vector<long int> loads(nbox, 0L);
5923 if (m_loadBalanceParticles && a_realm == m_particleRealm) {
5928 Vector<RefCountedPtr<ItoSolver>> loadBalanceProxySolvers = this->getLoadBalanceSolvers();
5930 for (
int isolver = 0; isolver < loadBalanceProxySolvers.size(); isolver++) {
5934 Vector<long int> solverLoads(nbox, 0L);
5935 loadBalanceProxySolvers[isolver]->computeLoads(solverLoads, dbl, a_level);
5938 for (
int ibox = 0; ibox < nbox; ibox++) {
5939 loads[ibox] += solverLoads[ibox];
5945 for (LayoutIterator lit = dbl.layoutIterator(); lit.ok(); ++lit) {
5946 const Box box = dbl[lit()];
5948 loads[lit().intCode()] += lround(m_loadPerCell * box.numPts());
5958template <
typename I,
typename C,
typename R,
typename F>
5962 CH_TIME(
"ItoKMCStepper::computeEdotJSource(a_dt)");
5963 if (m_verbosity > 5) {
5964 pout() << m_name +
"::computeEdotJSource(a_dt)" << endl;
5967 CH_assert(a_dt > 0.0);
5971 CH_assert(m_EdotJ.getRealm() == m_fluidRealm);
5992 m_amr->allocate(computationParticles, m_particleRealm);
5996 const EBAMRCellData potentialPhase = m_amr->alias(m_plasmaPhase, m_fieldSolver->getPotential());
5997 m_amr->copyData(m_particleScratch1, potentialPhase);
5999 m_amr->conservativeAverage(m_particleScratch1, m_particleRealm, m_plasmaPhase);
6000 m_amr->interpGhost(m_particleScratch1, m_particleRealm, m_plasmaPhase);
6002 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
6003 RefCountedPtr<ItoSolver>& solver = solverIt();
6004 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
6006 const int idx = solverIt.index();
6007 const int Z = species->getChargeNumber();
6008 const bool mobile = solver->isMobile();
6009 const bool diffusive = solver->isDiffusive();
6011 if (Z != 0 && (mobile || diffusive)) {
6017 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
6018 const DisjointBoxLayout& dbl = m_amr->getGrids(m_particleRealm)[lvl];
6019 const DataIterator& dit = dbl.dataIterator();
6021 const int nbox = dit.size();
6023#pragma omp parallel for schedule(runtime)
6024 for (
int mybox = 0; mybox < nbox; mybox++) {
6025 const DataIndex& din = dit[mybox];
6030 for (std::size_t i = 0; i < leaf.
size(); i++) {
6031 const RealVect posA = RealVect(D_DECL(leaf.template get<&ItoParticle::old_x>(i),
6032 leaf.template get<&ItoParticle::old_y>(i),
6033 leaf.template get<&ItoParticle::old_z>(i)));
6039 D_DECL(payload.
x0_x = posA[0], payload.
x0_y = posA[1], payload.
x0_z = posA[2]);
6051 solver->getDeposition(),
6056 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
6057 const DisjointBoxLayout& dbl = m_amr->getGrids(m_particleRealm)[lvl];
6058 const DataIterator& dit = dbl.dataIterator();
6060 const int nbox = dit.size();
6062#pragma omp parallel for schedule(runtime)
6063 for (
int mybox = 0; mybox < nbox; mybox++) {
6064 const DataIndex& din = dit[mybox];
6068 double*
const pos[SpaceDim] = {
6073 double*
const alt[SpaceDim] = {D_DECL(comp.template column<&ItoKMCFieldParticle::x0_x>(),
6074 comp.template column<&ItoKMCFieldParticle::x0_y>(),
6075 comp.template column<&ItoKMCFieldParticle::x0_z>())};
6078 for (
int dir = 0; dir < SpaceDim; dir++) {
6079 const double posB = pos[dir][i];
6080 pos[dir][i] = alt[dir][i];
6087 computationParticles.remap();
6094 solver->getDeposition(),
6098 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
6099 const DisjointBoxLayout& dbl = m_amr->getGrids(m_particleRealm)[lvl];
6100 const DataIterator& dit = dbl.dataIterator();
6102 const int nbox = dit.
size();
6104#pragma omp parallel for schedule(runtime)
6105 for (
int mybox = 0; mybox < nbox; mybox++) {
6106 const DataIndex& din = dit[mybox];
6110 double*
const pos[SpaceDim] = {
6113 const double*
const alt[SpaceDim] = {D_DECL(comp.template column<&ItoKMCFieldParticle::x0_x>(),
6114 comp.template column<&ItoKMCFieldParticle::x0_y>(),
6115 comp.template column<&ItoKMCFieldParticle::x0_z>())};
6117 const ParticleReal*
const phiA = comp.template column<&ItoKMCFieldParticle::phiA>();
6118 const ParticleReal*
const phiB = comp.template column<&ItoKMCFieldParticle::phiB>();
6121 for (
int dir = 0; dir < SpaceDim; dir++) {
6122 pos[dir][i] = alt[dir][i];
6126 w[i] *= (phiB[i] - phiA[i]);
6131 computationParticles.remap();
6134 m_amr->depositWeight(m_particleScratch1,
6137 computationParticles,
6138 solver->getDeposition(),
6139 solver->getCoarseFineDeposition(),
6143 m_amr->copyData(m_fluidScratch1, m_particleScratch1);
6152template <
typename I,
typename C,
typename R,
typename F>
6156 CH_TIME(
"ItoKMCStepper::computePhysicsPlotVariables");
6157 if (m_verbosity > 5) {
6158 pout() << m_name +
"::computePhysicsPlotVariables" << endl;
6162 const int numVars = m_physics->getNumberOfPlotVariables();
6163 const int numItoSpecies = m_physics->getNumItoSpecies();
6164 const int numCdrSpecies = m_physics->getNumCdrSpecies();
6165 const int numPlasmaSpecies = m_physics->getNumPlasmaSpecies();
6166 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
6168 CH_assert(!(a_physicsPlotVars[0].isNull()));
6169 CH_assert(a_physicsPlotVars[0]->nComp() == numVars);
6170 CH_assert(a_physicsPlotVars.getRealm() == m_fluidRealm);
6173 this->computeDensityGradients();
6175 const RealVect probLo = m_amr->getProbLo();
6177 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
6178 const DisjointBoxLayout& dbl = m_amr->getGrids(m_fluidRealm)[lvl];
6179 const DataIterator& dit = dbl.dataIterator();
6180 const EBISLayout& ebisl = m_amr->getEBISLayout(m_fluidRealm, m_plasmaPhase)[lvl];
6181 const Real dx = m_amr->getDx()[lvl];
6183 const int nbox = dit.size();
6185#pragma omp parallel for schedule(runtime)
6186 for (
int mybox = 0; mybox < nbox; mybox++) {
6187 const DataIndex& din = dit[mybox];
6189 const Box& cellBox = dbl[din];
6190 const EBISBox& ebisBox = ebisl[din];
6193 const EBCellFAB& electricField = (*m_electricFieldFluid[lvl])[din];
6194 const FArrayBox& electricFieldReg = electricField.getFArrayBox();
6197 Vector<const EBCellFAB*> densitiesIto(numItoSpecies);
6198 Vector<const EBCellFAB*> densityGradientsIto(numItoSpecies);
6199 Vector<const FArrayBox*> densitiesItoReg(numItoSpecies);
6200 Vector<const FArrayBox*> densityGradientsItoReg(numItoSpecies);
6202 Vector<const EBCellFAB*> densitiesCDR(numCdrSpecies);
6203 Vector<const EBCellFAB*> densityGradientsCDR(numCdrSpecies);
6204 Vector<const FArrayBox*> densitiesCDRReg(numCdrSpecies);
6205 Vector<const FArrayBox*> densityGradientsCDRReg(numCdrSpecies);
6207 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
6208 const RefCountedPtr<ItoSolver>& solver = it();
6210 const int i = it.index();
6212 densitiesIto[i] = &(*(m_fluidPhiIto[i])[lvl])[din];
6213 densitiesItoReg[i] = &(densitiesIto[i]->getFArrayBox());
6214 densityGradientsIto[i] = &(*m_fluidGradPhiIto[i][lvl])[din];
6215 densityGradientsItoReg[i] = &(densityGradientsIto[i]->getFArrayBox());
6218 for (
auto it = m_cdr->iterator(); it.ok(); ++it) {
6219 const RefCountedPtr<CdrSolver>& solver = it();
6220 const EBAMRCellData& phi = solver->getPhi();
6222 const int i = it.index();
6224 densitiesCDR[i] = &(*phi[lvl])[din];
6225 densitiesCDRReg[i] = &(densitiesCDR[i]->getFArrayBox());
6226 densityGradientsCDR[i] = &(*m_fluidGradPhiCDR[i][lvl])[din];
6227 densityGradientsCDRReg[i] = &(densityGradientsCDR[i]->getFArrayBox());
6231 const BaseFab<bool>& validCells = (*m_amr->getValidCells(m_fluidRealm)[lvl])[din];
6234 EBCellFAB& physicsPlotVars = (*a_physicsPlotVars[lvl])[din];
6235 FArrayBox& physicsPlotVarsReg = physicsPlotVars.getFArrayBox();
6238 Vector<Real> densities(numPlasmaSpecies);
6239 Vector<RealVect> densityGradients(numPlasmaSpecies);
6242 auto regularKernel = [&](
const IntVect& iv) ->
void {
6243 if (ebisBox.isRegular(iv) && validCells(iv, 0)) {
6244 const RealVect pos = probLo + dx * (RealVect(iv) + 0.5 * RealVect::Unit);
6245 const RealVect E = RealVect(
6246 D_DECL(electricFieldReg(iv, 0), electricFieldReg(iv, 1), electricFieldReg(iv, 2)));
6249 for (
int i = 0; i < numItoSpecies; i++) {
6250 densities[i] = (*densitiesItoReg[i])(iv, 0);
6251 densityGradients[i] = RealVect(D_DECL((*densityGradientsItoReg[i])(iv, 0),
6252 (*densityGradientsItoReg[i])(iv, 1),
6253 (*densityGradientsItoReg[i])(iv, 2)));
6256 for (
int i = 0; i < numCdrSpecies; i++) {
6257 densities[numItoSpecies + i] = (*densitiesCDRReg[i])(iv, 0);
6258 densityGradients[numItoSpecies + i] = RealVect(D_DECL((*densityGradientsCDRReg[i])(iv, 0),
6259 (*densityGradientsCDRReg[i])(iv, 1),
6260 (*densityGradientsCDRReg[i])(iv, 2)));
6264 const Vector<Real> plotVars = m_physics->getPlotVariables(E, pos, densities, densityGradients, dx, 1.0);
6266 CH_assert(plotVars.size() == numVars);
6268 for (
int i = 0; i < numVars; i++) {
6269 physicsPlotVarsReg(iv, i) = plotVars[i];
6275 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
6276 if (validCells(vof.gridIndex(), 0)) {
6277 const RealVect pos = probLo + dx * (RealVect(vof.gridIndex()) + 0.5 * RealVect::Unit);
6278 const RealVect E = RealVect(D_DECL(electricField(vof, 0), electricField(vof, 1), electricField(vof, 2)));
6281 for (
int i = 0; i < numItoSpecies; i++) {
6282 densities[i] = (*densitiesIto[i])(vof, 0);
6283 densityGradients[i] = RealVect(D_DECL((*densityGradientsIto[i])(vof, 0),
6284 (*densityGradientsIto[i])(vof, 1),
6285 (*densityGradientsIto[i])(vof, 2)));
6288 for (
int i = 0; i < numCdrSpecies; i++) {
6289 densities[numItoSpecies + i] = (*densitiesCDR[i])(vof, 0);
6290 densityGradients[numItoSpecies + i] = RealVect(D_DECL((*densityGradientsCDR[i])(vof, 0),
6291 (*densityGradientsCDR[i])(vof, 1),
6292 (*densityGradientsCDR[i])(vof, 2)));
6296 const Vector<Real> plotVars = m_physics->getPlotVariables(E, pos, densities, densityGradients, dx, 1.0);
6298 CH_assert(plotVars.size() == numVars);
6300 for (
int i = 0; i < numVars; i++) {
6301 physicsPlotVars(vof, i) = plotVars[i];
6307 VoFIterator& vofit = (*m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase)[lvl])[din];
6309 BoxLoops::loop<D_DECL(1, 1, 1)>(cellBox, regularKernel);
6314 m_amr->average(a_physicsPlotVars, m_fluidRealm, m_plasmaPhase, Average::Arithmetic, Interval(0, numVars - 1));
6315 m_amr->interpGhost(a_physicsPlotVars, m_fluidRealm, m_plasmaPhase);
6318#include <CD_NamespaceFooter.H>
Average
Various averaging methods.
Definition CD_Average.H:25
Agglomeration of useful data operations.
Declaration of an aggregated class for regrid operations.
EBIntersection
Enum for putting some logic into how we think about intersection between particles and EBs.
Definition CD_EBIntersection.H:22
EBRepresentation
Enum for putting some logic into how we think about EBs. This is just a simply supporting class for v...
Definition CD_EBRepresentation.H:23
SoA payload for the transient E-dot-J energy computation in ItoKMCStepper.
SpeciesType
Tag for distinguishing species solved with an Ito diffusion or CDR fluid formalism.
Definition CD_ItoKMCPhysics.H:71
Declaration of the Physics::ItoKMC::ItoKMCStepper abstract TimeStepper.
SpeciesSubset
Enum for selecting a subset of plasma species by mobility/diffusion/charge properties.
Definition CD_ItoKMCStepper.H:43
Declaration of cell positions.
Agglomeration of basic MPI reductions.
Declaration of a namespace for SIMD-decorated loops over SoA particles.
Declaration of a static class containing some common useful particle routines that would otherwise be...
CD_PARTICLE_REAL ParticleReal
Floating-point type a user may use for payload columns.
Definition CD_ParticleSoA.H:156
Implementation of CD_Timer.H.
Declaration of various useful units.
Factory class for CdrLayout. T is (usually) CdrSolver and S is the implementation class (e....
Definition CD_CdrLayout.H:316
RefCountedPtr< CdrLayout< T > > newLayout(const Vector< RefCountedPtr< CdrSpecies > > &a_species) const
Factory method, create a new CdrLayout.
Definition CD_CdrLayoutImplem.H:547
Iterator class for CdrLayout. This allows iteration through solvers (or subsets of solvers).
Definition CD_CdrIterator.H:29
static void scale(MFAMRCellData &a_lhs, const Real &a_scale) noexcept
Scale data by factor.
Definition CD_DataOps.cpp:2503
static void floor(EBAMRCellData &a_lhs, const Real a_value, const Vector< RefCountedPtr< LayoutData< VoFIterator > > > &a_vofIter)
Floor values in data holder. This sets all values below a_value to a_value.
Definition CD_DataOps.cpp:1465
static void getMaxMin(Real &max, Real &min, EBAMRCellData &a_data, const int a_comp, const Vector< RefCountedPtr< LayoutData< VoFIterator > > > &a_vofIter)
Get maximum and minimum value of specified component.
Definition CD_DataOps.cpp:1711
static void volumeScale(EBAMRCellData &a_data, const Vector< Real > &a_dx)
Scale data by dx^SpaceDim.
Definition CD_DataOps.cpp:2236
static void getMaxMinNorm(Real &a_max, Real &a_min, EBAMRCellData &data, const Vector< RefCountedPtr< LayoutData< VoFIterator > > > &a_vofIter)
Get maximum and minimum value of normed data.
Definition CD_DataOps.cpp:1879
static void computeMinValidBox(RealVect &a_lo, RealVect &a_hi, const RealVect &a_normal, const RealVect &a_centroid)
Compute the tightest possible valid box around a cut-cell volume.
Definition CD_DataOps.cpp:3687
static void vectorLength(EBAMRCellData &a_lhs, const EBAMRCellData &a_rhs, const EBAMRCellData &a_notCovered, const Vector< RefCountedPtr< LayoutData< VoFIterator > > > &a_vofIter)
Compute the vector length of a data holder. Sets a_lhs = |a_rhs| where a_rhs contains SpaceDim compon...
Definition CD_DataOps.cpp:3500
static void incr(MFAMRCellData &a_lhs, const MFAMRCellData &a_rhs, const Real a_scale) noexcept
Function which increments data in the form a_lhs = a_lhs + a_rhs*a_scale for all components.
Definition CD_DataOps.cpp:820
static void setValue(LevelData< MFInterfaceFAB< T > > &a_lhs, const T &a_value)
Set value in an MFInterfaceFAB data holder.
Definition CD_DataOpsImplem.H:24
static void divideFallback(EBAMRCellData &a_numerator, const EBAMRCellData &a_denominator, const Real a_fallback, const Vector< RefCountedPtr< LayoutData< VoFIterator > > > &a_vofIter)
Divide data. If the denominator is zero, set the value to a fallback option.
Definition CD_DataOps.cpp:1387
static void setCoveredValue(EBAMRCellData &a_lhs, const EBAMRCellData &a_coveredMask, const int a_comp, const Real a_value)
Set value in covered cells. Does specified component.
Definition CD_DataOps.cpp:2655
static void plus(EBAMRCellData &a_lhs, const EBAMRCellData &a_rhs, const int a_srcComp, const int a_dstComp, const int a_numComp)
General addition operator for adding together data. The user can choose which components to add.
Definition CD_DataOps.cpp:885
static void copy(MFAMRCellData &a_dst, const MFAMRCellData &a_src)
Copy data from one data holder to another.
Definition CD_DataOps.cpp:1201
static void averageCellToFace(EBAMRFluxData &a_faceData, const EBAMRCellData &a_cellData, const Vector< ProblemDomain > &a_domains, Vector< RefCountedPtr< LayoutData< std::array< FaceIterator, SpaceDim > > > > &a_faceIter)
Average all components of the cell-centered data to faces (arithmetic, no tangential ghost faces).
Definition CD_DataOps.cpp:148
static void multiplyScalar(EBAMRCellData &a_lhs, const EBAMRCellData &a_rhs)
Multiply data holder by another data holder.
Definition CD_DataOps.cpp:2341
Class for interpolating data to fine grids. Can use constant interpolation or include limiters.
Definition CD_EBCoarseToFineInterp.H:33
Factory class for making ItoLayout.
Definition CD_ItoLayout.H:412
RefCountedPtr< ItoLayout< T > > newLayout(const Vector< RefCountedPtr< ItoSpecies > > &a_species) const
Factory method which creates a new layout from a set of species. This can do automated casting betwee...
Definition CD_ItoLayoutImplem.H:438
"Iterator" class for going through solvers in an ItoLayout.
Definition CD_ItoIterator.H:26
WhichContainer
Enum class for distinguishing various types of particle containers.
Definition CD_ItoSolver.H:51
static void makeBalance(Vector< int > &a_ranks, const Vector< T > &a_loads, const Vector< Box > &a_boxes)
Load balancing, assigning ranks to boxes.
Definition CD_LoadBalancingImplem.H:36
static void sort(Vector< Vector< Box > > &a_boxes, Vector< Vector< T > > &a_loads, const BoxSorting a_whichSorting)
Sorts boxes and loads over a hierarchy according to some sorting criterion.
Definition CD_LoadBalancingImplem.H:227
Class for holding computational loads.
Definition CD_Loads.H:31
virtual void resetLoads() noexcept
Reset loads. Sets all loads to 0.
Definition CD_Loads.cpp:55
WhichContainer
Enum class for identifying various containers. Only used for interface reasons.
Definition CD_McPhoto.H:42
AMR-hierarchy container of computational particles, stored per patch in Struct-of-Arrays form.
Definition CD_ParticleContainer.H:123
void clearParticles()
Drop all valid particles on every level (keeps each leaf's arena capacity).
Definition CD_ParticleContainer.H:442
void transferParticles(AMRParticlesSoA< P, Traits > &a_source)
Move all particles from another holder (on the same valid grids) into the valid holder.
Definition CD_ParticleContainer.H:804
AMRParticlesSoA< P, Traits > & getParticles()
The valid particles on all levels.
Definition CD_ParticleContainer.H:317
static Real sum(const ParticleContainer< P, Traits > &a_particles) noexcept
Global sum of the container-owned weight column (SoA overload).
Definition CD_ParticleOpsImplem.H:302
static void getComputationalParticlesPerCell(EBAMRCellData &a_ppc, const ParticleContainer< P, Traits > &a_src) noexcept
Get the number of computational particles per cell (SoA overload).
Definition CD_ParticleOpsImplem.H:85
static void getPhysicalParticlesPerCell(EBAMRCellData &a_ppc, const ParticleContainer< P, Traits > &a_src) noexcept
Get the number of physical particles per cell (SoA overload).
Definition CD_ParticleOpsImplem.H:53
Arena-backed Struct-of-Arrays particle container for a single grid patch.
Definition CD_ParticleSoA.H:655
void sortByCell(const Box &a_box, const RealVect &a_dx, const RealVect &a_probLo)
Counting-sort the columns into Fortran cell order and build CSR cell offsets.
Definition CD_ParticleSoAImplem.H:303
void append(const RealVect &a_position, const double a_weight)
Append one particle with a default-constructed payload.
Definition CD_ParticleSoA.H:955
double * weightColumn() noexcept
Raw weight column (double*).
Definition CD_ParticleSoA.H:1160
RealVect position(const std::size_t a_index) const noexcept
Position of particle i as a RealVect (by value, assembled from the scalar columns).
Definition CD_ParticleSoA.H:1188
double & weight(const std::size_t a_index) noexcept
Weight of particle i.
Definition CD_ParticleSoA.H:1222
std::size_t size() const noexcept
Number of particles currently stored.
Definition CD_ParticleSoA.H:882
double * positionColumn(const int a_dir) noexcept
Raw position component column dir (double*, for SIMD kernels).
Definition CD_ParticleSoA.H:1137
std::pair< std::size_t, std::size_t > cellRange(const std::size_t a_cell) const noexcept
Half-open particle index range [begin, end) owned by cell c (valid after sortByCell).
Definition CD_ParticleSoA.H:1539
void reserve(const std::size_t a_capacity)
Ensure capacity for at least a_capacity particles (reallocates + moves on growth).
Definition CD_ParticleSoAImplem.H:88
Abstract TimeStepper for the Ito-KMC-Poisson system of equations.
Definition CD_ItoKMCStepper.H:66
virtual void transferCoveredParticles(const SpeciesSubset a_speciesSubset, const EBRepresentation a_representation, const Real a_tolerance) noexcept
Transfer covered particles (i.e., particles inside the EB) from the ItoSolver bulk container to EB co...
Definition CD_ItoKMCStepperImplem.H:2511
virtual void setupCdr() noexcept
Set up the CDR solvers.
Definition CD_ItoKMCStepperImplem.H:488
virtual void getParticleStatistics(Real &a_avgParticles, Real &a_sigma, Real &a_minParticles, Real &a_maxParticles, int &a_minRank, int &a_maxRank)
Compute some particle statistics.
Definition CD_ItoKMCStepperImplem.H:1436
virtual void computePhysicsPlotVariables(EBAMRCellData &a_physicsPlotVars) noexcept
Compute physics plot variables.
Definition CD_ItoKMCStepperImplem.H:6154
virtual void computePhysicsDt() noexcept
Compute a physics-based maximum time step.
Definition CD_ItoKMCStepperImplem.H:5356
virtual void computeReactiveMeanEnergiesPerCell(EBAMRCellData &a_meanEnergies) noexcept
Compute the mean particle energy in all grid cells.
Definition CD_ItoKMCStepperImplem.H:3788
virtual void parseRuntimeOptions() noexcept override
Parse runtime configurable options.
Definition CD_ItoKMCStepperImplem.H:160
virtual void computeElectricField(EBAMRCellData &a_electricField, const phase::which_phase a_phase) const noexcept
Recompute the electric field onto the specified data holder.
Definition CD_ItoKMCStepperImplem.H:1908
virtual void removeCoveredParticles(const SpeciesSubset a_which, const EBRepresentation a_representation, const Real a_tolerance) noexcept
Remove covered particles (i.e., particles inside the EB)
Definition CD_ItoKMCStepperImplem.H:2392
virtual void setupRadiativeTransfer() noexcept
Set up the radiative transfer solver.
Definition CD_ItoKMCStepperImplem.H:507
virtual void registerRealms() noexcept override
Register realms used for the simulation.
Definition CD_ItoKMCStepperImplem.H:1583
virtual void loadBalanceBoxes(Vector< Vector< int > > &a_procs, Vector< Vector< Box > > &a_boxes, const std::string &a_realm, const Vector< DisjointBoxLayout > &a_grids, const int a_lmin, const int a_finestLevel) override
Load balance grid boxes for a specified realm.
Definition CD_ItoKMCStepperImplem.H:5685
virtual Vector< RefCountedPtr< ItoSolver > > getLoadBalanceSolvers() const noexcept
Get the solvers used for load balancing.
Definition CD_ItoKMCStepperImplem.H:5629
virtual void computeSpaceChargeDensity() noexcept
Compute the space charge. Calls the other version.
Definition CD_ItoKMCStepperImplem.H:1935
virtual void fillNeutralDensity() noexcept
Compute the neutral density on the mesh.
Definition CD_ItoKMCStepperImplem.H:1819
virtual void setVoltage(const std::function< Real(const Real a_time)> &a_voltage) noexcept
Set voltage used for the simulation.
Definition CD_ItoKMCStepperImplem.H:1807
virtual void advanceReactionNetwork(const Real a_dt) noexcept
Chemistry advance over time a_dt.
Definition CD_ItoKMCStepperImplem.H:3929
virtual Real getTime() const noexcept
Get current simulation time.
Definition CD_ItoKMCStepperImplem.H:1923
virtual Vector< long int > getCheckpointLoads(const std::string &a_realm, const int a_level) const override
Get computational loads to be checkpointed.
Definition CD_ItoKMCStepperImplem.H:5911
virtual void computeDummyPhysicsDt() noexcept
Special routine which performs a dummy KMC advance over a zero time step.
Definition CD_ItoKMCStepperImplem.H:5373
virtual int getNumberOfPlotVariables() const noexcept override
Get number of plot variables for the output file.
Definition CD_ItoKMCStepperImplem.H:933
virtual void remapParticles(const SpeciesSubset a_speciesSubset) noexcept
Remap a subset of ItoSolver particles.
Definition CD_ItoKMCStepperImplem.H:2635
virtual void parseVerbosity() noexcept
Parse chattiness.
Definition CD_ItoKMCStepperImplem.H:187
virtual void computeReactiveCdrParticlesPerCell(EBAMRCellData &a_ppc) noexcept
Compute the number of reactive particles per cell for the CDR solvers.
Definition CD_ItoKMCStepperImplem.H:3681
virtual void registerOperators() noexcept override
Register operators used for the simulation.
Definition CD_ItoKMCStepperImplem.H:1597
virtual void loadBalanceParticleRealm(Vector< Vector< int > > &a_procs, Vector< Vector< Box > > &a_boxes, const std::string a_realm, const Vector< DisjointBoxLayout > &a_grids, const int a_lmin, const int a_finestLevel) noexcept
Routine called by loadBalanceBoxes and used for particle-based load balancing.
Definition CD_ItoKMCStepperImplem.H:5707
virtual void averageDiffusionCoefficientsCellToFace() noexcept
Average cell-centered diffusion coefficient to faces.
Definition CD_ItoKMCStepperImplem.H:3491
virtual void parsePlotVariables() noexcept
Parse plot variables.
Definition CD_ItoKMCStepperImplem.H:230
virtual void parseSuperParticles() noexcept
Parse the super-particle merge cadence.
Definition CD_ItoKMCStepperImplem.H:266
virtual void writeData(LevelData< EBCellFAB > &a_output, int &a_comp, const EBAMRCellData &a_data, const std::string a_outputRealm, const int a_level, const bool a_interpToCentroids, const bool a_interpGhost) const noexcept
Write data to output. Convenience function.
Definition CD_ItoKMCStepperImplem.H:1091
virtual void computeDensityGradients() noexcept
Compute grad(phi) and phi for both CDR and Ito species and put the result on the fluid realm.
Definition CD_ItoKMCStepperImplem.H:2074
virtual void computeEdotJSource(const Real a_dt) noexcept
Compute the energy source term for the various plasma species.
Definition CD_ItoKMCStepperImplem.H:5960
virtual bool solvePoisson() noexcept
Solve the electrostatic problem.
Definition CD_ItoKMCStepperImplem.H:2168
virtual Real computeQminu() const noexcept
Compute negative charge.
Definition CD_ItoKMCStepperImplem.H:5494
virtual void multiplyCdrVelocitiesByMobilities() noexcept
Multiply CDR solver velocities by mobilities.
Definition CD_ItoKMCStepperImplem.H:2930
virtual void parseRedistributeCDR() noexcept
Parse CDR mass redistribution when assigning reactive products.
Definition CD_ItoKMCStepperImplem.H:216
virtual void computeCurrentDensity(EBAMRCellData &a_J) noexcept
Compute the current density.
Definition CD_ItoKMCStepperImplem.H:2114
virtual void writeNumberOfParticlesPerPatch(LevelData< EBCellFAB > &a_output, int &a_icomp, const std::string a_outputRealm, const int a_level) const noexcept
Write number of particles per patch to output holder.
Definition CD_ItoKMCStepperImplem.H:1158
virtual void parseTimeStepRestrictions() noexcept
Parse time step restrictions.
Definition CD_ItoKMCStepperImplem.H:359
virtual void fillSecondaryEmissionEB(const Real a_dt) noexcept
Resolve particle injection at EBs.
Definition CD_ItoKMCStepperImplem.H:4897
virtual void initialSigma() noexcept
Fill surface charge solver with initial data taken from the physics interface.
Definition CD_ItoKMCStepperImplem.H:748
virtual void intersectParticles(const SpeciesSubset a_speciesSubset, const bool a_delete, const std::function< void(ParticleSoA< ItoParticle > &, std::size_t)> a_nonDeletionModifier=[](ParticleSoA< ItoParticle > &, std::size_t) -> void { return;}) noexcept
Intersect a subset of the particles with the domain and embedded boundary.
Definition CD_ItoKMCStepperImplem.H:2207
ItoKMCStepper() noexcept
Default constructor. Sets default options.
Definition CD_ItoKMCStepperImplem.H:87
virtual void printStepReport() noexcept override
Print a step report. Used by Driver for user monitoring of simulation.
Definition CD_ItoKMCStepperImplem.H:1223
virtual void depositParticles(const SpeciesSubset a_speciesSubset) noexcept
Deposit a subset of the ItoSolver particles on the mesh.
Definition CD_ItoKMCStepperImplem.H:2750
virtual void setupSigma() noexcept
Set up the surface charge solver.
Definition CD_ItoKMCStepperImplem.H:544
virtual void setupSolvers() noexcept override
Set up solvers.
Definition CD_ItoKMCStepperImplem.H:453
virtual void parseOptions() noexcept
Parse options.
Definition CD_ItoKMCStepperImplem.H:140
virtual void advancePhotons(const Real a_dt) noexcept
Photon advancement routine.
Definition CD_ItoKMCStepperImplem.H:5550
virtual void preRegrid(const int a_lmin, const int a_oldFinestLevel) noexcept override
Perform pre-regrid operations - storing relevant data from the old grids.
Definition CD_ItoKMCStepperImplem.H:1649
virtual void parseDualGrid() noexcept
Parse dual or single realm calculations.
Definition CD_ItoKMCStepperImplem.H:283
virtual void reconcilePhotoionization() noexcept
Reconcile the results from photoionization reactions.
Definition CD_ItoKMCStepperImplem.H:4664
virtual void loadBalanceFluidRealm(Vector< Vector< int > > &a_procs, Vector< Vector< Box > > &a_boxes, const std::string a_realm, const Vector< DisjointBoxLayout > &a_grids, const int a_lmin, const int a_finestLevel) noexcept
Routine called by loadBalanceBoxes and used for particle-based load balancing.
Definition CD_ItoKMCStepperImplem.H:5860
virtual Vector< std::string > getPlotVariableNames() const noexcept override
Get plot variable names.
Definition CD_ItoKMCStepperImplem.H:986
virtual void sortPhotonsByCell(const McPhoto::WhichContainer a_which) noexcept
Sort photons by cells.
Definition CD_ItoKMCStepperImplem.H:5601
virtual Real computeQplus() const noexcept
Compute positive charge.
Definition CD_ItoKMCStepperImplem.H:5450
virtual void parseLoadBalance() noexcept
Parse load balancing.
Definition CD_ItoKMCStepperImplem.H:306
virtual void computeDriftVelocities() noexcept
Compute ItoSolver velocities.
Definition CD_ItoKMCStepperImplem.H:2956
virtual void setupPoisson() noexcept
Set up the electrostatic field solver.
Definition CD_ItoKMCStepperImplem.H:527
virtual void setupIto() noexcept
Set up the Ito particle solvers.
Definition CD_ItoKMCStepperImplem.H:469
virtual Real computeQsurf() const noexcept
Compute surface charge.
Definition CD_ItoKMCStepperImplem.H:5538
virtual Real computeDt() override
Compute a time step used for the advance method.
Definition CD_ItoKMCStepperImplem.H:1468
virtual void synchronizeSolverTimes(const int a_step, const Real a_time, const Real a_dt) noexcept override
Synchronize solver times for all the solvers.
Definition CD_ItoKMCStepperImplem.H:1204
virtual Real computeTotalCharge() const noexcept
Compute total charge.
Definition CD_ItoKMCStepperImplem.H:5430
virtual void resolveSecondaryEmissionEB(const Real a_dt) noexcept
Resolve secondary emission at the EB.
Definition CD_ItoKMCStepperImplem.H:5201
virtual void regrid(const int a_lmin, const int a_oldFinestLevel, const int a_newFinestLevel) noexcept override
Regrid methods – puts all data on the new mesh.
Definition CD_ItoKMCStepperImplem.H:1752
virtual void computeDiffusionCoefficients() noexcept
Compute mesh-based diffusion coefficients for LFA coupling.
Definition CD_ItoKMCStepperImplem.H:3207
virtual void allocateInternals() noexcept
Allocate "internal" storage.
Definition CD_ItoKMCStepperImplem.H:579
virtual bool loadBalanceThisRealm(const std::string &a_realm) const override
Load balancing query for a specified realm. If this returns true for a_realm, load balancing routines...
Definition CD_ItoKMCStepperImplem.H:5664
virtual Real computeMaxReducedElectricField(const phase::which_phase a_phase) const noexcept
Compute the maximum electric field (norm)
Definition CD_ItoKMCStepperImplem.H:1876
virtual void setCdrVelocityFunctions() noexcept
Set the Cdr velocities to be sgn(charge) * E.
Definition CD_ItoKMCStepperImplem.H:2896
virtual void postRegrid() noexcept override
Perform post-regrid operations.
Definition CD_ItoKMCStepperImplem.H:1794
virtual Real computeRelaxationTime() noexcept
Compute the dielectric relaxation time.
Definition CD_ItoKMCStepperImplem.H:2133
virtual void parseParametersEB() noexcept
Parse parameters related to how we treat particle-EB interaction.
Definition CD_ItoKMCStepperImplem.H:437
virtual void initialData() noexcept override
Fill solvers with initial data.
Definition CD_ItoKMCStepperImplem.H:711
virtual void postPlot() noexcept override
Perform post-plot operations.
Definition CD_ItoKMCStepperImplem.H:1637
virtual ~ItoKMCStepper() noexcept
Destructor.
Definition CD_ItoKMCStepperImplem.H:133
virtual void getMaxMinRelativeItoDensity(Real &a_maxDensity, Real &a_minDensity, std::string &a_maxSolver, std::string &a_minSolver) const noexcept
Get maximum density of the Ito species (only for charged species)
Definition CD_ItoKMCStepperImplem.H:1340
virtual void computeReactiveItoParticlesPerCell(EBAMRCellData &a_ppc) noexcept
Compute the number of reactive particles per cell.
Definition CD_ItoKMCStepperImplem.H:3557
virtual void allocate() noexcept override
Allocate storage for solvers.
Definition CD_ItoKMCStepperImplem.H:561
virtual void parseExitOnFailure() noexcept
Parse exit on failure.
Definition CD_ItoKMCStepperImplem.H:202
virtual void reconcileCdrDensities(const EBAMRCellData &a_newParticlesPerCell, const EBAMRCellData &a_oldParticlesPerCell, const Real a_dt) noexcept
Reconcile the CDR densities after the reaction network.
Definition CD_ItoKMCStepperImplem.H:4722
virtual void computeConductivityCell(EBAMRCellData &a_conductivity) noexcept
Compute the cell-centered conductiivty.
Definition CD_ItoKMCStepperImplem.H:2006
void reconcileParticles(const EBAMRCellData &a_newParticlesPerCell, const EBAMRCellData &a_oldParticlesPerCell, const EBAMRCellData &a_newPhotonsPerCell, const EBAMRCellData &a_electricField) const noexcept
Reconcile particles. At the bottom, this will call the physics interface for particle reconciliation.
Definition CD_ItoKMCStepperImplem.H:4307
virtual void postCheckpointPoisson() noexcept
Do some post-checkpoint operations for the electrostatic part.
Definition CD_ItoKMCStepperImplem.H:816
virtual void prePlot() noexcept override
Perform pre-plot operations.
Definition CD_ItoKMCStepperImplem.H:1616
virtual void postInitialize() noexcept override
Post-initialization operations. Default does nothing.
Definition CD_ItoKMCStepperImplem.H:701
virtual void coarsenCDRSolvers() noexcept
Coarsen data for CDR solvers.
Definition CD_ItoKMCStepperImplem.H:4871
virtual void postCheckpointSetup() noexcept override
Perform post-checkpoint operations.
Definition CD_ItoKMCStepperImplem.H:797
virtual void getMaxMinRelativeCDRDensity(Real &a_maxDensity, Real &a_minDensity, std::string &a_maxSolver, std::string &a_minSolver) const noexcept
Get maximum density of the CDR species (only for charged species)
Definition CD_ItoKMCStepperImplem.H:1389
virtual void writePlotData(LevelData< EBCellFAB > &a_output, int &a_icomp, const std::string &a_outputRealm, const int a_level) const noexcept override
Write plot data to output holder.
Definition CD_ItoKMCStepperImplem.H:1037
virtual void computeMobilities() noexcept
Compute mesh-based mobilities for LFA coupling.
Definition CD_ItoKMCStepperImplem.H:2981
virtual void setItoVelocityFunctions() noexcept
Set the Ito velocity functions. This is sgn(charge) * E.
Definition CD_ItoKMCStepperImplem.H:2865
virtual void sortPhotonsByPatch(const McPhoto::WhichContainer a_which) noexcept
Sort photons by patch.
Definition CD_ItoKMCStepperImplem.H:5615
virtual void getPhysicalParticlesPerCell(EBAMRCellData &a_ppc) const noexcept
Get the physical number of particles per cell.
Definition CD_ItoKMCStepperImplem.H:3535
static const std::string Primal
Identifier for perimal realm.
Definition CD_Realm.H:44
Factory class for RtLayout.
Definition CD_RtLayout.H:278
RefCountedPtr< RtLayout< T > > newLayout(const Vector< RefCountedPtr< RtSpecies > > &a_species) const
Get a new Layout. This will cast S to a specific class (T)
Definition CD_RtLayoutImplem.H:458
Iterator class for RtLayout.
Definition CD_RtIterator.H:25
virtual bool ok()
Check if we can cycle further through the solvers.
Definition CD_RtIteratorImplem.H:65
Surface ODE solver.
Definition CD_SurfaceODESolver.H:29
virtual Vector< long int > getCheckpointLoads(const std::string &a_realm, int a_level) const
Get computational loads to be checkpointed.
Definition CD_TimeStepper.cpp:78
Class which is used for run-time monitoring of events.
Definition CD_Timer.H:32
void startEvent(const std::string &a_event) noexcept
Start an event.
Definition CD_TimerImplem.H:60
void eventReport(std::ostream &a_outputStream, const bool a_localReportOnly=false) const noexcept
Print all timed events to cout.
Definition CD_TimerImplem.H:170
void stopEvent(const std::string &a_event) noexcept
Stop an event.
Definition CD_TimerImplem.H:89
ALWAYS_INLINE void loop(const Box &a_computeBox, Functor &&kernel)
Launch a C++ kernel over a regular grid with compile-time per-dimension strides.
Definition CD_BoxLoopsImplem.H:39
std::string numberFmt(long long n, char a_sep=',') noexcept
Number formatting method – writes big numbers using an input separator. E.g. the number 123456 is wri...
Definition CD_DischargeIO.cpp:28
RealVect position(Location::Cell a_location, const VolIndex &a_vof, const EBISBox &a_ebisbox, const Real &a_dx)
Compute the position (ignoring the "origin) of a Vof.
Definition CD_LocationImplem.H:21
std::pair< Real, int > maxRank(const Real &a_val) noexcept
Get the maximum value and the rank having the maximum value.
Definition CD_ParallelOpsImplem.H:294
Real average(const Real &a_val) noexcept
Compute the average (across MPI ranks) of the input value.
Definition CD_ParallelOpsImplem.H:501
Real standardDeviation(const Real &a_value) noexcept
Compute the standard deviation of the input value.
Definition CD_ParallelOpsImplem.H:513
std::pair< Real, int > minRank(const Real &a_val) noexcept
Get the minimum value and the rank having the minimum value.
Definition CD_ParallelOpsImplem.H:324
Real sum(const Real &a_value) noexcept
Compute the sum across all MPI ranks.
Definition CD_ParallelOpsImplem.H:354
ALWAYS_INLINE void loop(const ParticleSoA< P, Traits > &a_soa, Functor &&a_kernel)
Launch a kernel over every particle in a ParticleSoA, decorating the loop with CD_PRAGMA_SIMD.
Definition CD_ParticleLoops.H:87
constexpr Real eps0
Permittivity of free space.
Definition CD_Units.H:30
constexpr Real Qe
Elementary charge.
Definition CD_Units.H:35
constexpr Real c
Speed of light.
Definition CD_Units.H:40
which_phase
Enumeration of supported phases.
Definition CD_MultiFluidIndexSpace.H:38
@ gas
Gas phase.
Definition CD_MultiFluidIndexSpace.H:39
SoA payload for the transient particles used by ItoKMCStepper::computeEdotJSource.
Definition CD_ItoKMCFieldParticle.H:29
ParticleReal phiA
Electrostatic potential at position A.
Definition CD_ItoKMCFieldParticle.H:30
ParticleReal phiB
Electrostatic potential at position B.
Definition CD_ItoKMCFieldParticle.H:31
double x0_z
Alternate (other) position, z-component (double: position-like).
Definition CD_ItoKMCFieldParticle.H:36
double x0_y
Alternate (other) position, y-component (double: position-like).
Definition CD_ItoKMCFieldParticle.H:34
double x0_x
Alternate (other) position, x-component (double: position-like).
Definition CD_ItoKMCFieldParticle.H:33