26 size_t k,
size_t j,
const AnyMap& dep_map
30 enthalpy_coeffs({0.0, 0.0, 0.0, 0.0, 0.0}),
31 entropy_coeffs({0.0, 0.0, 0.0, 0.0, 0.0}),
35 if (dep_map[
"model"] ==
"linear") {
36 if (dep_map.hasKey(
"enthalpy")) {
37 enthalpy_coeffs[1] = dep_map.convert(
"enthalpy",
"J/kmol");
39 if (dep_map.hasKey(
"entropy")) {
40 entropy_coeffs[1] = dep_map.convert(
"entropy",
"J/kmol/K");
44 }
else if (dep_map[
"model"] ==
"polynomial") {
45 if (dep_map.hasKey(
"enthalpy-coefficients")) {
46 enthalpy_coeffs = dep_map.convertVector(
47 "enthalpy-coefficients",
"J/kmol");
48 enthalpy_coeffs.insert(enthalpy_coeffs.begin(), 0.0);
50 if (dep_map.hasKey(
"entropy-coefficients")) {
51 entropy_coeffs = dep_map.convertVector(
52 "entropy-coefficients",
"J/kmol/K");
53 entropy_coeffs.insert(entropy_coeffs.begin(), 0.0);
59 size_t k,
size_t j,
const AnyMap& dep_map,
const AnyBase& node
63 enthalpy_map({{0.0, 0.0}, {1.0, 0.0}}),
64 entropy_map({{0.0, 0.0}, {1.0, 0.0}}),
70 if (dep_map[
"model"] ==
"piecewise-linear") {
71 if (dep_map.hasKey(
"enthalpy-low") ||
72 dep_map.hasKey(
"enthalpy-change") ||
73 dep_map.hasKey(
"enthalpy-high"))
75 auto cov_change = dep_map[
"enthalpy-change"].as<
double>();
76 enthalpy_map[cov_change] =
77 dep_map.convert(
"enthalpy-low",
"J/kmol") * cov_change;
78 enthalpy_map[1.0] = (1.0 - cov_change)
79 * dep_map.convert(
"enthalpy-high",
"J/kmol")
80 + enthalpy_map[cov_change];
82 if (dep_map.hasKey(
"entropy-low") ||
83 dep_map.hasKey(
"entropy-change") ||
84 dep_map.hasKey(
"entropy-high"))
86 auto cov_change = dep_map[
"entropy-change"].as<
double>();
87 entropy_map[cov_change] =
88 dep_map.convert(
"entropy-low",
"J/kmol/K") * cov_change;
89 entropy_map[1.0] = (1.0 - cov_change)
90 * dep_map.convert(
"entropy-high",
"J/kmol/K")
91 + entropy_map[cov_change];
95 }
else if (dep_map[
"model"] ==
"interpolative") {
96 if (dep_map.hasKey(
"enthalpy-coverages") || dep_map.hasKey(
"enthalpies")) {
97 auto hcovs = dep_map[
"enthalpy-coverages"].as<vector<double>>();
98 vector<double> enthalpies = dep_map.convertVector(
"enthalpies",
"J/kmol");
99 if (hcovs.size() != enthalpies.size()) {
100 throw InputFileError(
"CoverageDependentSurfPhase::"
101 "addInterpolativeDependency", node,
102 "Sizes of coverages array and enthalpies array are not equal.");
104 for (
size_t i = 0; i < hcovs.size(); i++) {
105 enthalpy_map[hcovs[i]] = enthalpies[i];
108 if (dep_map.hasKey(
"entropy-coverages") || dep_map.hasKey(
"entropies")) {
109 auto scovs = dep_map[
"entropy-coverages"].as<vector<double>>();
110 vector<double> entropies = dep_map.convertVector(
"entropies",
112 if (scovs.size() != entropies.size()) {
113 throw InputFileError(
"CoverageDependentSurfPhase::"
114 "addInterpolativeDependency", node,
115 "Sizes of coverages array and entropies array are not equal.");
117 for (
size_t i = 0; i < scovs.size(); i++) {
118 entropy_map[scovs[i]] = entropies[i];
137 throw CanteraError(
"CoverageDependentSurfPhase::addInterpolativeDependency",
138 "The first element of enthalpy-coverages array must be 0.0.");
141 throw CanteraError(
"CoverageDependentSurfPhase::addInterpolativeDependency",
142 "The last element of enthalpy-coverages array must be 1.0.");
146 throw CanteraError(
"CoverageDependentSurfPhase::addInterpolativeDependency",
147 "The first element of entropy-coverages array must be 0.0.");
150 throw CanteraError(
"CoverageDependentSurfPhase::addInterpolativeDependency",
151 "The last element of entropy-coverages array must be 1.0.");
162 if (m_theta_ref <= 0.0 || m_theta_ref > 1.0) {
164 m_input,
"Reference state coverage must be greater than 0.0 and \
165 less than or equal to 1.0.");
168 for (
auto& item : m_species) {
172 if (item.second->input.hasKey(
"coverage-dependencies")) {
173 auto& cov_map = item.second->input[
"coverage-dependencies"];
174 for (
const auto& item2 : cov_map) {
179 item.second->input,
"Unknown species '{}'.", item.first);
183 item.second->input,
"Unknown species '{}'.", item2.first);
185 auto& dep_map = item2.second.as<
AnyMap>();
187 if (dep_map[
"model"] ==
"linear" || dep_map[
"model"] ==
"polynomial") {
191 }
else if (dep_map[
"model"] ==
"piecewise-linear" ||
192 dep_map[
"model"] ==
"interpolative") {
198 item.second->input,
"Unrecognized coverage dependency model. \
199 Model must be 'linear', 'piecewise-linear', 'polynomial', \
200 or 'interpolative'.");
203 if (dep_map.hasKey(
"heat-capacity-a")) {
205 cpcov_deps.
coeff_a = dep_map.convert(
"heat-capacity-a",
"J/kmol/K");
206 cpcov_deps.
coeff_b = dep_map.convert(
"heat-capacity-b",
"J/kmol/K");
219 m_cov.push_back(0.0);
235 phaseNode[
"reference-state-coverage"] =
m_theta_ref;
239 AnyMap& speciesNode)
const
248 speciesNode[
"coverage-dependencies"][
speciesName(item.j)]
249 .getMapWhere(
"model",
"linear",
true);
250 covdepNode[
"enthalpy"].setQuantity(item.enthalpy_coeffs[1],
"J/kmol");
251 covdepNode[
"entropy"].setQuantity(item.entropy_coeffs[1],
"J/kmol/K");
254 speciesNode[
"coverage-dependencies"][
speciesName(item.j)]
255 .getMapWhere(
"model",
"polynomial",
true);
256 vector<double> hvec (
257 item.enthalpy_coeffs.begin() + 1, item.enthalpy_coeffs.end());
258 covdepNode[
"enthalpy-coefficients"].setQuantity(hvec,
"J/kmol");
259 vector<double> svec (
260 item.entropy_coeffs.begin() + 1, item.entropy_coeffs.end());
261 covdepNode[
"entropy-coefficients"].setQuantity(svec,
"J/kmol/K");
268 if (item.isPiecewise) {
270 speciesNode[
"coverage-dependencies"][
speciesName(item.j)]
271 .getMapWhere(
"model",
"piecewise-linear",
true);
272 vector<double> hcovs, enthalpies, scovs, entropies;
273 for (
const auto& hmap : item.enthalpy_map) {
274 hcovs.push_back(hmap.first);
275 enthalpies.push_back(hmap.second);
277 for (
const auto& smap : item.entropy_map) {
278 scovs.push_back(smap.first);
279 entropies.push_back(smap.second);
281 covdepNode[
"enthalpy-change"] = hcovs[1];
282 covdepNode[
"enthalpy-low"].setQuantity(
283 (enthalpies[1] - enthalpies[0]) / (hcovs[1] - hcovs[0]),
"J/kmol");
284 covdepNode[
"enthalpy-high"].setQuantity(
285 (enthalpies[2] - enthalpies[1]) / (hcovs[2] - hcovs[1]),
"J/kmol");
286 covdepNode[
"entropy-change"] = scovs[1];
287 covdepNode[
"entropy-low"].setQuantity(
288 (entropies[1] - entropies[0]) / (scovs[1] - scovs[0]),
"J/kmol/K");
289 covdepNode[
"entropy-high"].setQuantity(
290 (entropies[2] - entropies[1]) / (scovs[2] - scovs[1]),
"J/kmol/K");
293 speciesNode[
"coverage-dependencies"][
speciesName(item.j)]
294 .getMapWhere(
"model",
"interpolative",
true);
295 vector<double> hcovs, enthalpies, scovs, entropies;
296 for (
const auto& hmap : item.enthalpy_map) {
297 hcovs.push_back(hmap.first);
298 enthalpies.push_back(hmap.second);
300 for (
const auto& smap : item.entropy_map) {
301 scovs.push_back(smap.first);
302 entropies.push_back(smap.second);
304 covdepNode[
"enthalpy-coverages"] = std::move(hcovs);
305 covdepNode[
"enthalpies"].setQuantity(enthalpies,
"J/kmol");
306 covdepNode[
"entropy-coverages"] = std::move(scovs);
307 covdepNode[
"entropies"].setQuantity(entropies,
"J/kmol/K");
315 speciesNode[
"coverage-dependencies"][
speciesName(item.j)]
316 .getMapWhere(
"heat-capacity-a",
"",
true);
317 covdepNode[
"heat-capacity-a"].setQuantity(item.coeff_a,
"J/kmol/K");
318 covdepNode[
"heat-capacity-b"].setQuantity(item.coeff_b,
"J/kmol/K");
359 for (
size_t k = 0; k <
m_kk; k++) {
377 for (
size_t k = 0; k <
m_kk; k++) {
386 for (
size_t k = 0; k <
m_kk; k++) {
397 for (
size_t k = 0; k <
m_kk; k++) {
413 for (
size_t k = 0; k <
m_kk; k++) {
428 for (
size_t k = 0; k <
m_kk; k++) {
442 double entropy = 0.0;
443 for (
size_t k = 0; k <
m_kk; k++) {
461 for (
size_t k = 0; k <
m_kk; k++) {
476 auto h_iter = item.enthalpy_map.upper_bound(
m_cov[item.j]);
477 auto s_iter = item.entropy_map.upper_bound(
m_cov[item.j]);
479 "CoverageDependentSurfPhase::_updateCovDepThermo",
480 "Coverage out of range: {}",
m_cov[item.j]);
482 "CoverageDependentSurfPhase::_updateCovDepThermo",
483 "Coverage out of range: {}",
m_cov[item.j]);
485 "CoverageDependentSurfPhase::_updateCovDepThermo",
486 "Coverage out of range: {}",
m_cov[item.j]);
488 "CoverageDependentSurfPhase::_updateCovDepThermo",
489 "Coverage out of range: {}",
m_cov[item.j]);
491 double highHcov = h_iter->first;
492 double highH = h_iter->second;
493 double lowHcov = (--h_iter)->first;
494 double lowH = h_iter->second;
496 double highScov = s_iter->first;
497 double highS = s_iter->second;
498 double lowScov = (--s_iter)->first;
499 double lowS = s_iter->second;
501 m_h_cov[item.k] += (highH - lowH) / (highHcov - lowHcov)
502 * (
m_cov[item.j] - lowHcov) + lowH;
504 m_s_cov[item.k] += (highS - lowS) / (highScov - lowScov)
505 * (
m_cov[item.j] - lowScov) + lowS;
510 double a = item.coeff_a;
511 double b = item.coeff_b;
513 double int_cp_tnow = tnow * (a * log(tnow) - a + b);
514 double int_cp_298 = 298.15 * (a * log(298.15) - a + b);
515 m_h_cov[item.k] += (int_cp_tnow - int_cp_298) *
m_cov[item.j]
517 double int_cp_T_tnow = log(tnow) * (a * log(tnow) + 2 * b);
518 double int_cp_T_298 = log(298.15) * (a * log(298.15) + 2 * b);
519 m_s_cov[item.k] += 0.5 * (int_cp_T_tnow - int_cp_T_298) *
m_cov[item.j]
523 for (
size_t k = 0; k <
m_kk; k++) {
535 for (
size_t k = 0; k <
m_kk; k++) {
Header for a thermodynamics model of a coverage-dependent surface phase derived from SurfPhase,...
Declaration for class Cantera::Species.
Header for a simple thermodynamics model of a surface phase derived from ThermoPhase,...
Headers for the factory class that can create known ThermoPhase objects (see Thermodynamic Properties...
Base class defining common data possessed by both AnyMap and AnyValue objects.
A map of string keys to values whose type can vary at runtime.
bool hasKey(const string &key) const
Returns true if the map contains an item named key.
Base class for exceptions thrown by Cantera classes.
void getStandardChemPotentials(double *mu0) const override
Get the standard state chemical potential vector. Units: J/kmol.
void getPureGibbs(double *g) const override
Get the standard state gibbs free energy vector. Units: J/kmol.
double enthalpy_mole() const override
Return the solution's molar enthalpy. Units: J/kmol.
vector< double > m_entropy
Temporary storage for the sum of reference state entropies and coverage-dependent entropies.
vector< InterpolativeDependency > m_InterpolativeDependency
Array of enthalpy and entropy coverage dependency parameters used in the piecewise-linear and interpo...
void getPartialMolarEnthalpies(double *hbar) const override
Get the partial molar enthalpy vector. Units: J/kmol.
void getChemPotentials(double *mu) const override
Get the chemical potential vector. Units: J/kmol.
void getSpeciesParameters(const string &name, AnyMap &speciesNode) const override
Get phase-specific parameters of a Species object such that an identical one could be reconstructed a...
void getEntropy_R(double *sr) const override
Get the nondimensionalized standard state entropy vector.
CoverageDependentSurfPhase(const string &infile="", const string &id="")
Construct and initialize a CoverageDependentSurfPhase ThermoPhase object directly from an ASCII input...
vector< double > m_enthalpy
Temporary storage for the sum of reference state enthalpies and coverage-dependent enthalpies.
vector< HeatCapacityDependency > m_HeatCapacityDependency
Array of heat capacity coverage dependency parameters.
void getCp_R_ref(double *cpr) const override
Returns the vector of nondimensional constant pressure heat capacities of the reference state at the ...
void getCp_R(double *cpr) const override
Get the nondimensionalized standard state heat capacity vector.
void getParameters(AnyMap &phaseNode) const override
Store the parameters of a ThermoPhase object such that an identical one could be reconstructed using ...
void initThermo() override
Initialize the ThermoPhase object after all species have been set up.
vector< double > m_h_cov
Temporary storage for the coverage-dependent enthalpies.
void getEntropy_R_ref(double *sr) const override
Returns the vector of nondimensional entropies of the reference state at the current temperature of t...
int m_stateNumlast
Last value of the state number processed.
vector< double > m_chempot
Temporary storage for the sum of reference state chemical potentials and coverage-dependent chemical ...
void addInterpolativeDependency(const InterpolativeDependency &int_deps)
Add interpolative coverage dependence parameters for a species.
vector< double > m_heatcapacity
Temporary storage for the sum of reference state heat capacities and coverage-dependent heat capaciti...
void _updateTotalThermo() const
Update the total (reference state + coverage-dependent) thermodynamic functions.
void getEnthalpy_RT(double *hrt) const override
Get the nondimensionalized standard state enthalpy vector.
double m_theta_ref
Storage for the user-defined reference state coverage which has to be greater than 0....
void _updateCovDepThermo() const
Update the species coverage-dependent thermodynamic functions.
void getGibbs_RT(double *grt) const override
Get the nondimensionalized standard state gibbs free energy vector.
double entropy_mole() const override
Return the solution's molar entropy. Units: J/kmol/K.
vector< double > m_mu_cov
Temporary storage for the coverage-dependent chemical potentials.
vector< double > m_s_cov
Temporary storage for the coverage-dependent entropies.
double cp_mole() const override
Return the solution's molar heat capacity. Units: J/kmol/K.
vector< double > m_cov
Temporary storage for the coverages.
void getPartialMolarCp(double *cpbar) const override
Get the partial molar heat capacity vector. Units: J/kmol/K.
bool addSpecies(shared_ptr< Species > spec) override
Add a Species to this Phase.
void getGibbs_RT_ref(double *grt) const override
Returns the vector of nondimensional Gibbs Free Energies of the reference state at the current temper...
vector< PolynomialDependency > m_PolynomialDependency
Array of enthalpy and entropy coverage dependency parameters used in the linear and polynomial depend...
vector< double > m_cp_cov
Temporary storage for the coverage-dependent heat capacities.
void getPartialMolarEntropies(double *sbar) const override
Get the partial molar entropy vector. Units: J/kmol/K.
void getEnthalpy_RT_ref(double *hrt) const override
Returns the vector of nondimensional enthalpies of the reference state at the current temperature of ...
void setNDim(size_t ndim)
Set the number of spatial dimensions (1, 2, or 3).
size_t m_kk
Number of species in the phase.
double temperature() const
Temperature (K).
string speciesName(size_t k) const
Name of the species with index k.
size_t speciesIndex(const string &name) const
Returns the index of a species named 'name' within the Phase object.
double moleFraction(size_t k) const
Return the mole fraction of a single species.
int stateMFNumber() const
Return the State Mole Fraction Number.
double mean_X(const double *const Q) const
Evaluate the mole-fraction-weighted mean of an array Q.
string name() const
Return the name of the phase.
void getParameters(AnyMap &phaseNode) const override
Store the parameters of a ThermoPhase object such that an identical one could be reconstructed using ...
void initThermo() override
Initialize the ThermoPhase object after all species have been set up.
vector< double > m_h0
Temporary storage for the reference state enthalpies.
vector< double > m_s0
Temporary storage for the reference state entropies.
vector< double > m_cp0
Temporary storage for the reference state heat capacities.
void _updateThermo(bool force=false) const
Update the species reference state thermodynamic functions.
void getCoverages(double *theta) const
Return a vector of surface coverages.
vector< double > m_mu0
Temporary storage for the reference state Gibbs energies.
bool addSpecies(shared_ptr< Species > spec) override
Add a Species to this Phase.
double RT() const
Return the Gas Constant multiplied by the current temperature.
double m_tlast
last value of the temperature processed by reference state
void initThermoFile(const string &inputFile, const string &id)
Initialize a ThermoPhase object using an input file.
virtual void getSpeciesParameters(const string &name, AnyMap &speciesNode) const
Get phase-specific parameters of a Species object such that an identical one could be reconstructed a...
AnyMap m_input
Data supplied via setParameters.
#define AssertThrowMsg(expr, procedure,...)
Assertion must be true or an error is thrown.
R poly4(D x, R *c)
Evaluates a polynomial of order 4.
void scale(InputIter begin, InputIter end, OutputIter out, S scale_factor)
Multiply elements of an array by a scale factor.
const double GasConstant
Universal Gas Constant [J/kmol/K].
Namespace for the Cantera kernel.
const size_t npos
index returned by functions to indicate "no position"
const double SmallNumber
smallest number to compare to zero.
Contains declarations for string manipulation functions within Cantera.
A struct to store sets of parameters used in coverage-dependent heat capacity calculations by a log-q...
double coeff_a
coefficient [J/kmol/K] in the coverage-dependent heat capacity model
double coeff_b
coefficient [J/kmol/K] in the coverage-dependent heat capacity model
A struct to store sets of parameters used in coverage-dependent enthalpy and entropy calculations by ...
map< double, double > enthalpy_map
map of <coverage[dimensionless], enthalpy[J/kmol]> pairs
map< double, double > entropy_map
map of <coverage[dimensionless], entropy[J/kmol/K]> pairs
InterpolativeDependency(size_t k, size_t j, const AnyMap &dep_map, const AnyBase &node)
A struct to store sets of parameters used in coverage-dependent enthalpy and entropy calculations by ...
PolynomialDependency(size_t k, size_t j, const AnyMap &dep_map)
Various templated functions that carry out common vector and polynomial operations (see Templated Arr...