28 const doublereal RedlichKwongMFTP::omega_a = 4.27480233540E-01;
29 const doublereal RedlichKwongMFTP::omega_b = 8.66403499650E-02;
30 const doublereal RedlichKwongMFTP::omega_vc = 3.33333333333333E-01;
32 RedlichKwongMFTP::RedlichKwongMFTP() :
33 m_standardMixingRules(0),
47 m_standardMixingRules(0),
65 "Couldn't find phase named \"" + id_ +
"\" in file, " + infile);
71 m_standardMixingRules(0),
84 throw CanteraError(
"RedlichKwongMFTP::RedlichKwongMFTP()",
"Couldn't find phase named \"" + id_ +
"\" in XML node");
90 m_standardMixingRules(0),
99 "To be removed after Cantera 2.2");
100 std::string infile =
"co2_redlichkwong.xml";
103 infile =
"co2_redlichkwong.xml";
104 id_ =
"carbondioxide";
106 throw CanteraError(
"RedlichKwongMFTP::RedlichKwongMFTP(int testProb)",
107 "test prob = 1 only");
115 throw CanteraError(
"newPhase",
"Couldn't find phase named \"" + id_ +
"\" in file, " + infile);
121 m_standardMixingRules(0),
147 a_vec_Curr_ = b.a_vec_Curr_;
148 b_vec_Curr_ = b.b_vec_Curr_;
149 a_coeff_vec = b.a_coeff_vec;
151 m_pc_Species = b.m_pc_Species;
152 m_tc_Species = b.m_tc_Species;
153 m_vc_Species = b.m_vc_Species;
155 Vroot_[0] = b.Vroot_[0];
156 Vroot_[1] = b.Vroot_[1];
157 Vroot_[2] = b.Vroot_[2];
160 m_partialMolarVolumes = b.m_partialMolarVolumes;
175 return cRedlichKwongMFTP;
186 doublereal h_nonideal =
hresid();
187 return h_ideal + h_nonideal;
195 doublereal sr_nonideal =
sresid();
196 return sr_ideal + sr_nonideal;
203 doublereal sqt = sqrt(TKelvin);
208 doublereal dadt = da_dt();
209 doublereal fac = TKelvin * dadt - 3.0 *
m_a_current / 2.0;
210 doublereal dHdT_V = (cpref + mv *
dpdT_ -
GasConstant - 1.0 / (2.0 * m_b_current * TKelvin * sqt) * log(vpb/mv) * fac
211 +1.0/(m_b_current * sqt) * log(vpb/mv) * (-0.5 * dadt));
217 throw CanteraError(
"RedlichKwongMFTP::cv_mole",
"unimplemented");
233 throw CanteraError(
" RedlichKwongMFTP::pressure()",
"setState broken down, maybe");
295 for (
size_t k = 0; k <
m_kk; k++) {
309 "To be removed after Cantera 2.2.");
313 for (
int i = 0; i < sizeUA; i++) {
318 uA[1] = -
static_cast<int>(
nDim());
341 doublereal sqt = sqrt(TKelvin);
345 for (
size_t k = 0; k <
m_kk; k++) {
347 for (
size_t i = 0; i <
m_kk; i++) {
348 size_t counter = k + m_kk*i;
354 for (
size_t k = 0; k <
m_kk; k++) {
355 ac[k] = (- rt * log(pres * mv / rt)
357 + rt * b_vec_Curr_[k] / vmb
358 - 2.0 *
m_pp[k] / (m_b_current * sqt) * log(vpb/mv)
359 +
m_a_current * b_vec_Curr_[k] / (m_b_current * m_b_current * sqt) * log(vpb/mv)
360 -
m_a_current / (m_b_current * sqt) * (b_vec_Curr_[k]/vpb)
363 for (
size_t k = 0; k <
m_kk; k++) {
364 ac[k] = exp(ac[k]/rt);
375 doublereal invRT = 1.0 /
_RT();
376 for (
size_t k = 0; k <
m_kk; k++) {
385 for (
size_t k = 0; k <
m_kk; k++) {
387 mu[k] += rt*(log(xx));
392 doublereal sqt = sqrt(TKelvin);
396 for (
size_t k = 0; k <
m_kk; k++) {
398 for (
size_t i = 0; i <
m_kk; i++) {
399 size_t counter = k + m_kk*i;
406 for (
size_t k = 0; k <
m_kk; k++) {
407 mu[k] += (rt * log(pres/refP) - rt * log(pres * mv / rt)
409 + rt * b_vec_Curr_[k] / vmb
410 - 2.0 *
m_pp[k] / (m_b_current * sqt) * log(vpb/mv)
411 +
m_a_current * b_vec_Curr_[k] / (m_b_current * m_b_current * sqt) * log(vpb/mv)
412 -
m_a_current / (m_b_current * sqt) * (b_vec_Curr_[k]/vpb)
431 doublereal sqt = sqrt(TKelvin);
436 for (
size_t k = 0; k <
m_kk; k++) {
438 for (
size_t i = 0; i <
m_kk; i++) {
439 size_t counter = k + m_kk*i;
446 for (
size_t k = 0; k <
m_kk; k++) {
447 dpdni_[k] = rt/vmb + rt * b_vec_Curr_[k] / (vmb * vmb) - 2.0 *
m_pp[k] / (sqt * mv * vpb)
448 +
m_a_current * b_vec_Curr_[k]/(sqt * mv * vpb * vpb);
450 doublereal dadt = da_dt();
451 doublereal fac = TKelvin * dadt - 3.0 *
m_a_current / 2.0;
453 for (
size_t k = 0; k <
m_kk; k++) {
455 for (
size_t i = 0; i <
m_kk; i++) {
456 size_t counter = k + m_kk*i;
462 doublereal fac2 = mv + TKelvin *
dpdT_ /
dpdV_;
464 for (
size_t k = 0; k <
m_kk; k++) {
465 double hE_v = (mv *
dpdni_[k] - rt - b_vec_Curr_[k]/ (m_b_current * m_b_current * sqt) * log(vpb/mv)*fac
466 + 1.0 / (m_b_current * sqt) * log(vpb/mv) *
m_tmpV[k]
467 + b_vec_Curr_[k] / vpb / (m_b_current * sqt) * fac);
468 hbar[k] = hbar[k] + hE_v;
471 hbar[k] -= fac2 *
dpdni_[k];
482 doublereal sqt = sqrt(TKelvin);
486 for (
size_t k = 0; k <
m_kk; k++) {
488 sbar[k] += r * (- log(xx));
491 for (
size_t k = 0; k <
m_kk; k++) {
493 for (
size_t i = 0; i <
m_kk; i++) {
494 size_t counter = k + m_kk*i;
499 for (
size_t k = 0; k <
m_kk; k++) {
501 for (
size_t i = 0; i <
m_kk; i++) {
502 size_t counter = k + m_kk*i;
508 doublereal dadt = da_dt();
509 doublereal fac = dadt -
m_a_current / (2.0 * TKelvin);
514 for (
size_t k = 0; k <
m_kk; k++) {
519 +
m_pp[k]/(m_b_current * TKelvin * sqt) * log(vpb/mv)
520 - 2.0 *
m_tmpV[k]/(m_b_current * sqt) * log(vpb/mv)
521 + b_vec_Curr_[k] / (m_b_current * m_b_current * sqt) * log(vpb/mv) * fac
522 - 1.0 / (m_b_current * sqt) * b_vec_Curr_[k] / vpb * fac
528 for (
size_t k = 0; k <
m_kk; k++) {
529 sbar[k] -= -m_partialMolarVolumes[k] *
dpdT_;
549 for (
size_t k = 0; k <
m_kk; k++) {
551 for (
size_t i = 0; i <
m_kk; i++) {
552 size_t counter = k + m_kk*i;
557 for (
size_t k = 0; k <
m_kk; k++) {
559 for (
size_t i = 0; i <
m_kk; i++) {
560 size_t counter = k + m_kk*i;
566 doublereal sqt = sqrt(TKelvin);
574 for (
size_t k = 0; k <
m_kk; k++) {
576 doublereal num = (rt + rt * m_b_current/ vmb + rt * b_vec_Curr_[k] / vmb
577 + rt * m_b_current * b_vec_Curr_[k] /(vmb * vmb)
578 - 2.0 *
m_pp[k] / (sqt * vpb)
585 vbar[k] = num / denom;
595 for (
size_t i = 0; i <
m_kk; i++) {
596 for (
size_t j = 0; j <
m_kk; j++) {
597 size_t counter = i + m_kk * j;
611 for (
size_t i = 0; i <
m_kk; i++) {
612 for (
size_t j = 0; j <
m_kk; j++) {
613 size_t counter = i + m_kk * j;
628 for (
size_t i = 0; i <
m_kk; i++) {
629 for (
size_t j = 0; j <
m_kk; j++) {
630 size_t counter = i + m_kk * j;
644 for (
size_t i = 0; i <
m_kk; i++) {
645 for (
size_t j = 0; j <
m_kk; j++) {
646 size_t counter = i + m_kk * j;
660 for (
size_t i = 0; i <
m_kk; i++) {
661 for (
size_t j = 0; j <
m_kk; j++) {
662 size_t counter = i + m_kk * j;
695 doublereal pres = 0.0;
697 for (
size_t k = 0; k <
m_kk; k++) {
698 tmp = -
m_tmpV[k] + mu_RT[k];
701 }
else if (tmp > 500.0) {
704 m_pp[k] = m_p0 * exp(500.) * tmp2;
706 m_pp[k] = m_p0 * exp(tmp);
716 a_vec_Curr_.resize(
m_kk *
m_kk, 0.0);
717 b_vec_Curr_.resize(m_kk, 0.0);
719 a_coeff_vec.
resize(2, m_kk * m_kk, 0.0);
721 m_pc_Species.resize(m_kk, 0.0);
722 m_tc_Species.resize(m_kk, 0.0);
723 m_vc_Species.resize(m_kk, 0.0);
725 m_pp.resize(m_kk, 0.0);
727 m_partialMolarVolumes.resize(m_kk, 0.0);
743 std::string model = thermoNode[
"model"];
744 if (model ==
"RedlichKwong") {
746 }
else if (model ==
"RedlichKwongMFTP") {
750 "Unknown thermo model : " + model);
758 if (thermoNode.
hasChild(
"activityCoefficients")) {
767 for (
size_t i = 0; i < nC; i++) {
769 string stemp = xmlACChild.
name();
776 if (nodeName ==
"purefluidparameters") {
787 for (
size_t i = 0; i < nC; i++) {
789 string stemp = xmlACChild.
name();
796 if (nodeName ==
"crossfluidparameters") {
804 for (
size_t i = 0; i <
m_kk; i++) {
805 double a0coeff = a_coeff_vec(0, i*m_kk + i);
806 double aTcoeff = a_coeff_vec(1, i*m_kk + i);
807 double ai = a0coeff + aTcoeff * 500.;
808 double bi = b_vec_Curr_[i];
809 calcCriticalConditions(ai, bi, a0coeff, aTcoeff, m_pc_Species[i], m_tc_Species[i], m_vc_Species[i]);
818 string xname = pureFluidParam.
name();
819 if (xname !=
"pureFluidParameters") {
820 throw CanteraError(
"RedlichKwongMFTP::readXMLPureFluid",
821 "Incorrect name for processing this routine: " + xname);
828 string iName = pureFluidParam.
attrib(
"species");
830 throw CanteraError(
"RedlichKwongMFTP::readXMLPureFluid",
"no species attribute");
833 if (iSpecies ==
npos) {
836 size_t counter = iSpecies +
m_kk * iSpecies;
837 size_t nParamsExpected, nParamsFound;
839 for (
size_t iChild = 0; iChild < num; iChild++) {
841 string stemp = xmlChild.
name();
844 if (nodeName ==
"a_coeff") {
846 if (iModel ==
"constant") {
848 }
else if (iModel ==
"linear_a") {
854 throw CanteraError(
"RedlichKwongMFTP::readXMLPureFluid",
"unknown model");
857 getFloatArray(xmlChild, vParams,
true,
"Pascal-m6/kmol2",
"a_coeff");
858 nParamsFound = vParams.size();
859 if (nParamsFound != nParamsExpected) {
860 throw CanteraError(
"RedlichKwongMFTP::readXMLPureFluid(for a_coeff" + iName +
")",
861 "wrong number of params found");
864 for (
size_t i = 0; i < nParamsFound; i++) {
865 a_coeff_vec(i, counter) = vParams[i];
867 }
else if (nodeName ==
"b_coeff") {
868 getFloatArray(xmlChild, vParams,
true,
"m3/kmol",
"b_coeff");
869 nParamsFound = vParams.size();
870 if (nParamsFound != 1) {
871 throw CanteraError(
"RedlichKwongMFTP::readXMLPureFluid(for b_coeff" + iName +
")",
872 "wrong number of params found");
874 b_vec_Curr_[iSpecies] = vParams[0];
882 for (
size_t i = 0; i <
m_kk; i++) {
883 size_t icounter = i + m_kk * i;
884 for (
size_t j = 0; j <
m_kk; j++) {
886 size_t counter = i + m_kk * j;
887 size_t jcounter = j + m_kk * j;
888 for (
int n = 0; n < nParam; n++) {
889 a_coeff_vec(n, counter) = sqrt(a_coeff_vec(n, icounter) * a_coeff_vec(n, jcounter));
899 string xname = CrossFluidParam.
name();
900 if (xname !=
"crossFluidParameters") {
901 throw CanteraError(
"RedlichKwongMFTP::readXMLCrossFluid",
902 "Incorrect name for processing this routine: " + xname);
909 string iName = CrossFluidParam.
attrib(
"species1");
911 throw CanteraError(
"RedlichKwongMFTP::readXMLCrossFluid",
"no species1 attribute");
914 if (iSpecies ==
npos) {
917 string jName = CrossFluidParam.
attrib(
"species2");
919 throw CanteraError(
"RedlichKwongMFTP::readXMLCrossFluid",
"no species2 attribute");
922 if (jSpecies ==
npos) {
926 size_t counter = iSpecies +
m_kk * jSpecies;
927 size_t counter0 = jSpecies +
m_kk * iSpecies;
928 size_t nParamsExpected, nParamsFound;
929 size_t num = CrossFluidParam.
nChildren();
930 for (
size_t iChild = 0; iChild < num; iChild++) {
932 string stemp = xmlChild.
name();
935 if (nodeName ==
"a_coeff") {
937 if (iModel ==
"constant") {
939 }
else if (iModel ==
"linear_a") {
945 throw CanteraError(
"RedlichKwongMFTP::readXMLCrossFluid",
"unknown model");
948 getFloatArray(xmlChild, vParams,
true,
"Pascal-m6/kmol2",
"a_coeff");
949 nParamsFound = vParams.size();
950 if (nParamsFound != nParamsExpected) {
951 throw CanteraError(
"RedlichKwongMFTP::readXMLCrossFluid(for a_coeff" + iName +
")",
952 "wrong number of params found");
955 for (
size_t i = 0; i < nParamsFound; i++) {
956 a_coeff_vec(i, counter) = vParams[i];
957 a_coeff_vec(i, counter0) = vParams[i];
966 std::string model = thermoNode[
"model"];
974 doublereal molarV = mmw / rho;
977 doublereal dadt = da_dt();
979 doublereal sqT = sqrt(T);
990 doublereal molarV = mmw / rho;
993 doublereal dadt = da_dt();
995 doublereal sqT = sqrt(T);
996 doublereal fac = T * dadt - 3.0 *
m_a_current / (2.0);
1007 doublereal pres = std::max(
psatEst(TKelvin), presGuess);
1010 bool foundLiq =
false;
1014 int nsol =
NicholsSolve(TKelvin, pres, atmp, btmp, Vroot);
1016 if (nsol == 1 || nsol == 2) {
1026 }
while ((m < 100) && (!foundLiq));
1046 if (rhoguess == -1.0) {
1047 if (phaseRequested != FLUID_GAS) {
1048 if (TKelvin > tcrit) {
1049 rhoguess = presPa * mmw / (
GasConstant * TKelvin);
1051 if (phaseRequested == FLUID_GAS || phaseRequested == FLUID_SUPERCRIT) {
1052 rhoguess = presPa * mmw / (
GasConstant * TKelvin);
1053 }
else if (phaseRequested >= FLUID_LIQUID_0) {
1055 rhoguess = mmw / lqvol;
1063 rhoguess = presPa * mmw / (
GasConstant * TKelvin);
1068 doublereal volguess = mmw / rhoguess;
1071 doublereal molarVolLast = Vroot_[0];
1073 if (phaseRequested >= FLUID_LIQUID_0) {
1074 molarVolLast = Vroot_[0];
1075 }
else if (phaseRequested == FLUID_GAS || phaseRequested == FLUID_SUPERCRIT) {
1076 molarVolLast = Vroot_[2];
1078 if (volguess > Vroot_[1]) {
1079 molarVolLast = Vroot_[2];
1081 molarVolLast = Vroot_[0];
1084 }
else if (NSolns_ == 1) {
1085 if (phaseRequested == FLUID_GAS || phaseRequested == FLUID_SUPERCRIT || phaseRequested == FLUID_UNDEFINED) {
1086 molarVolLast = Vroot_[0];
1090 }
else if (NSolns_ == -1) {
1091 if (phaseRequested >= FLUID_LIQUID_0 || phaseRequested == FLUID_UNDEFINED || phaseRequested == FLUID_SUPERCRIT) {
1092 molarVolLast = Vroot_[0];
1093 }
else if (TKelvin > tcrit) {
1094 molarVolLast = Vroot_[0];
1099 molarVolLast = Vroot_[0];
1102 return mmw / molarVolLast;
1110 double vmax = Vroot_[1];
1111 double vmin = Vroot_[0];
1114 rf.
setTol(1.0E-5, 1.0E-10);
1117 double vbest = 0.5 * (Vroot_[0]+Vroot_[1]);
1118 double funcNeeded = 0.0;
1120 int status = rf.
solve(vmin, vmax, 100, funcNeeded, &vbest);
1122 throw CanteraError(
" RedlichKwongMFTP::densSpinodalLiquid() ",
"didn't converge");
1133 double vmax = Vroot_[2];
1134 double vmin = Vroot_[1];
1137 rf.
setTol(1.0E-5, 1.0E-10);
1140 double vbest = 0.5 * (Vroot_[1]+Vroot_[2]);
1141 double funcNeeded = 0.0;
1143 int status = rf.
solve(vmin, vmax, 100, funcNeeded, &vbest);
1145 throw CanteraError(
" RedlichKwongMFTP::densSpinodalGas() ",
"didn't converge");
1153 doublereal sqt = sqrt(TKelvin);
1161 doublereal sqt = sqrt(TKelvin);
1167 doublereal dpdv = (-
GasConstant * TKelvin / (vmb * vmb)
1168 +
m_a_current * (2 * molarVol + m_b_current) / (sqt * molarVol * molarVol * vpb * vpb));
1180 doublereal sqt = sqrt(TKelvin);
1183 doublereal dadt = da_dt();
1184 doublereal fac = dadt -
m_a_current/(2.0 * TKelvin);
1189 void RedlichKwongMFTP::updateMixingExpressions()
1198 for (
size_t i = 0; i <
m_kk; i++) {
1199 for (
size_t j = 0; j <
m_kk; j++) {
1200 size_t counter = i * m_kk + j;
1201 a_vec_Curr_[counter] = a_coeff_vec(0,counter) + a_coeff_vec(1,counter) * temp;
1208 for (
size_t i = 0; i <
m_kk; i++) {
1210 for (
size_t j = 0; j <
m_kk; j++) {
1221 for (
size_t i = 0; i <
m_kk; i++) {
1223 for (
size_t j = 0; j <
m_kk; j++) {
1224 size_t counter = i * m_kk + j;
1225 doublereal a_vec_Curr = a_coeff_vec(0,counter) + a_coeff_vec(1,counter) * temp;
1230 for (
size_t i = 0; i <
m_kk; i++) {
1232 for (
size_t j = 0; j <
m_kk; j++) {
1233 size_t counter = i * m_kk + j;
1234 doublereal a_vec_Curr = a_coeff_vec(0,counter);
1241 doublereal RedlichKwongMFTP::da_dt()
const
1243 doublereal dadT = 0.0;
1245 for (
size_t i = 0; i <
m_kk; i++) {
1246 for (
size_t j = 0; j <
m_kk; j++) {
1247 size_t counter = i * m_kk + j;
1255 void RedlichKwongMFTP::calcCriticalConditions(doublereal a, doublereal b, doublereal a0_coeff, doublereal aT_coeff,
1256 doublereal& pc, doublereal& tc, doublereal& vc)
const
1275 doublereal sqrttc, f, dfdt, deltatc;
1282 for (
int j = 0; j < 10; j++) {
1286 deltatc = - f / dfdt;
1289 if (deltatc > 0.1) {
1290 throw CanteraError(
"RedlichKwongMFTP::calcCriticalConditions",
"didn't converge");
1299 doublereal Vroot[3])
const
1304 if (TKelvin <= 0.0) {
1305 throw CanteraError(
"RedlichKwongMFTP::NicholsSolve()",
"neg temperature");
1310 doublereal an = 1.0;
1312 doublereal sqt = sqrt(TKelvin);
1313 doublereal cn = - (
GasConstant * TKelvin * b / pres - a/(pres * sqt) + b * b);
1314 doublereal dn = - (a * b / (pres * sqt));
1318 double tc = pow(tmp, pp);
1322 doublereal xN = - bn /(3 * an);
1326 doublereal delta2 = (bn * bn - 3 * an * cn) / (9 * an * an);
1327 doublereal delta = 0.0;
1330 doublereal ratio1 = 3.0 * an * cn / (bn * bn);
1331 doublereal ratio2 = pres * b / (
GasConstant * TKelvin);
1332 if (fabs(ratio1) < 1.0E-7) {
1335 if (fabs(ratio2) < 1.0E-5 && fabs(ratio3) < 1.0E-5) {
1336 doublereal zz = 1.0;
1337 for (
int i = 0; i < 10; i++) {
1338 doublereal znew = zz / (zz - ratio2) - ratio3 / (zz + ratio1);
1339 doublereal deltaz = znew - zz;
1341 if (fabs(deltaz) < 1.0E-14) {
1353 double h2 = 4. * an * an * delta2 * delta2 * delta2;
1355 delta = sqrt(delta2);
1358 doublereal h = 2.0 * an * delta * delta2;
1360 doublereal yN = 2.0 * bn * bn * bn / (27.0 * an * an) - bn * cn / (3.0 * an) + dn;
1362 doublereal desc = yN * yN - h2;
1364 if (fabs(fabs(h) - fabs(yN)) < 1.0E-10) {
1367 printf(
"NicholsSolve(): numerical issues\n");
1368 throw CanteraError(
"NicholsSolve()",
"numerical issues");
1375 }
else if (desc == 0.0) {
1378 }
else if (desc > 0.0) {
1386 doublereal tmpD = sqrt(desc);
1387 doublereal tmp1 = (- yN + tmpD) / (2.0 * an);
1388 doublereal sgn1 = 1.0;
1393 doublereal tmp2 = (- yN - tmpD) / (2.0 * an);
1394 doublereal sgn2 = 1.0;
1399 doublereal p1 = pow(tmp1, 1./3.);
1400 doublereal p2 = pow(tmp2, 1./3.);
1402 doublereal alpha = xN + sgn1 * p1 + sgn2 * p2;
1407 tmp = an * Vroot[0] * Vroot[0] * Vroot[0] + bn * Vroot[0] * Vroot[0] + cn * Vroot[0] + dn;
1409 }
else if (desc < 0.0) {
1410 doublereal tmp = - yN/h;
1412 doublereal val = acos(tmp);
1413 doublereal theta = val / 3.0;
1416 doublereal alpha = xN + 2. * delta * cos(theta);
1418 doublereal beta = xN + 2. * delta * cos(theta + oo);
1420 doublereal gamma = xN + 2. * delta * cos(theta + 2.0 * oo);
1427 for (
int i = 0; i < 3; i++) {
1428 tmp = an * Vroot[i] * Vroot[i] * Vroot[i] + bn * Vroot[i] * Vroot[i] + cn * Vroot[i] + dn;
1429 if (fabs(tmp) > 1.0E-4) {
1430 for (
int j = 0; j < 3; j++) {
1432 if (fabs(Vroot[i] - Vroot[j]) < 1.0E-4 * (fabs(Vroot[i]) + fabs(Vroot[j]))) {
1433 writelog(
"RedlichKwongMFTP::NicholsSolve(T = " +
fp2str(TKelvin) +
", p = " +
1434 fp2str(pres) +
"): WARNING roots have merged: " +
1442 }
else if (desc == 0.0) {
1443 if (yN == 0.0 && h == 0.0) {
1450 tmp = pow(yN/(2*an), 1./3.);
1451 if (fabs(tmp - delta) > 1.0E-9) {
1452 throw CanteraError(
"RedlichKwongMFTP::NicholsSolve()",
"unexpected");
1454 Vroot[1] = xN + delta;
1455 Vroot[0] = xN - 2.0*delta;
1457 tmp = pow(yN/(2*an), 1./3.);
1458 if (fabs(tmp - delta) > 1.0E-9) {
1459 throw CanteraError(
"RedlichKwongMFTP::NicholsSolve()",
"unexpected");
1462 Vroot[0] = xN + delta;
1463 Vroot[1] = xN - 2.0*delta;
1466 for (
int i = 0; i < 2; i++) {
1467 tmp = an * Vroot[i] * Vroot[i] * Vroot[i] + bn * Vroot[i] * Vroot[i] + cn * Vroot[i] + dn;
1474 double res, dresdV = 0.0;
1475 for (
int i = 0; i < nSolnValues; i++) {
1476 for (
int n = 0; n < 20; n++) {
1477 res = an * Vroot[i] * Vroot[i] * Vroot[i] + bn * Vroot[i] * Vroot[i] + cn * Vroot[i] + dn;
1478 if (fabs(res) < 1.0E-14) {
1481 dresdV = 3.0 * an * Vroot[i] * Vroot[i] + 2.0 * bn * Vroot[i] + cn;
1482 double del = - res / dresdV;
1485 if (fabs(del) / (fabs(Vroot[i]) + fabs(del)) < 1.0E-14) {
1488 double res2 = an * Vroot[i] * Vroot[i] * Vroot[i] + bn * Vroot[i] * Vroot[i] + cn * Vroot[i] + dn;
1489 if (fabs(res2) < fabs(res)) {
1493 Vroot[i] += 0.1 * del;
1496 if ((fabs(res) > 1.0E-14) && (fabs(res) > 1.0E-14 * fabs(dresdV) * fabs(Vroot[i]))) {
1497 writelog(
"RedlichKwongMFTP::NicholsSolve(T = " +
fp2str(TKelvin) +
", p = " +
1498 fp2str(pres) +
"): WARNING root didn't converge V = " +
fp2str(Vroot[i]));
1503 if (nSolnValues == 1) {
1505 if (Vroot[0] < vc) {
1509 if (Vroot[0] < xN) {
1515 if (nSolnValues == 2) {
int NicholsSolve(double TKelvin, double pres, doublereal a, doublereal b, doublereal Vroot[3]) const
Solve the cubic equation of state.
RedlichKwongMFTP & operator=(const RedlichKwongMFTP &right)
Assignment operator.
virtual doublereal density() const
Density (kg/m^3).
This class can handle either an ideal solution or an ideal gas approximation of a phase...
doublereal m_b_current
Value of b in the equation of state.
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Initialize a ThermoPhase object, potentially reading activity coefficient information from an XML dat...
doublereal dpdV_
The derivative of the pressure wrt the volume.
XML_Node * get_XML_File(const std::string &file, int debug)
Return a pointer to the XML tree for a Cantera input file.
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data...
virtual void getPartialMolarIntEnergies(doublereal *ubar) const
Get the species partial molar enthalpies. Units: J/kmol.
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
void resize(size_t n, size_t m, doublereal v=0.0)
Resize the array, and fill the new entries with 'v'.
virtual doublereal pressure() const
Return the thermodynamic pressure (Pa).
vector_fp m_tmpV
Temporary storage - length = m_kk.
virtual void getGibbs_ref(doublereal *g) const
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol/K.
doublereal _RT() const
Return the Gas Constant multiplied by the current temperature.
const size_t npos
index returned by functions to indicate "no position"
RedlichKwongMFTP()
Base constructor.
Headers for the factory class that can create known ThermoPhase objects (see Thermodynamic Properties...
doublereal z() const
Calculate the value of z.
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 densityCalc(doublereal TKelvin, doublereal pressure, int phase, doublereal rhoguess)
Calculates the density given the temperature and the pressure and a guess at the density.
virtual void setMoleFractions(const doublereal *const x)
Set the mole fractions to the specified values, and then normalize them so that they sum to 1...
Class XML_Node is a tree-based representation of the contents of an XML file.
virtual ThermoPhase * duplMyselfAsThermoPhase() const
Duplicator from the ThermoPhase parent class.
virtual doublereal enthalpy_mole() const
Molar enthalpy. Units: J/kmol.
MixtureFugacityTP & operator=(const MixtureFugacityTP &b)
Assignment operator.
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
Header file for implicit nonlinear solver of a one dimensional function (see Numerical Utilities with...
void readXMLPureFluid(XML_Node &pureFluidParam)
Read the pure species RedlichKwong input parameters.
virtual void getPartialMolarCp(doublereal *cpbar) const
Get the partial molar heat capacities Units: J/kmol/K.
virtual int eosType() const
Equation of state type flag.
void setFuncIsGenerallyDecreasing(bool value)
Set the function behavior flag.
virtual void getGibbs_RT_ref(doublereal *grt) const
Returns the vector of nondimensional Gibbs free energies of the reference state at the current temper...
std::string lowercase(const std::string &s)
Cast a copy of a string to lower case.
virtual void setMassFractions(const doublereal *const y)
Set the mass fractions to the specified values, and then normalize them so that they sum to 1...
virtual void initThermo()
virtual void getEnthalpy_RT_ref(doublereal *hrt) const
Returns the vector of nondimensional enthalpies of the reference state at the current temperature of ...
virtual void getPartialMolarVolumes(doublereal *vbar) const
Get the species partial molar volumes. Units: m^3/kmol.
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Initialize a ThermoPhase object, potentially reading activity coefficient information from an XML dat...
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
Base class for a phase with thermodynamic properties.
void setToEquilState(const doublereal *lambda_RT)
This method is used by the ChemEquil equilibrium solver.
vector_fp m_s0_R
Temporary storage for dimensionless reference state entropies.
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...
doublereal mean_X(const doublereal *const Q) const
Evaluate the mole-fraction-weighted mean of an array Q.
doublereal m_Pcurrent
Current value of the pressures.
int m_standardMixingRules
boolean indicating whether standard mixing rules are applied
size_t speciesIndex(const std::string &name) const
Returns the index of a species named 'name' within the Phase object.
static const doublereal omega_b
Omega constant for b.
bool importPhase(XML_Node &phase, ThermoPhase *th, SpeciesThermoFactory *spfactory)
Import a phase information into an empty ThermoPhase object.
virtual void setMoleFractions_NoNorm(const doublereal *const x)
Set the mole fractions to the specified values without normalizing.
int m_formTempParam
Form of the temperature parameterization.
virtual void setMassFractions_NoNorm(const doublereal *const y)
Set the mass fractions to the specified values without normalizing.
void setTol(doublereal rtolf, doublereal atolf, doublereal rtolx=0.0, doublereal atolx=0.0)
Set the tolerance parameters for the rootfinder.
virtual void setMassFractions(const doublereal *const y)
Set the mass fractions to the specified values, and then normalize them so that they sum to 1...
virtual void initThermo()
virtual doublereal psatEst(doublereal TKelvin) const
Estimate for the saturation pressure.
Root finder for 1D problems.
void setFuncIsGenerallyIncreasing(bool value)
Set the function behavior flag.
doublereal dpdT_
The derivative of the pressure wrt the temperature.
doublereal m_a_current
Value of a in the equation of state.
virtual doublereal sresid() const
Calculate the deviation terms for the total entropy of the mixture from the ideal gas mixture...
doublereal molarVolume() const
Molar volume (m^3/kmol).
virtual void setConcentrations(const doublereal *const c)
Set the concentrations to the specified values within the phase.
doublereal sum_xlogx() const
Evaluate .
void pressureDerivatives() const
Calculate dpdV and dpdT at the current conditions.
std::string fp2str(const double x, const std::string &fmt)
Convert a double into a c++ string.
virtual void setMoleFractions(const doublereal *const x)
Set the mole fractions to the specified values, and then normalize them so that they sum to 1...
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
vector_fp m_pp
Temporary storage - length = m_kk.
std::string name() const
Returns the name of the XML node.
virtual void setParametersFromXML(const XML_Node &thermoNode)
Set equation of state parameter values from XML entries.
Definition file for a derived class of ThermoPhase that assumes either an ideal gas or ideal solution...
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 void setMassFractions_NoNorm(const doublereal *const y)
Set the mass fractions to the specified values without normalizing.
virtual doublereal standardConcentration(size_t k=0) const
Returns the standard concentration , which is used to normalize the generalized concentration.
std::vector< doublereal > moleFractions_
Storage for the current values of the mole fractions of the species.
virtual doublereal refPressure(size_t k=npos) const =0
The reference-state pressure for species k.
virtual void setConcentrations(const doublereal *const c)
Set the concentrations to the specified values within the phase.
Base class for exceptions thrown by Cantera classes.
virtual doublereal cp_mole() const
Molar heat capacity at constant pressure. Units: J/kmol/K.
virtual void setTemperature(const doublereal temp)
Set the temperature (K)
virtual doublereal hresid() const
Calculate the deviation terms for the total enthalpy of the mixture from the ideal gas mixture...
virtual doublereal critDensity() const
Critical density (kg/m3).
void readXMLCrossFluid(XML_Node &pureFluidParam)
Read the cross species RedlichKwong input parameters.
virtual doublereal liquidVolEst(doublereal TKelvin, doublereal &pres) const
Estimate for the molar volume of the liquid.
virtual void calcDensity()
Calculate the density of the mixture using the partial molar volumes and mole fractions as input...
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
doublereal dot(InputIter x_begin, InputIter x_end, InputIter2 y_begin)
Function that calculates a templated inner product.
static const doublereal omega_a
Omega constant for a -> value of a in terms of critical properties.
virtual void getActivityConcentrations(doublereal *c) const
This method returns an array of generalized concentrations.
virtual void getIntEnergy_RT(doublereal *urt) const
Returns the vector of nondimensional internal Energies of the standard state at the current temperatu...
virtual doublereal refPressure() const
Returns the reference pressure in Pa.
int solve(doublereal xmin, doublereal xmax, int itmax, doublereal &funcTargetValue, doublereal *xbest)
Using a line search method, find the root of a 1D function.
virtual doublereal densSpinodalGas() const
Return the value of the density at the gas spinodal point (on the gas side) for the current temperatu...
void writelogendl()
Write an end of line character to the screen and flush output.
doublereal moleFraction(size_t k) const
Return the mole fraction of a single species.
doublereal temperature() const
Temperature (K).
size_t nDim() const
Returns the number of spatial dimensions (1, 2, or 3)
virtual doublereal critPressure() const
Critical pressure (Pa).
virtual doublereal critCompressibility() const
Critical compressibility (unitless).
const doublereal 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.
void calculateAB(doublereal temp, doublereal &aCalc, doublereal &bCalc) const
Calculate the a and the b parameters given the temperature.
virtual void setTemperature(const doublereal temp)
Set the internally stored temperature of the phase (K).
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, std::vector< doublereal > &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...
virtual void setParametersFromXML(const XML_Node &eosdata)
Set equation of state parameter values from XML entries.
doublereal meanMolecularWeight() const
The mean molecular weight. Units: (kg/kmol)
const doublereal GasConstant
Universal Gas Constant. [J/kmol/K].
virtual void setState_PX(doublereal p, doublereal *x)
Set the pressure (Pa) and mole fractions.
Contains declarations for string manipulation functions within Cantera.
#define DATA_PTR(vec)
Creates a pointer to the start of the raw data for a vector.
virtual void getPartialMolarEnthalpies(doublereal *hbar) const
Get the species partial molar enthalpies. Units: J/kmol.
static const doublereal omega_vc
Omega constant for the critical molar volume.
virtual doublereal densSpinodalLiquid() const
Return the value of the density at the liquid spinodal point (on the liquid side) for the current tem...
virtual doublereal cv_mole() const
Molar heat capacity at constant volume. Units: J/kmol/K.
void writelog(const std::string &msg)
Write a message to the screen.
virtual void getUnitsStandardConc(double *uA, int k=0, int sizeUA=6) const
Returns the units of the standard and generalized concentrations.
size_t m_kk
Number of species in the phase.
void applyStandardMixingRules()
Apply mixing rules for a coefficients.
virtual void getEntropy_R_ref(doublereal *er) const
virtual doublereal pressureCalc(doublereal TKelvin, doublereal molarVol) const
Calculate the pressure given the temperature and the molar volume.
void setPrintLvl(int printLvl)
Set the print level from the rootfinder.
virtual void _updateReferenceStateThermo() const
Updates the reference state thermodynamic functions at the current T of the solution.
void getChemPotentials_RT(doublereal *mu) const
Get the array of non-dimensional species chemical potentials.
virtual doublereal critTemperature() const
Critical temperature (K).
virtual void getPartialMolarEntropies(doublereal *sbar) const
Get the species partial molar entropies. Units: J/kmol/K.
#define ROOTFIND_SUCCESS
This means that the root solver was a success.
vector_fp dpdni_
Vector of derivatives of pressure wrt mole number.
SpeciesThermo * m_spthermo
Pointer to the calculation manager for species reference-state thermodynamic properties.
void updateAB()
Update the a and b parameters.
const doublereal * moleFractdivMMW() const
Returns a const pointer to the start of the moleFraction/MW array.
XML_Node * get_XML_NameID(const std::string &nameTarget, const std::string &file_ID, XML_Node *root)
This routine will locate an XML node in either the input XML tree or in another input file specified ...
size_t nChildren(bool discardComments=false) const
Return the number of children.
virtual void getActivityCoefficients(doublereal *ac) const
Get the array of non-dimensional activity coefficients at the current solution temperature, pressure, and solution concentration.
virtual void setDensity(const doublereal density_)
Set the internally stored density (kg/m^3) of the phase Note the density of a phase is an independent...
vector_fp m_h0_RT
Temporary storage for dimensionless reference state enthalpies.
vector_fp m_cp0_R
Temporary storage for dimensionless reference state heat capacities.
virtual doublereal critVolume() const
Critical volume (m3/kmol)