Cantera 2.6.0
MargulesVPSSTP.cpp
Go to the documentation of this file.
1/**
2 * @file MargulesVPSSTP.cpp
3 * Definitions for ThermoPhase object for phases which
4 * employ excess Gibbs free energy formulations related to Margules
5 * expansions (see \ref thermoprops
6 * and class \link Cantera::MargulesVPSSTP MargulesVPSSTP\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
15#include "cantera/base/ctml.h"
16
17using namespace std;
18
19namespace Cantera
20{
21MargulesVPSSTP::MargulesVPSSTP(const std::string& inputFile, const std::string& id_) :
22 numBinaryInteractions_(0),
23 formMargules_(0),
24 formTempModel_(0)
25{
26 initThermoFile(inputFile, id_);
27}
28
29MargulesVPSSTP::MargulesVPSSTP(XML_Node& phaseRoot, const std::string& id_) :
30 numBinaryInteractions_(0),
31 formMargules_(0),
32 formTempModel_(0)
33{
34 importPhase(phaseRoot, this);
35}
36
37// -- Activities, Standard States, Activity Concentrations -----------
38
40{
41 // Update the activity coefficients
43
44 // take the exp of the internally stored coefficients.
45 for (size_t k = 0; k < m_kk; k++) {
46 lnac[k] = lnActCoeff_Scaled_[k];
47 }
48}
49
50// ------------ Partial Molar Properties of the Solution ------------
51
52void MargulesVPSSTP::getChemPotentials(doublereal* mu) const
53{
54 // First get the standard chemical potentials in molar form. This requires
55 // updates of standard state as a function of T and P
57
58 // Update the activity coefficients
60 for (size_t k = 0; k < m_kk; k++) {
61 double xx = std::max(moleFractions_[k], SmallNumber);
62 mu[k] += RT() * (log(xx) + lnActCoeff_Scaled_[k]);
63 }
64}
65
67{
68 size_t kk = nSpecies();
69 double h = 0;
70 vector_fp hbar(kk);
72 for (size_t i = 0; i < kk; i++) {
73 h += moleFractions_[i]*hbar[i];
74 }
75 return h;
76}
77
79{
80 size_t kk = nSpecies();
81 double s = 0;
82 vector_fp sbar(kk);
84 for (size_t i = 0; i < kk; i++) {
85 s += moleFractions_[i]*sbar[i];
86 }
87 return s;
88}
89
90doublereal MargulesVPSSTP::cp_mole() const
91{
92 size_t kk = nSpecies();
93 double cp = 0;
94 vector_fp cpbar(kk);
95 getPartialMolarCp(&cpbar[0]);
96 for (size_t i = 0; i < kk; i++) {
97 cp += moleFractions_[i]*cpbar[i];
98 }
99 return cp;
100}
101
102doublereal MargulesVPSSTP::cv_mole() const
103{
104 return cp_mole() - GasConstant;
105}
106
108{
109 // Get the nondimensional standard state enthalpies
110 getEnthalpy_RT(hbar);
111
112 // dimensionalize it.
113 for (size_t k = 0; k < m_kk; k++) {
114 hbar[k] *= RT();
115 }
116
117 // Update the activity coefficients, This also update the internally stored
118 // molalities.
121 for (size_t k = 0; k < m_kk; k++) {
122 hbar[k] -= RT() * temperature() * dlnActCoeffdT_Scaled_[k];
123 }
124}
125
126void MargulesVPSSTP::getPartialMolarCp(doublereal* cpbar) const
127{
128 // Get the nondimensional standard state entropies
129 getCp_R(cpbar);
130 double T = temperature();
131
132 // Update the activity coefficients, This also update the internally stored
133 // molalities.
136
137 for (size_t k = 0; k < m_kk; k++) {
138 cpbar[k] -= 2 * T * dlnActCoeffdT_Scaled_[k] + T * T * d2lnActCoeffdT2_Scaled_[k];
139 }
140 // dimensionalize it.
141 for (size_t k = 0; k < m_kk; k++) {
142 cpbar[k] *= GasConstant;
143 }
144}
145
147{
148 // Get the nondimensional standard state entropies
149 getEntropy_R(sbar);
150 double T = temperature();
151
152 // Update the activity coefficients, This also update the internally stored
153 // molalities.
156
157 for (size_t k = 0; k < m_kk; k++) {
158 double xx = std::max(moleFractions_[k], SmallNumber);
159 sbar[k] += - lnActCoeff_Scaled_[k] -log(xx) - T * dlnActCoeffdT_Scaled_[k];
160 }
161
162 // dimensionalize it.
163 for (size_t k = 0; k < m_kk; k++) {
164 sbar[k] *= GasConstant;
165 }
166}
167
168void MargulesVPSSTP::getPartialMolarVolumes(doublereal* vbar) const
169{
170 double T = temperature();
171
172 // Get the standard state values in m^3 kmol-1
173 getStandardVolumes(vbar);
174
175 for (size_t i = 0; i < numBinaryInteractions_; i++) {
176 size_t iA = m_pSpecies_A_ij[i];
177 size_t iB = m_pSpecies_B_ij[i];
178 double XA = moleFractions_[iA];
179 double XB = moleFractions_[iB];
180 double g0 = (m_VHE_b_ij[i] - T * m_VSE_b_ij[i]);
181 double g1 = (m_VHE_c_ij[i] - T * m_VSE_c_ij[i]);
182 const doublereal temp1 = g0 + g1 * XB;
183 const doublereal all = -1.0*XA*XB*temp1 - XA*XB*XB*g1;
184
185 for (size_t iK = 0; iK < m_kk; iK++) {
186 vbar[iK] += all;
187 }
188 vbar[iA] += XB * temp1;
189 vbar[iB] += XA * temp1 + XA*XB*g1;
190 }
191}
192
194{
195 initLengths();
196 if (m_input.hasKey("interactions")) {
197 for (auto& item : m_input["interactions"].asVector<AnyMap>()) {
198 auto& species = item["species"].asVector<string>(2);
199 vector_fp h(2), s(2), vh(2), vs(2);
200 if (item.hasKey("excess-enthalpy")) {
201 h = item.convertVector("excess-enthalpy", "J/kmol", 2);
202 }
203 if (item.hasKey("excess-entropy")) {
204 s = item.convertVector("excess-entropy", "J/kmol/K", 2);
205 }
206 if (item.hasKey("excess-volume-enthalpy")) {
207 vh = item.convertVector("excess-volume-enthalpy", "m^3/kmol", 2);
208 }
209 if (item.hasKey("excess-volume-entropy")) {
210 vs = item.convertVector("excess-volume-entropy", "m^3/kmol/K", 2);
211 }
213 h[0], h[1], s[0], s[1], vh[0], vh[1], vs[0], vs[1]);
214 }
215 }
217}
218
220{
222 vector<AnyMap> interactions;
223 for (size_t n = 0; n < m_pSpecies_A_ij.size(); n++) {
224 AnyMap interaction;
225 interaction["species"] = vector<std::string>{
227 if (m_HE_b_ij[n] != 0 || m_HE_c_ij[n] != 0) {
228 interaction["excess-enthalpy"].setQuantity(
229 {m_HE_b_ij[n], m_HE_c_ij[n]}, "J/kmol");
230 }
231 if (m_SE_b_ij[n] != 0 || m_SE_c_ij[n] != 0) {
232 interaction["excess-entropy"].setQuantity(
233 {m_SE_b_ij[n], m_SE_c_ij[n]}, "J/kmol/K");
234 }
235 if (m_VHE_b_ij[n] != 0 || m_VHE_c_ij[n] != 0) {
236 interaction["excess-volume-enthalpy"].setQuantity(
237 {m_VHE_b_ij[n], m_VHE_c_ij[n]}, "m^3/kmol");
238 }
239 if (m_VSE_b_ij[n] != 0 || m_VSE_c_ij[n] != 0) {
240 interaction["excess-volume-entropy"].setQuantity(
241 {m_VSE_b_ij[n], m_VSE_c_ij[n]}, "m^3/kmol/K");
242 }
243 interactions.push_back(std::move(interaction));
244 }
245 phaseNode["interactions"] = std::move(interactions);
246}
247
249{
251}
252
253void MargulesVPSSTP::initThermoXML(XML_Node& phaseNode, const std::string& id_)
254{
255 if ((int) id_.size() > 0) {
256 string idp = phaseNode.id();
257 if (idp != id_) {
258 throw CanteraError("MargulesVPSSTP::initThermoXML", "phasenode and Id are incompatible");
259 }
260 }
261
262 // Find the Thermo XML node
263 if (!phaseNode.hasChild("thermo")) {
264 throw CanteraError("MargulesVPSSTP::initThermoXML",
265 "no thermo XML node");
266 }
267 XML_Node& thermoNode = phaseNode.child("thermo");
268
269 // Make sure that the thermo model is Margules
270 if (!caseInsensitiveEquals(thermoNode["model"], "margules")) {
271 throw CanteraError("MargulesVPSSTP::initThermoXML",
272 "model name isn't Margules: " + thermoNode["model"]);
273 }
274
275 // Go get all of the coefficients and factors in the activityCoefficients
276 // XML block
277 if (thermoNode.hasChild("activityCoefficients")) {
278 XML_Node& acNode = thermoNode.child("activityCoefficients");
279 if (!caseInsensitiveEquals(acNode["model"], "margules")) {
280 throw CanteraError("MargulesVPSSTP::initThermoXML",
281 "Unknown activity coefficient model: " + acNode["model"]);
282 }
283 for (size_t i = 0; i < acNode.nChildren(); i++) {
284 XML_Node& xmlACChild = acNode.child(i);
285
286 // Process a binary salt field, or any of the other XML fields that
287 // make up the Pitzer Database. Entries will be ignored if any of
288 // the species in the entry isn't in the solution.
289 if (caseInsensitiveEquals(xmlACChild.name(), "binaryneutralspeciesparameters")) {
290 readXMLBinarySpecies(xmlACChild);
291 }
292 }
293 }
294
295 // Go down the chain
296 GibbsExcessVPSSTP::initThermoXML(phaseNode, id_);
297}
298
299void MargulesVPSSTP::addBinaryInteraction(const std::string& speciesA,
300 const std::string& speciesB, double h0, double h1, double s0, double s1,
301 double vh0, double vh1, double vs0, double vs1)
302{
303 size_t kA = speciesIndex(speciesA);
304 size_t kB = speciesIndex(speciesB);
305 // The interaction is silently ignored if either species is not defined in
306 // the current phase.
307 if (kA == npos || kB == npos) {
308 return;
309 }
310 m_pSpecies_A_ij.push_back(kA);
311 m_pSpecies_B_ij.push_back(kB);
312
313 m_HE_b_ij.push_back(h0);
314 m_HE_c_ij.push_back(h1);
315 m_SE_b_ij.push_back(s0);
316 m_SE_c_ij.push_back(s1);
317 m_VHE_b_ij.push_back(vh0);
318 m_VHE_c_ij.push_back(vh1);
319 m_VSE_b_ij.push_back(vs0);
320 m_VSE_c_ij.push_back(vs1);
322}
323
324
326{
327 double T = temperature();
328 lnActCoeff_Scaled_.assign(m_kk, 0.0);
329 for (size_t i = 0; i < numBinaryInteractions_; i++) {
330 size_t iA = m_pSpecies_A_ij[i];
331 size_t iB = m_pSpecies_B_ij[i];
332 double g0 = (m_HE_b_ij[i] - T * m_SE_b_ij[i]) / RT();
333 double g1 = (m_HE_c_ij[i] - T * m_SE_c_ij[i]) / RT();
334 double XA = moleFractions_[iA];
335 double XB = moleFractions_[iB];
336 const doublereal XAXB = XA * XB;
337 const doublereal g0g1XB = (g0 + g1 * XB);
338 const doublereal all = -1.0 * XAXB * g0g1XB - XAXB * XB * g1;
339 for (size_t iK = 0; iK < m_kk; iK++) {
340 lnActCoeff_Scaled_[iK] += all;
341 }
342 lnActCoeff_Scaled_[iA] += XB * g0g1XB;
343 lnActCoeff_Scaled_[iB] += XA * g0g1XB + XAXB * g1;
344 }
345}
346
348{
349 doublereal invT = 1.0 / temperature();
350 doublereal invRTT = 1.0 / GasConstant*invT*invT;
351 dlnActCoeffdT_Scaled_.assign(m_kk, 0.0);
352 d2lnActCoeffdT2_Scaled_.assign(m_kk, 0.0);
353 for (size_t i = 0; i < numBinaryInteractions_; i++) {
354 size_t iA = m_pSpecies_A_ij[i];
355 size_t iB = m_pSpecies_B_ij[i];
356 double XA = moleFractions_[iA];
357 double XB = moleFractions_[iB];
358 double g0 = -m_HE_b_ij[i] * invRTT;
359 double g1 = -m_HE_c_ij[i] * invRTT;
360 const doublereal XAXB = XA * XB;
361 const doublereal g0g1XB = (g0 + g1 * XB);
362 const doublereal all = -1.0 * XAXB * g0g1XB - XAXB * XB * g1;
363 const doublereal mult = 2.0 * invT;
364 const doublereal dT2all = mult * all;
365 for (size_t iK = 0; iK < m_kk; iK++) {
366 dlnActCoeffdT_Scaled_[iK] += all;
367 d2lnActCoeffdT2_Scaled_[iK] -= dT2all;
368 }
369 dlnActCoeffdT_Scaled_[iA] += XB * g0g1XB;
370 dlnActCoeffdT_Scaled_[iB] += XA * g0g1XB + XAXB * g1;
371 d2lnActCoeffdT2_Scaled_[iA] -= mult * XB * g0g1XB;
372 d2lnActCoeffdT2_Scaled_[iB] -= mult * (XA * g0g1XB + XAXB * g1);
373 }
374}
375
376void MargulesVPSSTP::getdlnActCoeffdT(doublereal* dlnActCoeffdT) const
377{
379 for (size_t k = 0; k < m_kk; k++) {
380 dlnActCoeffdT[k] = dlnActCoeffdT_Scaled_[k];
381 }
382}
383
384void MargulesVPSSTP::getd2lnActCoeffdT2(doublereal* d2lnActCoeffdT2) const
385{
387 for (size_t k = 0; k < m_kk; k++) {
388 d2lnActCoeffdT2[k] = d2lnActCoeffdT2_Scaled_[k];
389 }
390}
391
392void MargulesVPSSTP::getdlnActCoeffds(const doublereal dTds, const doublereal* const dXds,
393 doublereal* dlnActCoeffds) const
394{
395 double T = temperature();
397 for (size_t iK = 0; iK < m_kk; iK++) {
398 dlnActCoeffds[iK] = 0.0;
399 }
400
401 for (size_t i = 0; i < numBinaryInteractions_; i++) {
402 size_t iA = m_pSpecies_A_ij[i];
403 size_t iB = m_pSpecies_B_ij[i];
404 double XA = moleFractions_[iA];
405 double XB = moleFractions_[iB];
406 double dXA = dXds[iA];
407 double dXB = dXds[iB];
408 double g0 = (m_HE_b_ij[i] - T * m_SE_b_ij[i]) / RT();
409 double g1 = (m_HE_c_ij[i] - T * m_SE_c_ij[i]) / RT();
410 const doublereal g02g1XB = g0 + 2*g1*XB;
411 const doublereal g2XAdXB = 2*g1*XA*dXB;
412 const doublereal all = (-XB * dXA - XA *dXB) * g02g1XB - XB *g2XAdXB;
413 for (size_t iK = 0; iK < m_kk; iK++) {
414 dlnActCoeffds[iK] += all + dlnActCoeffdT_Scaled_[iK]*dTds;
415 }
416 dlnActCoeffds[iA] += dXB * g02g1XB;
417 dlnActCoeffds[iB] += dXA * g02g1XB + g2XAdXB;
418 }
419}
420
422{
423 double T = temperature();
424 dlnActCoeffdlnN_diag_.assign(m_kk, 0.0);
425
426 for (size_t iK = 0; iK < m_kk; iK++) {
427 double XK = moleFractions_[iK];
428
429 for (size_t i = 0; i < numBinaryInteractions_; i++) {
430 size_t iA = m_pSpecies_A_ij[i];
431 size_t iB = m_pSpecies_B_ij[i];
432 size_t delAK = 0;
433 size_t delBK = 0;
434
435 if (iA==iK) {
436 delAK = 1;
437 } else if (iB==iK) {
438 delBK = 1;
439 }
440
441 double XA = moleFractions_[iA];
442 double XB = moleFractions_[iB];
443
444 double g0 = (m_HE_b_ij[i] - T * m_SE_b_ij[i]) / RT();
445 double g1 = (m_HE_c_ij[i] - T * m_SE_c_ij[i]) / RT();
446
447 dlnActCoeffdlnN_diag_[iK] += 2*(delBK-XB)*(g0*(delAK-XA)+g1*(2*(delAK-XA)*XB+XA*(delBK-XB)));
448 }
450 }
451}
452
454{
455 double T = temperature();
457
458 // Loop over the activity coefficient gamma_k
459 for (size_t iK = 0; iK < m_kk; iK++) {
460 for (size_t iM = 0; iM < m_kk; iM++) {
461 double XM = moleFractions_[iM];
462 for (size_t i = 0; i < numBinaryInteractions_; i++) {
463 size_t iA = m_pSpecies_A_ij[i];
464 size_t iB = m_pSpecies_B_ij[i];
465 double delAK = 0.0;
466 double delBK = 0.0;
467 double delAM = 0.0;
468 double delBM = 0.0;
469 if (iA==iK) {
470 delAK = 1.0;
471 } else if (iB==iK) {
472 delBK = 1.0;
473 }
474 if (iA==iM) {
475 delAM = 1.0;
476 } else if (iB==iM) {
477 delBM = 1.0;
478 }
479
480 double XA = moleFractions_[iA];
481 double XB = moleFractions_[iB];
482 double g0 = (m_HE_b_ij[i] - T * m_SE_b_ij[i]) / RT();
483 double g1 = (m_HE_c_ij[i] - T * m_SE_c_ij[i]) / RT();
484 dlnActCoeffdlnN_(iK,iM) += g0*((delAM-XA)*(delBK-XB)+(delAK-XA)*(delBM-XB));
485 dlnActCoeffdlnN_(iK,iM) += 2*g1*((delAM-XA)*(delBK-XB)*XB+(delAK-XA)*(delBM-XB)*XB+(delBM-XB)*(delBK-XB)*XA);
486 }
487 dlnActCoeffdlnN_(iK,iM) = XM*dlnActCoeffdlnN_(iK,iM);
488 }
489 }
490}
491
493{
494 doublereal T = temperature();
495 dlnActCoeffdlnX_diag_.assign(m_kk, 0.0);
496
497 for (size_t i = 0; i < numBinaryInteractions_; i++) {
498 size_t iA = m_pSpecies_A_ij[i];
499 size_t iB = m_pSpecies_B_ij[i];
500
501 doublereal XA = moleFractions_[iA];
502 doublereal XB = moleFractions_[iB];
503
504 doublereal g0 = (m_HE_b_ij[i] - T * m_SE_b_ij[i]) / RT();
505 doublereal g1 = (m_HE_c_ij[i] - T * m_SE_c_ij[i]) / RT();
506
507 dlnActCoeffdlnX_diag_[iA] += XA*XB*(2*g1*-2*g0-6*g1*XB);
508 dlnActCoeffdlnX_diag_[iB] += XA*XB*(2*g1*-2*g0-6*g1*XB);
509 }
510}
511
512void MargulesVPSSTP::getdlnActCoeffdlnN_diag(doublereal* dlnActCoeffdlnN_diag) const
513{
515 for (size_t k = 0; k < m_kk; k++) {
516 dlnActCoeffdlnN_diag[k] = dlnActCoeffdlnN_diag_[k];
517 }
518}
519
520void MargulesVPSSTP::getdlnActCoeffdlnX_diag(doublereal* dlnActCoeffdlnX_diag) const
521{
523 for (size_t k = 0; k < m_kk; k++) {
524 dlnActCoeffdlnX_diag[k] = dlnActCoeffdlnX_diag_[k];
525 }
526}
527
528void MargulesVPSSTP::getdlnActCoeffdlnN(const size_t ld, doublereal* dlnActCoeffdlnN)
529{
531 double* data = & dlnActCoeffdlnN_(0,0);
532 for (size_t k = 0; k < m_kk; k++) {
533 for (size_t m = 0; m < m_kk; m++) {
534 dlnActCoeffdlnN[ld * k + m] = data[m_kk * k + m];
535 }
536 }
537}
538
540{
541 string xname = xmLBinarySpecies.name();
542 if (xname != "binaryNeutralSpeciesParameters") {
543 throw CanteraError("MargulesVPSSTP::readXMLBinarySpecies",
544 "Incorrect name for processing this routine: " + xname);
545 }
546 string aName = xmLBinarySpecies.attrib("speciesA");
547 if (aName == "") {
548 throw CanteraError("MargulesVPSSTP::readXMLBinarySpecies", "no speciesA attrib");
549 }
550 string bName = xmLBinarySpecies.attrib("speciesB");
551 if (bName == "") {
552 throw CanteraError("MargulesVPSSTP::readXMLBinarySpecies", "no speciesB attrib");
553 }
554
555 vector_fp vParams;
556 double h0 = 0.0;
557 double h1 = 0.0;
558 double s0 = 0.0;
559 double s1 = 0.0;
560 double vh0 = 0.0;
561 double vh1 = 0.0;
562 double vs0 = 0.0;
563 double vs1 = 0.0;
564
565 for (size_t iChild = 0; iChild < xmLBinarySpecies.nChildren(); iChild++) {
566 XML_Node& xmlChild = xmLBinarySpecies.child(iChild);
567 string nodeName = toLowerCopy(xmlChild.name());
568
569 // Process the binary species interaction parameters.
570 // They are in subblocks labeled:
571 // excessEnthalpy
572 // excessEntropy
573 // excessVolume_Enthalpy
574 // excessVolume_Entropy
575 // Other blocks are currently ignored.
576 // @todo determine a policy about ignoring blocks that should or shouldn't be there.
577 if (nodeName == "excessenthalpy") {
578 // Get the string containing all of the values
579 getFloatArray(xmlChild, vParams, true, "toSI", "excessEnthalpy");
580 if (vParams.size() != 2) {
581 throw CanteraError("MargulesVPSSTP::readXMLBinarySpecies"
582 "excessEnthalpy for {} : {}: wrong number of params found."
583 " Need 2", aName, bName);
584 }
585 h0 = vParams[0];
586 h1 = vParams[1];
587 } else if (nodeName == "excessentropy") {
588 // Get the string containing all of the values
589 getFloatArray(xmlChild, vParams, true, "toSI", "excessEntropy");
590 if (vParams.size() != 2) {
591 throw CanteraError("MargulesVPSSTP::readXMLBinarySpecies"
592 "excessEntropy for {} : {}: wrong number of params found."
593 " Need 2", aName, bName);
594 }
595 s0 = vParams[0];
596 s1 = vParams[1];
597 } else if (nodeName == "excessvolume_enthalpy") {
598 // Get the string containing all of the values
599 getFloatArray(xmlChild, vParams, true, "toSI", "excessVolume_Enthalpy");
600 if (vParams.size() != 2) {
601 throw CanteraError("MargulesVPSSTP::readXMLBinarySpecies"
602 "excessVolume_Enthalpy for {} : {}: wrong number of params"
603 " found. Need 2", aName, bName);
604 }
605 vh0 = vParams[0];
606 vh1 = vParams[1];
607 } else if (nodeName == "excessvolume_entropy") {
608 // Get the string containing all of the values
609 getFloatArray(xmlChild, vParams, true, "toSI", "excessVolume_Entropy");
610 if (vParams.size() != 2) {
611 throw CanteraError("MargulesVPSSTP::readXMLBinarySpecies"
612 "excessVolume_Entropy for {} : {}: wrong number of params"
613 " found. Need 2", aName, bName);
614 }
615 vs0 = vParams[0];
616 vs1 = vParams[1];
617 }
618 }
619 addBinaryInteraction(aName, bName, h0, h1, s0, s1, vh0, vh1, vs0, vs1);
620}
621
622}
(see Thermodynamic Properties and class MargulesVPSSTP).
Headers for the factory class that can create known ThermoPhase objects (see Thermodynamic Properties...
A map of string keys to values whose type can vary at runtime.
Definition: AnyMap.h:399
bool hasKey(const std::string &key) const
Returns true if the map contains an item named key.
Definition: AnyMap.cpp:1406
void zero()
Set all of the entries to zero.
Definition: Array.h:139
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
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:61
Array2D dlnActCoeffdlnN_
Storage for the current derivative values of the gradients with respect to logarithm of the species m...
vector_fp dlnActCoeffdlnX_diag_
Storage for the current derivative values of the gradients with respect to logarithm of the mole frac...
vector_fp lnActCoeff_Scaled_
Storage for the current values of the activity coefficients of the species.
vector_fp d2lnActCoeffdT2_Scaled_
Storage for the current derivative values of the gradients with respect to temperature of the log of ...
vector_fp moleFractions_
Storage for the current values of the mole fractions of the species.
vector_fp dlnActCoeffdlnN_diag_
Storage for the current derivative values of the gradients with respect to logarithm of the mole frac...
vector_fp dlnActCoeffdT_Scaled_
Storage for the current derivative values of the gradients with respect to temperature of the log of ...
vector_fp m_SE_c_ij
Entropy term for the ternary mole fraction interaction of the excess Gibbs free energy expression.
virtual void getParameters(AnyMap &phaseNode) const
Store the parameters of a ThermoPhase object such that an identical one could be reconstructed using ...
virtual void getd2lnActCoeffdT2(doublereal *d2lnActCoeffdT2) const
Get the array of temperature second derivatives of the log activity coefficients.
vector_fp m_VSE_c_ij
Entropy term for the ternary mole fraction interaction of the excess Gibbs free energy expression.
virtual void getLnActivityCoefficients(doublereal *lnac) const
Get the array of non-dimensional molar-based ln activity coefficients at the current solution tempera...
virtual doublereal cp_mole() const
Molar heat capacity at constant pressure. Units: J/kmol/K.
virtual void getPartialMolarEnthalpies(doublereal *hbar) const
Returns an array of partial molar enthalpies for the species in the mixture.
virtual void getPartialMolarEntropies(doublereal *sbar) const
Returns an array of partial molar entropies for the species in the mixture.
virtual void getdlnActCoeffdT(doublereal *dlnActCoeffdT) const
Get the array of temperature derivatives of the log activity coefficients.
size_t numBinaryInteractions_
number of binary interaction expressions
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
virtual doublereal enthalpy_mole() const
Molar enthalpy. Units: J/kmol.
void s_update_dlnActCoeff_dlnN_diag() const
Update the derivative of the log of the activity coefficients wrt log(moles) - diagonal only.
virtual void getPartialMolarVolumes(doublereal *vbar) const
Return an array of partial molar volumes for the species in the mixture.
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 ...
void readXMLBinarySpecies(XML_Node &xmlBinarySpecies)
Process an XML node called "binaryNeutralSpeciesParameters".
virtual doublereal cv_mole() const
Molar heat capacity at constant volume. Units: J/kmol/K.
virtual void getdlnActCoeffdlnX_diag(doublereal *dlnActCoeffdlnX_diag) const
Get the array of ln mole fraction derivatives of the log activity coefficients - diagonal component o...
virtual void getPartialMolarCp(doublereal *cpbar) const
Returns an array of partial molar entropies for the species in the mixture.
vector_fp m_VHE_c_ij
Enthalpy term for the ternary mole fraction interaction of the excess Gibbs free energy expression.
std::vector< size_t > m_pSpecies_A_ij
vector of species indices representing species A in the interaction
void s_update_dlnActCoeff_dT() const
Update the derivative of the log of the activity coefficients wrt T.
vector_fp m_HE_b_ij
Enthalpy term for the binary mole fraction interaction of the excess Gibbs free energy expression.
void addBinaryInteraction(const std::string &speciesA, const std::string &speciesB, double h0, double h1, double s0, double s1, double vh0, double vh1, double vs0, double vs1)
Add a binary species interaction with the specified parameters.
vector_fp m_HE_c_ij
Enthalpy term for the ternary mole fraction interaction of the excess Gibbs free energy expression.
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol/K.
void s_update_dlnActCoeff_dlnN() const
Update the derivative of the log of the activity coefficients wrt log(moles_m)
vector_fp m_SE_b_ij
Entropy term for the binary mole fraction interaction of the excess Gibbs free energy expression.
vector_fp m_VHE_b_ij
Enthalpy term for the binary mole fraction interaction of the excess Gibbs free energy expression.
virtual void getdlnActCoeffdlnN_diag(doublereal *dlnActCoeffdlnN_diag) const
Get the array of log species mole number derivatives of the log activity coefficients.
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,...
std::vector< size_t > m_pSpecies_B_ij
vector of species indices representing species B in the interaction
void initLengths()
Initialize lengths of local variables after all species have been identified.
void s_update_dlnActCoeff_dlnX_diag() const
Update the derivative of the log of the activity coefficients wrt log(mole fraction)
void s_update_lnActCoeff() const
Update the activity coefficients.
MargulesVPSSTP(const std::string &inputFile="", const std::string &id="")
Construct a MargulesVPSSTP object from an input file.
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
vector_fp m_VSE_b_ij
Entropy term for the binary mole fraction interaction of the excess Gibbs free energy expression.
size_t nSpecies() const
Returns the number of species in the phase.
Definition: Phase.h:273
size_t m_kk
Number of species in the phase.
Definition: Phase.h:943
std::string speciesName(size_t k) const
Name of the species with index k.
Definition: Phase.cpp:200
doublereal temperature() const
Temperature (K).
Definition: Phase.h:654
size_t speciesIndex(const std::string &name) const
Returns the index of a species named 'name' within the Phase object.
Definition: Phase.cpp:187
shared_ptr< Species > species(const std::string &name) const
Return the Species object for the named species.
Definition: Phase.cpp:950
doublereal RT() const
Return the Gas Constant multiplied by the current temperature.
Definition: ThermoPhase.h:782
void initThermoFile(const std::string &inputFile, const std::string &id)
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
AnyMap m_input
Data supplied via setParameters.
Definition: ThermoPhase.h:1898
virtual void getParameters(int &n, doublereal *const c) const
Get the equation of state parameters in a vector.
virtual void getStandardVolumes(doublereal *vol) const
Get the molar volumes of the species standard states at the current T and P of the solution.
virtual void getCp_R(doublereal *cpr) const
Get the nondimensional Heat Capacities at constant pressure for the species standard states at the cu...
virtual void getEntropy_R(doublereal *sr) const
Get the array of nondimensional Entropy functions for the standard state species at the current T and...
virtual void getStandardChemPotentials(doublereal *mu) const
Get the array of chemical potentials at unit activity for the species at their standard states at the...
virtual void getEnthalpy_RT(doublereal *hrt) const
Get the nondimensional Enthalpy functions for the species at their standard states at the current T a...
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:103
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
Definition: xml.cpp:493
std::string name() const
Returns the name of the XML node.
Definition: xml.h:371
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:529
std::string id() const
Return the id attribute, if present.
Definition: xml.cpp:539
size_t nChildren(bool discardComments=false) const
Return the number of children.
Definition: xml.cpp:557
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 ("Cantera Markup Language") is the variant of XML that Cantera uses to store data.
void importPhase(XML_Node &phase, ThermoPhase *th)
Import a phase information into an empty ThermoPhase object.
Namespace for the Cantera kernel.
Definition: AnyMap.h:29
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:192
bool caseInsensitiveEquals(const std::string &input, const std::string &test)
Case insensitive equality predicate.
const double SmallNumber
smallest number to compare to zero.
Definition: ct_defs.h:153
std::string toLowerCopy(const std::string &input)
Convert to lower case.
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
const double GasConstant
Universal Gas Constant [J/kmol/K].
Definition: ct_defs.h:113
size_t getFloatArray(const XML_Node &node, vector_fp &v, const bool convert=true, const std::string &unitsString="", const std::string &nodeName="floatArray")
This function reads the current node or a child node of the current node with the default name,...
Definition: ctml.cpp:258
Contains declarations for string manipulation functions within Cantera.