Cantera  4.0.0a1
Loading...
Searching...
No Matches
PlasmaPhase.cpp
Go to the documentation of this file.
1//! @file PlasmaPhase.cpp
2
3// This file is part of Cantera. See License.txt in the top-level directory or
4// at https://cantera.org/license.txt for license and copyright information.
5
8#include <boost/math/special_functions/gamma.hpp>
10#include "cantera/base/global.h"
11#include "cantera/numerics/eigen_dense.h"
15#include <boost/polymorphic_pointer_cast.hpp>
17
18namespace Cantera {
19
20namespace {
21 const double gamma = sqrt(2 * ElectronCharge / ElectronMass);
22}
23
24PlasmaPhase::PlasmaPhase(const string& inputFile, const string& id_)
25{
26 initThermoFile(inputFile, id_);
27
28 // initial electron temperature
30
31 // Initialize the Boltzmann Solver
32 m_eedfSolver = make_unique<EEDFTwoTermApproximation>(this);
33
34 // Set Energy Grid (Hardcoded Defaults for Now)
35 double kTe_max = 60;
36 size_t nGridCells = 301;
37 m_nPoints = nGridCells + 1;
38 m_eedfSolver->setLinearGrid(kTe_max, nGridCells);
39 m_electronEnergyLevels = MappedVector(m_eedfSolver->getGridEdge().data(), m_nPoints);
41}
42
43PlasmaPhase::~PlasmaPhase()
44{
45 if (shared_ptr<Solution> soln = m_soln.lock()) {
46 soln->removeChangedCallback(this);
47 soln->kinetics()->removeReactionAddedCallback(this);
48 }
49 for (size_t k = 0; k < nCollisions(); k++) {
50 // remove callback
51 m_collisions[k]->removeSetRateCallback(this);
52 }
53}
54
56{
57 if (m_distributionType == "discretized") {
58 throw CanteraError("PlasmaPhase::updateElectronEnergyDistribution",
59 "Invalid for discretized electron energy distribution.");
60 } else if (m_distributionType == "isotropic") {
62 } else if (m_distributionType == "Boltzmann-two-term") {
63 auto ierr = m_eedfSolver->calculateDistributionFunction();
64 if (ierr == 0) {
65 auto y = m_eedfSolver->getEEDFEdge();
66 m_electronEnergyDist = Eigen::Map<const Eigen::ArrayXd>(y.data(), m_nPoints);
67 } else {
68 throw CanteraError("PlasmaPhase::updateElectronEnergyDistribution",
69 "Call to calculateDistributionFunction failed.");
70 }
71 bool validEEDF = (
72 static_cast<size_t>(m_electronEnergyDist.size()) == m_nPoints &&
73 m_electronEnergyDist.allFinite() &&
74 m_electronEnergyDist.maxCoeff() > 0.0 &&
75 m_electronEnergyDist.sum() > 0.0
76 );
77
78 if (validEEDF) {
80 } else {
81 writelog("Skipping Te update: EEDF is empty, non-finite, or unnormalized.\n");
82 }
83 } else {
84 throw CanteraError("PlasmaPhase::updateElectronEnergyDistribution",
85 "Unknown method '{}' for determining EEDF", m_distributionType);
86 }
89}
90
92 Eigen::ArrayXd eps32 = m_electronEnergyLevels.pow(3./2.);
93 double norm = 2./3. * numericalQuadrature(m_quadratureMethod,
95 if (norm < 0.0) {
96 throw CanteraError("PlasmaPhase::normalizeElectronEnergyDistribution",
97 "The norm is negative. This might be caused by bad "
98 "electron energy distribution");
99 }
100 m_electronEnergyDist /= norm;
101}
102
104{
105 if (type == "discretized" ||
106 type == "isotropic" ||
107 type == "Boltzmann-two-term") {
109 } else {
110 throw CanteraError("PlasmaPhase::setElectronEnergyDistributionType",
111 "Unknown type for electron energy distribution.");
112 }
113}
114
116{
118 double x = m_isotropicShapeFactor;
119 double gamma1 = boost::math::tgamma(3.0 / 2.0 / x);
120 double gamma2 = boost::math::tgamma(5.0 / 2.0 / x);
121 double c1 = x * std::pow(gamma2, 1.5) / std::pow(gamma1, 2.5);
122 double c2 = std::pow(gamma2 / gamma1, x);
124 c1 / std::pow(meanElectronEnergy(), 1.5) *
125 (-c2 * (m_electronEnergyLevels /
126 meanElectronEnergy()).pow(x)).exp();
128}
129
131 m_electronTemp = Te;
133}
134
136{
138
139 if (!m_inEquilibrate) {
140 m_inEquilibrate = true;
141 // Remember current Te and lock Te -> T for the duration
144 }
145}
146
148{
149 if (m_inEquilibrate) {
150 // Restore Te to the pre-equilibrate value
152 m_inEquilibrate = false;
153 }
154
156}
157
159 m_electronTemp = 2.0 / 3.0 * energy * ElectronCharge / Boltzmann;
161}
162
163void PlasmaPhase::setElectronEnergyLevels(const double* levels, size_t length)
164{
165 m_nPoints = length;
166 m_electronEnergyLevels = Eigen::Map<const Eigen::ArrayXd>(levels, length);
170}
171
173{
174 m_distNum++;
175}
176
178{
179 m_levelNum++;
180 // Cross sections are interpolated on the energy levels
181 if (m_collisions.size() > 0) {
182 vector<double> energyLevels(m_nPoints);
183 MappedVector(energyLevels.data(), m_nPoints) = m_electronEnergyLevels;
184 for (shared_ptr<Reaction> collision : m_collisions) {
185 const auto& rate = boost::polymorphic_pointer_downcast
187 rate->updateInterpolatedCrossSection(energyLevels);
188 }
189 }
190}
191
193{
194 Eigen::ArrayXd h = m_electronEnergyLevels.tail(m_nPoints - 1) -
196 if (m_electronEnergyLevels[0] < 0.0 || (h <= 0.0).any()) {
197 throw CanteraError("PlasmaPhase::checkElectronEnergyLevels",
198 "Values of electron energy levels need to be positive and "
199 "monotonically increasing.");
200 }
201}
202
204{
205 Eigen::ArrayXd h = m_electronEnergyLevels.tail(m_nPoints - 1) -
207 if ((m_electronEnergyDist < 0.0).any()) {
208 throw CanteraError("PlasmaPhase::checkElectronEnergyDistribution",
209 "Values of electron energy distribution cannot be negative.");
210 }
211 if (m_electronEnergyDist[m_nPoints - 1] > 0.01) {
212 warn_user("PlasmaPhase::checkElectronEnergyDistribution",
213 "The value of the last element of electron energy distribution exceed 0.01. "
214 "This indicates that the value of electron energy level is not high enough "
215 "to contain the isotropic distribution at mean electron energy of "
216 "{} eV", meanElectronEnergy());
217 }
218}
219
221 const double* dist,
222 size_t length)
223{
224 m_distributionType = "discretized";
225 m_nPoints = length;
227 Eigen::Map<const Eigen::ArrayXd>(levels, length);
229 Eigen::Map<const Eigen::ArrayXd>(dist, length);
233 }
239}
240
242{
243 // calculate mean electron energy and electron temperature
244 Eigen::ArrayXd eps52 = m_electronEnergyLevels.pow(5./2.);
245 double epsilon_m = 2.0 / 5.0 * numericalQuadrature(m_quadratureMethod,
246 m_electronEnergyDist, eps52);
247 if (epsilon_m < 0.0 && m_quadratureMethod == "simpson") {
248 // try trapezoidal method
249 epsilon_m = 2.0 / 5.0 * numericalQuadrature(
250 "trapezoidal", m_electronEnergyDist, eps52);
251 }
252
253 if (epsilon_m < 0.0) {
254 throw CanteraError("PlasmaPhase::updateElectronTemperatureFromEnergyDist",
255 "The electron energy distribution produces negative electron temperature.");
256 }
257
258 m_electronTemp = 2.0 / 3.0 * epsilon_m * ElectronCharge / Boltzmann;
259}
260
262 m_isotropicShapeFactor = x;
264}
265
266void PlasmaPhase::getParameters(AnyMap& phaseNode) const
267{
269 AnyMap eedf;
270 eedf["type"] = m_distributionType;
271 vector<double> levels(m_nPoints);
272 Eigen::Map<Eigen::ArrayXd>(levels.data(), m_nPoints) = m_electronEnergyLevels;
273 eedf["energy-levels"] = levels;
274 if (m_distributionType == "isotropic") {
275 eedf["shape-factor"] = m_isotropicShapeFactor;
276 eedf["mean-electron-energy"].setQuantity(meanElectronEnergy(), "eV");
277 } else if (m_distributionType == "discretized") {
278 vector<double> dist(m_nPoints);
279 Eigen::Map<Eigen::ArrayXd>(dist.data(), m_nPoints) = m_electronEnergyDist;
280 eedf["distribution"] = dist;
281 eedf["normalize"] = m_do_normalizeElectronEnergyDist;
282 }
283 phaseNode["electron-energy-distribution"] = std::move(eedf);
284}
285
286void PlasmaPhase::setParameters(const AnyMap& phaseNode, const AnyMap& rootNode)
287{
288 IdealGasPhase::setParameters(phaseNode, rootNode);
289 if (phaseNode.hasKey("electron-energy-distribution")) {
290 const AnyMap eedf = phaseNode["electron-energy-distribution"].as<AnyMap>();
291 m_distributionType = eedf["type"].asString();
292 if (m_distributionType == "isotropic") {
293 if (eedf.hasKey("shape-factor")) {
294 setIsotropicShapeFactor(eedf["shape-factor"].asDouble());
295 } else {
296 throw CanteraError("PlasmaPhase::setParameters",
297 "isotropic type requires shape-factor key.");
298 }
299 if (eedf.hasKey("mean-electron-energy")) {
300 double energy = eedf.convert("mean-electron-energy", "eV");
301 setMeanElectronEnergy(energy);
302 } else {
303 throw CanteraError("PlasmaPhase::setParameters",
304 "isotropic type requires electron-temperature key.");
305 }
306 if (eedf.hasKey("energy-levels")) {
307 auto levels = eedf["energy-levels"].asVector<double>();
308 setElectronEnergyLevels(levels.data(), levels.size());
309 }
311 } else if (m_distributionType == "discretized") {
312 if (!eedf.hasKey("energy-levels")) {
313 throw CanteraError("PlasmaPhase::setParameters",
314 "Cannot find key energy-levels.");
315 }
316 if (!eedf.hasKey("distribution")) {
317 throw CanteraError("PlasmaPhase::setParameters",
318 "Cannot find key distribution.");
319 }
320 if (eedf.hasKey("normalize")) {
321 enableNormalizeElectronEnergyDist(eedf["normalize"].asBool());
322 }
323 auto levels = eedf["energy-levels"].asVector<double>();
324 auto distribution = eedf["distribution"].asVector<double>(levels.size());
325 setDiscretizedElectronEnergyDist(levels.data(), distribution.data(),
326 levels.size());
327 }
328 }
329
330 if (rootNode.hasKey("electron-collisions")) {
331 for (const auto& item : rootNode["electron-collisions"].asVector<AnyMap>()) {
332 auto rate = make_shared<ElectronCollisionPlasmaRate>(item);
333 Composition reactants, products;
334 reactants[item["target"].asString()] = 1;
335 reactants[electronSpeciesName()] = 1;
336 if (item.hasKey("product")) {
337 products[item["product"].asString()] = 1;
338 } else {
339 products[item["target"].asString()] = 1;
340 }
341 products[electronSpeciesName()] = 1;
342 if (rate->kind() == "ionization") {
343 products[electronSpeciesName()] += 1;
344 } else if (rate->kind() == "attachment") {
345 products[electronSpeciesName()] -= 1;
346 }
347 auto R = make_shared<Reaction>(reactants, products, rate);
348 addCollision(R);
349 }
350 }
351}
352
353bool PlasmaPhase::addSpecies(shared_ptr<Species> spec)
354{
355 bool added = IdealGasPhase::addSpecies(spec);
356 size_t k = m_kk - 1;
357
358 if ((spec->name == "e" || spec->name == "Electron") ||
359 (spec->composition.find("E") != spec->composition.end() &&
360 spec->composition.size() == 1 &&
361 spec->composition["E"] == 1)) {
364 } else {
365 throw CanteraError("PlasmaPhase::addSpecies",
366 "Cannot add species, {}. "
367 "Only one electron species is allowed.", spec->name);
368 }
369 }
370 return added;
371}
372
374{
376
377 // Check electron species
379 throw CanteraError("PlasmaPhase::initThermo",
380 "No electron species found.");
381 }
382}
383
384void PlasmaPhase::setSolution(std::weak_ptr<Solution> soln) {
386 // register callback function to be executed
387 // when the thermo or kinetics object changed
388 if (shared_ptr<Solution> soln = m_soln.lock()) {
389 soln->registerChangedCallback(this, [&]() {
391 });
392 }
393}
394
396{
397 if (shared_ptr<Solution> soln = m_soln.lock()) {
398 shared_ptr<Kinetics> kin = soln->kinetics();
399 if (!kin) {
400 return;
401 }
402
403 // add collision from the initial list of reactions. Only add reactions we
404 // haven't seen before
405 set<Reaction*> existing;
406 for (auto& R : m_collisions) {
407 existing.insert(R.get());
408 }
409 for (size_t i = 0; i < kin->nReactions(); i++) {
410 shared_ptr<Reaction> R = kin->reaction(i);
411 if (R->rate()->type() != "electron-collision-plasma"
412 || existing.count(R.get())) {
413 continue;
414 }
415 addCollision(R);
416 }
417
418 // register callback when reaction is added later
419 // Modifying collision reactions is not supported
420 kin->registerReactionAddedCallback(this, [this, kin]() {
421 size_t i = kin->nReactions() - 1;
422 if (kin->reaction(i)->type() == "electron-collision-plasma") {
423 addCollision(kin->reaction(i));
424 }
425 });
426 }
427}
428
429void PlasmaPhase::addCollision(shared_ptr<Reaction> collision)
430{
431 size_t i = nCollisions();
432
433 // setup callback to signal updating the cross-section-related
434 // parameters
435 collision->registerSetRateCallback(this, [this, i, collision]() {
436 m_interp_cs_ready[i] = false;
438 std::dynamic_pointer_cast<ElectronCollisionPlasmaRate>(collision->rate());
439 });
440
441 // Identify target species for electron-collision reactions
442 string target;
443 for (const auto& [name, _] : collision->reactants) {
444 // Reactants are expected to be electrons and the target species
445 if (name != electronSpeciesName()) {
446 m_targetSpeciesIndices.emplace_back(speciesIndex(name, true));
447 target = name;
448 break;
449 }
450 }
451 if (target.empty()) {
452 throw CanteraError("PlasmaPhase::addCollision", "Error identifying target for"
453 " collision with equation '{}'", collision->equation());
454 }
455
456 m_collisions.emplace_back(collision);
457 m_collisionRates.emplace_back(
458 std::dynamic_pointer_cast<ElectronCollisionPlasmaRate>(collision->rate()));
459 m_interp_cs_ready.emplace_back(false);
460
461 // resize parameters
464
465 // Set up data used by Boltzmann solver
466 auto& rate = *m_collisionRates.back();
467 string kind = m_collisionRates.back()->kind();
468
469 if ((kind == "effective" || kind == "elastic")) {
470 for (size_t k = 0; k < m_collisions.size() - 1; k++) {
471 if (m_collisions[k]->reactants == collision->reactants &&
472 (m_collisionRates[k]->kind() == "elastic" ||
473 m_collisionRates[k]->kind() == "effective") && !collision->duplicate)
474 {
475 throw CanteraError("PlasmaPhase::addCollision", "Phase already contains"
476 " an effective/elastic cross section for '{}'.", target);
477 }
478 }
479 m_kElastic.push_back(i);
480 } else {
481 m_kInelastic.push_back(i);
482 }
483
484 m_energyLevels.push_back(rate.energyLevels());
485 m_crossSections.push_back(rate.crossSections());
486 m_eedfSolver->setGridCache();
487}
488
490{
491 if (m_interp_cs_ready[i]) {
492 return false;
493 }
494 vector<double> levels(m_nPoints);
495 Eigen::Map<Eigen::ArrayXd>(levels.data(), m_nPoints) = m_electronEnergyLevels;
496 m_collisionRates[i]->updateInterpolatedCrossSection(levels);
497 m_interp_cs_ready[i] = true;
498 return true;
499}
500
502{
504 // Forward difference for the first point
508
509 // Central difference for the middle points
510 for (size_t i = 1; i < m_nPoints - 1; i++) {
514 (h1 * h1 - h0 * h0) * m_electronEnergyDist[i] -
515 h1 * h1 * m_electronEnergyDist[i-1]) /
516 (h1 * h0) / (h1 + h0);
517 }
518
519 // Backward difference for the last point
525}
526
528{
529 // cache of cross section plus distribution plus energy-level number
530 static const int cacheId = m_cache.getId();
531 CachedScalar last_stateNum = m_cache.getScalar(cacheId);
532
533 // combine the distribution and energy level number
534 int stateNum = m_distNum + m_levelNum;
535
536 vector<bool> interpChanged(m_collisions.size());
537 for (size_t i = 0; i < m_collisions.size(); i++) {
538 interpChanged[i] = updateInterpolatedCrossSection(i);
539 }
540
541 if (last_stateNum.validate(temperature(), stateNum)) {
542 // check each cross section, and only update coefficients that
543 // the interpolated cross sections change
544 for (size_t i = 0; i < m_collisions.size(); i++) {
545 if (interpChanged[i]) {
547 }
548 }
549 } else {
550 // update every coefficient if distribution, temperature,
551 // or energy levels change.
552 for (size_t i = 0; i < m_collisions.size(); i++) {
554 }
555 }
556}
557
559{
560 // @todo exclude attachment collisions
561 size_t k = m_targetSpeciesIndices[i];
562
563 // Map cross sections to Eigen::ArrayXd
564 auto cs_array = Eigen::Map<const Eigen::ArrayXd>(
565 m_collisionRates[i]->crossSectionInterpolated().data(),
566 m_collisionRates[i]->crossSectionInterpolated().size()
567 );
568
569 // Mass ratio calculation
570 double mass_ratio = ElectronMass / molecularWeight(k) * Avogadro;
571
572 // Calculate the rate using Simpson's rule or trapezoidal rule
573 Eigen::ArrayXd f0_plus = m_electronEnergyDist + Boltzmann * temperature() /
575 m_elasticElectronEnergyLossCoefficients[i] = 2.0 * mass_ratio * gamma *
577 m_quadratureMethod, 1.0 / 3.0 * f0_plus.cwiseProduct(cs_array),
578 m_electronEnergyLevels.pow(3.0));
579}
580
582{
583 if (m_electronEnergyDist.size() != m_nPoints
584 || m_electronEnergyDistDiff.size() != m_nPoints) {
585 throw CanteraError("PlasmaPhase::elasticPowerLoss:",
586 "EEDF not initialized");
587 }
588
590 // The elastic power loss includes the contributions from inelastic
591 // collisions (inelastic recoil effects).
592 double rate = 0.0;
593 for (size_t i = 0; i < nCollisions(); i++) {
596 }
597 const double q_elastic = Avogadro * Avogadro * ElectronCharge *
599
600 if (!std::isfinite(q_elastic)) {
601 throw CanteraError("PlasmaPhase::elasticPowerLoss:",
602 "Non-finite elastic power loss");
603 }
604
605 return q_elastic;
606}
607
609{
611 static const int cacheId = m_cache.getId();
612 CachedScalar cached = m_cache.getScalar(cacheId);
613 double tempNow = temperature();
614 double electronTempNow = electronTemperature();
615 size_t k = m_electronSpeciesIndex;
616 // If the electron temperature has changed since the last time these
617 // properties were computed, recompute them.
618 if (cached.state1 != tempNow || cached.state2 != electronTempNow) {
620 &m_cp0_R[k], &m_h0_RT[k], &m_s0_R[k]);
621 cached.state1 = tempNow;
622 cached.state2 = electronTempNow;
623 }
624 // update the species Gibbs functions
625 m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k];
626}
627
629 double value = IdealGasPhase::enthalpy_mole();
630 value += GasConstant * (electronTemperature() - temperature()) *
633 return value;
634}
635
637{
638 m_work.resize(m_kk);
640 double u = 0.0;
641 for (size_t k = 0; k < m_kk; ++k) {
642 u += moleFraction(k) * m_work[k];
643 }
644 return u;
645}
646
648{
649 m_work.resize(m_kk);
651 double s = 0.0;
652 for (size_t k = 0; k < m_kk; ++k) {
653 s += moleFraction(k) * m_work[k];
654 }
655 return s;
656}
657
659{
660 m_work.resize(m_kk);
662 double g = 0.0;
663 for (size_t k = 0; k < m_kk; ++k) {
664 g += moleFraction(k) * m_work[k];
665 }
666 return g;
667}
668
669void PlasmaPhase::getGibbs_ref(double* g) const
670{
673}
674
676{
679}
680
682{
685}
686
688{
690 double logp = log(pressure());
691 double logpe = log(electronPressure());
692 sbar[m_electronSpeciesIndex] += GasConstant * (logp - logpe);
693}
694
696{
697 const vector<double>& _h = enthalpy_RT_ref();
698 for (size_t k = 0; k < m_kk; k++) {
699 ubar[k] = RT() * (_h[k] - 1.0);
700 }
701 size_t k = m_electronSpeciesIndex;
702 ubar[k] = RTe() * (_h[k] - 1.0);
703}
704
705void PlasmaPhase::getChemPotentials(double* mu) const
706{
708 size_t k = m_electronSpeciesIndex;
709 double xx = std::max(SmallNumber, moleFraction(k));
710 mu[k] += (RTe() - RT()) * log(xx);
711}
712
714{
716 size_t k = m_electronSpeciesIndex;
717 muStar[k] -= log(pressure() / refPressure()) * RT();
718 muStar[k] += log(electronPressure() / refPressure()) * RTe();
719}
720
721void PlasmaPhase::getEntropy_R(double* sr) const
722{
723 const vector<double>& _s = entropy_R_ref();
724 copy(_s.begin(), _s.end(), sr);
725 double tmp = log(pressure() / refPressure());
726 for (size_t k = 0; k < m_kk; k++) {
727 if (k != m_electronSpeciesIndex) {
728 sr[k] -= tmp;
729 } else {
730 sr[k] -= log(electronPressure() / refPressure());
731 }
732 }
733}
734
735void PlasmaPhase::getGibbs_RT(double* grt) const
736{
737 const vector<double>& gibbsrt = gibbs_RT_ref();
738 copy(gibbsrt.begin(), gibbsrt.end(), grt);
739 double tmp = log(pressure() / refPressure());
740 for (size_t k = 0; k < m_kk; k++) {
741 if (k != m_electronSpeciesIndex) {
742 grt[k] += tmp;
743 } else {
744 grt[k] += log(electronPressure() / refPressure());
745 }
746 }
747}
748
750{
751 // Only implemented when using the Boltzmann two-term EEDF
752 if (m_distributionType == "Boltzmann-two-term") {
753 return m_eedfSolver->getElectronMobility();
754 } else {
755 throw NotImplementedError("PlasmaPhase::electronMobility",
756 "Electron mobility is only available for 'Boltzmann-two-term' "
757 "electron energy distributions.");
758 }
759}
760
761
763{
764 // sigma = e * n_e * mu_e [S/m]; q_J = sigma * E^2 [W/m^3]
765 const double mu_e = electronMobility(); // m^2 / (V·s)
766 if (mu_e <= 0.0) {
767 return 0.0;
768 }
769 const double ne = concentration(m_electronSpeciesIndex) * Avogadro; // m^-3
770 if (ne <= 0.0) {
771 return 0.0;
772 }
773 const double E = electricField(); // V/m
774 if (E <= 0.0) {
775 return 0.0;
776 }
777 const double sigma = ElectronCharge * ne * mu_e; // S/m
778 return sigma * E * E; // W/m^3
779}
780
782{
783 // Joule heating: sigma * E^2 [W/m^3]
784 const double qJ = jouleHeatingPower();
785 checkFinite(qJ);
786
787 // Elastic + inelastic recoil power loss [W/m^3]
788 double qElastic = elasticPowerLoss();
789 checkFinite(qElastic);
790
791 return qJ + qElastic;
792}
793
794
795}
EEDF Two-Term approximation solver.
Header for plasma reaction rates parameterized by electron collision cross section and electron energ...
Base class for kinetics managers and also contains the kineticsmgr module documentation (see Kinetics...
Header file for class PlasmaPhase.
Declaration for class Cantera::Species.
A map of string keys to values whose type can vary at runtime.
Definition AnyMap.h:431
bool hasKey(const string &key) const
Returns true if the map contains an item named key.
Definition AnyMap.cpp:1477
double convert(const string &key, const string &units) const
Convert the item stored by the given key to the units specified in units.
Definition AnyMap.cpp:1595
Base class for exceptions thrown by Cantera classes.
Electron collision plasma reaction rate type.
void updateInterpolatedCrossSection(const vector< double > &)
Update the value of m_crossSectionsInterpolated [m2].
const vector< double > & entropy_R_ref() const
Returns a reference to the dimensionless reference state Entropy vector.
double enthalpy_mole() const override
Return the Molar enthalpy. Units: J/kmol.
void getPartialMolarEnthalpies(double *hbar) const override
Returns an array of partial molar enthalpies for the species in the mixture.
void getChemPotentials(double *mu) const override
Get the species chemical potentials. Units: J/kmol.
double pressure() const override
Pressure.
vector< double > m_g0_RT
Temporary storage for dimensionless reference state Gibbs energies.
vector< double > m_h0_RT
Temporary storage for dimensionless reference state enthalpies.
void getGibbs_ref(double *g) const override
Returns the vector of the Gibbs function of the reference state at the current temperature of the sol...
void getStandardChemPotentials(double *mu) const override
Get the array of chemical potentials at unit activity for the species at their standard states at the...
const vector< double > & gibbs_RT_ref() const
Returns a reference to the dimensionless reference state Gibbs free energy vector.
void getStandardVolumes_ref(double *vol) const override
Get the molar volumes of the species reference states at the current T and P_ref of the solution.
virtual void updateThermo() const
Update the species reference state thermodynamic functions.
vector< double > m_s0_R
Temporary storage for dimensionless reference state entropies.
vector< double > m_cp0_R
Temporary storage for dimensionless reference state heat capacities.
bool addSpecies(shared_ptr< Species > spec) override
Add a Species to this Phase.
void getPartialMolarEntropies(double *sbar) const override
Returns an array of partial molar entropies of the species in the solution.
const vector< double > & enthalpy_RT_ref() const
Returns a reference to the dimensionless reference state enthalpy vector.
virtual void update_single(size_t k, double T, double *cp_R, double *h_RT, double *s_R) const
Get reference-state properties for a single species.
An error indicating that an unimplemented function has been called.
ValueCache m_cache
Cached for saved calculations within each ThermoPhase.
Definition Phase.h:870
size_t m_kk
Number of species in the phase.
Definition Phase.h:890
size_t speciesIndex(const string &name, bool raise=true) const
Returns the index of a species named 'name' within the Phase object.
Definition Phase.cpp:127
double temperature() const
Temperature (K).
Definition Phase.h:598
virtual double concentration(const size_t k) const
Concentration of species k.
Definition Phase.cpp:501
double moleFraction(size_t k) const
Return the mole fraction of a single species.
Definition Phase.cpp:464
double molecularWeight(size_t k) const
Molecular weight of species k.
Definition Phase.cpp:408
string name() const
Return the name of the phase.
Definition Phase.cpp:20
void checkElectronEnergyDistribution() const
Check the electron energy distribution.
vector< vector< double > > m_energyLevels
Electron energy levels corresponding to the cross section data.
void setCollisions()
Set collisions.
double meanElectronEnergy() const
Mean electron energy [eV].
double m_electronTempEquil
Saved electron temperature during an equilibrium solve.
double enthalpy_mole() const override
Return the Molar enthalpy. Units: J/kmol.
size_t m_nPoints
Number of points of electron energy levels.
void addCollision(shared_ptr< Reaction > collision)
Add a collision and record the target species.
virtual void setSolution(std::weak_ptr< Solution > soln) override
Set the link to the Solution object that owns this ThermoPhase.
void getPartialMolarEnthalpies(double *hbar) const override
Returns an array of partial molar enthalpies for the species in the mixture.
void getChemPotentials(double *mu) const override
Get the species chemical potentials. Units: J/kmol.
void normalizeElectronEnergyDistribution()
Electron energy distribution norm.
void getStandardChemPotentials(double *muStar) const override
Get the array of chemical potentials at unit activity for the species at their standard states at the...
void updateThermo() const override
Update the species reference state thermodynamic functions.
vector< size_t > m_targetSpeciesIndices
The collision-target species indices of m_collisions.
void setElectronTemperature(double Te) override
Set the internally stored electron temperature of the phase (K).
void electronEnergyLevelChanged()
When electron energy level changed, plasma properties such as electron-collision reaction rates need ...
double elasticPowerLoss()
The elastic power loss (J/s/m³)
int m_levelNum
Electron energy level change variable.
bool updateInterpolatedCrossSection(size_t k)
Update interpolated cross section of a collision.
bool m_inEquilibrate
Lock flag (default off)
void electronEnergyDistributionChanged()
When electron energy distribution changed, plasma properties such as electron-collision reaction rate...
void getEntropy_R(double *sr) const override
Get the array of nondimensional Entropy functions for the standard state species at the current T and...
size_t nElectronEnergyLevels() const
Number of electron levels.
void getGibbs_ref(double *g) const override
Returns the vector of the Gibbs function of the reference state at the current temperature of the sol...
size_t nCollisions() const
Number of electron collision cross sections.
void endEquilibrate() override
Hook called at the end of an equilibrium calculation on this phase.
Eigen::ArrayXd m_electronEnergyDist
Normalized electron energy distribution vector [-] Length: m_nPoints.
double electricField() const
Get the applied electric field strength [V/m].
Eigen::ArrayXd m_electronEnergyLevels
electron energy levels [ev]. Length: m_nPoints
void setDiscretizedElectronEnergyDist(const double *levels, const double *distrb, size_t length)
Set discretized electron energy distribution.
double intrinsicHeating() override
Intrinsic volumetric heating rate [W/m³].
double electronMobility() const
The electron mobility (m²/V/s)
void getParameters(AnyMap &phaseNode) const override
Store the parameters of a ThermoPhase object such that an identical one could be reconstructed using ...
string type() const override
String indicating the thermodynamic model implemented.
void checkElectronEnergyLevels() const
Check the electron energy levels.
void initThermo() override
Initialize the ThermoPhase object after all species have been set up.
void updateElasticElectronEnergyLossCoefficients()
Update elastic electron energy loss coefficients.
void updateElectronTemperatureFromEnergyDist()
Update electron temperature (K) From energy distribution.
string m_distributionType
Electron energy distribution type.
void getStandardVolumes_ref(double *vol) const override
Get the molar volumes of the species reference states at the current T and P_ref of the solution.
void updateElectronEnergyDistribution()
Update the electron energy distribution.
vector< double > m_elasticElectronEnergyLossCoefficients
Elastic electron energy loss coefficients (eV m3/s)
string m_quadratureMethod
Numerical quadrature method for electron energy distribution.
PlasmaPhase(const string &inputFile="", const string &id="")
Construct and initialize a PlasmaPhase object directly from an input file.
void beginEquilibrate() override
Hook called at the beginning of an equilibrium calculation on this phase.
double m_electronTemp
Electron temperature [K].
double RTe() const
Return the Gas Constant multiplied by the current electron temperature.
void setElectronEnergyLevels(const double *levels, size_t length)
Set electron energy levels.
void getGibbs_RT(double *grt) const override
Get the nondimensional Gibbs functions for the species in their standard states at the current T and ...
double intEnergy_mole() const override
Return the molar internal energy. Units: J/kmol.
double entropy_mole() const override
Return the molar entropy. Units: J/kmol/K.
bool m_do_normalizeElectronEnergyDist
Flag of normalizing electron energy distribution.
void updateElectronEnergyDistDifference()
Update electron energy distribution difference.
void updateElasticElectronEnergyLossCoefficient(size_t i)
Updates the elastic electron energy loss coefficient for collision index i.
vector< size_t > m_kElastic
Indices of elastic collisions in m_crossSections.
unique_ptr< EEDFTwoTermApproximation > m_eedfSolver
Solver used to calculate the EEDF based on electron collision rates.
void getPartialMolarIntEnergies(double *ubar) const override
Return an array of partial molar internal energies for the species in the mixture.
string electronSpeciesName() const
Electron species name.
void setIsotropicElectronEnergyDistribution()
Set isotropic electron energy distribution.
Eigen::ArrayXd m_electronEnergyDistDiff
ionization degree for the electron-electron collisions (tmp is the previous one)
double gibbs_mole() const override
Return the molar Gibbs free energy. Units: J/kmol.
std::vector< double > m_work
Work array.
bool addSpecies(shared_ptr< Species > spec) override
Add a Species to this Phase.
const shared_ptr< Reaction > collision(size_t i) const
Get the Reaction object associated with electron collision i.
vector< bool > m_interp_cs_ready
The list of whether the interpolated cross sections is ready.
vector< shared_ptr< ElectronCollisionPlasmaRate > > m_collisionRates
The list of shared pointers of collision rates.
vector< shared_ptr< Reaction > > m_collisions
The list of shared pointers of plasma collision reactions.
void setParameters(const AnyMap &phaseNode, const AnyMap &rootNode=AnyMap()) override
Set equation of state parameters from an AnyMap phase description.
void setMeanElectronEnergy(double energy)
Set mean electron energy [eV].
size_t m_electronSpeciesIndex
Index of electron species.
vector< vector< double > > m_crossSections
Cross section data.
void setElectronEnergyDistributionType(const string &type)
Set electron energy distribution type.
void getPartialMolarEntropies(double *sbar) const override
Returns an array of partial molar entropies of the species in the solution.
virtual double electronPressure() const
Electron pressure.
double jouleHeatingPower() const
The joule heating power (W/m³)
vector< size_t > m_kInelastic
Indices of inelastic collisions in m_crossSections.
double electronTemperature() const override
Electron Temperature (K)
void setIsotropicShapeFactor(double x)
Set the shape factor of isotropic electron energy distribution.
void enableNormalizeElectronEnergyDist(bool enable)
Set flag of automatically normalize electron energy distribution Flag: m_do_normalizeElectronEnergyDi...
int m_distNum
Electron energy distribution change variable.
virtual void endEquilibrate()
Hook called at the end of an equilibrium calculation on this phase.
virtual void setParameters(const AnyMap &phaseNode, const AnyMap &rootNode=AnyMap())
Set equation of state parameters from an AnyMap phase description.
virtual void getParameters(AnyMap &phaseNode) const
Store the parameters of a ThermoPhase object such that an identical one could be reconstructed using ...
double RT() const
Return the Gas Constant multiplied by the current temperature.
virtual void setSolution(std::weak_ptr< Solution > soln)
Set the link to the Solution object that owns this ThermoPhase.
virtual void initThermo()
Initialize the ThermoPhase object after all species have been set up.
void initThermoFile(const string &inputFile, const string &id)
Initialize a ThermoPhase object using an input file.
std::weak_ptr< Solution > m_soln
reference to Solution
virtual void beginEquilibrate()
Hook called at the beginning of an equilibrium calculation on this phase.
MultiSpeciesThermo m_spthermo
Pointer to the calculation manager for species reference-state thermodynamic properties.
virtual double refPressure() const
Returns the reference pressure in Pa.
CachedScalar getScalar(int id)
Get a reference to a CachedValue object representing a scalar (double) with the given id.
Definition ValueCache.h:161
int getId()
Get a unique id for a cached value.
Header for a file containing miscellaneous numerical functions.
This file contains definitions for utility functions and text for modules, inputfiles and logging,...
void writelog(const string &fmt, const Args &... args)
Write a formatted message to the screen.
Definition global.h:171
double numericalQuadrature(const string &method, const Eigen::ArrayXd &f, const Eigen::ArrayXd &x)
Numerical integration of a function.
Definition funcs.cpp:116
const double Boltzmann
Boltzmann constant [J/K].
Definition ct_defs.h:86
const double Avogadro
Avogadro's Number [number/kmol].
Definition ct_defs.h:83
const double GasConstant
Universal Gas Constant [J/kmol/K].
Definition ct_defs.h:122
const double ElectronCharge
Elementary charge [C].
Definition ct_defs.h:92
const double ElectronMass
Electron Mass [kg].
Definition ct_defs.h:113
void warn_user(const string &method, const string &msg, const Args &... args)
Print a user warning raised from method as CanteraWarning.
Definition global.h:263
Namespace for the Cantera kernel.
Definition AnyMap.cpp:595
const size_t npos
index returned by functions to indicate "no position"
Definition ct_defs.h:182
void checkFinite(const double tmp)
Check to see that a number is finite (not NaN, +Inf or -Inf)
const double SmallNumber
smallest number to compare to zero.
Definition ct_defs.h:160
map< string, double > Composition
Map from string names to doubles.
Definition ct_defs.h:179
A cached property value and the state at which it was evaluated.
Definition ValueCache.h:33
double state2
Value of the second state variable for the state at which value was evaluated, for example density or...
Definition ValueCache.h:106
bool validate(double state1New)
Check whether the currently cached value is valid based on a single state variable.
Definition ValueCache.h:39
double state1
Value of the first state variable for the state at which value was evaluated, for example temperature...
Definition ValueCache.h:102