Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

electron-temperature reaction #1099

Merged
merged 12 commits into from
Jan 13, 2022
99 changes: 99 additions & 0 deletions include/cantera/kinetics/Arrhenius.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ class ArrheniusBase : public ReactionRate
double m_b; //!< Temperature exponent
double m_Ea_R; //!< Activation energy (in temperature units)
double m_order; //!< Reaction order
std::string m_A_str = "A"; //!< The string for temperature exponent
std::string m_b_str = "b"; //!< The string for temperature exponent
std::string m_Ea_str = "Ea"; //!< The string for activation energy
Units m_rate_units; //!< Reaction rate units
};

Expand Down Expand Up @@ -195,6 +198,102 @@ class ArrheniusRate final : public ArrheniusBase
};


//! Two temperature plasma reaction rate type depends on both
//! gas temperature and electron temperature.
/*!
* The form of the two temperature plasma reaction rate coefficient is similar to an
* Arrhenius reaction rate coefficient. The temperature exponent (b) is applied to
* the electron temperature instead. In addition, the exponential term with
* activation energy for electron is included.
*
* \f[
* k_f = A T_e^b \exp (-E_a/RT) \exp (-E_{a,e}/RT_e)
* \f]
*
* Ref.: Kossyi, I. A., Kostinsky, A. Y., Matveyev, A. A., & Silakov, V. P. (1992).
* Kinetic scheme of the non-equilibrium discharge in nitrogen-oxygen mixtures.
* Plasma Sources Science and Technology, 1(3), 207.
* doi: 10.1088/0963-0252/1/3/011
* @ingroup arrheniusGroup
*/
class TwoTempPlasmaRate final : public ArrheniusBase
{
public:
TwoTempPlasmaRate();

//! Constructor.
/*!
* @param A Pre-exponential factor. The unit system is (kmol, m, s); actual units
* depend on the reaction order and the dimensionality (surface or bulk).
* @param b Temperature exponent (non-dimensional)
* @param Ea Activation energy in energy units [J/kmol]
* @param EE Activation electron energy in energy units [J/kmol]
*/
TwoTempPlasmaRate(double A, double b, double Ea, double EE);

unique_ptr<MultiRateBase> newMultiRate() const override {
return unique_ptr<MultiRateBase>(
new MultiBulkRate<TwoTempPlasmaRate, TwoTempPlasmaData>);
}

//! Constructor based on AnyMap content
TwoTempPlasmaRate(const AnyMap& node, const UnitStack& rate_units={})
: TwoTempPlasmaRate()
{
setParameters(node, rate_units);
}

//! Identifier of reaction rate type
virtual const std::string type() const override {
return "two-temperature-plasma";
}

virtual void setRateParameters(const AnyValue& rate,
ischoegl marked this conversation as resolved.
Show resolved Hide resolved
const UnitSystem& units,
const UnitStack& rate_units) override;

//! Perform object setup based on AnyMap node information
/*!
* @param node AnyMap containing rate information
* @param rate_units Unit definitions specific to rate information
*/
virtual void setParameters(const AnyMap& node, const UnitStack& rate_units) override;

virtual void getParameters(AnyMap& node) const override;

double evalFromStruct(const TwoTempPlasmaData& shared_data) {
return m_A * std::exp(m_b * shared_data.logTe -
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BangShiuh this is not equivalent to the form given in the docstrings above, isn't it?

k_f = A T_e^b \exp (-E_a/RT) \exp (-E_{a,e}/RT_e)

which is the form I would expect in 2-T plasma

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TwoTempPlasma is no longer in Arrhenius. The docstrings should be update-to-date in TwoTempPlasmaRate.h.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm don't think the currently implemented form would work for (at least) our plasma models.

The currently implemented form is (1) :

k_f =  A T_e^b \exp (-E_{a,g}/RT) \exp (E_{a,e} (T_e - T)/(R T T_e))

For T_e >> T which is typical in the discharge phase, it reduces to (2) :

k_f = A T_e^b \exp (E_{a,e}-E_{a,g}/RT)

This doesn't let you model Ionization and Excitation reactions.

In Kossyi's paper, these reactions are modeled as a function of the reduced electric field
For instance nitrogen ionization below :

image

In a 2-T model you could write them as a function of electron temperature. E/N is proportional to Te in the drift-diffusion approximation. You could convert these to an Arrhenius form, where the temperature is electron temperature :

k_f = A T_e^b \exp (-E_a/RT) \exp (-E_{a,e}/RT_e)

However, the form currently implemented in Cantera won't help.

It seems to be good to model electron attachment and detachment processes, as used by Kosssyi, but unfortunately these are not the main mechanisms in (at least) our plasma-assisted-combustion models.


How hard would it be to add the Electron-temperature Arrhenius form back ?
I'm really not familiar with C so cannot help unfortunately.

Copy link
Contributor Author

@BangShiuh BangShiuh Sep 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$k_f = A T_e^b \exp (-E_{a,g}/RT) \exp (E_{a,e} (T_e - T)/(R T T_e))$
is the same as
$k_f = A T_e^b \exp (-E_{a,g}/RT) \exp (E_{a,e}/(R T)) \exp(-E_{a,e}/(R T_e))$
You need to cancel $\exp (E_{a,e}/(R T))$ by setting $E_{a,g} = E_{a,e}$.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am working on ElectronCollisionPlasmaRate which will use the cross-section data and electron energy distribution function to calculate the reaction rates. Thank you for your interest in this feature! We would like to see more people contribute to this!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. It might be hard to read and slightly slower to compute, but it works so that's enough.

Your end goal is challenging but very helpful. How do you solve the electron energy distribution ? Bolsig / Bolos ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will write an electron Boltzmann equation solver similar to BOLOS in C++.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd use this right-away 👏 🚀

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth an update to the documentation to note this use case of setting $E_{a,g} = E_{a,e}$ to support reactions with the rate expression desired here, since that transformation of the rate expression might not occur to users.

m_Ea_R * shared_data.recipT +
m_EE_R * (shared_data.electronTemp - shared_data.temperature)
* shared_data.recipTe * shared_data.recipT);
}

//! Return the activation energy *Ea* [J/kmol]
double activationEnergy() const {
return m_Ea_R * GasConstant;
}

//! Return the activation energy divided by the gas constant (i.e. the
//! activation temperature) [K]
double activationEnergy_R() const {
return m_Ea_R;
}

//! Return the electron activation energy *Ea* [J/kmol]
double activationElectronEnergy() const {
return m_EE_R * GasConstant;
}

//! Return the electron activation energy divided by the gas constant (i.e. the
//! activation temperature) [K]
double activationElectronEnergy_R() const {
return m_EE_R;
}
protected:
double m_EE_R; //!< Activation electron energy (in temperature units)
};


//! Blowers Masel reaction rate type depends on the enthalpy of reaction
/**
* The Blowers Masel approximation is written by Paul Blowers,
Expand Down
16 changes: 16 additions & 0 deletions include/cantera/kinetics/Reaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,22 @@ class ThreeBodyReaction3 : public ElementaryReaction3
};


//! A reaction for two-temperature-plasma reaction rate
class TwoTempPlasmaReaction: public Reaction
{
public:
TwoTempPlasmaReaction();
TwoTempPlasmaReaction(const Composition& reactants, const Composition& products,
const TwoTempPlasmaRate& rate);

TwoTempPlasmaReaction(const AnyMap& node, const Kinetics& kin);

virtual std::string type() const {
return "two-temperature-plasma";
}
};


//! A reaction with rate parameters for Blowers-Masel approximation
class BlowersMaselReaction: public Reaction
{
Expand Down
28 changes: 28 additions & 0 deletions include/cantera/kinetics/ReactionData.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,34 @@ struct ArrheniusData : public ReactionData
};


//! Data container holding shared data specific to TwoTempPlasmaRate
/**
* The data container `TwoTempPlasmaData` holds precalculated data common to
* all `TwoTempPlasmaRate` objects.
*/
struct TwoTempPlasmaData : public ReactionData
{
TwoTempPlasmaData() : electronTemp(1.), logTe(0.), recipTe(1.) {}

virtual bool update(const ThermoPhase& bulk, const Kinetics& kin) override;

virtual void update(double T) override;

virtual void update(double T, double Te) override;

virtual void updateTe(double Te);

virtual void invalidateCache() override {
ReactionData::invalidateCache();
electronTemp = NAN;
}

double electronTemp; //!< electron temperature
double logTe; //!< logarithm of electron temperature
double recipTe; //!< inverse of electron temperature
};


//! Data container holding shared data specific to BlowersMaselRate
/**
* The data container `BlowersMaselData` holds precalculated data common to
Expand Down
21 changes: 21 additions & 0 deletions include/cantera/thermo/Phase.h
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,12 @@ class Phase
return m_temp;
}

//! Electron Temperature (K)
//! @return The electron temperature of the phase
double electronTemperature() const {
return m_electronTemp;
}

//! Return the thermodynamic pressure (Pa).
/*!
* This method must be overloaded in derived classes. Within %Cantera, the
Expand Down Expand Up @@ -718,6 +724,18 @@ class Phase
"temperature must be positive. T = {}", temp);
}
}

//! Set the internally stored electron temperature of the phase (K).
//! @param etemp Electron temperature in Kelvin
virtual void setElectronTemperature(const double etemp) {
if (etemp > 0) {
m_electronTemp = etemp;
} else {
throw CanteraError("Phase::setElectronTemperature",
"electron temperature must be positive. Te = {}", etemp);
}
}

//! @}

//! @name Mean Properties
Expand Down Expand Up @@ -966,6 +984,9 @@ class Phase

doublereal m_temp; //!< Temperature (K). This is an independent variable

//! Electron Temperature (K).
double m_electronTemp;

//! Density (kg m-3). This is an independent variable except in the case
//! of incompressible phases, where it has to be changed using the
//! assignDensity() method. For compressible substances, the pressure is
Expand Down
14 changes: 14 additions & 0 deletions interfaces/cython/cantera/_cantera.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ cdef extern from "cantera/thermo/ThermoPhase.h" namespace "Cantera":

# basic thermodynamic properties
double temperature() except +translate_exception
double electronTemperature() except +translate_exception
double pressure() except +translate_exception
double density() except +translate_exception
double molarDensity() except +translate_exception
Expand Down Expand Up @@ -322,6 +323,7 @@ cdef extern from "cantera/thermo/ThermoPhase.h" namespace "Cantera":
void setState_VH(double, double) except +translate_exception
void setState_TH(double, double) except +translate_exception
void setState_SH(double, double) except +translate_exception
void setElectronTemperature(double) except +translate_exception

# molar thermodynamic properties:
double enthalpy_mole() except +translate_exception
Expand Down Expand Up @@ -415,6 +417,15 @@ cdef extern from "cantera/kinetics/Reaction.h" namespace "Cantera":
cbool allowNegativePreExponentialFactor()
void setAllowNegativePreExponentialFactor(bool)

cdef cppclass CxxTwoTempPlasmaRate "Cantera::TwoTempPlasmaRate" (CxxReactionRate, CxxArrheniusBase):
CxxTwoTempPlasmaRate()
CxxTwoTempPlasmaRate(CxxAnyMap) except +translate_exception
CxxTwoTempPlasmaRate(double, double, double, double)
double activationEnergy()
double activationElectronEnergy()
cbool allowNegativePreExponentialFactor()
void setAllowNegativePreExponentialFactor(bool)

cdef cppclass CxxBlowersMaselRate "Cantera::BlowersMaselRate" (CxxReactionRate, CxxArrheniusBase):
CxxBlowersMaselRate()
CxxBlowersMaselRate(CxxAnyMap) except +translate_exception
Expand Down Expand Up @@ -599,6 +610,9 @@ cdef extern from "cantera/kinetics/Reaction.h" namespace "Cantera":
CxxThreeBodyReaction3()
shared_ptr[CxxThirdBody] thirdBody()

cdef cppclass CxxTwoTempPlasmaReaction "Cantera::TwoTempPlasmaReaction"(CxxReaction):
CxxTwoTempPlasmaReaction()

cdef cppclass CxxBlowersMaselReaction "Cantera::BlowersMaselReaction"(CxxReaction):
CxxBlowersMaselReaction()

Expand Down
Loading