12 #ifndef CD_ItoKMCPhysicsImplem_H
13 #define CD_ItoKMCPhysicsImplem_H
16 #include <ParmParse.H>
23 #include <CD_NamespaceHeader.H>
25 using namespace Physics::ItoKMC;
29 CH_TIME(
"ItoKMCPhysics::ItoKMCPhysics");
51 bool useCentroid =
false;
52 ParmParse pp(
"ItoKMCPhysics");
53 pp.query(
"use_centroid", useCentroid);
62 CH_TIME(
"ItoKMCPhysics::~ItoKMCPhysics");
68 CH_TIME(
"ItoKMCPhysics::define");
76 const auto& lhsReactants =
R.getReactants();
77 const auto& rhsReactants =
R.getReactiveProducts();
78 const auto& rhsPhotons =
R.getNonReactiveProducts();
80 for (
const auto& r : lhsReactants) {
83 for (
const auto& r : rhsReactants) {
86 for (
const auto& r : rhsPhotons) {
98 CH_TIME(
"ItoKMCPhysics::defineSpeciesMap");
104 for (
int i = 0; i < numItoSpecies; i++, species++) {
105 m_speciesMap.emplace(species, std::make_pair(SpeciesType::Ito, i));
108 for (
int i = 0; i < numCdrSpecies; i++, species++) {
109 m_speciesMap.emplace(species, std::make_pair(SpeciesType::CDR, i));
116 CH_TIME(
"ItoKMCPhysics::defineKMC");
136 CH_TIME(
"ItoKMCPhysics::defineKMC");
150 CH_TIME(
"ItoKMCPhysics::definePhotoPathways");
161 std::map<int, std::vector<std::pair<int, Real>>> pathways;
169 pathways[src].emplace_back(std::make_pair(i, efficiency));
177 for (
const auto& p : pathways) {
178 const int photoSpecies = p.first;
179 const std::vector<std::pair<int, Real>> reactionsAndEfficiencies = p.second;
181 std::map<int, int> localToGlobalMap;
182 std::list<double> efficiencies;
183 double sumEfficiencies = 0.0;
185 for (
int i = 0; i < reactionsAndEfficiencies.size(); i++) {
186 sumEfficiencies += (double)reactionsAndEfficiencies[i].second;
189 for (
int i = 0; i < reactionsAndEfficiencies.size(); i++) {
190 localToGlobalMap.emplace(i, reactionsAndEfficiencies[i].first);
191 efficiencies.emplace_back((
double)reactionsAndEfficiencies[i].second / sumEfficiencies);
194 std::discrete_distribution<int> distribution(efficiencies.begin(), efficiencies.end());
196 m_photoPathways.insert(std::make_pair((
int)photoSpecies, std::make_pair(distribution, localToGlobalMap)));
200 inline const std::map<int, std::pair<SpeciesType, int>>&
203 CH_TIME(
"ItoKMCPhysics::getSpeciesMap");
211 CH_TIME(
"ItoKMCPhysics::computeDt");
213 CH_assert(m_isDefined);
221 CH_TIME(
"ItoKMCPhysics::parseRuntimeOptions");
231 CH_TIME(
"ItoKMCPhysics::parsePPC");
242 CH_TIME(
"ItoKMCPhysics::parseDebug");
252 CH_TIME(
"ItoKMCPhysics::parseAlgorithm");
258 pp.get(
"algorithm", str);
261 pp.get(
"prop_eps",
m_eps);
267 else if (str ==
"tau_plain") {
270 else if (str ==
"tau_midpoint") {
273 else if (str ==
"hybrid_plain") {
276 else if (str ==
"hybrid_midpoint") {
280 MayDay::Error(
"ItoKMCPhysics::parseAlgorithm - unknown algorithm requested");
284 inline const Vector<RefCountedPtr<ItoSpecies>>&
290 inline const Vector<RefCountedPtr<CdrSpecies>>&
296 inline const Vector<RefCountedPtr<RtSpecies>>&
334 Vector<FPR>& a_numNewPhotons,
335 const Vector<Real>& a_phi,
336 const Vector<RealVect>& a_gradPhi,
339 const RealVect a_pos,
341 const Real a_kappa)
const
343 CH_TIME(
"ItoKMCPhysics::advanceKMC");
353 for (
size_t i = 0; i < a_numParticles.size(); i++) {
354 kmcParticles[i] = a_numParticles[i];
357 for (
auto& p : kmcPhotons) {
366 case Algorithm::SSA: {
371 case Algorithm::TauPlain: {
376 case Algorithm::TauMidpoint: {
381 case Algorithm::HybridPlain: {
386 case Algorithm::HybridMidpoint: {
392 MayDay::Error(
"ItoKMCPhysics::advanceKMC - logic bust");
397 for (
size_t i = 0; i < a_numParticles.size(); i++) {
398 a_numParticles[i] = (
FPR)kmcParticles[i];
400 for (
size_t i = 0; i < a_numNewPhotons.size(); i++) {
401 a_numNewPhotons[i] = (
FPR)kmcPhotons[i];
407 const Vector<FPR>& a_newNumParticles,
408 const Vector<FPR>& a_oldNumParticles,
409 const RealVect a_cellPos,
410 const RealVect a_centroidPos,
413 const RealVect a_bndryCentroid,
414 const RealVect a_bndryNormal,
416 const Real a_kappa)
const noexcept
418 CH_TIME(
"ItoKMCPhysics::reconcileParticles(Vector<List<ItoParticle>*>, ...)");
420 CH_assert(m_isDefined);
421 CH_assert(a_particles.size() == a_newNumParticles.size());
422 CH_assert(a_oldNumParticles.size() == a_newNumParticles.size());
425 for (
int i = 0; i < a_particles.size(); i++) {
426 const FPR& numNew = a_newNumParticles[i];
427 const FPR& numOld = a_oldNumParticles[i];
429 if (numNew < (
FPR)0) {
430 MayDay::Warning(
"ItoKMCPhysics::reconcileParticles - new number of particles is < 0 (overflow issue?)");
432 else if ((
long long)numNew < 0LL) {
433 MayDay::Warning(
"ItoKMCPhysics::reconcileParticles - integer overflow!");
437 MayDay::Warning(
"ItoKMCPhysics::reconcileParticles - old number of particles is < 0");
439 else if ((
long long)numOld < 0LL) {
440 MayDay::Warning(
"ItoKMCPhysics::reconcileParticles - integer overflow for old particles!");
445 for (
int i = 0; i < a_particles.size(); i++) {
446 const long long diff = (
long long)(a_newNumParticles[i] - a_oldNumParticles[i]);
450 const std::vector<long long> particleWeights = ParticleManagement::partitionParticleWeights(
452 (
long long)m_maxNewParticles);
454 for (
const auto& w : particleWeights) {
455 RealVect x = RealVect::Zero;
458 switch (m_particlePlacement) {
459 case ParticlePlacement::Random: {
464 case ParticlePlacement::Centroid: {
465 x = a_cellPos + a_centroidPos * a_dx;
470 MayDay::Error(
"ItoKMCPhysics::reconcileParticles - logic bust");
479 else if (diff < 0LL) {
481 this->removeParticles(*a_particles[i], -diff);
489 CH_TIME(
"ItoKMCPhysics::removeParticles");
491 constexpr
long long zero = 0LL;
494 CH_assert(a_numParticlesToRemove >= zero);
497 auto getTotalWeight = [&]() ->
long long {
500 for (ListIterator<ItoParticle> lit(a_particles); lit.ok(); ++lit) {
501 W += (
long long)lit().weight();
503 if (lit().weight() < 1.0) {
504 MayDay::Error(
"ItoKMCPhysics::removeParticles -- bad particle mass!");
511 if (a_numParticlesToRemove > zero) {
514 long long totalWeightBefore = 0;
515 long long totalWeightAfter = 0;
519 totalWeightBefore = getTotalWeight();
521 if (totalWeightBefore < a_numParticlesToRemove) {
522 MayDay::Error(
"ItoKMCPhysics::removeParticles: logic bust (trying to remove too many particles)");
527 ParticleManagement::removePhysicalParticles(a_particles, a_numParticlesToRemove);
535 totalWeightAfter = getTotalWeight();
537 const long long errDiff = std::abs(totalWeightBefore - totalWeightAfter) - a_numParticlesToRemove;
538 if (std::abs(errDiff) != zero) {
540 pout() <<
"ItoKMCPhysics::removeParticles: Total weight before = " << totalWeightBefore << endl;
541 pout() <<
"ItoKMCPhysics::removeParticles: Total weight after = " << totalWeightAfter << endl;
542 pout() <<
"ItoKMCPhysics::removeParticles: Should have removed = " << a_numParticlesToRemove << endl;
543 pout() <<
"ItoKMCPhysics::removeParticles: Error = " << errDiff << endl;
545 MayDay::Abort(
"ItoKMCPhysics::removeParticles - incorrect mass removed");
553 const Vector<FPR>& a_numNewPhotons,
554 const RealVect a_cellPos,
555 const RealVect a_centroidPos,
558 const RealVect a_bndryCentroid,
559 const RealVect a_bndryNormal,
561 const Real a_kappa)
const noexcept
563 CH_TIME(
"ItoKMCPhysics::reconcilePhotons");
565 CH_assert(m_isDefined);
567 for (
int i = 0; i < a_newPhotons.size(); i++) {
568 if (a_numNewPhotons[i] > 0LL) {
570 const std::vector<long long> photonWeights = ParticleManagement::partitionParticleWeights(
571 (
long long)a_numNewPhotons[i],
572 (
long long)m_maxNewPhotons);
574 for (
const auto& w : photonWeights) {
575 const RealVect x =
Random::randomPosition(a_cellPos, a_lo, a_hi, a_bndryCentroid, a_bndryNormal, a_dx, a_kappa);
578 a_newPhotons[i]->add(
Photon(x, v, m_rtSpecies[i]->getAbsorptionCoefficient(x), 1.0 * w));
586 Vector<List<PointParticle>*>& a_cdrParticles,
587 const Vector<List<Photon>*>& a_absorbedPhotons)
const noexcept
589 CH_TIME(
"ItoKMCPhysics::reconcilePhotoionization");
591 CH_assert(m_isDefined);
592 CH_assert(a_itoParticles.size() == m_itoSpecies.size());
593 CH_assert(a_cdrParticles.size() == m_cdrSpecies.size());
595 for (
int i = 0; i < a_absorbedPhotons.size(); i++) {
596 if (m_photoPathways.find(i) != m_photoPathways.end()) {
597 std::discrete_distribution<int> d = m_photoPathways.at(i).first;
598 const std::map<int, int>& localToGlobalMap = m_photoPathways.at(i).second;
600 for (ListIterator<Photon> lit(*a_absorbedPhotons[i]); lit.ok(); ++lit) {
601 const RealVect x = lit().position();
602 const Real w = lit().weight();
606 const int globalReaction = localToGlobalMap.at(localReaction);
611 for (
const auto& t : plasmaTargets) {
612 const SpeciesType& type = m_speciesMap.at(t).first;
613 const int& localIndex = m_speciesMap.at(t).second;
615 if (type == SpeciesType::Ito) {
616 a_itoParticles[localIndex]->add(
ItoParticle(w, x));
618 else if (type == SpeciesType::CDR) {
622 MayDay::Error(
"CD_ItoKMCPhysics.H - logic bust in reconcilePhotoionization");
630 #include <CD_NamespaceFooter.H>
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:66
Namespace containing various particle management utilities.
File containing some useful static methods related to random number generation.
Declaration of various useful units.
A particle class for use with ItoSolvers, i.e. drifting Brownian walkers.
Definition: CD_ItoParticle.H:40
State & getNonReactiveState() noexcept
Get modifiable non-reactive state.
Definition: CD_KMCDualStateImplem.H:80
void define(const size_t a_numReactiveSpecies, const size_t a_numNonReactiveSpecies) noexcept
Define function constructor.
Definition: CD_KMCDualStateImplem.H:33
State & getReactiveState() noexcept
Get modifiable reactive state.
Definition: CD_KMCDualStateImplem.H:66
void setSolverParameters(const T a_numCrit, const T a_numSSA, const Real a_eps, const Real a_SSAlim) noexcept
Set solver parameters.
Definition: CD_KMCSolverImplem.H:59
void advanceTauMidpoint(State &a_state, const Real a_dt) const noexcept
Perform one leaping step using the midpoint method all reactions over a time step a_dt.
Definition: CD_KMCSolverImplem.H:445
void define(const ReactionList &a_reactions) noexcept
Define function. Sets the reactions.
Definition: CD_KMCSolverImplem.H:47
void advanceSSA(State &a_state, const Real a_dt) const noexcept
Advance with the SSA over the input time. This can end up using substepping.
Definition: CD_KMCSolverImplem.H:562
void advanceTauPlain(State &a_state, const Real a_dt) const noexcept
Advance with plain tau-leaping step over the input time. This can end up using substepping.
Definition: CD_KMCSolverImplem.H:358
void advanceHybrid(State &a_state, const Real a_dt, const KMCLeapPropagator &a_leapPropagator=KMCLeapPropagator::TauPlain) const noexcept
Advance using Cao et. al. hybrid algorithm over the input time. This can end up using substepping.
Definition: CD_KMCSolverImplem.H:601
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
const Real & getEfficiency() const noexcept
Get reaction efficiency.
Definition: CD_ItoKMCPhotoReactionImplem.H:59
const size_t & getSourcePhoton() const noexcept
Get the photon source.
Definition: CD_ItoKMCPhotoReactionImplem.H:47
const std::list< size_t > & getTargetSpecies() const noexcept
Get the photon target products.
Definition: CD_ItoKMCPhotoReactionImplem.H:53
int m_maxNewParticles
Maximum new number of particles generated by the chemistry advance.
Definition: CD_ItoKMCPhysics.H:496
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:552
int m_NSSA
Solver setting for the Cao et. al algorithm.
Definition: CD_ItoKMCPhysics.H:513
Vector< RefCountedPtr< RtSpecies > > m_rtSpecies
List of solver-tracked photon species.
Definition: CD_ItoKMCPhysics.H:491
virtual Real computeDt(const RealVect a_E, const RealVect a_pos, const Vector< FPR > a_numParticles) const noexcept
Compute a time step to use.
Definition: CD_ItoKMCPhysicsImplem.H:209
Real m_eps
Solver setting for the Cao et. al. algorithm.
Definition: CD_ItoKMCPhysics.H:525
bool m_debug
Turn on/off debugging.
Definition: CD_ItoKMCPhysics.H:426
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:585
int m_maxNewPhotons
Maximum new number of photons generated by the chemistry advance.
Definition: CD_ItoKMCPhysics.H:501
void defineKMC() const noexcept
Define the KMC solver and state.
Definition: CD_ItoKMCPhysicsImplem.H:114
std::string m_className
Class name. Used for options parsing.
Definition: CD_ItoKMCPhysics.H:421
std::vector< ItoKMCPhotoReaction > m_photoReactions
List of photoionization reactions.
Definition: CD_ItoKMCPhysics.H:463
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:481
Vector< RefCountedPtr< CdrSpecies > > m_cdrSpecies
List of solver-tracked fluid drift-diffusion species.
Definition: CD_ItoKMCPhysics.H:486
virtual ~ItoKMCPhysics() noexcept
Destructor. Does nothing.
Definition: CD_ItoKMCPhysicsImplem.H:60
static thread_local KMCSolverType m_kmcSolver
Kinetic Monte Carlo solver used in advanceReactionNetwork.
Definition: CD_ItoKMCPhysics.H:441
void defineSpeciesMap() noexcept
Build internal representation of how we distinguish the Ito and CDR solvers.
Definition: CD_ItoKMCPhysicsImplem.H:96
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:519
void parseAlgorithm() noexcept
Parse reaction algorithm.
Definition: CD_ItoKMCPhysicsImplem.H:250
int m_Ncrit
Solver setting for the Cao et. al algorithm.
Definition: CD_ItoKMCPhysics.H:507
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:201
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_dx, const Real a_kappa) const noexcept=0
Update reaction rates.
void advanceKMC(Vector< FPR > &a_numParticles, Vector< FPR > &a_numNewPhotons, 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 particles.
Definition: CD_ItoKMCPhysicsImplem.H:333
void reconcileParticles(Vector< List< ItoParticle > * > &a_particles, const Vector< FPR > &a_newNumParticles, const Vector< FPR > &a_oldNumParticles, 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:406
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:471
Algorithm m_algorithm
Algorithm to use for KMC advance.
Definition: CD_ItoKMCPhysics.H:406
virtual void parseRuntimeOptions() noexcept
Parse run-time options.
Definition: CD_ItoKMCPhysicsImplem.H:219
void removeParticles(List< ItoParticle > &a_particles, const long long a_numToRemove) const
Remove particles from the input list.
Definition: CD_ItoKMCPhysicsImplem.H:487
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:453
std::vector< KMCReaction > m_kmcReactions
List of reactions for the KMC solver.
Definition: CD_ItoKMCPhysics.H:458
int getNumPhotonSpecies() const
Return number of RTE solvers.
Definition: CD_ItoKMCPhysicsImplem.H:321
int getNumPlasmaSpecies() const
Return total number of plasma species.
Definition: CD_ItoKMCPhysicsImplem.H:315
int getNumItoSpecies() const
Return number of Ito solvers.
Definition: CD_ItoKMCPhysicsImplem.H:303
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:327
void define() noexcept
Define method – defines all the internal machinery.
Definition: CD_ItoKMCPhysicsImplem.H:66
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:416
void killKMC() const noexcept
Kill the KMC solver.
Definition: CD_ItoKMCPhysicsImplem.H:134
void definePhotoPathways() noexcept
Define pathways for photo-reactions.
Definition: CD_ItoKMCPhysicsImplem.H:148
void parsePPC() noexcept
Parse the maximum number of particles generated per cell.
Definition: CD_ItoKMCPhysicsImplem.H:229
static thread_local bool m_hasKMCSolver
Is the KMC solver defined or not.
Definition: CD_ItoKMCPhysics.H:436
int getNumCdrSpecies() const
Return number of CDR solvers.
Definition: CD_ItoKMCPhysicsImplem.H:309
ParticlePlacement m_particlePlacement
Particle placement algorithm.
Definition: CD_ItoKMCPhysics.H:411
void parseDebug() noexcept
Parse the maximum number of particles generated per cell.
Definition: CD_ItoKMCPhysicsImplem.H:240
bool m_isDefined
Is defined or not.
Definition: CD_ItoKMCPhysics.H:431
static thread_local KMCState m_kmcState
KMC state used in advanceReactionNetwork.
Definition: CD_ItoKMCPhysics.H:446
ItoKMCPhysics() noexcept
Constructor. Does nothing.
Definition: CD_ItoKMCPhysicsImplem.H:27
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:208
static RealVect getDirection()
Get a random direction in space.
Definition: CD_RandomImplem.H:171
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:270
Real max(const Real &a_input) noexcept
Get the maximum of the input, reduced over MPI ranks (in the Chombo communicator)
Definition: CD_ParallelOpsImplem.H:176
Real min(const Real &a_input) noexcept
Get the minimum of the input, reduced over MPI ranks (in the Chombo communicator)
Definition: CD_ParallelOpsImplem.H:58
constexpr Real R
Universal gas constant.
Definition: CD_Units.H:64
constexpr Real c
Speed of light.
Definition: CD_Units.H:39