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