Cantera 2.6.0

RedlichKisterVPSSTP.cpp
Go to the documentation of this file.
1/**
2 * @file RedlichKisterVPSSTP.cpp
3 * Definitions for ThermoPhase object for phases which
4 * employ excess Gibbs free energy formulations related to RedlichKister
5 * expansions (see \ref thermoprops
6 * and class \link Cantera::RedlichKisterVPSSTP RedlichKisterVPSSTP\endlink).
7 */
8
9// This file is part of Cantera. See License.txt in the top-level directory or
10// at https://cantera.org/license.txt for license and copyright information.
11
12#include "cantera/thermo/RedlichKisterVPSSTP.h"
13#include "cantera/thermo/ThermoFactory.h"
14#include "cantera/base/stringUtils.h"
15#include "cantera/base/ctml.h"
16
17 using namespace std;
18
19 namespace Cantera
20{
21 RedlichKisterVPSSTP::RedlichKisterVPSSTP(const std::string& inputFile,
22 const std::string& id_) :
23 numBinaryInteractions_(0),
24 formRedlichKister_(0),
25 formTempModel_(0)
26{
27 initThermoFile(inputFile, id_);
28}
29
30 RedlichKisterVPSSTP::RedlichKisterVPSSTP(XML_Node& phaseRoot,
31 const std::string& id_) :
32 numBinaryInteractions_(0),
33 formRedlichKister_(0),
34 formTempModel_(0)
35{
36 importPhase(phaseRoot, this);
37}
38
39// - Activities, Standard States, Activity Concentrations -----------
40
41 void RedlichKisterVPSSTP::getLnActivityCoefficients(doublereal* lnac) const
42{
43 // Update the activity coefficients
44 s_update_lnActCoeff();
45
46 for (size_t k = 0; k < m_kk; k++) {
47 lnac[k] = lnActCoeff_Scaled_[k];
48 }
49}
50
51// ------------ Partial Molar Properties of the Solution ------------
52
53 void RedlichKisterVPSSTP::getChemPotentials(doublereal* mu) const
54{
55 // First get the standard chemical potentials in molar form. This requires
56 // updates of standard state as a function of T and P
57 getStandardChemPotentials(mu);
58 // Update the activity coefficients
59 s_update_lnActCoeff();
60
61 for (size_t k = 0; k < m_kk; k++) {
62 double xx = std::max(moleFractions_[k], SmallNumber);
63 mu[k] += RT() * (log(xx) + lnActCoeff_Scaled_[k]);
64 }
65}
66
67doublereal RedlichKisterVPSSTP::enthalpy_mole() const
68{
69 double h = 0;
70 vector_fp hbar(m_kk);
71 getPartialMolarEnthalpies(&hbar[0]);
72 for (size_t i = 0; i < m_kk; i++) {
73 h += moleFractions_[i]*hbar[i];
74 }
75 return h;
76}
77
78doublereal RedlichKisterVPSSTP::entropy_mole() const
79{
80 double s = 0;
81 vector_fp sbar(m_kk);
82 getPartialMolarEntropies(&sbar[0]);
83 for (size_t i = 0; i < m_kk; i++) {
84 s += moleFractions_[i]*sbar[i];
85 }
86 return s;
87}
88
89doublereal RedlichKisterVPSSTP::cp_mole() const
90{
91 double cp = 0;
92 vector_fp cpbar(m_kk);
93 getPartialMolarCp(&cpbar[0]);
94 for (size_t i = 0; i < m_kk; i++) {
95 cp += moleFractions_[i]*cpbar[i];
96 }
97 return cp;
98}
99
100doublereal RedlichKisterVPSSTP::cv_mole() const
101{
102 return cp_mole() - GasConstant;
103}
104
105 void RedlichKisterVPSSTP::getPartialMolarEnthalpies(doublereal* hbar) const
106{
107 // Get the nondimensional standard state enthalpies
108 getEnthalpy_RT(hbar);
109 // dimensionalize it.
110 double T = temperature();
111 for (size_t k = 0; k < m_kk; k++) {
112 hbar[k] *= GasConstant * T;
113 }
114
115 // Update the activity coefficients, This also update the internally stored
116 // molalities.
117 s_update_lnActCoeff();
118 s_update_dlnActCoeff_dT();
119 for (size_t k = 0; k < m_kk; k++) {
120 hbar[k] -= GasConstant * T * T * dlnActCoeffdT_Scaled_[k];
121 }
122}
123
124 void RedlichKisterVPSSTP::getPartialMolarCp(doublereal* cpbar) const
125{
126 getCp_R(cpbar);
127 double T = temperature();
128
129 // Update the activity coefficients, This also update the internally stored
130 // molalities.
131 s_update_lnActCoeff();
132 s_update_dlnActCoeff_dT();
133
134 for (size_t k = 0; k < m_kk; k++) {
135 cpbar[k] -= 2 * T * dlnActCoeffdT_Scaled_[k] + T * T * d2lnActCoeffdT2_Scaled_[k];
136 }
137 // dimensionalize it.
138 for (size_t k = 0; k < m_kk; k++) {
139 cpbar[k] *= GasConstant;
140 }
141}
142
143 void RedlichKisterVPSSTP::getPartialMolarEntropies(doublereal* sbar) const
144{
145 // Get the nondimensional standard state entropies
146 getEntropy_R(sbar);
147 double T = temperature();
148
149 // Update the activity coefficients, This also update the internally stored
150 // molalities.
151 s_update_lnActCoeff();
152 s_update_dlnActCoeff_dT();
153
154 for (size_t k = 0; k < m_kk; k++) {
155 double xx = std::max(moleFractions_[k], SmallNumber);
156 sbar[k] += - lnActCoeff_Scaled_[k] -log(xx) - T * dlnActCoeffdT_Scaled_[k];
157 }
158 // dimensionalize it.
159 for (size_t k = 0; k < m_kk; k++) {
160 sbar[k] *= GasConstant;
161 }
162}
163
164 void RedlichKisterVPSSTP::getPartialMolarVolumes(doublereal* vbar) const
165{
166 // Get the standard state values in m^3 kmol-1
167 getStandardVolumes(vbar);
168 for (size_t iK = 0; iK < m_kk; iK++) {
169 vbar[iK] += 0.0;
170 }
171}
172
173 void RedlichKisterVPSSTP::initThermo()
174{
175 if (m_input.hasKey("interactions")) {
176 for (const auto& item : m_input["interactions"].asVector<AnyMap>()) {
177 auto& species = item["species"].asVector<string>(2);
178 vector_fp h_excess = item.convertVector("excess-enthalpy", "J/kmol");
179 vector_fp s_excess = item.convertVector("excess-entropy", "J/kmol/K");
180 addBinaryInteraction(species[0], species[1],
181 h_excess.data(), h_excess.size(),
182 s_excess.data(), s_excess.size());
183 }
184 }
185 initLengths();
186 GibbsExcessVPSSTP::initThermo();
187}
188
189 void RedlichKisterVPSSTP::getParameters(AnyMap& phaseNode) const
190{
191 GibbsExcessVPSSTP::getParameters(phaseNode);
192 vector<AnyMap> interactions;
193 for (size_t n = 0; n < m_pSpecies_A_ij.size(); n++) {
194 AnyMap interaction;
195 interaction["species"] = vector<std::string>{
196 speciesName(m_pSpecies_A_ij[n]), speciesName(m_pSpecies_B_ij[n])};
197 vector_fp h = m_HE_m_ij[n];
198 vector_fp s = m_SE_m_ij[n];
199 while (h.size() > 1 && h.back() == 0) {
200 h.pop_back();
201 }
202 while (s.size() > 1 && s.back() == 0) {
203 s.pop_back();
204 }
205 interaction["excess-enthalpy"].setQuantity(std::move(h), "J/kmol");
206 interaction["excess-entropy"].setQuantity(std::move(s), "J/kmol/K");
207 interactions.push_back(std::move(interaction));
208 }
209 phaseNode["interactions"] = std::move(interactions);
210}
211
212 void RedlichKisterVPSSTP::initLengths()
213{
214 dlnActCoeffdlnN_.resize(m_kk, m_kk);
215}
216
217 void RedlichKisterVPSSTP::initThermoXML(XML_Node& phaseNode, const std::string& id_)
218{
219 if ((int) id_.size() > 0 && phaseNode.id() != id_) {
220 throw CanteraError("RedlichKisterVPSSTP::initThermoXML",
221 "phasenode and Id are incompatible");
222 }
223
224 // Check on the thermo field. Must have:
225 // <thermo model="Redlich-Kister" />
226 if (!phaseNode.hasChild("thermo")) {
227 throw CanteraError("RedlichKisterVPSSTP::initThermoXML",
228 "no thermo XML node");
229 }
230 XML_Node& thermoNode = phaseNode.child("thermo");
231 if (!caseInsensitiveEquals(thermoNode["model"], "redlich-kister")) {
232 throw CanteraError("RedlichKisterVPSSTP::initThermoXML",
233 "Unknown thermo model: " + thermoNode["model"]
234 + " - This object only knows \"Redlich-Kister\" ");
235 }
236
237 // Go get all of the coefficients and factors in the activityCoefficients
238 // XML block
239 if (thermoNode.hasChild("activityCoefficients")) {
240 XML_Node& acNode = thermoNode.child("activityCoefficients");
241 if (!caseInsensitiveEquals(acNode["model"], "redlich-kister")) {
242 throw CanteraError("RedlichKisterVPSSTP::initThermoXML",
243 "Unknown activity coefficient model: " + acNode["model"]);
244 }
245 for (size_t i = 0; i < acNode.nChildren(); i++) {
246 XML_Node& xmlACChild = acNode.child(i);
247
248 // Process a binary salt field, or any of the other XML fields that
249 // make up the Pitzer Database. Entries will be ignored if any of
250 // the species in the entry isn't in the solution.
251 if (caseInsensitiveEquals(xmlACChild.name(), "binaryneutralspeciesparameters")) {
252 readXMLBinarySpecies(xmlACChild);
253 }
254 }
255 }
256 // Go down the chain
257 GibbsExcessVPSSTP::initThermoXML(phaseNode, id_);
258}
259
260 void RedlichKisterVPSSTP::s_update_lnActCoeff() const
261{
262 doublereal T = temperature();
263 lnActCoeff_Scaled_.assign(m_kk, 0.0);
264
265 // Scaling: I moved the division of RT higher so that we are always dealing
266 // with G/RT dimensionless terms within the routine. There is a severe
267 // problem with roundoff error in these calculations. The dimensionless
268 // terms help.
269 for (size_t i = 0; i < numBinaryInteractions_; i++) {
270 size_t iA = m_pSpecies_A_ij[i];
271 size_t iB = m_pSpecies_B_ij[i];
272 double XA = moleFractions_[iA];
273 double XB = moleFractions_[iB];
274 doublereal deltaX = XA - XB;
275 size_t N = m_N_ij[i];
276 vector_fp& he_vec = m_HE_m_ij[i];
277 vector_fp& se_vec = m_SE_m_ij[i];
278 doublereal poly = 1.0;
279 doublereal polyMm1 = 1.0;
280 doublereal sum = 0.0;
281 doublereal sumMm1 = 0.0;
282 doublereal sum2 = 0.0;
283 for (size_t m = 0; m < N; m++) {
284 doublereal A_ge = (he_vec[m] - T * se_vec[m]) / (GasConstant * T);
285 sum += A_ge * poly;
286 sum2 += A_ge * (m + 1) * poly;
287 poly *= deltaX;
288 if (m >= 1) {
289 sumMm1 += (A_ge * polyMm1 * m);
290 polyMm1 *= deltaX;
291 }
292 }
293 doublereal oneMXA = 1.0 - XA;
294 doublereal oneMXB = 1.0 - XB;
295 for (size_t k = 0; k < m_kk; k++) {
296 if (iA == k) {
297 lnActCoeff_Scaled_[k] += (oneMXA * XB * sum) + (XA * XB * sumMm1 * (oneMXA + XB));
298 } else if (iB == k) {
299 lnActCoeff_Scaled_[k] += (oneMXB * XA * sum) + (XA * XB * sumMm1 * (-oneMXB - XA));
300 } else {
301 lnActCoeff_Scaled_[k] += -(XA * XB * sum2);
302 }
303 }
304 // Debug against formula in literature
305 }
306}
307
308 void RedlichKisterVPSSTP::s_update_dlnActCoeff_dT() const
309{
310 dlnActCoeffdT_Scaled_.assign(m_kk, 0.0);
311 d2lnActCoeffdT2_Scaled_.assign(m_kk, 0.0);
312
313 for (size_t i = 0; i < numBinaryInteractions_; i++) {
314 size_t iA = m_pSpecies_A_ij[i];
315 size_t iB = m_pSpecies_B_ij[i];
316 double XA = moleFractions_[iA];
317 double XB = moleFractions_[iB];
318 doublereal deltaX = XA - XB;
319 size_t N = m_N_ij[i];
320 doublereal poly = 1.0;
321 doublereal sum = 0.0;
322 vector_fp& se_vec = m_SE_m_ij[i];
323 doublereal sumMm1 = 0.0;
324 doublereal polyMm1 = 1.0;
325 doublereal sum2 = 0.0;
326 for (size_t m = 0; m < N; m++) {
327 doublereal A_ge = - se_vec[m];
328 sum += A_ge * poly;
329 sum2 += A_ge * (m + 1) * poly;
330 poly *= deltaX;
331 if (m >= 1) {
332 sumMm1 += (A_ge * polyMm1 * m);
333 polyMm1 *= deltaX;
334 }
335 }
336 doublereal oneMXA = 1.0 - XA;
337 doublereal oneMXB = 1.0 - XB;
338 for (size_t k = 0; k < m_kk; k++) {
339 if (iA == k) {
340 dlnActCoeffdT_Scaled_[k] += (oneMXA * XB * sum) + (XA * XB * sumMm1 * (oneMXA + XB));
341 } else if (iB == k) {
342 dlnActCoeffdT_Scaled_[k] += (oneMXB * XA * sum) + (XA * XB * sumMm1 * (-oneMXB - XA));
343 } else {
344 dlnActCoeffdT_Scaled_[k] += -(XA * XB * sum2);
345 }
346 }
347 }
348}
349
350 void RedlichKisterVPSSTP::getdlnActCoeffdT(doublereal* dlnActCoeffdT) const
351{
352 s_update_dlnActCoeff_dT();
353 for (size_t k = 0; k < m_kk; k++) {
354 dlnActCoeffdT[k] = dlnActCoeffdT_Scaled_[k];
355 }
356}
357
358 void RedlichKisterVPSSTP::getd2lnActCoeffdT2(doublereal* d2lnActCoeffdT2) const
359{
360 s_update_dlnActCoeff_dT();
361 for (size_t k = 0; k < m_kk; k++) {
362 d2lnActCoeffdT2[k] = d2lnActCoeffdT2_Scaled_[k];
363 }
364}
365
366 void RedlichKisterVPSSTP::s_update_dlnActCoeff_dlnX_diag() const
367{
368 double T = temperature();
369 dlnActCoeffdlnX_diag_.assign(m_kk, 0.0);
370
371 for (size_t i = 0; i < numBinaryInteractions_; i++) {
372 size_t iA = m_pSpecies_A_ij[i];
373 size_t iB = m_pSpecies_B_ij[i];
374 double XA = moleFractions_[iA];
375 double XB = moleFractions_[iB];
376 double deltaX = XA - XB;
377 size_t N = m_N_ij[i];
378 double poly = 1.0;
379 double sum = 0.0;
380 vector_fp& he_vec = m_HE_m_ij[i];
381 vector_fp& se_vec = m_SE_m_ij[i];
382 double sumMm1 = 0.0;
383 double polyMm1 = 1.0;
384 double polyMm2 = 1.0;
385 double sumMm2 = 0.0;
386 for (size_t m = 0; m < N; m++) {
387 double A_ge = (he_vec[m] - T * se_vec[m]) / (GasConstant * T);;
388 sum += A_ge * poly;
389 poly *= deltaX;
390 if (m >= 1) {
391 sumMm1 += (A_ge * polyMm1 * m);
392 polyMm1 *= deltaX;
393 }
394 if (m >= 2) {
395 sumMm2 += (A_ge * polyMm2 * m * (m - 1.0));
396 polyMm2 *= deltaX;
397 }
398 }
399
400 for (size_t k = 0; k < m_kk; k++) {
401 if (iA == k) {
402 dlnActCoeffdlnX_diag_[k] +=
403 XA * (- (1-XA+XB) * sum + 2*(1.0 - XA) * XB * sumMm1
404 + sumMm1 * (XB * (1 - 2*XA + XB) - XA * (1 - XA + 2*XB))
405 + 2 * XA * XB * sumMm2 * (1.0 - XA + XB));
406 } else if (iB == k) {
407 dlnActCoeffdlnX_diag_[k] +=
408 XB * (- (1-XB+XA) * sum - 2*(1.0 - XB) * XA * sumMm1
409 + sumMm1 * (XA * (2*XB - XA - 1) - XB * (-2*XA + XB - 1))
410 - 2 * XA * XB * sumMm2 * (-XA - 1 + XB));
411 }
412 }
413 }
414}
415
416 void RedlichKisterVPSSTP::s_update_dlnActCoeff_dX_() const
417{
418 doublereal T = temperature();
419 dlnActCoeff_dX_.zero();
420
421 for (size_t i = 0; i < numBinaryInteractions_; i++) {
422 size_t iA = m_pSpecies_A_ij[i];
423 size_t iB = m_pSpecies_B_ij[i];
424 double XA = moleFractions_[iA];
425 double XB = moleFractions_[iB];
426 doublereal deltaX = XA - XB;
427 size_t N = m_N_ij[i];
428 doublereal poly = 1.0;
429 doublereal sum = 0.0;
430 vector_fp& he_vec = m_HE_m_ij[i];
431 vector_fp& se_vec = m_SE_m_ij[i];
432 doublereal sumMm1 = 0.0;
433 doublereal polyMm1 = 1.0;
434 doublereal polyMm2 = 1.0;
435 doublereal sum2 = 0.0;
436 doublereal sum2Mm1 = 0.0;
437 doublereal sumMm2 = 0.0;
438 for (size_t m = 0; m < N; m++) {
439 doublereal A_ge = he_vec[m] - T * se_vec[m];
440 sum += A_ge * poly;
441 sum2 += A_ge * (m + 1) * poly;
442 poly *= deltaX;
443 if (m >= 1) {
444 sumMm1 += (A_ge * polyMm1 * m);
445 sum2Mm1 += (A_ge * polyMm1 * m * (1.0 + m));
446 polyMm1 *= deltaX;
447 }
448 if (m >= 2) {
449 sumMm2 += (A_ge * polyMm2 * m * (m - 1.0));
450 polyMm2 *= deltaX;
451 }
452 }
453
454 for (size_t k = 0; k < m_kk; k++) {
455 if (iA == k) {
456 dlnActCoeff_dX_(k, iA) += (- XB * sum + (1.0 - XA) * XB * sumMm1
457 + XB * sumMm1 * (1.0 - 2.0 * XA + XB)
458 + XA * XB * sumMm2 * (1.0 - XA + XB));
459
460 dlnActCoeff_dX_(k, iB) += ((1.0 - XA) * sum - (1.0 - XA) * XB * sumMm1
461 + XA * sumMm1 * (1.0 + 2.0 * XB - XA)
462 - XA * XB * sumMm2 * (1.0 - XA + XB));
463 } else if (iB == k) {
464 dlnActCoeff_dX_(k, iA) += ((1.0 - XB) * sum + (1.0 - XA) * XB * sumMm1
465 + XB * sumMm1 * (1.0 - 2.0 * XA + XB)
466 + XA * XB * sumMm2 * (1.0 - XA + XB));
467
468 dlnActCoeff_dX_(k, iB) += (- XA * sum - (1.0 - XB) * XA * sumMm1
469 + XA * sumMm1 * (XB - XA - (1.0 - XB))
470 - XA * XB * sumMm2 * (-XA - (1.0 - XB)));
471 } else {
472 dlnActCoeff_dX_(k, iA) += (- XB * sum2 - XA * XB * sum2Mm1);
473 dlnActCoeff_dX_(k, iB) += (- XA * sum2 + XA * XB * sum2Mm1);
474 }
475 }
476 }
477}
478
479 void RedlichKisterVPSSTP::getdlnActCoeffds(const doublereal dTds, const doublereal* const dXds,
480 doublereal* dlnActCoeffds) const
481{
482 s_update_dlnActCoeff_dT();
483 s_update_dlnActCoeff_dX_();
484 for (size_t k = 0; k < m_kk; k++) {
485 dlnActCoeffds[k] = dlnActCoeffdT_Scaled_[k] * dTds;
486 for (size_t j = 0; j < m_kk; j++) {
487 dlnActCoeffds[k] += dlnActCoeff_dX_(k, j) * dXds[j];
488 }
489 }
490}
491
492 void RedlichKisterVPSSTP::getdlnActCoeffdlnN_diag(doublereal* dlnActCoeffdlnN_diag) const
493{
494 s_update_dlnActCoeff_dX_();
495 for (size_t j = 0; j < m_kk; j++) {
496 dlnActCoeffdlnN_diag[j] = dlnActCoeff_dX_(j, j);
497 for (size_t k = 0; k < m_kk; k++) {
498 dlnActCoeffdlnN_diag[k] -= dlnActCoeff_dX_(j, k) * moleFractions_[k];
499 }
500 }
501}
502
503 void RedlichKisterVPSSTP::getdlnActCoeffdlnX_diag(doublereal* dlnActCoeffdlnX_diag) const
504{
505 s_update_dlnActCoeff_dlnX_diag();
506 for (size_t k = 0; k < m_kk; k++) {
507 dlnActCoeffdlnX_diag[k] = dlnActCoeffdlnX_diag_[k];
508 }
509}
510
511 void RedlichKisterVPSSTP::getdlnActCoeffdlnN(const size_t ld, doublereal* dlnActCoeffdlnN)
512{
513 s_update_dlnActCoeff_dX_();
514 double* data = & dlnActCoeffdlnN_(0,0);
515 for (size_t k = 0; k < m_kk; k++) {
516 for (size_t m = 0; m < m_kk; m++) {
517 dlnActCoeffdlnN[ld * k + m] = data[m_kk * k + m];
518 }
519 }
520}
521
522 void RedlichKisterVPSSTP::readXMLBinarySpecies(XML_Node& xmLBinarySpecies)
523{
524 std::string xname = xmLBinarySpecies.name();
525 if (xname != "binaryNeutralSpeciesParameters") {
526 throw CanteraError("RedlichKisterVPSSTP::readXMLBinarySpecies",
527 "Incorrect name for processing this routine: " + xname);
528 }
529 vector_fp hParams, sParams;
530 std::string iName = xmLBinarySpecies.attrib("speciesA");
531 if (iName == "") {
532 throw CanteraError("RedlichKisterVPSSTP::readXMLBinarySpecies", "no speciesA attrib");
533 }
534 std::string jName = xmLBinarySpecies.attrib("speciesB");
535 if (jName == "") {
536 throw CanteraError("RedlichKisterVPSSTP::readXMLBinarySpecies", "no speciesB attrib");
537 }
538
539 // Find the index of the species in the current phase. It's not an error to
540 // not find the species. This means that the interaction doesn't occur for
541 // the current implementation of the phase.
542 size_t iSpecies = speciesIndex(iName);
543 if (iSpecies == npos) {
544 return;
545 }
546 size_t jSpecies = speciesIndex(jName);
547 if (jSpecies == npos) {
548 return;
549 }
550
551 // Ok we have found a valid interaction
552 for (size_t iChild = 0; iChild < xmLBinarySpecies.nChildren(); iChild++) {
553 XML_Node& xmlChild = xmLBinarySpecies.child(iChild);
554 string nodeName = toLowerCopy(xmlChild.name());
555
556 // Process the binary species interaction child elements
557 if (nodeName == "excessenthalpy") {
558 getFloatArray(xmlChild, hParams, true, "toSI", "excessEnthalpy");
559 } else if (nodeName == "excessentropy") {
560 getFloatArray(xmlChild, sParams, true, "toSI", "excessEntropy");
561 }
562 }
563 addBinaryInteraction(iName, jName, hParams.data(), hParams.size(),
564 sParams.data(), sParams.size());
565}
566
567 void RedlichKisterVPSSTP::addBinaryInteraction(
568 const std::string& speciesA, const std::string& speciesB,
569 const double* excess_enthalpy, size_t n_enthalpy,
570 const double* excess_entropy, size_t n_entropy)
571{
572 size_t kA = speciesIndex(speciesA);
573 size_t kB = speciesIndex(speciesB);
574 if (kA == npos) {
575 throw CanteraError("RedlichKisterVPSSTP::addBinaryInteraction",
576 "Species '{}' not present in phase", speciesA);
577 } else if (kB == npos) {
578 throw CanteraError("RedlichKisterVPSSTP::addBinaryInteraction",
579 "Species '{}' not present in phase", speciesB);
580 }
581 if (charge(kA) != 0) {
582 throw CanteraError("RedlichKisterVPSSTP::addBinaryInteraction",
583 "Species '{}' should be neutral", speciesA);
584 } else if (charge(kB) != 0) {
585 throw CanteraError("RedlichKisterVPSSTP::addBinaryInteraction",
586 "Species '{}' should be neutral", speciesB);
587 }
588
589 m_pSpecies_A_ij.push_back(kA);
590 m_pSpecies_B_ij.push_back(kB);
591 m_HE_m_ij.emplace_back(excess_enthalpy, excess_enthalpy + n_enthalpy);
592 m_SE_m_ij.emplace_back(excess_entropy, excess_entropy + n_entropy);
593 size_t N = max(n_enthalpy, n_entropy);
594 m_HE_m_ij.back().resize(N, 0.0);
595 m_SE_m_ij.back().resize(N, 0.0);
596 m_N_ij.push_back(N);
597 dlnActCoeff_dX_.resize(N, N, 0.0);
598 numBinaryInteractions_++;
599}
600
601}
RedlichKisterVPSSTP.h
(see Thermodynamic Properties and class RedlichKisterVPSSTP).
ThermoFactory.h
Headers for the factory class that can create known ThermoPhase objects (see Thermodynamic Properties...
Cantera::AnyMap
A map of string keys to values whose type can vary at runtime.
Definition: AnyMap.h:399
Cantera::AnyMap::hasKey
bool hasKey(const std::string &key) const
Returns true if the map contains an item named key.
Definition: AnyMap.cpp:1406
Cantera::Array2D::zero
void zero()
Set all of the entries to zero.
Definition: Array.h:139
Cantera::Array2D::resize
void resize(size_t n, size_t m, double v=0.0)
Resize the array, and fill the new entries with 'v'.
Definition: Array.cpp:52
Cantera::CanteraError
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:61
Cantera::GibbsExcessVPSSTP::dlnActCoeffdlnN_
Array2D dlnActCoeffdlnN_
Storage for the current derivative values of the gradients with respect to logarithm of the species m...
Definition: GibbsExcessVPSSTP.h:275
Cantera::GibbsExcessVPSSTP::dlnActCoeffdlnX_diag_
vector_fp dlnActCoeffdlnX_diag_
Storage for the current derivative values of the gradients with respect to logarithm of the mole frac...
Definition: GibbsExcessVPSSTP.h:266
Cantera::GibbsExcessVPSSTP::lnActCoeff_Scaled_
vector_fp lnActCoeff_Scaled_
Storage for the current values of the activity coefficients of the species.
Definition: GibbsExcessVPSSTP.h:248
Cantera::GibbsExcessVPSSTP::d2lnActCoeffdT2_Scaled_
vector_fp d2lnActCoeffdT2_Scaled_
Storage for the current derivative values of the gradients with respect to temperature of the log of ...
Definition: GibbsExcessVPSSTP.h:256
Cantera::GibbsExcessVPSSTP::moleFractions_
vector_fp moleFractions_
Storage for the current values of the mole fractions of the species.
Definition: GibbsExcessVPSSTP.h:244
Cantera::GibbsExcessVPSSTP::dlnActCoeffdT_Scaled_
vector_fp dlnActCoeffdT_Scaled_
Storage for the current derivative values of the gradients with respect to temperature of the log of ...
Definition: GibbsExcessVPSSTP.h:252
Cantera::Phase::charge
doublereal charge(size_t k) const
Dimensionless electrical charge of a single molecule of species k The charge is normalized by the the...
Definition: Phase.h:630
Cantera::Phase::m_kk
size_t m_kk
Number of species in the phase.
Definition: Phase.h:943
Cantera::Phase::speciesName
std::string speciesName(size_t k) const
Name of the species with index k.
Definition: Phase.cpp:200
Cantera::Phase::temperature
doublereal temperature() const
Temperature (K).
Definition: Phase.h:654
Cantera::Phase::speciesIndex
size_t speciesIndex(const std::string &name) const
Returns the index of a species named 'name' within the Phase object.
Definition: Phase.cpp:187
Cantera::Phase::species
shared_ptr< Species > species(const std::string &name) const
Return the Species object for the named species.
Definition: Phase.cpp:950
Cantera::RedlichKisterVPSSTP::s_update_dlnActCoeff_dX_
void s_update_dlnActCoeff_dX_() const
Internal routine that calculates the derivative of the activity coefficients wrt the mole fractions.
Definition: RedlichKisterVPSSTP.cpp:416
Cantera::RedlichKisterVPSSTP::getParameters
virtual void getParameters(AnyMap &phaseNode) const
Store the parameters of a ThermoPhase object such that an identical one could be reconstructed using ...
Definition: RedlichKisterVPSSTP.cpp:189
Cantera::RedlichKisterVPSSTP::dlnActCoeff_dX_
Array2D dlnActCoeff_dX_
Two dimensional array of derivatives of activity coefficients wrt mole fractions.
Definition: RedlichKisterVPSSTP.h:474
Cantera::RedlichKisterVPSSTP::getd2lnActCoeffdT2
virtual void getd2lnActCoeffdT2(doublereal *d2lnActCoeffdT2) const
Get the array of temperature second derivatives of the log activity coefficients.
Definition: RedlichKisterVPSSTP.cpp:358
Cantera::RedlichKisterVPSSTP::getLnActivityCoefficients
virtual void getLnActivityCoefficients(doublereal *lnac) const
Get the array of non-dimensional molar-based ln activity coefficients at the current solution tempera...
Definition: RedlichKisterVPSSTP.cpp:41
Cantera::RedlichKisterVPSSTP::cp_mole
virtual doublereal cp_mole() const
Molar heat capacity at constant pressure. Units: J/kmol/K.
Definition: RedlichKisterVPSSTP.cpp:89
Cantera::RedlichKisterVPSSTP::getPartialMolarEnthalpies
virtual void getPartialMolarEnthalpies(doublereal *hbar) const
Returns an array of partial molar enthalpies for the species in the mixture.
Definition: RedlichKisterVPSSTP.cpp:105
Cantera::RedlichKisterVPSSTP::getPartialMolarEntropies
virtual void getPartialMolarEntropies(doublereal *sbar) const
Returns an array of partial molar entropies for the species in the mixture.
Definition: RedlichKisterVPSSTP.cpp:143
Cantera::RedlichKisterVPSSTP::RedlichKisterVPSSTP
RedlichKisterVPSSTP(const std::string &inputFile="", const std::string &id="")
Construct a RedlichKisterVPSSTP object from an input file.
Definition: RedlichKisterVPSSTP.cpp:21
Cantera::RedlichKisterVPSSTP::getdlnActCoeffdT
virtual void getdlnActCoeffdT(doublereal *dlnActCoeffdT) const
Get the array of temperature derivatives of the log activity coefficients.
Definition: RedlichKisterVPSSTP.cpp:350
Cantera::RedlichKisterVPSSTP::numBinaryInteractions_
size_t numBinaryInteractions_
number of binary interaction expressions
Definition: RedlichKisterVPSSTP.h:436
Cantera::RedlichKisterVPSSTP::initThermoXML
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
Definition: RedlichKisterVPSSTP.cpp:217
Cantera::RedlichKisterVPSSTP::enthalpy_mole
virtual doublereal enthalpy_mole() const
Molar enthalpy. Units: J/kmol.
Definition: RedlichKisterVPSSTP.cpp:67
Cantera::RedlichKisterVPSSTP::getPartialMolarVolumes
virtual void getPartialMolarVolumes(doublereal *vbar) const
Return an array of partial molar volumes for the species in the mixture.
Definition: RedlichKisterVPSSTP.cpp:164
Cantera::RedlichKisterVPSSTP::m_HE_m_ij
std::vector< vector_fp > m_HE_m_ij
Enthalpy term for the binary mole fraction interaction of the excess Gibbs free energy expression.
Definition: RedlichKisterVPSSTP.h:457
Cantera::RedlichKisterVPSSTP::getdlnActCoeffdlnN
virtual void getdlnActCoeffdlnN(const size_t ld, doublereal *const dlnActCoeffdlnN)
Get the array of derivatives of the log activity coefficients with respect to the log of the species ...
Definition: RedlichKisterVPSSTP.cpp:511
Cantera::RedlichKisterVPSSTP::readXMLBinarySpecies
void readXMLBinarySpecies(XML_Node &xmlBinarySpecies)
Process an XML node called "binaryNeutralSpeciesParameters".
Definition: RedlichKisterVPSSTP.cpp:522
Cantera::RedlichKisterVPSSTP::m_N_ij
std::vector< size_t > m_N_ij
Vector of the length of the polynomial for the interaction.
Definition: RedlichKisterVPSSTP.h:453
Cantera::RedlichKisterVPSSTP::cv_mole
virtual doublereal cv_mole() const
Molar heat capacity at constant volume. Units: J/kmol/K.
Definition: RedlichKisterVPSSTP.cpp:100
Cantera::RedlichKisterVPSSTP::getdlnActCoeffdlnX_diag
virtual void getdlnActCoeffdlnX_diag(doublereal *dlnActCoeffdlnX_diag) const
Get the array of ln mole fraction derivatives of the log activity coefficients - diagonal component o...
Definition: RedlichKisterVPSSTP.cpp:503
Cantera::RedlichKisterVPSSTP::getPartialMolarCp
virtual void getPartialMolarCp(doublereal *cpbar) const
Returns an array of partial molar entropies for the species in the mixture.
Definition: RedlichKisterVPSSTP.cpp:124
Cantera::RedlichKisterVPSSTP::m_pSpecies_A_ij
std::vector< size_t > m_pSpecies_A_ij
vector of species indices representing species A in the interaction
Definition: RedlichKisterVPSSTP.h:443
Cantera::RedlichKisterVPSSTP::s_update_dlnActCoeff_dT
void s_update_dlnActCoeff_dT() const
Update the derivative of the log of the activity coefficients wrt T.
Definition: RedlichKisterVPSSTP.cpp:308
Cantera::RedlichKisterVPSSTP::entropy_mole
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol/K.
Definition: RedlichKisterVPSSTP.cpp:78
Cantera::RedlichKisterVPSSTP::initThermo
virtual void initThermo()
Definition: RedlichKisterVPSSTP.cpp:173
Cantera::RedlichKisterVPSSTP::getdlnActCoeffdlnN_diag
virtual void getdlnActCoeffdlnN_diag(doublereal *dlnActCoeffdlnN_diag) const
Get the array of log species mole number derivatives of the log activity coefficients.
Definition: RedlichKisterVPSSTP.cpp:492
Cantera::RedlichKisterVPSSTP::getdlnActCoeffds
virtual void getdlnActCoeffds(const doublereal dTds, const doublereal *const dXds, doublereal *dlnActCoeffds) const
Get the change in activity coefficients wrt changes in state (temp, mole fraction,...
Definition: RedlichKisterVPSSTP.cpp:479
Cantera::RedlichKisterVPSSTP::m_pSpecies_B_ij
std::vector< size_t > m_pSpecies_B_ij
vector of species indices representing species B in the interaction
Definition: RedlichKisterVPSSTP.h:450
Cantera::RedlichKisterVPSSTP::initLengths
void initLengths()
Initialize lengths of local variables after all species have been identified.
Definition: RedlichKisterVPSSTP.cpp:212
Cantera::RedlichKisterVPSSTP::s_update_dlnActCoeff_dlnX_diag
void s_update_dlnActCoeff_dlnX_diag() const
Internal routine that calculates the total derivative of the activity coefficients with respect to th...
Definition: RedlichKisterVPSSTP.cpp:366
Cantera::RedlichKisterVPSSTP::s_update_lnActCoeff
void s_update_lnActCoeff() const
Update the activity coefficients.
Definition: RedlichKisterVPSSTP.cpp:260
Cantera::RedlichKisterVPSSTP::getChemPotentials
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
Definition: RedlichKisterVPSSTP.cpp:53
Cantera::RedlichKisterVPSSTP::m_SE_m_ij
std::vector< vector_fp > m_SE_m_ij
Entropy term for the binary mole fraction interaction of the excess Gibbs free energy expression.
Definition: RedlichKisterVPSSTP.h:461
Cantera::RedlichKisterVPSSTP::addBinaryInteraction
void addBinaryInteraction(const std::string &speciesA, const std::string &speciesB, const double *excess_enthalpy, size_t n_enthalpy, const double *excess_entropy, size_t n_entropy)
Add a binary species interaction with the specified parameters.
Definition: RedlichKisterVPSSTP.cpp:567
Cantera::ThermoPhase::RT
doublereal RT() const
Return the Gas Constant multiplied by the current temperature.
Definition: ThermoPhase.h:782
Cantera::ThermoPhase::initThermoFile
void initThermoFile(const std::string &inputFile, const std::string &id)
Definition: ThermoPhase.cpp:1066
Cantera::ThermoPhase::initThermoXML
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
Definition: ThermoPhase.cpp:1095
Cantera::ThermoPhase::m_input
AnyMap m_input
Data supplied via setParameters.
Definition: ThermoPhase.h:1898
Cantera::ThermoPhase::getParameters
virtual void getParameters(int &n, doublereal *const c) const
Get the equation of state parameters in a vector.
Definition: ThermoPhase.cpp:1193
Cantera::VPStandardStateTP::getStandardVolumes
virtual void getStandardVolumes(doublereal *vol) const
Get the molar volumes of the species standard states at the current T and P of the solution.
Definition: VPStandardStateTP.cpp:98
Cantera::VPStandardStateTP::getCp_R
virtual void getCp_R(doublereal *cpr) const
Get the nondimensional Heat Capacities at constant pressure for the species standard states at the cu...
Definition: VPStandardStateTP.cpp:92
Cantera::VPStandardStateTP::getEntropy_R
virtual void getEntropy_R(doublereal *sr) const
Get the array of nondimensional Entropy functions for the standard state species at the current T and...
Definition: VPStandardStateTP.cpp:64
Cantera::VPStandardStateTP::initThermo
virtual void initThermo()
Definition: VPStandardStateTP.cpp:154
Cantera::VPStandardStateTP::getStandardChemPotentials
virtual void getStandardChemPotentials(doublereal *mu) const
Get the array of chemical potentials at unit activity for the species at their standard states at the...
Definition: VPStandardStateTP.cpp:50
Cantera::VPStandardStateTP::getEnthalpy_RT
virtual void getEnthalpy_RT(doublereal *hrt) const
Get the nondimensional Enthalpy functions for the species at their standard states at the current T a...
Definition: VPStandardStateTP.cpp:58
Cantera::XML_Node
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:103
Cantera::XML_Node::attrib
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
Definition: xml.cpp:493
Cantera::XML_Node::name
std::string name() const
Returns the name of the XML node.
Definition: xml.h:371
Cantera::XML_Node::hasChild
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:529
Cantera::XML_Node::id
std::string id() const
Return the id attribute, if present.
Definition: xml.cpp:539
Cantera::XML_Node::nChildren
size_t nChildren(bool discardComments=false) const
Return the number of children.
Definition: xml.cpp:557
Cantera::XML_Node::child
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
Definition: xml.cpp:547
ctml.h
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data.
Cantera::importPhase
void importPhase(XML_Node &phase, ThermoPhase *th)
Import a phase information into an empty ThermoPhase object.
Definition: ThermoFactory.cpp:250
Cantera
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:557
Cantera::npos
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:192
Cantera::caseInsensitiveEquals
bool caseInsensitiveEquals(const std::string &input, const std::string &test)
Case insensitive equality predicate.
Definition: stringUtils.cpp:266
Cantera::SmallNumber
const double SmallNumber
smallest number to compare to zero.
Definition: ct_defs.h:153
Cantera::toLowerCopy
std::string toLowerCopy(const std::string &input)
Convert to lower case.
Definition: stringUtils.cpp:262
Cantera::vector_fp
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
Definition: ct_defs.h:184
Cantera::GasConstant
const double GasConstant
Universal Gas Constant [J/kmol/K].
Definition: ct_defs.h:113
Cantera::getFloatArray
size_t getFloatArray(const XML_Node &node, vector_fp &v, const bool convert, const std::string &unitsString, const std::string &nodeName)
This function reads the current node or a child node of the current node with the default name,...
Definition: ctml.cpp:258
stringUtils.h
Contains declarations for string manipulation functions within Cantera.