chombo-discharge
CD_ItoPlasmaPhysicsImplem.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_ItoPlasmaPhysicsImplem_H
13 #define CD_ItoPlasmaPhysicsImplem_H
14 
15 // Chombo includes
16 #include <ParmParse.H>
17 
18 // Our includes
19 #include <CD_ItoPlasmaPhysics.H>
20 #include <CD_ParticleManagement.H>
21 #include <CD_Random.H>
22 #include <CD_Units.H>
23 #include <CD_NamespaceHeader.H>
24 
25 using namespace Physics::ItoPlasma;
26 
28 {
29  CH_TIME("ItoPlasmaPhysics::ItoPlasmaPhysics");
30 
31  m_className = "ItoPlasmaPhysics";
32 
33  m_kmcReactions.clear();
34  m_photoReactions.clear();
35 
36  // Some default settings in case user forgets to call the parsing algorithms.
37  m_debug = true;
38  m_maxNewParticles = 32;
39  m_maxNewPhotons = 32;
40  m_Ncrit = 5;
41  m_eps = 0.1;
42  m_NSSA = 10;
43  m_SSAlim = 5.0;
44  m_algorithm = Algorithm::Hybrid;
45  m_particlePlacement = ParticlePlacement::Random;
46 
47  // Development code for switching to centroid for secondary emission. To be removed later.
48 #if 1
49  bool useCentroid = false;
50  ParmParse pp("ItoPlasmaPhysics");
51  pp.query("use_centroid", useCentroid);
52  if (useCentroid) {
53  m_particlePlacement = ParticlePlacement::Centroid;
54  }
55 #endif
56 }
57 
58 inline ItoPlasmaPhysics::~ItoPlasmaPhysics() { CH_TIME("ItoPlasmaPhysics::~ItoPlasmaPhysics"); }
59 
60 inline Real
61 ItoPlasmaPhysics::computeDt(const RealVect a_E, const RealVect a_pos, const Vector<FPR> a_numParticles) const noexcept
62 {
63  CH_TIME("ItoPlasmaPhysics::computeDt");
64 
66 }
67 
68 inline void
70 {
71  CH_TIME("ItoPlasmaPhysics::defineKMC");
72 
74 
76 
77  // Define solver parameters in case they've been changed since last time.
79 }
80 
81 inline void
83 {
84  CH_TIME("ItoPlasmaPhysics::parseRuntimeOptions");
85 
86  this->parsePPC();
87  this->parseDebug();
88  this->parseAlgorithm();
89 
90  // Define solver parameters in case they've been changed since last time.
92 }
93 
94 inline void
96 {
97  CH_TIME("ItoPlasmaPhysics::parsePPC");
98 
99  ParmParse pp(m_className.c_str());
100 
101  pp.get("max_new_particles", m_maxNewParticles);
102  pp.get("max_new_photons", m_maxNewPhotons);
103 }
104 
105 inline void
107 {
108  CH_TIME("ItoPlasmaPhysics::parseDebug");
109 
110  ParmParse pp(m_className.c_str());
111 
112  pp.get("debug", m_debug);
113 }
114 
115 inline void
117 {
118  CH_TIME("ItoPlasmaPhysics::parseAlgorithm");
119 
120  ParmParse pp(m_className.c_str());
121 
122  std::string str;
123 
124  pp.get("algorithm", str);
125  pp.get("Ncrit", m_Ncrit);
126  pp.get("NSSA", m_NSSA);
127  pp.get("prop_eps", m_eps);
128  pp.get("SSAlim", m_SSAlim);
129 
130  if (str == "hybrid") {
131  m_algorithm = Algorithm::Hybrid;
132  }
133  else if (str == "tau") {
134  m_algorithm = Algorithm::Tau;
135  }
136  else if (str == "ssa") {
137  m_algorithm = Algorithm::SSA;
138  }
139  else {
140  MayDay::Error("ItoPlasmaPhysics::parseAlgorithm - unknown algorithm requested");
141  }
142 }
143 
144 inline const Vector<RefCountedPtr<ItoSpecies>>&
146 {
147  return m_plasmaSpecies;
148 }
149 
150 inline const Vector<RefCountedPtr<RtSpecies>>&
152 {
153  return m_rtSpecies;
154 }
155 
156 inline int
158 {
159  return m_plasmaSpecies.size();
160 }
161 
162 inline int
164 {
165  return m_rtSpecies.size();
166 }
167 
168 inline Real
169 ItoPlasmaPhysics::initialSigma(const Real a_time, const RealVect a_pos) const
170 {
171  return 0.0;
172 }
173 
174 inline void
175 ItoPlasmaPhysics::advanceKMC(Vector<FPR>& a_numParticles,
176  Vector<FPR>& a_numNewPhotons,
177  const Real a_dt,
178  const RealVect a_E,
179  const Real a_dx,
180  const Real a_kappa) const
181 {
182  CH_TIME("ItoPlasmaPhysics::advanceKMC");
183 
184  // Populate the KMC solver state.
185  std::vector<FPR>& kmcParticles = m_kmcState.getReactiveState();
186  std::vector<FPR>& kmcPhotons = m_kmcState.getNonReactiveState();
187 
188  for (size_t i = 0; i < a_numParticles.size(); i++) {
189  kmcParticles[i] = a_numParticles[i];
190  }
191 
192  for (auto& p : kmcPhotons) {
193  p = 0LL;
194  }
195 
196  // Update the reaction rates and run the KMC solver.
197  this->updateReactionRates(a_E, a_dx, a_kappa);
198 
199  // // Which algorithm?
200  if (m_algorithm == Algorithm::SSA) {
202  }
203  else if (m_algorithm == Algorithm::Tau) {
205  }
206  else if (m_algorithm == Algorithm::Hybrid) {
208  }
209 
210  // Put KMC back into ItoPlasma
211  for (size_t i = 0; i < a_numParticles.size(); i++) {
212  a_numParticles[i] = (FPR)kmcParticles[i];
213  }
214  for (size_t i = 0; i < a_numNewPhotons.size(); i++) {
215  a_numNewPhotons[i] = (FPR)kmcPhotons[i];
216  }
217 }
218 
219 inline void
220 ItoPlasmaPhysics::reconcileParticles(Vector<List<ItoParticle>*>& a_particles,
221  const Vector<FPR>& a_newNumParticles,
222  const Vector<FPR>& a_oldNumParticles,
223  const RealVect a_cellPos,
224  const RealVect a_centroidPos,
225  const RealVect a_lo,
226  const RealVect a_hi,
227  const RealVect a_bndryCentroid,
228  const RealVect a_bndryNormal,
229  const Real a_dx,
230  const Real a_kappa) const noexcept
231 {
232  CH_TIME("ItoPlasmaPhysics::reconcileParticles(Vector<List<ItoParticle>*>, ...)");
233 
234  CH_assert(a_particles.size() == a_newNumParticles.size());
235  CH_assert(a_oldNumParticles.size() == a_newNumParticles.size());
236 
237  if (m_debug) {
238  for (int i = 0; i < a_particles.size(); i++) {
239  const FPR& numNew = a_newNumParticles[i];
240  const FPR& numOld = a_oldNumParticles[i];
241 
242  if (numNew < (FPR)0) {
243  MayDay::Warning("ItoPlasmaPhysics::reconcileParticles - new number of particles is < 0 (overflow issue?)");
244  }
245  else if ((long long)numNew < 0LL) {
246  MayDay::Warning("ItoPlasmaPhysics::reconcileParticles - integer overflow!");
247  }
248 
249  if (numOld < 0) {
250  MayDay::Warning("ItoPlasmaPhysics::reconcileParticles - old number of particles is < 0");
251  }
252  else if ((long long)numOld < 0LL) {
253  MayDay::Warning("ItoPlasmaPhysics::reconcileParticles - integer overflow for old particles!");
254  }
255  }
256  }
257 
258  for (int i = 0; i < a_particles.size(); i++) {
259  const long long diff = (long long)(a_newNumParticles[i] - a_oldNumParticles[i]);
260 
261  if (diff > 0LL) {
262  // Adding particles, which is fairly simple. Just choose weights for the particles and go.
263  const std::vector<long long> particleWeights =
264  ParticleManagement::partitionParticleWeights(diff, (long long)m_maxNewParticles);
265 
266  for (const auto& w : particleWeights) {
267  RealVect x = RealVect::Zero;
268 
269  // Figure out where to place the particles.
270  switch (m_particlePlacement) {
271  case ParticlePlacement::Random: {
272  x = Random::randomPosition(a_cellPos, a_lo, a_hi, a_bndryCentroid, a_bndryNormal, a_dx, a_kappa);
273 
274  break;
275  }
276  case ParticlePlacement::Centroid: {
277  x = a_cellPos + a_centroidPos * a_dx;
278 
279  break;
280  }
281  default: {
282  MayDay::Error("ItoPlasmaPhysics::reconcileParticles - logic bust");
283 
284  break;
285  }
286  }
287 
288  a_particles[i]->add(ItoParticle(1.0 * w, x));
289  }
290  }
291  else if (diff < 0LL) {
292  // Removing particles is a bit more difficult because we need to manipulate weights.
293  this->removeParticles(*a_particles[i], -diff);
294  }
295  }
296 }
297 
298 inline void
299 ItoPlasmaPhysics::removeParticles(List<ItoParticle>& a_particles, const long long a_numParticlesToRemove) const
300 {
301  CH_TIME("ItoPlasmaPhysics::removeParticles");
302 
303  constexpr long long zero = 0LL;
304 
305  CH_assert(a_numParticlesToRemove >= zero);
306 
307  // Quick lambda for getting total particle weight. Used for debugging.
308  auto getTotalWeight = [&]() -> long long {
309  long long W = zero;
310 
311  for (ListIterator<ItoParticle> lit(a_particles); lit.ok(); ++lit) {
312  W += (long long)lit().weight();
313 
314  if (lit().weight() < 1.0) {
315  MayDay::Error("ItoPlasmaPhysics::removeParticles -- bad particle mass!");
316  }
317  }
318 
319  return W;
320  };
321 
322  if (a_numParticlesToRemove > zero) {
323 
324  // For debugging only.
325  long long totalWeightBefore = 0;
326  long long totalWeightAfter = 0;
327 
328  // Debug hook, compute the total particle weight before we start removing weights.
329  if (m_debug) {
330  totalWeightBefore = getTotalWeight();
331 
332  if (totalWeightBefore < a_numParticlesToRemove) {
333  MayDay::Error("ItoPlasmaPhysics::removeParticles: logic bust (trying to remove too many particles)");
334  }
335  }
336 
337  // Remove physical particles.
338  ParticleManagement::removePhysicalParticles(a_particles, a_numParticlesToRemove);
339 
340  // Remove particles with too low weight.
341  ParticleManagement::deleteParticles(a_particles, std::numeric_limits<Real>::min());
342 
343  // Debug hook, make sure that particle weights are > 0 AND we've removed the desired
344  // particle weight.
345  if (m_debug) {
346  totalWeightAfter = getTotalWeight();
347 
348  const long long errDiff = std::abs(totalWeightBefore - totalWeightAfter) - a_numParticlesToRemove;
349  if (std::abs(errDiff) != zero) {
350 
351  pout() << "ItoPlasmaPhysics::removeParticles: Total weight before = " << totalWeightBefore << endl;
352  pout() << "ItoPlasmaPhysics::removeParticles: Total weight after = " << totalWeightAfter << endl;
353  pout() << "ItoPlasmaPhysics::removeParticles: Should have removed = " << a_numParticlesToRemove << endl;
354  pout() << "ItoPlasmaPhysics::removeParticles: Error = " << errDiff << endl;
355 
356  MayDay::Abort("ItoPlasmaPhysics::removeParticles - incorrect mass removed");
357  }
358  }
359  }
360 }
361 
362 inline void
363 ItoPlasmaPhysics::reconcilePhotons(Vector<List<Photon>*>& a_newPhotons,
364  const Vector<FPR>& a_numNewPhotons,
365  const RealVect a_cellPos,
366  const RealVect a_centroidPos,
367  const RealVect a_lo,
368  const RealVect a_hi,
369  const RealVect a_bndryCentroid,
370  const RealVect a_bndryNormal,
371  const Real a_dx,
372  const Real a_kappa) const noexcept
373 {
374  CH_TIME("ItoPlasmaPhysics::reconcilePhotons");
375 
376  for (int i = 0; i < a_newPhotons.size(); i++) {
377  if (a_numNewPhotons[i] > 0LL) {
378 
379  const std::vector<long long> photonWeights =
380  ParticleManagement::partitionParticleWeights((long long)a_numNewPhotons[i], (long long)m_maxNewPhotons);
381 
382  for (const auto& w : photonWeights) {
383  const RealVect x = Random::randomPosition(a_cellPos, a_lo, a_hi, a_bndryCentroid, a_bndryNormal, a_dx, a_kappa);
384  const RealVect v = Units::c * Random::getDirection();
385 
386  a_newPhotons[i]->add(Photon(x, v, m_rtSpecies[i]->getAbsorptionCoefficient(x), 1.0 * w));
387  }
388  }
389  }
390 }
391 
392 inline void
393 ItoPlasmaPhysics::reconcilePhotoionization(Vector<List<ItoParticle>*>& a_particles,
394  const Vector<List<Photon>*>& a_absorbedPhotons) const noexcept
395 {
396  CH_TIME("ItoPlasmaPhysics::reconcilePhotoionization");
397 
398  for (const auto& r : m_photoReactions) {
399 
400  // Source and targets
401  const size_t& src = r->getSourcePhoton();
402  const std::list<size_t>& targets = r->getTargetSpecies();
403 
404  for (ListIterator<Photon> lit(*a_absorbedPhotons[src]); lit.ok(); ++lit) {
405  const RealVect x = lit().position();
406  const Real w = lit().weight();
407 
408  for (const auto& t : targets) {
409  a_particles[t]->add(ItoParticle(w, x));
410  }
411  }
412  }
413 }
414 
415 #include <CD_NamespaceFooter.H>
416 
417 #endif
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_ItoPlasmaPhysics.H:41
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 advanceTau(State &a_state, const Real a_dt) const noexcept
Advance with 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 noexcept
Advance using Cao et. al. hybrid algorithm over the input time. This can end up using substepping.
Definition: CD_KMCSolverImplem.H:512
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:473
Particle class for usage with Monte Carlo radiative transfer.
Definition: CD_Photon.H:29
const Vector< RefCountedPtr< ItoSpecies > > & getItoSpecies() const
Get all particle species.
Definition: CD_ItoPlasmaPhysicsImplem.H:145
void defineKMC() noexcept
Define the KMC solver and state.
Definition: CD_ItoPlasmaPhysicsImplem.H:69
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_ItoPlasmaPhysicsImplem.H:61
KMCSolverType m_kmcSolver
Kinetic Monte Carlo solver.
Definition: CD_ItoPlasmaPhysics.H:324
std::string m_className
Class name. Used for options parsing.
Definition: CD_ItoPlasmaPhysics.H:309
void parseDebug() noexcept
Parse the maximum number of particles generated per cell.
Definition: CD_ItoPlasmaPhysicsImplem.H:106
Real m_eps
Solver setting for the Cao et. al. algorithm.
Definition: CD_ItoPlasmaPhysics.H:378
bool m_debug
Turn on/off debugging.
Definition: CD_ItoPlasmaPhysics.H:314
void removeParticles(List< ItoParticle > &a_particles, const long long a_numToRemove) const
Remove particles from the input list.
Definition: CD_ItoPlasmaPhysicsImplem.H:299
std::vector< std::shared_ptr< const KMCReaction > > m_kmcReactions
List of reactions for the KMC solver.
Definition: CD_ItoPlasmaPhysics.H:329
KMCState m_kmcState
Kinetic Monte Carlo state.
Definition: CD_ItoPlasmaPhysics.H:319
int getNumPlasmaSpecies() const
Return number of ion equations.
Definition: CD_ItoPlasmaPhysicsImplem.H:157
virtual ~ItoPlasmaPhysics()
Destructor. Does nothing.
Definition: CD_ItoPlasmaPhysicsImplem.H:58
ParticlePlacement m_particlePlacement
Particle placement algorithm.
Definition: CD_ItoPlasmaPhysics.H:304
const Vector< RefCountedPtr< RtSpecies > > & getRtSpecies() const
Get all photon species.
Definition: CD_ItoPlasmaPhysicsImplem.H:151
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_ItoPlasmaPhysicsImplem.H:220
virtual void updateReactionRates(const RealVect a_E, const Real a_dx, const Real a_kappa) const noexcept=0
Update reaction rates.
void parsePPC() noexcept
Parse the maximum number of particles generated per cell.
Definition: CD_ItoPlasmaPhysicsImplem.H:95
int m_maxNewParticles
Maximum new number of particles generated by the chemistry advance.
Definition: CD_ItoPlasmaPhysics.H:349
Vector< RefCountedPtr< ItoSpecies > > m_plasmaSpecies
List of solver-tracked particle species.
Definition: CD_ItoPlasmaPhysics.H:339
Algorithm m_algorithm
Algorithm to use for KMC advance.
Definition: CD_ItoPlasmaPhysics.H:299
void parseAlgorithm() noexcept
Parse reaction algorithm.
Definition: CD_ItoPlasmaPhysicsImplem.H:116
virtual void parseRuntimeOptions() noexcept
Parse run-time options.
Definition: CD_ItoPlasmaPhysicsImplem.H:82
ItoPlasmaPhysics()
Constructor. Does nothing.
Definition: CD_ItoPlasmaPhysicsImplem.H:27
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_ItoPlasmaPhysicsImplem.H:363
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_ItoPlasmaPhysicsImplem.H:169
void advanceKMC(Vector< FPR > &a_numParticles, Vector< FPR > &a_numNewPhotons, const Real a_dt, const RealVect a_E, const Real a_dx, const Real a_kappa) const
Advance particles.
Definition: CD_ItoPlasmaPhysicsImplem.H:175
Vector< RefCountedPtr< RtSpecies > > m_rtSpecies
List of solver-tracked photon species.
Definition: CD_ItoPlasmaPhysics.H:344
int getNumPhotonSpecies() const
Return number of RTE equations.
Definition: CD_ItoPlasmaPhysicsImplem.H:163
int m_Ncrit
Solver setting for the Cao et. al algorithm.
Definition: CD_ItoPlasmaPhysics.H:360
void reconcilePhotoionization(Vector< List< ItoParticle > * > &a_particles, const Vector< List< Photon > * > &a_absorbedPhotons) const noexcept
Reconcile photoionization reactions.
Definition: CD_ItoPlasmaPhysicsImplem.H:393
int m_NSSA
Solver setting for the Cao et. al algorithm.
Definition: CD_ItoPlasmaPhysics.H:366
int m_maxNewPhotons
Maximum new number of photons generated by the chemistry advance.
Definition: CD_ItoPlasmaPhysics.H:354
std::vector< std::shared_ptr< const ItoPlasmaPhotoReaction > > m_photoReactions
List of photoionization reactions.
Definition: CD_ItoPlasmaPhysics.H:334
Real m_SSAlim
Solver setting for the Cao et. al. algorithm.
Definition: CD_ItoPlasmaPhysics.H:372
static RealVect getDirection()
Get a random direction in space.
Definition: CD_RandomImplem.H:157
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:247
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:142
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:54
constexpr Real c
Speed of light.
Definition: CD_Units.H:36