11 #include <boost/math/tools/roots.hpp>
16 namespace bmt = boost::math::tools;
21 const doublereal RedlichKwongMFTP::omega_a = 4.27480233540E-01;
22 const doublereal RedlichKwongMFTP::omega_b = 8.66403499650E-02;
23 const doublereal RedlichKwongMFTP::omega_vc = 3.33333333333333E-01;
25 RedlichKwongMFTP::RedlichKwongMFTP() :
33 fill_n(Vroot_, 3, 0.0);
44 fill_n(Vroot_, 3, 0.0);
56 fill_n(Vroot_, 3, 0.0);
61 double a0,
double a1,
double b)
66 "Unknown species '{}'.",
species);
73 size_t counter = k +
m_kk * k;
74 a_coeff_vec(0, counter) = a0;
75 a_coeff_vec(1, counter) = a1;
78 for (
size_t j = 0; j <
m_kk; j++) {
84 if (isnan(a_coeff_vec(0, j +
m_kk * j))) {
87 }
else if (isnan(a_coeff_vec(0, j +
m_kk * k))) {
90 double a0kj = sqrt(a_coeff_vec(0, j +
m_kk * j) * a0);
91 double a1kj = sqrt(a_coeff_vec(1, j +
m_kk * j) * a1);
92 a_coeff_vec(0, j +
m_kk * k) = a0kj;
93 a_coeff_vec(1, j +
m_kk * k) = a1kj;
94 a_coeff_vec(0, k +
m_kk * j) = a0kj;
95 a_coeff_vec(1, k +
m_kk * j) = a1kj;
98 a_coeff_vec.
getRow(0, a_vec_Curr_.data());
103 const std::string& species_j,
double a0,
double a1)
108 "Unknown species '{}'.", species_i);
113 "Unknown species '{}'.", species_j);
119 size_t counter1 = ki +
m_kk * kj;
120 size_t counter2 = kj +
m_kk * ki;
121 a_coeff_vec(0, counter1) = a_coeff_vec(0, counter2) = a0;
122 a_coeff_vec(1, counter1) = a_coeff_vec(1, counter2) = a1;
123 a_vec_Curr_[counter1] = a_vec_Curr_[counter2] = a0;
132 doublereal h_nonideal =
hresid();
133 return h_ideal + h_nonideal;
141 doublereal sr_nonideal =
sresid();
142 return sr_ideal + sr_nonideal;
149 doublereal sqt = sqrt(TKelvin);
154 doublereal dadt = da_dt();
155 doublereal fac = TKelvin * dadt - 3.0 *
m_a_current / 2.0;
157 +1.0/(
m_b_current * sqt) * log(vpb/mv) * (-0.5 * dadt));
165 doublereal sqt = sqrt(TKelvin);
169 doublereal dadt = da_dt();
170 doublereal fac = TKelvin * dadt - 3.0 *
m_a_current / 2.0;
171 return (cvref - 1.0/(2.0 *
m_b_current * TKelvin * sqt) * log(vpb/mv)*fac
172 +1.0/(
m_b_current * sqt) * log(vpb/mv)*(-0.5*dadt));
214 for (
size_t k = 0; k <
m_kk; k++) {
232 for (
size_t k = 0; k <
m_kk; k++) {
234 for (
size_t i = 0; i <
m_kk; i++) {
235 size_t counter = k +
m_kk*i;
241 for (
size_t k = 0; k <
m_kk; k++) {
242 ac[k] = (-
RT() * log(pres * mv /
RT())
243 +
RT() * log(mv / vmb)
244 +
RT() * b_vec_Curr_[k] / vmb
250 for (
size_t k = 0; k <
m_kk; k++) {
251 ac[k] = exp(ac[k]/
RT());
260 for (
size_t k = 0; k <
m_kk; k++) {
261 muRT[k] *= 1.0 /
RT();
268 for (
size_t k = 0; k <
m_kk; k++) {
270 mu[k] +=
RT()*(log(xx));
278 for (
size_t k = 0; k <
m_kk; k++) {
280 for (
size_t i = 0; i <
m_kk; i++) {
281 size_t counter = k +
m_kk*i;
288 for (
size_t k = 0; k <
m_kk; k++) {
289 mu[k] += (
RT() * log(pres/refP) -
RT() * log(pres * mv /
RT())
290 +
RT() * log(mv / vmb)
291 +
RT() * b_vec_Curr_[k] / vmb
308 doublereal sqt = sqrt(TKelvin);
311 for (
size_t k = 0; k <
m_kk; k++) {
313 for (
size_t i = 0; i <
m_kk; i++) {
314 size_t counter = k +
m_kk*i;
318 for (
size_t k = 0; k <
m_kk; k++) {
319 dpdni_[k] =
RT()/vmb +
RT() * b_vec_Curr_[k] / (vmb * vmb) - 2.0 *
m_pp[k] / (sqt * mv * vpb)
320 +
m_a_current * b_vec_Curr_[k]/(sqt * mv * vpb * vpb);
322 doublereal dadt = da_dt();
323 doublereal fac = TKelvin * dadt - 3.0 *
m_a_current / 2.0;
325 for (
size_t k = 0; k <
m_kk; k++) {
327 for (
size_t i = 0; i <
m_kk; i++) {
328 size_t counter = k +
m_kk*i;
334 doublereal fac2 = mv + TKelvin *
dpdT_ /
dpdV_;
335 for (
size_t k = 0; k <
m_kk; k++) {
338 + b_vec_Curr_[k] / vpb / (
m_b_current * sqt) * fac);
339 hbar[k] = hbar[k] + hE_v;
340 hbar[k] -= fac2 *
dpdni_[k];
349 doublereal sqt = sqrt(TKelvin);
353 for (
size_t k = 0; k <
m_kk; k++) {
357 for (
size_t k = 0; k <
m_kk; k++) {
359 for (
size_t i = 0; i <
m_kk; i++) {
360 size_t counter = k +
m_kk*i;
364 for (
size_t k = 0; k <
m_kk; k++) {
366 for (
size_t i = 0; i <
m_kk; i++) {
367 size_t counter = k +
m_kk*i;
372 doublereal dadt = da_dt();
373 doublereal fac = dadt -
m_a_current / (2.0 * TKelvin);
376 for (
size_t k = 0; k <
m_kk; k++) {
384 - 1.0 / (
m_b_current * sqt) * b_vec_Curr_[k] / vpb * fac
390 for (
size_t k = 0; k <
m_kk; k++) {
391 sbar[k] -= -m_partialMolarVolumes[k] *
dpdT_;
409 for (
size_t k = 0; k <
m_kk; k++) {
411 for (
size_t i = 0; i <
m_kk; i++) {
412 size_t counter = k +
m_kk*i;
416 for (
size_t k = 0; k <
m_kk; k++) {
418 for (
size_t i = 0; i <
m_kk; i++) {
419 size_t counter = k +
m_kk*i;
428 for (
size_t k = 0; k <
m_kk; k++) {
431 - 2.0 *
m_pp[k] / (sqt * vpb)
436 vbar[k] = num / denom;
445 for (
size_t i = 0; i <
m_kk; i++) {
446 for (
size_t j = 0; j <
m_kk; j++) {
447 size_t counter = i +
m_kk * j;
461 for (
size_t i = 0; i <
m_kk; i++) {
462 for (
size_t j = 0; j <
m_kk; j++) {
463 size_t counter = i +
m_kk * j;
477 for (
size_t i = 0; i <
m_kk; i++) {
478 for (
size_t j = 0; j <
m_kk; j++) {
479 size_t counter = i +
m_kk * j;
493 for (
size_t i = 0; i <
m_kk; i++) {
494 for (
size_t j = 0; j <
m_kk; j++) {
495 size_t counter = i +
m_kk * j;
509 for (
size_t i = 0; i <
m_kk; i++) {
510 for (
size_t j = 0; j <
m_kk; j++) {
511 size_t counter = i +
m_kk * j;
525 a_vec_Curr_.resize(
m_kk *
m_kk, 0.0);
529 b_vec_Curr_.push_back(NAN);
534 m_partialMolarVolumes.push_back(0.0);
544 std::string model = thermoNode[
"model"];
545 if (model !=
"RedlichKwong" && model !=
"RedlichKwongMFTP") {
547 "Unknown thermo model : " + model);
553 a_coeff_vec.
data().assign(a_coeff_vec.
data().size(), NAN);
557 if (thermoNode.
hasChild(
"activityCoefficients")) {
564 for (
size_t i = 0; i < acNode.
nChildren(); i++) {
580 for (
size_t i = 0; i <
m_kk; i++) {
587 size_t counter = iSpecies +
m_kk * iSpecies;
590 if (isnan(a_coeff_vec(0, counter))) {
592 vector<double> coeffArray;
601 if (!isnan(coeffArray[0])) {
614 for (
auto& item : m_species) {
617 if (item.second->input.hasKey(
"equation-of-state")) {
618 auto eos = item.second->input[
"equation-of-state"].getMapWhere(
619 "model",
"Redlich-Kwong");
620 double a0 = 0, a1 = 0;
621 if (eos[
"a"].isScalar()) {
622 a0 = eos.convert(
"a",
"Pa*m^6/kmol^2*K^0.5");
624 auto avec = eos[
"a"].asVector<
AnyValue>(2);
625 a0 = eos.units().convert(avec[0],
"Pa*m^6/kmol^2*K^0.5");
626 a1 = eos.units().convert(avec[1],
"Pa*m^6/kmol^2/K^0.5");
628 double b = eos.convert(
"b",
"m^3/kmol");
630 if (eos.hasKey(
"binary-a")) {
633 for (
auto& item2 : binary_a) {
634 double a0 = 0, a1 = 0;
635 if (item2.second.isScalar()) {
636 a0 = units.
convert(item2.second,
"Pa*m^6/kmol^2*K^0.5");
638 auto avec = item2.second.asVector<
AnyValue>(2);
639 a0 = units.convert(avec[0],
"Pa*m^6/kmol^2*K^0.5");
640 a1 = units.convert(avec[1],
"Pa*m^6/kmol^2/K^0.5");
650 if (isnan(a_coeff_vec(0, k +
m_kk * k))) {
652 vector<double> coeffs =
getCoeff(item.first);
656 if (!isnan(coeffs[0])) {
677 for (
size_t isp = 0; isp < nDatabase; isp++) {
684 if (iNameLower == dbName) {
695 std::string critTemp = xmlChildCoeff.
attrib(
"value");
701 "Critical Temperature must be positive ");
706 "Critical Temperature not in database ");
719 "Critical Pressure must be positive ");
724 "Critical Pressure not in database ");
738 string xname = pureFluidParam.
name();
739 if (xname !=
"pureFluidParameters") {
740 throw CanteraError(
"RedlichKwongMFTP::readXMLPureFluid",
741 "Incorrect name for processing this routine: " + xname);
747 for (
size_t iChild = 0; iChild < pureFluidParam.
nChildren(); iChild++) {
751 if (nodeName ==
"a_coeff") {
754 getFloatArray(xmlChild, vParams,
true,
"Pascal-m6/kmol2",
"a_coeff");
756 if (iModel ==
"constant" && vParams.size() == 1) {
759 }
else if (iModel ==
"linear_a" && vParams.size() == 2) {
763 throw CanteraError(
"RedlichKwongMFTP::readXMLPureFluid",
764 "unknown model or incorrect number of parameters");
767 }
else if (nodeName ==
"b_coeff") {
776 string xname = CrossFluidParam.
name();
777 if (xname !=
"crossFluidParameters") {
778 throw CanteraError(
"RedlichKwongMFTP::readXMLCrossFluid",
779 "Incorrect name for processing this routine: " + xname);
782 string iName = CrossFluidParam.
attrib(
"species1");
783 string jName = CrossFluidParam.
attrib(
"species2");
785 size_t num = CrossFluidParam.
nChildren();
786 for (
size_t iChild = 0; iChild < num; iChild++) {
790 if (nodeName ==
"a_coeff") {
792 getFloatArray(xmlChild, vParams,
true,
"Pascal-m6/kmol2",
"a_coeff");
794 if (iModel ==
"constant" && vParams.size() == 1) {
796 }
else if (iModel ==
"linear_a") {
799 throw CanteraError(
"RedlichKwongMFTP::readXMLCrossFluid",
800 "unknown model ({}) or wrong number of parameters ({})",
801 iModel, vParams.size());
810 std::string model = thermoNode[
"model"];
818 doublereal molarV = mmw / rho;
821 doublereal dadt = da_dt();
823 doublereal sqT = sqrt(T);
834 doublereal molarV = mmw / rho;
837 doublereal dadt = da_dt();
839 doublereal sqT = sqrt(T);
840 doublereal fac = T * dadt - 3.0 *
m_a_current / (2.0);
850 doublereal pres = std::max(
psatEst(TKelvin), presGuess);
852 bool foundLiq =
false;
854 while (m < 100 && !foundLiq) {
855 int nsol =
NicholsSolve(TKelvin, pres, atmp, btmp, Vroot);
856 if (nsol == 1 || nsol == 2) {
882 if (rhoguess == -1.0) {
883 if (phaseRequested != FLUID_GAS) {
884 if (TKelvin > tcrit) {
887 if (phaseRequested == FLUID_GAS || phaseRequested == FLUID_SUPERCRIT) {
889 }
else if (phaseRequested >= FLUID_LIQUID_0) {
891 rhoguess = mmw / lqvol;
901 doublereal volguess = mmw / rhoguess;
904 doublereal molarVolLast = Vroot_[0];
906 if (phaseRequested >= FLUID_LIQUID_0) {
907 molarVolLast = Vroot_[0];
908 }
else if (phaseRequested == FLUID_GAS || phaseRequested == FLUID_SUPERCRIT) {
909 molarVolLast = Vroot_[2];
911 if (volguess > Vroot_[1]) {
912 molarVolLast = Vroot_[2];
914 molarVolLast = Vroot_[0];
917 }
else if (NSolns_ == 1) {
918 if (phaseRequested == FLUID_GAS || phaseRequested == FLUID_SUPERCRIT || phaseRequested == FLUID_UNDEFINED) {
919 molarVolLast = Vroot_[0];
923 }
else if (NSolns_ == -1) {
924 if (phaseRequested >= FLUID_LIQUID_0 || phaseRequested == FLUID_UNDEFINED || phaseRequested == FLUID_SUPERCRIT) {
925 molarVolLast = Vroot_[0];
926 }
else if (TKelvin > tcrit) {
927 molarVolLast = Vroot_[0];
932 molarVolLast = Vroot_[0];
935 return mmw / molarVolLast;
947 auto resid = [
this, T](
double v) {
952 boost::uintmax_t maxiter = 100;
953 std::pair<double, double> vv = bmt::toms748_solve(
954 resid, Vroot[0], Vroot[1], bmt::eps_tolerance<double>(48), maxiter);
957 return mmw / (0.5 * (vv.first + vv.second));
969 auto resid = [
this, T](
double v) {
974 boost::uintmax_t maxiter = 100;
975 std::pair<double, double> vv = bmt::toms748_solve(
976 resid, Vroot[1], Vroot[2], bmt::eps_tolerance<double>(48), maxiter);
979 return mmw / (0.5 * (vv.first + vv.second));
984 doublereal sqt = sqrt(TKelvin);
992 doublereal sqt = sqrt(TKelvin);
998 doublereal dpdv = (-
GasConstant * TKelvin / (vmb * vmb)
1010 doublereal sqt = sqrt(TKelvin);
1013 doublereal dadt = da_dt();
1014 doublereal fac = dadt -
m_a_current/(2.0 * TKelvin);
1018 void RedlichKwongMFTP::updateMixingExpressions()
1027 for (
size_t i = 0; i <
m_kk; i++) {
1028 for (
size_t j = 0; j <
m_kk; j++) {
1029 size_t counter = i *
m_kk + j;
1030 a_vec_Curr_[counter] = a_coeff_vec(0,counter) + a_coeff_vec(1,counter) * temp;
1037 for (
size_t i = 0; i <
m_kk; i++) {
1039 for (
size_t j = 0; j <
m_kk; j++) {
1045 fmt::memory_buffer b;
1046 for (
size_t k = 0; k <
m_kk; k++) {
1047 if (isnan(b_vec_Curr_[k])) {
1056 "Missing Redlich-Kwong coefficients for species: {}", to_string(b));
1065 for (
size_t i = 0; i <
m_kk; i++) {
1067 for (
size_t j = 0; j <
m_kk; j++) {
1068 size_t counter = i *
m_kk + j;
1069 doublereal a_vec_Curr = a_coeff_vec(0,counter) + a_coeff_vec(1,counter) * temp;
1074 for (
size_t i = 0; i <
m_kk; i++) {
1076 for (
size_t j = 0; j <
m_kk; j++) {
1077 size_t counter = i *
m_kk + j;
1078 doublereal a_vec_Curr = a_coeff_vec(0,counter);
1085 doublereal RedlichKwongMFTP::da_dt()
const
1087 doublereal dadT = 0.0;
1089 for (
size_t i = 0; i <
m_kk; i++) {
1090 for (
size_t j = 0; j <
m_kk; j++) {
1091 size_t counter = i *
m_kk + j;
1099 void RedlichKwongMFTP::calcCriticalConditions(doublereal a, doublereal b, doublereal a0_coeff, doublereal aT_coeff,
1100 doublereal& pc, doublereal& tc, doublereal& vc)
const
1119 doublereal sqrttc, f, dfdt, deltatc;
1125 for (
int j = 0; j < 10; j++) {
1129 deltatc = - f / dfdt;
1132 if (deltatc > 0.1) {
1133 throw CanteraError(
"RedlichKwongMFTP::calcCriticalConditions",
"didn't converge");
1142 doublereal Vroot[3])
const
1147 if (TKelvin <= 0.0) {
1148 throw CanteraError(
"RedlichKwongMFTP::NicholsSolve",
"neg temperature");
1152 doublereal an = 1.0;
1154 doublereal sqt = sqrt(TKelvin);
1155 doublereal cn = - (
GasConstant * TKelvin * b / pres - a/(pres * sqt) + b * b);
1156 doublereal dn = - (a * b / (pres * sqt));
1160 double tc = pow(tmp, pp);
1164 doublereal xN = - bn /(3 * an);
1168 doublereal delta2 = (bn * bn - 3 * an * cn) / (9 * an * an);
1169 doublereal delta = 0.0;
1172 doublereal ratio1 = 3.0 * an * cn / (bn * bn);
1173 doublereal ratio2 = pres * b / (
GasConstant * TKelvin);
1174 if (fabs(ratio1) < 1.0E-7) {
1176 if (fabs(ratio2) < 1.0E-5 && fabs(ratio3) < 1.0E-5) {
1177 doublereal zz = 1.0;
1178 for (
int i = 0; i < 10; i++) {
1179 doublereal znew = zz / (zz - ratio2) - ratio3 / (zz + ratio1);
1180 doublereal deltaz = znew - zz;
1182 if (fabs(deltaz) < 1.0E-14) {
1193 double h2 = 4. * an * an * delta2 * delta2 * delta2;
1195 delta = sqrt(delta2);
1198 doublereal h = 2.0 * an * delta * delta2;
1199 doublereal yN = 2.0 * bn * bn * bn / (27.0 * an * an) - bn * cn / (3.0 * an) + dn;
1200 doublereal desc = yN * yN - h2;
1202 if (fabs(fabs(h) - fabs(yN)) < 1.0E-10) {
1205 throw CanteraError(
"RedlichKwongMFTP::NicholsSolve",
"numerical issues");
1212 }
else if (desc == 0.0) {
1215 }
else if (desc > 0.0) {
1221 doublereal tmpD = sqrt(desc);
1222 doublereal tmp1 = (- yN + tmpD) / (2.0 * an);
1223 doublereal sgn1 = 1.0;
1228 doublereal tmp2 = (- yN - tmpD) / (2.0 * an);
1229 doublereal sgn2 = 1.0;
1234 doublereal p1 = pow(tmp1, 1./3.);
1235 doublereal p2 = pow(tmp2, 1./3.);
1236 doublereal alpha = xN + sgn1 * p1 + sgn2 * p2;
1240 tmp = an * Vroot[0] * Vroot[0] * Vroot[0] + bn * Vroot[0] * Vroot[0] + cn * Vroot[0] + dn;
1241 }
else if (desc < 0.0) {
1242 doublereal tmp = - yN/h;
1243 doublereal val = acos(tmp);
1244 doublereal theta = val / 3.0;
1245 doublereal oo = 2. *
Pi / 3.;
1246 doublereal alpha = xN + 2. * delta * cos(theta);
1247 doublereal beta = xN + 2. * delta * cos(theta + oo);
1248 doublereal gamma = xN + 2. * delta * cos(theta + 2.0 * oo);
1253 for (
int i = 0; i < 3; i++) {
1254 tmp = an * Vroot[i] * Vroot[i] * Vroot[i] + bn * Vroot[i] * Vroot[i] + cn * Vroot[i] + dn;
1255 if (fabs(tmp) > 1.0E-4) {
1256 for (
int j = 0; j < 3; j++) {
1257 if (j != i && fabs(Vroot[i] - Vroot[j]) < 1.0E-4 * (fabs(Vroot[i]) + fabs(Vroot[j]))) {
1258 warn_user(
"RedlichKwongMFTP::NicholsSolve",
1259 "roots have merged: {}, {} (T = {}, p = {})",
1260 Vroot[i], Vroot[j], TKelvin, pres);
1265 }
else if (desc == 0.0) {
1266 if (yN == 0.0 && h == 0.0) {
1273 tmp = pow(yN/(2*an), 1./3.);
1274 if (fabs(tmp - delta) > 1.0E-9) {
1275 throw CanteraError(
"RedlichKwongMFTP::NicholsSolve",
"unexpected");
1277 Vroot[1] = xN + delta;
1278 Vroot[0] = xN - 2.0*delta;
1280 tmp = pow(yN/(2*an), 1./3.);
1281 if (fabs(tmp - delta) > 1.0E-9) {
1282 throw CanteraError(
"RedlichKwongMFTP::NicholsSolve",
"unexpected");
1285 Vroot[0] = xN + delta;
1286 Vroot[1] = xN - 2.0*delta;
1289 for (
int i = 0; i < 2; i++) {
1290 tmp = an * Vroot[i] * Vroot[i] * Vroot[i] + bn * Vroot[i] * Vroot[i] + cn * Vroot[i] + dn;
1296 double res, dresdV = 0.0;
1297 for (
int i = 0; i < nSolnValues; i++) {
1298 for (
int n = 0; n < 20; n++) {
1299 res = an * Vroot[i] * Vroot[i] * Vroot[i] + bn * Vroot[i] * Vroot[i] + cn * Vroot[i] + dn;
1300 if (fabs(res) < 1.0E-14) {
1303 dresdV = 3.0 * an * Vroot[i] * Vroot[i] + 2.0 * bn * Vroot[i] + cn;
1304 double del = - res / dresdV;
1306 if (fabs(del) / (fabs(Vroot[i]) + fabs(del)) < 1.0E-14) {
1309 double res2 = an * Vroot[i] * Vroot[i] * Vroot[i] + bn * Vroot[i] * Vroot[i] + cn * Vroot[i] + dn;
1310 if (fabs(res2) < fabs(res)) {
1314 Vroot[i] += 0.1 * del;
1317 if ((fabs(res) > 1.0E-14) && (fabs(res) > 1.0E-14 * fabs(dresdV) * fabs(Vroot[i]))) {
1318 warn_user(
"RedlichKwongMFTP::NicholsSolve",
1319 "root did not converge: V = {} (T = {}, p = {})",
1320 Vroot[i], TKelvin, pres);
1324 if (nSolnValues == 1) {
1326 if (Vroot[0] < vc) {
1330 if (Vroot[0] < xN) {
1335 if (nSolnValues == 2 && delta > 0.0) {
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.
const UnitSystem & units() const
Return the default units that should be used to convert stored values.
A wrapper for a variable whose type is determined at runtime.
void resize(size_t n, size_t m, doublereal v=0.0)
Resize the array, and fill the new entries with 'v'.
vector_fp & data()
Return a reference to the data vector.
void getRow(size_t n, doublereal *const rw)
Get the nth row and return it in a vector.
Base class for exceptions thrown by Cantera classes.
vector_fp m_cp0_R
Temporary storage for dimensionless reference state heat capacities.
virtual bool addSpecies(shared_ptr< Species > spec)
doublereal z() const
Calculate the value of z.
vector_fp m_h0_RT
Temporary storage for dimensionless reference state enthalpies.
virtual void _updateReferenceStateThermo() const
Updates the reference state thermodynamic functions at the current T of the solution.
virtual void getStandardVolumes(doublereal *vol) const
Get the molar volumes of each species in their standard states at the current T and P of the solution...
vector_fp m_s0_R
Temporary storage for dimensionless reference state entropies.
virtual void getCp_R(doublereal *cpr) const
Get the nondimensional Heat Capacities at constant pressure for the standard state of the species at ...
virtual doublereal psatEst(doublereal TKelvin) const
Estimate for the saturation pressure.
virtual void getEntropy_R_ref(doublereal *er) const
Returns the vector of nondimensional entropies of the reference state at the current temperature of t...
virtual void getIntEnergy_RT(doublereal *urt) const
Returns the vector of nondimensional internal Energies of the standard state at the current temperatu...
vector_fp moleFractions_
Storage for the current values of the mole fractions of the species.
virtual void compositionChanged()
Apply changes to the state which are needed after the composition changes.
virtual void getGibbs_ref(doublereal *g) const
Returns the vector of the Gibbs function of the reference state at the current temperature of the sol...
virtual void getEnthalpy_RT_ref(doublereal *hrt) const
doublereal mean_X(const doublereal *const Q) const
Evaluate the mole-fraction-weighted mean of an array Q.
const double * moleFractdivMMW() const
Returns a const pointer to the start of the moleFraction/MW array.
size_t m_kk
Number of species in the phase.
std::string speciesName(size_t k) const
Name of the species with index k.
virtual void setDensity(const double density_)
Set the internally stored density (kg/m^3) of the phase.
doublereal meanMolecularWeight() const
The mean molecular weight. Units: (kg/kmol)
double moleFraction(size_t k) const
Return the mole fraction of a single species.
virtual double density() const
Density (kg/m^3).
doublereal temperature() const
Temperature (K).
size_t speciesIndex(const std::string &name) const
Returns the index of a species named 'name' within the Phase object.
virtual void setTemperature(const doublereal temp)
Set the internally stored temperature of the phase (K).
double molarVolume() const
Molar volume (m^3/kmol).
shared_ptr< Species > species(const std::string &name) const
Return the Species object for the named species.
doublereal sum_xlogx() const
Evaluate .
virtual bool addSpecies(shared_ptr< Species > spec)
virtual void getActivityCoefficients(doublereal *ac) const
Get the array of non-dimensional activity coefficients at the current solution temperature,...
void updateAB()
Update the a and b parameters.
static const doublereal omega_b
Omega constant for b.
int m_formTempParam
Form of the temperature parameterization.
virtual doublereal hresid() const
Calculate the deviation terms for the total enthalpy of the mixture from the ideal gas mixture.
doublereal m_b_current
Value of b in the equation of state.
doublereal dpdT_
The derivative of the pressure wrt the temperature.
virtual doublereal pressure() const
Return the thermodynamic pressure (Pa).
virtual void getPartialMolarIntEnergies(doublereal *ubar) const
Return an array of partial molar internal energies for the species in the mixture.
virtual doublereal critVolume() const
Critical volume (m3/kmol).
virtual doublereal cp_mole() const
Molar heat capacity at constant pressure. Units: J/kmol/K.
virtual std::vector< double > getCoeff(const std::string &iName)
Retrieve a and b coefficients by looking up tabulated critical parameters.
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 of the species in the solution.
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
virtual doublereal critPressure() const
Critical pressure (Pa).
virtual doublereal enthalpy_mole() const
Molar enthalpy. Units: J/kmol.
virtual doublereal densityCalc(doublereal TKelvin, doublereal pressure, int phase, doublereal rhoguess)
Calculates the density given the temperature and the pressure and a guess at the density.
void readXMLCrossFluid(XML_Node &pureFluidParam)
Read the cross species RedlichKwong input parameters.
virtual void getPartialMolarVolumes(doublereal *vbar) const
Return an array of partial molar volumes for the species in the mixture.
vector_fp m_pp
Temporary storage - length = m_kk.
virtual doublereal cv_mole() const
Molar heat capacity at constant volume. Units: J/kmol/K.
virtual void getActivityConcentrations(doublereal *c) const
This method returns an array of generalized concentrations.
void readXMLPureFluid(XML_Node &pureFluidParam)
Read the pure species RedlichKwong input parameters.
virtual doublereal dpdVCalc(doublereal TKelvin, doublereal molarVol, doublereal &presCalc) const
Calculate the pressure and the pressure derivative given the temperature and the molar volume.
virtual doublereal sresid() const
Calculate the deviation terms for the total entropy of the mixture from the ideal gas mixture.
virtual void getPartialMolarCp(doublereal *cpbar) const
Return an array of partial molar heat capacities for the species in the mixture.
void setBinaryCoeffs(const std::string &species_i, const std::string &species_j, double a0, double a1)
Set values for the interaction parameter between two species.
void pressureDerivatives() const
Calculate dpdV and dpdT at the current conditions.
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol/K.
static const doublereal omega_vc
Omega constant for the critical molar volume.
virtual doublereal liquidVolEst(doublereal TKelvin, doublereal &pres) const
Estimate for the molar volume of the liquid.
virtual void initThermo()
Initialize the ThermoPhase object after all species have been set up.
virtual doublereal critTemperature() const
Critical temperature (K).
doublereal m_a_current
Value of a in the equation of state.
virtual doublereal densSpinodalGas() const
Return the value of the density at the gas spinodal point (on the gas side) for the current temperatu...
void setSpeciesCoeffs(const std::string &species, double a0, double a1, double b)
Set the pure fluid interaction parameters for a species.
RedlichKwongMFTP()
Base constructor.
virtual void setTemperature(const doublereal temp)
Set the temperature of the phase.
int NicholsSolve(double TKelvin, double pres, doublereal a, doublereal b, doublereal Vroot[3]) const
Solve the cubic equation of state.
virtual doublereal pressureCalc(doublereal TKelvin, doublereal molarVol) const
Calculate the pressure given the temperature and the molar volume.
virtual void compositionChanged()
Apply changes to the state which are needed after the composition changes.
void calculateAB(doublereal temp, doublereal &aCalc, doublereal &bCalc) const
Calculate the a and the b parameters given the temperature.
virtual void getChemPotentials_RT(doublereal *mu) const
Get the array of non-dimensional species chemical potentials.
doublereal dpdV_
The derivative of the pressure wrt the volume.
virtual doublereal critCompressibility() const
Critical compressibility (unitless).
virtual doublereal densSpinodalLiquid() const
Return the value of the density at the liquid spinodal point (on the liquid side) for the current tem...
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
virtual doublereal critDensity() const
Critical density (kg/m3).
vector_fp m_tmpV
Temporary storage - length = m_kk.
static const doublereal omega_a
Omega constant for a -> value of a in terms of critical properties.
vector_fp dpdni_
Vector of derivatives of pressure wrt mole number.
virtual void setParametersFromXML(const XML_Node &thermoNode)
Set equation of state parameter values from XML entries.
virtual void calcDensity()
Calculate the density of the mixture using the partial molar volumes and mole fractions as input.
virtual doublereal standardConcentration(size_t k=0) const
Returns the standard concentration , which is used to normalize the generalized concentration.
doublereal RT() const
Return the Gas Constant multiplied by the current temperature.
virtual 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.
virtual doublereal refPressure() const
Returns the reference pressure in Pa.
virtual void setParametersFromXML(const XML_Node &eosdata)
Set equation of state parameter values from XML entries.
double convert(double value, const std::string &src, const std::string &dest) const
Convert value from the units of src to the units of dest.
Class XML_Node is a tree-based representation of the contents of an XML file.
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
std::string name() const
Returns the name of the XML node.
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
size_t nChildren(bool discardComments=false) const
Return the number of children.
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
bool hasAttrib(const std::string &a) const
Tests whether the current node has an attribute with a particular name.
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data.
const size_t npos
index returned by functions to indicate "no position"
const double SmallNumber
smallest number to compare to zero.
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
const double GasConstant
Universal Gas Constant [J/kmol/K].
void importPhase(XML_Node &phase, ThermoPhase *th)
Import a phase information into an empty ThermoPhase object.
Namespace for the Cantera kernel.
doublereal getFloatCurrent(const XML_Node &node, const std::string &type)
Get a floating-point value from the current XML element.
doublereal dot(InputIter x_begin, InputIter x_end, InputIter2 y_begin)
Function that calculates a templated inner product.
bool caseInsensitiveEquals(const std::string &input, const std::string &test)
Case insensitive equality predicate.
std::string toLowerCopy(const std::string &input)
Convert to lower case.
void scale(InputIter begin, InputIter end, OutputIter out, S scale_factor)
Multiply elements of an array by a scale factor.
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,...
doublereal strSItoDbl(const std::string &strSI)
Interpret one or two token string as a single double.
Contains declarations for string manipulation functions within Cantera.