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]);
66template <
typename P,
typename Traits>
72 const RealVect& a_probLo)
noexcept
74 CH_assert(a_cells.size() ==
static_cast<std::size_t
>(a_box.numPts()));
79 std::vector<std::size_t> cellStart(a_cells.size() + 1, 0);
80 for (std::size_t c = 0; c < a_cells.size(); c++) {
81 cellStart[c + 1] = cellStart[c] + a_cells[c].size();
85 rebuilt.
reserve(cellStart.back());
92 a_leaf.adoptCellSort(a_box, a_dx * RealVect::Unit, a_probLo, std::move(cellStart));
97template <
typename I,
typename C,
typename R,
typename F>
100 CH_TIME(
"ItoKMCStepper::ItoKMCStepper");
104 m_name =
"ItoKMCStepper";
108 m_maxGrowthDt = 1.E99;
109 m_maxShrinkDt = 1.E99;
113 m_redistributeCDR =
true;
114 m_cdrProductInjection = CdrProductInjection::Particle;
117 m_minParticleAdvectionCFL = 0.0;
118 m_maxParticleAdvectionCFL = 1.0;
119 m_minParticleDiffusionCFL = 0.0;
120 m_physicsDtFactor = 1.0;
121 m_maxParticleDiffusionCFL = std::numeric_limits<Real>::max();
122 m_minParticleAdvectionDiffusionCFL = std::numeric_limits<Real>::max();
123 m_maxParticleAdvectionDiffusionCFL = std::numeric_limits<Real>::max();
124 m_fluidAdvectionDiffusionCFL = 0.5;
125 m_relaxTimeFactor = std::numeric_limits<Real>::max();
126 m_minDt = std::numeric_limits<Real>::min();
127 m_maxDt = std::numeric_limits<Real>::max();
128 m_physicsDt = std::numeric_limits<Real>::max();
129 m_maxReducedField = 0.0;
132template <
typename I,
typename C,
typename R,
typename F>
135 CH_TIME(
"ItoKMCStepper::ItoKMCStepper(RefCountrPtr<ItoKMCPhysics>)");
137 m_physics = a_physics;
139 if (m_physics->getNumPlasmaSpecies() == 0) {
140 MayDay::Abort(
"ItoKMCStepper::ItoKMCStepper -- numPlasmaSpecies = 0, there's no problem to solve here!");
144template <
typename I,
typename C,
typename R,
typename F>
147 CH_TIME(
"ItoKMCStepper::~ItoKMCStepper");
150template <
typename I,
typename C,
typename R,
typename F>
154 CH_TIME(
"ItoKMCStepper::parseOptions");
155 if (m_verbosity > 5) {
156 pout() << m_name +
"::parseOptions" << endl;
159 this->parseVerbosity();
160 this->parseExitOnFailure();
161 this->parseRedistributeCDR();
162 this->parseCdrProducts();
163 this->parsePlotVariables();
164 this->parseSuperParticles();
165 this->parseDualGrid();
166 this->parseLoadBalance();
167 this->parseTimeStepRestrictions();
168 this->parseParametersEB();
171template <
typename I,
typename C,
typename R,
typename F>
175 CH_TIME(
"ItoKMCStepper::parseRuntimeOptions");
176 if (m_verbosity > 5) {
177 pout() << m_name +
"::parseRuntimeOptions" << endl;
180 this->parseVerbosity();
181 this->parseExitOnFailure();
182 this->parseRedistributeCDR();
183 this->parseCdrProducts();
184 this->parsePlotVariables();
185 this->parseSuperParticles();
186 this->parseLoadBalance();
187 this->parseTimeStepRestrictions();
188 this->parseParametersEB();
190 m_ito->parseRuntimeOptions();
191 m_cdr->parseRuntimeOptions();
192 m_fieldSolver->parseRuntimeOptions();
193 m_rte->parseRuntimeOptions();
194 m_sigmaSolver->parseRuntimeOptions();
196 m_physics->parseRuntimeOptions();
199template <
typename I,
typename C,
typename R,
typename F>
203 CH_TIME(
"ItoKMCStepper::parseVerbosity");
204 if (m_verbosity > 5) {
205 pout() << m_name +
"::parseVerbosity" << endl;
208 ParmParse pp(m_name.c_str());
210 pp.get(
"verbosity", m_verbosity);
211 pp.get(
"profile", m_profile);
214template <
typename I,
typename C,
typename R,
typename F>
218 CH_TIME(
"ItoKMCStepper::parseExitOnFailure");
219 if (m_verbosity > 5) {
220 pout() << m_name +
"::parseExitOnFailure" << endl;
223 ParmParse pp(m_name.c_str());
225 pp.get(
"abort_on_failure", m_abortOnFailure);
228template <
typename I,
typename C,
typename R,
typename F>
232 CH_TIME(
"ItoKMCStepper::parseRedistributeCDR");
233 if (m_verbosity > 5) {
234 pout() << m_name +
"::parseRedistributeCDR" << endl;
237 ParmParse pp(m_name.c_str());
239 pp.get(
"redistribute_cdr", m_redistributeCDR);
242template <
typename I,
typename C,
typename R,
typename F>
246 CH_TIME(
"ItoKMCStepper::parseCdrProducts");
247 if (m_verbosity > 5) {
248 pout() << m_name +
"::parseCdrProducts" << endl;
251 ParmParse pp(m_name.c_str());
255 pp.get(
"cdr_products", str);
258 m_cdrProductInjection = CdrProductInjection::Mesh;
260 else if (str ==
"particle") {
261 m_cdrProductInjection = CdrProductInjection::Particle;
264 MayDay::Error((
"ItoKMCStepper::parseCdrProducts - unknown '" + m_name +
".cdr_products = " + str +
265 "', must be 'mesh' or 'particle'")
270template <
typename I,
typename C,
typename R,
typename F>
274 CH_TIME(
"ItoKMCStepper::parsePlotVariables");
275 if (m_verbosity > 5) {
276 pout() << m_name +
"::parsePlotVariables" << endl;
279 m_plotConductivity =
false;
280 m_plotCurrentDensity =
false;
281 m_plotParticlesPerPatch =
false;
284 ParmParse pp(m_name.c_str());
285 const int num = pp.countval(
"plt_vars");
288 Vector<std::string> str(num);
289 pp.getarr(
"plt_vars", str, 0, num);
292 for (
int i = 0; i < num; i++) {
293 if (str[i] ==
"conductivity") {
294 m_plotConductivity =
true;
296 else if (str[i] ==
"current_density") {
297 m_plotCurrentDensity =
true;
299 else if (str[i] ==
"particles_per_patch") {
300 m_plotParticlesPerPatch =
true;
306template <
typename I,
typename C,
typename R,
typename F>
310 CH_TIME(
"ItoKMCStepper::parseSuperParticles");
311 if (m_verbosity > 5) {
312 pout() << m_name +
"::parseSuperParticles" << endl;
315 ParmParse pp(m_name.c_str());
320 pp.get(
"merge_interval", m_mergeInterval);
323template <
typename I,
typename C,
typename R,
typename F>
327 CH_TIME(
"ItoKMCStepper::parseDualGrid");
328 if (m_verbosity > 5) {
329 pout() << m_name +
"::parseDualGrid" << endl;
332 ParmParse pp(m_name.c_str());
334 pp.get(
"dual_grid", m_dualGrid);
337 m_particleRealm =
"ParticleRealm";
339 CH_assert(m_particleRealm != m_fluidRealm);
342 m_particleRealm = m_fluidRealm;
346template <
typename I,
typename C,
typename R,
typename F>
350 CH_TIME(
"ItoKMCStepper::parseLoadBalance");
351 if (m_verbosity > 5) {
352 pout() << m_name +
"::parseLoadBalance" << endl;
355 ParmParse pp(m_name.c_str());
359 pp.get(
"load_balance_particles", m_loadBalanceParticles);
360 pp.get(
"load_balance_fluid", m_loadBalanceFluid);
361 pp.get(
"load_per_cell", m_loadPerCell);
364 pp.get(
"box_sorting", str);
366 m_boxSort = BoxSorting::None;
368 else if (str ==
"std") {
369 m_boxSort = BoxSorting::Std;
371 else if (str ==
"shuffle") {
372 m_boxSort = BoxSorting::Shuffle;
374 else if (str ==
"morton") {
375 m_boxSort = BoxSorting::Morton;
377 else if (str ==
"hilbert") {
378 m_boxSort = BoxSorting::Hilbert;
381 const std::string err =
"ItoKMCStepper::parseLoadBalance - 'box_sorting = " + str +
"' not recognized";
383 MayDay::Error(err.c_str());
387 const int numIndices = pp.countval(
"load_indices");
389 if (numIndices > 0) {
390 pp.getarr(
"load_indices", m_loadBalanceIndices, 0, numIndices);
393 const std::string err =
"ItoKMCStepper::parseLoadBalance - 'load_indices' argument has zero entries";
395 MayDay::Error(err.c_str());
399template <
typename I,
typename C,
typename R,
typename F>
403 CH_TIME(
"ItoKMCStepper::parseTimeStepRestrictions");
404 if (m_verbosity > 5) {
405 pout() << m_name +
"::parseTimeStepRestrictions" << endl;
408 ParmParse pp(m_name.c_str());
410 pp.get(
"min_particle_advection_cfl", m_minParticleAdvectionCFL);
411 pp.get(
"max_particle_advection_cfl", m_maxParticleAdvectionCFL);
412 pp.get(
"min_particle_diffusion_cfl", m_minParticleDiffusionCFL);
413 pp.get(
"max_particle_diffusion_cfl", m_maxParticleDiffusionCFL);
414 pp.get(
"min_particle_advection_diffusion_cfl", m_minParticleAdvectionDiffusionCFL);
415 pp.get(
"max_particle_advection_diffusion_cfl", m_maxParticleAdvectionDiffusionCFL);
416 pp.get(
"fluid_advection_diffusion_cfl", m_fluidAdvectionDiffusionCFL);
417 pp.get(
"relax_dt_factor", m_relaxTimeFactor);
418 pp.get(
"min_dt", m_minDt);
419 pp.get(
"max_dt", m_maxDt);
420 pp.get(
"max_growth_dt", m_maxGrowthDt);
421 pp.get(
"max_shrink_dt", m_maxShrinkDt);
422 pp.get(
"physics_dt_factor", m_physicsDtFactor);
424 if (m_maxGrowthDt <= 1.0) {
425 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have max_growth_dt > 1.0");
428 if (m_maxShrinkDt <= 1.0) {
429 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have max_shrink_dt > 1.0");
432 if (m_relaxTimeFactor <= 0.0) {
433 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have relax_dt > 0.0");
437 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have min_dt >= 0.0");
441 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have max_dt >= 0.0");
444 if (m_maxParticleAdvectionCFL <= 0.0) {
445 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have max_particle_advection_cfl > 0.0");
448 if (m_minParticleAdvectionCFL < 0.0) {
449 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have min_particle_advection_cfl >= 0.0");
452 if (m_maxParticleDiffusionCFL <= 0.0) {
453 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have particle_diffusion_cfl > 0.0");
456 if (m_minParticleDiffusionCFL < 0.0) {
457 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have particle_diffusion_cfl >= 0.0");
460 if (m_maxParticleAdvectionDiffusionCFL <= 0.0) {
461 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have particle_advection_diffusion_cfl > 0.0");
464 if (m_minParticleAdvectionDiffusionCFL < 0.0) {
465 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have particle_advection_diffusion_cfl >= 0.0");
468 if (m_fluidAdvectionDiffusionCFL <= 0.0) {
469 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have fluid_advection_diffusion_cfl > 0.0");
472 if (m_physicsDtFactor <= 0.0) {
473 MayDay::Error(
"ItoKMCStepper::parseTimeStepRestrictions() - must have physics_dft_factor > 0.0");
477template <
typename I,
typename C,
typename R,
typename F>
481 CH_TIME(
"ItoKMCStepper::parseTimeStepRestrictions");
482 if (m_verbosity > 5) {
483 pout() << m_name +
"::parseTimeStepRestrictions" << endl;
486 ParmParse pp(m_name.c_str());
490 pp.get(
"eb_tolerance", m_toleranceEB);
493template <
typename I,
typename C,
typename R,
typename F>
497 CH_TIME(
"ItoKMCStepper::setupSolver");
498 if (m_verbosity > 5) {
499 pout() << m_name +
"::setupSolvers" << endl;
504 this->setupPoisson();
505 this->setupRadiativeTransfer();
509template <
typename I,
typename C,
typename R,
typename F>
513 CH_TIME(
"ItoKMCStepper::setupIto");
514 if (m_verbosity > 5) {
515 pout() << m_name +
"::setupIto" << endl;
519 m_ito = factory.
newLayout(m_physics->getItoSpecies());
521 m_ito->parseOptions();
522 m_ito->setAmr(m_amr);
523 m_ito->setPhase(m_plasmaPhase);
524 m_ito->setComputationalGeometry(m_computationalGeometry);
525 m_ito->setRealm(m_particleRealm);
528template <
typename I,
typename C,
typename R,
typename F>
532 CH_TIME(
"ItoKMCStepper::setupCdr");
533 if (m_verbosity > 5) {
534 pout() << m_name +
"::setupCdr" << endl;
538 m_cdr = factory.
newLayout(m_physics->getCdrSpecies());
540 m_cdr->parseOptions();
541 m_cdr->setAmr(m_amr);
542 m_cdr->setPhase(m_plasmaPhase);
543 m_cdr->setComputationalGeometry(m_computationalGeometry);
544 m_cdr->setRealm(m_fluidRealm);
547template <
typename I,
typename C,
typename R,
typename F>
551 CH_TIME(
"ItoKMCStepper::setupRadiativeTransfer");
552 if (m_verbosity > 5) {
553 pout() << m_name +
"::setupRadiativeTransfer" << endl;
557 m_rte = factory.
newLayout(m_physics->getRtSpecies());
559 m_rte->parseOptions();
560 m_rte->setPhase(m_plasmaPhase);
561 m_rte->setAmr(m_amr);
562 m_rte->setComputationalGeometry(m_computationalGeometry);
563 m_rte->setRealm(m_particleRealm);
564 m_rte->sanityCheck();
567template <
typename I,
typename C,
typename R,
typename F>
571 CH_TIME(
"ItoKMCStepper::setupPoisson");
572 if (m_verbosity > 5) {
573 pout() << m_name +
"::setupPoisson" << endl;
576 m_fieldSolver = RefCountedPtr<FieldSolver>(
new F());
577 m_fieldSolver->parseOptions();
578 m_fieldSolver->setAmr(m_amr);
579 m_fieldSolver->setComputationalGeometry(m_computationalGeometry);
580 m_fieldSolver->setVoltage(m_voltage);
581 m_fieldSolver->setRealm(m_fluidRealm);
584template <
typename I,
typename C,
typename R,
typename F>
588 CH_TIME(
"ItoKMCStepper::setupSigma");
589 if (m_verbosity > 5) {
590 pout() << m_name +
"::setupSigma" << endl;
594 m_sigmaSolver->parseOptions();
595 m_sigmaSolver->setRealm(m_fluidRealm);
596 m_sigmaSolver->setPhase(m_plasmaPhase);
597 m_sigmaSolver->setName(
"Surface charge");
598 m_sigmaSolver->setTime(0, 0.0, 0.0);
601template <
typename I,
typename C,
typename R,
typename F>
605 CH_TIME(
"ItoKMCStepper::allocate");
606 if (m_verbosity > 5) {
607 pout() << m_name +
"::allocate" << endl;
613 m_fieldSolver->allocate();
614 m_sigmaSolver->allocate();
616 this->allocateInternals();
619template <
typename I,
typename C,
typename R,
typename F>
623 CH_TIME(
"ItoKMCStepper::allocateInternals");
624 if (m_verbosity > 5) {
625 pout() << m_name +
"::allocateInternals" << endl;
628 const int numItoSpecies = m_physics->getNumItoSpecies();
629 const int numCdrSpecies = m_physics->getNumCdrSpecies();
630 const int numPlasmaSpecies = m_physics->getNumPlasmaSpecies();
631 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
633 CH_assert(numPlasmaSpecies > 0);
636 m_amr->allocate(m_fluidScratch1, m_fluidRealm, m_plasmaPhase, 1);
637 m_amr->allocate(m_fluidScratchD, m_fluidRealm, m_plasmaPhase, SpaceDim);
638 m_amr->allocate(m_fluidScratchEB, m_fluidRealm, m_plasmaPhase, 1);
640 m_amr->allocate(m_particleScratch1, m_particleRealm, m_plasmaPhase, 1);
641 m_amr->allocate(m_particleScratchD, m_particleRealm, m_plasmaPhase, SpaceDim);
642 m_amr->allocate(m_particleScratchEB, m_particleRealm, m_plasmaPhase, 1);
645 m_amr->allocate(m_neutralDensity, m_fluidRealm, m_plasmaPhase, 1);
648 m_amr->allocate(m_conductivityCell, m_fluidRealm, m_plasmaPhase, 1);
649 m_amr->allocate(m_conductivityFace, m_fluidRealm, m_plasmaPhase, 1);
650 m_amr->allocate(m_conductivityEB, m_fluidRealm, m_plasmaPhase, 1);
653 m_amr->allocate(m_electricFieldParticle, m_particleRealm, m_plasmaPhase, SpaceDim);
654 m_amr->allocate(m_electricFieldFluid, m_fluidRealm, m_plasmaPhase, SpaceDim);
657 m_cdrMobilities.resize(numCdrSpecies);
658 m_cdrProducts.resize(numCdrSpecies);
659 for (
int i = 0; i < numCdrSpecies; i++) {
660 m_amr->allocate(m_cdrMobilities[i], m_fluidRealm, m_plasmaPhase, 1);
663 m_amr->allocate(*m_cdrProducts[i], m_particleRealm);
667 m_fluidScratchIto.resize(numItoSpecies);
668 for (
int i = 0; i < numItoSpecies; i++) {
669 m_amr->allocate(m_fluidScratchIto[i], m_fluidRealm, m_plasmaPhase, 1);
673 m_fluidGradPhiIto.resize(numItoSpecies);
674 m_fluidPhiIto.resize(numItoSpecies);
675 m_fluidGradPhiCDR.resize(numCdrSpecies);
676 for (
int i = 0; i < numItoSpecies; i++) {
677 m_amr->allocate(m_fluidGradPhiIto[i], m_fluidRealm, m_plasmaPhase, SpaceDim);
678 m_amr->allocate(m_fluidPhiIto[i], m_fluidRealm, m_plasmaPhase, 1);
680 for (
int i = 0; i < numCdrSpecies; i++) {
681 m_amr->allocate(m_fluidGradPhiCDR[i], m_fluidRealm, m_plasmaPhase, SpaceDim);
685 m_secondaryParticles.resize(numItoSpecies);
686 m_secondaryPhotons.resize(numPhotonSpecies);
688 m_cdrFluxes.resize(numCdrSpecies);
689 m_cdrFluxesExtrap.resize(numCdrSpecies);
691 for (
int i = 0; i < numItoSpecies; i++) {
693 m_amr->allocate(*m_secondaryParticles[i], m_particleRealm);
696 for (
int i = 0; i < numPhotonSpecies; i++) {
698 m_amr->allocate(*m_secondaryPhotons[i], m_particleRealm);
701 for (
int i = 0; i < numCdrSpecies; i++) {
702 m_amr->allocate(m_cdrFluxes[i], m_particleRealm, m_plasmaPhase, 1);
703 m_amr->allocate(m_cdrFluxesExtrap[i], m_particleRealm, m_plasmaPhase, 1);
707 m_amr->allocate(m_currentDensity, m_fluidRealm, m_plasmaPhase, SpaceDim);
710 m_amr->allocate(m_kmcDt, m_fluidRealm, m_plasmaPhase, 1);
713 m_amr->allocate(m_fluidPPC, m_fluidRealm, m_plasmaPhase, numPlasmaSpecies);
715 if (numItoSpecies > 0) {
716 m_amr->allocate(m_particleItoPPC, m_particleRealm, m_plasmaPhase, numItoSpecies);
717 m_amr->allocate(m_particleOldItoPPC, m_particleRealm, m_plasmaPhase, numItoSpecies);
721 m_amr->allocate(m_particleItoPPC, m_particleRealm, m_plasmaPhase, 1);
722 m_amr->allocate(m_particleOldItoPPC, m_particleRealm, m_plasmaPhase, 1);
725 if (numCdrSpecies > 0) {
726 m_amr->allocate(m_fluidCdrPPC, m_fluidRealm, m_plasmaPhase, numCdrSpecies);
727 m_amr->allocate(m_fluidOldCdrPPC, m_fluidRealm, m_plasmaPhase, numCdrSpecies);
728 m_amr->allocate(m_particleCdrProduction, m_particleRealm, m_plasmaPhase, numCdrSpecies);
731 m_amr->allocatePointer(m_fluidCdrPPC, m_fluidRealm);
732 m_amr->allocatePointer(m_fluidOldCdrPPC, m_fluidRealm);
735 m_amr->allocate(m_particleCdrProduction, m_particleRealm, m_plasmaPhase, 1);
738 if (numPhotonSpecies > 0) {
739 m_amr->allocate(m_particleYPC, m_particleRealm, m_plasmaPhase, numPhotonSpecies);
740 m_amr->allocate(m_fluidYPC, m_fluidRealm, m_plasmaPhase, numPhotonSpecies);
744 m_amr->allocate(m_particleYPC, m_particleRealm, m_plasmaPhase, 1);
745 m_amr->allocate(m_fluidYPC, m_fluidRealm, m_plasmaPhase, 1);
751template <
typename I,
typename C,
typename R,
typename F>
755 CH_TIME(
"ItoKMCStepper::postInitialize");
756 if (m_verbosity > 5) {
757 pout() << m_name +
"::postInitialize" << endl;
761template <
typename I,
typename C,
typename R,
typename F>
765 CH_TIME(
"ItoKMCStepper::initialData");
766 if (m_verbosity > 5) {
767 pout() << m_name +
"::initialData" << endl;
770 CH_assert(!(m_cdr.isNull()));
771 CH_assert(!(m_ito.isNull()));
772 CH_assert(!(m_rte.isNull()));
773 CH_assert(!(m_sigmaSolver.isNull()));
774 CH_assert(!(m_fieldSolver.isNull()));
776 m_ito->initialData();
777 m_cdr->initialData();
778 m_rte->initialData();
779 this->initialSigma();
783 m_ito->makeSuperparticles(ItoSolver::WhichContainer::Bulk);
786 m_fieldSolver->setPermittivities();
787 this->computeSpaceChargeDensity();
788 this->solvePoisson();
791 this->computeDriftVelocities();
792 this->computeDiffusionCoefficients();
795 this->fillNeutralDensity();
798template <
typename I,
typename C,
typename R,
typename F>
802 CH_TIME(
"ItoKMCStepper::initialSigma");
803 if (m_verbosity > 5) {
804 pout() << m_name +
"::initialSigma" << endl;
807 const RealVect probLo = m_amr->getProbLo();
809 EBAMRIVData& sigma = m_sigmaSolver->getPhi();
811 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
812 const DisjointBoxLayout& dbl = m_amr->getGrids(m_sigmaSolver->getRealm())[lvl];
813 const DataIterator& dit = dbl.dataIterator();
814 const EBISLayout& ebisl = m_amr->getEBISLayout(m_sigmaSolver->getRealm(), m_sigmaSolver->getPhase())[lvl];
815 const Real dx = m_amr->getDx()[lvl];
817 const int nbox = dit.size();
819#pragma omp parallel for schedule(runtime)
820 for (
int mybox = 0; mybox < nbox; mybox++) {
821 const DataIndex& din = dit[mybox];
823 BaseIVFAB<Real>& phi = (*sigma[lvl])[din];
824 const EBISBox& ebisbox = ebisl[din];
826 CH_assert(phi.nComp() == 1);
828 auto kernel = [&](
const VolIndex& vof) ->
void {
829 const RealVect pos = probLo +
Location::position(Location::Cell::Boundary, vof, ebisbox, dx);
831 phi(vof, 0) = m_physics->initialSigma(m_time, pos);
834 VoFIterator& vofit = (*m_amr->getVofIterator(m_sigmaSolver->getRealm(), m_sigmaSolver->getPhase())[lvl])[din];
841 m_amr->conservativeAverage(sigma, m_fluidRealm, m_sigmaSolver->getPhase());
844 m_sigmaSolver->resetElectrodes(sigma, 0.0);
847template <
typename I,
typename C,
typename R,
typename F>
851 CH_TIME(
"ItoKMCStepper::postCheckpointSetup");
852 if (m_verbosity > 5) {
853 pout() << m_name +
"::postCheckpointSetup" << endl;
859 this->postCheckpointPoisson();
862 this->computeDriftVelocities();
863 this->computeDiffusionCoefficients();
866template <
typename I,
typename C,
typename R,
typename F>
870 CH_TIME(
"ItoKMCStepper::postCheckpointPoisson");
871 if (m_verbosity > 5) {
872 pout() << m_name +
"::postCheckpointPoisson" << endl;
876 m_fieldSolver->postCheckpoint();
879 MFAMRCellData& potential = m_fieldSolver->getPotential();
881 m_amr->conservativeAverage(potential, m_fluidRealm);
882 m_amr->interpGhostMG(potential, m_fluidRealm);
884 m_fieldSolver->computeElectricField();
887 const EBAMRCellData E = m_amr->alias(m_plasmaPhase, m_fieldSolver->getElectricField());
890 m_amr->copyData(m_electricFieldFluid, E);
891 m_amr->conservativeAverage(m_electricFieldFluid, m_fluidRealm, m_plasmaPhase);
892 m_amr->interpGhostPwl(m_electricFieldFluid, m_fluidRealm, m_plasmaPhase);
893 m_amr->interpToCentroids(m_electricFieldFluid, m_fluidRealm, m_plasmaPhase);
896 m_amr->copyData(m_electricFieldParticle, E);
897 m_amr->conservativeAverage(m_electricFieldParticle, m_particleRealm, m_plasmaPhase);
898 m_amr->interpGhostPwl(m_electricFieldParticle, m_particleRealm, m_plasmaPhase);
899 m_amr->interpToCentroids(m_electricFieldParticle, m_particleRealm, m_plasmaPhase);
902 m_fieldSolver->setupSolver();
906template <
typename I,
typename C,
typename R,
typename F>
910 CH_TIME(
"ItoKMCStepper::writeCheckpointHeader");
911 if (m_verbosity > 5) {
912 pout() << m_name +
"::writeCheckpointHeader" << endl;
918template <
typename I,
typename C,
typename R,
typename F>
922 CH_TIME(
"ItoKMCStepper::readCheckpointHeader");
923 if (m_verbosity > 5) {
924 pout() << m_name +
"::readCheckpointHeader" << endl;
930template <
typename I,
typename C,
typename R,
typename F>
934 CH_TIME(
"ItoKMCStepper::writeCheckpointData");
935 if (m_verbosity > 5) {
936 pout() << m_name +
"::writeCheckpointData" << endl;
940 solverIt()->writeCheckpointLevel(a_handle, a_lvl);
944 solverIt()->writeCheckpointLevel(a_handle, a_lvl);
948 solverIt()->writeCheckpointLevel(a_handle, a_lvl);
951 m_fieldSolver->writeCheckpointLevel(a_handle, a_lvl);
952 m_sigmaSolver->writeCheckpointLevel(a_handle, a_lvl);
957template <
typename I,
typename C,
typename R,
typename F>
961 CH_TIME(
"ItoKMCStepper::readCheckpointData");
962 if (m_verbosity > 5) {
963 pout() << m_name +
"::readCheckpointData" << endl;
967 solverIt()->readCheckpointLevel(a_handle, a_lvl);
971 solverIt()->readCheckpointLevel(a_handle, a_lvl);
975 solverIt()->readCheckpointLevel(a_handle, a_lvl);
978 m_fieldSolver->readCheckpointLevel(a_handle, a_lvl);
979 m_sigmaSolver->readCheckpointLevel(a_handle, a_lvl);
983template <
typename I,
typename C,
typename R,
typename F>
987 CH_TIME(
"ItoKMCStepper::getNumberOfPlotVariables");
988 if (m_verbosity > 5) {
989 pout() << m_name +
"::getNumberOfPlotVariables" << endl;
996 numComp += solverIt()->getNumberOfPlotVariables();
1000 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
1001 numComp += solverIt()->getNumberOfPlotVariables();
1006 numComp += solverIt()->getNumberOfPlotVariables();
1010 numComp += m_fieldSolver->getNumberOfPlotVariables();
1013 numComp += m_sigmaSolver->getNumberOfPlotVariables();
1016 if (m_plotConductivity) {
1021 if (m_plotCurrentDensity) {
1022 numComp += SpaceDim;
1026 if (m_plotParticlesPerPatch) {
1031 numComp += m_physics->getNumberOfPlotVariables();
1036template <
typename I,
typename C,
typename R,
typename F>
1040 CH_TIME(
"ItoKMCStepper::getPlotVariableNames");
1041 if (m_verbosity > 5) {
1042 pout() << m_name +
"::getPlotVariableNames" << endl;
1045 Vector<std::string> plotVarNames;
1047 plotVarNames.append(m_fieldSolver->getPlotVariableNames());
1048 plotVarNames.append(m_sigmaSolver->getPlotVariableNames());
1051 plotVarNames.append(solverIt()->getPlotVariableNames());
1054 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
1055 plotVarNames.append(solverIt()->getPlotVariableNames());
1059 plotVarNames.append(solverIt()->getPlotVariableNames());
1063 if (m_plotConductivity) {
1064 plotVarNames.push_back(
"Conductivity");
1068 if (m_plotCurrentDensity) {
1069 plotVarNames.push_back(
"x-J");
1070 plotVarNames.push_back(
"y-J");
1071 if (SpaceDim == 3) {
1072 plotVarNames.push_back(
"z-J");
1077 if (m_plotParticlesPerPatch) {
1078 plotVarNames.push_back(
"Particles per patch");
1082 plotVarNames.append(m_physics->getPlotVariableNames());
1084 return plotVarNames;
1087template <
typename I,
typename C,
typename R,
typename F>
1091 const std::string& a_outputRealm,
1092 const int a_level)
const noexcept
1094 CH_TIME(
"ItoKMCStepper::writePlotData");
1095 if (m_verbosity > 5) {
1096 pout() << m_name +
"::writePlotData" << endl;
1100 m_fieldSolver->writePlotData(a_output, a_icomp, a_outputRealm, a_level);
1103 m_sigmaSolver->writePlotData(a_output, a_icomp, a_outputRealm, a_level);
1107 solverIt()->writePlotData(a_output, a_icomp, a_outputRealm, a_level);
1111 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
1112 solverIt()->writePlotData(a_output, a_icomp, a_outputRealm, a_level);
1117 solverIt()->writePlotData(a_output, a_icomp, a_outputRealm, a_level);
1121 if (m_plotConductivity) {
1122 this->writeData(a_output, a_icomp, m_conductivityCell, a_outputRealm, a_level,
false,
true);
1126 if (m_plotCurrentDensity) {
1127 this->writeData(a_output, a_icomp, m_currentDensity, a_outputRealm, a_level,
false,
true);
1131 if (m_plotParticlesPerPatch) {
1132 this->writeNumberOfParticlesPerPatch(a_output, a_icomp, a_outputRealm, a_level);
1136 if (m_physics->getNumberOfPlotVariables() > 0) {
1137 this->writeData(a_output, a_icomp, m_physicsPlotVariables, a_outputRealm, a_level,
false,
true);
1141template <
typename I,
typename C,
typename R,
typename F>
1145 const EBAMRCellData& a_data,
1146 const std::string a_outputRealm,
1148 const bool a_interpToCentroids,
1149 const bool a_interpGhost)
const noexcept
1152 CH_TIMERS(
"ItoKMCStepper::writeData");
1153 CH_TIMER(
"ItoKMCStepper::writeData::allocate", t1);
1154 CH_TIMER(
"ItoKMCStepper::writeData::local_copy", t2);
1155 CH_TIMER(
"ItoKMCStepper::writeData::interp_ghost", t3);
1156 CH_TIMER(
"ItoKMCStepper::writeData::interp_centroid", t4);
1157 CH_TIMER(
"ItoKMCStepper::writeData::final_copy", t5);
1158 if (m_verbosity > 5) {
1159 pout() << m_name +
"::writeData" << endl;
1163 const int numComp = a_data[a_level]->nComp();
1166 const Interval srcInterv(0, numComp - 1);
1167 const Interval dstInterv(a_comp, a_comp + numComp - 1);
1170 LevelData<EBCellFAB> scratch;
1171 m_amr->allocate(scratch, a_data.getRealm(), m_plasmaPhase, a_level, numComp);
1175 m_amr->copyData(scratch, *a_data[a_level], a_level, a_data.getRealm(), a_data.getRealm());
1180 if (a_level > 0 && a_interpGhost) {
1181 m_amr->interpGhost(scratch, *a_data[a_level - 1], a_level, a_data.getRealm(), m_plasmaPhase);
1186 if (a_interpToCentroids) {
1187 m_amr->interpToCentroids(scratch, a_data.getRealm(), m_plasmaPhase, a_level);
1194 m_amr->copyData(a_output,
1201 CopyStrategy::ValidGhost,
1202 CopyStrategy::ValidGhost);
1208template <
typename I,
typename C,
typename R,
typename F>
1212 const std::string a_outputRealm,
1213 const int a_level)
const noexcept
1215 CH_TIME(
"ItoKMCStepper::writeNumberOfParticlesPerPatch");
1216 if (m_verbosity > 5) {
1217 pout() << m_name +
"::writeNumberOfParticlesPerPatch" << endl;
1220 CH_assert(a_level >= 0);
1221 CH_assert(a_level <= m_amr->getFinestLevel());
1225 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
1228 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
1229 const DisjointBoxLayout& dbl = m_amr->getGrids(m_particleRealm)[lvl];
1230 const DataIterator& dit = dbl.dataIterator();
1232 const int nbox = dit.size();
1234#pragma omp parallel for schedule(runtime)
1235 for (
int mybox = 0; mybox < nbox; mybox++) {
1236 const DataIndex& din = dit[mybox];
1238 (*m_particleScratch1[lvl])[din] += particles[lvl][din].size();
1243 m_amr->copyData(a_output,
1244 *m_particleScratch1[a_level],
1248 Interval(a_icomp, a_icomp),
1254template <
typename I,
typename C,
typename R,
typename F>
1258 CH_TIME(
"ItoKMCStepper::synchronizeSolverTimes");
1259 if (m_verbosity > 5) {
1260 pout() << m_name +
"::synchronizeSolverTimes" << endl;
1263 m_timeStep = a_step;
1267 m_ito->setTime(a_step, a_time, a_dt);
1268 m_fieldSolver->setTime(a_step, a_time, a_dt);
1269 m_rte->setTime(a_step, a_time, a_dt);
1270 m_sigmaSolver->setTime(a_step, a_time, a_dt);
1273template <
typename I,
typename C,
typename R,
typename F>
1277 CH_TIME(
"ItoKMCStepper::printStepReport");
1278 if (m_verbosity > 5) {
1279 pout() << m_name +
"::printStepReport" << endl;
1282 const unsigned long long localParticlesBulk = m_ito->getNumParticles(ItoSolver::WhichContainer::Bulk,
true);
1283 const unsigned long long globalParticlesBulk = m_ito->getNumParticles(ItoSolver::WhichContainer::Bulk,
false);
1284 const unsigned long long localParticlesEB = m_ito->getNumParticles(ItoSolver::WhichContainer::EB,
true);
1285 const unsigned long long globalParticlesEB = m_ito->getNumParticles(ItoSolver::WhichContainer::EB,
false);
1286 const unsigned long long localParticlesDomain = m_ito->getNumParticles(ItoSolver::WhichContainer::Domain,
true);
1287 const unsigned long long globalParticlesDomain = m_ito->getNumParticles(ItoSolver::WhichContainer::Domain,
false);
1288 const unsigned long long localParticlesSource = m_ito->getNumParticles(ItoSolver::WhichContainer::Source,
true);
1289 const unsigned long long globalParticlesSource = m_ito->getNumParticles(ItoSolver::WhichContainer::Source,
false);
1291 Real avgParticles = 0.0;
1294 Real minParticles = 0.0;
1295 Real maxParticles = 0.0;
1300 this->getParticleStatistics(avgParticles, stdDev, minParticles, maxParticles, minRank, maxRank);
1302 Real maxDensity = -std::numeric_limits<Real>::max();
1303 Real minDensity = +std::numeric_limits<Real>::max();
1305 std::string maxSolver =
"invalid solver";
1306 std::string minSolver =
"invalid solver";
1308 this->getMaxMinRelativeItoDensity(maxDensity, minDensity, maxSolver, minSolver);
1309 this->getMaxMinRelativeCDRDensity(maxDensity, minDensity, maxSolver, minSolver);
1312 switch (m_timeCode) {
1313 case TimeCode::Physics: {
1314 str =
"dt restricted by 'Physics'";
1318 case TimeCode::AdvectionIto: {
1319 str =
"dt restricted by 'Advection (Ito)'";
1323 case TimeCode::DiffusionIto: {
1324 str =
"dt restricted by 'Diffusion (Ito)'";
1328 case TimeCode::AdvectionDiffusionIto: {
1329 str =
"dt restricted by 'AdvectionDiffusion (Ito)'";
1333 case TimeCode::AdvectionDiffusionCDR: {
1334 str =
"dt restricted by 'AdvectionDiffusion (CDR)'";
1338 case TimeCode::RelaxationTime: {
1339 str =
"dt restricted by 'Relaxation time'";
1343 case TimeCode::Hardcap: {
1344 str =
"dt restricted by 'Hardcap'";
1349 str =
"dt restricted by 'Unspecified'";
1356 const Real Qplus = this->computeQplus();
1357 const Real Qminu = this->computeQminu();
1358 const Real Qsurf = this->computeQsurf();
1359 const Real Qtot = Qplus + Qminu + Qsurf;
1364 const std::string whitespace =
" ";
1365 pout() <<
" " + str << endl;
1366 pout() << whitespace +
"Emax = " << m_maxReducedField <<
" (Td)" << endl
1367 << whitespace +
"Max n/N = " << maxDensity <<
" (" << maxSolver <<
")" << endl
1368 << whitespace +
"Qplus = " << Qplus << endl
1369 << whitespace +
"Qminu = " << Qminu << endl
1370 << whitespace +
"Qsurf = " << Qsurf << endl
1371 << whitespace +
"Qtot = " << Qtot << endl
1372 << whitespace +
"CFL (Ito) = " << m_dt / m_particleAdvectionDiffusionDt << endl
1373 << whitespace +
"CFL (CDR) = " << m_dt / m_fluidAdvectionDiffusionDt << endl
1374 << whitespace +
"dt/dt_relax = " << m_dt / m_relaxationTime << endl
1383 << whitespace +
"#Min part. = " << minParticles <<
" (on rank = " << minRank <<
")" << endl
1384 << whitespace +
"#Max part. = " << maxParticles <<
" (on rank = " << maxRank <<
")" << endl
1385 << whitespace +
"#Avg. part. = " << avgParticles << endl
1386 << whitespace +
"#Dev. part. = " << stdDev <<
" (" << 100. * stdDev / avgParticles <<
"%)" << endl;
1390template <
typename I,
typename C,
typename R,
typename F>
1394 std::string& a_maxSolver,
1395 std::string& a_minSolver)
const noexcept
1397 CH_TIME(
"ItoKMCStepper::getMaxMinDensity(Realx2, std::string2x)");
1398 if (m_verbosity > 5) {
1399 pout() << m_name +
"::getMaxMinDensity(Realx2, std::string2x)" << endl;
1403 EBAMRCellData& tmp = m_fluidScratch1;
1406 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
1407 const RefCountedPtr<ItoSolver>& solver = solverIt();
1408 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
1409 const int Z = species->getChargeNumber();
1412 Real curMin = std::numeric_limits<Real>::max();
1413 Real curMax = -std::numeric_limits<Real>::max();
1417 const Interval dstInterv = Interval(0, 0);
1418 const Interval srcInterv = Interval(0, 0);
1420 m_amr->copyData(tmp, solverIt()->getPhi(), dstInterv, srcInterv);
1422 DataOps::divideFallback(tmp, m_neutralDensity, 0.0, m_amr->getMultiCutVofIterator(m_fluidRealm, m_plasmaPhase));
1425 if (curMax > a_maxDensity) {
1426 a_maxDensity = curMax;
1427 a_maxSolver = solver->getName();
1430 if (curMin < a_minDensity) {
1431 a_minDensity = curMin;
1432 a_minSolver = solver->getName();
1438template <
typename I,
typename C,
typename R,
typename F>
1442 std::string& a_maxSolver,
1443 std::string& a_minSolver)
const noexcept
1445 CH_TIME(
"ItoKMCStepper::getMaxMinRelativeCDRDensity(Realx2, std::string2x)");
1446 if (m_verbosity > 5) {
1447 pout() << m_name +
"::getMaxMinRelativeCDRDensity(Realx2, std::string2x)" << endl;
1451 EBAMRCellData& tmp = m_fluidScratch1;
1454 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
1455 const RefCountedPtr<CdrSolver>& solver = solverIt();
1456 const RefCountedPtr<CdrSpecies>& species = solver->getSpecies();
1457 const int Z = species->getChargeNumber();
1460 Real curMin = std::numeric_limits<Real>::max();
1461 Real curMax = -std::numeric_limits<Real>::max();
1464 const Interval dstInterv = Interval(0, 0);
1465 const Interval srcInterv = Interval(0, 0);
1467 m_amr->copyData(tmp, solverIt()->getPhi(), dstInterv, srcInterv);
1470 DataOps::getMaxMin(curMax, curMin, tmp, 0, m_amr->getMultiCutVofIterator(m_fluidRealm, m_plasmaPhase));
1472 if (curMax > a_maxDensity) {
1473 a_maxDensity = curMax;
1474 a_maxSolver = solver->getName();
1477 if (curMin < a_minDensity) {
1478 a_minDensity = curMin;
1479 a_minSolver = solver->getName();
1485template <
typename I,
typename C,
typename R,
typename F>
1489 Real& a_minParticles,
1490 Real& a_maxParticles,
1494 CH_TIME(
"ItoKMCStepper::getParticleStatistics");
1495 if (m_verbosity > 5) {
1496 pout() << m_name +
"::getParticleStatistics" << endl;
1502 const Real numParticles = 1.0 * m_ito->getNumParticles(ItoSolver::WhichContainer::Bulk,
true);
1510 a_minParticles = minParticles.first;
1511 a_maxParticles = maxParticles.first;
1513 a_minRank = minParticles.second;
1514 a_maxRank = maxParticles.second;
1517template <
typename I,
typename C,
typename R,
typename F>
1521 CH_TIME(
"ItoKMCStepper::computeDt");
1522 if (m_verbosity > 5) {
1523 pout() << m_name +
"::computeDt" << endl;
1526 Timer timer(m_name +
"::computeDt");
1528 Real dt = std::numeric_limits<Real>::max();
1530 const Real maxGrowthDt = m_prevDt > 0.0 ? m_prevDt * m_maxGrowthDt : dt;
1531 const Real minShrinkDt = m_prevDt > 0.0 ? m_prevDt / m_maxShrinkDt : 0.0;
1533 if (m_timeStep == 0) {
1534 this->computeDummyPhysicsDt();
1539 m_particleAdvectionDt = m_ito->computeAdvectiveDt();
1543 m_particleDiffusionDt = m_ito->computeDiffusiveDt();
1546 timer.
startEvent(
"AdvectionDiffusion (Ito)");
1547 m_particleAdvectionDiffusionDt = m_ito->computeDt();
1548 timer.
stopEvent(
"AdvectionDiffusion (Ito)");
1550 timer.
startEvent(
"AdvectionDiffusion (CDR)");
1551 m_fluidAdvectionDiffusionDt = m_cdr->computeAdvectionDiffusionDt();
1552 timer.
stopEvent(
"AdvectionDiffusion (CDR)");
1555 m_relaxationTime = this->computeRelaxationTime();
1558 const bool hasParticleAdvectionDt = m_particleAdvectionDt < std::numeric_limits<Real>::max();
1559 const bool hasParticleDiffusionDt = m_particleDiffusionDt < std::numeric_limits<Real>::max();
1560 const bool hasParticleAdvectionDiffusionDt = m_particleAdvectionDiffusionDt < std::numeric_limits<Real>::max();
1562 if (m_maxParticleAdvectionCFL * m_particleAdvectionDt < dt) {
1563 dt = m_maxParticleAdvectionCFL * m_particleAdvectionDt;
1564 m_timeCode = TimeCode::AdvectionIto;
1567 if (m_maxParticleDiffusionCFL * m_particleDiffusionDt < dt) {
1568 dt = m_maxParticleDiffusionCFL * m_particleDiffusionDt;
1569 m_timeCode = TimeCode::DiffusionIto;
1572 if (m_maxParticleAdvectionDiffusionCFL * m_particleAdvectionDiffusionDt < dt) {
1573 dt = m_maxParticleAdvectionDiffusionCFL * m_particleAdvectionDiffusionDt;
1574 m_timeCode = TimeCode::AdvectionDiffusionIto;
1577 if (std::min(m_fluidAdvectionDiffusionCFL, 0.9) * m_fluidAdvectionDiffusionDt < dt) {
1578 dt = std::min(m_fluidAdvectionDiffusionCFL, 0.9) * m_fluidAdvectionDiffusionDt;
1579 m_timeCode = TimeCode::AdvectionDiffusionCDR;
1582 if (m_relaxTimeFactor * m_relaxationTime < dt) {
1583 dt = m_relaxTimeFactor * m_relaxationTime;
1584 m_timeCode = TimeCode::RelaxationTime;
1587 if (m_physicsDtFactor * m_physicsDt < dt) {
1588 dt = m_physicsDtFactor * m_physicsDt;
1589 m_timeCode = TimeCode::Physics;
1592 if ((dt < m_minParticleAdvectionCFL * m_particleAdvectionDt) && hasParticleAdvectionDt) {
1593 dt = m_minParticleAdvectionCFL * m_particleAdvectionDt;
1594 m_timeCode = TimeCode::AdvectionIto;
1597 if ((dt < m_minParticleDiffusionCFL * m_particleDiffusionDt) && hasParticleDiffusionDt) {
1598 dt = m_minParticleDiffusionCFL * m_particleDiffusionDt;
1599 m_timeCode = TimeCode::DiffusionIto;
1602 if ((dt < m_minParticleAdvectionDiffusionCFL * m_particleAdvectionDiffusionDt) && hasParticleAdvectionDiffusionDt) {
1603 dt = m_minParticleAdvectionDiffusionCFL * m_particleAdvectionDiffusionDt;
1604 m_timeCode = TimeCode::AdvectionDiffusionIto;
1607 if (dt > maxGrowthDt) {
1611 if (dt < minShrinkDt) {
1617 m_timeCode = TimeCode::Hardcap;
1622 m_timeCode = TimeCode::Hardcap;
1632template <
typename I,
typename C,
typename R,
typename F>
1636 CH_TIME(
"ItoKMCStepper::registerRealms");
1637 if (m_verbosity > 5) {
1638 pout() << m_name +
"::registerRealms" << endl;
1642 m_amr->registerRealm(m_fluidRealm);
1643 m_amr->registerRealm(m_particleRealm);
1646template <
typename I,
typename C,
typename R,
typename F>
1650 CH_TIME(
"ItoKMCStepper::registerOperators");
1651 if (m_verbosity > 5) {
1652 pout() << m_name +
"::registerOperators" << endl;
1655 m_ito->registerOperators();
1656 m_cdr->registerOperators();
1657 m_fieldSolver->registerOperators();
1658 m_rte->registerOperators();
1659 m_sigmaSolver->registerOperators();
1662 m_amr->registerParticleGhostMask(m_particleRealm, 1);
1665template <
typename I,
typename C,
typename R,
typename F>
1669 CH_TIME(
"ItoKMCStepper::prePlot");
1670 if (m_verbosity > 5) {
1671 pout() << m_name +
"::prePlot" << endl;
1674 const int numPhysicsPlotVars = m_physics->getNumberOfPlotVariables();
1676 if (numPhysicsPlotVars > 0) {
1677 m_amr->allocate(m_physicsPlotVariables, m_fluidRealm, m_plasmaPhase, numPhysicsPlotVars);
1679 this->computePhysicsPlotVariables(m_physicsPlotVariables);
1682 this->computeCurrentDensity(this->m_currentDensity);
1683 m_ito->depositParticles();
1686template <
typename I,
typename C,
typename R,
typename F>
1690 CH_TIME(
"ItoKMCStepper::postPlot");
1691 if (m_verbosity > 5) {
1692 pout() << m_name +
"::postPlot" << endl;
1695 m_physicsPlotVariables.clear();
1698template <
typename I,
typename C,
typename R,
typename F>
1702 CH_TIME(
"ItoKMCStepper::preRegrid");
1703 if (m_verbosity > 5) {
1704 pout() << m_name +
"::preRegrid" << endl;
1707 const int numItoSpecies = m_physics->getNumItoSpecies();
1708 const int numCdrSpecies = m_physics->getNumCdrSpecies();
1709 const int numPlasmaSpecies = m_physics->getNumPlasmaSpecies();
1710 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
1719 if (m_loadBalanceParticles) {
1720 Vector<RefCountedPtr<ItoSolver>> lbSolvers = this->getLoadBalanceSolvers();
1722 m_loadBalancePPC.resize(lbSolvers.size());
1725 for (
int i = 0; i < lbSolvers.size(); i++) {
1726 m_amr->allocate(m_loadBalancePPC[i], m_particleRealm, m_plasmaPhase, 1);
1728 EBAMRCellData& compPPC = m_loadBalancePPC[i];
1736 m_fluidScratch1.clear();
1737 m_fluidScratchD.clear();
1738 m_fluidScratchEB.clear();
1740 for (
int i = 0; i < m_fluidScratchIto.size(); i++) {
1741 m_fluidScratchIto[i].clear();
1744 m_particleScratch1.clear();
1745 m_particleScratchD.clear();
1746 m_particleScratchEB.clear();
1748 m_conductivityCell.clear();
1749 m_conductivityFace.clear();
1750 m_conductivityEB.clear();
1752 m_electricFieldParticle.clear();
1753 m_electricFieldFluid.clear();
1755 m_electricFieldParticle.clear();
1756 m_electricFieldFluid.clear();
1758 for (
int i = 0; i < numCdrSpecies; i++) {
1759 m_cdrMobilities[i].clear();
1760 m_cdrProducts[i]->clearParticles();
1763 for (
int i = 0; i < numItoSpecies; i++) {
1764 m_fluidGradPhiIto[i].clear();
1765 m_fluidPhiIto[i].clear();
1767 for (
int i = 0; i < numCdrSpecies; i++) {
1768 m_fluidGradPhiCDR[i].clear();
1771 for (
int i = 0; i < numItoSpecies; i++) {
1772 m_secondaryParticles[i]->clearParticles();
1774 for (
int i = 0; i < numPhotonSpecies; i++) {
1775 m_secondaryPhotons[i]->clearParticles();
1778 for (
int i = 0; i < numCdrSpecies; i++) {
1779 m_cdrFluxes[i].clear();
1780 m_cdrFluxesExtrap[i].clear();
1783 m_currentDensity.clear();
1786 m_particleItoPPC.clear();
1787 m_particleOldItoPPC.clear();
1789 if (numCdrSpecies > 0) {
1790 m_fluidCdrPPC.clear();
1791 m_fluidOldCdrPPC.clear();
1795 m_particleCdrProduction.clear();
1797 m_particleYPC.clear();
1801 m_ito->preRegrid(a_lmin, a_oldFinestLevel);
1802 m_cdr->preRegrid(a_lmin, a_oldFinestLevel);
1803 m_fieldSolver->preRegrid(a_lmin, a_oldFinestLevel);
1804 m_rte->preRegrid(a_lmin, a_oldFinestLevel);
1805 m_sigmaSolver->preRegrid(a_lmin, a_oldFinestLevel);
1808template <
typename I,
typename C,
typename R,
typename F>
1812 CH_TIME(
"ItoKMCStepper::regrid");
1813 if (m_verbosity > 5) {
1814 pout() << m_name +
"::regrid" << endl;
1817 this->allocateInternals();
1819 m_ito->regrid(a_lmin, a_oldFinestLevel, a_newFinestLevel);
1820 m_cdr->regrid(a_lmin, a_oldFinestLevel, a_newFinestLevel);
1821 m_fieldSolver->regrid(a_lmin, a_oldFinestLevel, a_newFinestLevel);
1822 m_rte->regrid(a_lmin, a_oldFinestLevel, a_newFinestLevel);
1823 m_sigmaSolver->regrid(a_lmin, a_oldFinestLevel, a_newFinestLevel);
1830 m_ito->depositParticles();
1832 const bool converged = this->solvePoisson();
1834 const std::string err =
"ItoKMCStepper::regrid - Poisson solve did not converge after regrid!!!";
1836 if (m_abortOnFailure) {
1837 MayDay::Error(err.c_str());
1840 MayDay::Warning(err.c_str());
1844 this->computeDriftVelocities();
1845 this->computeDiffusionCoefficients();
1847 this->fillNeutralDensity();
1850template <
typename I,
typename C,
typename R,
typename F>
1854 CH_TIME(
"ItoKMCStepper::postRegrid");
1856 if (m_loadBalanceParticles) {
1857 for (
int i = 0; i < m_loadBalancePPC.size(); i++) {
1858 m_amr->deallocate(m_loadBalancePPC[i]);
1863template <
typename I,
typename C,
typename R,
typename F>
1867 CH_TIME(
"ItoKMCStepper::setVoltage");
1868 if (m_verbosity > 5) {
1869 pout() << m_name +
"::setVoltage" << endl;
1872 m_voltage = a_voltage;
1875template <
typename I,
typename C,
typename R,
typename F>
1879 CH_TIME(
"ItoKMCStepper::fillNeutralDensity");
1880 if (m_verbosity > 5) {
1881 pout() << m_name +
"::fillNeutralDensity" << endl;
1886 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
1887 const DisjointBoxLayout& dbl = m_amr->getGrids(m_fluidRealm)[lvl];
1888 const EBISLayout& ebisl = m_amr->getEBISLayout(m_fluidRealm, m_plasmaPhase)[lvl];
1889 const DataIterator& dit = dbl.dataIterator();
1890 const Real dx = m_amr->getDx()[lvl];
1891 const RealVect probLo = m_amr->getProbLo();
1893 const int nbox = dit.size();
1895 CH_assert(!(m_neutralDensity[lvl].isNull()));
1896 CH_assert(m_neutralDensity[lvl]->nComp() == 1);
1898#pragma omp parallel for schedule(runtime)
1899 for (
int mybox = 0; mybox < nbox; mybox++) {
1900 const DataIndex& din = dit[mybox];
1901 const Box cellBox = dbl[din];
1902 const EBISBox& ebisbox = ebisl[din];
1904 EBCellFAB& neutralDensity = (*m_neutralDensity[lvl])[din];
1905 FArrayBox& neutralDensityReg = neutralDensity.getFArrayBox();
1907 auto regularKernel = [&](
const IntVect& iv) ->
void {
1908 const RealVect pos = probLo + (0.5 * RealVect::Unit + iv) * dx;
1910 neutralDensityReg(iv, 0) = m_physics->getNeutralDensity(pos);
1913 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
1914 const RealVect pos = probLo +
Location::position(Location::Cell::Centroid, vof, ebisbox, dx);
1916 neutralDensity(vof, 0) = m_physics->getNeutralDensity(pos);
1919 VoFIterator& vofit = (*m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase)[lvl])[din];
1923 BoxLoops::loop<D_DECL(1, 1, 1)>(cellBox, regularKernel);
1928 m_amr->conservativeAverage(m_neutralDensity, m_fluidRealm, m_plasmaPhase);
1929 m_amr->interpGhostPwl(m_neutralDensity, m_fluidRealm, m_plasmaPhase);
1932template <
typename I,
typename C,
typename R,
typename F>
1936 CH_TIME(
"ItoKMCStepper::computeMaxReducedElectricField");
1937 if (m_verbosity > 5) {
1938 pout() << m_name +
"::computeMaxReducedElectricField" << endl;
1943 CH_assert(a_phase == m_plasmaPhase);
1946 const EBAMRCellData cellCenteredE = m_amr->alias(a_phase, m_fieldSolver->getElectricField());
1950 EBAMRCellData& tmp = m_fluidScratch1;
1954 m_amr->getNotCoveredCells(m_fluidRealm, a_phase),
1955 m_amr->getMultiCutVofIterator(m_fluidRealm, a_phase));
1956 m_amr->interpToCentroids(tmp, m_fluidRealm, m_plasmaPhase);
1958 DataOps::divideFallback(tmp, m_neutralDensity, 0.0, m_amr->getMultiCutVofIterator(m_fluidRealm, m_plasmaPhase));
1963 DataOps::getMaxMin(max, min, tmp, 0, m_amr->getMultiCutVofIterator(m_fluidRealm, m_plasmaPhase));
1968template <
typename I,
typename C,
typename R,
typename F>
1973 CH_TIME(
"ItoKMCStepper::computeElectricField(EBAMRCellData, phase)");
1974 if (m_verbosity > 5) {
1975 pout() << m_name +
"::computeElectricField(EBAMRCellData, phase)" << endl;
1978 CH_assert(a_electricField.getRealm() == m_fluidRealm);
1980 m_fieldSolver->computeElectricField(a_electricField, a_phase, m_fieldSolver->getPotential());
1983template <
typename I,
typename C,
typename R,
typename F>
1987 CH_TIME(
"ItoKMCStepper::getTime");
1988 if (m_verbosity > 5) {
1989 pout() << m_name +
"::getTime" << endl;
1995template <
typename I,
typename C,
typename R,
typename F>
1999 CH_TIME(
"ItoKMCStepper::computeSpaceChargeDensity()");
2000 if (m_verbosity > 5) {
2001 pout() << m_name +
"::computeSpaceChargeDensity()" << endl;
2004 this->computeSpaceChargeDensity(m_fieldSolver->getRho(), m_ito->getDensities(), m_cdr->getPhis());
2007template <
typename I,
typename C,
typename R,
typename F>
2010 const Vector<EBAMRCellData*>& a_itoDensities,
2011 const Vector<EBAMRCellData*>& a_cdrDensities)
noexcept
2013 CH_TIME(
"ItoKMCStepper::computeSpaceChargeDensity(rho, densities)");
2014 if (m_verbosity > 5) {
2015 pout() << m_name +
"::computeSpaceChargeDensity(rho, densities)" << endl;
2022 CH_assert(a_rho.getRealm() == m_fluidRealm);
2023 CH_assert(a_itoDensities.size() == 0 || a_itoDensities[0]->getRealm() == m_particleRealm);
2024 CH_assert(a_cdrDensities.size() == 0 || a_cdrDensities[0]->getRealm() == m_fluidRealm);
2031 EBAMRCellData rhoPhase = m_amr->alias(m_plasmaPhase, a_rho);
2033 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
2034 const RefCountedPtr<ItoSolver>& solver = solverIt();
2035 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
2036 const int idx = solverIt.index();
2037 const int Z = species->getChargeNumber();
2040 m_amr->copyData(m_fluidScratch1, *a_itoDensities[idx]);
2046 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
2047 const RefCountedPtr<CdrSolver>& solver = solverIt();
2048 const RefCountedPtr<CdrSpecies>& species = solver->getSpecies();
2049 const int idx = solverIt.index();
2050 const int Z = species->getChargeNumber();
2059 m_amr->arithmeticAverage(a_rho, m_fluidRealm);
2060 m_amr->interpGhostPwl(a_rho, m_fluidRealm);
2063 m_amr->interpToCentroids(rhoPhase, m_fluidRealm, m_plasmaPhase);
2066template <
typename I,
typename C,
typename R,
typename F>
2070 CH_TIME(
"ItoKMCStepper::computeConductivityCell(EBAMRCellData)");
2071 if (m_verbosity > 5) {
2072 pout() << m_name +
"::computeConductivityCell(EBAMRCellData)" << endl;
2075 this->computeConductivityCell(a_conductivity, m_ito->getParticles(ItoSolver::WhichContainer::Bulk));
2078template <
typename I,
typename C,
typename R,
typename F>
2083 CH_TIME(
"ItoKMCStepper::computeConductivityCell(EBAMRCellData, Particles)");
2084 if (m_verbosity > 5) {
2085 pout() << m_name +
"::computeConductivityCell(EBAMRCellData, Particles)" << endl;
2091 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
2092 RefCountedPtr<ItoSolver>& solver = solverIt();
2093 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
2095 const int idx = solverIt.index();
2096 const int Z = species->getChargeNumber();
2098 if (Z != 0 && solver->isMobile()) {
2099 solver->depositConductivity(m_particleScratch1, *a_particles[idx]);
2102 m_amr->copyData(m_fluidScratch1, m_particleScratch1);
2103 DataOps::incr(a_conductivity, m_fluidScratch1, 1.0 * std::abs(Z));
2108 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
2109 const RefCountedPtr<CdrSolver>& solver = solverIt();
2110 const RefCountedPtr<CdrSpecies>& species = solver->getSpecies();
2112 const int idx = solverIt.index();
2113 const int Z = species->getChargeNumber();
2115 if (Z != 0 && solver->isMobile()) {
2116 const EBAMRCellData& phi = solver->getPhi();
2117 const EBAMRCellData& mobility = m_cdrMobilities[idx];
2121 DataOps::incr(a_conductivity, m_fluidScratch1, 1.0 * std::abs(Z));
2127 m_amr->arithmeticAverage(a_conductivity, m_fluidRealm, m_plasmaPhase);
2128 m_amr->interpGhostPwl(a_conductivity, m_fluidRealm, m_plasmaPhase);
2131 m_amr->interpToCentroids(a_conductivity, m_fluidRealm, m_plasmaPhase);
2134template <
typename I,
typename C,
typename R,
typename F>
2138 CH_TIME(
"ItoKMCStepper::computeDensityGradients()");
2139 if (m_verbosity > 5) {
2140 pout() << m_name +
"::computeDensityGradients()" << endl;
2143 const int numItoSpecies = m_physics->getNumItoSpecies();
2155 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
2156 const RefCountedPtr<ItoSolver>& solver = it();
2158 const int idx = it.index();
2160 if (!(m_physics->needGradient(idx))) {
2167 m_amr->copyData(m_fluidPhiIto[idx], solver->getPhi());
2169 m_amr->arithmeticAverage(m_fluidPhiIto[idx], m_fluidRealm, m_plasmaPhase);
2170 m_amr->interpGhostPwl(m_fluidPhiIto[idx], m_fluidRealm, m_plasmaPhase);
2172 m_amr->computeGradient(m_fluidGradPhiIto[idx], m_fluidPhiIto[idx], m_fluidRealm, m_plasmaPhase);
2176 for (
auto it = m_cdr->iterator(); it.ok(); ++it) {
2177 const RefCountedPtr<CdrSolver>& solver = it();
2179 const int idx = it.index();
2181 if (!(m_physics->needGradient(numItoSpecies + idx))) {
2188 m_amr->copyData(m_fluidScratch1, solver->getPhi());
2190 m_amr->arithmeticAverage(m_fluidScratch1, m_fluidRealm, m_plasmaPhase);
2191 m_amr->interpGhostPwl(m_fluidScratch1, m_fluidRealm, m_plasmaPhase);
2193 m_amr->computeGradient(m_fluidGradPhiCDR[idx], m_fluidScratch1, m_fluidRealm, m_plasmaPhase);
2197template <
typename I,
typename C,
typename R,
typename F>
2201 CH_TIME(
"ItoKMCStepper::computeCurrentDensity(EBAMRCellData)");
2202 if (m_verbosity > 5) {
2203 pout() << m_name +
"::computeCurrentDensity(EBAMRCellData)" << endl;
2206 CH_assert(a_J[0]->nComp() == SpaceDim);
2208 EBAMRCellData conductivity;
2209 m_amr->allocate(conductivity, m_fluidRealm, m_plasmaPhase, 1);
2210 this->computeConductivityCell(conductivity);
2216template <
typename I,
typename C,
typename R,
typename F>
2220 CH_TIME(
"ItoKMCStepper::computeRelaxationTime()");
2221 if (m_verbosity > 5) {
2222 pout() << m_name +
"::computeRelaxationTime()" << endl;
2227 EBAMRCellData conductivity;
2228 EBAMRCellData relaxTime;
2230 m_amr->allocate(conductivity, m_fluidRealm, m_plasmaPhase, 1);
2231 m_amr->allocate(relaxTime, m_fluidRealm, m_plasmaPhase, 1);
2233 this->computeConductivityCell(conductivity);
2238 std::numeric_limits<Real>::max(),
2239 m_amr->getMultiCutVofIterator(m_fluidRealm, m_plasmaPhase));
2241 m_amr->conservativeAverage(relaxTime, m_fluidRealm, m_plasmaPhase);
2243 Real min = std::numeric_limits<Real>::max();
2244 Real max = -std::numeric_limits<Real>::max();
2251template <
typename I,
typename C,
typename R,
typename F>
2255 CH_TIME(
"ItoKMCStepper::solvePoisson()");
2256 if (m_verbosity > 5) {
2257 pout() << m_name +
"::solvePoisson()" << endl;
2261 MFAMRCellData& phi = m_fieldSolver->getPotential();
2262 MFAMRCellData& rho = m_fieldSolver->getRho();
2263 EBAMRIVData& sigma = m_sigmaSolver->getPhi();
2265 const bool converged = m_fieldSolver->solve(phi, rho, sigma,
false);
2267 m_fieldSolver->computeElectricField();
2272 m_amr->allocatePointer(E, m_fluidRealm);
2273 m_amr->alias(E, m_plasmaPhase, m_fieldSolver->getElectricField());
2276 m_amr->copyData(m_electricFieldFluid, E);
2277 m_amr->conservativeAverage(m_electricFieldFluid, m_fluidRealm, m_plasmaPhase);
2278 m_amr->interpGhostPwl(m_electricFieldFluid, m_fluidRealm, m_plasmaPhase);
2279 m_amr->interpToCentroids(m_electricFieldFluid, m_fluidRealm, m_plasmaPhase);
2282 m_amr->copyData(m_electricFieldParticle, E);
2283 m_amr->conservativeAverage(m_electricFieldParticle, m_particleRealm, m_plasmaPhase);
2284 m_amr->interpGhostPwl(m_electricFieldParticle, m_particleRealm, m_plasmaPhase);
2285 m_amr->interpToCentroids(m_electricFieldParticle, m_particleRealm, m_plasmaPhase);
2290template <
typename I,
typename C,
typename R,
typename F>
2294 const bool a_delete,
2297 CH_TIME(
"ItoKMCStepper::intersectParticles(SpeciesSubset, bool, std::function)");
2298 if (m_verbosity > 5) {
2299 pout() << m_name +
"::intersectParticles(SpeciesSubset, bool, std::function)" << endl;
2302 this->intersectParticles(a_speciesSubset,
2303 ItoSolver::WhichContainer::Bulk,
2304 ItoSolver::WhichContainer::EB,
2305 ItoSolver::WhichContainer::Domain,
2307 a_nonDeletionModifier);
2310template <
typename I,
typename C,
typename R,
typename F>
2317 const bool a_delete,
2320 CH_TIME(
"ItoKMCStepper::intersectParticles(SpeciesSubset, Containerx3, bool, std::function)");
2321 if (m_verbosity > 5) {
2322 pout() << m_name +
"::intersectParticles(SpeciesSubset, Containerx3, bool, std::function)" << endl;
2325 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
2326 RefCountedPtr<ItoSolver>& solver = solverIt();
2327 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
2329 const bool mobile = solver->isMobile();
2330 const bool diffusive = solver->isDiffusive();
2331 const bool charged = (species->getChargeNumber() != 0);
2333 const EBIntersection intersectionAlgorithm = solver->getIntersectionAlgorithm();
2335 switch (a_speciesSubset) {
2336 case SpeciesSubset::All: {
2337 solver->intersectParticles(a_containerBulk,
2340 intersectionAlgorithm,
2342 a_nonDeletionModifier);
2346 case SpeciesSubset::AllMobile: {
2348 solver->intersectParticles(a_containerBulk,
2351 intersectionAlgorithm,
2353 a_nonDeletionModifier);
2358 case SpeciesSubset::AllDiffusive: {
2360 solver->intersectParticles(a_containerBulk,
2363 intersectionAlgorithm,
2365 a_nonDeletionModifier);
2370 case SpeciesSubset::AllMobileOrDiffusive: {
2371 if (mobile || diffusive) {
2372 solver->intersectParticles(a_containerBulk,
2375 intersectionAlgorithm,
2377 a_nonDeletionModifier);
2382 case SpeciesSubset::AllMobileAndDiffusive: {
2383 if (mobile && diffusive) {
2384 solver->intersectParticles(a_containerBulk,
2387 intersectionAlgorithm,
2389 a_nonDeletionModifier);
2394 case SpeciesSubset::Charged: {
2396 solver->intersectParticles(a_containerBulk,
2399 intersectionAlgorithm,
2401 a_nonDeletionModifier);
2406 case SpeciesSubset::ChargedMobile: {
2407 if (charged && mobile) {
2408 solver->intersectParticles(a_containerBulk,
2411 intersectionAlgorithm,
2413 a_nonDeletionModifier);
2418 case SpeciesSubset::ChargedDiffusive: {
2419 if (charged && diffusive) {
2420 solver->intersectParticles(a_containerBulk,
2423 intersectionAlgorithm,
2425 a_nonDeletionModifier);
2430 case SpeciesSubset::ChargedMobileOrDiffusive: {
2431 if (charged && (mobile || diffusive)) {
2432 solver->intersectParticles(a_containerBulk,
2435 intersectionAlgorithm,
2437 a_nonDeletionModifier);
2442 case SpeciesSubset::ChargedMobileAndDiffusive: {
2443 if (charged && (mobile && diffusive)) {
2444 solver->intersectParticles(a_containerBulk,
2447 intersectionAlgorithm,
2449 a_nonDeletionModifier);
2454 case SpeciesSubset::Stationary: {
2455 if (!mobile && !diffusive) {
2456 solver->intersectParticles(a_containerBulk,
2459 intersectionAlgorithm,
2461 a_nonDeletionModifier);
2467 MayDay::Abort(
"ItoKMCStepper::intersectParticles - logic bust");
2475template <
typename I,
typename C,
typename R,
typename F>
2479 const Real a_tolerance)
noexcept
2481 CH_TIME(
"ItoKMCStepper::removeCoveredParticles(SpeciesSubset, EBRepresentation, Real)");
2482 if (m_verbosity > 5) {
2483 pout() << m_name +
"::removeCoveredParticles(SpeciesSubset, EBRepresentation, Real)" << endl;
2486 this->removeCoveredParticles(a_speciesSubset, ItoSolver::WhichContainer::Bulk, a_representation, a_tolerance);
2489template <
typename I,
typename C,
typename R,
typename F>
2494 const Real a_tolerance)
noexcept
2496 CH_TIME(
"ItoKMCStepper::removeCoveredParticles(SpeciesSubset, container, EBRepresentation, tolerance)");
2497 if (m_verbosity > 5) {
2498 pout() << m_name +
"::removeCoveredParticles(SpeciesSubset, container, EBRepresentation, tolerance)" << endl;
2501 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
2502 RefCountedPtr<ItoSolver>& solver = solverIt();
2503 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
2505 const bool mobile = solver->isMobile();
2506 const bool diffusive = solver->isDiffusive();
2507 const bool charged = (species->getChargeNumber() != 0);
2510 case SpeciesSubset::All: {
2511 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2515 case SpeciesSubset::AllMobile: {
2517 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2522 case SpeciesSubset::AllDiffusive: {
2524 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2529 case SpeciesSubset::AllMobileOrDiffusive: {
2530 if (mobile || diffusive) {
2531 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2536 case SpeciesSubset::AllMobileAndDiffusive: {
2537 if (mobile && diffusive) {
2538 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2543 case SpeciesSubset::Charged: {
2545 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2550 case SpeciesSubset::ChargedMobile: {
2551 if (charged && mobile) {
2552 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2557 case SpeciesSubset::ChargedDiffusive: {
2558 if (charged && diffusive) {
2559 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2564 case SpeciesSubset::ChargedMobileOrDiffusive: {
2565 if (charged && (mobile || diffusive)) {
2566 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2571 case SpeciesSubset::ChargedMobileAndDiffusive: {
2572 if (charged && (mobile && diffusive)) {
2573 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2578 case SpeciesSubset::Stationary: {
2579 if (!mobile && !diffusive) {
2580 solver->removeCoveredParticles(a_container, a_representation, a_tolerance);
2586 MayDay::Abort(
"ItoKMCStepper::removeCoveredParticles - logic bust");
2594template <
typename I,
typename C,
typename R,
typename F>
2598 const Real a_tolerance)
noexcept
2600 CH_TIME(
"ItoKMCStepper::transferCoveredParticles(SpeciesSubset, EBRepresentation, Real)");
2601 if (m_verbosity > 5) {
2602 pout() << m_name +
"::transferCoveredParticles(SpeciesSubset, EBRepresentation, Real)" << endl;
2605 this->transferCoveredParticles(a_speciesSubset,
2606 ItoSolver::WhichContainer::Bulk,
2607 ItoSolver::WhichContainer::Covered,
2612template <
typename I,
typename C,
typename R,
typename F>
2618 const Real a_tolerance)
noexcept
2620 CH_TIME(
"ItoKMCStepper::transferCoveredParticles(SpeciesSubset, Containerx2, EBRepresentation, Real)");
2621 if (m_verbosity > 5) {
2622 pout() << m_name +
"::transferCoveredParticles(SpeciesSubset, Containerx2, EBRepresentation, Real)" << endl;
2625 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
2626 RefCountedPtr<ItoSolver>& solver = solverIt();
2627 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
2629 const bool mobile = solver->isMobile();
2630 const bool diffusive = solver->isDiffusive();
2631 const bool charged = (species->getChargeNumber() != 0);
2633 switch (a_speciesSubset) {
2634 case SpeciesSubset::All: {
2635 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2639 case SpeciesSubset::AllMobile: {
2641 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2646 case SpeciesSubset::AllDiffusive: {
2648 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2653 case SpeciesSubset::AllMobileOrDiffusive: {
2654 if (mobile || diffusive) {
2655 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2660 case SpeciesSubset::AllMobileAndDiffusive: {
2661 if (mobile && diffusive) {
2662 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2667 case SpeciesSubset::Charged: {
2669 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2674 case SpeciesSubset::ChargedMobile: {
2675 if (charged && mobile) {
2676 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2681 case SpeciesSubset::ChargedDiffusive: {
2682 if (charged && diffusive) {
2683 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2688 case SpeciesSubset::ChargedMobileOrDiffusive: {
2689 if (charged && (mobile || diffusive)) {
2690 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2695 case SpeciesSubset::ChargedMobileAndDiffusive: {
2696 if (charged && (mobile && diffusive)) {
2697 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2702 case SpeciesSubset::Stationary: {
2703 if (!mobile && !diffusive) {
2704 solver->transferCoveredParticles(a_containerFrom, a_containerTo, a_representation, a_tolerance);
2710 MayDay::Abort(
"ItoKMCStepper::transferCoveredParticles - logic bust");
2718template <
typename I,
typename C,
typename R,
typename F>
2722 CH_TIME(
"ItoKMCStepper::remapParticles(SpeciesSubset)");
2723 if (m_verbosity > 5) {
2724 pout() << m_name +
"::remapParticles(SpeciesSubset)" << endl;
2727 this->remapParticles(a_speciesSubset, ItoSolver::WhichContainer::Bulk);
2730template <
typename I,
typename C,
typename R,
typename F>
2735 CH_TIME(
"ItoKMCStepper::remapParticles(SpeciesSubset, WhichContainer)");
2736 if (m_verbosity > 5) {
2737 pout() << m_name +
"::remapParticles(SpeciesSubset, WhichContainer)" << endl;
2740 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
2741 RefCountedPtr<ItoSolver>& solver = solverIt();
2742 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
2744 const bool mobile = solver->isMobile();
2745 const bool diffusive = solver->isDiffusive();
2746 const bool charged = (species->getChargeNumber() != 0);
2748 switch (a_speciesSubset) {
2749 case SpeciesSubset::All: {
2750 solver->remap(a_container);
2754 case SpeciesSubset::AllMobile: {
2756 solver->remap(a_container);
2761 case SpeciesSubset::AllDiffusive: {
2763 solver->remap(a_container);
2768 case SpeciesSubset::AllMobileOrDiffusive: {
2769 if (mobile || diffusive) {
2770 solver->remap(a_container);
2775 case SpeciesSubset::AllMobileAndDiffusive: {
2776 if (mobile && diffusive) {
2777 solver->remap(a_container);
2782 case SpeciesSubset::Charged: {
2784 solver->remap(a_container);
2789 case SpeciesSubset::ChargedMobile: {
2790 if (charged && mobile) {
2791 solver->remap(a_container);
2796 case SpeciesSubset::ChargedDiffusive: {
2797 if (charged && diffusive) {
2798 solver->remap(a_container);
2803 case SpeciesSubset::ChargedMobileOrDiffusive: {
2804 if (charged && (mobile || diffusive)) {
2805 solver->remap(a_container);
2810 case SpeciesSubset::ChargedMobileAndDiffusive: {
2811 if (charged && (mobile && diffusive)) {
2812 solver->remap(a_container);
2817 case SpeciesSubset::Stationary: {
2818 if (!mobile && !diffusive) {
2819 solver->remap(a_container);
2825 MayDay::Abort(
"ItoKMCStepper::remapParticles - logic bust");
2833template <
typename I,
typename C,
typename R,
typename F>
2837 CH_TIME(
"ItoKMCStepper::depositParticles(SpeciesSubset)");
2838 if (m_verbosity > 5) {
2839 pout() << m_name +
"::depositParticles(SpeciesSubset)" << endl;
2842 this->depositParticles(a_speciesSubset, ItoSolver::WhichContainer::Bulk);
2845template <
typename I,
typename C,
typename R,
typename F>
2850 CH_TIME(
"ItoKMCStepper::depositParticles(SpeciesSubset)");
2851 if (m_verbosity > 5) {
2852 pout() << m_name +
"::depositParticles(SpeciesSubset)" << endl;
2855 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
2856 RefCountedPtr<ItoSolver>& solver = solverIt();
2857 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
2859 const bool mobile = solver->isMobile();
2860 const bool diffusive = solver->isDiffusive();
2861 const bool charged = (species->getChargeNumber() != 0);
2863 switch (a_speciesSubset) {
2864 case SpeciesSubset::All: {
2865 solver->depositParticles(a_container);
2869 case SpeciesSubset::AllMobile: {
2871 solver->depositParticles(a_container);
2876 case SpeciesSubset::AllDiffusive: {
2878 solver->depositParticles(a_container);
2883 case SpeciesSubset::AllMobileOrDiffusive: {
2884 if (mobile || diffusive) {
2885 solver->depositParticles(a_container);
2890 case SpeciesSubset::AllMobileAndDiffusive: {
2891 if (mobile && diffusive) {
2892 solver->depositParticles(a_container);
2897 case SpeciesSubset::Charged: {
2899 solver->depositParticles(a_container);
2904 case SpeciesSubset::ChargedMobile: {
2905 if (charged && mobile) {
2906 solver->depositParticles(a_container);
2911 case SpeciesSubset::ChargedDiffusive: {
2912 if (charged && diffusive) {
2913 solver->depositParticles(a_container);
2918 case SpeciesSubset::ChargedMobileOrDiffusive: {
2919 if (charged && (mobile || diffusive)) {
2920 solver->depositParticles(a_container);
2925 case SpeciesSubset::ChargedMobileAndDiffusive: {
2926 if (charged && (mobile && diffusive)) {
2927 solver->depositParticles(a_container);
2932 case SpeciesSubset::Stationary: {
2933 if (!mobile && !diffusive) {
2934 solver->depositParticles(a_container);
2940 MayDay::Abort(
"ItoKMCStepper::depositParticles - logic bust");
2948template <
typename I,
typename C,
typename R,
typename F>
2952 CH_TIME(
"ItoKMCStepper::setItoVelocityFunctions");
2953 if (m_verbosity > 5) {
2954 pout() << m_name +
"::setItoVelocityFunctions" << endl;
2957 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
2958 RefCountedPtr<ItoSolver>& solver = solverIt();
2959 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
2960 const int Z = species->getChargeNumber();
2962 if (solver->isMobile() && Z != 0) {
2963 EBAMRCellData& velocityFunction = solver->getVelocityFunction();
2964 m_amr->copyData(velocityFunction, m_electricFieldParticle);
2966 const int Z = species->getChargeNumber();
2973 m_amr->conservativeAverage(velocityFunction, m_particleRealm, m_plasmaPhase);
2974 m_amr->interpGhostPwl(velocityFunction, m_particleRealm, m_plasmaPhase);
2979template <
typename I,
typename C,
typename R,
typename F>
2983 CH_TIME(
"ItoKMCStepper::setCdrVelocityFunctions");
2984 if (m_verbosity > 5) {
2985 pout() << m_name +
"::setCdrVelocityFunctions" << endl;
2988 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
2989 RefCountedPtr<CdrSolver>& solver = solverIt();
2990 const RefCountedPtr<CdrSpecies>& species = solver->getSpecies();
2991 const int Z = species->getChargeNumber();
2993 if (solver->isMobile() && Z != 0) {
2994 EBAMRCellData& velocity = solver->getCellCenteredVelocity();
2995 m_amr->copyData(velocity, m_electricFieldFluid);
2997 const int Z = species->getChargeNumber();
3004 m_amr->conservativeAverage(velocity, m_fluidRealm, m_plasmaPhase);
3005 m_amr->interpGhostPwl(velocity, m_fluidRealm, m_plasmaPhase);
3007 else if (solver->isMobile() && Z == 0) {
3008 MayDay::Warning(
"ItoKMCStepper::setCdrVelocityFunctions -- how to handle mobile neutral species?");
3013template <
typename I,
typename C,
typename R,
typename F>
3017 CH_TIME(
"ItoKMCStepper::multiplyCdrVelocitiesByMobilities()");
3018 if (m_verbosity > 5) {
3019 pout() << m_name +
"::multiplyCdrVelocitiesByMobilities()" << endl;
3022 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
3023 RefCountedPtr<CdrSolver>& solver = solverIt();
3024 const int idx = solverIt.index();
3026 if (solver->isMobile()) {
3027 EBAMRCellData& velocity = solver->getCellCenteredVelocity();
3028 const EBAMRCellData& mobility = m_cdrMobilities[idx];
3033 m_amr->conservativeAverage(velocity, m_fluidRealm, m_plasmaPhase);
3034 m_amr->interpGhostPwl(velocity, m_fluidRealm, m_plasmaPhase);
3039template <
typename I,
typename C,
typename R,
typename F>
3043 CH_TIME(
"ItoKMCStepper::computeDriftVelocities()");
3044 if (m_verbosity > 5) {
3045 pout() << m_name +
"::computeDriftVelocities()" << endl;
3049 this->setItoVelocityFunctions();
3050 this->setCdrVelocityFunctions();
3053 this->computeMobilities();
3057 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
3058 solverIt()->interpolateVelocities();
3061 this->multiplyCdrVelocitiesByMobilities();
3064template <
typename I,
typename C,
typename R,
typename F>
3068 CH_TIME(
"ItoKMCStepper::computeMobilities()");
3069 if (m_verbosity > 5) {
3070 pout() << m_name +
"::computeMobilities()" << endl;
3073 Vector<EBAMRCellData*> itoMobilities = m_ito->getMobilityFunctions();
3075 this->computeMobilities(itoMobilities, m_cdrMobilities, m_electricFieldFluid, m_time);
3078template <
typename I,
typename C,
typename R,
typename F>
3081 Vector<EBAMRCellData>& a_cdrMobilities,
3082 const EBAMRCellData& a_electricField,
3083 const Real a_time)
noexcept
3085 CH_TIME(
"ItoKMCStepper::computeMobilities(mobilities, E, time)");
3086 if (m_verbosity > 5) {
3087 pout() << m_name +
"::computeMobilities(mobilities, E, time)" << endl;
3090 const int numItoSpecies = m_physics->getNumItoSpecies();
3091 const int numCdrSpecies = m_physics->getNumCdrSpecies();
3093 CH_assert(a_electricField.getRealm() == m_fluidRealm);
3094 CH_assert(a_itoMobilities.size() == numItoSpecies);
3095 CH_assert(a_cdrMobilities.size() == numCdrSpecies);
3101 CH_assert(m_fluidScratchIto.size() == numItoSpecies);
3103 for (
int i = 0; i < numItoSpecies; i++) {
3107 CH_assert(a_itoMobilities[i]->getRealm() == m_particleRealm);
3111 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
3112 Vector<LevelData<EBCellFAB>*> itoMobilities(numItoSpecies);
3113 Vector<LevelData<EBCellFAB>*> cdrMobilities(numCdrSpecies);
3115 for (
int i = 0; i < numItoSpecies; i++) {
3116 itoMobilities[i] = &(*(m_fluidScratchIto[i])[lvl]);
3119 for (
int i = 0; i < numCdrSpecies; i++) {
3120 cdrMobilities[i] = &(*(a_cdrMobilities[i])[lvl]);
3124 this->computeMobilities(itoMobilities, cdrMobilities, *a_electricField[lvl], lvl, a_time);
3128 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
3129 RefCountedPtr<ItoSolver>& solver = solverIt();
3131 if (solver->isMobile()) {
3132 const int idx = solverIt.index();
3134 m_amr->copyData(*a_itoMobilities[idx], m_fluidScratchIto[idx]);
3135 m_amr->conservativeAverage(*a_itoMobilities[idx], m_particleRealm, m_plasmaPhase);
3136 m_amr->interpGhostPwl(*a_itoMobilities[idx], m_particleRealm, m_plasmaPhase);
3138 solver->interpolateMobilities();
3143template <
typename I,
typename C,
typename R,
typename F>
3146 Vector<LevelData<EBCellFAB>*>& a_cdrMobilities,
3147 const LevelData<EBCellFAB>& a_electricField,
3149 const Real a_time)
noexcept
3151 CH_TIME(
"ItoKMCStepper::computeMobilities(mobilities, E, level, time)");
3152 if (m_verbosity > 5) {
3153 pout() << m_name +
"::computeMobilities(mobilities, E, level, time)" << endl;
3156 const DisjointBoxLayout& dbl = m_amr->getGrids(m_fluidRealm)[a_level];
3157 const DataIterator& dit = dbl.dataIterator();
3159 const int nbox = dit.size();
3161#pragma omp parallel for schedule(runtime)
3162 for (
int mybox = 0; mybox < nbox; mybox++) {
3163 const DataIndex& din = dit[mybox];
3165 const EBCellFAB& E = a_electricField[din];
3166 const Box cellBox = dbl[din];
3168 Vector<EBCellFAB*> itoMobilities;
3169 Vector<EBCellFAB*> cdrMobilities;
3171 for (
int i = 0; i < a_itoMobilities.size(); i++) {
3172 itoMobilities.push_back(&((*a_itoMobilities[i])[din]));
3175 for (
int i = 0; i < a_cdrMobilities.size(); i++) {
3176 cdrMobilities.push_back(&((*a_cdrMobilities[i])[din]));
3179 this->computeMobilities(itoMobilities, cdrMobilities, E, a_level, din, cellBox, a_time);
3183template <
typename I,
typename C,
typename R,
typename F>
3186 Vector<EBCellFAB*>& a_cdrMobilities,
3187 const EBCellFAB& a_electricField,
3189 const DataIndex a_din,
3191 const Real a_time)
noexcept
3193 CH_TIME(
"ItoKMCStepper::computeMobilities(meshMobilities, E, level, dit, box, time)");
3194 if (m_verbosity > 5) {
3195 pout() << m_name +
"::computeMobilities(meshMobilities, E, level, dit, box, time)" << endl;
3200 const int numItoSpecies = m_physics->getNumItoSpecies();
3201 const int numCdrSpecies = m_physics->getNumCdrSpecies();
3202 const int numPlasmaSpecies = m_physics->getNumPlasmaSpecies();
3204 const Real dx = m_amr->getDx()[a_level];
3205 const RealVect probLo = m_amr->getProbLo();
3206 const EBISBox& ebisbox = m_amr->getEBISLayout(m_fluidRealm, m_plasmaPhase)[a_level][a_din];
3209 const FArrayBox& electricFieldReg = a_electricField.getFArrayBox();
3210 Vector<FArrayBox*> itoMobilitiesReg(numItoSpecies);
3211 Vector<FArrayBox*> cdrMobilitiesReg(numCdrSpecies);
3213 for (
int i = 0; i < a_itoMobilities.size(); i++) {
3214 itoMobilitiesReg[i] = (&(a_itoMobilities[i]->getFArrayBox()));
3217 for (
int i = 0; i < a_cdrMobilities.size(); i++) {
3218 cdrMobilitiesReg[i] = (&(a_cdrMobilities[i]->getFArrayBox()));
3222 const std::map<int, std::pair<SpeciesType, int>>& speciesMap = m_physics->getSpeciesMap();
3228 Vector<Real> mobilities;
3231 auto regularKernel = [&](
const IntVect& iv) ->
void {
3232 const RealVect pos = m_amr->getProbLo() + dx * (RealVect(iv) + 0.5 * RealVect::Unit);
3233 const RealVect E = RealVect(D_DECL(electricFieldReg(iv, 0), electricFieldReg(iv, 1), electricFieldReg(iv, 2)));
3236 m_physics->computeMobilities(mobilities, a_time, pos, E);
3238 CH_assert(mobilities.size() == numPlasmaSpecies);
3241 for (
const auto& s : speciesMap) {
3242 const int& globalIndex = s.first;
3244 const int& localIndex = s.second.second;
3246 if (type == SpeciesType::Ito) {
3247 (*itoMobilitiesReg[localIndex])(iv, 0) = mobilities[globalIndex];
3249 else if (type == SpeciesType::CDR) {
3250 (*cdrMobilitiesReg[localIndex])(iv, 0) = mobilities[globalIndex];
3256 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
3257 const RealVect e = RealVect(D_DECL(a_electricField(vof, 0), a_electricField(vof, 1), a_electricField(vof, 2)));
3258 const RealVect pos = probLo +
Location::position(Location::Cell::Centroid, vof, ebisbox, dx);
3261 m_physics->computeMobilities(mobilities, a_time, pos, e);
3263 CH_assert(mobilities.size() == numPlasmaSpecies);
3266 for (
const auto& s : speciesMap) {
3267 const int& globalIndex = s.first;
3269 const int& localIndex = s.second.second;
3271 if (type == SpeciesType::Ito) {
3272 (*a_itoMobilities[localIndex])(vof, 0) = mobilities[globalIndex];
3274 else if (type == SpeciesType::CDR) {
3275 (*a_cdrMobilities[localIndex])(vof, 0) = mobilities[globalIndex];
3280 VoFIterator& vofit = (*m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase)[a_level])[a_din];
3284 BoxLoops::loop<D_DECL(1, 1, 1)>(a_box, regularKernel);
3288 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
3289 a_itoMobilities[solverIt.index()]->setCoveredCellVal(0.0, 0);
3292 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
3293 a_cdrMobilities[solverIt.index()]->setCoveredCellVal(0.0, 0);
3297template <
typename I,
typename C,
typename R,
typename F>
3301 CH_TIME(
"ItoKMCStepper::computeDiffusionCoefficients()");
3302 if (m_verbosity > 5) {
3303 pout() << m_name +
"::computeDiffusionCoefficients()" << endl;
3306 Vector<EBAMRCellData*> itoDiffusionCoefficients = m_ito->getDiffusionFunctions();
3307 Vector<EBAMRCellData*> cdrDiffusionCoefficients = m_cdr->getCellCenteredDiffusionCoefficients();
3309 this->computeDiffusionCoefficients(itoDiffusionCoefficients, cdrDiffusionCoefficients, m_electricFieldFluid, m_time);
3310 this->averageDiffusionCoefficientsCellToFace();
3313template <
typename I,
typename C,
typename R,
typename F>
3316 Vector<EBAMRCellData*>& a_cdrDiffusionCoefficients,
3317 const EBAMRCellData& a_electricField,
3318 const Real a_time)
noexcept
3320 CH_TIME(
"ItoKMCStepper::computeDiffusionCoefficients(Vector<EBAMRCellData*>, EBAMRCellData, Real)");
3321 if (m_verbosity > 5) {
3322 pout() << m_name +
"::computeDiffusionCoefficients(Vector<EBAMRCellData*>, EBAMRCellData, Real)" << endl;
3325 const int numItoSpecies = m_physics->getNumItoSpecies();
3326 const int numCdrSpecies = m_physics->getNumCdrSpecies();
3328 CH_assert(a_electricField.getRealm() == m_fluidRealm);
3329 CH_assert(a_itoDiffusionCoefficients.size() == numItoSpecies);
3330 CH_assert(a_cdrDiffusionCoefficients.size() == numCdrSpecies);
3333 for (
int i = 0; i < numItoSpecies; i++) {
3334 CH_assert(a_itoDiffusionCoefficients[i]->getRealm() == m_particleRealm);
3336 for (
int i = 0; i < numCdrSpecies; i++) {
3337 CH_assert(a_cdrDiffusionCoefficients[i]->getRealm() == m_fluidRealm);
3343 CH_assert(m_fluidScratchIto.size() == numItoSpecies);
3346 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
3347 Vector<LevelData<EBCellFAB>*> itoDiffusionCoefficients(numItoSpecies);
3348 Vector<LevelData<EBCellFAB>*> cdrDiffusionCoefficients(numCdrSpecies);
3350 for (
int i = 0; i < numItoSpecies; i++) {
3351 itoDiffusionCoefficients[i] = &(*(m_fluidScratchIto[i])[lvl]);
3353 for (
int i = 0; i < numCdrSpecies; i++) {
3354 cdrDiffusionCoefficients[i] = &(*(*a_cdrDiffusionCoefficients[i])[lvl]);
3357 this->computeDiffusionCoefficients(itoDiffusionCoefficients,
3358 cdrDiffusionCoefficients,
3359 *a_electricField[lvl],
3366 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
3367 RefCountedPtr<ItoSolver>& solver = solverIt();
3369 if (solver->isDiffusive()) {
3370 const int idx = solverIt.index();
3372 m_amr->copyData(*a_itoDiffusionCoefficients[idx], m_fluidScratchIto[idx]);
3373 m_amr->conservativeAverage(*a_itoDiffusionCoefficients[idx], m_particleRealm, m_plasmaPhase);
3374 m_amr->interpGhostPwl(*a_itoDiffusionCoefficients[idx], m_particleRealm, m_plasmaPhase);
3376 solver->interpolateDiffusion();
3381template <
typename I,
typename C,
typename R,
typename F>
3384 Vector<LevelData<EBCellFAB>*>& a_cdrDiffusionCoefficients,
3385 const LevelData<EBCellFAB>& a_electricField,
3387 const Real a_time)
noexcept
3389 CH_TIME(
"ItoKMCStepper::computeDiffusionCoefficients(Vector<LD<EBCellFAB>*>, LD<EBCellFAB>, int, Real)");
3390 if (m_verbosity > 5) {
3391 pout() << m_name +
"::computeDiffusionCoefficients(Vector<LD<EBCellFAB>*>, LD<EBCellFAB>, int, Real)" << endl;
3394 const int numItoSpecies = m_physics->getNumItoSpecies();
3395 const int numCdrSpecies = m_physics->getNumCdrSpecies();
3397 CH_assert(a_itoDiffusionCoefficients.size() == numItoSpecies);
3398 CH_assert(a_cdrDiffusionCoefficients.size() == numCdrSpecies);
3400 const DisjointBoxLayout& dbl = m_amr->getGrids(m_fluidRealm)[a_level];
3401 const DataIterator& dit = dbl.dataIterator();
3403 const int nbox = dit.size();
3405#pragma omp parallel for schedule(runtime)
3406 for (
int mybox = 0; mybox < nbox; mybox++) {
3407 const DataIndex& din = dit[mybox];
3409 Vector<EBCellFAB*> itoDiffusionCoefficients(numItoSpecies);
3410 Vector<EBCellFAB*> cdrDiffusionCoefficients(numCdrSpecies);
3412 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
3413 const int idx = solverIt.index();
3415 if (solverIt()->isDiffusive()) {
3416 itoDiffusionCoefficients[idx] = &(*a_itoDiffusionCoefficients[idx])[din];
3419 itoDiffusionCoefficients[idx] =
nullptr;
3423 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
3424 const int idx = solverIt.index();
3426 if (solverIt()->isDiffusive()) {
3427 cdrDiffusionCoefficients[idx] = &(*a_cdrDiffusionCoefficients[idx])[din];
3430 cdrDiffusionCoefficients[idx] =
nullptr;
3434 this->computeDiffusionCoefficients(itoDiffusionCoefficients,
3435 cdrDiffusionCoefficients,
3436 a_electricField[din],
3444template <
typename I,
typename C,
typename R,
typename F>
3447 Vector<EBCellFAB*>& a_cdrDiffusionCoefficients,
3448 const EBCellFAB& a_electricField,
3450 const DataIndex a_din,
3452 const Real a_time)
noexcept
3454 CH_TIME(
"ItoKMCStepper::computeDiffusionCoefficients(Patch)");
3455 if (m_verbosity > 5) {
3456 pout() << m_name +
"::computeDiffusionCoefficients(Patch)" << endl;
3459 const int numItoSpecies = m_physics->getNumItoSpecies();
3460 const int numCdrSpecies = m_physics->getNumCdrSpecies();
3461 const int numPlasmaSpecies = m_physics->getNumPlasmaSpecies();
3463 CH_assert(a_electricField.nComp() == SpaceDim);
3464 CH_assert(a_itoDiffusionCoefficients.size() == numItoSpecies);
3465 CH_assert(a_cdrDiffusionCoefficients.size() == numCdrSpecies);
3468 const Real dx = m_amr->getDx()[a_level];
3469 const RealVect probLo = m_amr->getProbLo();
3470 const EBISBox& ebisbox = m_amr->getEBISLayout(m_fluidRealm, m_plasmaPhase)[a_level][a_din];
3473 const FArrayBox& electricFieldReg = a_electricField.getFArrayBox();
3475 Vector<FArrayBox*> itoDiffCoReg(numItoSpecies,
nullptr);
3476 Vector<FArrayBox*> cdrDiffCoReg(numCdrSpecies,
nullptr);
3478 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
3479 RefCountedPtr<ItoSolver>& solver = solverIt();
3481 if (solver->isDiffusive()) {
3482 const int i = solverIt.index();
3483 itoDiffCoReg[i] = &(a_itoDiffusionCoefficients[i]->getFArrayBox());
3487 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
3488 RefCountedPtr<CdrSolver>& solver = solverIt();
3490 if (solver->isDiffusive()) {
3491 const int i = solverIt.index();
3492 cdrDiffCoReg[i] = &(a_cdrDiffusionCoefficients[i]->getFArrayBox());
3497 const std::map<int, std::pair<SpeciesType, int>>& speciesMap = m_physics->getSpeciesMap();
3500 Vector<Real> diffusionCoefficients;
3503 auto regularKernel = [&](
const IntVect& iv) ->
void {
3504 const RealVect pos = probLo + dx * (RealVect(iv) + 0.5 * RealVect::Unit);
3505 const RealVect E = RealVect(D_DECL(electricFieldReg(iv, 0), electricFieldReg(iv, 1), electricFieldReg(iv, 2)));
3508 m_physics->computeDiffusionCoefficients(diffusionCoefficients, a_time, pos, E);
3510 CH_assert(diffusionCoefficients.size() == numPlasmaSpecies);
3513 for (
const auto& s : speciesMap) {
3514 const int& globalIndex = s.first;
3516 const int& localIndex = s.second.second;
3519 if (type == SpeciesType::Ito) {
3520 if (m_ito->getSolvers()[localIndex]->isDiffusive()) {
3521 (*itoDiffCoReg[localIndex])(iv, 0) = diffusionCoefficients[globalIndex];
3524 else if (type == SpeciesType::CDR) {
3525 if (m_cdr->getSolvers()[localIndex]->isDiffusive()) {
3526 (*cdrDiffCoReg[localIndex])(iv, 0) = diffusionCoefficients[globalIndex];
3533 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
3534 const RealVect E = RealVect(D_DECL(a_electricField(vof, 0), a_electricField(vof, 1), a_electricField(vof, 2)));
3535 const RealVect pos = probLo +
Location::position(Location::Cell::Centroid, vof, ebisbox, dx);
3538 m_physics->computeDiffusionCoefficients(diffusionCoefficients, a_time, pos, E);
3541 for (
const auto& s : speciesMap) {
3542 const int& globalIndex = s.first;
3544 const int& localIndex = s.second.second;
3547 if (type == SpeciesType::Ito) {
3548 if (m_ito->getSolvers()[localIndex]->isDiffusive()) {
3549 (*a_itoDiffusionCoefficients[localIndex])(vof, 0) = diffusionCoefficients[globalIndex];
3552 else if (type == SpeciesType::CDR) {
3553 if (m_cdr->getSolvers()[localIndex]->isDiffusive()) {
3554 (*a_cdrDiffusionCoefficients[localIndex])(vof, 0) = diffusionCoefficients[globalIndex];
3561 VoFIterator& vofit = (*m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase)[a_level])[a_din];
3563 BoxLoops::loop<D_DECL(1, 1, 1)>(a_box, regularKernel);
3567 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
3568 if (solverIt()->isDiffusive()) {
3569 a_itoDiffusionCoefficients[solverIt.index()]->setCoveredCellVal(0.0, 0);
3573 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
3574 if (solverIt()->isDiffusive()) {
3575 a_cdrDiffusionCoefficients[solverIt.index()]->setCoveredCellVal(0.0, 0);
3580template <
typename I,
typename C,
typename R,
typename F>
3584 CH_TIME(
"ItoKMCStepper::averageDiffusionCoefficientsCellToFace");
3585 if (m_verbosity > 5) {
3586 pout() << m_name +
"::averageDiffusionCoefficientsCellToFace" << endl;
3589 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
3590 RefCountedPtr<CdrSolver>& solver = solverIt();
3592 if (solver->isDiffusive()) {
3594 EBAMRCellData& cellCenteredDiffusionCoefficient = solver->getCellCenteredDiffusionCoefficient();
3595 EBAMRFluxData& faceCenteredDiffusionCoefficient = solver->getFaceCenteredDiffusionCoefficient();
3597 CH_assert(cellCenteredDiffusionCoefficient.getRealm() == m_fluidRealm);
3598 CH_assert(faceCenteredDiffusionCoefficient.getRealm() == m_fluidRealm);
3600 DataOps::setValue(faceCenteredDiffusionCoefficient, std::numeric_limits<Real>::max());
3603 m_amr->arithmeticAverage(cellCenteredDiffusionCoefficient, m_fluidRealm, m_cdr->getPhase());
3604 m_amr->interpGhostPwl(cellCenteredDiffusionCoefficient, m_fluidRealm, m_cdr->getPhase());
3608 const int tanGhost = 1;
3609 const Interval interv = Interval(0, 0);
3610 const Average average = Average::Arithmetic;
3613 cellCenteredDiffusionCoefficient,
3614 m_amr->getDomains(),
3619 m_amr->getFaceIteratorWithTangentialGhosts(m_fluidRealm, m_cdr->getPhase()));
3624template <
typename I,
typename C,
typename R,
typename F>
3628 CH_TIME(
"ItoKMCStepper::getPhysicalParticlesPerCell(EBAMRCellData)");
3629 if (m_verbosity > 5) {
3630 pout() << m_name +
"::getPhysicaParticlesPerCell(EBAMRCellData)" << endl;
3633 CH_assert(a_ppc.getRealm() == m_particleRealm);
3635 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
3636 const int idx = it.index();
3638 EBAMRCellData ppc = m_amr->slice(a_ppc, Interval(idx, idx));
3646template <
typename I,
typename C,
typename R,
typename F>
3650 CH_TIME(
"ItoKMCStepper::computeReactiveItoParticlesPerCell(EBAMRCellData)");
3651 if (m_verbosity > 5) {
3652 pout() << m_name +
"::computeReactiveItoParticlesPerCell(EBAMRCellData)" << endl;
3655 CH_assert(a_ppc.getRealm() == m_particleRealm);
3659 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
3660 this->computeReactiveItoParticlesPerCell(*a_ppc[lvl], lvl);
3664template <
typename I,
typename C,
typename R,
typename F>
3668 CH_TIME(
"ItoKMCStepper::computeReactiveItoParticlesPerCell(LD<EBCellFAB>, int)");
3669 if (m_verbosity > 5) {
3670 pout() << m_name +
"::computeReactiveItoParticlesPerCell(LD<EBCellFAB>, int)" << endl;
3673 const int numItoSpecies = m_physics->getNumItoSpecies();
3675 CH_assert(a_ppc.nComp() == numItoSpecies);
3677 const DisjointBoxLayout& dbl = m_amr->getGrids(m_particleRealm)[a_level];
3678 const EBISLayout& ebisl = m_amr->getEBISLayout(m_particleRealm, m_plasmaPhase)[a_level];
3679 const DataIterator& dit = dbl.dataIterator();
3681 const int nbox = dit.size();
3683#pragma omp parallel for schedule(runtime)
3684 for (
int mybox = 0; mybox < nbox; mybox++) {
3685 const DataIndex& din = dit[mybox];
3687 const Box box = dbl[din];
3688 const EBISBox& ebisbox = ebisl[din];
3690 this->computeReactiveItoParticlesPerCell(a_ppc[din], a_level, din, box, ebisbox);
3694template <
typename I,
typename C,
typename R,
typename F>
3698 const DataIndex a_din,
3700 const EBISBox& a_ebisbox)
noexcept
3702 CH_TIME(
"ItoKMCStepper::computeReactiveItoParticlesPerCell(EBCellFAB, int, DataIndex, Box, EBISBox)");
3703 if (m_verbosity > 5) {
3704 pout() << m_name +
"::computeReactiveItoParticlesPerCell(EBCellFAB, int, DataIndex, Box, EBISBox)" << endl;
3707 const int numItoSpecies = m_physics->getNumItoSpecies();
3709 CH_assert(a_ppc.nComp() == numItoSpecies);
3711 const Real dx = m_amr->getDx()[a_level];
3712 const RealVect probLo = m_amr->getProbLo();
3716 FArrayBox& ppcRegular = a_ppc.getFArrayBox();
3718 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
3719 RefCountedPtr<ItoSolver>& solver = solverIt();
3720 const int idx = solverIt.index();
3727 leaf.
sortByCell(a_box, dx * RealVect::Unit, probLo);
3730 auto regularKernel = [&](
const IntVect& iv) ->
void {
3733 if (a_ebisbox.isRegular(iv)) {
3734 const std::pair<std::size_t, std::size_t> range = leaf.
cellRange(a_box.index(iv));
3735 for (std::size_t i = range.first; i < range.second; i++) {
3740 ppcRegular(iv, idx) = num;
3744 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
3745 const IntVect iv = vof.gridIndex();
3746 const RealVect normal = a_ebisbox.normal(vof);
3747 const RealVect physCentroid = probLo +
Location::position(Location::Cell::Boundary, vof, a_ebisbox, dx);
3751 const std::pair<std::size_t, std::size_t> range = leaf.
cellRange(a_box.index(iv));
3752 for (std::size_t i = range.first; i < range.second; i++) {
3753 const RealVect pos = leaf.
position(i);
3754 if ((pos - physCentroid).dotProduct(normal) >= 0.0) {
3759 a_ppc(vof, idx) = num;
3763 VoFIterator& vofit = (*m_amr->getVofIterator(m_particleRealm, m_plasmaPhase)[a_level])[a_din];
3765 BoxLoops::loop<D_DECL(1, 1, 1)>(a_box, regularKernel);
3770template <
typename I,
typename C,
typename R,
typename F>
3774 CH_TIME(
"ItoKMCStepper::computeReactiveCdrParticlesPerCell(EBAMRCellData)");
3775 if (m_verbosity > 5) {
3776 pout() << m_name +
"::computeReactiveCdrParticlesPerCell(EBAMRCellData)" << endl;
3779 CH_assert(a_ppc.getRealm() == m_fluidRealm);
3783 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
3784 this->computeReactiveCdrParticlesPerCell(*a_ppc[lvl], lvl);
3788template <
typename I,
typename C,
typename R,
typename F>
3792 CH_TIME(
"ItoKMCStepper::computeReactiveCdrParticlesPerCell(LD<EBCellFAB>, int)");
3793 if (m_verbosity > 5) {
3794 pout() << m_name +
"::computeReactiveCdrParticlesPerCell(LD<EBCellFAB>, int)" << endl;
3797 const int numCdrSpecies = m_physics->getNumCdrSpecies();
3799 CH_assert(a_ppc.nComp() == numCdrSpecies);
3801 if (numCdrSpecies > 0) {
3802 const DisjointBoxLayout& dbl = m_amr->getGrids(m_fluidRealm)[a_level];
3803 const EBISLayout& ebisl = m_amr->getEBISLayout(m_fluidRealm, m_plasmaPhase)[a_level];
3804 const DataIterator& dit = dbl.dataIterator();
3806 const int nbox = dit.size();
3808#pragma omp parallel for schedule(runtime)
3809 for (
int mybox = 0; mybox < nbox; mybox++) {
3810 const DataIndex& din = dit[mybox];
3812 const Box box = dbl[din];
3813 const EBISBox& ebisbox = ebisl[din];
3815 this->computeReactiveCdrParticlesPerCell(a_ppc[din], a_level, din, box, ebisbox);
3820template <
typename I,
typename C,
typename R,
typename F>
3824 const DataIndex a_din,
3826 const EBISBox& a_ebisbox)
noexcept
3828 CH_TIME(
"ItoKMCStepper::computeReactiveCdrParticlesPerCell(EBCellFAB, int, DataIndex, Box, EBISBox)");
3829 if (m_verbosity > 5) {
3830 pout() << m_name +
"::computeReactiveCdrParticlesPerCell(EBCellFAB, int, DataIndex, Box, EBISBox)" << endl;
3833 constexpr Real zero = 0.0;
3835 const int numCdrSpecies = m_physics->getNumCdrSpecies();
3837 CH_assert(a_ppc.nComp() == numCdrSpecies);
3839 const Real dx = m_amr->getDx()[a_level];
3840 const Real vol = std::pow(dx, SpaceDim);
3841 const RealVect probLo = m_amr->getProbLo();
3844 FArrayBox& ppcRegular = a_ppc.getFArrayBox();
3846 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
3847 RefCountedPtr<CdrSolver>& solver = solverIt();
3848 const int idx = solverIt.index();
3850 const EBCellFAB& phi = (*(solver->getPhi())[a_level])[a_din];
3851 const FArrayBox& phiReg = phi.getFArrayBox();
3856 auto regularKernel = [&](
const IntVect& iv) ->
void {
3857 if (a_ebisbox.isRegular(iv)) {
3858 ppcRegular(iv, idx) = std::max(zero, std::floor(phiReg(iv, 0) * vol));
3863 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
3864 const Real kappa = a_ebisbox.volFrac(vof);
3866 a_ppc(vof, idx) = std::max(zero, std::floor(kappa * phi(vof, 0) * vol));
3870 VoFIterator& vofit = (*m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase)[a_level])[a_din];
3872 BoxLoops::loop<D_DECL(1, 1, 1)>(a_box, regularKernel);
3877template <
typename I,
typename C,
typename R,
typename F>
3881 CH_TIME(
"ItoKMCStepper::computeReactiveMaeanEnergiesPerCell(EBAMRCellData)");
3882 if (m_verbosity > 5) {
3883 pout() << m_name +
"::computeReactiveMaeanEnergiesPerCell(EBAMRCellData)" << endl;
3886 CH_assert(a_meanEnergies.getRealm() == m_particleRealm);
3890 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
3891 this->computeReactiveMeanEnergiesPerCell(*a_meanEnergies[lvl], lvl);
3895template <
typename I,
typename C,
typename R,
typename F>
3898 const int a_level)
noexcept
3900 CH_TIME(
"ItoKMCStepper::computeReactiveMeanEnergiesPerCell(LD<EBCellFAB>, int)");
3901 if (m_verbosity > 5) {
3902 pout() << m_name +
"::computeReactiveMeanEnergiesPerCell(LD<EBCellFAB>, int)" << endl;
3905 const int numPlasmaSpecies = m_physics->getNumItoSpecies();
3907 CH_assert(a_meanEnergies.nComp() == numPlasmaSpecies);
3909 const DisjointBoxLayout& dbl = m_amr->getGrids(m_particleRealm)[a_level];
3910 const EBISLayout& ebisl = m_amr->getEBISLayout(m_particleRealm, m_plasmaPhase)[a_level];
3911 const DataIterator& dit = dbl.dataIterator();
3913 const int nbox = dit.size();
3915#pragma omp parallel for schedule(runtime)
3916 for (
int mybox = 0; mybox < nbox; mybox++) {
3917 const DataIndex& din = dit[mybox];
3919 const Box box = dbl[din];
3920 const EBISBox& ebisbox = ebisl[din];
3922 this->computeReactiveMeanEnergiesPerCell(a_meanEnergies[din], a_level, din, box, ebisbox);
3926template <
typename I,
typename C,
typename R,
typename F>
3930 const DataIndex a_din,
3932 const EBISBox& a_ebisbox)
noexcept
3934 CH_TIME(
"ItoKMCStepper::computeReactiveMeanEnergiesPerCell(EBCellFABint, DataIndex, Box, EBISBox)");
3935 if (m_verbosity > 5) {
3936 pout() << m_name +
"::computeReactiveMeanEnergiesPerCell(EBCellFABint, DataIndex, Box, EBISBox))" << endl;
3939 const int numPlasmaSpecies = m_physics->getNumItoSpecies();
3941 CH_assert(a_meanEnergies.nComp() == numPlasmaSpecies);
3943 const Real dx = m_amr->getDx()[a_level];
3944 const RealVect probLo = m_amr->getProbLo();
3947 FArrayBox& meanEnergiesReg = a_meanEnergies.getFArrayBox();
3949 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
3950 RefCountedPtr<ItoSolver>& solver = solverIt();
3951 const int idx = solverIt.index();
3958 leaf.
sortByCell(a_box, dx * RealVect::Unit, probLo);
3961 auto regularKernel = [&](
const IntVect& iv) ->
void {
3962 if (a_ebisbox.isRegular(iv)) {
3963 Real totalWeight = 0.0;
3964 Real totalEnergy = 0.0;
3966 const std::pair<std::size_t, std::size_t> range = leaf.
cellRange(a_box.index(iv));
3967 for (std::size_t i = range.first; i < range.second; i++) {
3968 const Real w = leaf.
weight(i);
3970 totalEnergy += w * leaf.template get<&ItoParticle::energy>(i);
3973 if (totalWeight > 0.0) {
3974 meanEnergiesReg(iv, idx) = totalEnergy / totalWeight;
3977 meanEnergiesReg(iv, idx) = 0.0;
3983 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
3984 const IntVect iv = vof.gridIndex();
3985 const RealVect normal = a_ebisbox.normal(vof);
3986 const RealVect ebCentroid = probLo +
Location::position(Location::Cell::Boundary, vof, a_ebisbox, dx);
3988 Real totalWeight = 0.0;
3989 Real totalEnergy = 0.0;
3991 const std::pair<std::size_t, std::size_t> range = leaf.
cellRange(a_box.index(iv));
3992 for (std::size_t i = range.first; i < range.second; i++) {
3993 const RealVect pos = leaf.
position(i);
3995 if ((pos - ebCentroid).dotProduct(normal) >= 0.0) {
3996 const Real w = leaf.
weight(i);
3998 totalEnergy += w * leaf.template get<&ItoParticle::energy>(i);
4002 if (totalWeight > 0.0) {
4003 meanEnergiesReg(iv, idx) = totalEnergy / totalWeight;
4006 meanEnergiesReg(iv, idx) = 0.0;
4011 VoFIterator& vofit = (*m_amr->getVofIterator(m_particleRealm, m_plasmaPhase)[a_level])[a_din];
4013 BoxLoops::loop<D_DECL(1, 1, 1)>(a_box, regularKernel);
4018template <
typename I,
typename C,
typename R,
typename F>
4022 CH_TIME(
"ItoKMCStepper::advanceReactionNetwork(dt)");
4023 if (m_verbosity > 5) {
4024 pout() << m_name +
"::advanceReactionNetwork(dt)" << endl;
4027 CH_assert(a_dt > 0.0);
4029 this->advanceReactionNetwork(m_electricFieldFluid, a_dt);
4036template <
typename I,
typename C,
typename R,
typename F>
4040 CH_TIMERS(
"ItoKMCStepper::advanceReactionNetwork");
4041 CH_TIMER(
"ItoKMCStepper::advanceReactionNetwork::compute_ppc", t1);
4042 CH_TIMER(
"ItoKMCStepper::advanceReactionNetwork::integrate_network", t2);
4043 CH_TIMER(
"ItoKMCStepper::advanceReactionNetwork::copies", t3);
4044 CH_TIMER(
"ItoKMCStepper::advanceReactionNetwork::reconcile_particles", t4);
4045 CH_TIMER(
"ItoKMCStepper::advanceReactionNetwork::reconcile_cdr", t5);
4046 if (m_verbosity > 5) {
4047 pout() << m_name +
"::advanceReactionNetwork" << endl;
4050 const int numItoSpecies = m_physics->getNumItoSpecies();
4051 const int numCdrSpecies = m_physics->getNumCdrSpecies();
4052 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
4054 CH_assert(a_electricField.getRealm() == m_fluidRealm);
4055 CH_assert(a_dt > 0.0);
4060 if (numItoSpecies > 0) {
4061 this->computeReactiveItoParticlesPerCell(m_particleItoPPC);
4063 const Interval srcInterv(0, numItoSpecies - 1);
4064 const Interval dstInterv(0, numItoSpecies - 1);
4066 m_amr->copyData(m_fluidPPC, m_particleItoPPC, dstInterv, srcInterv);
4070 if (numCdrSpecies > 0) {
4071 this->computeReactiveCdrParticlesPerCell(m_fluidCdrPPC);
4073 const Interval srcInterv(0, numCdrSpecies - 1);
4074 const Interval dstInterv(numItoSpecies, numItoSpecies + numCdrSpecies - 1);
4076 m_amr->copyData(m_fluidPPC, m_fluidCdrPPC, dstInterv, srcInterv);
4088 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
4089 this->advanceReactionNetwork(*m_fluidPPC[lvl], *m_fluidYPC[lvl], *a_electricField[lvl], lvl, a_dt);
4095 if (numItoSpecies > 0) {
4096 const Interval srcInterv(0, numItoSpecies - 1);
4097 const Interval dstInterv(0, numItoSpecies - 1);
4099 m_amr->copyData(m_particleItoPPC, m_fluidPPC, dstInterv, srcInterv);
4101 if (numCdrSpecies > 0) {
4102 const Interval srcInterv(numItoSpecies, numItoSpecies + numCdrSpecies - 1);
4103 const Interval dstInterv(0, numCdrSpecies - 1);
4105 m_amr->copyData(m_fluidCdrPPC, m_fluidPPC, dstInterv, srcInterv);
4107 if (numPhotonSpecies > 0) {
4108 m_amr->copyData(m_particleYPC, m_fluidYPC);
4125 if (numCdrSpecies > 0) {
4128 if (m_cdrProductInjection == CdrProductInjection::Particle) {
4129 const Vector<RefCountedPtr<LayoutData<VoFIterator>>>& vofIter = m_amr->getVofIterator(m_fluidRealm,
4137 m_amr->copyData(m_particleCdrProduction, m_fluidOldCdrPPC);
4141 for (
int i = 0; i < m_cdrProducts.size(); i++) {
4142 m_cdrProducts[i]->clearParticles();
4143 m_cdrProducts[i]->organizeParticlesByCell();
4148 this->reconcileParticles(m_particleItoPPC,
4149 m_particleOldItoPPC,
4151 m_particleCdrProduction,
4152 m_electricFieldParticle);
4157 this->depositCdrProducts(m_fluidCdrPPC);
4159 this->reconcileCdrDensities(m_fluidCdrPPC, a_dt);
4163template <
typename I,
typename C,
typename R,
typename F>
4167 CH_TIME(
"ItoKMCStepper::depositCdrProducts");
4168 if (m_verbosity > 5) {
4169 pout() << m_name +
"::depositCdrProducts" << endl;
4172 CH_assert(a_cdrChange.getRealm() == m_fluidRealm);
4183 Vector<long long int> numProducts(m_cdrProducts.size(), 0LL);
4185 for (
int i = 0; i < m_cdrProducts.size(); i++) {
4186 numProducts[i] =
static_cast<long long int>(m_cdrProducts[i]->getNumberOfValidParticlesLocal());
4206 const bool useItoDeposition = (m_cdrProductInjection == CdrProductInjection::Particle) &&
4207 (m_physics->getNumItoSpecies() > 0);
4209 for (
int i = 0; i < m_cdrProducts.size(); i++) {
4210 if (numProducts[i] == 0LL) {
4214 m_cdrProducts[i]->organizeParticlesByPatch();
4216 if (useItoDeposition) {
4217 const auto& solver = m_ito->getSolvers()[0];
4219 solver->depositWeight(m_particleScratch1,
4221 solver->getDeposition(),
4222 solver->getCoarseFineDeposition());
4225 m_amr->depositWeight(m_particleScratch1,
4229 DepositionType::NGP,
4230 CoarseFineDeposition::Halo,
4234 m_amr->copyData(m_fluidScratch1, m_particleScratch1);
4237 EBAMRCellData cdrChange = m_amr->slice(a_cdrChange, Interval(i, i));
4241 m_cdrProducts[i]->clearParticles();
4245template <
typename I,
typename C,
typename R,
typename F>
4248 LevelData<EBCellFAB>& a_newPhotonsPerCell,
4249 const LevelData<EBCellFAB>& a_electricField,
4251 const Real a_dt)
const noexcept
4253 CH_TIME(
"ItoKMCStepper::advanceReactionNetwork(LD<EBCellFAB>x3, int, Real)");
4254 if (m_verbosity > 5) {
4255 pout() << m_name +
"::advanceReactionNetwork(LD<EBCellFAB>x3, int, Real)" << endl;
4258 const int numPlasmaSpecies = m_physics->getNumPlasmaSpecies();
4259 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
4261 CH_assert(a_particlesPerCell.nComp() == numPlasmaSpecies);
4262 CH_assert(a_newPhotonsPerCell.nComp() == numPhotonSpecies);
4263 CH_assert(a_electricField.nComp() == SpaceDim);
4265 const DisjointBoxLayout& dbl = m_amr->getGrids(m_fluidRealm)[a_level];
4266 const DataIterator& dit = dbl.dataIterator();
4268 const int nbox = dit.size();
4272 m_physics->defineKMC();
4274#pragma omp for schedule(runtime)
4275 for (
int mybox = 0; mybox < nbox; mybox++) {
4276 const DataIndex& din = dit[mybox];
4278 this->advanceReactionNetwork(a_particlesPerCell[din],
4279 a_newPhotonsPerCell[din],
4280 a_electricField[din],
4284 m_amr->getDx()[a_level],
4288 m_physics->killKMC();
4292template <
typename I,
typename C,
typename R,
typename F>
4295 EBCellFAB& a_newPhotonsPerCell,
4296 const EBCellFAB& a_electricField,
4298 const DataIndex a_din,
4301 const Real a_dt)
const noexcept
4303 CH_TIME(
"ItoKMCStepper::advanceReactionNetwork(EBCellFABx3, int, DataIndex, Box, Realx2)");
4304 if (m_verbosity > 5) {
4305 pout() << m_name +
"::advanceReactionNetwork(EBCellFABx3, int, DataIndex, Box, Realx2)" << endl;
4308 const int numCdrSpecies = m_physics->getNumCdrSpecies();
4309 const int numItoSpecies = m_physics->getNumItoSpecies();
4310 const int numPlasmaSpecies = m_physics->getNumPlasmaSpecies();
4311 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
4313 CH_assert(a_particlesPerCell.nComp() == numPlasmaSpecies);
4314 CH_assert(a_newPhotonsPerCell.nComp() == numPhotonSpecies);
4315 CH_assert(a_electricField.nComp() == SpaceDim);
4318 const RealVect probLo = m_amr->getProbLo();
4319 const EBISBox& ebisbox = m_amr->getEBISLayout(m_fluidRealm, m_plasmaPhase)[a_level][a_din];
4321 const FArrayBox& electricFieldReg = a_electricField.getFArrayBox();
4324 Vector<Physics::ItoKMC::FPR> particles(numPlasmaSpecies);
4325 Vector<Physics::ItoKMC::FPR> newPhotons(numPhotonSpecies);
4326 Vector<Real> meanEnergies(numPlasmaSpecies);
4327 Vector<Real> energySources(numPlasmaSpecies);
4328 Vector<Real> densities(numPlasmaSpecies, 0.0);
4329 Vector<RealVect> densityGradients(numPlasmaSpecies, RealVect::Zero);
4332 FArrayBox& particlesPerCellReg = a_particlesPerCell.getFArrayBox();
4333 FArrayBox& newPhotonsReg = a_newPhotonsPerCell.getFArrayBox();
4336 Vector<const EBCellFAB*> densitiesIto(numItoSpecies);
4337 Vector<const EBCellFAB*> densityGradientsIto(numItoSpecies);
4338 Vector<const FArrayBox*> densitiesItoReg(numItoSpecies);
4339 Vector<const FArrayBox*> densityGradientsItoReg(numItoSpecies);
4341 Vector<const EBCellFAB*> densitiesCDR(numCdrSpecies);
4342 Vector<const EBCellFAB*> densityGradientsCDR(numCdrSpecies);
4343 Vector<const FArrayBox*> densitiesCDRReg(numCdrSpecies);
4344 Vector<const FArrayBox*> densityGradientsCDRReg(numCdrSpecies);
4347 EBCellFAB& physicsDt = (*m_kmcDt[a_level])[a_din];
4349 FArrayBox& physicsDtReg = physicsDt.getFArrayBox();
4351 physicsDt.setVal(std::numeric_limits<Real>::max());
4353 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
4354 const RefCountedPtr<ItoSolver>& solver = it();
4356 const int i = it.index();
4358 densitiesIto[i] = &(*(m_fluidPhiIto[i])[a_level])[a_din];
4359 densitiesItoReg[i] = &(densitiesIto[i]->getFArrayBox());
4360 densityGradientsIto[i] = &(*m_fluidGradPhiIto[i][a_level])[a_din];
4361 densityGradientsItoReg[i] = &(densityGradientsIto[i]->getFArrayBox());
4364 for (
auto it = m_cdr->iterator(); it.ok(); ++it) {
4365 const RefCountedPtr<CdrSolver>& solver = it();
4366 const EBAMRCellData& phi = solver->getPhi();
4368 const int i = it.index();
4370 densitiesCDR[i] = &(*phi[a_level])[a_din];
4371 densitiesCDRReg[i] = &(densitiesCDR[i]->getFArrayBox());
4372 densityGradientsCDR[i] = &(*m_fluidGradPhiCDR[i][a_level])[a_din];
4373 densityGradientsCDRReg[i] = &(densityGradientsCDR[i]->getFArrayBox());
4377 const BaseFab<bool>& validCells = (*m_amr->getValidCells(m_fluidRealm)[a_level])[a_din];
4380 auto regularKernel = [&](
const IntVect& iv) ->
void {
4381 if (ebisbox.isRegular(iv) && validCells(iv, 0)) {
4382 const RealVect pos = probLo + a_dx * (RealVect(iv) + 0.5 * RealVect::Unit);
4383 const RealVect E = RealVect(D_DECL(electricFieldReg(iv, 0), electricFieldReg(iv, 1), electricFieldReg(iv, 2)));
4386 for (
int i = 0; i < numPlasmaSpecies; i++) {
4387 particles[i] = llround(particlesPerCellReg(iv, i));
4390 for (
int i = 0; i < numPhotonSpecies; i++) {
4391 newPhotons[i] = 0LL;
4395 for (
int i = 0; i < numItoSpecies; i++) {
4396 densities[i] = (*densitiesItoReg[i])(iv, 0);
4397 densityGradients[i] = RealVect(D_DECL((*densityGradientsItoReg[i])(iv, 0),
4398 (*densityGradientsItoReg[i])(iv, 1),
4399 (*densityGradientsItoReg[i])(iv, 2)));
4402 for (
int i = 0; i < numCdrSpecies; i++) {
4403 densities[numItoSpecies + i] = (*densitiesCDRReg[i])(iv, 0);
4404 densityGradients[numItoSpecies + i] = RealVect(D_DECL((*densityGradientsCDRReg[i])(iv, 0),
4405 (*densityGradientsCDRReg[i])(iv, 1),
4406 (*densityGradientsCDRReg[i])(iv, 2)));
4410 Real physDt = std::numeric_limits<Real>::max();
4412 m_physics->advanceKMC(particles, newPhotons, physDt, densities, densityGradients, a_dt, E, pos, a_dx, 1.0);
4415 for (
int i = 0; i < numPlasmaSpecies; i++) {
4416 particlesPerCellReg(iv, i) = 1.0 * particles[i];
4419 for (
int i = 0; i < numPhotonSpecies; i++) {
4420 newPhotonsReg(iv, i) = 1.0 * newPhotons[i];
4423 physicsDtReg(iv, 0) = physDt;
4428 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
4429 const IntVect iv = vof.gridIndex();
4431 if (ebisbox.isIrregular(iv) && validCells(iv, 0)) {
4432 const Real kappa = ebisbox.volFrac(vof);
4433 const RealVect pos = probLo +
Location::position(Location::Cell::Centroid, vof, ebisbox, a_dx);
4434 const RealVect E = RealVect(D_DECL(a_electricField(vof, 0), a_electricField(vof, 1), a_electricField(vof, 2)));
4437 for (
int i = 0; i < numPlasmaSpecies; i++) {
4438 particles[i] = llround(a_particlesPerCell(vof, i));
4441 for (
int i = 0; i < numPhotonSpecies; i++) {
4442 newPhotons[i] = 0LL;
4446 for (
int i = 0; i < numItoSpecies; i++) {
4447 densities[i] = (*densitiesIto[i])(vof, 0);
4448 densityGradients[i] = RealVect(D_DECL((*densityGradientsIto[i])(vof, 0),
4449 (*densityGradientsIto[i])(vof, 1),
4450 (*densityGradientsIto[i])(vof, 2)));
4453 for (
int i = 0; i < numCdrSpecies; i++) {
4454 densities[numItoSpecies + i] = (*densitiesCDR[i])(vof, 0);
4455 densityGradients[numItoSpecies + i] = RealVect(D_DECL((*densityGradientsCDR[i])(vof, 0),
4456 (*densityGradientsCDR[i])(vof, 1),
4457 (*densityGradientsCDR[i])(vof, 2)));
4461 Real physDt = std::numeric_limits<Real>::max();
4463 m_physics->advanceKMC(particles, newPhotons, physDt, densities, densityGradients, a_dt, E, pos, a_dx, kappa);
4466 for (
int i = 0; i < numPlasmaSpecies; i++) {
4467 a_particlesPerCell(vof, i) = 1.0 * particles[i];
4470 for (
int i = 0; i < numPhotonSpecies; i++) {
4471 a_newPhotonsPerCell(vof, i) = 1.0 * newPhotons[i];
4474 physicsDt(vof, 0) = physDt;
4481 VoFIterator& vofit = (*m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase)[a_level])[a_din];
4483 BoxLoops::loop<D_DECL(1, 1, 1)>(a_box, regularKernel);
4487template <
typename I,
typename C,
typename R,
typename F>
4490 const EBAMRCellData& a_oldParticlesPerCell,
4491 const EBAMRCellData& a_newPhotonsPerCell,
4492 const EBAMRCellData& a_cdrProduction,
4493 const EBAMRCellData& a_electricField)
const noexcept
4495 CH_TIME(
"ItoKMCStepper::reconcileParticles(EBAMRCellDatax4)");
4496 if (m_verbosity > 5) {
4497 pout() << m_name +
"::reconcileParticles(EBAMRCellDatax4)";
4500 CH_assert(a_newParticlesPerCell.getRealm() == m_particleRealm);
4501 CH_assert(a_oldParticlesPerCell.getRealm() == m_particleRealm);
4502 CH_assert(a_newPhotonsPerCell.getRealm() == m_particleRealm);
4503 CH_assert(a_cdrProduction.getRealm() == m_particleRealm);
4504 CH_assert(a_electricField.getRealm() == m_particleRealm);
4506 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
4507 this->reconcileParticles(*a_newParticlesPerCell[lvl],
4508 *a_oldParticlesPerCell[lvl],
4509 *a_newPhotonsPerCell[lvl],
4510 *a_cdrProduction[lvl],
4511 *a_electricField[lvl],
4516template <
typename I,
typename C,
typename R,
typename F>
4519 const LevelData<EBCellFAB>& a_oldParticlesPerCell,
4520 const LevelData<EBCellFAB>& a_newPhotonsPerCell,
4521 const LevelData<EBCellFAB>& a_cdrProduction,
4522 const LevelData<EBCellFAB>& a_electricField,
4523 const int a_level)
const noexcept
4525 CH_TIME(
"ItoKMCStepper::reconcileParticles(LevelData<EBCellFAB>x4, int)");
4526 if (m_verbosity > 5) {
4527 pout() << m_name +
"::reconcileParticles(LevelData<EBCellFAB>x4, int)" << endl;
4530 const int numItoSpecies = m_physics->getNumItoSpecies();
4531 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
4533 CH_assert(a_newParticlesPerCell.nComp() == numItoSpecies);
4534 CH_assert(a_oldParticlesPerCell.nComp() == numItoSpecies);
4535 CH_assert(a_newPhotonsPerCell.nComp() == numPhotonSpecies);
4536 CH_assert(a_electricField.nComp() == SpaceDim);
4538 const DisjointBoxLayout& dbl = m_amr->getGrids(m_particleRealm)[a_level];
4539 const DataIterator& dit = dbl.dataIterator();
4541 const int nbox = dit.size();
4543#pragma omp parallel for schedule(runtime)
4544 for (
int mybox = 0; mybox < nbox; mybox++) {
4545 const DataIndex& din = dit[mybox];
4547 this->reconcileParticles(a_newParticlesPerCell[din],
4548 a_oldParticlesPerCell[din],
4549 a_newPhotonsPerCell[din],
4550 a_cdrProduction[din],
4551 a_electricField[din],
4555 m_amr->getDx()[a_level]);
4559template <
typename I,
typename C,
typename R,
typename F>
4562 const EBCellFAB& a_oldParticlesPerCell,
4563 const EBCellFAB& a_newPhotonsPerCell,
4564 const EBCellFAB& a_cdrProduction,
4565 const EBCellFAB& a_electricField,
4567 const DataIndex a_din,
4569 const Real a_dx)
const noexcept
4571 CH_TIMERS(
"ItoKMCStepper::reconcileParticles(patch)");
4572 CH_TIMER(
"ItoKMCStepper::reconcileParticles(patch)::collect_ptr", t1);
4573 CH_TIMER(
"ItoKMCStepper::reconcileParticles(patch)::regular_cells", t2);
4574 CH_TIMER(
"ItoKMCStepper::reconcileParticles(patch)::irregular_cells", t3);
4575 if (m_verbosity > 5) {
4576 pout() << m_name +
"::reconcileParticles(patch)" << endl;
4586 const int numItoSpecies = m_physics->getNumItoSpecies();
4587 const int numCdrSpecies = m_physics->getNumCdrSpecies();
4588 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
4590 CH_assert(a_newParticlesPerCell.nComp() == numItoSpecies);
4591 CH_assert(a_oldParticlesPerCell.nComp() == numItoSpecies);
4592 CH_assert(a_newPhotonsPerCell.nComp() == numPhotonSpecies);
4593 CH_assert(a_electricField.nComp() == SpaceDim);
4596 const RealVect probLo = m_amr->getProbLo();
4597 const EBISBox& ebisbox = m_amr->getEBISLayout(m_particleRealm, m_plasmaPhase)[a_level][a_din];
4601 const BaseFab<bool>& validCells = (*m_amr->getValidCells(m_particleRealm)[a_level])[a_din];
4604 const FArrayBox& electricFieldReg = a_electricField.getFArrayBox();
4609 std::vector<std::vector<ParticleSoA<ItoParticle>>> itoCells(numItoSpecies);
4610 std::vector<std::vector<ParticleSoA<Photon>>> bulkPhotonCells(numPhotonSpecies);
4611 std::vector<std::vector<ParticleSoA<Photon>>> sourcePhotonCells(numPhotonSpecies);
4612 std::vector<std::vector<ParticleSoA<NoPayload>>> cdrCells(numCdrSpecies);
4615 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
4616 const int idx = solverIt.index();
4620 binLeafToCells(itoCells[idx], solverParticles[a_level][a_din], a_box, a_dx, probLo);
4624 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
4625 const int idx = solverIt.index();
4627 binLeafToCells(cdrCells[idx], (*m_cdrProducts[idx])[a_level][a_din], a_box, a_dx, probLo);
4631 for (
auto solverIt = m_rte->iterator(); solverIt.ok(); ++solverIt) {
4632 const int idx = solverIt.index();
4637 binLeafToCells(bulkPhotonCells[idx], solverBulkPhotons[a_level][a_din], a_box, a_dx, probLo);
4638 binLeafToCells(sourcePhotonCells[idx], solverSourcePhotons[a_level][a_din], a_box, a_dx, probLo);
4644 Vector<Physics::ItoKMC::FPR> numNewParticles(numItoSpecies);
4645 Vector<Physics::ItoKMC::FPR> numOldParticles(numItoSpecies);
4646 Vector<Physics::ItoKMC::FPR> numNewPhotons(numPhotonSpecies);
4648 Vector<long long> numNewCdrParticles(numCdrSpecies);
4652 const bool injectCdrProducts = (m_cdrProductInjection == CdrProductInjection::Particle);
4657 Vector<ParticleSoA<ItoParticle>*> itoParticles(numItoSpecies);
4658 Vector<ParticleSoA<NoPayload>*> cdrParticles(numCdrSpecies);
4659 Vector<ParticleSoA<Photon>*> bulkPhotons(numPhotonSpecies);
4660 Vector<ParticleSoA<Photon>*> sourcePhotons(numPhotonSpecies);
4664 auto regularKernel = [&](
const IntVect& iv) ->
void {
4665 if (ebisbox.isRegular(iv) && validCells(iv)) {
4666 const RealVect electricField = RealVect(
4667 D_DECL(electricFieldReg(iv, 0), electricFieldReg(iv, 1), electricFieldReg(iv, 2)));
4668 const RealVect cellPos = probLo + a_dx * (RealVect(iv) + 0.5 * RealVect::Unit);
4669 const RealVect centroidPos = RealVect::Zero;
4670 const RealVect lo = -0.5 * RealVect::Unit;
4671 const RealVect hi = 0.5 * RealVect::Unit;
4672 const RealVect bndryCentroid = RealVect::Zero;
4673 const RealVect bndryNormal = RealVect::Zero;
4674 const Real kappa = 1.0;
4677 for (
int i = 0; i < numItoSpecies; i++) {
4678 itoParticles[i] = &itoCells[i][a_box.index(iv)];
4679 numNewParticles[i] = llround(a_newParticlesPerCell.getSingleValuedFAB()(iv, i));
4680 numOldParticles[i] = llround(a_oldParticlesPerCell.getSingleValuedFAB()(iv, i));
4684 for (
int i = 0; i < numCdrSpecies; i++) {
4685 cdrParticles[i] = &cdrCells[i][a_box.index(iv)];
4686 numNewCdrParticles[i] = injectCdrProducts ? llround(a_cdrProduction.getSingleValuedFAB()(iv, i)) : 0LL;
4690 for (
int i = 0; i < numPhotonSpecies; i++) {
4691 bulkPhotons[i] = &bulkPhotonCells[i][a_box.index(iv)];
4692 sourcePhotons[i] = &sourcePhotonCells[i][a_box.index(iv)];
4694 numNewPhotons[i] = llround(a_newPhotonsPerCell.getSingleValuedFAB()(iv, i));
4698 sourcePhotons[i]->clear();
4709 m_physics->reconcileCdrParticles(cdrParticles,
4724 m_physics->reconcileParticles(itoParticles,
4739 m_physics->reconcilePhotons(sourcePhotons,
4751 m_physics->reconcilePhotoionization(itoParticles, cdrParticles, bulkPhotons);
4762 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
4763 const IntVect iv = vof.gridIndex();
4764 if (ebisbox.isIrregular(iv) && validCells(iv, 0)) {
4765 const RealVect electricField = RealVect(
4766 D_DECL(a_electricField(vof, 0), a_electricField(vof, 1), a_electricField(vof, 2)));
4767 const RealVect cellPos = probLo +
Location::position(Location::Cell::Center, vof, ebisbox, a_dx);
4768 const RealVect centroidPos = ebisbox.centroid(vof);
4769 const RealVect bndryCentroid = ebisbox.bndryCentroid(vof);
4770 const RealVect bndryNormal = ebisbox.normal(vof);
4771 const Real kappa = ebisbox.volFrac(vof);
4774 RealVect lo = -0.5 * RealVect::Unit;
4775 RealVect hi = 0.5 * RealVect::Unit;
4781 for (
int i = 0; i < numItoSpecies; i++) {
4782 itoParticles[i] = &itoCells[i][a_box.index(iv)];
4783 numNewParticles[i] = llround(a_newParticlesPerCell(vof, i));
4784 numOldParticles[i] = llround(a_oldParticlesPerCell(vof, i));
4788 for (
int i = 0; i < numCdrSpecies; i++) {
4789 cdrParticles[i] = &cdrCells[i][a_box.index(iv)];
4790 numNewCdrParticles[i] = injectCdrProducts ? llround(a_cdrProduction(vof, i)) : 0LL;
4794 for (
int i = 0; i < numPhotonSpecies; i++) {
4795 bulkPhotons[i] = &bulkPhotonCells[i][a_box.index(iv)];
4796 sourcePhotons[i] = &sourcePhotonCells[i][a_box.index(iv)];
4798 numNewPhotons[i] = llround(a_newPhotonsPerCell(vof, i));
4802 sourcePhotons[i]->clear();
4806 m_physics->reconcileCdrParticles(cdrParticles,
4821 m_physics->reconcileParticles(itoParticles,
4836 m_physics->reconcilePhotons(sourcePhotons,
4848 m_physics->reconcilePhotoionization(itoParticles, cdrParticles, bulkPhotons);
4856 VoFIterator& vofit = (*m_amr->getVofIterator(m_particleRealm, m_plasmaPhase)[a_level])[a_din];
4859 BoxLoops::loop<D_DECL(1, 1, 1)>(a_box, regularKernel);
4869 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
4870 const int idx = solverIt.index();
4874 rebuildLeafFromCells(solverParticles[a_level][a_din], itoCells[idx], a_box, a_dx, probLo);
4877 for (
auto solverIt = m_rte->iterator(); solverIt.ok(); ++solverIt) {
4878 const int idx = solverIt.index();
4882 rebuildLeafFromCells(solverSourcePhotons[a_level][a_din], sourcePhotonCells[idx], a_box, a_dx, probLo);
4886 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
4887 const int idx = solverIt.index();
4889 rebuildLeafFromCells((*m_cdrProducts[idx])[a_level][a_din], cdrCells[idx], a_box, a_dx, probLo);
4893template <
typename I,
typename C,
typename R,
typename F>
4897 CH_TIME(
"ItoKMCStepper::reconcilePhotoionization()");
4898 if (m_verbosity > 5) {
4899 pout() << m_name +
"::reconcilePhotoionization()" << endl;
4902 const int numItoSpecies = m_physics->getNumItoSpecies();
4903 const int numCdrSpecies = m_physics->getNumCdrSpecies();
4904 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
4906 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
4907 const DisjointBoxLayout& dbl = m_amr->getGrids(m_particleRealm)[lvl];
4908 const DataIterator& dit = dbl.dataIterator();
4910 const int nbox = dit.size();
4912#pragma omp parallel for schedule(runtime)
4913 for (
int mybox = 0; mybox < nbox; mybox++) {
4914 const DataIndex& din = dit[mybox];
4920 Vector<ParticleSoA<ItoParticle>> itoProducts(numItoSpecies);
4922 Vector<ParticleSoA<ItoParticle>*> itoParticles(numItoSpecies);
4923 Vector<ParticleSoA<NoPayload>*> cdrParticles(numCdrSpecies);
4924 Vector<ParticleSoA<Photon>*> photonParticles(numPhotonSpecies);
4926 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
4927 itoParticles[solverIt.index()] = &itoProducts[solverIt.index()];
4930 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
4931 cdrParticles[solverIt.index()] = &((*m_cdrProducts[solverIt.index()])[lvl][din]);
4934 for (
auto solverIt = m_rte->iterator(); solverIt.ok(); ++solverIt) {
4935 photonParticles[solverIt.index()] = &(solverIt()->getBulkPhotons()[lvl][din]);
4938 m_physics->reconcilePhotoionization(itoParticles, cdrParticles, photonParticles);
4941 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
4942 const int idx = solverIt.index();
4945 leaf.
append(itoProducts[idx]);
4951template <
typename I,
typename C,
typename R,
typename F>
4955 CH_TIME(
"ItoKMCStepper::reconcileCdrDensities(EBAMRCellData, Real)");
4956 if (m_verbosity > 5) {
4957 pout() << m_name +
"::reconcileCdrDensities(EBAMRCellData, Real)" << endl;
4960 const int numCdrSpecies = m_physics->getNumCdrSpecies();
4962 CH_assert(a_cdrChange.getRealm() == m_fluidRealm);
4963 CH_assert(a_dt > 0.0);
4965 if (numCdrSpecies > 0) {
4968 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
4969 this->reconcileCdrDensities(*a_cdrChange[lvl], lvl, a_dt);
4976 if (m_redistributeCDR && m_cdrProductInjection == CdrProductInjection::Mesh) {
4977 for (
auto it = m_cdr->iterator(); it.ok(); ++it) {
4978 const int idx = it.index();
4980 const EBAMRCellData cdrChange = m_amr->slice(a_cdrChange, Interval(idx, idx));
4982 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
4983 const DisjointBoxLayout& dbl = m_amr->getGrids(m_fluidRealm)[lvl];
4984 const DataIterator& dit = dbl.dataIterator();
4985 const EBISLayout& ebisl = m_amr->getEBISLayout(m_fluidRealm, m_plasmaPhase)[lvl];
4986 const Real dx = m_amr->getDx()[lvl];
4988 const int nbox = dit.size();
4990#pragma omp parallel for schedule(runtime)
4991 for (
int mybox = 0; mybox < nbox; mybox++) {
4992 const DataIndex& din = dit[mybox];
4993 const EBISBox& ebisbox = ebisl[din];
4995 BaseIVFAB<Real>& deltaMass = (*m_fluidScratchEB[lvl])[din];
4997 deltaMass.setVal(0.0);
4999 const EBCellFAB& change = (*a_cdrChange[lvl])[din];
5001 auto kernel = [&](
const VolIndex& vof) ->
void {
5002 const Real kappa = ebisbox.volFrac(vof);
5004 deltaMass(vof, 0) = change(vof, idx) * (1.0 - kappa) / std::pow(dx, SpaceDim);
5007 VoFIterator& vofit = (*m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase)[lvl])[din];
5013 const RefCountedPtr<CdrSolver>& solver = it();
5015 solver->redistribute(solver->getPhi(), m_fluidScratchEB);
5021 this->coarsenCDRSolvers(
false);
5025template <
typename I,
typename C,
typename R,
typename F>
5029 const Real a_dt)
noexcept
5031 CH_TIME(
"ItoKMCStepper::reconcileCdrDensities(LD<EBCellFAB>, int, Real)");
5032 if (m_verbosity > 5) {
5033 pout() << m_name +
"::reconcileCdrDensities(LD<EBCellFAB>, int, Real)" << endl;
5036 const int numCdrSpecies = m_physics->getNumCdrSpecies();
5038 CH_assert(a_cdrChange.nComp() == numCdrSpecies);
5040 const DisjointBoxLayout& dbl = m_amr->getGrids(m_fluidRealm)[a_level];
5041 const DataIterator& dit = dbl.dataIterator();
5042 const Real dx = m_amr->getDx()[a_level];
5044 const int nbox = dit.size();
5046#pragma omp parallel for schedule(runtime)
5047 for (
int mybox = 0; mybox < nbox; mybox++) {
5048 const DataIndex& din = dit[mybox];
5050 this->reconcileCdrDensities(a_cdrChange[din], a_level, din, dbl[din], dx, a_dt);
5054template <
typename I,
typename C,
typename R,
typename F>
5058 const DataIndex a_din,
5061 const Real a_dt)
noexcept
5063 CH_TIME(
"ItoKMCStepper::reconcileCdrDensities(EBCellFAB, int, DataIndex, Box, Realx2)");
5064 if (m_verbosity > 5) {
5065 pout() << m_name +
"::reconcileCdrDensities(EBCellFAB, int, DataIndex, Box, Realx2)" << endl;
5068 const int numCdrSpecies = m_physics->getNumCdrSpecies();
5070 CH_assert(a_cdrChange.nComp() == numCdrSpecies);
5072 const Real volume = std::pow(a_dx, SpaceDim);
5074 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
5075 RefCountedPtr<CdrSolver>& solver = solverIt();
5076 const int index = solverIt.index();
5078 EBCellFAB& phi = (*(solver->getPhi()[a_level]))[a_din];
5079 EBCellFAB& src = (*(solver->getSource()[a_level]))[a_din];
5083 src.plus(a_cdrChange, index, 0, 1);
5094template <
typename I,
typename C,
typename R,
typename F>
5098 CH_TIME(
"ItoKMCStepper::coarsenCDRSolvers");
5099 if (m_verbosity > 5) {
5100 pout() << m_name +
"::coarsenCDRSolvers" << endl;
5103 for (
auto solverIt = this->m_cdr->iterator(); solverIt.ok(); ++solverIt) {
5104 auto& solver = solverIt();
5106 EBAMRCellData& phi = solver->getPhi();
5107 EBAMRCellData& src = solver->getSource();
5109 this->m_amr->conservativeAverage(phi, phi.getRealm(), this->m_plasmaPhase);
5110 this->m_amr->conservativeAverage(src, src.getRealm(), this->m_plasmaPhase);
5115 if (a_interpGhosts) {
5116 this->m_amr->interpGhostPwl(phi, phi.getRealm(), this->m_plasmaPhase);
5124template <
typename I,
typename C,
typename R,
typename F>
5128 CH_TIME(
"ItoKMCStepper::needSecondaryEmissionEB");
5129 if (m_verbosity > 5) {
5130 pout() << m_name +
"::needSecondaryEmissionEB" << endl;
5135 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
5136 if (solverIt()->isMobile()) {
5141 long long numPrimaries = 0;
5143 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
5144 numPrimaries +=
static_cast<long long>(
5145 solverIt()->getParticles(ItoSolver::WhichContainer::EB).getNumberOfValidParticlesLocal());
5148 for (
auto solverIt = m_rte->iterator(); solverIt.ok(); ++solverIt) {
5149 numPrimaries +=
static_cast<long long>(solverIt()->getEbPhotons().getNumberOfValidParticlesLocal());
5155template <
typename I,
typename C,
typename R,
typename F>
5159 CH_TIME(
"ItoKMCStepper::fillSecondaryEmissionEB(Real)");
5160 if (m_verbosity > 5) {
5161 pout() << m_name +
"::fillSecondaryEmissionEB(Real)" << endl;
5165 Vector<ParticleContainer<ItoParticle>*> primaryParticles;
5166 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
5169 primaryParticles.push_back(&intersectedParticles);
5175 m_amr->allocate(tmp, m_fluidRealm, m_plasmaPhase, 1);
5177 for (
auto solverIt = m_cdr->iterator(); solverIt.ok(); ++solverIt) {
5178 const int idx = solverIt.index();
5179 const RefCountedPtr<CdrSolver>& solver = solverIt();
5181 EBAMRIVData& extrapFlux = m_cdrFluxesExtrap[idx];
5183 if (solver->isMobile()) {
5184 solver->extrapolateAdvectiveFluxToEB(tmp);
5186 m_amr->copyData(extrapFlux, tmp);
5194 Vector<ParticleContainer<Photon>*> primaryPhotons;
5195 for (
auto it = m_rte->iterator(); it.ok(); ++it) {
5198 primaryPhotons.push_back(&intersectedPhotons);
5202 this->fillSecondaryEmissionEB(m_secondaryParticles,
5208 m_electricFieldParticle,
5212template <
typename I,
typename C,
typename R,
typename F>
5216 Vector<EBAMRIVData>& a_cdrFluxes,
5219 Vector<EBAMRIVData>& a_cdrFluxesExtrap,
5221 const EBAMRCellData& a_electricField,
5222 const Real a_dt)
noexcept
5224 CH_TIME(
"ItoKMCStepper::fillSecondaryEmissionEB(full)");
5225 if (m_verbosity > 5) {
5226 pout() << m_name +
"::fillSecondaryEmissionEB(full)" << endl;
5229 const int numItoSpecies = m_physics->getNumItoSpecies();
5230 const int numCdrSpecies = m_physics->getNumCdrSpecies();
5231 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
5233 CH_assert(a_secondaryParticles.size() == numItoSpecies);
5234 CH_assert(a_cdrFluxes.size() == numCdrSpecies);
5235 CH_assert(a_secondaryPhotons.size() == numPhotonSpecies);
5236 CH_assert(a_primaryParticles.size() == numItoSpecies);
5237 CH_assert(a_cdrFluxesExtrap.size() == numCdrSpecies);
5238 CH_assert(a_primaryPhotons.size() == numPhotonSpecies);
5239 CH_assert(a_electricField.getRealm() == m_particleRealm);
5240 CH_assert(a_dt >= 0.0);
5243 for (
int i = 0; i < numItoSpecies; i++) {
5244 CH_assert(a_secondaryParticles[i]->getRealm() == m_particleRealm);
5245 CH_assert(a_primaryParticles[i]->getRealm() == m_particleRealm);
5247 a_secondaryParticles[i]->clearParticles();
5248 a_secondaryParticles[i]->organizeParticlesByCell();
5250 a_primaryParticles[i]->organizeParticlesByCell();
5253 for (
int i = 0; i < numCdrSpecies; i++) {
5254 CH_assert(a_cdrFluxes[i].getRealm() == m_particleRealm);
5255 CH_assert(a_cdrFluxesExtrap[i].getRealm() == m_particleRealm);
5261 for (
int i = 0; i < numPhotonSpecies; i++) {
5262 CH_assert(a_secondaryPhotons[i]->getRealm() == m_particleRealm);
5263 CH_assert(a_primaryPhotons[i]->getRealm() == m_particleRealm);
5265 a_secondaryPhotons[i]->clearParticles();
5267 a_secondaryPhotons[i]->organizeParticlesByCell();
5268 a_primaryPhotons[i]->organizeParticlesByCell();
5271 const RealVect probLo = m_amr->getProbLo();
5273 const Vector<Electrode>& electrodes = m_computationalGeometry->getElectrodes();
5274 const Vector<Dielectric>& dielectrics = m_computationalGeometry->getDielectrics();
5276 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
5277 const DisjointBoxLayout& dbl = m_amr->getGrids(m_particleRealm)[lvl];
5278 const DataIterator& dit = dbl.dataIterator();
5279 const EBISLayout& ebisl = m_amr->getEBISLayout(m_particleRealm, m_plasmaPhase)[lvl];
5280 const Real dx = m_amr->getDx()[lvl];
5282 const int nbox = dit.size();
5284#pragma omp parallel for schedule(runtime)
5285 for (
int mybox = 0; mybox < nbox; mybox++) {
5286 const DataIndex& din = dit[mybox];
5293 VoFIterator& vofit = (*m_amr->getVofIterator(m_particleRealm, m_plasmaPhase)[lvl])[din];
5295 if (vofit.size() == 0) {
5299 const EBISBox& ebisbox = ebisl[din];
5300 const EBCellFAB& electricField = (*a_electricField[lvl])[din];
5301 const BaseFab<bool>& validCells = (*m_amr->getValidCells(m_particleRealm)[lvl])[din];
5302 const Box box = dbl[din];
5304 bool isDielectric =
false;
5308 std::vector<std::vector<ParticleSoA<ItoParticle>>> primaryItoCells(numItoSpecies);
5309 std::vector<std::vector<ParticleSoA<ItoParticle>>> secondaryItoCells(numItoSpecies);
5310 std::vector<std::vector<ParticleSoA<Photon>>> primaryPhotonCells(numPhotonSpecies);
5311 std::vector<std::vector<ParticleSoA<Photon>>> secondaryPhotonCells(numPhotonSpecies);
5313 Vector<BaseIVFAB<Real>*> cdrFluxesFAB;
5314 Vector<BaseIVFAB<Real>*> cdrFluxesExtrapFAB;
5316 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
5317 const int idx = it.index();
5319 binLeafToCells(primaryItoCells[idx], (*a_primaryParticles[idx])[lvl][din], box, dx, probLo);
5320 secondaryItoCells[idx].resize(box.numPts());
5323 for (
auto it = m_cdr->iterator(); it.ok(); ++it) {
5324 cdrFluxesFAB.push_back(&((*(a_cdrFluxes[it.index()])[lvl])[din]));
5325 cdrFluxesExtrapFAB.push_back(&((*(a_cdrFluxesExtrap[it.index()])[lvl])[din]));
5328 for (
auto it = m_rte->iterator(); it.ok(); ++it) {
5329 const int idx = it.index();
5331 binLeafToCells(primaryPhotonCells[idx], (*a_primaryPhotons[idx])[lvl][din], box, dx, probLo);
5332 secondaryPhotonCells[idx].resize(box.numPts());
5336 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
5337 const IntVect iv = vof.gridIndex();
5339 if (validCells(iv)) {
5340 const RealVect E = RealVect(D_DECL(electricField(vof, 0), electricField(vof, 1), electricField(vof, 2)));
5341 const RealVect bndryNormal = ebisbox.normal(vof);
5342 const RealVect bndryCentroid = ebisbox.bndryCentroid(vof);
5343 const RealVect cellCentroid = ebisbox.centroid(vof);
5344 const RealVect cellCenter = probLo +
Location::position(Location::Cell::Center, vof, ebisbox, dx);
5345 const RealVect physPos = cellCenter + bndryCentroid * dx;
5346 const Real bndryArea = ebisbox.bndryArea(vof);
5348 const long cellIdx = box.index(iv);
5352 Vector<ParticleSoA<ItoParticle>> secondaryParticles(numItoSpecies);
5353 Vector<ParticleSoA<ItoParticle>> primaryParticles(numItoSpecies);
5355 Vector<Real> cdrFluxes(numCdrSpecies, 0.0);
5356 Vector<Real> cdrFluxesExtrap(numCdrSpecies, 0.0);
5358 Vector<ParticleSoA<Photon>> secondaryPhotons(numPhotonSpecies);
5359 Vector<ParticleSoA<Photon>> primaryPhotons(numPhotonSpecies);
5361 for (
int i = 0; i < numItoSpecies; i++) {
5362 primaryParticles[i] = std::move(primaryItoCells[i][cellIdx]);
5366 for (
int i = 0; i < numCdrSpecies; i++) {
5368 cdrFluxesExtrap[i] = (*cdrFluxesExtrapFAB[i])(vof, 0);
5371 for (
int i = 0; i < numPhotonSpecies; i++) {
5372 primaryPhotons[i] = std::move(primaryPhotonCells[i][cellIdx]);
5377 Real minDist = std::numeric_limits<Real>::max();
5379 for (
int i = 0; i < electrodes.size(); i++) {
5380 const Real curDist = electrodes[i].getImplicitFunction()->value(physPos);
5382 if (std::abs(curDist) < std::abs(minDist)) {
5388 for (
int i = 0; i < dielectrics.size(); i++) {
5389 const Real curDist = dielectrics[i].getImplicitFunction()->value(physPos);
5391 if (std::abs(curDist) < std::abs(minDist)) {
5394 isDielectric =
true;
5399 m_physics->secondaryEmissionEB(secondaryParticles,
5417 for (
int i = 0; i < numItoSpecies; i++) {
5418 secondaryItoCells[i][cellIdx] = std::move(secondaryParticles[i]);
5421 for (
int i = 0; i < numCdrSpecies; i++) {
5422 (*cdrFluxesFAB[i])(vof, 0) = cdrFluxes[i];
5425 for (
int i = 0; i < numPhotonSpecies; i++) {
5426 secondaryPhotonCells[i][cellIdx] = std::move(secondaryPhotons[i]);
5436 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
5437 const int idx = it.index();
5438 rebuildLeafFromCells((*a_secondaryParticles[idx])[lvl][din], secondaryItoCells[idx], box, dx, probLo);
5440 for (
auto it = m_rte->iterator(); it.ok(); ++it) {
5441 const int idx = it.index();
5442 rebuildLeafFromCells((*a_secondaryPhotons[idx])[lvl][din], secondaryPhotonCells[idx], box, dx, probLo);
5448 for (
int i = 0; i < numItoSpecies; i++) {
5449 a_secondaryParticles[i]->organizeParticlesByPatch();
5450 a_primaryParticles[i]->organizeParticlesByPatch();
5453 for (
int i = 0; i < numPhotonSpecies; i++) {
5454 a_secondaryPhotons[i]->organizeParticlesByPatch();
5455 a_primaryPhotons[i]->organizeParticlesByPatch();
5459template <
typename I,
typename C,
typename R,
typename F>
5463 CH_TIME(
"ItoKMCStepper::resolveSecondaryEmissionEB(short)");
5464 if (m_verbosity > 5) {
5465 pout() << m_name +
"::resolveSecondaryEmissionEB(short)" << endl;
5468 Vector<ParticleContainer<ItoParticle>*> secondaryParticles;
5469 Vector<ParticleContainer<ItoParticle>*> primaryParticles;
5471 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
5472 const int idx = it.index();
5474 primaryParticles.push_back(&(it()->getParticles(ItoSolver::WhichContainer::EB)));
5475 secondaryParticles.push_back(&(*m_secondaryParticles[idx]));
5479 Vector<EBAMRIVData*> cdrFluxes;
5480 for (
auto it = m_cdr->iterator(); it.ok(); ++it) {
5481 const RefCountedPtr<CdrSolver>& solver = it();
5482 const int idx = it.index();
5484 EBAMRIVData& ebFlux = solver->getEbFlux();
5486 m_amr->copyData(ebFlux, m_cdrFluxes[idx]);
5488 m_amr->arithmeticAverage(ebFlux, m_fluidRealm, m_plasmaPhase);
5490 cdrFluxes.push_back(&ebFlux);
5494 EBAMRIVData& surfaceChargeDensity = m_sigmaSolver->getPhi();
5496 this->resolveSecondaryEmissionEB(secondaryParticles, primaryParticles, cdrFluxes, surfaceChargeDensity, a_dt);
5498 m_sigmaSolver->resetElectrodes(0.0);
5499 m_amr->arithmeticAverage(surfaceChargeDensity, m_fluidRealm, m_plasmaPhase);
5502template <
typename I,
typename C,
typename R,
typename F>
5506 Vector<EBAMRIVData*>& a_cdrFluxes,
5507 EBAMRIVData& a_surfaceChargeDensity,
5508 const Real a_dt)
noexcept
5510 CH_TIME(
"ItoKMCStepper::resolveSecondaryEmissionEB(full)");
5511 if (m_verbosity > 5) {
5512 pout() << m_name +
"::resolveSecondaryEmissionEB(full)" << endl;
5515 const int numItoSpecies = m_physics->getNumItoSpecies();
5516 const int numCdrSpecies = m_physics->getNumCdrSpecies();
5518 CH_assert(a_secondaryParticles.size() == numItoSpecies);
5519 CH_assert(a_primaryParticles.size() == numItoSpecies);
5520 CH_assert(a_cdrFluxes.size() == numCdrSpecies);
5521 CH_assert(a_surfaceChargeDensity.getRealm() == m_fluidRealm);
5523 for (
int i = 0; i < numItoSpecies; i++) {
5524 CH_assert(a_secondaryParticles[i]->getRealm() == m_particleRealm);
5525 CH_assert(a_primaryParticles[i]->getRealm() == m_particleRealm);
5528 for (
int i = 0; i < numCdrSpecies; i++) {
5529 CH_assert(a_secondaryParticles[i]->getRealm() == m_particleRealm);
5530 CH_assert(a_primaryParticles[i]->getRealm() == m_particleRealm);
5534 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
5535 const RefCountedPtr<ItoSolver>& solver = it();
5536 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
5538 const int idx = it.index();
5539 const int Z = species->getChargeNumber();
5544 m_amr->depositParticles(m_particleScratchEB, m_particleRealm, m_plasmaPhase, *a_primaryParticles[idx]);
5546 m_amr->copyData(m_fluidScratchEB, m_particleScratchEB);
5550 m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase));
5553 m_amr->depositParticles(m_particleScratchEB, m_particleRealm, m_plasmaPhase, *a_secondaryParticles[idx]);
5555 m_amr->copyData(m_fluidScratchEB, m_particleScratchEB);
5559 m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase));
5566 a_primaryParticles[idx]->clearParticles();
5568 if (a_secondaryParticles[idx]->getNumberOfValidParticlesGlobal() > 0) {
5569 MayDay::Abort(
"logic bust");
5574 for (
auto it = m_cdr->iterator(); it.ok(); ++it) {
5575 const RefCountedPtr<CdrSolver>& solver = it();
5576 const RefCountedPtr<CdrSpecies>& species = solver->getSpecies();
5578 const int idx = it.index();
5579 const int Z = species->getChargeNumber();
5585 m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase));
5593 m_amr->allocate(divG, m_fluidRealm, m_plasmaPhase, 1);
5594 m_amr->allocate(G, m_fluidRealm, m_plasmaPhase, 1);
5598 solver->computeDivG(divG, G, *a_cdrFluxes[idx],
false);
5600 EBAMRCellData& phi = solver->getPhi();
5603 m_amr->conservativeAverage(phi, m_fluidRealm, m_plasmaPhase);
5604 m_amr->interpGhostPwl(phi, m_fluidRealm, m_plasmaPhase);
5607 DataOps::floor(phi, 0.0, m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase));
5611 m_amr->conservativeAverage(a_surfaceChargeDensity, m_fluidRealm, m_plasmaPhase);
5614template <
typename I,
typename C,
typename R,
typename F>
5618 CH_TIME(
"ItoKMCStepper::computePhysicsDt()");
5619 if (m_verbosity > 5) {
5620 pout() << m_name +
"::computePhysicsDt()" << endl;
5623 Real maxDt = std::numeric_limits<Real>::max();
5624 Real minDt = std::numeric_limits<Real>::max();
5626 DataOps::getMaxMin(maxDt, minDt, m_kmcDt, 0, m_amr->getMultiCutVofIterator(m_fluidRealm, m_plasmaPhase));
5628 m_physicsDt = minDt;
5631template <
typename I,
typename C,
typename R,
typename F>
5635 CH_TIME(
"ItoKMCStepper::computeDummyPhysicsDt()");
5636 if (m_verbosity > 5) {
5637 pout() << m_name +
"::computeDummyPhysicsDt()" << endl;
5640 const int numItoSpecies = m_physics->getNumItoSpecies();
5641 const int numCdrSpecies = m_physics->getNumCdrSpecies();
5642 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
5645 (this->m_ito)->organizeParticlesByCell(ItoSolver::WhichContainer::Bulk);
5646 this->sortPhotonsByCell(McPhoto::WhichContainer::Bulk);
5647 this->sortPhotonsByCell(McPhoto::WhichContainer::Source);
5651 if (numItoSpecies > 0) {
5652 this->computeReactiveItoParticlesPerCell(m_particleItoPPC);
5654 const Interval srcInterv(0, numItoSpecies - 1);
5655 const Interval dstInterv(0, numItoSpecies - 1);
5657 m_amr->copyData(m_fluidPPC, m_particleItoPPC, dstInterv, srcInterv);
5661 if (numCdrSpecies > 0) {
5662 this->computeReactiveCdrParticlesPerCell(m_fluidCdrPPC);
5664 const Interval srcInterv(0, numCdrSpecies - 1);
5665 const Interval dstInterv(numItoSpecies, numItoSpecies + numCdrSpecies - 1);
5667 m_amr->copyData(m_fluidPPC, m_fluidCdrPPC, dstInterv, srcInterv);
5676 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
5677 this->advanceReactionNetwork(*m_fluidPPC[lvl], *m_fluidYPC[lvl], *m_electricFieldFluid[lvl], lvl, 0.0);
5681 (this->m_ito)->organizeParticlesByPatch(ItoSolver::WhichContainer::Bulk);
5682 this->sortPhotonsByPatch(McPhoto::WhichContainer::Bulk);
5683 this->sortPhotonsByPatch(McPhoto::WhichContainer::Source);
5685 this->computePhysicsDt();
5688template <
typename I,
typename C,
typename R,
typename F>
5692 CH_TIME(
"ItoKMCStepper::computeTotalCharge()");
5693 if (m_verbosity > 5) {
5694 pout() << m_name +
"::computeTotalCharge()" << endl;
5697 const bool kappaScale =
true;
5699 Real totalCharge = 0.0;
5701 totalCharge += this->computeQplus();
5702 totalCharge += this->computeQminu();
5703 totalCharge += this->computeQsurf();
5708template <
typename I,
typename C,
typename R,
typename F>
5712 CH_TIME(
"ItoKMCStepper::computeQplus()");
5713 if (m_verbosity > 5) {
5714 pout() << m_name +
"::computeQplus()" << endl;
5717 const bool kappaScale =
true;
5719 Real totalCharge = 0.0;
5722 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
5723 const RefCountedPtr<ItoSolver>& solver = it();
5724 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
5726 const int Z = species->getChargeNumber();
5736 for (
auto it = m_cdr->iterator(); it.ok(); ++it) {
5737 const RefCountedPtr<CdrSolver>& solver = it();
5738 const RefCountedPtr<CdrSpecies>& species = solver->getSpecies();
5740 const int Z = species->getChargeNumber();
5743 const EBAMRCellData& phi = solver->getPhi();
5745 totalCharge += Z * solver->computeMass(phi, kappaScale);
5752template <
typename I,
typename C,
typename R,
typename F>
5756 CH_TIME(
"ItoKMCStepper::computeQminu()");
5757 if (m_verbosity > 5) {
5758 pout() << m_name +
"::computeQminu()" << endl;
5761 const bool kappaScale =
true;
5763 Real totalCharge = 0.0;
5766 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
5767 const RefCountedPtr<ItoSolver>& solver = it();
5768 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
5770 const int Z = species->getChargeNumber();
5780 for (
auto it = m_cdr->iterator(); it.ok(); ++it) {
5781 const RefCountedPtr<CdrSolver>& solver = it();
5782 const RefCountedPtr<CdrSpecies>& species = solver->getSpecies();
5784 const int Z = species->getChargeNumber();
5787 const EBAMRCellData& phi = solver->getPhi();
5789 totalCharge += Z * solver->computeMass(phi, kappaScale);
5796template <
typename I,
typename C,
typename R,
typename F>
5800 CH_TIME(
"ItoKMCStepper::computeQsurf()");
5801 if (m_verbosity > 5) {
5802 pout() << m_name +
"::computeQsurf()" << endl;
5805 return m_sigmaSolver->computeMass();
5808template <
typename I,
typename C,
typename R,
typename F>
5812 CH_TIME(
"ItoKMCStepper::advancePhotons(Real)");
5813 if (m_verbosity > 5) {
5814 pout() << m_name +
"::advancePhotons(Real)" << endl;
5822 for (
auto solverIt = m_rte->iterator(); solverIt.ok(); ++solverIt) {
5823 RefCountedPtr<McPhoto>& solver = solverIt();
5834 solver->clear(bulkPhotons);
5835 solver->clear(ebPhotons);
5836 solver->clear(domainPhotons);
5838 if (solver->isInstantaneous()) {
5839 solver->clear(photons);
5843 solver->clear(sourcePhotons);
5846 solver->advancePhotonsInstantaneous(bulkPhotons, ebPhotons, domainPhotons, photons);
5851 solver->clear(sourcePhotons);
5854 solver->advancePhotonsTransient(bulkPhotons, ebPhotons, domainPhotons, photons, a_dt);
5859template <
typename I,
typename C,
typename R,
typename F>
5863 CH_TIME(
"ItoKMCStepper::sortPhotonsByCell(McPhoto::WhichContainer)");
5864 if (m_verbosity > 5) {
5865 pout() << m_name +
"::sortPhotonsByCell(McPhoto::WhichContainer)" << endl;
5868 for (
auto solverIt = m_rte->iterator(); solverIt.ok(); ++solverIt) {
5869 solverIt()->sortPhotonsByCell(a_which);
5873template <
typename I,
typename C,
typename R,
typename F>
5877 CH_TIME(
"ItoKMCStepper::sortPhotonsByPatch(McPhoto::WhichContainer)");
5878 if (m_verbosity > 5) {
5879 pout() << m_name +
"::sortPhotonsByPatch(McPhoto::WhichContainer)" << endl;
5882 for (
auto solverIt = m_rte->iterator(); solverIt.ok(); ++solverIt) {
5883 solverIt()->sortPhotonsByPatch(a_which);
5887template <
typename I,
typename C,
typename R,
typename F>
5888Vector<RefCountedPtr<ItoSolver>>
5891 CH_TIME(
"ItoKMCStepper::getLoadBalanceSolvers()");
5892 if (m_verbosity > 5) {
5893 pout() << m_name +
"::getLoadBalanceSolvers()" << endl;
5896 Vector<RefCountedPtr<ItoSolver>> lbSolvers;
5899 bool loadBalanceAll =
false;
5900 for (
int i = 0; i < m_loadBalanceIndices.size(); i++) {
5901 if (m_loadBalanceIndices[i] < 0) {
5902 loadBalanceAll =
true;
5906 if (loadBalanceAll) {
5907 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
5908 lbSolvers.push_back(solverIt());
5912 for (
int i = 0; i < m_loadBalanceIndices.size(); i++) {
5913 RefCountedPtr<ItoSolver>& solver = m_ito->getSolvers()[i];
5915 lbSolvers.push_back(solver);
5922template <
typename I,
typename C,
typename R,
typename F>
5926 CH_TIME(
"TimeStepper::loadBalanceThisRealm");
5927 if (m_verbosity > 5) {
5928 pout() <<
"TimeStepper::loadBalanceThisRealm" << endl;
5933 if (a_realm == m_particleRealm && m_loadBalanceParticles) {
5936 else if (a_realm == m_fluidRealm && m_loadBalanceFluid) {
5943template <
typename I,
typename C,
typename R,
typename F>
5946 Vector<Vector<Box>>& a_boxes,
5947 const std::string& a_realm,
5948 const Vector<DisjointBoxLayout>& a_grids,
5950 const int a_finestLevel)
5952 CH_TIME(
"ItoKMCStepper::loadBalanceBoxes");
5953 if (m_verbosity > 5) {
5954 pout() << m_name +
"::loadBalanceBoxes" << endl;
5957 if (m_loadBalanceParticles && a_realm == m_particleRealm) {
5958 this->loadBalanceParticleRealm(a_procs, a_boxes, a_realm, a_grids, a_lmin, a_finestLevel);
5960 else if (m_loadBalanceFluid && a_realm == m_fluidRealm) {
5961 this->loadBalanceFluidRealm(a_procs, a_boxes, a_realm, a_grids, a_lmin, a_finestLevel);
5965template <
typename I,
typename C,
typename R,
typename F>
5968 Vector<Vector<Box>>& a_boxes,
5969 const std::string a_realm,
5970 const Vector<DisjointBoxLayout>& a_grids,
5972 const int a_finestLevel)
noexcept
5974 CH_TIME(
"ItoKMCStepper::loadBalanceParticleRealm(...)");
5975 if (m_verbosity > 5) {
5976 pout() << m_name +
"::loadBalanceParticleRealm(...)" << endl;
5995 if (!m_loadBalanceParticles) {
5996 MayDay::Error(
"ItoKMCStepper::loadBalanceParticleRealm -- logic bust, should not have been called!");
6000 Vector<RefCountedPtr<ItoSolver>> lbSolvers = this->getLoadBalanceSolvers();
6003 a_procs.resize(1 + a_finestLevel);
6004 a_boxes.resize(1 + a_finestLevel);
6006 for (
int lvl = a_lmin; lvl <= a_finestLevel; lvl++) {
6007 a_procs[lvl] = a_grids[lvl].procIDs();
6008 a_boxes[lvl] = a_grids[lvl].boxArray();
6013 EBAMRCellData totalPPC;
6014 EBAMRCellData speciesPPC;
6016 m_amr->allocate(totalPPC, m_particleRealm, m_plasmaPhase, 1);
6017 m_amr->allocate(speciesPPC, m_particleRealm, m_plasmaPhase, 1);
6024 Vector<RefCountedPtr<EBCoarseToFineInterp>> interpOp(1 + a_finestLevel);
6025 for (
int lvl = 1; lvl <= a_finestLevel; lvl++) {
6026 const EBLevelGrid& eblgFine = *m_amr->getEBLevelGrid(m_particleRealm, m_plasmaPhase)[lvl];
6027 const EBLevelGrid& eblgCoFi = *m_amr->getEBLevelGridCoFi(m_particleRealm, m_plasmaPhase)[lvl - 1];
6028 const EBLevelGrid& eblgCoar = *m_amr->getEBLevelGrid(m_particleRealm, m_plasmaPhase)[lvl - 1];
6029 const int refRat = m_amr->getRefinementRatios()[lvl - 1];
6031 interpOp[lvl] = RefCountedPtr<EBCoarseToFineInterp>(
new EBCoarseToFineInterp(eblgFine, eblgCoFi, eblgCoar, refRat));
6036 for (
int i = 0; i < lbSolvers.size(); i++) {
6037 const EBAMRCellData& oldData = m_loadBalancePPC[i];
6038 const int oldFinestLevel = oldData.size() - 1;
6041 for (
int lvl = 0; lvl <= std::max(0, a_lmin - 1); lvl++) {
6042 oldData[lvl]->copyTo(*speciesPPC[lvl]);
6046 for (
int lvl = std::max(1, a_lmin); lvl <= a_finestLevel; lvl++) {
6047 RefCountedPtr<EBCoarseToFineInterp>& interpolator = interpOp[lvl];
6049 interpolator->interpolate(*speciesPPC[lvl],
6050 *speciesPPC[lvl - 1],
6052 EBCoarseToFineInterp::Type::ConservativePWC);
6056 if (lvl <= std::min(oldFinestLevel, a_finestLevel)) {
6057 oldData[lvl]->copyTo(*speciesPPC[lvl]);
6067 Vector<Vector<long int>> loads(1 + a_finestLevel, 0L);
6068 for (
int lvl = 0; lvl <= a_finestLevel; lvl++) {
6069 const DisjointBoxLayout& dbl = a_grids[lvl];
6070 const DataIterator& dit = dbl.dataIterator();
6072 Vector<long int>& levelLoads = loads[lvl];
6074 levelLoads.resize(dbl.size());
6076 const int nbox = dit.size();
6078#pragma omp parallel for schedule(runtime)
6079 for (
int mybox = 0; mybox < nbox; mybox++) {
6080 const DataIndex& din = dit[mybox];
6082 const Box cellBox = dbl[din];
6083 const EBCellFAB& PPC = (*totalPPC[lvl])[din];
6084 const EBISBox& ebisbox = PPC.getEBISBox();
6085 const BaseFab<bool>& validCells = (*m_amr->getValidCells(m_particleRealm)[lvl])[din];
6086 const FArrayBox& regPPC = PPC.getFArrayBox();
6088 auto regularKernel = [&](
const IntVect& iv) ->
void {
6089 if (validCells(iv, 0) && ebisbox.isRegular(iv)) {
6090 levelLoads[din.intCode()] += (
long int)regPPC(iv, 0);
6094 BoxLoops::loop<D_DECL(1, 1, 1)>(cellBox, regularKernel);
6100 for (LayoutIterator lit = dbl.layoutIterator(); lit.ok(); ++lit) {
6101 const Box cellBox = dbl[lit()];
6103 levelLoads[lit().intCode()] += (
long int)m_loadPerCell * cellBox.numPts();
6113 for (
int lvl = 0; lvl <= a_finestLevel; lvl++) {
6118template <
typename I,
typename C,
typename R,
typename F>
6121 Vector<Vector<Box>>& a_boxes,
6122 const std::string a_realm,
6123 const Vector<DisjointBoxLayout>& a_grids,
6125 const int a_finestLevel)
noexcept
6127 CH_TIME(
"ItoKMCStepper::loadBalanceFluidRealm(...)");
6128 if (m_verbosity > 5) {
6129 pout() << m_name +
"::loadBalanceFluidRealm(...)" << endl;
6132 CH_assert(m_loadBalanceFluid);
6133 CH_assert(a_realm == m_fluidRealm);
6141 a_procs.resize(1 + a_finestLevel);
6142 a_boxes.resize(1 + a_finestLevel);
6147 m_amr->regridOperators(m_fluidRealm, a_lmin);
6150 m_fieldSolver->allocate();
6151 m_fieldSolver->setupSolver();
6158 for (
int lvl = 0; lvl <= a_finestLevel; lvl++) {
6159 Vector<long long> boxLoads = m_fieldSolver->computeLoads(a_grids[lvl], lvl);
6162 a_boxes[lvl] = a_grids[lvl].boxArray();
6169template <
typename I,
typename C,
typename R,
typename F>
6173 CH_TIME(
"ItoKMCStepper::getCheckpointLoads(...)");
6174 if (m_verbosity > 5) {
6175 pout() << m_name +
"::getCheckpointLoads(...)" << endl;
6178 const DisjointBoxLayout& dbl = m_amr->getGrids(a_realm)[a_level];
6179 const int nbox = dbl.size();
6181 Vector<long int> loads(nbox, 0L);
6183 if (m_loadBalanceParticles && a_realm == m_particleRealm) {
6188 Vector<RefCountedPtr<ItoSolver>> loadBalanceProxySolvers = this->getLoadBalanceSolvers();
6190 for (
int isolver = 0; isolver < loadBalanceProxySolvers.size(); isolver++) {
6194 Vector<long int> solverLoads(nbox, 0L);
6195 loadBalanceProxySolvers[isolver]->computeLoads(solverLoads, dbl, a_level);
6198 for (
int ibox = 0; ibox < nbox; ibox++) {
6199 loads[ibox] += solverLoads[ibox];
6205 for (LayoutIterator lit = dbl.layoutIterator(); lit.ok(); ++lit) {
6206 const Box box = dbl[lit()];
6208 loads[lit().intCode()] += lround(m_loadPerCell * box.numPts());
6218template <
typename I,
typename C,
typename R,
typename F>
6222 CH_TIME(
"ItoKMCStepper::computeEdotJSource(a_dt)");
6223 if (m_verbosity > 5) {
6224 pout() << m_name +
"::computeEdotJSource(a_dt)" << endl;
6227 CH_assert(a_dt > 0.0);
6231 CH_assert(m_EdotJ.getRealm() == m_fluidRealm);
6252 m_amr->allocate(computationParticles, m_particleRealm);
6256 const EBAMRCellData potentialPhase = m_amr->alias(m_plasmaPhase, m_fieldSolver->getPotential());
6257 m_amr->copyData(m_particleScratch1, potentialPhase);
6259 m_amr->conservativeAverage(m_particleScratch1, m_particleRealm, m_plasmaPhase);
6260 m_amr->interpGhost(m_particleScratch1, m_particleRealm, m_plasmaPhase);
6262 for (
auto solverIt = m_ito->iterator(); solverIt.ok(); ++solverIt) {
6263 RefCountedPtr<ItoSolver>& solver = solverIt();
6264 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
6266 const int idx = solverIt.index();
6267 const int Z = species->getChargeNumber();
6268 const bool mobile = solver->isMobile();
6269 const bool diffusive = solver->isDiffusive();
6271 if (Z != 0 && (mobile || diffusive)) {
6277 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
6278 const DisjointBoxLayout& dbl = m_amr->getGrids(m_particleRealm)[lvl];
6279 const DataIterator& dit = dbl.dataIterator();
6281 const int nbox = dit.size();
6283#pragma omp parallel for schedule(runtime)
6284 for (
int mybox = 0; mybox < nbox; mybox++) {
6285 const DataIndex& din = dit[mybox];
6290 for (std::size_t i = 0; i < leaf.
size(); i++) {
6291 const RealVect posA = RealVect(D_DECL(leaf.template get<&ItoParticle::old_x>(i),
6292 leaf.template get<&ItoParticle::old_y>(i),
6293 leaf.template get<&ItoParticle::old_z>(i)));
6299 D_DECL(payload.
x0_x = posA[0], payload.
x0_y = posA[1], payload.
x0_z = posA[2]);
6311 solver->getDeposition(),
6316 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
6317 const DisjointBoxLayout& dbl = m_amr->getGrids(m_particleRealm)[lvl];
6318 const DataIterator& dit = dbl.dataIterator();
6320 const int nbox = dit.size();
6322#pragma omp parallel for schedule(runtime)
6323 for (
int mybox = 0; mybox < nbox; mybox++) {
6324 const DataIndex& din = dit[mybox];
6328 double*
const pos[SpaceDim] = {
6333 double*
const alt[SpaceDim] = {D_DECL(comp.template column<&ItoKMCFieldParticle::x0_x>(),
6334 comp.template column<&ItoKMCFieldParticle::x0_y>(),
6335 comp.template column<&ItoKMCFieldParticle::x0_z>())};
6338 for (
int dir = 0; dir < SpaceDim; dir++) {
6339 const double posB = pos[dir][i];
6340 pos[dir][i] = alt[dir][i];
6347 computationParticles.remap();
6354 solver->getDeposition(),
6358 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
6359 const DisjointBoxLayout& dbl = m_amr->getGrids(m_particleRealm)[lvl];
6360 const DataIterator& dit = dbl.dataIterator();
6362 const int nbox = dit.
size();
6364#pragma omp parallel for schedule(runtime)
6365 for (
int mybox = 0; mybox < nbox; mybox++) {
6366 const DataIndex& din = dit[mybox];
6370 double*
const pos[SpaceDim] = {
6373 const double*
const alt[SpaceDim] = {D_DECL(comp.template column<&ItoKMCFieldParticle::x0_x>(),
6374 comp.template column<&ItoKMCFieldParticle::x0_y>(),
6375 comp.template column<&ItoKMCFieldParticle::x0_z>())};
6377 const ParticleReal*
const phiA = comp.template column<&ItoKMCFieldParticle::phiA>();
6378 const ParticleReal*
const phiB = comp.template column<&ItoKMCFieldParticle::phiB>();
6381 for (
int dir = 0; dir < SpaceDim; dir++) {
6382 pos[dir][i] = alt[dir][i];
6386 w[i] *= (phiB[i] - phiA[i]);
6391 computationParticles.remap();
6394 m_amr->depositWeight(m_particleScratch1,
6397 computationParticles,
6398 solver->getDeposition(),
6399 solver->getCoarseFineDeposition(),
6403 m_amr->copyData(m_fluidScratch1, m_particleScratch1);
6412template <
typename I,
typename C,
typename R,
typename F>
6416 CH_TIME(
"ItoKMCStepper::computePhysicsPlotVariables");
6417 if (m_verbosity > 5) {
6418 pout() << m_name +
"::computePhysicsPlotVariables" << endl;
6422 const int numVars = m_physics->getNumberOfPlotVariables();
6423 const int numItoSpecies = m_physics->getNumItoSpecies();
6424 const int numCdrSpecies = m_physics->getNumCdrSpecies();
6425 const int numPlasmaSpecies = m_physics->getNumPlasmaSpecies();
6426 const int numPhotonSpecies = m_physics->getNumPhotonSpecies();
6428 CH_assert(!(a_physicsPlotVars[0].isNull()));
6429 CH_assert(a_physicsPlotVars[0]->nComp() == numVars);
6430 CH_assert(a_physicsPlotVars.getRealm() == m_fluidRealm);
6433 this->computeDensityGradients();
6435 const RealVect probLo = m_amr->getProbLo();
6437 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
6438 const DisjointBoxLayout& dbl = m_amr->getGrids(m_fluidRealm)[lvl];
6439 const DataIterator& dit = dbl.dataIterator();
6440 const EBISLayout& ebisl = m_amr->getEBISLayout(m_fluidRealm, m_plasmaPhase)[lvl];
6441 const Real dx = m_amr->getDx()[lvl];
6443 const int nbox = dit.size();
6445#pragma omp parallel for schedule(runtime)
6446 for (
int mybox = 0; mybox < nbox; mybox++) {
6447 const DataIndex& din = dit[mybox];
6449 const Box& cellBox = dbl[din];
6450 const EBISBox& ebisBox = ebisl[din];
6453 const EBCellFAB& electricField = (*m_electricFieldFluid[lvl])[din];
6454 const FArrayBox& electricFieldReg = electricField.getFArrayBox();
6457 Vector<const EBCellFAB*> densitiesIto(numItoSpecies);
6458 Vector<const EBCellFAB*> densityGradientsIto(numItoSpecies);
6459 Vector<const FArrayBox*> densitiesItoReg(numItoSpecies);
6460 Vector<const FArrayBox*> densityGradientsItoReg(numItoSpecies);
6462 Vector<const EBCellFAB*> densitiesCDR(numCdrSpecies);
6463 Vector<const EBCellFAB*> densityGradientsCDR(numCdrSpecies);
6464 Vector<const FArrayBox*> densitiesCDRReg(numCdrSpecies);
6465 Vector<const FArrayBox*> densityGradientsCDRReg(numCdrSpecies);
6467 for (
auto it = m_ito->iterator(); it.ok(); ++it) {
6468 const RefCountedPtr<ItoSolver>& solver = it();
6470 const int i = it.index();
6472 densitiesIto[i] = &(*(m_fluidPhiIto[i])[lvl])[din];
6473 densitiesItoReg[i] = &(densitiesIto[i]->getFArrayBox());
6474 densityGradientsIto[i] = &(*m_fluidGradPhiIto[i][lvl])[din];
6475 densityGradientsItoReg[i] = &(densityGradientsIto[i]->getFArrayBox());
6478 for (
auto it = m_cdr->iterator(); it.ok(); ++it) {
6479 const RefCountedPtr<CdrSolver>& solver = it();
6480 const EBAMRCellData& phi = solver->getPhi();
6482 const int i = it.index();
6484 densitiesCDR[i] = &(*phi[lvl])[din];
6485 densitiesCDRReg[i] = &(densitiesCDR[i]->getFArrayBox());
6486 densityGradientsCDR[i] = &(*m_fluidGradPhiCDR[i][lvl])[din];
6487 densityGradientsCDRReg[i] = &(densityGradientsCDR[i]->getFArrayBox());
6491 const BaseFab<bool>& validCells = (*m_amr->getValidCells(m_fluidRealm)[lvl])[din];
6494 EBCellFAB& physicsPlotVars = (*a_physicsPlotVars[lvl])[din];
6495 FArrayBox& physicsPlotVarsReg = physicsPlotVars.getFArrayBox();
6498 Vector<Real> densities(numPlasmaSpecies);
6499 Vector<RealVect> densityGradients(numPlasmaSpecies);
6502 auto regularKernel = [&](
const IntVect& iv) ->
void {
6503 if (ebisBox.isRegular(iv) && validCells(iv, 0)) {
6504 const RealVect pos = probLo + dx * (RealVect(iv) + 0.5 * RealVect::Unit);
6505 const RealVect E = RealVect(
6506 D_DECL(electricFieldReg(iv, 0), electricFieldReg(iv, 1), electricFieldReg(iv, 2)));
6509 for (
int i = 0; i < numItoSpecies; i++) {
6510 densities[i] = (*densitiesItoReg[i])(iv, 0);
6511 densityGradients[i] = RealVect(D_DECL((*densityGradientsItoReg[i])(iv, 0),
6512 (*densityGradientsItoReg[i])(iv, 1),
6513 (*densityGradientsItoReg[i])(iv, 2)));
6516 for (
int i = 0; i < numCdrSpecies; i++) {
6517 densities[numItoSpecies + i] = (*densitiesCDRReg[i])(iv, 0);
6518 densityGradients[numItoSpecies + i] = RealVect(D_DECL((*densityGradientsCDRReg[i])(iv, 0),
6519 (*densityGradientsCDRReg[i])(iv, 1),
6520 (*densityGradientsCDRReg[i])(iv, 2)));
6524 const Vector<Real> plotVars = m_physics->getPlotVariables(E, pos, densities, densityGradients, dx, 1.0);
6526 CH_assert(plotVars.size() == numVars);
6528 for (
int i = 0; i < numVars; i++) {
6529 physicsPlotVarsReg(iv, i) = plotVars[i];
6535 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
6536 if (validCells(vof.gridIndex(), 0)) {
6537 const RealVect pos = probLo + dx * (RealVect(vof.gridIndex()) + 0.5 * RealVect::Unit);
6538 const RealVect E = RealVect(D_DECL(electricField(vof, 0), electricField(vof, 1), electricField(vof, 2)));
6541 for (
int i = 0; i < numItoSpecies; i++) {
6542 densities[i] = (*densitiesIto[i])(vof, 0);
6543 densityGradients[i] = RealVect(D_DECL((*densityGradientsIto[i])(vof, 0),
6544 (*densityGradientsIto[i])(vof, 1),
6545 (*densityGradientsIto[i])(vof, 2)));
6548 for (
int i = 0; i < numCdrSpecies; i++) {
6549 densities[numItoSpecies + i] = (*densitiesCDR[i])(vof, 0);
6550 densityGradients[numItoSpecies + i] = RealVect(D_DECL((*densityGradientsCDR[i])(vof, 0),
6551 (*densityGradientsCDR[i])(vof, 1),
6552 (*densityGradientsCDR[i])(vof, 2)));
6556 const Vector<Real> plotVars = m_physics->getPlotVariables(E, pos, densities, densityGradients, dx, 1.0);
6558 CH_assert(plotVars.size() == numVars);
6560 for (
int i = 0; i < numVars; i++) {
6561 physicsPlotVars(vof, i) = plotVars[i];
6567 VoFIterator& vofit = (*m_amr->getVofIterator(m_fluidRealm, m_plasmaPhase)[lvl])[din];
6569 BoxLoops::loop<D_DECL(1, 1, 1)>(cellBox, regularKernel);
6574 m_amr->average(a_physicsPlotVars, m_fluidRealm, m_plasmaPhase, Average::Arithmetic, Interval(0, numVars - 1));
6575 m_amr->interpGhost(a_physicsPlotVars, m_fluidRealm, m_plasmaPhase);
6578#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
@ Native
Deposit as-is, with no cut-cell treatment at all.
@ NGP
Put the particle's entire cloud in its own cell when that cell is a cut cell.
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:76
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:2564
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:1526
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:1772
static void volumeScale(EBAMRCellData &a_data, const Vector< Real > &a_dx)
Scale data by dx^SpaceDim.
Definition CD_DataOps.cpp:2297
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:1940
static void roof(EBAMRCellData &a_lhs, const Real a_value, const Vector< RefCountedPtr< LayoutData< VoFIterator > > > &a_vofIter)
Roof values in data holder. This sets all values above a_value to a_value.
Definition CD_DataOps.cpp:1617
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:3748
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:3561
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:881
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:1448
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:2716
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:946
static void copy(MFAMRCellData &a_dst, const MFAMRCellData &a_src)
Copy data from one data holder to another.
Definition CD_DataOps.cpp:1262
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:149
static void multiplyScalar(EBAMRCellData &a_lhs, const EBAMRCellData &a_rhs)
Multiply data holder by another data holder.
Definition CD_DataOps.cpp:2402
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:52
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:43
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:962
double * weightColumn() noexcept
Raw weight column (double*).
Definition CD_ParticleSoA.H:1167
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:1195
double & weight(const std::size_t a_index) noexcept
Weight of particle i.
Definition CD_ParticleSoA.H:1229
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:1144
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:1546
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:2596
virtual void setupCdr() noexcept
Set up the CDR solvers.
Definition CD_ItoKMCStepperImplem.H:530
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:1487
virtual void computePhysicsPlotVariables(EBAMRCellData &a_physicsPlotVars) noexcept
Compute physics plot variables.
Definition CD_ItoKMCStepperImplem.H:6414
virtual void computePhysicsDt() noexcept
Compute a physics-based maximum time step.
Definition CD_ItoKMCStepperImplem.H:5616
virtual void computeReactiveMeanEnergiesPerCell(EBAMRCellData &a_meanEnergies) noexcept
Compute the mean particle energy in all grid cells.
Definition CD_ItoKMCStepperImplem.H:3879
virtual void parseRuntimeOptions() noexcept override
Parse runtime configurable options.
Definition CD_ItoKMCStepperImplem.H:173
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:1970
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:2477
virtual void setupRadiativeTransfer() noexcept
Set up the radiative transfer solver.
Definition CD_ItoKMCStepperImplem.H:549
virtual void registerRealms() noexcept override
Register realms used for the simulation.
Definition CD_ItoKMCStepperImplem.H:1634
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:5945
virtual Vector< RefCountedPtr< ItoSolver > > getLoadBalanceSolvers() const noexcept
Get the solvers used for load balancing.
Definition CD_ItoKMCStepperImplem.H:5889
virtual void computeSpaceChargeDensity() noexcept
Compute the space charge. Calls the other version.
Definition CD_ItoKMCStepperImplem.H:1997
virtual void fillNeutralDensity() noexcept
Compute the neutral density on the mesh.
Definition CD_ItoKMCStepperImplem.H:1877
virtual void setVoltage(const std::function< Real(const Real a_time)> &a_voltage) noexcept
Set voltage used for the simulation.
Definition CD_ItoKMCStepperImplem.H:1865
virtual void advanceReactionNetwork(const Real a_dt) noexcept
Chemistry advance over time a_dt.
Definition CD_ItoKMCStepperImplem.H:4020
virtual Real getTime() const noexcept
Get current simulation time.
Definition CD_ItoKMCStepperImplem.H:1985
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:6171
virtual void computeDummyPhysicsDt() noexcept
Special routine which performs a dummy KMC advance over a zero time step.
Definition CD_ItoKMCStepperImplem.H:5633
void reconcileParticles(const EBAMRCellData &a_newParticlesPerCell, const EBAMRCellData &a_oldParticlesPerCell, const EBAMRCellData &a_newPhotonsPerCell, const EBAMRCellData &a_cdrProduction, const EBAMRCellData &a_electricField) const noexcept
Reconcile particles. At the bottom, this will call the physics interface for particle reconciliation.
Definition CD_ItoKMCStepperImplem.H:4489
virtual int getNumberOfPlotVariables() const noexcept override
Get number of plot variables for the output file.
Definition CD_ItoKMCStepperImplem.H:985
virtual void remapParticles(const SpeciesSubset a_speciesSubset) noexcept
Remap a subset of ItoSolver particles.
Definition CD_ItoKMCStepperImplem.H:2720
virtual void parseVerbosity() noexcept
Parse chattiness.
Definition CD_ItoKMCStepperImplem.H:201
virtual void computeReactiveCdrParticlesPerCell(EBAMRCellData &a_ppc) noexcept
Compute the number of reactive particles per cell for the CDR solvers.
Definition CD_ItoKMCStepperImplem.H:3772
virtual void registerOperators() noexcept override
Register operators used for the simulation.
Definition CD_ItoKMCStepperImplem.H:1648
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:5967
virtual void averageDiffusionCoefficientsCellToFace() noexcept
Average cell-centered diffusion coefficient to faces.
Definition CD_ItoKMCStepperImplem.H:3582
virtual void parsePlotVariables() noexcept
Parse plot variables.
Definition CD_ItoKMCStepperImplem.H:272
virtual void parseSuperParticles() noexcept
Parse the super-particle merge cadence.
Definition CD_ItoKMCStepperImplem.H:308
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:1143
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:2136
virtual void computeEdotJSource(const Real a_dt) noexcept
Compute the energy source term for the various plasma species.
Definition CD_ItoKMCStepperImplem.H:6220
virtual void parseCdrProducts() noexcept
Parse how the reaction network's CDR production reaches the mesh.
Definition CD_ItoKMCStepperImplem.H:244
virtual bool solvePoisson() noexcept
Solve the electrostatic problem.
Definition CD_ItoKMCStepperImplem.H:2253
virtual Real computeQminu() const noexcept
Compute negative charge.
Definition CD_ItoKMCStepperImplem.H:5754
virtual void multiplyCdrVelocitiesByMobilities() noexcept
Multiply CDR solver velocities by mobilities.
Definition CD_ItoKMCStepperImplem.H:3015
virtual void parseRedistributeCDR() noexcept
Parse CDR mass redistribution when assigning reactive products.
Definition CD_ItoKMCStepperImplem.H:230
virtual void computeCurrentDensity(EBAMRCellData &a_J) noexcept
Compute the current density.
Definition CD_ItoKMCStepperImplem.H:2199
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:1210
virtual void parseTimeStepRestrictions() noexcept
Parse time step restrictions.
Definition CD_ItoKMCStepperImplem.H:401
virtual void fillSecondaryEmissionEB(const Real a_dt) noexcept
Resolve particle injection at EBs.
Definition CD_ItoKMCStepperImplem.H:5157
virtual void initialSigma() noexcept
Fill surface charge solver with initial data taken from the physics interface.
Definition CD_ItoKMCStepperImplem.H:800
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:2292
ItoKMCStepper() noexcept
Default constructor. Sets default options.
Definition CD_ItoKMCStepperImplem.H:98
virtual void printStepReport() noexcept override
Print a step report. Used by Driver for user monitoring of simulation.
Definition CD_ItoKMCStepperImplem.H:1275
virtual void depositParticles(const SpeciesSubset a_speciesSubset) noexcept
Deposit a subset of the ItoSolver particles on the mesh.
Definition CD_ItoKMCStepperImplem.H:2835
virtual void setupSigma() noexcept
Set up the surface charge solver.
Definition CD_ItoKMCStepperImplem.H:586
virtual void setupSolvers() noexcept override
Set up solvers.
Definition CD_ItoKMCStepperImplem.H:495
virtual void parseOptions() noexcept
Parse options.
Definition CD_ItoKMCStepperImplem.H:152
virtual void advancePhotons(const Real a_dt) noexcept
Photon advancement routine.
Definition CD_ItoKMCStepperImplem.H:5810
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:1700
virtual void depositCdrProducts(EBAMRCellData &a_cdrChange) noexcept
Deposit the CDR reaction products in m_cdrProducts and add the result to a per-cell change.
Definition CD_ItoKMCStepperImplem.H:4165
virtual void parseDualGrid() noexcept
Parse dual or single realm calculations.
Definition CD_ItoKMCStepperImplem.H:325
virtual void reconcilePhotoionization() noexcept
Reconcile the results from photoionization reactions.
Definition CD_ItoKMCStepperImplem.H:4895
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:6120
virtual Vector< std::string > getPlotVariableNames() const noexcept override
Get plot variable names.
Definition CD_ItoKMCStepperImplem.H:1038
virtual void sortPhotonsByCell(const McPhoto::WhichContainer a_which) noexcept
Sort photons by cells.
Definition CD_ItoKMCStepperImplem.H:5861
virtual Real computeQplus() const noexcept
Compute positive charge.
Definition CD_ItoKMCStepperImplem.H:5710
virtual void parseLoadBalance() noexcept
Parse load balancing.
Definition CD_ItoKMCStepperImplem.H:348
virtual void computeDriftVelocities() noexcept
Compute ItoSolver velocities.
Definition CD_ItoKMCStepperImplem.H:3041
virtual void setupPoisson() noexcept
Set up the electrostatic field solver.
Definition CD_ItoKMCStepperImplem.H:569
virtual void setupIto() noexcept
Set up the Ito particle solvers.
Definition CD_ItoKMCStepperImplem.H:511
virtual Real computeQsurf() const noexcept
Compute surface charge.
Definition CD_ItoKMCStepperImplem.H:5798
virtual Real computeDt() override
Compute a time step used for the advance method.
Definition CD_ItoKMCStepperImplem.H:1519
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:1256
virtual Real computeTotalCharge() const noexcept
Compute total charge.
Definition CD_ItoKMCStepperImplem.H:5690
virtual void resolveSecondaryEmissionEB(const Real a_dt) noexcept
Resolve secondary emission at the EB.
Definition CD_ItoKMCStepperImplem.H:5461
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:1810
virtual void coarsenCDRSolvers(const bool a_interpGhosts) noexcept
Coarsen data for CDR solvers.
Definition CD_ItoKMCStepperImplem.H:5096
virtual void computeDiffusionCoefficients() noexcept
Compute mesh-based diffusion coefficients for LFA coupling.
Definition CD_ItoKMCStepperImplem.H:3299
virtual void allocateInternals() noexcept
Allocate "internal" storage.
Definition CD_ItoKMCStepperImplem.H:621
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:5924
virtual Real computeMaxReducedElectricField(const phase::which_phase a_phase) const noexcept
Compute the maximum electric field (norm)
Definition CD_ItoKMCStepperImplem.H:1934
virtual void setCdrVelocityFunctions() noexcept
Set the Cdr velocities to be sgn(charge) * E.
Definition CD_ItoKMCStepperImplem.H:2981
virtual void postRegrid() noexcept override
Perform post-regrid operations.
Definition CD_ItoKMCStepperImplem.H:1852
virtual Real computeRelaxationTime() noexcept
Compute the dielectric relaxation time.
Definition CD_ItoKMCStepperImplem.H:2218
virtual void parseParametersEB() noexcept
Parse parameters related to how we treat particle-EB interaction.
Definition CD_ItoKMCStepperImplem.H:479
virtual void initialData() noexcept override
Fill solvers with initial data.
Definition CD_ItoKMCStepperImplem.H:763
virtual void postPlot() noexcept override
Perform post-plot operations.
Definition CD_ItoKMCStepperImplem.H:1688
virtual ~ItoKMCStepper() noexcept
Destructor.
Definition CD_ItoKMCStepperImplem.H:145
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:1392
virtual void computeReactiveItoParticlesPerCell(EBAMRCellData &a_ppc) noexcept
Compute the number of reactive particles per cell.
Definition CD_ItoKMCStepperImplem.H:3648
virtual bool needSecondaryEmissionEB() const noexcept
Whether anything can be emitted from the EB this step, answered globally.
Definition CD_ItoKMCStepperImplem.H:5126
virtual void allocate() noexcept override
Allocate storage for solvers.
Definition CD_ItoKMCStepperImplem.H:603
virtual void parseExitOnFailure() noexcept
Parse exit on failure.
Definition CD_ItoKMCStepperImplem.H:216
virtual void computeConductivityCell(EBAMRCellData &a_conductivity) noexcept
Compute the cell-centered conductiivty.
Definition CD_ItoKMCStepperImplem.H:2068
virtual void postCheckpointPoisson() noexcept
Do some post-checkpoint operations for the electrostatic part.
Definition CD_ItoKMCStepperImplem.H:868
virtual void reconcileCdrDensities(const EBAMRCellData &a_cdrChange, const Real a_dt) noexcept
Reconcile the CDR densities after the reaction network.
Definition CD_ItoKMCStepperImplem.H:4953
virtual void prePlot() noexcept override
Perform pre-plot operations.
Definition CD_ItoKMCStepperImplem.H:1667
virtual void postInitialize() noexcept override
Post-initialization operations. Default does nothing.
Definition CD_ItoKMCStepperImplem.H:753
virtual void postCheckpointSetup() noexcept override
Perform post-checkpoint operations.
Definition CD_ItoKMCStepperImplem.H:849
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:1440
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:1089
virtual void computeMobilities() noexcept
Compute mesh-based mobilities for LFA coupling.
Definition CD_ItoKMCStepperImplem.H:3066
virtual void setItoVelocityFunctions() noexcept
Set the Ito velocity functions. This is sgn(charge) * E.
Definition CD_ItoKMCStepperImplem.H:2950
virtual void sortPhotonsByPatch(const McPhoto::WhichContainer a_which) noexcept
Sort photons by patch.
Definition CD_ItoKMCStepperImplem.H:5875
virtual void getPhysicalParticlesPerCell(EBAMRCellData &a_ppc) const noexcept
Get the physical number of particles per cell.
Definition CD_ItoKMCStepperImplem.H:3626
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:37
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:521
Real standardDeviation(const Real &a_value) noexcept
Compute the standard deviation of the input value.
Definition CD_ParallelOpsImplem.H:533
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