chombo-discharge
Loading...
Searching...
No Matches
CD_ItoKMCPhysicsImplem.H
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2021-2026 SINTEF Energy Research
3 *
4 * SPDX-License-Identifier: GPL-3.0-or-later
5 */
6
13#ifndef CD_ITOKMCPHYSICSIMPLEM_H
14#define CD_ITOKMCPHYSICSIMPLEM_H
15
16// Chombo includes
17#include <ParmParse.H>
18
19// Our includes
20#include <CD_ItoKMCPhysics.H>
22#include <CD_Random.H>
23#include <CD_Units.H>
24#include <CD_DataOps.H>
25#include <CD_NamespaceHeader.H>
26
27using namespace Physics::ItoKMC;
28
30{
31 CH_TIME("ItoKMCPhysics::ItoKMCPhysics");
32
33 m_className = "ItoKMCPhysics";
34
35 m_kmcReactions.clear();
36 m_photoReactions.clear();
37
38 // Some default settings (mostly in case user forgets to call the parsing algorithms).
39 m_isDefined = false;
40 m_debug = true;
41 m_hasKMCSolver = false;
45 m_maxNewPhotons = 32;
46 m_Ncrit = 5;
47 m_eps = 2.0;
48 m_NSSA = 5;
49 m_maxIter = 10;
50 m_SSAlim = 5.0;
51 m_exitTol = 1.E-6;
54}
55
57{
58 CH_TIME("ItoKMCPhysics::~ItoKMCPhysics");
59}
60
61inline void
63{
64 CH_TIME("ItoKMCPhysics::define");
65
66 this->defineSpeciesMap();
67 this->definePhotoPathways();
68
69 // Safety hook -- make sure no one defines reactions using an out-of-range species index.
70#ifndef NDEBUG
71 for (const auto& R : m_kmcReactions) {
72 const auto& lhsReactants = R.getReactants();
73 const auto& rhsReactants = R.getReactiveProducts();
74 const auto& rhsPhotons = R.getNonReactiveProducts();
75
76 for (const auto& r : lhsReactants) {
77 CH_assert(r < m_itoSpecies.size() + m_cdrSpecies.size());
78 }
79 for (const auto& r : rhsReactants) {
80 CH_assert(r < m_itoSpecies.size() + m_cdrSpecies.size());
81 }
82 for (const auto& r : rhsPhotons) {
83 CH_assert(r < m_rtSpecies.size());
84 }
85 }
86#endif
87
88 m_isDefined = true;
89}
90
91inline void
93{
94 CH_TIME("ItoKMCPhysics::defineSpeciesMap");
95
96 const int numItoSpecies = this->getNumItoSpecies();
97 const int numCdrSpecies = this->getNumCdrSpecies();
98
99 int species = 0;
100 for (int i = 0; i < numItoSpecies; i++, species++) {
101 m_speciesMap.emplace(species, std::make_pair(SpeciesType::Ito, i));
102 }
103
104 for (int i = 0; i < numCdrSpecies; i++, species++) {
105 m_speciesMap.emplace(species, std::make_pair(SpeciesType::CDR, i));
106 }
107}
108
109inline void
111{
112 CH_TIME("ItoKMCPhysics::defineKMC");
113
115
116 // Deep copy of reaction rates
118 for (const auto& r : m_kmcReactions) {
120 }
121
123 m_kmcSolver.setSolverParameters(m_Ncrit, m_NSSA, m_maxIter, m_eps, m_SSAlim, m_exitTol);
124 m_kmcState.define(m_itoSpecies.size() + m_cdrSpecies.size(), m_rtSpecies.size());
125
126 m_hasKMCSolver = true;
127}
128
129inline void
131{
132 CH_TIME("ItoKMCPhysics::killKMC");
133
135
138 m_kmcState.define(0, 0);
139
140 m_hasKMCSolver = false;
141}
142
143inline void
145{
146 CH_TIME("ItoKMCPhysics::definePhotoPathways");
147
148 // Build a temporary list of pathways. I.e. restructure the list of reactions
149 //
150 // Y1 -> A
151 // Y1 -> B
152 // Y2 -> C
153 // Y2 -> D
154 //
155 // into separate lists for Y1, Y2, ....
156 //
158
159 for (int i = 0; i < m_photoReactions.size(); i++) {
161
162 const size_t& src = r.getSourcePhoton();
163 const Real efficiency = r.getEfficiency();
164
165 pathways[src].emplace_back(std::make_pair(i, efficiency));
166 }
167
168 // Go through the temporary pathways list and compute the relative efficiencies of one of the
169 // photons triggering a reaction. The relative efficiencies are given by
170 //
171 // p(i) = R(i)/sum_j R(j).
172 //
173 for (const auto& p : pathways) {
174 const int photoSpecies = p.first;
176
179 double sumEfficiencies = 0.0;
180
181 for (int i = 0; i < reactionsAndEfficiencies.size(); i++) {
183 }
184
185 for (int i = 0; i < reactionsAndEfficiencies.size(); i++) {
187 efficiencies.emplace_back((double)reactionsAndEfficiencies[i].second / sumEfficiencies);
188 }
189
191
193 }
194}
195
198{
199 CH_TIME("ItoKMCPhysics::getSpeciesMap");
200
201 return m_speciesMap;
202}
203
204inline void
206{
207 CH_TIME("ItoKMCPhysics::parseRuntimeOptions");
208
209 this->parsePPC();
210 this->parseDebug();
211 this->parseAlgorithm();
212}
213
214inline void
216{
217 CH_TIME("ItoKMCPhysics::parsePPC");
218
219 ParmParse pp(m_className.c_str());
220
221 pp.get("max_new_particles", m_maxNewParticles);
222 pp.get("max_new_photons", m_maxNewPhotons);
223 pp.get("increment_weights", m_incrementNewParticles);
224}
225
226inline void
228{
229 CH_TIME("ItoKMCPhysics::parseDebug");
230
231 ParmParse pp(m_className.c_str());
232
233 pp.get("debug", m_debug);
234}
235
236inline void
238{
239 CH_TIME("ItoKMCPhysics::parseAlgorithm");
240
241 ParmParse pp(m_className.c_str());
242
244
245 pp.get("algorithm", str);
246 pp.get("crit_num", m_Ncrit);
247 pp.get("SSA_num", m_NSSA);
248 pp.get("prop_eps", m_eps);
249 pp.get("SSA_lim", m_SSAlim);
250 pp.get("max_iter", m_maxIter);
251 pp.get("exit_tolerance", m_exitTol);
252
253 if (str == "ssa") {
255 }
256 else if (str == "explicit_euler") {
258 }
259 else if (str == "midpoint") {
261 }
262 else if (str == "prc") {
264 }
265 else if (str == "implicit_euler") {
267 }
268 else if (str == "hybrid_explicit_euler") {
270 }
271 else if (str == "hybrid_midpoint") {
273 }
274 else if (str == "hybrid_prc") {
276 }
277 else if (str == "hybrid_implicit_euler") {
279 }
280 else {
281 MayDay::Error("ItoKMCPhysics::parseAlgorithm - unknown algorithm requested");
282 }
283}
284
287{
288 return m_itoSpecies;
289}
290
293{
294 return m_cdrSpecies;
295}
296
299{
300 return m_rtSpecies;
301}
302
303inline const Vector<DiffusionFunction>&
308
309inline int
311{
312 return m_itoSpecies.size();
313}
314
315inline int
317{
318 return m_cdrSpecies.size();
319}
320
321inline int
323{
324 return m_itoSpecies.size() + m_cdrSpecies.size();
325}
326
327inline int
329{
330 return m_rtSpecies.size();
331}
332
333inline Real
335{
336 return 0.0;
337}
338
339inline void
343 const Vector<Real>& a_phi,
345 const Real a_dt,
346 const RealVect a_E,
347 const RealVect a_pos,
348 const Real a_dx,
349 const Real a_kappa) const
350{
351 CH_TIME("ItoKMCPhysics::advanceKMC");
352
353 // Note: This is called PER GRID CELL, i.e. within OpenMP parallel regions. For this reason the KMC solver
354 // must be defined through defineKMC() (which must be later killed).
357
358 std::vector<FPR>& kmcParticles = m_kmcState.getReactiveState();
359 std::vector<FPR>& kmcPhotons = m_kmcState.getNonReactiveState();
360
361 for (size_t i = 0; i < a_numParticles.size(); i++) {
363 }
364
365 for (auto& p : kmcPhotons) {
366 p = 0LL;
367 }
368
369 // Lambda function used for computing charge before and after reactions. Used only in debug mode
370 // for ensuring that nothing goes wrong with charge conservation in the chemistry integration.
371 auto computeCharge = [&]() -> long long {
372 long long Q = 0.0;
373 for (int i = 0; i < kmcParticles.size(); i++) {
374 const SpeciesType& speciesType = m_speciesMap.at(i).first;
375 const int& speciesIndex = m_speciesMap.at(i).second;
376
377 int Z = 0;
378
379 switch (speciesType) {
380 case SpeciesType::Ito: {
381 Z = m_itoSpecies[speciesIndex]->getChargeNumber();
382
383 break;
384 }
385 case SpeciesType::CDR: {
386 Z = m_cdrSpecies[speciesIndex]->getChargeNumber();
387
388 break;
389 }
390 default: {
391 MayDay::Abort("ItoKMCPhysics::advanceKMC -- logic bust in computeCharge()");
392
393 break;
394 }
395 }
396
397 Q += llround(kmcParticles[i]) * Z;
398 }
399
400 return Q;
401 };
402
403 // In debug mode, compute the total charge.
404 const long long chargeBefore = m_debug ? computeCharge() : 0LL;
405
406 // Update the reaction rates to be used by the KMC solver.
408
409 // Run the KMC solver.
410 switch (m_algorithm) {
411 case Algorithm::SSA: {
412 m_kmcSolver.advanceSSA(m_kmcState, a_dt);
413
414 break;
415 }
418
419 break;
420 }
421 case Algorithm::Midpoint: {
423
424 break;
425 }
426 case Algorithm::PRC: {
428
429 break;
430 }
433
434 break;
435 }
438
439 break;
440 }
443
444 break;
445 }
448
449 break;
450 }
453
454 break;
455 }
456 default: {
457 MayDay::Error("ItoKMCPhysics::advanceKMC - logic bust");
458 }
459 }
460
461 // Put KMC back into ItoKMC
462 for (size_t i = 0; i < a_numParticles.size(); i++) {
464 }
465 for (size_t i = 0; i < a_numNewPhotons.size(); i++) {
467 }
468
469 const long long chargeAfter = m_debug ? computeCharge() : 0LL;
470
471 if (chargeAfter != chargeBefore) {
472 MayDay::Warning("ItoKMCPhysics::advanceKMC -- charge not conserved!");
473 }
474
475 // This loop is for isolating reactions that the user will explicitly ask to fire before computing the physics-based time step. It exists
476 // because if there are no electrons but lots of ions, one may get a time step that is too large because X/|sum mu| is zero for the electrons.
477 // Similarly, one may get a time step that is too small away from ionization regions because X/|sum mu| may be tiny if there is, say, 1 electron
478 // but lots of detachment.
481
482 for (int i = 0; i < propensities.size(); i++) {
483 propensities[i] *= m_reactiveDtFactors[i];
484 }
485
486 return propensities;
487 };
488
489 // Do a time step limitation on the complete state, using the user-specified reactions.
492
493 a_physicsDt = std::min(a_physicsDt, physicsDt);
494
495 // Go through reactions that are potentially detaching species and do the calculation again.
496 for (const auto& reaction : m_kmcReactionsThreadLocal) {
497 auto S = m_kmcState;
498 const auto N = reaction->computeCriticalNumberOfReactions(m_kmcState);
499
500 // Trigger on both the reactions and the reactions with completely consumed reactants
501 if (N < std::numeric_limits<FPR>::max()) {
502 reaction->advanceState(S, N);
503
504 const auto propensitiesDt = getPropensitiesDt(S);
506
507 a_physicsDt = std::min(a_physicsDt, physicsDt);
508 }
509 }
510}
511
512inline void
517 const RealVect a_cellPos,
519 const RealVect a_lo,
520 const RealVect a_hi,
523 const Real a_dx,
524 const Real a_kappa) const noexcept
525{
526 CH_TIMERS("ItoKMCPhysics::reconcileParticles");
527 CH_TIMER("ItoKMCPhysics::reconcileParticles::compute_downstream", t1);
528 CH_TIMER("ItoKMCPhysics::reconcileParticles::particle_placement", t2);
529
530 CH_assert(m_isDefined);
531 CH_assert(a_particles.size() == a_newNumParticles.size());
533
534 if (m_debug) {
535 for (int i = 0; i < a_particles.size(); i++) {
536 const FPR& numNew = a_newNumParticles[i];
537 const FPR& numOld = a_oldNumParticles[i];
538
539 if (numNew < (FPR)0) {
540 MayDay::Warning("ItoKMCPhysics::reconcileParticles - new number of particles is < 0 (overflow issue?)");
541 }
542 else if (static_cast<long long>(numNew) < 0LL) {
543 MayDay::Warning("ItoKMCPhysics::reconcileParticles - integer overflow!");
544 }
545
546 if (numOld < 0) {
547 MayDay::Warning("ItoKMCPhysics::reconcileParticles - old number of particles is < 0");
548 }
549 else if (static_cast<long long>(numOld) < 0LL) {
550 MayDay::Warning("ItoKMCPhysics::reconcileParticles - integer overflow for old particles!");
551 }
552 }
553 }
554
555 // Compute the upstream position of the particles (which is usually the electrons).
556 bool hasDownstream = false;
561 int Z = 0;
562
563 if (m_particlePlacement == ParticlePlacement::Downstream) {
564 CH_assert(m_downstreamSpecies >= 0);
565
566 Z = m_itoSpecies[m_downstreamSpecies]->getChargeNumber();
567
568 if (Z != 0) {
569 v = Z * a_electricField;
570 v = v / v.vectorLength();
571 }
572
573 hasDownstream = this->computeUpstreamPosition(upstreamPosition,
576 Z,
577 *a_particles[m_downstreamSpecies],
579 a_cellPos,
580 a_dx);
581 }
582
583 CH_START(t2);
584 for (int i = 0; i < a_particles.size(); i++) {
585 const long long diff = static_cast<long long>(a_newNumParticles[i] - a_oldNumParticles[i]);
586
587 if (diff > 0LL) {
588 const long long numParticles = static_cast<long long>(a_particles[i]->length());
589
590 if (numParticles > 0LL && m_incrementNewParticles) {
591 // If the cell already contains particles, partition the new particle weights and increment the existing particles
592 const std::vector<long long> particleWeights = ParticleManagement::partitionParticleWeights(diff, numParticles);
593
595
596 for (int j = 0; lit.ok() && j < particleWeights.size(); ++lit, j++) {
597 lit().weight() += 1.0 * particleWeights[j];
598 }
599 }
600 else {
601 // Adding new particles, which is fairly simple. Just choose weights for the particles and go with one of the placement algorithms.
602 const std::vector<long long> particleWeights = ParticleManagement::partitionParticleWeights(
603 diff,
604 static_cast<long long>(m_maxNewParticles));
605
606 for (const auto& w : particleWeights) {
608
609 // Figure out where to place the particles.
610 switch (m_particlePlacement) {
611 case ParticlePlacement::Centroid: {
613
614 break;
615 }
616 case ParticlePlacement::Random: {
618
619 break;
620 }
621 case ParticlePlacement::Downstream: {
622 if (hasDownstream) {
624
625 if ((x - a_bndryCentroid).dotProduct(a_bndryNormal) < 0.0) {
627 }
628
629 x = a_cellPos + x * a_dx;
630 }
631 else {
632
634 }
635
636 break;
637 }
638 default: {
639 MayDay::Error("ItoKMCPhysics::reconcileParticles - logic bust");
640
641 break;
642 }
643 }
644
645 a_particles[i]->add(ItoParticle(1.0 * w, x));
646 }
647 }
648 }
649 else if (diff < 0LL) {
650 // Removing particles is a bit more difficult because we need to manipulate weights.
651 this->removeParticles(*a_particles[i], -diff);
652 }
653 }
654 CH_STOP(t2);
655}
656
657inline bool
659 RealVect& a_lo,
660 RealVect& a_hi,
661 const int& a_Z,
664 const RealVect& a_cellPos,
665 const Real& a_dx) const noexcept
666{
667 CH_TIME("ItoKMCPhysics::computeUpstreamPosition");
668
669 CH_assert(a_dx > 0.0);
670
672 a_lo = -0.5 * RealVect::Unit;
673 a_hi = +0.5 * RealVect::Unit;
674
675 // Quick lambda for turning physical position into unit cell position.
676 auto unitCellPosition = [&](const ItoParticle& p) -> RealVect {
677 return (p.position() - a_cellPos) / a_dx;
678 };
679
680 const int Z = (a_Z > 0) ? 1 : (a_Z < 0) ? -1 : 0;
681 const RealVect E = a_electricField / a_electricField.vectorLength();
682 const RealVect v = Z * E;
683
684 // Upstream can only exist if there is a velocity direction and there are particles.
685 const bool hasDownstream = (a_particles.length() > 0) && (v.vectorLength() > 0.0);
686
687 if (hasDownstream) {
688
689 Real D = std::numeric_limits<Real>::max();
690
692 const RealVect x = unitCellPosition(lit());
693 const Real d = x.dotProduct(v);
694
695 if (d < D) {
696 D = d;
697 a_pos = x;
698 }
699 }
700
702 }
703
704 if (m_debug) {
705 for (int dir = 0; dir < SpaceDim; dir++) {
706 if (a_pos[dir] > 0.5 || a_pos[dir] < -0.5) {
707 MayDay::Abort("ItoKMCPhysics::computeUpstreamPosition - logic bust");
708 }
709 }
710 }
711
712 return hasDownstream;
713}
714
715inline void
717{
718 CH_TIME("ItoKMCPhysics::removeParticles");
719
720 constexpr long long zero = 0LL;
721
724
725 // Quick lambda for getting total particle weight. Used for debugging.
726 auto getTotalWeight = [&]() -> long long {
727 long long W = zero;
728
730 W += llround(lit().weight());
731
732 if (lit().weight() < 1.0) {
733 MayDay::Error("ItoKMCPhysics::removeParticles -- bad particle mass!");
734 }
735 }
736
737 return W;
738 };
739
741
742 // For debugging only.
743 long long totalWeightBefore = 0;
744 long long totalWeightAfter = 0;
745
746 // Debug hook, compute the total particle weight before we start removing weights.
747 if (m_debug) {
749
751 MayDay::Error("ItoKMCPhysics::removeParticles: logic bust (trying to remove too many particles)");
752 }
753 }
754
755 // Remove physical particles.
756 ParticleManagement::removePhysicalParticles(a_particles, a_numParticlesToRemove);
757
758 // Remove particles with too low weight.
759 ParticleManagement::deleteParticles(a_particles, std::numeric_limits<Real>::min());
760
761 // Debug hook, make sure that particle weights are > 0 AND we've removed the desired
762 // particle weight.
763 if (m_debug) {
765
767 if (std::abs(errDiff) != zero) {
768
769 pout() << "ItoKMCPhysics::removeParticles: Total weight before = " << totalWeightBefore << endl;
770 pout() << "ItoKMCPhysics::removeParticles: Total weight after = " << totalWeightAfter << endl;
771 pout() << "ItoKMCPhysics::removeParticles: Should have removed = " << a_numParticlesToRemove << endl;
772 pout() << "ItoKMCPhysics::removeParticles: Error = " << errDiff << endl;
773
774 MayDay::Abort("ItoKMCPhysics::removeParticles - incorrect mass removed");
775 }
776 }
777 }
778}
779
780inline void
783 const RealVect a_cellPos,
785 const RealVect a_lo,
786 const RealVect a_hi,
789 const Real a_dx,
790 const Real a_kappa) const noexcept
791{
792 CH_TIME("ItoKMCPhysics::reconcilePhotons");
793
794 CH_assert(m_isDefined);
795
796 for (int i = 0; i < a_newPhotons.size(); i++) {
797 if (a_numNewPhotons[i] > 0LL) {
798
799 const std::vector<long long> photonWeights = ParticleManagement::partitionParticleWeights(
800 static_cast<long long>(a_numNewPhotons[i]),
801 static_cast<long long>(m_maxNewPhotons));
802
803 for (const auto& w : photonWeights) {
806
807 a_newPhotons[i]->add(Photon(x, v, m_rtSpecies[i]->getAbsorptionCoefficient(x), 1.0 * w));
808 }
809 }
810 }
811}
812
813inline void
816 const Vector<List<Photon>*>& a_absorbedPhotons) const noexcept
817{
818 CH_TIME("ItoKMCPhysics::reconcilePhotoionization");
819
820 CH_assert(m_isDefined);
821 CH_assert(a_itoParticles.size() == m_itoSpecies.size());
822 CH_assert(a_cdrParticles.size() == m_cdrSpecies.size());
823
824 for (int i = 0; i < a_absorbedPhotons.size(); i++) {
825 if (m_photoPathways.find(i) != m_photoPathways.end()) {
826 std::discrete_distribution<int> d = m_photoPathways.at(i).first;
827 const std::map<int, int>& localToGlobalMap = m_photoPathways.at(i).second;
828
830 const RealVect x = lit().position();
831 const Real w = lit().weight();
832
833 // Determine the photo-reaction type.
834 const int localReaction = Random::get(d);
836
837 const ItoKMCPhotoReaction& photoReaction = m_photoReactions[globalReaction];
838 const std::list<size_t>& plasmaTargets = photoReaction.getTargetSpecies();
839
840 for (const auto& t : plasmaTargets) {
841 const SpeciesType& type = m_speciesMap.at(t).first;
842 const int& localIndex = m_speciesMap.at(t).second;
843
844 if (type == SpeciesType::Ito) {
846 }
847 else if (type == SpeciesType::CDR) {
849 }
850 else {
851 MayDay::Error("CD_ItoKMCPhysics.H - logic bust in reconcilePhotoionization");
852 }
853 }
854 }
855 }
856 }
857}
858
859inline RealVect
861{
862 return RealVect::Zero;
863}
864
865inline RealVect
867{
869
870 for (int dir = 0; dir < SpaceDim; dir++) {
872 }
873
874 return sqrt(2.0 * a_particle.diffusion() * a_dt) * r;
875}
876
877inline RealVect
879{
880 RealVect hop = this->isotropicDiffusion(a_particle, a_dt);
881
882 const RealVect v = a_particle.velocity();
883
884 if (v != RealVect::Zero) {
885 const RealVect u = v / v.vectorLength();
886 const Real d = u.dotProduct(hop);
887
888 hop -= std::min(d, 0.0) * u;
889 }
890
891 return hop;
892}
893
894#include <CD_NamespaceFooter.H>
895
896#endif
Agglomeration of useful data operations.
Declaration of the Physics::ItoKMC::ItoKMCPhysics abstract base class.
Real FPR
Floating-point type used to represent particle counts in the KMC state.
Definition CD_ItoKMCPhysics.H:45
SpeciesType
Tag for distinguishing species solved with an Ito diffusion or CDR fluid formalism.
Definition CD_ItoKMCPhysics.H:71
@ ImplicitEuler
Implicit Euler tau leaping.
@ Midpoint
Gillespie's midpoint method.
@ ExplicitEuler
Regular tau leaping.
@ PRC
Hu and Li's Poisson random correction method.
Namespace containing various particle management utilities.
File containing some useful static methods related to random number generation.
Declaration of various useful units.
static void computeMinValidBox(RealVect &a_lo, RealVect &a_hi, const RealVect &a_normal, const RealVect &a_centroid)
Compute the tightest possible valid box around a cut-cell volume.
Definition CD_DataOps.cpp:3687
A particle class for use with ItoSolvers, i.e. drifting Brownian walkers.
Definition CD_ItoParticle.H:41
Particle class for usage with Monte Carlo radiative transfer.
Definition CD_Photon.H:30
Reaction class for describing photoionization in ItoKMCPhysics.
Definition CD_ItoKMCPhotoReaction.H:32
int m_maxNewParticles
Maximum new number of particles generated by the chemistry advance.
Definition CD_ItoKMCPhysics.H:545
void reconcilePhotons(Vector< List< Photon > * > &a_newPhotons, const Vector< FPR > &a_numNewPhotons, const RealVect a_cellPos, const RealVect a_centroidPos, const RealVect a_lo, const RealVect a_hi, const RealVect a_bndryCentroid, const RealVect a_bndryNormal, const Real a_dx, const Real a_kappa) const noexcept
Generate new photons.
Definition CD_ItoKMCPhysicsImplem.H:781
int m_NSSA
Solver setting for the Cao et. al algorithm.
Definition CD_ItoKMCPhysics.H:562
bool m_incrementNewParticles
If true, increment onto existing particles rather than creating new ones.
Definition CD_ItoKMCPhysics.H:464
Vector< RefCountedPtr< RtSpecies > > m_rtSpecies
List of solver-tracked photon species.
Definition CD_ItoKMCPhysics.H:533
int m_downstreamSpecies
An internal integer describing which species is the "ionizing" species.
Definition CD_ItoKMCPhysics.H:540
virtual void updateReactionRates(std::vector< std::shared_ptr< const KMCReaction > > &a_kmcReactions, const RealVect a_E, const RealVect a_pos, const Vector< Real > &a_phi, const Vector< RealVect > &a_gradPhi, const Real a_dt, const Real a_dx, const Real a_kappa) const noexcept=0
Update reaction rates.
RealVect forwardIsotropicDiffusion(const ItoParticle &a_particle, const Real a_dt) const noexcept
Quasi-isotropic diffusion function for a particle which does not permit backward diffusion.
Definition CD_ItoKMCPhysicsImplem.H:878
Vector< DiffusionFunction > m_itoDiffusionFunctions
Diffusion functions for the various Ito species.
Definition CD_ItoKMCPhysics.H:518
Real m_eps
Solver setting for the Cao et. al. algorithm.
Definition CD_ItoKMCPhysics.H:579
bool m_debug
Turn on/off debugging.
Definition CD_ItoKMCPhysics.H:454
void reconcilePhotoionization(Vector< List< ItoParticle > * > &a_itoParticles, Vector< List< PointParticle > * > &a_cdrParticles, const Vector< List< Photon > * > &a_absorbedPhotons) const noexcept
Reconcile photoionization reactions.
Definition CD_ItoKMCPhysicsImplem.H:814
std::vector< Real > m_reactiveDtFactors
List of reactions that are a part of the time step limitation.
Definition CD_ItoKMCPhysics.H:500
int m_maxNewPhotons
Maximum new number of photons generated by the chemistry advance.
Definition CD_ItoKMCPhysics.H:550
void defineKMC() const noexcept
Define the KMC solver and state.
Definition CD_ItoKMCPhysicsImplem.H:110
RealVect isotropicDiffusion(const ItoParticle &a_particle, const Real a_dt) const noexcept
Isotropic diffusion function for a particle.
Definition CD_ItoKMCPhysicsImplem.H:866
void advanceKMC(Vector< FPR > &a_numParticles, Vector< FPR > &a_numNewPhotons, Real &a_physicsDt, const Vector< Real > &a_phi, const Vector< RealVect > &a_gradPhi, const Real a_dt, const RealVect a_E, const RealVect a_pos, const Real a_dx, const Real a_kappa) const
Advance the reaction network using the KMC algorithm.
Definition CD_ItoKMCPhysicsImplem.H:340
std::string m_className
Class name. Used for options parsing.
Definition CD_ItoKMCPhysics.H:449
bool computeUpstreamPosition(RealVect &a_pos, RealVect &a_lo, RealVect &a_hi, const int &a_Z, const List< ItoParticle > &a_particles, const RealVect &a_electricField, const RealVect &a_cellPos, const Real &a_dx) const noexcept
Compute the upstream position in a grid cell. Returns false if an upstream position was undefinable.
Definition CD_ItoKMCPhysicsImplem.H:658
const Vector< DiffusionFunction > & getItoDiffusionFunctions() const noexcept
Get diffusion functions for all Ito species.
Definition CD_ItoKMCPhysicsImplem.H:304
std::vector< ItoKMCPhotoReaction > m_photoReactions
List of photoionization reactions.
Definition CD_ItoKMCPhysics.H:495
const Vector< RefCountedPtr< RtSpecies > > & getRtSpecies() const
Get all photon species.
Definition CD_ItoKMCPhysicsImplem.H:298
Vector< RefCountedPtr< ItoSpecies > > m_itoSpecies
List of solver-tracked particle drift-diffusion species.
Definition CD_ItoKMCPhysics.H:523
Vector< RefCountedPtr< CdrSpecies > > m_cdrSpecies
List of solver-tracked fluid drift-diffusion species.
Definition CD_ItoKMCPhysics.H:528
virtual Real initialSigma(const Real a_time, const RealVect &a_pos) const
Set initial surface charge. Default is 0, override if you want.
Definition CD_ItoKMCPhysicsImplem.H:334
Real m_exitTol
Exit tolerance for implicit KMC-leaping algorithms.
Definition CD_ItoKMCPhysics.H:584
virtual ~ItoKMCPhysics() noexcept
Destructor. Does nothing.
Definition CD_ItoKMCPhysicsImplem.H:56
static thread_local KMCSolverType m_kmcSolver
Kinetic Monte Carlo solver used in advanceReactionNetwork.
Definition CD_ItoKMCPhysics.H:474
void defineSpeciesMap() noexcept
Build internal representation of how we distinguish the Ito and CDR solvers.
Definition CD_ItoKMCPhysicsImplem.H:92
const Vector< RefCountedPtr< ItoSpecies > > & getItoSpecies() const
Get all particle drift-diffusion species.
Definition CD_ItoKMCPhysicsImplem.H:286
Real m_SSAlim
Solver setting for the Cao et. al. algorithm.
Definition CD_ItoKMCPhysics.H:573
void parseAlgorithm() noexcept
Parse reaction algorithm.
Definition CD_ItoKMCPhysicsImplem.H:237
int m_maxIter
Maximum number of iterations for implicit KMC-leaping algorithms.
Definition CD_ItoKMCPhysics.H:567
int m_Ncrit
Solver setting for the Cao et. al algorithm.
Definition CD_ItoKMCPhysics.H:556
const std::map< int, std::pair< SpeciesType, int > > & getSpeciesMap() const noexcept
Get the internal mapping from plasma-species index to solver type and solver index.
Definition CD_ItoKMCPhysicsImplem.H:197
std::map< int, std::pair< std::discrete_distribution< int >, std::map< int, int > > > m_photoPathways
Random number generators for photoionization pathways.
Definition CD_ItoKMCPhysics.H:508
void reconcileParticles(Vector< List< ItoParticle > * > &a_particles, const Vector< FPR > &a_newNumParticles, const Vector< FPR > &a_oldNumParticles, const RealVect a_electricField, const RealVect a_cellPos, const RealVect a_centroidPos, const RealVect a_lo, const RealVect a_hi, const RealVect a_bndryCentroid, const RealVect a_bndryNormal, const Real a_dx, const Real a_kappa) const noexcept
Reconcile the number of particles.
Definition CD_ItoKMCPhysicsImplem.H:513
@ HybridMidpoint
Hybrid SSA / midpoint (Cao et al.).
@ ImplicitEuler
Implicit tau-leaping with Euler steps.
@ SSA
Gillespie's Stochastic Simulation Algorithm (exact).
@ Midpoint
Explicit tau-leaping with midpoint (second-order) steps.
@ ExplicitEuler
Explicit tau-leaping with Euler steps.
@ HybridImplicitEuler
Hybrid SSA / implicit Euler (Cao et al.).
@ HybridPRC
Hybrid SSA / PRC (Cao et al.).
@ HybridExplicitEuler
Hybrid SSA / explicit Euler (Cao et al.).
@ PRC
Partially-rejected corrections tau-leaping.
Algorithm m_algorithm
Algorithm to use for KMC advance.
Definition CD_ItoKMCPhysics.H:434
virtual void parseRuntimeOptions() noexcept
Parse run-time options.
Definition CD_ItoKMCPhysicsImplem.H:205
@ Random
Place particles at a uniformly random position within the cell.
void removeParticles(List< ItoParticle > &a_particles, const long long a_numToRemove) const
Remove particles from the input list.
Definition CD_ItoKMCPhysicsImplem.H:716
const Vector< RefCountedPtr< CdrSpecies > > & getCdrSpecies() const
Get all fluid drift-diffusion species.
Definition CD_ItoKMCPhysicsImplem.H:292
static thread_local std::vector< std::shared_ptr< const KMCReaction > > m_kmcReactionsThreadLocal
Thread-local copies of KMC reactions used in advanceReactionNetwork.
Definition CD_ItoKMCPhysics.H:485
std::vector< KMCReaction > m_kmcReactions
List of reactions for the KMC solver.
Definition CD_ItoKMCPhysics.H:490
int getNumPhotonSpecies() const
Return number of RTE solvers.
Definition CD_ItoKMCPhysicsImplem.H:328
int getNumPlasmaSpecies() const
Return total number of plasma species.
Definition CD_ItoKMCPhysicsImplem.H:322
int getNumItoSpecies() const
Return number of Ito solvers.
Definition CD_ItoKMCPhysicsImplem.H:310
void define() noexcept
Define method – defines all the internal machinery.
Definition CD_ItoKMCPhysicsImplem.H:62
std::map< int, std::pair< SpeciesType, int > > m_speciesMap
Map for associating a plasma species with an Ito solver or CDR solver.
Definition CD_ItoKMCPhysics.H:444
RealVect noDiffusion(const ItoParticle &a_particle, const Real a_dt) const noexcept
No diffusion function for a particle.
Definition CD_ItoKMCPhysicsImplem.H:860
void killKMC() const noexcept
Kill the KMC solver.
Definition CD_ItoKMCPhysicsImplem.H:130
void definePhotoPathways() noexcept
Define pathways for photo-reactions.
Definition CD_ItoKMCPhysicsImplem.H:144
void parsePPC() noexcept
Parse the maximum number of particles generated per cell.
Definition CD_ItoKMCPhysicsImplem.H:215
static thread_local bool m_hasKMCSolver
Is the KMC solver defined or not.
Definition CD_ItoKMCPhysics.H:469
int getNumCdrSpecies() const
Return number of CDR solvers.
Definition CD_ItoKMCPhysicsImplem.H:316
ParticlePlacement m_particlePlacement
Particle placement algorithm.
Definition CD_ItoKMCPhysics.H:439
void parseDebug() noexcept
Parse the maximum number of particles generated per cell.
Definition CD_ItoKMCPhysicsImplem.H:227
bool m_isDefined
Is defined or not.
Definition CD_ItoKMCPhysics.H:459
static thread_local KMCState m_kmcState
KMC state used in advanceReactionNetwork.
Definition CD_ItoKMCPhysics.H:479
ItoKMCPhysics() noexcept
Constructor. Does nothing.
Definition CD_ItoKMCPhysicsImplem.H:29
A particle class that only has a position and a weight.
Definition CD_PointParticle.H:30
static Real get(T &a_distribution)
For getting a random number from a user-supplied distribution. T must be a distribution for which we ...
Definition CD_RandomImplem.H:217
static RealVect getDirection()
Get a random direction in space.
Definition CD_RandomImplem.H:180
static Real getNormal01()
Get a number from a normal distribution centered on zero and variance 1.
Definition CD_RandomImplem.H:172
static RealVect randomPosition(const RealVect &a_lo, const RealVect &a_hi) noexcept
Return a random position in the cube (a_lo, a_hi);.
Definition CD_RandomImplem.H:284
Base class for a tracer particle solver. This solver can advance particles in a pre-defined velocity ...
Definition CD_TracerParticleSolver.H:38
TracerParticleSolver()
Default constructor.
Definition CD_TracerParticleSolverImplem.H:26
virtual Real computeDt() const
Compute dt = dx/max(v_x, v_y, v_z) minimized over all particles.
Definition CD_TracerParticleSolverImplem.H:623
constexpr Real c
Speed of light.
Definition CD_Units.H:40