13#ifndef CD_ITOKMCGODUNOVSTEPPERIMPLEM_H
14#define CD_ITOKMCGODUNOVSTEPPERIMPLEM_H
28#include <CD_NamespaceHeader.H>
30using namespace Physics::ItoKMC;
42depositPointParticlesLikeSolver(
const RefCountedPtr<ItoSolver>& a_solver,
46 a_solver->depositWeight(a_phi, a_particles, a_solver->getDeposition(), a_solver->getCoarseFineDeposition());
51template <
typename I,
typename C,
typename R,
typename F>
55 CH_TIME(
"ItoKMCGodunovStepper::ItoKMCGodunovStepper");
57 this->
m_name =
"ItoKMCGodunovStepper";
71template <
typename I,
typename C,
typename R,
typename F>
74 CH_TIME(
"ItoKMCGodunovStepper::~ItoKMCGodunovStepper");
75 if (this->m_verbosity > 5) {
76 pout() <<
"ItoKMCGodunovStepper::~ItoKMCGodunovStepper" << endl;
80template <
typename I,
typename C,
typename R,
typename F>
84 CH_TIME(
"ItoKMCGodunovStepper::registerOperators");
85 if (this->m_verbosity > 5) {
86 pout() <<
"ItoKMCGodunovStepper::registerOperators" << endl;
93 (this->m_amr)->registerOperator(s_particle_mesh, this->m_particleRealm,
phase::solid);
96template <
typename I,
typename C,
typename R,
typename F>
100 CH_TIME(
"ItoKMCGodunovStepper::allocate");
101 if (this->m_verbosity > 5) {
102 pout() <<
"ItoKMCGodunovStepper::allocate" << endl;
110 const int numItoSpecies = this->m_physics->getNumItoSpecies();
112 m_conductivityParticles.resize(numItoSpecies);
113 m_irregularParticles.resize(numItoSpecies);
114 m_rhoDaggerParticles.resize(numItoSpecies);
116 for (
auto solverIt = (this->m_ito)->iterator(); solverIt.ok(); ++solverIt) {
117 const int idx = solverIt.index();
123 (this->m_amr)->allocate(*m_conductivityParticles[idx], this->m_particleRealm);
124 (this->m_amr)->allocate(*m_irregularParticles[idx], this->m_particleRealm);
125 (this->m_amr)->allocate(*m_rhoDaggerParticles[idx], this->m_particleRealm);
129template <
typename I,
typename C,
typename R,
typename F>
133 CH_TIME(
"ItoKMCGodunovStepper::allocateInternals");
134 if (this->m_verbosity > 5) {
135 pout() << this->m_name +
"::allocateInternals" << endl;
140 const int numCdrSpecies = this->m_physics->getNumCdrSpecies();
142 m_cdrDivD.resize(numCdrSpecies);
143 for (
int i = 0; i < numCdrSpecies; i++) {
144 this->m_amr->allocate(m_cdrDivD[i], this->m_fluidRealm, this->m_plasmaPhase, 1);
147 this->m_amr->allocate(m_semiImplicitRhoCDR, this->m_fluidRealm, this->m_plasmaPhase, 1);
148 this->m_amr->allocate(m_semiImplicitConductivityCDR, this->m_fluidRealm, this->m_plasmaPhase, 1);
158 this->m_amr->allocate(m_reactiveElectricField, this->m_fluidRealm, this->m_plasmaPhase, SpaceDim);
161template <
typename I,
typename C,
typename R,
typename F>
165 CH_TIME(
"ItoKMCGodunovStepper::barrier");
166 if (this->m_verbosity > 5) {
167 pout() << this->m_name +
"::barrier" << endl;
170 if ((this->m_profile)) {
175template <
typename I,
typename C,
typename R,
typename F>
179 CH_TIME(
"ItoKMCGodunovStepper::parseOptions");
180 if (this->m_verbosity > 5) {
181 pout() << this->m_name +
"::parseOptions" << endl;
186 this->parseAlgorithm();
187 this->parseFiltering();
188 this->parseCheckpointParticles();
189 this->parseSecondaryEmissionSpecification();
190 this->parseReactiveFieldCentering();
193template <
typename I,
typename C,
typename R,
typename F>
197 CH_TIME(
"ItoKMCGodunovStepper::parseRuntimeOptions");
198 if (this->m_verbosity > 5) {
199 pout() << this->m_name +
"::parseRuntimeOptions" << endl;
204 this->parseAlgorithm();
205 this->parseFiltering();
206 this->parseCheckpointParticles();
207 this->parseSecondaryEmissionSpecification();
208 this->parseReactiveFieldCentering();
211template <
typename I,
typename C,
typename R,
typename F>
215 CH_TIME(
"ItoKMCGodunovStepper::parseAlgorithm");
216 if (this->m_verbosity > 5) {
217 pout() << this->m_name +
"::parseAlgorithm" << endl;
220 ParmParse pp(this->m_name.c_str());
223 pp.get(
"extend_conductivity", m_extendConductivityEB);
224 pp.get(
"algorithm", str);
225 pp.get(
"abort_max_field", m_maxFieldAbort);
228 if (str ==
"euler_maruyama") {
229 m_algorithm = WhichAlgorithm::EulerMaruyama;
232 MayDay::Abort(
"ItoKMCGodunovStepper::parseAlgorithm - unknown algorithm requested");
236template <
typename I,
typename C,
typename R,
typename F>
240 CH_TIME(
"ItoKMCGodunovStepper::parseFiltering");
241 if (this->m_verbosity > 5) {
242 pout() << this->m_name +
"::parseFiltering" << endl;
245 ParmParse pp(this->m_name.c_str());
249 m_rhoFilterMaxStride = 1;
250 m_rhoFilterAlpha = 0.5;
252 m_condFilterNum = -1;
253 m_condFilterMaxStride = 1;
254 m_condFilterAlpha = 0.5;
256 pp.get(
"rho_filter_num", m_rhoFilterNum);
257 pp.get(
"rho_filter_max_stride", m_rhoFilterMaxStride);
258 pp.get(
"rho_filter_alpha", m_rhoFilterAlpha);
260 pp.get(
"cond_filter_num", m_condFilterNum);
261 pp.get(
"cond_filter_max_stride", m_condFilterMaxStride);
262 pp.get(
"cond_filter_alpha", m_condFilterAlpha);
264 if (m_rhoFilterAlpha <= 0.0 || m_rhoFilterAlpha >= 1.0) {
265 MayDay::Abort(
"ItoKMCGodunovStepper::parseFiltering -- cannot have alpha <= 0 or alpha >= 1 for rho_filter");
267 if (m_condFilterAlpha <= 0.0 || m_condFilterAlpha >= 1.0) {
268 MayDay::Abort(
"ItoKMCGodunovStepper::parseFiltering -- cannot have alpha <= 0 or alpha >= 1 for cond_filter");
272template <
typename I,
typename C,
typename R,
typename F>
276 CH_TIME(
"ItoKMCGodunovStepper::parseCheckpointParticles");
277 if (this->m_verbosity > 5) {
278 pout() << this->m_name +
"::parseCheckpointParticles" << endl;
281 ParmParse pp(this->m_name.c_str());
283 pp.query(
"checkpoint_particles", m_writeCheckpointParticles);
286template <
typename I,
typename C,
typename R,
typename F>
290 CH_TIME(
"ItoKMCGodunovStepper::parseSecondaryEmissionSpecifiation");
291 if (this->m_verbosity > 5) {
292 pout() << this->m_name +
"::parseSecondaryEmissionSpecification" << endl;
295 ParmParse pp(this->m_name.c_str());
299 pp.query(
"secondary_emission", str);
301 if (str ==
"before_reactions") {
302 m_emitSecondaryParticlesBeforeReactions =
true;
304 else if (str ==
"after_reactions") {
305 m_emitSecondaryParticlesBeforeReactions =
false;
310 err =
"ItoKMCGodunovStepper::parseSecondaryEmissionSpecification - expected 'before_reactions' or 'after_reactions'";
311 err +=
"but got" + str;
313 MayDay::Abort(err.c_str());
317template <
typename I,
typename C,
typename R,
typename F>
321 CH_TIME(
"ItoKMCGodunovStepper::parseReactiveFieldCentering");
322 if (this->m_verbosity > 5) {
323 pout() << this->m_name +
"::parseReactiveFieldCentering" << endl;
326 ParmParse pp(this->m_name.c_str());
328 pp.get(
"reactive_E_centering", m_reactiveFieldCentering);
332 if (m_reactiveFieldCentering < 0.0 || m_reactiveFieldCentering > 1.0) {
333 MayDay::Abort(
"ItoKMCGodunovStepper::parseReactiveFieldCentering -- 'reactive_E_centering' must lie in [0,1]");
337template <
typename I,
typename C,
typename R,
typename F>
341 CH_TIME(
"ItoKMCGodunovStepper::computeDt");
342 if (this->m_verbosity > 5) {
343 pout() << this->m_name +
"::computeDt" << endl;
348 if ((this->m_maxReducedField > m_maxFieldAbort) && (m_maxFieldAbort > 0.0)) {
349 pout() << this->m_name +
" stopping because maximum field is too high (" << this->m_maxReducedField <<
")" << endl;
351 this->m_keepGoing =
false;
357template <
typename I,
typename C,
typename R,
typename F>
361 CH_TIME(
"ItoKMCGodunovStepper::advance");
362 if (this->m_verbosity > 5) {
363 pout() << this->m_name +
"::advance" << endl;
370 m_canRegridOnRestart =
true;
372 m_timer =
Timer(
"ItoKMCGodunovStepper::advance");
375 this->m_prevDt = a_dt;
378 m_timer.startEvent(
"Deposit photons");
379 for (
auto solverIt = (this->m_rte)->iterator(); solverIt.ok(); ++solverIt) {
380 RefCountedPtr<McPhoto> solver = solverIt();
382 EBAMRCellData& phi = solver->getPhi();
385 solver->depositPhotons(phi, photons, DepositionType::NGP);
387 m_timer.stopEvent(
"Deposit photons");
391 m_timer.startEvent(
"Store E^k");
392 DataOps::copy(m_reactiveElectricField, this->m_electricFieldFluid);
393 m_timer.stopEvent(
"Store E^k");
397 switch (m_algorithm) {
398 case WhichAlgorithm::EulerMaruyama: {
399 this->advanceEulerMaruyama(a_dt);
404 MayDay::Abort(
"ItoKMCGodunovStepper::advance - logic bust");
413 m_timer.startEvent(
"EB/Particle intersection");
414 if (m_extendConductivityEB) {
423 const std::size_t i) ->
void {
424 leaf.template get<&ItoParticle::scratch>(i) = 1.0;
428 leaf.template get<&ItoParticle::scratch>(i) = -1.0;
432 for (
auto it = this->m_ito->iterator(); it.ok(); ++it) {
437 const bool deleteParticles =
false;
438 this->intersectParticles(SpeciesSubset::AllMobileOrDiffusive, deleteParticles, nonDeletionModifier);
441 for (
auto it = this->m_ito->iterator(); it.ok(); ++it) {
442 const RefCountedPtr<ItoSolver>& solver = it();
443 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
445 const int idx = it.index();
446 const int Z = species->getChargeNumber();
454 if (Z != 0 && solver->isMobile()) {
455 for (
int lvl = 0; lvl <= (this->m_amr)->getFinestLevel(); lvl++) {
456 const DisjointBoxLayout& dbl = (this->m_amr)->getGrids((this->m_particleRealm))[lvl];
457 const DataIterator& dit = dbl.dataIterator();
459 const int nbox = dit.size();
461#pragma omp parallel for schedule(runtime)
462 for (
int mybox = 0; mybox < nbox; mybox++) {
463 const DataIndex& din = dit[mybox];
468 for (std::size_t i = 0; i < leaf.
size(); i++) {
469 if (leaf.template get<&ItoParticle::scratch>(i) < 0.0) {
470 const RealVect pos = leaf.
position(i);
471 const Real weight = leaf.
weight(i);
472 const Real mobility = leaf.template get<&ItoParticle::mobility>(i);
474 pointParticles.
append(pos, weight * mobility);
483 for (
auto it = this->m_ito->iterator(); it.ok(); ++it) {
486 for (
int lvl = 0; lvl <= (this->m_amr)->getFinestLevel(); lvl++) {
487 const DisjointBoxLayout& dbl = (this->m_amr)->getGrids((this->m_particleRealm))[lvl];
488 const DataIterator& dit = dbl.dataIterator();
490 const int nbox = dit.size();
492#pragma omp parallel for schedule(runtime)
493 for (
int mybox = 0; mybox < nbox; mybox++) {
494 const DataIndex& din = dit[mybox];
499 while (i < leaf.
size()) {
500 if (leaf.template get<&ItoParticle::scratch>(i) < 0.0) {
512 const bool deleteParticles =
true;
514 this->intersectParticles(SpeciesSubset::AllMobileOrDiffusive, deleteParticles);
519 for (
auto it = this->m_ito->iterator(); it.ok(); ++it) {
520 const RefCountedPtr<ItoSolver>& solver = it();
525 this->m_amr->transferIrregularParticles(ebParticles, bulkParticles, this->m_plasmaPhase);
527 m_timer.stopEvent(
"EB/Particle intersection");
532 m_timer.startEvent(
"Photon transport");
533 this->advancePhotons(a_dt);
534 m_timer.stopEvent(
"Photon transport");
537 if ((this->m_physics)->needGradients()) {
538 m_timer.startEvent(
"Gradient calculation");
539 (this->m_ito)->depositParticles();
540 this->computeDensityGradients();
541 m_timer.stopEvent(
"Gradient calculation");
546 if (m_emitSecondaryParticlesBeforeReactions) {
548 m_timer.startEvent(
"EB particle injection");
549 this->fillSecondaryEmissionEB(a_dt);
550 this->resolveSecondaryEmissionEB(a_dt);
551 m_timer.stopEvent(
"EB particle injection");
556 m_timer.startEvent(
"Sort by cell");
557 (this->m_ito)->organizeParticlesByCell(ItoSolver::WhichContainer::Bulk);
558 this->sortPhotonsByCell(McPhoto::WhichContainer::Bulk);
559 this->sortPhotonsByCell(McPhoto::WhichContainer::Source);
560 m_timer.stopEvent(
"Sort by cell");
570 m_timer.startEvent(
"Reaction network");
571 DataOps::scale(m_reactiveElectricField, 1.0 - m_reactiveFieldCentering);
572 DataOps::incr(m_reactiveElectricField, this->m_electricFieldFluid, m_reactiveFieldCentering);
573 this->advanceReactionNetwork(m_reactiveElectricField, a_dt);
574 m_timer.stopEvent(
"Reaction network");
581 m_timer.startEvent(
"Make superparticles");
582 if (this->m_mergeInterval > 0 && (this->m_timeStep + 1) % this->m_mergeInterval == 0) {
583 (this->m_ito)->makeSuperparticles(ItoSolver::WhichContainer::Bulk);
585 m_timer.stopEvent(
"Make superparticles");
589 m_timer.startEvent(
"Sort by patch");
590 (this->m_ito)->organizeParticlesByPatch(ItoSolver::WhichContainer::Bulk);
591 this->sortPhotonsByPatch(McPhoto::WhichContainer::Bulk);
592 this->sortPhotonsByPatch(McPhoto::WhichContainer::Source);
593 m_timer.stopEvent(
"Sort by patch");
597 if (!m_emitSecondaryParticlesBeforeReactions) {
599 m_timer.startEvent(
"EB particle injection");
600 this->fillSecondaryEmissionEB(a_dt);
601 this->resolveSecondaryEmissionEB(a_dt);
602 m_timer.stopEvent(
"EB particle injection");
608 m_timer.startEvent(
"Remove covered");
609 this->removeCoveredParticles(SpeciesSubset::AllMobileOrDiffusive, EBRepresentation::Discrete, this->m_toleranceEB);
610 m_timer.stopEvent(
"Remove covered");
613 for (
auto solverIt = (this->m_ito)->iterator(); solverIt.ok(); ++solverIt) {
614 solverIt()->clear(ItoSolver::WhichContainer::EB);
615 solverIt()->clear(ItoSolver::WhichContainer::Domain);
620 m_timer.startEvent(
"Post-compute v");
621 this->computeDriftVelocities();
622 m_timer.stopEvent(
"Post-compute v");
625 m_timer.startEvent(
"Post-compute D");
626 this->computeDiffusionCoefficients();
627 m_timer.stopEvent(
"Post-compute D");
629 this->computePhysicsDt();
631 if ((this->m_profile)) {
632 m_timer.eventReport(pout(),
false);
638 this->m_maxReducedField = this->computeMaxReducedElectricField(this->m_plasmaPhase);
643template <
typename I,
typename C,
typename R,
typename F>
647 CH_TIME(
"ItoKMCGodunovStepper::preRegrid");
648 if (this->m_verbosity > 5) {
649 pout() <<
"ItoKMCGodunovStepper::preRegrid" << endl;
652 const int numItoSpecies = (this->m_physics)->getNumItoSpecies();
653 const int numCdrSpecies = (this->m_physics)->getNumCdrSpecies();
654 const int numPlasmaSpecies = (this->m_physics)->getNumPlasmaSpecies();
655 const int numPhotonSpecies = (this->m_physics)->getNumPhotonSpecies();
659 for (
auto solverIt = (this->m_ito)->iterator(); solverIt.ok(); ++solverIt) {
660 const int idx = solverIt.index();
662 m_conductivityParticles[idx]->preRegrid();
663 m_irregularParticles[idx]->preRegrid();
664 m_rhoDaggerParticles[idx]->preRegrid();
667 this->m_amr->allocate(m_scratchSemiImplicitRhoCDR, this->m_fluidRealm, this->m_plasmaPhase, 1);
668 this->m_amr->allocate(m_scratchSemiImplicitConductivityCDR, this->m_fluidRealm, this->m_plasmaPhase, 1);
670 DataOps::copy(m_scratchSemiImplicitRhoCDR, m_semiImplicitRhoCDR);
671 DataOps::copy(m_scratchSemiImplicitConductivityCDR, m_semiImplicitConductivityCDR);
674 for (
int i = 0; i < numCdrSpecies; i++) {
675 m_cdrDivD[i].clear();
678 m_semiImplicitRhoCDR.clear();
679 m_semiImplicitConductivityCDR.clear();
682template <
typename I,
typename C,
typename R,
typename F>
685 const int a_oldFinestLevel,
686 const int a_newFinestLevel)
noexcept
688 CH_TIME(
"ItoKMCGodunovStepper::regrid");
689 if (this->m_verbosity > 5) {
690 pout() <<
"ItoKMCGodunovStepper::regrid" << endl;
693 m_timer =
Timer(
"ItoKMCGodunovStepper::regrid");
697 if (!m_canRegridOnRestart) {
698 const std::string baseErr =
"ItoKMCGodunovStepper::regrid -- can't regrid because";
699 const std::string err1 =
"checkpoint file does not contain particles. Set Driver.initial_regrids=0";
701 pout() << baseErr + err1 << endl;
703 MayDay::Error((baseErr + err1).c_str());
707 m_timer.startEvent(
"Regrid ItoSolver");
708 (this->m_ito)->regrid(a_lmin, a_oldFinestLevel, a_newFinestLevel);
709 if (this->m_timeStep == 0) {
713 (this->m_ito)->depositParticles();
715 m_timer.stopEvent(
"Regrid ItoSolver");
717 m_timer.startEvent(
"Regrid CdrSolver");
718 (this->m_cdr)->regrid(a_lmin, a_oldFinestLevel, a_newFinestLevel);
719 m_timer.stopEvent(
"Regrid CdrSolver");
721 m_timer.startEvent(
"Regrid FieldSolver");
722 (this->m_fieldSolver)->regrid(a_lmin, a_oldFinestLevel, a_newFinestLevel);
723 m_timer.stopEvent(
"Regrid FieldSolver");
725 m_timer.startEvent(
"Regrid RTE");
726 (this->m_rte)->regrid(a_lmin, a_oldFinestLevel, a_newFinestLevel);
727 m_timer.stopEvent(
"Regrid RTE");
729 m_timer.startEvent(
"Regrid SurfaceODESolver");
730 this->m_sigmaSolver->regrid(a_lmin, a_oldFinestLevel, a_newFinestLevel);
731 m_timer.stopEvent(
"Regrid SurfaceODESolver");
734 m_timer.startEvent(
"Allocate internals");
735 this->allocateInternals();
736 m_timer.stopEvent(
"Allocate internals");
739 m_timer.startEvent(
"Remap algorithm-particles");
740 for (
auto solverIt = (this->m_ito)->iterator(); solverIt.ok(); ++solverIt) {
741 const int idx = solverIt.index();
742 (this->m_amr)->remapToNewGrids(*m_rhoDaggerParticles[idx], a_lmin, a_newFinestLevel);
743 (this->m_amr)->remapToNewGrids(*m_conductivityParticles[idx], a_lmin, a_newFinestLevel);
744 (this->m_amr)->remapToNewGrids(*m_irregularParticles[idx], a_lmin, a_newFinestLevel);
746 m_timer.stopEvent(
"Remap algorithm-particles");
749 this->m_amr->interpToNewGrids(m_semiImplicitRhoCDR,
750 m_scratchSemiImplicitRhoCDR,
755 EBCoarseToFineInterp::Type::ConservativeMinMod);
757 this->m_amr->interpToNewGrids(m_semiImplicitConductivityCDR,
758 m_scratchSemiImplicitConductivityCDR,
763 EBCoarseToFineInterp::Type::ConservativeMinMod);
767 m_timer.startEvent(
"Setup field solver");
768 (this->m_fieldSolver)->setupSolver();
769 this->computeConductivities(m_conductivityParticles,
true);
770 this->setupSemiImplicitPoisson(this->m_prevDt);
771 m_timer.stopEvent(
"Setup field solver");
774 m_timer.startEvent(
"Solve Poisson");
775 if (this->m_timeStep == 0) {
776 this->computeSpaceChargeDensity();
779 this->depositPointParticles(m_rhoDaggerParticles, SpeciesSubset::All);
780 this->computeSemiImplicitRho();
783 const bool converged = this->solvePoisson();
786 const std::string errMsg =
"ItoKMCGodunovStepper::regrid - Poisson solve did not converge after regrid";
788 pout() << errMsg << endl;
790 if (this->m_abortOnFailure) {
791 MayDay::Error(errMsg.c_str());
794 m_timer.stopEvent(
"Solve Poisson");
810 m_timer.startEvent(
"Deposit particles");
811 (this->m_ito)->depositParticles();
812 m_timer.stopEvent(
"Deposit particles");
815 m_timer.startEvent(
"Prepare next step");
816 this->computeDiffusionCoefficients();
817 this->computeDriftVelocities();
818 m_timer.stopEvent(
"Prepare next step");
820 m_timer.eventReport(pout(),
false);
823 m_scratchSemiImplicitRhoCDR.clear();
824 m_scratchSemiImplicitConductivityCDR.clear();
827 this->fillNeutralDensity();
830template <
typename I,
typename C,
typename R,
typename F>
834 CH_TIME(
"ItoKMCGodunovStepper::setOldPositions");
835 if (this->m_verbosity > 5) {
836 pout() << this->m_name +
"::setOldPositions" << endl;
839 for (
auto solverIt = (this->m_ito)->iterator(); solverIt.ok(); ++solverIt) {
840 RefCountedPtr<ItoSolver>& solver = solverIt();
842 for (
int lvl = 0; lvl <= (this->m_amr)->getFinestLevel(); lvl++) {
843 const DisjointBoxLayout& dbl = (this->m_amr)->getGrids((this->m_particleRealm))[lvl];
844 const DataIterator& dit = dbl.dataIterator();
846 auto& particles = solver->getParticles(ItoSolver::WhichContainer::Bulk)[lvl];
848 const int nbox = dit.size();
850#pragma omp parallel for schedule(runtime)
851 for (
int mybox = 0; mybox < nbox; mybox++) {
852 const DataIndex& din = dit[mybox];
857 double*
const oldPos[SpaceDim] = {D_DECL(leaf.template column<&ItoParticle::old_x>(),
858 leaf.template column<&ItoParticle::old_y>(),
859 leaf.template column<&ItoParticle::old_z>())};
862 D_DECL(oldPos[0][i] = pos[0][i], oldPos[1][i] = pos[1][i], oldPos[2][i] = pos[2][i]);
869template <
typename I,
typename C,
typename R,
typename F>
874 CH_TIME(
"ItoKMCGodunovStepper::remapPointParticles");
875 if (this->m_verbosity > 5) {
876 pout() << this->m_name +
"::remapPointParticles" << endl;
879 for (
auto solverIt = (this->m_ito)->iterator(); solverIt.ok(); ++solverIt) {
880 RefCountedPtr<ItoSolver>& solver = solverIt();
881 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
883 const int idx = solverIt.index();
885 const bool mobile = solver->isMobile();
886 const bool diffusive = solver->isDiffusive();
887 const bool charged = species->getChargeNumber() != 0;
890 case SpeciesSubset::All: {
891 a_particles[idx]->remap();
895 case SpeciesSubset::AllMobile: {
897 a_particles[idx]->remap();
902 case SpeciesSubset::AllDiffusive: {
904 a_particles[idx]->remap();
909 case SpeciesSubset::AllMobileOrDiffusive: {
910 if (mobile || diffusive) {
911 a_particles[idx]->remap();
916 case SpeciesSubset::AllMobileAndDiffusive: {
917 if (mobile && diffusive) {
918 a_particles[idx]->remap();
923 case SpeciesSubset::Charged: {
925 a_particles[idx]->remap();
930 case SpeciesSubset::ChargedMobile: {
931 if (charged && mobile) {
932 a_particles[idx]->remap();
937 case SpeciesSubset::ChargedDiffusive: {
938 if (charged && diffusive) {
939 a_particles[idx]->remap();
944 case SpeciesSubset::ChargedMobileOrDiffusive: {
945 if (charged && (mobile || diffusive)) {
946 a_particles[idx]->remap();
951 case SpeciesSubset::ChargedMobileAndDiffusive: {
952 if (charged && (mobile && diffusive)) {
953 a_particles[idx]->remap();
958 case SpeciesSubset::Stationary: {
959 if (!mobile && !diffusive) {
960 a_particles[idx]->remap();
966 MayDay::Abort(
"ItoKMCGodunovStepper::remapPointParticles - logic bust");
974template <
typename I,
typename C,
typename R,
typename F>
980 CH_TIME(
"ItoKMCGodunovStepper::depositPointParticles");
981 if (this->m_verbosity > 5) {
982 pout() << this->m_name +
"::depositPointParticles" << endl;
985 for (
auto solverIt = (this->m_ito)->iterator(); solverIt.ok(); ++solverIt) {
986 RefCountedPtr<ItoSolver>& solver = solverIt();
987 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
989 const int idx = solverIt.index();
991 const bool mobile = solver->isMobile();
992 const bool diffusive = solver->isDiffusive();
993 const bool charged = species->getChargeNumber() != 0;
996 case SpeciesSubset::All: {
997 depositPointParticlesLikeSolver(solver, solver->getPhi(), *a_particles[idx]);
1001 case SpeciesSubset::AllMobile: {
1003 depositPointParticlesLikeSolver(solver, solver->getPhi(), *a_particles[idx]);
1008 case SpeciesSubset::AllDiffusive: {
1010 depositPointParticlesLikeSolver(solver, solver->getPhi(), *a_particles[idx]);
1015 case SpeciesSubset::AllMobileOrDiffusive: {
1016 if (mobile || diffusive) {
1017 depositPointParticlesLikeSolver(solver, solver->getPhi(), *a_particles[idx]);
1021 case SpeciesSubset::AllMobileAndDiffusive: {
1022 if (mobile && diffusive) {
1023 depositPointParticlesLikeSolver(solver, solver->getPhi(), *a_particles[idx]);
1027 case SpeciesSubset::Charged: {
1029 depositPointParticlesLikeSolver(solver, solver->getPhi(), *a_particles[idx]);
1033 case SpeciesSubset::ChargedMobile: {
1034 if (charged && mobile) {
1035 depositPointParticlesLikeSolver(solver, solver->getPhi(), *a_particles[idx]);
1039 case SpeciesSubset::ChargedDiffusive: {
1040 if (charged && diffusive) {
1041 depositPointParticlesLikeSolver(solver, solver->getPhi(), *a_particles[idx]);
1046 case SpeciesSubset::ChargedMobileOrDiffusive: {
1047 if (charged && (mobile || diffusive)) {
1048 depositPointParticlesLikeSolver(solver, solver->getPhi(), *a_particles[idx]);
1053 case SpeciesSubset::ChargedMobileAndDiffusive: {
1054 if (charged && (mobile && diffusive)) {
1055 depositPointParticlesLikeSolver(solver, solver->getPhi(), *a_particles[idx]);
1060 case SpeciesSubset::Stationary: {
1061 if (!mobile && !diffusive) {
1062 depositPointParticlesLikeSolver(solver, solver->getPhi(), *a_particles[idx]);
1068 MayDay::Abort(
"ItoKMCGodunovStepper::depositPointParticles - logic bust");
1076template <
typename I,
typename C,
typename R,
typename F>
1082 CH_TIME(
"ItoKMCGodunovStepper::clearPointParticles");
1083 if (this->m_verbosity > 5) {
1084 pout() << this->m_name +
"::clearPointParticles" << endl;
1087 for (
auto solverIt = (this->m_ito)->iterator(); solverIt.ok(); ++solverIt) {
1088 RefCountedPtr<ItoSolver>& solver = solverIt();
1089 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
1091 const int idx = solverIt.index();
1093 const bool mobile = solver->isMobile();
1094 const bool diffusive = solver->isDiffusive();
1095 const bool charged = species->getChargeNumber() != 0;
1098 case SpeciesSubset::All: {
1099 a_particles[idx]->clearParticles();
1103 case SpeciesSubset::AllMobile: {
1105 a_particles[idx]->clearParticles();
1110 case SpeciesSubset::AllDiffusive: {
1112 a_particles[idx]->clearParticles();
1117 case SpeciesSubset::AllMobileOrDiffusive: {
1118 if (mobile || diffusive) {
1119 a_particles[idx]->clearParticles();
1124 case SpeciesSubset::AllMobileAndDiffusive: {
1125 if (mobile && diffusive) {
1126 a_particles[idx]->clearParticles();
1131 case SpeciesSubset::Charged: {
1133 a_particles[idx]->clearParticles();
1138 case SpeciesSubset::ChargedMobile: {
1139 if (charged && mobile) {
1140 a_particles[idx]->clearParticles();
1145 case SpeciesSubset::ChargedDiffusive: {
1146 if (charged && diffusive) {
1147 a_particles[idx]->clearParticles();
1152 case SpeciesSubset::ChargedMobileOrDiffusive: {
1153 if (charged && (mobile || diffusive)) {
1154 a_particles[idx]->clearParticles();
1159 case SpeciesSubset::ChargedMobileAndDiffusive: {
1160 if (charged && (mobile && diffusive)) {
1161 a_particles[idx]->clearParticles();
1166 case SpeciesSubset::Stationary: {
1167 if (!mobile && !diffusive) {
1168 a_particles[idx]->clearParticles();
1174 MayDay::Abort(
"ItoKMCGodunovStepper::clearPointParticles - logic bust");
1182template <
typename I,
typename C,
typename R,
typename F>
1186 CH_TIME(
"ItoKMCGodunovStepper::computeCdrConductivity");
1187 if (this->m_verbosity > 5) {
1188 pout() << this->m_name +
"::computeCdrConductivity" << endl;
1193 for (
auto solverIt = (this->m_cdr)->iterator(); solverIt.ok(); ++solverIt) {
1194 const RefCountedPtr<CdrSolver>& solver = solverIt();
1195 const RefCountedPtr<CdrSpecies>& species = solver->getSpecies();
1197 const int index = solverIt.index();
1198 const int Z = species->getChargeNumber();
1200 if (Z != 0 && solver->isMobile()) {
1201 const EBAMRCellData& phi = solver->getPhi();
1202 const EBAMRCellData& mu = this->m_cdrMobilities[index];
1207 DataOps::incr(m_semiImplicitConductivityCDR, this->m_fluidScratch1, 1.0 * std::abs(Z));
1212template <
typename I,
typename C,
typename R,
typename F>
1216 const bool a_useStoredCdrConductivity)
noexcept
1218 CH_TIME(
"ItoKMCGodunovStepper::computeConductivities");
1219 if (this->m_verbosity > 5) {
1220 pout() << this->m_name +
"::computeConductivities" << endl;
1223 this->computeCellConductivity((this->m_conductivityCell), a_particles, a_useStoredCdrConductivity);
1224 this->computeFaceConductivity();
1227template <
typename I,
typename C,
typename R,
typename F>
1230 EBAMRCellData& a_conductivityCell,
1232 const bool a_useStoredCdrConductivity)
noexcept
1234 CH_TIME(
"ItoKMCGodunovStepper::computeCellConductivity(EBAMRCellData, ParticleContainer)");
1235 if (this->m_verbosity > 5) {
1236 pout() << this->m_name +
"::computeCellConductivity(EBAMRCellData, ParticleContainer)" << endl;
1242 for (
auto solverIt = (this->m_ito)->iterator(); solverIt.ok(); ++solverIt) {
1243 RefCountedPtr<ItoSolver>& solver = solverIt();
1244 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
1246 const int idx = solverIt.index();
1247 const int Z = species->getChargeNumber();
1249 if (Z != 0 && solver->isMobile()) {
1252 depositPointParticlesLikeSolver(solver, this->m_particleScratch1, *a_particles[idx]);
1255 (this->m_amr)->copyData(this->m_fluidScratch1, this->m_particleScratch1);
1256 DataOps::incr(a_conductivityCell, this->m_fluidScratch1, 1.0 * std::abs(Z));
1263 if (!a_useStoredCdrConductivity) {
1264 this->computeCdrConductivity();
1267 DataOps::incr(a_conductivityCell, m_semiImplicitConductivityCDR, 1.0);
1273 (this->m_amr)->arithmeticAverage(a_conductivityCell, this->m_fluidRealm, (this->m_plasmaPhase));
1274 (this->m_amr)->interpGhostPwl(a_conductivityCell, this->m_fluidRealm, (this->m_plasmaPhase));
1277 if (m_condFilterNum > 0 && m_condFilterMaxStride > 0) {
1278 for (
int i = 0; i < m_condFilterNum; i++) {
1279 for (
int curStride = 1; curStride <= m_condFilterMaxStride; curStride++) {
1282 (this->m_amr)->arithmeticAverage(a_conductivityCell, this->m_fluidRealm, (this->m_plasmaPhase));
1283 (this->m_amr)->interpGhostPwl(a_conductivityCell, this->m_fluidRealm, (this->m_plasmaPhase));
1288 (this->m_amr)->interpToCentroids(a_conductivityCell, this->m_fluidRealm, (this->m_plasmaPhase));
1294 DataOps::floor(a_conductivityCell, 0.0, (this->m_amr)->getVofIterator(this->m_fluidRealm, this->m_plasmaPhase));
1297template <
typename I,
typename C,
typename R,
typename F>
1301 CH_TIME(
"ItoKMCGodunovStepper::computeFaceConductivity");
1302 if (this->m_verbosity > 5) {
1303 pout() << this->m_name +
"::computeFaceConductivity" << endl;
1311 const Average average = Average::Arithmetic;
1312 const int tanGhost = 1;
1313 const Interval interv(0, 0);
1316 (this->m_conductivityFace),
1317 (this->m_conductivityCell),
1318 (this->m_amr)->getDomains(),
1323 (this->m_amr)->getFaceIteratorWithTangentialGhosts(this->m_fluidRealm, this->m_plasmaPhase));
1327 (this->m_conductivityCell),
1329 (this->m_amr)->getVofIterator(this->m_fluidRealm, this->m_plasmaPhase));
1332template <
typename I,
typename C,
typename R,
typename F>
1336 CH_TIMERS(
"ItoKMCGodunovStepper::computeSemiImplicitRho");
1337 CH_TIMER(
"ItoKMCGodunovStepper::computeSemiImplicitRho::plasma_phase", t1);
1338 CH_TIMER(
"ItoKMCGodunovStepper::computeSemiImplicitRho::solid_phase", t2);
1339 CH_TIMER(
"ItoKMCGodunovStepper::computeSemiImplicitRho::filter", t3);
1340 if (this->m_verbosity > 5) {
1341 pout() << this->m_name +
"::computeSemiImplicitRho" << endl;
1345 CH_assert(this->m_plasmaPhase ==
phase::gas);
1347 const RefCountedPtr<MultiFluidIndexSpace>& mfis = (this->m_computationalGeometry)->getMfIndexSpace();
1348 const Vector<Dielectric>& dielectrics = (this->m_computationalGeometry)->getDielectrics();
1350 const bool hasDielectrics = (mfis->numPhases() > 1) && (dielectrics.size() > 0);
1352 MFAMRCellData& rho = this->m_fieldSolver->getRho();
1353 EBAMRCellData rhoGas = (this->m_amr)->alias(
phase::gas, rho);
1354 EBAMRCellData rhoSolid;
1356 if (hasDielectrics) {
1364 for (
auto solverIt = this->m_ito->iterator(); solverIt.ok(); ++solverIt) {
1365 const RefCountedPtr<ItoSolver>& solver = solverIt();
1366 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
1367 const int Z = species->getChargeNumber();
1370 (this->m_amr)->copyData(this->m_fluidScratch1, solver->getPhi());
1383 if (hasDielectrics) {
1386 EBAMRCellData particleScratch;
1387 EBAMRCellData fluidScratch;
1389 (this->m_amr)->allocate(particleScratch, this->m_particleRealm,
phase::solid, 1);
1390 (this->m_amr)->allocate(fluidScratch, this->m_fluidRealm,
phase::solid, 1);
1392 for (
auto solverIt = (this->m_ito)->iterator(); solverIt.ok(); ++solverIt) {
1393 const RefCountedPtr<ItoSolver>& solver = solverIt();
1394 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
1395 const int Z = species->getChargeNumber();
1402 ->depositWeight(particleScratch,
1403 this->m_particleRealm,
1405 *m_rhoDaggerParticles[solverIt.index()],
1406 DepositionType::CIC,
1407 CoarseFineDeposition::Halo,
1410 (this->m_amr)->copyData(fluidScratch, particleScratch);
1420 this->m_amr->arithmeticAverage(rho, this->m_fluidRealm);
1421 this->m_amr->interpGhostPwl(rho, this->m_fluidRealm);
1424 if (m_rhoFilterNum > 0 && m_rhoFilterMaxStride > 0) {
1426 for (
int i = 0; i < m_rhoFilterNum; i++) {
1427 for (
int curStride = 1; curStride <= m_rhoFilterMaxStride; curStride++) {
1431 this->m_amr->arithmeticAverage(rhoGas, this->m_fluidRealm, this->m_plasmaPhase);
1432 this->m_amr->interpGhost(rhoGas, this->m_fluidRealm, this->m_plasmaPhase);
1439 this->m_amr->interpToCentroids(rhoGas, this->m_fluidRealm,
phase::gas);
1440 if (hasDielectrics) {
1441 this->m_amr->interpToCentroids(rhoSolid, this->m_fluidRealm,
phase::solid);
1445template <
typename I,
typename C,
typename R,
typename F>
1449 CH_TIME(
"ItoKMCGodunovStepper::setupSemiImplicitPoisson");
1450 if (this->m_verbosity > 5) {
1451 pout() << this->m_name +
"::setupSemiImplicitPoisson" << endl;
1455 (this->m_fieldSolver)->setPermittivities();
1458 MFAMRCellData& permCell = (this->m_fieldSolver)->getPermittivityCell();
1459 MFAMRFluxData& permFace = (this->m_fieldSolver)->getPermittivityFace();
1460 MFAMRIVData& permEB = (this->m_fieldSolver)->getPermittivityEB();
1463 EBAMRFluxData permFaceGas = (this->m_amr)->alias((this->m_plasmaPhase), permFace);
1464 EBAMRIVData permEBGas = (this->m_amr)->alias((this->m_plasmaPhase), permEB);
1470 (this->m_conductivityEB),
1472 (this->m_amr)->getVofIterator(this->m_fluidRealm, this->m_plasmaPhase));
1475 (this->m_amr)->arithmeticAverage(permFaceGas, this->m_fluidRealm, (this->m_plasmaPhase));
1476 (this->m_amr)->arithmeticAverage(permEBGas, this->m_fluidRealm, (this->m_plasmaPhase));
1479 (this->m_fieldSolver)->setSolverPermittivities(permCell, permFace, permEB);
1482template <
typename I,
typename C,
typename R,
typename F>
1487 const Real a_tolerance)
const noexcept
1489 CH_TIME(
"ItoKMCGodunovStepper::removeCoveredPointParticles");
1490 if (this->m_verbosity > 5) {
1491 pout() << this->m_name +
"::removeCoveredPointParticles" << endl;
1494 for (
int i = 0; i < a_particles.size(); i++) {
1495 if (a_particles[i] !=
nullptr) {
1498 switch (a_representation) {
1499 case EBRepresentation::Discrete: {
1500 (this->m_amr)->removeCoveredParticlesDiscrete(particles, (this->m_plasmaPhase), a_tolerance);
1504 case EBRepresentation::ImplicitFunction: {
1505 (this->m_amr)->removeCoveredParticlesIF(particles, (this->m_plasmaPhase), a_tolerance);
1509 case EBRepresentation::Voxel: {
1510 (this->m_amr)->removeCoveredParticlesVoxels(particles, (this->m_plasmaPhase));
1515 MayDay::Error(
"ItoKMCGodunovStepper::removeCoveredParticles - logic bust");
1522template <
typename I,
typename C,
typename R,
typename F>
1527 CH_TIME(
"ItoKMCGodunovStepper::copyConductivityParticles");
1528 if (this->m_verbosity > 5) {
1529 pout() << this->m_name +
"::copyConductivityParticles" << endl;
1533 this->clearPointParticles(a_conductivityParticles, SpeciesSubset::All);
1535 for (
auto solverIt = (this->m_ito)->iterator(); solverIt.ok(); ++solverIt) {
1536 const RefCountedPtr<ItoSolver>& solver = solverIt();
1537 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
1539 const int idx = solverIt.index();
1540 const int Z = species->getChargeNumber();
1542 if (Z != 0 && solver->isMobile()) {
1545 for (
int lvl = 0; lvl <= (this->m_amr)->getFinestLevel(); lvl++) {
1546 const DisjointBoxLayout& dbl = (this->m_amr)->getGrids((this->m_particleRealm))[lvl];
1547 const DataIterator& dit = dbl.dataIterator();
1549 const int nbox = dit.size();
1551#pragma omp parallel for schedule(runtime)
1552 for (
int mybox = 0; mybox < nbox; mybox++) {
1553 const DataIndex& din = dit[mybox];
1560 for (std::size_t i = 0; i < leaf.
size(); i++) {
1561 const RealVect pos = leaf.
position(i);
1562 const Real weight = leaf.
weight(i);
1563 const Real mobility = leaf.template get<&ItoParticle::mobility>(i);
1565 pointParticles.
append(pos, weight * mobility);
1568 pointParticles.
catenate(irregParticles);
1575template <
typename I,
typename C,
typename R,
typename F>
1579 CH_TIME(
"ItoKMCGodunovStepper::solvePoisson()");
1580 if (this->m_verbosity > 5) {
1581 pout() << this->m_name +
"::solvePoisson()" << endl;
1585 MFAMRCellData& phi = this->m_fieldSolver->getPotential();
1586 MFAMRCellData& rho = this->m_fieldSolver->getRho();
1587 EBAMRIVData& sigma = this->m_sigmaSolver->getPhi();
1589 const bool converged = (this->m_fieldSolver)->solve(phi, rho, sigma,
false);
1591 (this->m_fieldSolver)->computeElectricField();
1596 (this->m_amr)->allocatePointer(E, this->m_fluidRealm);
1597 (this->m_amr)->alias(E, this->m_plasmaPhase, (this->m_fieldSolver)->getElectricField());
1600 (this->m_amr)->copyData(this->m_electricFieldFluid, E);
1601 (this->m_amr)->conservativeAverage(this->m_electricFieldFluid, this->m_fluidRealm, this->m_plasmaPhase);
1602 (this->m_amr)->interpGhostPwl(this->m_electricFieldFluid, this->m_fluidRealm, this->m_plasmaPhase);
1603 (this->m_amr)->interpToCentroids(this->m_electricFieldFluid, this->m_fluidRealm, this->m_plasmaPhase);
1606 (this->m_amr)->copyData(this->m_electricFieldParticle, E);
1607 (this->m_amr)->conservativeAverage(this->m_electricFieldParticle, this->m_particleRealm, this->m_plasmaPhase);
1608 (this->m_amr)->interpGhostPwl(this->m_electricFieldParticle, this->m_particleRealm, this->m_plasmaPhase);
1609 (this->m_amr)->interpToCentroids(this->m_electricFieldParticle, this->m_particleRealm, this->m_plasmaPhase);
1614template <
typename I,
typename C,
typename R,
typename F>
1618 CH_TIME(
"ItoKMCGodunovStepper::advanceEulerMaruyama");
1619 if (this->m_verbosity > 5) {
1620 pout() << this->m_name +
"::advanceEulerMaruyama" << endl;
1624 this->setOldPositions();
1629 m_timer.startEvent(
"Diffuse particles");
1630 this->diffuseParticlesEulerMaruyama(m_rhoDaggerParticles, a_dt);
1631 this->remapPointParticles(m_rhoDaggerParticles, SpeciesSubset::ChargedDiffusive);
1632 m_timer.stopEvent(
"Diffuse particles");
1636 m_timer.startEvent(
"Diffuse CDR");
1637 this->computeDiffusionTermCDR(m_semiImplicitRhoCDR, a_dt);
1638 m_timer.stopEvent(
"Diffuse CDR");
1642 m_timer.startEvent(
"Compute conductivities");
1643 this->copyConductivityParticles(m_conductivityParticles);
1644 this->computeConductivities(m_conductivityParticles,
false);
1645 m_timer.stopEvent(
"Compute conductivities");
1649 m_timer.startEvent(
"Setup Poisson");
1650 this->setupSemiImplicitPoisson(a_dt);
1651 m_timer.stopEvent(
"Setup Poisson");
1656 m_timer.startEvent(
"Deposit point particles");
1657 this->depositPointParticles(m_rhoDaggerParticles, SpeciesSubset::Charged);
1658 this->computeSemiImplicitRho();
1659 m_timer.stopEvent(
"Deposit point particles");
1663 m_timer.startEvent(
"Solve Poisson");
1664 const bool converged = this->solvePoisson();
1666 const std::string errMsg =
"ItoKMCGodunovStepper::advanceEulerMaruyama - Poisson solve did not converge";
1668 pout() << errMsg << endl;
1670 if (this->m_abortOnFailure) {
1671 MayDay::Error(errMsg.c_str());
1674 m_timer.stopEvent(
"Solve Poisson");
1679 m_timer.startEvent(
"Step-compute v");
1681 this->setCdrVelocityFunctions();
1682 this->setItoVelocityFunctions();
1683 (this->m_ito)->interpolateVelocities();
1684 this->multiplyCdrVelocitiesByMobilities();
1686 this->computeDriftVelocities();
1688 m_timer.stopEvent(
"Step-compute v");
1692 m_timer.startEvent(
"Euler-Maruyama step");
1693 this->stepEulerMaruyamaParticles(a_dt);
1694 this->remapParticles(SpeciesSubset::AllMobileOrDiffusive);
1695 this->stepEulerMaruyamaCDR(a_dt);
1696 m_timer.stopEvent(
"Euler-Maruyama step");
1699template <
typename I,
typename C,
typename R,
typename F>
1703 const Real a_dt)
noexcept
1705 CH_TIME(
"ItoKMCGodunovStepper::diffuseParticlesEulerMaruyama");
1706 if (this->m_verbosity > 5) {
1707 pout() << this->m_name +
"::diffuseParticlesEulerMaruyama" << endl;
1710 this->clearPointParticles(a_rhoDaggerParticles, SpeciesSubset::All);
1712 for (
auto solverIt = (this->m_ito)->iterator(); solverIt.ok(); ++solverIt) {
1713 RefCountedPtr<ItoSolver>& solver = solverIt();
1714 const RefCountedPtr<ItoSpecies>& species = solver->getSpecies();
1716 const int idx = solverIt.index();
1718 const bool mobile = solver->isMobile();
1719 const bool diffusive = solver->isDiffusive();
1720 const int Z = species->getChargeNumber();
1722 const auto& diffusionFunction = (this->m_physics)->getItoDiffusionFunctions()[idx];
1724 for (
int lvl = 0; lvl <= (this->m_amr)->getFinestLevel(); lvl++) {
1725 const DisjointBoxLayout& dbl = (this->m_amr)->getGrids((this->m_particleRealm))[lvl];
1726 const DataIterator& dit = dbl.dataIterator();
1728 auto& particles = solver->getParticles(ItoSolver::WhichContainer::Bulk)[lvl];
1730 const int nbox = dit.size();
1732#pragma omp parallel for schedule(runtime)
1733 for (
int mybox = 0; mybox < nbox; mybox++) {
1734 const DataIndex& din = dit[mybox];
1739 for (std::size_t i = 0; i < leaf.
size(); i++) {
1740 const Real weight = leaf.
weight(i);
1741 const RealVect pos = leaf.
position(i);
1746 const RealVect hop = diffusive ? diffusionFunction(p, a_dt) : RealVect::Zero;
1748 D_DECL(leaf.template get<&ItoParticle::scratch_x>(i) =
static_cast<ParticleReal>(hop[0]),
1749 leaf.template get<&ItoParticle::scratch_y>(i) =
static_cast<ParticleReal>(hop[1]),
1750 leaf.template get<&ItoParticle::scratch_z>(i) =
static_cast<ParticleReal>(hop[2]));
1753 pointParticles.
append(pos + hop, weight);
1761template <
typename I,
typename C,
typename R,
typename F>
1765 CH_TIME(
"ItoKMCGodunovStepper::diffuseCDREulerMaruyama");
1766 if (this->m_verbosity > 5) {
1767 pout() << this->m_name +
"::diffuseCDREulerMaruyama" << endl;
1772 for (
auto solverIt = this->m_cdr->iterator(); solverIt.ok(); ++solverIt) {
1773 const RefCountedPtr<CdrSolver>& solver = solverIt();
1774 const RefCountedPtr<CdrSpecies>& species = solver->getSpecies();
1776 const int index = solverIt.index();
1777 const int Z = species->getChargeNumber();
1779 const EBAMRCellData& phi = solver->getPhi();
1782 if (solver->isDiffusive()) {
1783 solver->computeDivD(m_cdrDivD[index], solver->getPhi(),
false,
false,
false);
1789 if (solver->isDiffusive()) {
1790 DataOps::incr(a_semiImplicitRhoCDR, m_cdrDivD[index], 1.0 * Z * a_dt);
1797 this->m_amr->arithmeticAverage(a_semiImplicitRhoCDR, this->m_fluidRealm, this->m_plasmaPhase);
1798 this->m_amr->interpGhostPwl(a_semiImplicitRhoCDR, this->m_fluidRealm, this->m_plasmaPhase);
1801template <
typename I,
typename C,
typename R,
typename F>
1805 CH_TIME(
"ItoKMCGodunovStepper::stepEulerMaruyamaParticles");
1806 if (this->m_verbosity > 5) {
1807 pout() << this->m_name +
"::stepEulerMaruyamaParticles" << endl;
1810 for (
auto solverIt = (this->m_ito)->iterator(); solverIt.ok(); ++solverIt) {
1811 RefCountedPtr<ItoSolver>& solver = solverIt();
1813 const bool mobile = solver->isMobile();
1814 const bool diffusive = solver->isDiffusive();
1816 const Real f = mobile ? a_dt : 0.0;
1817 const Real g = diffusive ? 1.0 : 0.0;
1819 if (mobile || diffusive) {
1820 for (
int lvl = 0; lvl <= (this->m_amr)->getFinestLevel(); lvl++) {
1821 const DisjointBoxLayout& dbl = (this->m_amr)->getGrids((this->m_particleRealm))[lvl];
1822 const DataIterator& dit = dbl.dataIterator();
1824 auto& particles = solver->getParticles(ItoSolver::WhichContainer::Bulk)[lvl];
1826 const int nbox = dit.size();
1828#pragma omp parallel for schedule(runtime)
1829 for (
int mybox = 0; mybox < nbox; mybox++) {
1830 const DataIndex& din = dit[mybox];
1834 double*
const pos[SpaceDim] = {
1836 double*
const oldPos[SpaceDim] = {D_DECL(leaf.template column<&ItoParticle::old_x>(),
1837 leaf.template column<&ItoParticle::old_y>(),
1838 leaf.template column<&ItoParticle::old_z>())};
1839 ParticleReal*
const vel[SpaceDim] = {D_DECL(leaf.template column<&ItoParticle::vx>(),
1840 leaf.template column<&ItoParticle::vy>(),
1841 leaf.template column<&ItoParticle::vz>())};
1842 ParticleReal*
const hop[SpaceDim] = {D_DECL(leaf.template column<&ItoParticle::scratch_x>(),
1843 leaf.template column<&ItoParticle::scratch_y>(),
1844 leaf.template column<&ItoParticle::scratch_z>())};
1848 for (
int dir = 0; dir < SpaceDim; dir++) {
1849 pos[dir][i] = oldPos[dir][i] + f * vel[dir][i] + g * hop[dir][i];
1858template <
typename I,
typename C,
typename R,
typename F>
1862 CH_TIME(
"ItoKMCGodunovStepper::stepEulerMaruyamaCDR");
1863 if (this->m_verbosity > 5) {
1864 pout() << this->m_name +
"::stepEulerMaruyamaCDR" << endl;
1867 for (
auto solverIt = (this->m_cdr)->iterator(); solverIt.ok(); ++solverIt) {
1868 RefCountedPtr<CdrSolver>& solver = solverIt();
1870 const int index = solverIt.index();
1872 EBAMRCellData& phi = solver->getPhi();
1874 this->m_amr->conservativeAverage(phi, this->m_fluidRealm, this->m_plasmaPhase);
1875 this->m_amr->interpGhostPwl(phi, this->m_fluidRealm, this->m_plasmaPhase);
1878 if (solver->isMobile()) {
1883 solver->computeDivF(this->m_fluidScratch1, phi, a_dt,
false,
true,
true);
1889 if (solver->isDiffusive()) {
1893 DataOps::floor(phi, 0.0, this->m_amr->getVofIterator(this->m_fluidRealm, this->m_plasmaPhase));
1896 this->coarsenCDRSolvers();
1900template <
typename I,
typename C,
typename R,
typename F>
1904 CH_TIME(
"ItoKMCGodunovStepper::writeCheckpointHeader");
1905 if (this->m_verbosity > 5) {
1906 pout() << this->m_name +
"::writeCheckpointHeader" << endl;
1909 a_header.m_real[
"prev_dt"] = this->m_prevDt;
1910 a_header.m_real[
"physics_dt"] = this->m_physicsDt;
1911 a_header.m_int[
"checkpoint_particles"] = m_writeCheckpointParticles ? 1 : 0;
1916template <
typename I,
typename C,
typename R,
typename F>
1920 CH_TIME(
"ItoKMCGodunovStepper::readCheckpointHeader");
1921 if (this->m_verbosity > 5) {
1922 pout() << this->m_name +
"::readCheckpointHeader" << endl;
1925 this->m_prevDt = a_header.m_real[
"prev_dt"];
1926 this->m_physicsDt = a_header.m_real[
"physics_dt"];
1928 m_readCheckpointParticles = (a_header.m_int[
"checkpoint_particles"] != 0) ?
true : false;
1929 m_canRegridOnRestart = m_readCheckpointParticles;
1934template <
typename I,
typename C,
typename R,
typename F>
1938 CH_TIME(
"ItoKMCGodunovStepper::writeCheckpointData");
1939 if (this->m_verbosity > 5) {
1940 pout() << this->m_name +
"::writeCheckpointData" << endl;
1946 if (m_writeCheckpointParticles) {
1947 for (
int i = 0; i < (this->m_physics)->getNumItoSpecies(); i++) {
1948 const std::string identifierSigma =
"ItoKMCGodunovStepper::conductivityParticles_" + std::to_string(i);
1949 const std::string identifierRho =
"ItoKMCGodunovStepper::spaceChargeParticles_" + std::to_string(i);
1954 DischargeIO::writeCheckParticlesToHDF(a_handle, conductivityParticles[a_lvl], identifierSigma);
1955 DischargeIO::writeCheckParticlesToHDF(a_handle, rhoDaggerParticles[a_lvl], identifierRho);
1960 if (this->m_physics->getNumCdrSpecies() > 0) {
1961 write(a_handle, *m_semiImplicitRhoCDR[a_lvl],
"ItoKMCGodunovStepper::semiImplicitRhoCDR");
1962 write(a_handle, *m_semiImplicitConductivityCDR[a_lvl],
"ItoKMCGodunovStepper::semiImplicitConductivityCDR");
1968template <
typename I,
typename C,
typename R,
typename F>
1972 CH_TIME(
"ItoKMCGodunovStepper::readCheckpointData");
1973 if (this->m_verbosity > 5) {
1974 pout() << this->m_name +
"::readCheckpointData" << endl;
1980 if (m_readCheckpointParticles) {
1981 for (
int i = 0; i < (this->m_physics)->getNumItoSpecies(); i++) {
1982 const std::string identifierSigma =
"ItoKMCGodunovStepper::conductivityParticles_" + std::to_string(i);
1983 const std::string identifierRho =
"ItoKMCGodunovStepper::spaceChargeParticles_" + std::to_string(i);
1988 DischargeIO::readCheckParticlesFromHDF(a_handle, conductivityParticles[a_lvl], identifierSigma);
1989 DischargeIO::readCheckParticlesFromHDF(a_handle, rhoDaggerParticles[a_lvl], identifierRho);
1994 if (this->m_physics->getNumCdrSpecies() > 0) {
1995 const Interval interv(0, 0);
1997 read<EBCellFAB>(a_handle,
1998 *m_semiImplicitRhoCDR[a_lvl],
1999 "ItoKMCGodunovStepper::semiImplicitRhoCDR",
2000 this->m_amr->getGrids(this->m_fluidRealm)[a_lvl],
2004 read<EBCellFAB>(a_handle,
2005 *m_semiImplicitConductivityCDR[a_lvl],
2006 "ItoKMCGodunovStepper::semiImplicitConductivityCDR",
2007 this->m_amr->getGrids(this->m_fluidRealm)[a_lvl],
2014template <
typename I,
typename C,
typename R,
typename F>
2018 CH_TIME(
"ItoKMCGodunovStepper::postPlot");
2019 if (this->m_verbosity > 5) {
2020 pout() << this->m_name +
"::postPlot" << endl;
2023 this->m_physicsPlotVariables.clear();
2025 this->plotParticles();
2028template <
typename I,
typename C,
typename R,
typename F>
2032 CH_TIME(
"ItoKMCGodunovStepper::plotParticles");
2033 if (this->m_verbosity > 2) {
2034 pout() << this->m_name +
"::plotParticles" << endl;
2037 bool plotParticles =
false;
2039 ParmParse pp(this->m_name.c_str());
2041 pp.query(
"plot_particles", plotParticles);
2043 if (plotParticles) {
2045 for (
auto solverIt = (this->m_ito)->iterator(); solverIt.ok(); ++solverIt) {
2046 const RefCountedPtr<ItoSolver>& solver = solverIt();
2050 std::string cmd =
"mkdir -p particles/" + solver->getName();
2052 if (procID() == 0) {
2053 success = system(cmd.c_str());
2057 MayDay::Error(
"ItoKMCGodunovStepper::plotParticles - could not create 'particles' directory");
2061 const std::string prefix =
"./particles/" + solver->getName() +
"/" + solver->getName();
2062 char fileChar[1000];
2063 sprintf(fileChar,
"%s.step%07d.%dd.h5part", prefix.c_str(), this->m_timeStep, SpaceDim);
2072#include <CD_NamespaceFooter.H>
Average
Various averaging methods.
Definition CD_Average.H:25
Agglomeration of useful data operations.
Silly, but useful functions that override standard Chombo HDF5 IO.
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
Declaration of a class which uses a semi-implicit Godunov method for Ito plasma equations.
SpeciesSubset
Enum for selecting a subset of plasma species by mobility/diffusion/charge properties.
Definition CD_ItoKMCStepper.H:43
Agglomeration of basic MPI reductions.
Declaration of a namespace for SIMD-decorated loops over SoA particles.
CD_PARTICLE_REAL ParticleReal
Floating-point type a user may use for payload columns.
Definition CD_ParticleSoA.H:156
SoA payload for Monte Carlo radiative-transfer photons.
Implementation of CD_Timer.H.
Declaration of various useful units.
static void scale(MFAMRCellData &a_lhs, const Real &a_scale) noexcept
Scale data by factor.
Definition CD_DataOps.cpp:2503
static void floor(EBAMRCellData &a_lhs, const Real a_value, const Vector< RefCountedPtr< LayoutData< VoFIterator > > > &a_vofIter)
Floor values in data holder. This sets all values below a_value to a_value.
Definition CD_DataOps.cpp:1465
static void filterSmooth(EBAMRCellData &a_data, const Real a_alpha, const int a_stride, const bool a_zeroEB) noexcept
Apply a convolved filter phi = alpha * phi_i + 0.5*(1-alpha) * [phi_(i+s) + phi_(i-s)] in each direct...
Definition CD_DataOps.cpp:679
static void multiply(EBAMRCellData &a_lhs, const EBAMRCellData &a_rhs)
Multiply data holder by another data holder.
Definition CD_DataOps.cpp:2246
static void incr(MFAMRCellData &a_lhs, const MFAMRCellData &a_rhs, const Real a_scale) noexcept
Function which increments data in the form a_lhs = a_lhs + a_rhs*a_scale for all components.
Definition CD_DataOps.cpp:820
static void setValue(LevelData< MFInterfaceFAB< T > > &a_lhs, const T &a_value)
Set value in an MFInterfaceFAB data holder.
Definition CD_DataOpsImplem.H:24
static void copy(MFAMRCellData &a_dst, const MFAMRCellData &a_src)
Copy data from one data holder to another.
Definition CD_DataOps.cpp:1201
static void averageCellToFace(EBAMRFluxData &a_faceData, const EBAMRCellData &a_cellData, const Vector< ProblemDomain > &a_domains, Vector< RefCountedPtr< LayoutData< std::array< FaceIterator, SpaceDim > > > > &a_faceIter)
Average all components of the cell-centered data to faces (arithmetic, no tangential ghost faces).
Definition CD_DataOps.cpp:148
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
RealVect getProbLo() const
Lower-left corner of the physical domain.
Definition CD_ParticleContainer.H:280
AMRParticlesSoA< P, Traits > & getParticles()
The valid particles on all levels.
Definition CD_ParticleContainer.H:317
static void setData(ParticleContainer< P, Traits > &a_particles, const std::function< void(ParticleSoA< P, Traits > &, std::size_t)> &a_functor) noexcept
Set value function for SoA containers. Lets the user set particle parameters via a (leaf,...
Definition CD_ParticleOpsImplem.H:334
Arena-backed Struct-of-Arrays particle container for a single grid patch.
Definition CD_ParticleSoA.H:655
void append(const RealVect &a_position, const double a_weight)
Append one particle with a default-constructed payload.
Definition CD_ParticleSoA.H:955
RealVect position(const std::size_t a_index) const noexcept
Position of particle i as a RealVect (by value, assembled from the scalar columns).
Definition CD_ParticleSoA.H:1188
double & weight(const std::size_t a_index) noexcept
Weight of particle i.
Definition CD_ParticleSoA.H:1222
std::size_t size() const noexcept
Number of particles currently stored.
Definition CD_ParticleSoA.H:882
double * positionColumn(const int a_dir) noexcept
Raw position component column dir (double*, for SIMD kernels).
Definition CD_ParticleSoA.H:1137
P gather(const std::size_t a_index) const
Gather particle i's payload back into the AoS payload view.
Definition CD_ParticleSoA.H:1021
void catenate(ParticleSoA &a_other)
Move every particle of another container into this one, leaving a_other empty (catenate).
Definition CD_ParticleSoA.H:1002
void remove(const std::size_t a_index) noexcept
Remove particle i using swap-and-pop (O(1), does NOT preserve order).
Definition CD_ParticleSoA.H:1033
Implementation of ItoKMCStepper that uses a semi-implicit split-step formalism for advancing the Ito-...
Definition CD_ItoKMCGodunovStepper.H:31
virtual void setupSemiImplicitPoisson(const Real a_dt) noexcept
Set up the semi-implicit Poisson solver.
Definition CD_ItoKMCGodunovStepperImplem.H:1447
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_ItoKMCGodunovStepperImplem.H:684
virtual void computeDiffusionTermCDR(EBAMRCellData &m_semiImplicitRhoCDR, const Real a_dt) noexcept
Compute the diffusion term for the CDR equations as well as the resulting CDR-contributions to the sp...
Definition CD_ItoKMCGodunovStepperImplem.H:1763
virtual void allocate() noexcept override
Allocate storage required for advancing the equations.
Definition CD_ItoKMCGodunovStepperImplem.H:98
bool m_readCheckpointParticles
If true, then the HDF5 checkpoint file contained particles that we can read.
Definition CD_ItoKMCGodunovStepper.H:170
virtual Real advance(const Real a_dt) override
Advance the Ito-Poisson-KMC system over a_dt.
Definition CD_ItoKMCGodunovStepperImplem.H:359
virtual void allocateInternals() noexcept override
Allocate "internal" storage.
Definition CD_ItoKMCGodunovStepperImplem.H:131
Real m_maxFieldAbort
Limit for maximum field abort.
Definition CD_ItoKMCGodunovStepper.H:231
virtual void stepEulerMaruyamaCDR(const Real a_dt) noexcept
Step the CDR equations according to the regular Euler-Maruyama scheme.
Definition CD_ItoKMCGodunovStepperImplem.H:1860
virtual void computeConductivities(const Vector< RefCountedPtr< ParticleContainer< NoPayload > > > &a_particles, const bool a_useStoredCdrConductivity) noexcept
Compute all conductivities (cell, face, and EB) from the input point particles.
Definition CD_ItoKMCGodunovStepperImplem.H:1214
virtual void parseAlgorithm() noexcept
Parse advancement algorithm.
Definition CD_ItoKMCGodunovStepperImplem.H:213
virtual void clearPointParticles(const Vector< RefCountedPtr< ParticleContainer< NoPayload > > > &a_particles, const SpeciesSubset a_subset) noexcept
Clear the input particle data holders.
Definition CD_ItoKMCGodunovStepperImplem.H:1078
virtual void postPlot() noexcept override
Perform post-plot operations.
Definition CD_ItoKMCGodunovStepperImplem.H:2016
virtual Real computeDt() override
Compute a time step used for the advance method.
Definition CD_ItoKMCGodunovStepperImplem.H:339
virtual void diffuseParticlesEulerMaruyama(Vector< RefCountedPtr< ParticleContainer< NoPayload > > > &a_rhoDaggerParticles, const Real a_dt) noexcept
Perform the diffusive Ito advance in the Euler-Maruyama step.
Definition CD_ItoKMCGodunovStepperImplem.H:1701
virtual void parseSecondaryEmissionSpecification() noexcept
Parse when secondary particles are emitted.
Definition CD_ItoKMCGodunovStepperImplem.H:288
virtual void parseFiltering() noexcept
Parse filter settings.
Definition CD_ItoKMCGodunovStepperImplem.H:238
virtual void parseRuntimeOptions() noexcept override
Parse run-time options.
Definition CD_ItoKMCGodunovStepperImplem.H:195
virtual void depositPointParticles(const Vector< RefCountedPtr< ParticleContainer< NoPayload > > > &a_particles, const SpeciesSubset a_subset) noexcept
Deposit the input point particles on the mesh.
Definition CD_ItoKMCGodunovStepperImplem.H:976
virtual bool solvePoisson() noexcept override
Solve the electrostatic problem.
Definition CD_ItoKMCGodunovStepperImplem.H:1577
bool m_canRegridOnRestart
If true, then the class supports regrid-on-restart.
Definition CD_ItoKMCGodunovStepper.H:176
virtual void computeFaceConductivity() noexcept
Compute the cell-centered conductivity.
Definition CD_ItoKMCGodunovStepperImplem.H:1299
virtual void computeCellConductivity(EBAMRCellData &a_conductivityCell, const Vector< RefCountedPtr< ParticleContainer< NoPayload > > > &a_particles, const bool a_useStoredCdrConductivity) noexcept
Compute the cell-centered conductivity.
Definition CD_ItoKMCGodunovStepperImplem.H:1229
virtual void removeCoveredPointParticles(Vector< RefCountedPtr< ParticleContainer< NoPayload > > > &a_particles, const EBRepresentation a_representation, const Real a_tolerance) const noexcept
Remove covered particles.
Definition CD_ItoKMCGodunovStepperImplem.H:1484
virtual void remapPointParticles(Vector< RefCountedPtr< ParticleContainer< NoPayload > > > &a_particles, const SpeciesSubset a_subset) noexcept
Remap the input point particles.
Definition CD_ItoKMCGodunovStepperImplem.H:871
virtual ~ItoKMCGodunovStepper()
Destructor. Does nothing.
Definition CD_ItoKMCGodunovStepperImplem.H:72
bool m_extendConductivityEB
For achieving a slightly smoother gradient in the conductivity near the EB.
Definition CD_ItoKMCGodunovStepper.H:181
virtual void setOldPositions() noexcept
Set the starting positions for the ItoSolver particles.
Definition CD_ItoKMCGodunovStepperImplem.H:832
bool m_writeCheckpointParticles
If true, then the particles are checkpointed so we can regrid on checkpoint-restart.
Definition CD_ItoKMCGodunovStepper.H:165
virtual void computeSemiImplicitRho() noexcept
Set up the space charge density for the regrid operation.
Definition CD_ItoKMCGodunovStepperImplem.H:1334
virtual void advanceEulerMaruyama(const Real a_dt) noexcept
Advance the particles using the Euler-Maruyama scheme.
Definition CD_ItoKMCGodunovStepperImplem.H:1616
virtual void preRegrid(const int a_lmin, const int a_oldFinestLevel) noexcept override
Perform pre-regrid operations.
Definition CD_ItoKMCGodunovStepperImplem.H:645
virtual void registerOperators() noexcept override
Register operators used for the simulation.
Definition CD_ItoKMCGodunovStepperImplem.H:82
virtual void plotParticles() const noexcept
Utility function for plotting the ItoSolver particles. These are written in a particles folder.
Definition CD_ItoKMCGodunovStepperImplem.H:2030
ItoKMCGodunovStepper()=delete
Disallowed default constructor. Use the full constructor.
virtual void parseReactiveFieldCentering() noexcept
Parse the time-centering of the electric field used for the reactive substep.
Definition CD_ItoKMCGodunovStepperImplem.H:319
virtual void parseCheckpointParticles() noexcept
Parse checkpoint-restart functionality.
Definition CD_ItoKMCGodunovStepperImplem.H:274
virtual void barrier() const noexcept
Set an MPI barrier if using debug mode.
Definition CD_ItoKMCGodunovStepperImplem.H:163
virtual void parseOptions() noexcept override
Parse options.
Definition CD_ItoKMCGodunovStepperImplem.H:177
virtual void computeCdrConductivity() noexcept
Compute the CDR contribution to the semi-implicit conductivity, i.e. sum(|Z| * phi * mu).
Definition CD_ItoKMCGodunovStepperImplem.H:1184
virtual void stepEulerMaruyamaParticles(const Real a_dt) noexcept
Step the particles according to the regular Euler-Maruyama scheme.
Definition CD_ItoKMCGodunovStepperImplem.H:1803
virtual void copyConductivityParticles(Vector< RefCountedPtr< ParticleContainer< NoPayload > > > &a_conductivityParticles) noexcept
Copy particles from the ItoSolver into PointParticles whose weight are ItoParticle::m_weight * ItoPar...
Definition CD_ItoKMCGodunovStepperImplem.H:1524
Abstract TimeStepper for the Ito-KMC-Poisson system of equations.
Definition CD_ItoKMCStepper.H:66
virtual void parseRuntimeOptions() noexcept override
Parse runtime configurable options.
Definition CD_ItoKMCStepperImplem.H:160
std::string m_name
Time stepper name.
Definition CD_ItoKMCStepper.H:380
virtual void registerOperators() noexcept override
Register operators used for the simulation.
Definition CD_ItoKMCStepperImplem.H:1597
virtual void parseOptions() noexcept
Parse options.
Definition CD_ItoKMCStepperImplem.H:140
virtual void preRegrid(const int a_lmin, const int a_oldFinestLevel) noexcept override
Perform pre-regrid operations - storing relevant data from the old grids.
Definition CD_ItoKMCStepperImplem.H:1649
Real m_prevDt
Previous time step.
Definition CD_ItoKMCStepper.H:509
virtual Real computeDt() override
Compute a time step used for the advance method.
Definition CD_ItoKMCStepperImplem.H:1468
virtual void allocateInternals() noexcept
Allocate "internal" storage.
Definition CD_ItoKMCStepperImplem.H:579
virtual void allocate() noexcept override
Allocate storage for solvers.
Definition CD_ItoKMCStepperImplem.H:561
Class which is used for run-time monitoring of events.
Definition CD_Timer.H:32
void writeH5Part(std::string a_filename, const ParticleContainer< P, Traits > &a_particles, RealVect a_shift, Real a_time) noexcept
Write an SoA particle container to an H5Part file (quick visualization).
Definition CD_DischargeIOImplem.H:201
void barrier() noexcept
MPI barrier.
Definition CD_ParallelOpsImplem.H:26
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
@ solid
Solid (dielectric) phase.
Definition CD_MultiFluidIndexSpace.H:40
@ gas
Gas phase.
Definition CD_MultiFluidIndexSpace.H:39
SoA payload for ItoSolver particles, i.e. drifting Brownian walkers.
Definition CD_ItoParticle.H:31