17#ifndef CD_DISCHARGEINCEPTIONSTEPPERIMPLEM_H
18#define CD_DISCHARGEINCEPTIONSTEPPERIMPLEM_H
33#include <CD_NamespaceHeader.H>
35using namespace Physics::DischargeInception;
37template <
typename P,
typename F,
typename C>
40 CH_TIME(
"DischargeInceptionStepper::DischargeInceptionStepper");
41 if (m_verbosity > 5) {
42 pout() <<
"DischargeInceptionStepper::DischargeInceptionStepper" << endl;
49 m_mode = Mode::Stationary;
50 m_transportAlgorithm = TransportAlgorithm::ImExCTU;
51 m_timeStepRestriction = TimeStepRestriction::Unknown;
54 m_fullIntegration =
false;
55 m_evaluateTownsend =
false;
56 m_relativeDeltaU = 1 + 0.05;
62 m_rho = [](
const RealVect x) -> Real {
66 m_sigma = [](
const RealVect x) -> Real {
70 m_alpha = [](
const Real E,
const RealVect x) -> Real {
74 m_eta = [](
const Real E,
const RealVect x) -> Real {
78 m_voltageCurve = [](
const Real a_time) -> Real {
82 m_backgroundRate = [](
const Real E,
const RealVect x) -> Real {
86 m_detachmentRate = [](
const Real E,
const RealVect x) -> Real {
90 m_fieldEmission = [](
const Real E,
const RealVect x) -> Real {
94 m_secondaryEmission = [](
const Real E,
const RealVect x) -> Real {
98 m_initialIonDensity = [](
const RealVect x) -> Real {
102 m_ionMobility = [](
const Real E) -> Real {
106 m_ionDiffusion = [](
const Real E) -> Real {
111template <
typename P,
typename F,
typename C>
114 CH_TIME(
"DischargeInceptionStepper::~DischargeInceptionStepper");
115 if (m_verbosity > 5) {
116 pout() <<
"DischargeInceptionStepper::~DischargeInceptionStepper" << endl;
120template <
typename P,
typename F,
typename C>
124 CH_TIME(
"DischargeInceptionStepper::setupSolvers");
125 if (m_verbosity > 5) {
126 pout() <<
"DischargeInceptionStepper::setupSolvers" << endl;
130 auto voltage = [](
const Real a_time) -> Real {
135 m_fieldSolver = RefCountedPtr<FieldSolver>(
new F());
136 m_fieldSolver->setVerbosity(m_verbosity);
137 m_fieldSolver->parseOptions();
138 m_fieldSolver->setAmr(m_amr);
139 m_fieldSolver->setComputationalGeometry(m_computationalGeometry);
140 m_fieldSolver->setVoltage(voltage);
141 m_fieldSolver->setRealm(m_realm);
142 m_fieldSolver->setTime(0, 0.0, 0.0);
146 m_tracerParticleSolver->parseOptions();
147 m_tracerParticleSolver->setAmr(m_amr);
148 m_tracerParticleSolver->setComputationalGeometry(m_computationalGeometry);
149 m_tracerParticleSolver->setRealm(m_realm);
150 m_tracerParticleSolver->setPhase(m_phase);
151 m_tracerParticleSolver->setTime(0, 0.0, 0.0);
152 m_tracerParticleSolver->setName(
"Tracer particle solver");
153 m_tracerParticleSolver->setVolumeScale(
true);
154 m_tracerParticleSolver->setDeposition(DepositionType::NGP);
159 m_ionSolver->parseOptions();
160 m_ionSolver->setPhase(m_phase);
161 m_ionSolver->setAmr(m_amr);
162 m_ionSolver->setComputationalGeometry(m_computationalGeometry);
163 m_ionSolver->setRealm(m_realm);
167 m_ionSolver->setSpecies(
species);
170template <
typename P,
typename F,
typename C>
174 CH_TIME(
"DischargeInceptionStepper::allocate");
176 pout() <<
"DischargeInceptionStepper::allocate" <<
endl;
179 m_fieldSolver->allocate();
180 m_tracerParticleSolver->allocate();
181 m_ionSolver->allocate();
198 case Mode::Stationary: {
215 case Mode::Transient: {
236template <
typename P,
typename F,
typename C>
240 CH_TIME(
"DischargeInceptionStepper::initialData");
242 pout() <<
"DischargeInceptionStepper::initialData" <<
endl;
245 this->solvePoisson();
248template <
typename P,
typename F,
typename C>
252 CH_TIME(
"DischargeInceptionStepper::solvePoisson");
254 pout() <<
"DischargeInceptionStepper::solvePoisson" <<
endl;
258 m_fieldSolver->setRho(m_rho);
259 m_fieldSolver->setSigma(m_sigma);
260 m_fieldSolver->setVoltage([](
const Real&
a_time) {
265 DataOps::copy(m_fieldSolver->getPotential(), m_potentialInho);
266 const bool convergedInho = m_fieldSolver->solve(m_fieldSolver->getPotential(),
267 m_fieldSolver->getRho(),
268 m_fieldSolver->getSigma(),
272 MayDay::Warning(
"DischargeInceptionStepper::solvePoisson -- could not solve the inhomogeneous Poisson equation. ");
275 DataOps::copy(m_potentialInho, m_fieldSolver->getPotential());
276 DataOps::copy(m_electricFieldInho, m_fieldSolver->getElectricField());
285 m_fieldSolver->setVoltage([](
const Real&
a_time) {
289 DataOps::copy(m_fieldSolver->getPotential(), m_potentialHomo);
290 const bool convergedHomo = m_fieldSolver->solve(m_fieldSolver->getPotential(),
291 m_fieldSolver->getRho(),
292 m_fieldSolver->getSigma(),
296 MayDay::Warning(
"DischargeInceptionStepper::solvePoisson -- could not solve the homogeneous Poisson equation. ");
299 DataOps::copy(m_potentialHomo, m_fieldSolver->getPotential());
300 DataOps::copy(m_electricFieldHomo, m_fieldSolver->getElectricField());
324 m_fieldSolver->setRho(m_rho);
325 m_fieldSolver->setSigma(m_sigma);
326 m_fieldSolver->setVoltage(
voltage);
327 m_fieldSolver->solve(m_fieldSolver->getPotential(), m_fieldSolver->getRho(), m_fieldSolver->getSigma(),
false);
330 DataOps::incr(m_potential, m_fieldSolver->getPotential(), -1.0);
340 MayDay::Error(
"DischargeInceptionStepper::solvePoisson - debug test failed. Check your BCs!");
345template <
typename P,
typename F,
typename C>
349 CH_TIME(
"DischargeInceptionStepper::registerRealms");
351 pout() <<
"DischargeInceptionStepper::registerRealms" <<
endl;
357template <
typename P,
typename F,
typename C>
361 CH_TIME(
"DischargeInceptionStepper::registerOperators");
363 pout() <<
"DischargeInceptionStepper::registerOperators" <<
endl;
366 m_fieldSolver->registerOperators();
367 m_tracerParticleSolver->registerOperators();
368 m_ionSolver->registerOperators();
371template <
typename P,
typename F,
typename C>
375 CH_TIME(
"DischargeInceptionStepper::parseOptions");
379 this->parseVoltages();
382 this->parseInceptionAlgorithm();
383 this->parseTransportAlgorithm();
386template <
typename P,
typename F,
typename C>
390 CH_TIME(
"DischargeInceptionStepper::parseRuntimeOptions");
392 pout() <<
"DischargeInceptionStepper::parseRuntimeOptions" <<
endl;
397 this->parseInceptionAlgorithm();
398 this->parseTransportAlgorithm();
401template <
typename P,
typename F,
typename C>
405 CH_TIME(
"DischargeInceptionStepper::parseVerbosity");
407 pout() <<
"DischargeInceptionStepper::parseVerbosity" <<
endl;
412 pp.get(
"profile", m_profile);
413 pp.query(
"debug", m_debug);
416template <
typename P,
typename F,
typename C>
420 CH_TIME(
"DischargeInceptionStepper::parseMode");
422 pout() <<
"DischargeInceptionStepper::parseMode" <<
endl;
430 if (
str ==
"stationary") {
431 m_mode = Mode::Stationary;
433 else if (
str ==
"transient") {
434 m_mode = Mode::Transient;
437 MayDay::Error(
"Expected 'none', 'stationary', or 'transient' for 'DischargeInceptionStepper.mode'");
441template <
typename P,
typename F,
typename C>
445 CH_TIME(
"DischargeInceptionStepper::parseVoltages");
447 pout() <<
"DischargeInceptionStepper::parseVoltages" <<
endl;
452 pp.get(
"rel_step_dU", m_relativeDeltaU);
453 pp.get(
"step_dK", m_deltaK);
454 pp.get(
"limit_max_K", m_maxKLimit);
455 pp.get(
"K_inception", m_inceptionK);
456 pp.get(
"eval_townsend", m_evaluateTownsend);
458 m_relativeDeltaU = 1.0 + m_relativeDeltaU;
461template <
typename P,
typename F,
typename C>
465 CH_TIME(
"DischargeInceptionStepper::parseOutput");
467 pout() <<
"DischargeInceptionStepper::parseOutput" <<
endl;
472 pp.get(
"output_file", m_outputFile);
475template <
typename P,
typename F,
typename C>
479 CH_TIME(
"DischargeInceptionStepper::parseInceptionAlgorithm");
481 pout() <<
"DischargeInceptionStepper::parseInceptionAlgorithm" <<
endl;
489 pp.get(
"full_integration", m_fullIntegration);
490 pp.get(
"inception_alg",
str);
491 if (
str ==
"euler") {
492 m_inceptionAlgorithm = IntegrationAlgorithm::Euler;
494 else if (
str ==
"trapz") {
495 m_inceptionAlgorithm = IntegrationAlgorithm::Trapezoidal;
498 MayDay::Error(
"Expected 'euler' or 'trapz' for 'DischargeInceptionStepper.inception_alg'");
501 pp.get(
"min_phys_dx", m_minPhysDx);
502 pp.get(
"max_phys_dx", m_maxPhysDx);
503 pp.get(
"min_grid_dx", m_minGridDx);
504 pp.get(
"max_grid_dx", m_maxGridDx);
505 pp.get(
"alpha_dx", m_alphaDx);
506 pp.get(
"grad_alpha_dx", m_gradAlphaDx);
507 pp.get(
"townsend_grid_dx", m_townsendGridDx);
509 if (m_minPhysDx <= 0.0) {
510 MayDay::Abort(
"DischargeInceptionStepper.min_phys_dx must be > 0.0");
512 if (m_maxPhysDx <= 0.0) {
513 MayDay::Abort(
"DischargeInceptionStepper.max_phys_dx must be > 0.0");
515 if (m_minGridDx <= 0.0) {
516 MayDay::Abort(
"DischargeInceptionStepper.min_grid_dx must be > 0.0");
518 if (m_maxGridDx <= 0.0) {
519 MayDay::Abort(
"DischargeInceptionStepper.max_grid_dx must be > 0.0");
521 if (m_alphaDx <= 0.0) {
522 MayDay::Abort(
"DischargeInceptionStepper.alpha_dx must be > 0.0");
524 if (m_gradAlphaDx <= 0.0) {
525 MayDay::Abort(
"DischargeInceptionStepper.grad_alpha_dx must be > 0.0");
527 if (m_townsendGridDx <= 0.0) {
528 MayDay::Abort(
"DischargeInceptionStepper.townsend_grid_dx must be > 0.0");
532template <
typename P,
typename F,
typename C>
536 CH_TIME(
"DischargeInceptionStepper::parseTransportAlgorithm");
538 pout() <<
"DischargeInceptionStepper::parseTransportAlgorithm" <<
endl;
545 pp.get(
"transport_alg",
str);
546 pp.get(
"ion_transport", m_ionTransport);
547 pp.get(
"cfl", m_cfl);
548 pp.get(
"first_dt", m_firstDt);
549 pp.get(
"min_dt", m_minDt);
550 pp.get(
"max_dt", m_maxDt);
551 pp.get(
"max_dt_growth", m_maxDtGrowth);
552 pp.get(
"voltage_eps", m_epsVoltage);
558 if (
str ==
"euler") {
559 m_transportAlgorithm = TransportAlgorithm::Euler;
561 else if (
str ==
"heun") {
562 m_transportAlgorithm = TransportAlgorithm::Heun;
564 else if (
str ==
"imex") {
565 m_transportAlgorithm = TransportAlgorithm::ImExCTU;
568 MayDay::Error(
"Expected 'euler', 'heun', or 'imex' for 'DischargeInceptionStepper.transport_alg'");
572template <
typename P,
typename F,
typename C>
576 CH_TIME(
"DischargeInceptionStepper::parsePlotVariables");
578 pout() <<
"DischargeInceptionStepper::parsePlotVariables" <<
endl;
582 m_plotPoisson =
false;
583 m_plotTracer =
false;
584 m_plotNegativeIons =
false;
585 m_plotInceptionIntegral =
false;
586 m_plotInceptionVoltage =
false;
587 m_plotBackgroundIonization =
false;
588 m_plotDetachment =
false;
589 m_plotFieldEmission =
false;
592 m_plotTownsend =
false;
597 const int num =
pp.countval(
"plt_vars");
602 for (
int i = 0;
i <
num;
i++) {
607 m_plotPoisson =
true;
613 m_plotNegativeIons =
true;
616 m_plotInceptionIntegral =
true;
619 m_plotInceptionVoltage =
true;
622 m_plotBackgroundIonization =
true;
625 m_plotDetachment =
true;
628 m_plotFieldEmission =
true;
637 m_plotTownsend =
true;
644template <
typename P,
typename F,
typename C>
648 CH_TIME(
"DischargeInceptionStepper::writeCheckpointData");
650 pout() <<
"DischargeInceptionStepper::writeCheckpointData" <<
endl;
656template <
typename P,
typename F,
typename C>
660 CH_TIME(
"DischargeInceptionStepper::readCheckpointData");
662 pout() <<
"DischargeInceptionStepper::readCheckpointData" <<
endl;
665 MayDay::Error(
"DischargeInceptionStepper::readCheckpointData -- restart not supported. Use Driver.restart=0");
669template <
typename P,
typename F,
typename C>
673 CH_TIME(
"DischargeInceptionStepper::getNumberOfPlotVariables");
675 pout() <<
"DischargeInceptionStepper::getNumberOfPlotVariables" <<
endl;
686 if (m_plotNegativeIons) {
691 case Mode::Stationary: {
695 ncomp += 2 * m_voltageSweeps.size();
698 ncomp += 2 * m_voltageSweeps.size();
708 if (m_plotInceptionIntegral) {
709 ncomp += 2 * m_voltageSweeps.size();
713 if (m_plotInceptionVoltage) {
718 if (m_plotBackgroundIonization) {
719 ncomp += m_voltageSweeps.size();
723 if (m_plotDetachment) {
724 ncomp += m_voltageSweeps.size();
728 if (m_plotFieldEmission) {
729 ncomp += 2 * m_voltageSweeps.size();
734 ncomp += m_voltageSweeps.size();
739 ncomp += m_voltageSweeps.size();
743 if (m_plotAlpha && m_plotEta) {
744 ncomp += m_voltageSweeps.size();
748 if (m_plotTownsend) {
749 ncomp += 2 * m_voltageSweeps.size();
754 case Mode::Transient: {
771 if (m_plotInceptionIntegral) {
774 if (m_plotTownsend) {
777 if (m_plotBackgroundIonization) {
780 if (m_plotDetachment) {
783 if (m_plotFieldEmission) {
792 if (m_plotAlpha && m_plotEta) {
806template <
typename P,
typename F,
typename C>
810 CH_TIME(
"DischargeInceptionStepper::getPlotVariableNames");
812 pout() <<
"DischargeInceptionStepper::getPlotVariableNames" <<
endl;
833 if (m_plotNegativeIons) {
842 case Mode::Stationary: {
843 plotVars.append(this->getStationaryPlotVariableNames());
847 case Mode::Transient: {
848 plotVars.append(this->getTransientPlotVariableNames());
853 MayDay::Error(
"DischargeInceptionStepper::getPlotVariableNames - logic bust");
862template <
typename P,
typename F,
typename C>
866 CH_TIME(
"DischargeInceptionStepper::getStationaryPlotVariableNames");
868 pout() <<
"DischargeInceptionStepper::getStationaryPlotVariableNames" <<
endl;
877 for (
const Real&
V : m_voltageSweeps) {
882 for (
const Real&
V : m_voltageSweeps) {
903 if (m_plotInceptionVoltage) {
912 if (m_plotInceptionIntegral) {
915 for (
const Real&
V : m_voltageSweeps) {
920 for (
const Real&
V : m_voltageSweeps) {
927 if (m_plotTownsend) {
928 for (
size_t i = 0;
i < m_voltageSweeps.size();
i++) {
934 for (
size_t i = 0;
i < m_voltageSweeps.size();
i++) {
942 if (m_plotBackgroundIonization) {
945 for (
const Real&
V : m_voltageSweeps) {
952 if (m_plotDetachment) {
955 for (
const Real&
V : m_voltageSweeps) {
962 if (m_plotFieldEmission) {
965 for (
const Real&
V : m_voltageSweeps) {
970 for (
const Real&
V : m_voltageSweeps) {
978 for (
size_t i = 0;
i < m_voltageSweeps.size();
i++) {
988 for (
size_t i = 0;
i < m_voltageSweeps.size();
i++) {
996 if (m_plotAlpha && m_plotEta) {
997 for (
size_t i = 0;
i < m_voltageSweeps.size();
i++) {
1007template <
typename P,
typename F,
typename C>
1011 CH_TIME(
"DischargeInceptionStepper::getTransientPlotVariableNames");
1013 pout() <<
"DischargeInceptionStepper::getTransientPlotVariableNames" <<
endl;
1020 plotVars.push_back(
"Electric potential");
1029 plotVars.push_back(
"Space charge density");
1030 plotVars.push_back(
"Surface charge density");
1033 if (m_plotInceptionIntegral) {
1034 plotVars.push_back(
"Inception integral");
1037 if (m_plotTownsend) {
1038 plotVars.push_back(
"Townsend criterion");
1041 if (m_plotBackgroundIonization) {
1042 plotVars.push_back(
"Background rate");
1045 if (m_plotDetachment) {
1046 plotVars.push_back(
"Detachment rate");
1049 if (m_plotFieldEmission) {
1050 plotVars.push_back(
"Field emission");
1054 plotVars.push_back(
"Townsend alpha coefficient");
1058 plotVars.push_back(
"Townsend eta coefficient");
1061 if (m_plotAlpha && m_plotEta) {
1062 plotVars.push_back(
"Effective Townsend coefficient");
1072template <
typename P,
typename F,
typename C>
1079 CH_TIME(
"DischargeInceptionStepper::writePlotData");
1081 pout() <<
"DischargeInceptionStepper::writePlotData" <<
endl;
1084 if (m_plotPoisson) {
1092 if (m_plotNegativeIons) {
1098 case Mode::Stationary: {
1103 case Mode::Transient:
1108 MayDay::Error(
"DischargeInceptionStepper::writePlotData - logic bust");
1115template <
typename P,
typename F,
typename C>
1120 const int a_level)
const noexcept
1122 CH_TIME(
"DischargeInceptionStepper::writePlotDataStationary");
1123 if (m_verbosity > 5) {
1124 pout() <<
"DischargeInceptionStepper::writePlotDataStationary" <<
endl;
1136 for (
const auto&
V : m_voltageSweeps) {
1151 for (
const auto&
V : m_voltageSweeps) {
1158 m_amr->getMultiCutVofIterator(m_realm,
phase::gas),
1169 m_amr->getMultiCutVofIterator(m_realm,
phase::gas),
1183 m_amr->arithmeticAverage(
scratch, m_realm);
1184 m_amr->interpGhostPwl(
scratch, m_realm);
1196 if (m_plotInceptionVoltage) {
1207 if (m_plotInceptionIntegral) {
1208 for (
int i = 0;
i < m_voltageSweeps.size();
i++) {
1211 for (
int i = 0;
i < m_voltageSweeps.size();
i++) {
1216 if (m_plotTownsend) {
1217 for (
int i = 0;
i < m_voltageSweeps.size();
i++) {
1221 for (
int i = 0;
i < m_voltageSweeps.size();
i++) {
1226 if (m_plotBackgroundIonization) {
1227 for (
int i = 0;
i < m_voltageSweeps.size();
i++) {
1232 if (m_plotDetachment) {
1233 for (
int i = 0;
i < m_voltageSweeps.size();
i++) {
1238 if (m_plotFieldEmission) {
1239 for (
int i = 0;
i < m_voltageSweeps.size();
i++) {
1242 for (
int i = 0;
i < m_voltageSweeps.size();
i++) {
1256 for (
size_t i = 0;
i < m_voltageSweeps.size();
i++) {
1257 this->evaluateFunction(
alpha, m_voltageSweeps[
i], m_alpha,
a_level);
1281 for (
size_t i = 0;
i < m_voltageSweeps.size();
i++) {
1282 this->evaluateFunction(
eta, m_voltageSweeps[
i], m_eta,
a_level);
1284 this->evaluateFunction(
etaCoar, m_voltageSweeps[
i], m_eta,
a_level - 1);
1297 if (m_plotAlpha && m_plotEta) {
1310 for (
size_t i = 0;
i < m_voltageSweeps.size();
i++) {
1329template <
typename P,
typename F,
typename C>
1334 const int a_level)
const noexcept
1336 CH_TIME(
"DischargeInceptionStepper::writePlotDataTransient");
1337 if (m_verbosity > 5) {
1338 pout() <<
"DischargeInceptionStepper::writePlotDataTransient" <<
endl;
1356 m_amr->getMultiCutVofIterator(m_realm,
phase::gas),
1358 m_amr->arithmeticAverage(
scratch, m_realm);
1359 m_amr->interpGhostPwl(
scratch, m_realm);
1373 m_amr->arithmeticAverage(
scratch, m_realm);
1374 m_amr->interpGhostPwl(
scratch, m_realm);
1386 if (m_plotInceptionIntegral) {
1390 if (m_plotTownsend) {
1394 if (m_plotBackgroundIonization) {
1408 if (m_plotDetachment) {
1417 this->evaluateFunction(
detachRate, m_voltageCurve(m_time), m_detachmentRate,
a_level);
1428 if (m_plotFieldEmission) {
1441 this->evaluateFunction(
alpha, m_voltageCurve(m_time), m_alpha,
a_level);
1443 this->evaluateFunction(
alphaCoar, m_voltageCurve(m_time), m_alpha,
a_level - 1);
1466 this->evaluateFunction(
eta, m_voltageCurve(m_time), m_eta,
a_level);
1468 this->evaluateFunction(
etaCoar, m_voltageCurve(m_time), m_eta,
a_level - 1);
1482 if (m_plotAlpha && m_plotEta) {
1512template <
typename P,
typename F,
typename C>
1516 CH_TIME(
"DischargeInceptionStepper::computeDt");
1518 pout() <<
"DischargeInceptionStepper::computeDt" <<
endl;
1521 Real dt = std::numeric_limits<Real>::max();
1523 if (m_mode == Mode::Transient) {
1526 m_timeStepRestriction = TimeStepRestriction::Unknown;
1529 if (m_ionTransport) {
1530 Real ionDt = std::numeric_limits<Real>::infinity();
1531 switch (m_transportAlgorithm) {
1532 case TransportAlgorithm::Euler: {
1533 ionDt = m_cfl * m_ionSolver->computeAdvectionDiffusionDt();
1537 case TransportAlgorithm::Heun: {
1538 ionDt = m_cfl * m_ionSolver->computeAdvectionDiffusionDt();
1542 case TransportAlgorithm::ImExCTU: {
1543 ionDt = m_cfl * m_ionSolver->computeAdvectionDt();
1548 MayDay::Error(
"DischargeInceptionStepper::computDt -- logic bust");
1556 m_timeStepRestriction = TimeStepRestriction::CDR;
1570 if (
dVdt > std::numeric_limits<Real>::epsilon()) {
1581 m_timeStepRestriction = TimeStepRestriction::VoltageCurve;
1587 m_timeStepRestriction = TimeStepRestriction::MaxHardcap;
1592 m_timeStepRestriction = TimeStepRestriction::MinHardcap;
1599template <
typename P,
typename F,
typename C>
1603 CH_TIME(
"DischargeInceptionStepper::advance");
1605 pout() <<
"DischargeInceptionStepper::advance" <<
endl;
1608 if (m_mode == Mode::Transient) {
1609 Timer timer(
"DischargeInceptionStepper::advance");
1630 timer.startEvent(
"Ion advance");
1631 if (m_ionTransport) {
1634 this->advanceIons(
a_dt);
1636 timer.stopEvent(
"Ion advance");
1639 timer.startEvent(
"Inception integral");
1641 this->computeInceptionIntegralTransient(
curVoltage);
1642 timer.stopEvent(
"Inception integral");
1644 if (m_evaluateTownsend) {
1645 timer.startEvent(
"Townsend criterion");
1647 this->computeTownsendCriterionTransient(
curVoltage);
1648 timer.stopEvent(
"Townsend criterion");
1652 timer.startEvent(
"Compute Vcr");
1653 const Real Vcr = this->computeCriticalVolumeTransient();
1654 const Real Acr = this->computeCriticalAreaTransient();
1657 timer.stopEvent(
"Compute Vcr");
1661 m_ionizationVolumeTransient.emplace_back(
curTime,
Vion);
1665 if (m_Rdot.size() >= 2) {
1668 for (
size_t i = 0;
i < m_Rdot.size() - 1;
i++) {
1669 const Real dt = m_Rdot[
i + 1].first - m_Rdot[
i].first;
1671 p += 0.5 *
dt * (m_Rdot[
i + 1].second + m_Rdot[
i].second);
1674 m_inceptionProbability.emplace_back(
curTime, 1.0 -
exp(-p));
1678 timer.startEvent(
"Get max/min K");
1679 Real maxK = -std::numeric_limits<Real>::max();
1680 Real minK = +std::numeric_limits<Real>::max();
1682 Real maxT = -std::numeric_limits<Real>::max();
1683 Real minT = +std::numeric_limits<Real>::max();
1688 if (!m_fullIntegration) {
1689 maxK = std::min(
maxK, m_inceptionK);
1694 timer.stopEvent(
"Get max/min K");
1696 timer.startEvent(
"Write report");
1697 this->writeReportTransient();
1698 timer.stopEvent(
"Write report");
1705 MayDay::Error(
"DischargeInceptionStepper::advance -- must have 'DischargeInceptionStepper.mode = transient'");
1711template <
typename P,
typename F,
typename C>
1715 CH_TIME(
"DischargeInceptionStepper::advanceIons");
1716 if (m_verbosity > 5) {
1717 pout() <<
"DischargeInceptionStepper::advanceIons" <<
endl;
1726 m_ionSolver->extrapolateAdvectiveFluxToEB(
ebFlux);
1729 switch (m_transportAlgorithm) {
1730 case TransportAlgorithm::Euler: {
1734 m_ionSolver->computeDivJ(
divJ,
phi, 0.0,
false,
true,
false);
1740 case TransportAlgorithm::Heun: {
1751 m_ionSolver->computeDivJ(
k1,
phi, 0.0,
false,
true,
false);
1756 m_ionSolver->computeDivJ(
k2,
yp, 0.0,
false,
true,
false);
1762 case TransportAlgorithm::ImExCTU: {
1773 m_ionSolver->computeDivF(
k1,
phi,
a_dt,
false,
true,
true);
1782 m_ionSolver->advanceCrankNicholson(
phi,
k2,
k1,
a_dt);
1787 MayDay::Error(
"DischargeInceptionStepper::advanceIons -- logic bust");
1793 m_amr->average(
phi, m_realm, m_phase, Average::Conservative);
1794 m_amr->interpGhost(
phi, m_realm, m_phase);
1797template <
typename P,
typename F,
typename C>
1801 CH_TIME(
"DischargeInceptionStepper::synchronizeSolverTimes");
1803 pout() <<
"DischargeInceptionStepper::synchronizeSolverTimes" <<
endl;
1815template <
typename P,
typename F,
typename C>
1819 CH_TIME(
"DischargeInceptionStepper::printStepReport");
1822 pout() <<
"DischargeInceptionStepper::printStepReport" <<
endl;
1827 switch (m_timeStepRestriction) {
1828 case TimeStepRestriction::Unknown: {
1833 case TimeStepRestriction::CDR: {
1838 case TimeStepRestriction::VoltageCurve: {
1843 case TimeStepRestriction::MinHardcap: {
1848 case TimeStepRestriction::MaxHardcap: {
1854 MayDay::Warning(
"DischargeInceptionStepper::printStepReport - logic bust");
1862 pout() <<
" ** Crit. volume = " << m_criticalVolume.back().second <<
endl;
1863 pout() <<
" ** Inception probability = " << m_inceptionProbability.back().second <<
endl;
1868template <
typename P,
typename F,
typename C>
1872 CH_TIME(
"DischargeInceptionStepper::preRegrid");
1874 pout() <<
"DischargeInceptionStepper::preRegrid" <<
endl;
1884 m_amr->copyData(m_scratchHomo, m_potentialHomo);
1885 m_amr->copyData(m_scratchInho, m_potentialInho);
1888template <
typename P,
typename F,
typename C>
1892 CH_TIME(
"DischargeInceptionStepper::regrid");
1894 pout() <<
"DischargeInceptionStepper::regrid" <<
endl;
1919 case Mode::Stationary: {
1929 case Mode::Transient: {
1944 this->solvePoisson();
1947 this->computeIonVelocity(m_voltageCurve(
m_time));
1948 this->computeIonDiffusion(m_voltageCurve(
m_time));
1951template <
typename P,
typename F,
typename C>
1955 CH_TIME(
"DischargeInceptionStepper::postRegrid");
1957 pout() <<
"DischargeInceptionStepper::postRegrid" <<
endl;
1960 m_scratchHomo.clear();
1961 m_scratchInho.clear();
1964template <
typename P,
typename F,
typename C>
1968 CH_TIME(
"DischargeInceptionStepper::setVoltageCurve");
1969 if (m_verbosity > 5) {
1970 pout() <<
"DischargeInceptionStepper::setVoltageCurve" <<
endl;
1976template <
typename P,
typename F,
typename C>
1980 CH_TIME(
"DischargeInceptionStepper::setRho");
1981 if (m_verbosity > 5) {
1982 pout() <<
"DischargeInceptionStepper::setRho" <<
endl;
1988template <
typename P,
typename F,
typename C>
1992 CH_TIME(
"DischargeInceptionStepper::setSigma");
1993 if (m_verbosity > 5) {
1994 pout() <<
"DischargeInceptionStepper::setSigma" <<
endl;
2000template <
typename P,
typename F,
typename C>
2004 CH_TIME(
"DischargeInceptionStepper::setIonDensity");
2005 if (m_verbosity > 5) {
2006 pout() <<
"DischargeInceptionStepper::setIonDensity" <<
endl;
2012template <
typename P,
typename F,
typename C>
2016 CH_TIME(
"DischargeInceptionStepper::setIonMobility");
2017 if (m_verbosity > 5) {
2018 pout() <<
"DischargeInceptionStepper::setIonMobility" <<
endl;
2024template <
typename P,
typename F,
typename C>
2028 CH_TIME(
"DischargeInceptionStepper::setIonDiffusion");
2029 if (m_verbosity > 5) {
2030 pout() <<
"DischargeInceptionStepper::setIonDiffusion" <<
endl;
2036template <
typename P,
typename F,
typename C>
2041 CH_TIME(
"DischargeInceptionStepper::setAlpha");
2042 if (m_verbosity > 5) {
2043 pout() <<
"DischargeInceptionStepper::setAlpha" <<
endl;
2049template <
typename P,
typename F,
typename C>
2053 CH_TIME(
"DischargeInceptionStepper::setEta");
2054 if (m_verbosity > 5) {
2055 pout() <<
"DischargeInceptionStepper::setEta" <<
endl;
2061template <
typename P,
typename F,
typename C>
2068template <
typename P,
typename F,
typename C>
2075template <
typename P,
typename F,
typename C>
2080 CH_TIME(
"DischargeInceptionStepper::setBackgroundRate");
2081 if (m_verbosity > 5) {
2082 pout() <<
"DischargeInceptionStepper::setBackgroundRate" <<
endl;
2088template <
typename P,
typename F,
typename C>
2093 CH_TIME(
"DischargeInceptionStepper::setDetachmentRate");
2094 if (m_verbosity > 5) {
2095 pout() <<
"DischargeInceptionStepper::setDetachmentRate" <<
endl;
2101template <
typename P,
typename F,
typename C>
2106 CH_TIME(
"DischargeInceptionStepper::setFieldEmission");
2107 if (m_verbosity > 5) {
2108 pout() <<
"DischargeInceptionStepper::setFieldEmission" <<
endl;
2114template <
typename P,
typename F,
typename C>
2119 CH_TIME(
"DischargeInceptionStepper::setSecondaryEmission");
2120 if (m_verbosity > 5) {
2121 pout() <<
"DischargeInceptionStepper::setSecondaryEmission" <<
endl;
2127template <
typename P,
typename F,
typename C>
2134template <
typename P,
typename F,
typename C>
2138 CH_TIME(
"DischargeInceptionStepper::seedUniformParticles");
2140 pout() <<
"DischargeInceptionStepper::seedUniformParticles" <<
endl;
2159#pragma omp parallel for schedule(runtime)
2201 p.template
vect<0>() = p.position();
2212template <
typename P,
typename F,
typename C>
2216 CH_TIME(
"DischargeInceptionStepper::seedIonizationParticles");
2217 if (m_verbosity > 5) {
2218 pout() <<
"DischargeInceptionStepper::seedIonizationParticles" <<
endl;
2235 for (
int lvl = 0;
lvl <= m_amr->getFinestLevel();
lvl++) {
2249#pragma omp parallel for schedule(runtime)
2264 if (!
ebisbox.isAllCovered()) {
2273 const Real E =
EE.vectorLength();
2295 const Real E =
EE.vectorLength();
2325 p.template
vect<0>() = p.position();
2332 m_amr->arithmeticAverage(
alphaMesh, m_realm, m_phase);
2333 m_amr->interpGhost(
alphaMesh, m_realm, m_phase);
2336 m_amr->computeGradient(m_gradAlpha,
alphaMesh, m_realm, m_phase);
2339 m_amr->arithmeticAverage(m_gradAlpha, m_realm, m_phase);
2340 m_amr->interpGhost(m_gradAlpha, m_realm, m_phase);
2341 m_amr->interpToCentroids(m_gradAlpha, m_realm, m_phase);
2344template <
typename P,
typename F,
typename C>
2348 CH_TIME(
"DischargeInceptionStepper::postInitialize");
2350 pout() <<
"DischargeInceptionStepper::postInitialize" <<
endl;
2354 m_ionSolver->initialData();
2355 this->computeIonVelocity(m_voltageCurve(
m_time));
2356 this->computeIonDiffusion(m_voltageCurve(
m_time));
2359 case Mode::Stationary: {
2360 this->computeInceptionIntegralStationary();
2361 this->computeTownsendCriterionStationary();
2362 this->computeCriticalVolumeStationary();
2363 this->computeCriticalAreaStationary();
2364 this->computeIonizationVolumeStationary();
2365 this->computeInceptionVoltageVolume();
2368 if (m_plotBackgroundIonization) {
2369 this->computeBackgroundIonizationStationary();
2372 if (m_plotDetachment) {
2373 this->computeDetachmentStationary();
2376 if (m_plotFieldEmission) {
2377 this->computeFieldEmissionStationary();
2380 this->writeReportStationary();
2384 case Mode::Transient: {
2387 this->seedIonizationParticles(m_voltageCurve(
m_time));
2388 this->computeInceptionIntegralTransient(m_voltageCurve(
m_time));
2391 if (m_evaluateTownsend) {
2392 this->seedIonizationParticles(m_voltageCurve(
m_time));
2393 this->computeTownsendCriterionTransient(m_voltageCurve(
m_time));
2397 Real maxK = -std::numeric_limits<Real>::max();
2398 Real minK = +std::numeric_limits<Real>::max();
2400 Real maxT = -std::numeric_limits<Real>::max();
2401 Real minT = +std::numeric_limits<Real>::max();
2405 if (!m_fullIntegration) {
2406 maxK = std::min(
maxK, m_inceptionK);
2410 m_Rdot.emplace_back(
m_time, this->computeRdot(m_voltageCurve(
m_time)));
2411 m_criticalVolume.emplace_back(
m_time, this->computeCriticalVolumeTransient());
2412 m_criticalArea.emplace_back(
m_time, this->computeCriticalAreaTransient());
2413 m_ionizationVolumeTransient.emplace_back(
m_time, this->computeIonizationVolumeTransient(m_voltageCurve(
m_time)));
2414 m_inceptionProbability.emplace_back(
m_time, 0.0);
2426template <
typename P,
typename F,
typename C>
2430 CH_TIME(
"DischargeInceptionStepper::interpolateGradAlphaToParticles");
2432 pout() <<
"DischargeInceptionStepper::interpolateGradAlphaToParticles" <<
endl;
2440 m_tracerParticleSolver->getInterpolationType(),
2444template <
typename P,
typename F,
typename C>
2449 CH_TIME(
"DischargeInceptionStepper::computeInceptionIntegral");
2450 if (m_verbosity > 5) {
2451 pout() <<
"DischargeInceptionStepper::computeInceptionIntegral" <<
endl;
2470 this->seedIonizationParticles(
a_voltage);
2471 this->resetTracerParticles();
2474 switch (m_inceptionAlgorithm) {
2475 case IntegrationAlgorithm::Euler: {
2476 this->inceptionIntegrateEuler(
a_voltage);
2480 case IntegrationAlgorithm::Trapezoidal: {
2481 this->inceptionIntegrateTrapezoidal(
a_voltage);
2486 MayDay::Error(
"DischargeInceptionStepper::computeInceptionIntegral -- logic bust");
2499template <
typename P,
typename F,
typename C>
2503 CH_TIME(
"DischargeInceptionStepper::computeInceptionIntegralStationary");
2505 pout() <<
"DischargeInceptionStepper::computeInceptionIntegralStationary" <<
endl;
2516 this->superposition(
gasField, 1.0);
2521 const Real Ecrit = this->getCriticalField();
2527 m_inceptionIntegralPlus.resize(0);
2528 m_inceptionIntegralMinu.resize(0);
2546 m_inceptionIntegralPlus.push_back(
Kplus);
2547 m_inceptionIntegralMinu.push_back(
Kminu);
2597 m_voltageSweeps.resize(0);
2598 for (
int i = 0;
i < m_KPlusValues.size();
i++) {
2599 m_voltageSweeps.push_back(
std::get<0>(m_KPlusValues[
i]));
2603template <
typename P,
typename F,
typename C>
2607 CH_TIME(
"DischargeInceptionStepper::computeInceptionIntegralTransient");
2608 if (m_verbosity > 5) {
2609 pout() <<
"DischargeInceptionStepper::computeInceptionIntegralTransient" <<
endl;
2613 switch (m_inceptionAlgorithm) {
2614 case IntegrationAlgorithm::Euler: {
2615 this->inceptionIntegrateEuler(
a_voltage);
2619 case IntegrationAlgorithm::Trapezoidal: {
2620 this->inceptionIntegrateTrapezoidal(
a_voltage);
2625 MayDay::Error(
"DischargeInceptionStepper::computeInceptionIntegralTransient - logic bust");
2632 m_tracerParticleSolver->deposit(m_inceptionIntegral);
2634 m_amr->conservativeAverage(m_inceptionIntegral, m_realm, m_phase);
2635 m_amr->interpGhost(m_inceptionIntegral, m_realm, m_phase);
2638template <
typename P,
typename F,
typename C>
2642 CH_TIME(
"DischargeInceptionStepper::inceptionIntegrateEuler");
2643 if (m_verbosity > 5) {
2644 pout() <<
"DischargeInceptionStepper::inceptionIntegrateEuler" <<
endl;
2658 m_tracerParticleSolver->
remap();
2672 m_tracerParticleSolver->setVelocity(
scratch);
2673 m_tracerParticleSolver->interpolateVelocities();
2675 while (
amrParticles.getNumberOfValidParticlesGlobal() > 0) {
2677 this->interpolateGradAlphaToParticles();
2680 for (
int lvl = 0;
lvl <= m_amr->getFinestLevel();
lvl++) {
2688#pragma omp parallel for schedule(runtime)
2754 if (!m_fullIntegration) {
2758 if (p.weight() >= m_inceptionK) {
2770 m_tracerParticleSolver->
remap();
2777 if (!m_fullIntegration) {
2778 for (
int lvl = 0;
lvl <= m_amr->getFinestLevel();
lvl++) {
2784#pragma omp parallel for schedule(runtime)
2791 lit().weight() = std::min(m_inceptionK,
lit().weight());
2797 this->rewindTracerParticles();
2806 MayDay::Warning(
"DischargeInceptionStepper::inceptionIntegrateEuler - lost/gained particles!");
2810template <
typename P,
typename F,
typename C>
2814 CH_TIME(
"DischargeInceptionStepper::inceptionIntegrateTrapezoidal");
2815 if (m_verbosity > 5) {
2816 pout() <<
"DischargeInceptionStepper::inceptionIntegrateTrapezoidal" <<
endl;
2842 m_tracerParticleSolver->
remap();
2856 m_tracerParticleSolver->setVelocity(
scratch);
2857 m_tracerParticleSolver->interpolateVelocities();
2859 while (
amrParticles.getNumberOfValidParticlesGlobal() > 0) {
2861 this->interpolateGradAlphaToParticles();
2864 for (
int lvl = 0;
lvl <= m_amr->getFinestLevel();
lvl++) {
2872#pragma omp parallel for schedule(runtime)
2944 m_tracerParticleSolver->
remap();
2948 for (
int lvl = 0;
lvl <= m_amr->getFinestLevel();
lvl++) {
2956#pragma omp parallel for schedule(runtime)
3020 if (!m_fullIntegration) {
3024 if (p.weight() >= m_inceptionK) {
3036 m_tracerParticleSolver->
remap();
3044 if (!m_fullIntegration) {
3045 for (
int lvl = 0;
lvl <= m_amr->getFinestLevel();
lvl++) {
3051#pragma omp parallel for schedule(runtime)
3058 lit().weight() = std::min(m_inceptionK,
lit().weight());
3064 this->rewindTracerParticles();
3067template <
typename P,
typename F,
typename C>
3071 CH_TIME(
"DischargeInceptionStepper::computeTownsendCriterionStationary");
3073 pout() <<
"DischargeInceptionStepper::computeTownsendCriterionStationary" <<
endl;
3076 CH_assert(m_inceptionIntegralPlus.size() == m_inceptionIntegralMinu.size());
3078 m_townsendCriterionPlus.resize(0);
3079 m_townsendCriterionMinu.resize(0);
3081 for (
size_t i = 0;
i < m_voltageSweeps.size();
i++) {
3111 if (m_evaluateTownsend) {
3114 this->resetTracerParticles();
3116 switch (m_inceptionAlgorithm) {
3117 case IntegrationAlgorithm::Euler: {
3118 this->townsendTrackEuler(
voltage);
3122 case IntegrationAlgorithm::Trapezoidal: {
3123 this->townsendTrackTrapezoidal(
voltage);
3128 MayDay::Error(
"DischargeInceptionStepper::computeTownsendCriterionStationary -- logic bust");
3140 this->resetTracerParticles();
3142 switch (m_inceptionAlgorithm) {
3143 case IntegrationAlgorithm::Euler: {
3144 this->townsendTrackEuler(-
voltage);
3148 case IntegrationAlgorithm::Trapezoidal: {
3149 this->townsendTrackTrapezoidal(-
voltage);
3154 MayDay::Error(
"DischargeInceptionStepper::computeTownsendCriterionStationary -- logic bust");
3167 return x > 0.0 ?
exp(
x) - 1 : 0.0;
3183 if (!m_fullIntegration) {
3184 auto truncate = [](
const Real x) ->
Real {
3185 return std::min(
x, 1.0);
3201template <
typename P,
typename F,
typename C>
3205 CH_TIME(
"DischargeInceptionStepper::computeTownsendCriterionTransient");
3206 if (m_verbosity > 5) {
3207 pout() <<
"DischargeInceptionStepper::computeTownsendCriterionTransient" <<
endl;
3211 switch (m_inceptionAlgorithm) {
3212 case IntegrationAlgorithm::Euler: {
3217 case IntegrationAlgorithm::Trapezoidal: {
3218 this->townsendTrackTrapezoidal(
a_voltage);
3223 MayDay::Error(
"DischargeInceptionStepper::computeTownsendCriterionTransient - logic bust");
3233 m_tracerParticleSolver->deposit(
gamma);
3237 return x > 0.0 ?
exp(
x) - 1 : 0.0;
3244 if (!m_fullIntegration) {
3246 m_townsendCriterion,
3248 return std::min(
x, 1.0);
3250 m_amr->getMultiCutVofIterator(m_realm, m_phase));
3253 m_amr->conservativeAverage(m_townsendCriterion, m_realm, m_phase);
3254 m_amr->interpGhost(m_townsendCriterion, m_realm, m_phase);
3257template <
typename P,
typename F,
typename C>
3261 CH_TIME(
"DischargeInceptionStepper::townsendTrackEuler");
3262 if (m_verbosity > 5) {
3263 pout() <<
"DischargeInceptionStepper::townsendTrackEuler" <<
endl;
3276 m_tracerParticleSolver->
remap();
3289 m_tracerParticleSolver->setVelocity(
scratch);
3290 m_tracerParticleSolver->interpolateVelocities();
3292 while (
amrParticles.getNumberOfValidParticlesGlobal() > 0) {
3295 for (
int lvl = 0;
lvl <= m_amr->getFinestLevel();
lvl++) {
3304#pragma omp parallel for schedule(runtime)
3334 p.weight() = m_secondaryEmission(
E,
x);
3351 m_tracerParticleSolver->
remap();
3357 this->rewindTracerParticles();
3366 MayDay::Warning(
"DischargeInceptionStepper::townsendTrackEuler - lost/gained particles!");
3370template <
typename P,
typename F,
typename C>
3374 CH_TIME(
"DischargeInceptionStepper::townsendTrackTrapezoidal");
3375 if (m_verbosity > 5) {
3376 pout() <<
"DischargeInceptionStepper::townsendTrackTrapezoidal" <<
endl;
3396 m_tracerParticleSolver->
remap();
3409 m_tracerParticleSolver->setVelocity(
scratch);
3410 m_tracerParticleSolver->interpolateVelocities();
3412 while (
amrParticles.getNumberOfValidParticlesGlobal() > 0) {
3415 for (
int lvl = 0;
lvl <= m_amr->getFinestLevel();
lvl++) {
3424#pragma omp parallel for schedule(runtime)
3451 p.weight() = m_secondaryEmission(
E,
x);
3476 m_tracerParticleSolver->
remap();
3480 for (
int lvl = 0;
lvl <= m_amr->getFinestLevel();
lvl++) {
3486#pragma omp parallel for schedule(runtime)
3522 p.weight() = m_secondaryEmission(
E,
oldPos);
3539 m_tracerParticleSolver->
remap();
3546 this->rewindTracerParticles();
3555 MayDay::Warning(
"DischargeInceptionStepper::townsendTrackTrapezoidal - lost/gained particles!");
3559template <
typename P,
typename F,
typename C>
3563 CH_TIME(
"DischargeInceptionStepper::computeRdot");
3564 if (m_verbosity > 5) {
3565 pout() <<
"DischargeInceptionStepper::computeRdot" <<
endl;
3578 for (
int lvl = 0;
lvl <= m_amr->getFinestLevel();
lvl++) {
3589#pragma omp parallel for schedule(runtime) reduction(+ : Rdot)
3612 const Real E =
EE.vectorLength();
3616 const Real k = m_detachmentRate(
E,
pos);
3633 const Real E =
EE.vectorLength();
3639 const Real k = m_detachmentRate(
E,
pos);
3662template <
typename P,
typename F,
typename C>
3666 CH_TIME(
"DischargeInceptionStepper::rewindTracerParticles");
3668 pout() <<
"DischargeInceptionStepper::rewindTracerParticles" <<
endl;
3679#pragma omp parallel for schedule(runtime)
3686 p.position() = p.template
vect<0>();
3694template <
typename P,
typename F,
typename C>
3698 CH_TIME(
"DischargeInceptionStepper::resetTracerParticles");
3700 pout() <<
"DischargeInceptionStepper::resetTracerParticles" <<
endl;
3711#pragma omp parallel for schedule(runtime)
3724template <
typename P,
typename F,
typename C>
3728 CH_TIME(
"DischargeInceptionStepper::computeBackgroundIonizationStationary");
3730 pout() <<
"DischargeInceptionStepper::computeBackgroundIonizationStationary" <<
endl;
3733 CH_assert(m_inceptionIntegralPlus.size() == m_inceptionIntegralMinu.size());
3734 CH_assert(m_inceptionIntegralPlus.size() == m_KPlusValues.size());
3735 CH_assert(m_inceptionIntegralMinu.size() == m_KMinuValues.size());
3737 m_backgroundIonizationStationary.resize(0);
3744 for (
size_t i = 0;
i < m_voltageSweeps.size();
i++) {
3763#pragma omp parallel for schedule(runtime)
3779 const Real E =
EE.vectorLength();
3787 const Real E =
EE.vectorLength();
3806template <
typename P,
typename F,
typename C>
3810 CH_TIME(
"DischargeInceptionStepper::computeDetachmentStationary");
3812 pout() <<
"DischargeInceptionStepper::computeDetachmentStationary" <<
endl;
3815 CH_assert(m_inceptionIntegralPlus.size() == m_inceptionIntegralMinu.size());
3816 CH_assert(m_inceptionIntegralPlus.size() == m_KPlusValues.size());
3817 CH_assert(m_inceptionIntegralMinu.size() == m_KMinuValues.size());
3819 m_detachmentStationary.resize(0);
3826 for (
size_t i = 0;
i < m_voltageSweeps.size();
i++) {
3845#pragma omp parallel for schedule(runtime)
3864 const Real E =
EE.vectorLength();
3873 const Real E =
EE.vectorLength();
3894template <
typename P,
typename F,
typename C>
3898 CH_TIME(
"DischargeInceptionStepper::computeFieldEmissionStationary");
3900 pout() <<
"DischargeInceptionStepper::computeFieldEmissionStationary" <<
endl;
3903 CH_assert(m_inceptionIntegralPlus.size() == m_inceptionIntegralMinu.size());
3904 CH_assert(m_inceptionIntegralPlus.size() == m_KPlusValues.size());
3905 CH_assert(m_inceptionIntegralMinu.size() == m_KMinuValues.size());
3907 m_emissionRatesPlus.resize(0);
3908 m_emissionRatesMinu.resize(0);
3910 const int numVoltages = m_inceptionIntegralPlus.size();
3919 for (
size_t i = 0;
i < m_voltageSweeps.size();
i++) {
3944#pragma omp parallel for schedule(runtime)
3994template <
typename P,
typename F,
typename C>
3999 CH_TIME(
"DischargeInceptionStepper::computeFieldEmission");
4000 if (m_verbosity > 5) {
4001 pout() <<
"DischargeInceptionStepper::computeFieldEmission" <<
endl;
4013 for (
int lvl = 0;
lvl <= m_amr->getFinestLevel();
lvl++) {
4021#pragma omp parallel for schedule(runtime)
4039 const Real E =
EE.vectorLength();
4053template <
typename P,
typename F,
typename C>
4060 CH_TIME(
"DischargeInceptionStepper::evaluateFunction");
4061 if (m_verbosity > 5) {
4062 pout() <<
"DischargeInceptionStepper::evaluateFunction" <<
endl;
4065 for (
int lvl = 0;
lvl <= m_amr->getFinestLevel();
lvl++) {
4070template <
typename P,
typename F,
typename C>
4075 const int a_level)
const noexcept
4077 CH_TIME(
"DischargeInceptionStepper::evaluateFunction(level)");
4078 if (m_verbosity > 5) {
4079 pout() <<
"DischargeInceptionStepper::evaluateFunction(level)" <<
endl;
4099#pragma omp parallel for schedule(runtime)
4118 const Real E =
EE.vectorLength();
4126 const Real E =
EE.vectorLength();
4140template <
typename P,
typename F,
typename C>
4144 CH_TIME(
"DischargeInceptionStepper::computeInceptionVoltageVolume");
4146 pout() <<
"DischargeInceptionStepper::computeInceptionVoltageVolume" <<
endl;
4154 if (m_inceptionIntegralPlus.size() < 2) {
4155 DataOps::setValue(m_inceptionVoltagePlus, std::numeric_limits<Real>::quiet_NaN());
4156 DataOps::setValue(m_inceptionVoltageMinu, std::numeric_limits<Real>::quiet_NaN());
4158 MayDay::Warning(
"DischargeInceptionStepper::computeInceptionVoltageVolume -- not enough voltages for estimating "
4159 "inception voltage");
4162 constexpr int comp = 0;
4174 for (
size_t i = 0;
i < K.size() - 1;
i++) {
4180 else if (K[
i] ==
Kinc) {
4188 for (
size_t i = 0;
i <
T.size() - 1;
i++) {
4189 if (
T[
i] <= 1.0 &&
T[
i + 1] > 1) {
4194 else if (
T[
i] == 1.0) {
4204 Uinc = std::numeric_limits<Real>::quiet_NaN();
4227 for (
size_t i = 0;
i < K.size() - 1;
i++) {
4236 for (
size_t i = 0;
i <
T.size() - 1;
i++) {
4237 if (
T[
i] <= 1.0 &&
T[
i + 1] >= 1) {
4247 Uinc = std::numeric_limits<Real>::quiet_NaN();
4269#pragma omp parallel for schedule(runtime)
4298 for (
int i = 0;
i < m_voltageSweeps.size();
i++) {
4318 for (
size_t i = 0;
i < m_voltageSweeps.size();
i++) {
4329 if (m_fullIntegration) {
4356 for (
size_t i = 0;
i < m_voltageSweeps.size();
i++) {
4367 if (m_fullIntegration) {
4401template <
typename P,
typename F,
typename C>
4405 CH_TIME(
"DischargeInceptionStepper::computeMinimumInceptionVoltage");
4406 if (m_verbosity > 5) {
4407 pout() <<
"DischargeInceptionStepper::computeMinimumInceptionVoltage" <<
endl;
4414 UxInc.first = std::numeric_limits<Real>::max();
4417 for (
int lvl = 0;
lvl <= m_amr->getFinestLevel();
lvl++) {
4425#pragma omp parallel for schedule(runtime) reduction(pairmin : UxInc)
4476template <
typename P,
typename F,
typename C>
4480 CH_TIME(
"DischargeInceptionStepper::computeCriticalVolumeStationary");
4482 pout() <<
"DischargeInceptionStepper::computeCriticalVolumeStationary" <<
endl;
4485 CH_assert(m_inceptionIntegralPlus.size() == m_inceptionIntegralMinu.size());
4486 CH_assert(m_inceptionIntegralPlus.size() == m_KPlusValues.size());
4487 CH_assert(m_inceptionIntegralMinu.size() == m_KMinuValues.size());
4489 m_criticalVolumePlus.resize(0);
4490 m_criticalVolumeMinu.resize(0);
4492 const int numVoltages = m_inceptionIntegralPlus.size();
4510#pragma omp parallel for schedule(runtime) reduction(+ : criticalVolumePlus, criticalVolumeMinu)
4567template <
typename P,
typename F,
typename C>
4571 CH_TIME(
"DischargeInceptionStepper::computeCriticalVolumeTransient");
4573 pout() <<
"DischargeInceptionStepper::computeCriticalVolumeTransient" <<
endl;
4590#pragma omp parallel for schedule(runtime) reduction(+ : Vcr)
4631template <
typename P,
typename F,
typename C>
4635 CH_TIME(
"DischargeInceptionStepper::computeCriticalAreaStationary");
4637 pout() <<
"DischargeInceptionStepper::computeCriticalAreaStationary" <<
endl;
4640 CH_assert(m_inceptionIntegralPlus.size() == m_inceptionIntegralMinu.size());
4641 CH_assert(m_inceptionIntegralPlus.size() == m_KPlusValues.size());
4642 CH_assert(m_inceptionIntegralMinu.size() == m_KMinuValues.size());
4644 m_criticalAreaPlus.resize(0);
4645 m_criticalAreaMinu.resize(0);
4647 const int numVoltages = m_inceptionIntegralPlus.size();
4665#pragma omp parallel for schedule(runtime) reduction(+ : criticalAreaPlus, criticalAreaMinu)
4703template <
typename P,
typename F,
typename C>
4707 CH_TIME(
"DischargeInceptionStepper::computeCriticalAreaTransient");
4709 pout() <<
"DischargeInceptionStepper::computeCriticalAreaTransient" <<
endl;
4726#pragma omp parallel for schedule(runtime) reduction(+ : Acr)
4754template <
typename P,
typename F,
typename C>
4758 CH_TIME(
"DischargeInceptionStepper::computeIonizationVolumeStationary");
4760 pout() <<
"DischargeInceptionStepper::computeIonizationVolumeStationary" <<
endl;
4763 CH_assert(m_inceptionIntegralPlus.size() == m_inceptionIntegralMinu.size());
4764 CH_assert(m_inceptionIntegralPlus.size() == m_KPlusValues.size());
4765 CH_assert(m_inceptionIntegralMinu.size() == m_KMinuValues.size());
4767 m_ionizationVolume.resize(0);
4769 const int numVoltages = m_inceptionIntegralPlus.size();
4776 for (
size_t i = 0;
i < m_voltageSweeps.size();
i++) {
4795#pragma omp parallel for schedule(runtime) reduction(+ : ionizationVolume)
4810 const Real E =
EE.vectorLength();
4826 const Real E =
EE.vectorLength();
4852template <
typename P,
typename F,
typename C>
4856 CH_TIME(
"DischargeInceptionStepper::computeIonizationVolumeTransient");
4857 if (m_verbosity > 5) {
4858 pout() <<
"DischargeInceptionStepper::computeIonizationVolumeTransient" <<
endl;
4868 for (
int lvl = 0;
lvl <= m_amr->getFinestLevel(); ++
lvl) {
4881#pragma omp parallel for schedule(runtime) reduction(+ : Vion)
4897 const Real E =
EE.vectorLength();
4912 const Real E =
EE.vectorLength();
4934template <
typename P,
typename F,
typename C>
4938 CH_TIME(
"DischargeInceptionStepper::writeReportStationary");
4940 pout() <<
"DischargeInceptionStepper::writeReportStationary" <<
endl;
4943 const auto UIncPlus = this->computeMinimumInceptionVoltage(m_inceptionVoltagePlus);
4944 const auto UIncMinu = this->computeMinimumInceptionVoltage(m_inceptionVoltageMinu);
4946 const auto streamerUIncPlus = this->computeMinimumInceptionVoltage(m_streamerInceptionVoltagePlus);
4947 const auto streamerUIncMinu = this->computeMinimumInceptionVoltage(m_streamerInceptionVoltageMinu);
4949 const auto townsendUIncPlus = this->computeMinimumInceptionVoltage(m_townsendInceptionVoltagePlus);
4950 const auto townsendUIncMinu = this->computeMinimumInceptionVoltage(m_townsendInceptionVoltageMinu);
4965 output <<
"# Could not compute inception voltage\n";
4968 if(m_fullIntegration){
4969 output <<
"# Minimum inception voltage(+) = " <<
UIncPlus.first <<
",\t x = " <<
UIncPlus.second <<
"\n";
4970 output <<
"# Minimum inception voltage(-) = " <<
UIncMinu.first <<
",\t x = " <<
UIncMinu.second <<
"\n";
4979 output <<
"# Minimum inception voltage(+) >= " <<
UIncPlus.first <<
",\t x = " <<
UIncPlus.second <<
"\n";
4980 output <<
"# Minimum inception voltage(-) >= " <<
UIncMinu.first <<
",\t x = " <<
UIncMinu.second <<
"\n";
5021 for (
int i = 0;
i < m_voltageSweeps.size();
i++) {
5045template <
typename P,
typename F,
typename C>
5049 CH_TIME(
"DischargeInceptionStepper::writeReportTransient");
5051 pout() <<
"DischargeInceptionStepper::writeReportTransient" <<
endl;
5074 for (
size_t i = 0;
i < m_Rdot.size() - 1;
i++) {
5075 const Real t = m_Rdot[
i].first;
5076 const Real dt = m_Rdot[
i + 1].first - m_Rdot[
i].first;
5077 const Real prob = m_inceptionProbability[
i].second;
5082 dProb.emplace_back(0.0);
5086 for (
size_t i = 0;
i < m_Rdot.size() - 1;
i++) {
5087 const Real t1 = m_Rdot[
i].first;
5088 const Real t2 = m_Rdot[
i + 1].first;
5090 const Real prob = m_inceptionProbability[
i].second;
5095 for (
int i = 0;
i <
tau.size();
i++) {
5096 const Real prob = m_inceptionProbability[
i].second;
5098 tau[
i] =
prob > 0.0 ?
tau[
i] /
prob : std::numeric_limits<Real>::infinity();
5101 for (
size_t i = 0;
i < m_Rdot.size();
i++) {
5125template <
typename P,
typename F,
typename C>
5132 CH_TIME(
"DischargeInceptionStepper::particleOutsideGrid");
5133 if (m_verbosity > 5) {
5134 pout() <<
"DischargeInceptionStepper::particleOutsideGrid" <<
endl;
5149template <
typename P,
typename F,
typename C>
5154 CH_TIME(
"DischargeInceptionStepper::particleInsideEB");
5155 if (m_verbosity > 5) {
5156 pout() <<
"DischargeInceptionStepper::particleInsideEB" <<
endl;
5165template <
typename P,
typename F,
typename C>
5169 CH_TIME(
"DischargeInceptionStepper::computeIonVelocity");
5170 if (m_verbosity > 5) {
5171 pout() <<
"DischargeInceptionStepper::computeIonVelocity" <<
endl;
5187 for (
int lvl = 0;
lvl <= m_amr->getFinestLevel();
lvl++) {
5193#pragma omp parallel for schedule(runtime)
5205 const Real E =
EE.vectorLength();
5212 const Real E =
EE.vectorLength();
5214 MU(
vof, 0) = m_ionMobility(
E);
5227 m_amr->arithmeticAverage(
vel, m_realm, m_phase);
5228 m_amr->interpGhostPwl(
vel, m_realm, m_phase);
5231template <
typename P,
typename F,
typename C>
5235 CH_TIME(
"DischargeInceptionStepper::computeIonDiffusion");
5236 if (m_verbosity > 5) {
5237 pout() <<
"DischargeInceptionStepper::computeIonDiffusion" <<
endl;
5252 for (
int lvl = 0;
lvl <= m_amr->getFinestLevel();
lvl++) {
5258#pragma omp parallel for schedule(runtime)
5270 const Real E =
EE.vectorLength();
5277 const Real E =
EE.vectorLength();
5279 dCo(
vof, 0) = m_ionDiffusion(
E);
5291 m_amr->arithmeticAverage(
diffCoCell, m_realm, m_phase);
5292 m_amr->interpGhostPwl(
diffCoCell, m_realm, m_phase);
5303 m_amr->getDomains(),
5307 Average::Arithmetic,
5308 m_amr->getFaceIteratorWithTangentialGhosts(m_realm, m_phase));
5311template <
typename P,
typename F,
typename C>
5318 CH_TIME(
"DischargeInceptionStepper::superposition(full)");
5327 m_amr->arithmeticAverage(
a_sumField, m_realm, m_phase);
5328 m_amr->interpGhostPwl(
a_sumField, m_realm, m_phase);
5332template <
typename P,
typename F,
typename C>
5336 CH_TIME(
"DischargeInceptionStepper::superposition(short)");
5341template <
typename P,
typename F,
typename C>
5347 CH_TIME(
"DischargeInceptionStepper::getMaxValueAndLocation");
5348 if (m_verbosity > 5) {
5349 pout() <<
"DischargeInceptionStepper::getMaxValueAndLocation" <<
endl;
5355 maxValAndPos.first = -std::numeric_limits<Real>::max();
5358 for (
int lvl = 0;
lvl <= m_amr->getFinestLevel();
lvl++) {
5369#pragma omp parallel for schedule(runtime) reduction(pairmax : maxValAndPos)
5413template <
typename P,
typename F,
typename C>
5423 CH_TIMERS(
"DischargeInceptionStepper::writeData");
5424 CH_TIMER(
"DischargeInceptionStepper::writeData::allocate",
t1);
5425 CH_TIMER(
"DischargeInceptionStepper::writeData::local_copy",
t2);
5426 CH_TIMER(
"DischargeInceptionStepper::writeData::interp_ghost",
t3);
5427 CH_TIMER(
"DischargeInceptionStepper::writeData::interp_centroid",
t4);
5428 CH_TIMER(
"DischargeInceptionStepper::writeData::final_copy",
t5);
5429 if (m_verbosity > 5) {
5430 pout() <<
"DischargeInceptionStepper::writeData" <<
endl;
5471template <
typename P,
typename F,
typename C>
5475 CH_TIMERS(
"DischargeInceptionStepper::getElectricField");
5477 return &m_homogeneousFieldGas;
5480template <
typename P,
typename F,
typename C>
5484 CH_TIME(
"DischargeInceptionStepper::getCriticalField");
5486 pout() <<
"DischargeInceptionStepper::getCriticalField" <<
endl;
5499 return std::pow(10.0, p);
5502#include <CD_NamespaceFooter.H>
Declaration of the Physics::DischargeInception::DischargeInceptionSpecies CDR species.
Declaration of the Physics::DischargeInception::DischargeInceptionStepper TimeStepper.
Mode
Solver mode: stationary (voltage sweep) or transient (time-dependent).
Definition CD_DischargeInceptionStepper.H:56
Declaration of various useful OpenMP-related utilities.
Agglomeration of some useful algebraic/polynomial routines.
Declaration of various useful units.
static void scale(MFAMRCellData &a_lhs, const Real &a_scale) noexcept
Scale data by factor.
Definition CD_DataOps.cpp:2503
static void floor(EBAMRCellData &a_lhs, const Real a_value, const Vector< RefCountedPtr< LayoutData< VoFIterator > > > &a_vofIter)
Floor values in data holder. This sets all values below a_value to a_value.
Definition CD_DataOps.cpp:1465
static void getMaxMin(Real &max, Real &min, EBAMRCellData &a_data, const int a_comp, const Vector< RefCountedPtr< LayoutData< VoFIterator > > > &a_vofIter)
Get maximum and minimum value of specified component.
Definition CD_DataOps.cpp:1711
static void getMaxMinNorm(Real &a_max, Real &a_min, EBAMRCellData &data, const Vector< RefCountedPtr< LayoutData< VoFIterator > > > &a_vofIter)
Get maximum and minimum value of normed data.
Definition CD_DataOps.cpp:1879
static void multiply(EBAMRCellData &a_lhs, const EBAMRCellData &a_rhs)
Multiply data holder by another data holder.
Definition CD_DataOps.cpp:2246
static void incr(MFAMRCellData &a_lhs, const MFAMRCellData &a_rhs, const Real a_scale) noexcept
Function which increments data in the form a_lhs = a_lhs + a_rhs*a_scale for all components.
Definition CD_DataOps.cpp:820
static void kappaScale(EBAMRCellData &a_data, const Vector< RefCountedPtr< LayoutData< VoFIterator > > > &a_vofIter) noexcept
Scale data by volume fraction.
Definition CD_DataOps.cpp:2142
static void setValue(LevelData< MFInterfaceFAB< T > > &a_lhs, const T &a_value)
Set value in an MFInterfaceFAB data holder.
Definition CD_DataOpsImplem.H:24
static void dotProduct(MFAMRCellData &a_result, const MFAMRCellData &a_data1, const MFAMRCellData &a_data2)
Compote the cell-wise dot product between two data holders.
Definition CD_DataOps.cpp:537
static void squareRoot(EBAMRFluxData &a_lhs, Vector< RefCountedPtr< LayoutData< std::array< FaceIterator, SpaceDim > > > > &a_faceIter)
Compute the square root of the input data.
Definition CD_DataOps.cpp:3384
static void setCoveredValue(EBAMRCellData &a_lhs, const EBAMRCellData &a_coveredMask, const int a_comp, const Real a_value)
Set value in covered cells. Does specified component.
Definition CD_DataOps.cpp:2655
static void compute(EBAMRCellData &a_data, const std::function< Real(const Real a_cellValue)> &a_func, const Vector< RefCountedPtr< LayoutData< VoFIterator > > > &a_vofIter) noexcept
Compute a new value given the old cell value.
Definition CD_DataOps.cpp:482
static void copy(MFAMRCellData &a_dst, const MFAMRCellData &a_src)
Copy data from one data holder to another.
Definition CD_DataOps.cpp:1201
static void averageCellToFace(EBAMRFluxData &a_faceData, const EBAMRCellData &a_cellData, const Vector< ProblemDomain > &a_domains, Vector< RefCountedPtr< LayoutData< std::array< FaceIterator, SpaceDim > > > > &a_faceIter)
Average all components of the cell-centered data to faces (arithmetic, no tangential ghost faces).
Definition CD_DataOps.cpp:148
static void multiplyScalar(EBAMRCellData &a_lhs, const EBAMRCellData &a_rhs)
Multiply data holder by another data holder.
Definition CD_DataOps.cpp:2341
Type
Type of interpolation methods supported. PWC = Piecewise constant, ignoring the embedded boundary....
Definition CD_EBCoarseToFineInterp.H:43
static bool ebIntersectionBisect(const RefCountedPtr< BaseIF > &a_impFunc, const RealVect &a_oldPos, const RealVect &a_newPos, const Real &a_bisectStep, Real &a_s)
Compute the intersection point between a particle path and an implicit function using a bisection alg...
Definition CD_ParticleOpsImplem.H:178
static void copyDestructive(ParticleContainer< P > &a_dst, ParticleContainer< P > &a_src) noexcept
Copy all the particles from the a_src to a_dst. This destroys the source particles.
Definition CD_ParticleOpsImplem.H:296
static bool domainIntersection(const RealVect &a_oldPos, const RealVect &a_newPos, const RealVect &a_probLo, const RealVect &a_probHi, Real &a_s)
Compute the intersection point between a particle path and a domain side.
Definition CD_ParticleOpsImplem.H:132
CdrSpecies subclass for use with DischargeInceptionStepper.
Definition CD_DischargeInceptionSpecies.H:30
TimeStepper for evaluating the streamer inception criterion in static or transient electric fields.
Definition CD_DischargeInceptionStepper.H:94
virtual const std::function< Real(const Real &E, const RealVect &x)> & getAlpha() const noexcept
Get ionization coefficient.
Definition CD_DischargeInceptionStepperImplem.H:2063
void parseRuntimeOptions() override
Parse runtime options.
Definition CD_DischargeInceptionStepperImplem.H:388
virtual const EBAMRCellData * getElectricField() const noexcept
Get the electric field.
Definition CD_DischargeInceptionStepperImplem.H:5473
void parseMode() noexcept
Parse simulation mode.
Definition CD_DischargeInceptionStepperImplem.H:418
void computeIonVelocity(const Real &a_voltage) noexcept
Set the negative ion velocity. Note.
Definition CD_DischargeInceptionStepperImplem.H:5167
virtual void setIonMobility(const std::function< Real(const Real E)> &a_mobility) noexcept
Set the negative ion mobility (field-dependent)
Definition CD_DischargeInceptionStepperImplem.H:2014
virtual void writeReportStationary() const noexcept
Print report to the terminal.
Definition CD_DischargeInceptionStepperImplem.H:4936
virtual Real advance(const Real a_dt) override
Advancement method. Swaps between various kernels.
Definition CD_DischargeInceptionStepperImplem.H:1601
virtual void townsendTrackTrapezoidal(const Real &a_voltage) noexcept
Track particles (positive ions) using a trapezoidal rule and check if the collide with a cathode.
Definition CD_DischargeInceptionStepperImplem.H:3372
virtual void seedUniformParticles() noexcept
Distribute particles in every grid cell.
Definition CD_DischargeInceptionStepperImplem.H:2136
virtual void resetTracerParticles() noexcept
Reset particles.
Definition CD_DischargeInceptionStepperImplem.H:3696
virtual void setIonDensity(const std::function< Real(const RealVect x)> &a_density) noexcept
Set the negative ion density.
Definition CD_DischargeInceptionStepperImplem.H:2002
virtual void computeCriticalVolumeStationary() noexcept
Compute the critical volume of the K values for each voltage.
Definition CD_DischargeInceptionStepperImplem.H:4478
virtual void writePlotDataStationary(LevelData< EBCellFAB > &a_output, int &a_icomp, const std::string &a_outputRealm, const int a_level) const noexcept
Write plot data for the 'stationary' mode.
Definition CD_DischargeInceptionStepperImplem.H:1117
virtual void postRegrid() override
Perform post-regrid operations.
Definition CD_DischargeInceptionStepperImplem.H:1953
virtual void inceptionIntegrateTrapezoidal(const Real &a_voltage) noexcept
K integral: Add integration parts after particles move.
Definition CD_DischargeInceptionStepperImplem.H:2812
virtual void setBackgroundRate(const std::function< Real(const Real &E, const RealVect &x)> &a_backgroundRate) noexcept
Set the background ionization rate (e.g. from cosmic radiation etc).
Definition CD_DischargeInceptionStepperImplem.H:2077
void computeIonDiffusion(const Real &a_voltage) noexcept
Set the negative ion diffusion coefficient.
Definition CD_DischargeInceptionStepperImplem.H:5233
virtual std::pair< Real, RealVect > computeMinimumInceptionVoltage(const EBAMRCellData &a_Uinc) const noexcept
Compute the minimum inception voltage and the starting electron position.
Definition CD_DischargeInceptionStepperImplem.H:4403
virtual void computeTownsendCriterionStationary() noexcept
Solve for the Townsend criterion for each particle in each voltage.
Definition CD_DischargeInceptionStepperImplem.H:3069
virtual void synchronizeSolverTimes(const int a_step, const Real a_time, const Real a_dt) override
Synchronize solver times and time steps.
Definition CD_DischargeInceptionStepperImplem.H:1799
virtual void inceptionIntegrateEuler(const Real &a_voltage) noexcept
Integrate the inception integral using the Euler rule.
Definition CD_DischargeInceptionStepperImplem.H:2640
virtual void computeInceptionVoltageVolume() noexcept
Interpolate between K values to find voltage giving K_inception and store values in m_inceptionVoltag...
Definition CD_DischargeInceptionStepperImplem.H:4142
virtual Real computeIonizationVolumeTransient(const Real &a_voltage) const noexcept
Compute the ionization volume for each voltage.
Definition CD_DischargeInceptionStepperImplem.H:4854
virtual void computeFieldEmission(EBAMRCellData &a_emissionRate, const Real &a_voltage) const noexcept
Compute field emission rates.
Definition CD_DischargeInceptionStepperImplem.H:3996
virtual int getNumberOfPlotVariables() const override
Get the number of plot variables for this time stepper.
Definition CD_DischargeInceptionStepperImplem.H:671
virtual Real computeCriticalVolumeTransient() const noexcept
Compute the critical volume of the K values for each voltage.
Definition CD_DischargeInceptionStepperImplem.H:4569
void registerOperators() override
Register operators.
Definition CD_DischargeInceptionStepperImplem.H:359
virtual void getMaxValueAndLocation(Real &a_maxVal, RealVect &a_maxPos, const EBAMRCellData &a_data) const noexcept
Get the maximum value and location corresponding to the maximum value in the input data holder.
Definition CD_DischargeInceptionStepperImplem.H:5343
virtual void evaluateFunction(EBAMRCellData &a_data, const Real &a_voltage, const std::function< Real(const Real E, const RealVect x)> &a_func) const noexcept
Evaluate a function f = f(E, x) in a volume.
Definition CD_DischargeInceptionStepperImplem.H:4055
void allocate() override
Allocate storage for solvers and time stepper.
Definition CD_DischargeInceptionStepperImplem.H:172
virtual Vector< std::string > getTransientPlotVariableNames() const noexcept
Get plot variable names for transient mode.
Definition CD_DischargeInceptionStepperImplem.H:1009
virtual Mode getMode() const noexcept
Get the solver mode.
Definition CD_DischargeInceptionStepperImplem.H:2129
void parseInceptionAlgorithm() noexcept
Parse the inception algorithm.
Definition CD_DischargeInceptionStepperImplem.H:477
virtual ~DischargeInceptionStepper()
Destructor.
Definition CD_DischargeInceptionStepperImplem.H:112
void solvePoisson() noexcept
Solve the Poisson equation.
Definition CD_DischargeInceptionStepperImplem.H:250
virtual void setAlpha(const std::function< Real(const Real &E, const RealVect &x)> &a_alpha) noexcept
Set the ionization coefficient.
Definition CD_DischargeInceptionStepperImplem.H:2038
virtual void computeInceptionIntegral(EBAMRCellData &a_inceptionIntegral, const Real a_voltage) noexcept
Compute the inception integral for the input voltage.
Definition CD_DischargeInceptionStepperImplem.H:2446
virtual void regrid(const int a_lmin, const int a_oldFinestLevel, const int a_newFinestLevel) override
Time stepper regrid method.
Definition CD_DischargeInceptionStepperImplem.H:1890
bool particleOutsideGrid(const RealVect &a_pos, const RealVect &a_probLo, const RealVect &a_probHi) const noexcept
Check if particle is outside grid boundaries.
Definition CD_DischargeInceptionStepperImplem.H:5127
virtual void writeReportTransient() const noexcept
Print report to the terminal.
Definition CD_DischargeInceptionStepperImplem.H:5047
virtual void rewindTracerParticles() noexcept
Move particles back to their original position.
Definition CD_DischargeInceptionStepperImplem.H:3664
virtual void townsendTrackEuler(const Real &a_voltage) noexcept
Track particles (positive ions) using an Euler rule and check if the collide with a cathode.
Definition CD_DischargeInceptionStepperImplem.H:3259
void superposition(EBAMRCellData &a_sumField, const MFAMRCellData &a_inhomogeneousField, const MFAMRCellData &a_homogeneousField, const Real a_voltage) const noexcept
Calculate the total electric field = inhomogeneous + V * homogeneous.
Definition CD_DischargeInceptionStepperImplem.H:5313
void parseOptions()
Parse options.
Definition CD_DischargeInceptionStepperImplem.H:373
void setupSolvers() override
Instantiate the tracer particle solver.
Definition CD_DischargeInceptionStepperImplem.H:122
virtual void setEta(const std::function< Real(const Real &E, const RealVect &x)> &a_eta) noexcept
Set the attachment coefficient.
Definition CD_DischargeInceptionStepperImplem.H:2051
virtual Vector< std::string > getStationaryPlotVariableNames() const noexcept
Get plot variable names for stationary mode.
Definition CD_DischargeInceptionStepperImplem.H:864
virtual void setDetachmentRate(const std::function< Real(const Real &E, const RealVect &x)> &a_detachmentRate) noexcept
Set the detachment rate for negative ions.
Definition CD_DischargeInceptionStepperImplem.H:2090
virtual void computeTownsendCriterionTransient(const Real &a_voltage) noexcept
Solve for the Townsend criterion for each particle in each voltage.
Definition CD_DischargeInceptionStepperImplem.H:3203
virtual void computeIonizationVolumeStationary() noexcept
Compute the ionization volume for each voltage.
Definition CD_DischargeInceptionStepperImplem.H:4756
virtual void writePlotDataTransient(LevelData< EBCellFAB > &a_output, int &a_icomp, const std::string &a_outputRealm, const int a_level) const noexcept
Write plot data for the 'transient' mode.
Definition CD_DischargeInceptionStepperImplem.H:1331
virtual void computeFieldEmissionStationary() noexcept
Compute field emission rates.
Definition CD_DischargeInceptionStepperImplem.H:3896
void parseOutput() noexcept
Parse output settings.
Definition CD_DischargeInceptionStepperImplem.H:463
virtual void computeInceptionIntegralStationary() noexcept
Solve streamer inception integral for each particle in each voltage and store K values in m_inception...
Definition CD_DischargeInceptionStepperImplem.H:2501
virtual Real computeCriticalAreaTransient() const noexcept
Compute the critical area of the K values for each voltage.
Definition CD_DischargeInceptionStepperImplem.H:4705
virtual Real getCriticalField() const noexcept
Get the breakdown field.
Definition CD_DischargeInceptionStepperImplem.H:5482
virtual Vector< std::string > getPlotVariableNames() const override
Get plot variable names.
Definition CD_DischargeInceptionStepperImplem.H:808
virtual void computeDetachmentStationary() noexcept
Compute the detachment ionization rate for all voltages.
Definition CD_DischargeInceptionStepperImplem.H:3808
virtual void writeData(LevelData< EBCellFAB > &a_output, int &a_comp, const EBAMRCellData &a_data, const std::string a_outputRealm, const int a_level, const bool a_interpToCentroids, const bool a_interpGhost) const noexcept
Write data to output. Convenience function used for IO.
Definition CD_DischargeInceptionStepperImplem.H:5415
void parseVoltages() noexcept
Parse voltage levels.
Definition CD_DischargeInceptionStepperImplem.H:443
virtual void interpolateGradAlphaToParticles() noexcept
Interpolate alpha/|grad(alpha)| onto some scratch particle storage.
Definition CD_DischargeInceptionStepperImplem.H:2428
virtual void writePlotData(LevelData< EBCellFAB > &a_output, int &a_icomp, const std::string &a_outputRealm, const int a_level) const override
Write plot data to output holder.
Definition CD_DischargeInceptionStepperImplem.H:1074
virtual void setIonDiffusion(const std::function< Real(const Real E)> &a_diffCo) noexcept
Set the negative ion diffusion coefficient (field-dependent)
Definition CD_DischargeInceptionStepperImplem.H:2026
void postInitialize() override
Perform any post-initialization steps.
Definition CD_DischargeInceptionStepperImplem.H:2346
bool particleInsideEB(const RealVect &a_pos) const noexcept
Check if particle is inside electrode.
Definition CD_DischargeInceptionStepperImplem.H:5151
virtual void setSigma(const std::function< Real(const RealVect &x)> &a_sigma) noexcept
Set surface charge distribution.
Definition CD_DischargeInceptionStepperImplem.H:1990
void parseTransportAlgorithm() noexcept
Parse the transport algorithm.
Definition CD_DischargeInceptionStepperImplem.H:534
virtual void seedIonizationParticles(const Real a_voltage) noexcept
Add particles to every cell where alpha - eta > 0.0.
Definition CD_DischargeInceptionStepperImplem.H:2214
DischargeInceptionStepper()
Default constructor.
Definition CD_DischargeInceptionStepperImplem.H:38
void parsePlotVariables() noexcept
Parse plot variables.
Definition CD_DischargeInceptionStepperImplem.H:574
void initialData() override
Fill problem with initial data.
Definition CD_DischargeInceptionStepperImplem.H:238
virtual const std::function< Real(const Real &E, const RealVect &x)> & getEta() const noexcept
Get attachment coefficient.
Definition CD_DischargeInceptionStepperImplem.H:2070
virtual void setSecondaryEmission(const std::function< Real(const Real &E, const RealVect &x)> &a_coeff) noexcept
Set the secondary emission coefficient.
Definition CD_DischargeInceptionStepperImplem.H:2116
virtual Real computeDt() override
Compute a time step to be used by Driver.
Definition CD_DischargeInceptionStepperImplem.H:1514
virtual void preRegrid(const int a_lmin, const int a_oldFinestLevel) override
Perform pre-regrid operations.
Definition CD_DischargeInceptionStepperImplem.H:1870
virtual void printStepReport() override
Print a step report. Used in transient simulations.
Definition CD_DischargeInceptionStepperImplem.H:1817
virtual void setRho(const std::function< Real(const RealVect &x)> &a_rho) noexcept
Set space charge distribution.
Definition CD_DischargeInceptionStepperImplem.H:1978
void parseVerbosity() noexcept
Parse class verbosity.
Definition CD_DischargeInceptionStepperImplem.H:403
void registerRealms() override
Register realms. Primal is the only realm we need.
Definition CD_DischargeInceptionStepperImplem.H:347
virtual void computeBackgroundIonizationStationary() noexcept
Compute the background ionization rate for all voltages.
Definition CD_DischargeInceptionStepperImplem.H:3726
virtual void computeInceptionIntegralTransient(const Real &a_voltage) noexcept
Solve streamer inception integral.
Definition CD_DischargeInceptionStepperImplem.H:2605
virtual void setVoltageCurve(const std::function< Real(const Real &a_time)> &a_voltageCurve) noexcept
Set the voltage curve (used for transient mode)
Definition CD_DischargeInceptionStepperImplem.H:1966
virtual void computeCriticalAreaStationary() noexcept
Compute the critical area of the K values for each voltage.
Definition CD_DischargeInceptionStepperImplem.H:4633
virtual void advanceIons(const Real a_dt) noexcept
Advance negative ions.
Definition CD_DischargeInceptionStepperImplem.H:1713
virtual Real computeRdot(const Real &a_voltage) const noexcept
Compute integral_Vcr(done/dt * (1 - eta/alpha) dV)
Definition CD_DischargeInceptionStepperImplem.H:3561
virtual void setFieldEmission(const std::function< Real(const Real &E, const RealVect &x)> &a_currentDensity) noexcept
Set the field emission current.
Definition CD_DischargeInceptionStepperImplem.H:2103
static const std::string Primal
Identifier for perimal realm.
Definition CD_Realm.H:39
Class which is used for run-time monitoring of events.
Definition CD_Timer.H:32
Base class for a tracer particle solver. This solver can advance particles in a pre-defined velocity ...
Definition CD_TracerParticleSolver.H:38
virtual void remap()
Remap particles.
Definition CD_TracerParticleSolverImplem.H:339
void parsePlotVariables()
Parse plot variables.
Definition CD_TracerParticleSolverImplem.H:148
phase::which_phase m_phase
Phase where this solver lives.
Definition CD_TracerParticleSolver.H:367
TracerParticleSolver()
Default constructor.
Definition CD_TracerParticleSolverImplem.H:26
virtual void setTime(const int a_step, const Real a_time, const Real a_dt)
Set the time for this solver.
Definition CD_TracerParticleSolverImplem.H:257
std::string m_realm
Realm where this solver lives.
Definition CD_TracerParticleSolver.H:352
virtual ParticleContainer< P > & getParticles()
Get all particles.
Definition CD_TracerParticleSolverImplem.H:663
void parseVerbosity()
Parse solver verbosity.
Definition CD_TracerParticleSolverImplem.H:163
int m_verbosity
Verbosity level.
Definition CD_TracerParticleSolver.H:387
RefCountedPtr< AmrMesh > m_amr
Handle to AMR mesh.
Definition CD_TracerParticleSolver.H:327
virtual Vector< std::string > getPlotVariableNames() const
Get plot variable names.
Definition CD_TracerParticleSolverImplem.H:482
Real m_dt
Time step.
Definition CD_TracerParticleSolver.H:372
virtual void allocate()
Allocate storage for this solver.
Definition CD_TracerParticleSolverImplem.H:195
int m_timeStep
Time step.
Definition CD_TracerParticleSolver.H:382
virtual void interpolateVelocities()
Interpolate particles velocities.
Definition CD_TracerParticleSolverImplem.H:393
Real m_time
Time.
Definition CD_TracerParticleSolver.H:377
virtual int getNumberOfPlotVariables() const
Get the number of plot variables.
Definition CD_TracerParticleSolverImplem.H:461
ALWAYS_INLINE void loop(const Box &a_computeBox, Functor &&kernel)
Launch a C++ kernel over a regular grid with compile-time per-dimension strides.
Definition CD_BoxLoopsImplem.H:39
RealVect position(Location::Cell a_location, const VolIndex &a_vof, const EBISBox &a_ebisbox, const Real &a_dx)
Compute the position (ignoring the "origin) of a Vof.
Definition CD_LocationImplem.H:21
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:177
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:59
Real sum(const Real &a_value) noexcept
Compute the sum across all MPI ranks.
Definition CD_ParallelOpsImplem.H:354
Real brentSolve(const Real a_point1, const Real a_point2, const std::function< Real(const Real x)> &a_func) noexcept
Compute the root of a function between two points. This is a 1D problem.
Definition CD_PolyUtils.cpp:169
constexpr Real Qe
Elementary charge.
Definition CD_Units.H:35
@ solid
Solid (dielectric) phase.
Definition CD_MultiFluidIndexSpace.H:40
@ gas
Gas phase.
Definition CD_MultiFluidIndexSpace.H:39