28double A_Debye_default = 1.172576;
29double maxIionicStrength_default = 100.0;
30double crop_ln_gamma_o_min_default = -6.0;
31double crop_ln_gamma_o_max_default = 3.0;
32double crop_ln_gamma_k_min_default = -5.0;
33double crop_ln_gamma_k_max_default = 15.0;
42 m_maxIionicStrength(maxIionicStrength_default),
43 CROP_ln_gamma_o_min(crop_ln_gamma_o_min_default),
44 CROP_ln_gamma_o_max(crop_ln_gamma_o_max_default),
45 CROP_ln_gamma_k_min(crop_ln_gamma_k_min_default),
46 CROP_ln_gamma_k_max(crop_ln_gamma_k_max_default),
59 for (
size_t k = 0; k <
m_kk; k++) {
71 size_t kcation =
npos;
74 for (
size_t k = 0; k <
m_kk; k++) {
80 }
else if (
charge(k) < 0.0) {
87 if (kcation ==
npos || kanion ==
npos) {
90 double xuse = xcation;
92 if (xanion < xcation) {
94 if (
charge(kcation) != 1.0) {
98 if (
charge(kanion) != 1.0) {
102 xuse = xuse / factor;
113 return cp - beta * beta * tt * molarV / kappa_t;
139 for (
size_t k = 1; k <
m_kk; k++) {
152 return 1.0 / mvSolvent;
165 for (
size_t k = 1; k <
m_kk; k++) {
174 checkArraySize(
"HMWSoln::getUnscaledMolalityActivityCoefficients",
175 acMolality.size(),
m_kk);
181 for (
size_t k = 0; k <
m_kk; k++) {
182 acMolality[k] = exp(acMolality[k]);
200 for (
size_t k = 1; k <
m_kk; k++) {
214 for (
size_t k = 0; k <
m_kk; k++) {
222 for (
size_t k = 0; k <
m_kk; k++) {
234 for (
size_t k = 0; k <
m_kk; k++) {
245 for (
size_t k = 1; k <
m_kk; k++) {
257 for (
size_t k = 0; k <
m_kk; k++) {
270 for (
size_t k = 0; k <
m_kk; k++) {
278 for (
size_t k = 0; k <
m_kk; k++) {
287 for (
size_t k = 0; k <
m_kk; k++) {
307static void check_nParams(
const string& method,
size_t m_formPitzerTemp,
308 const vector<span<const double>> paramLists)
310 for (
const auto& params : paramLists) {
311 size_t nParams = params.size();
312 if (m_formPitzerTemp == PITZER_TEMP_CONSTANT && nParams != 1) {
313 throw CanteraError(method,
"'constant' temperature model requires one"
314 " coefficient for each of parameter, but {} were given", nParams);
315 }
else if (m_formPitzerTemp == PITZER_TEMP_LINEAR && nParams != 2) {
316 throw CanteraError(method,
"'linear' temperature model requires two"
317 " coefficients for each parameter, but {} were given", nParams);
319 if (m_formPitzerTemp == PITZER_TEMP_COMPLEX1 && nParams != 5) {
320 throw CanteraError(method,
"'complex' temperature model requires five"
321 " coefficients for each parameter, but {} were given", nParams);
328void HMWSoln::setBinarySalt(
const string& sp1,
const string& sp2,
329 span<const double> beta0, span<const double> beta1,
330 span<const double> beta2, span<const double> Cphi,
double alpha1,
338 throw CanteraError(
"HMWSoln::setBinarySalt",
"Species '{}' and '{}' "
339 "do not have opposite charges ({}, {})", sp1, sp2,
342 check_nParams(
"HMWSoln::setBinarySalt",
m_formPitzerTemp, {beta0, beta1, Cphi});
349 for (
size_t n = 0; n < beta0.size(); n++) {
355 m_Alpha1MX_ij[c] = alpha1;
359void HMWSoln::setTheta(
const string& sp1,
const string& sp2, span<const double> theta)
364 throw CanteraError(
"HMWSoln::setTheta",
"Species '{}' and '{}' "
365 "should both have the same (non-zero) charge ({}, {})", sp1, sp2,
371 for (
size_t n = 0; n < theta.size(); n++) {
376void HMWSoln::setPsi(
const string& sp1,
const string& sp2,
377 const string& sp3, span<const double> psi)
385 throw CanteraError(
"HMWSoln::setPsi",
"All species must be ions and"
386 " must include at least one cation and one anion, but given species"
387 " (charges) were: {} ({}), {} ({}), and {} ({}).",
398 for (
size_t n = 0; n < psi.size(); n++) {
405void HMWSoln::setLambda(
const string& sp1,
const string& sp2, span<const double> lambda)
411 throw CanteraError(
"HMWSoln::setLambda",
"Expected at least one neutral"
412 " species, but given species (charges) were: {} ({}) and {} ({}).",
419 size_t c = k1*
m_kk + k2;
420 for (
size_t n = 0; n < lambda.size(); n++) {
426void HMWSoln::setMunnn(
const string& sp, span<const double> munnn)
431 throw CanteraError(
"HMWSoln::setMunnn",
"Expected a neutral species,"
432 " got {} ({}).", sp,
charge(k));
435 for (
size_t n = 0; n < munnn.size(); n++) {
441void HMWSoln::setZeta(
const string& sp1,
const string& sp2,
442 const string& sp3, span<const double> psi)
450 throw CanteraError(
"HMWSoln::setZeta",
"Requires one neutral species, "
451 "one cation, and one anion, but given species (charges) were: "
452 "{} ({}), {} ({}), and {} ({}).",
459 }
else if (
charge(k3) == 0) {
471 for (
size_t n = 0; n < psi.size(); n++) {
477void HMWSoln::setPitzerTempModel(
const string& model)
486 throw CanteraError(
"HMWSoln::setPitzerTempModel",
487 "Unknown Pitzer ActivityCoeff Temp model: {}", model);
501void HMWSoln::setCroppingCoefficients(
double ln_gamma_k_min,
502 double ln_gamma_k_max,
double ln_gamma_o_min,
double ln_gamma_o_max)
504 CROP_ln_gamma_k_min = ln_gamma_k_min;
505 CROP_ln_gamma_k_max = ln_gamma_k_max;
506 CROP_ln_gamma_o_min = ln_gamma_o_min;
507 CROP_ln_gamma_o_max = ln_gamma_o_max;
510vector<double> getSizedVector(
const AnyMap& item,
const string& key,
size_t nCoeffs)
513 if (item[key].is<double>()) {
516 v.push_back(item[key].asDouble());
518 v = item[key].asVector<
double>(1, nCoeffs);
520 if (v.size() == 1 && nCoeffs == 5) {
533 setPitzerTempModel(actData[
"temperature-model"].asString());
541 if (actData.hasKey(
"A_Debye")) {
542 if (actData[
"A_Debye"] ==
"variable") {
545 setA_Debye(actData.convert(
"A_Debye",
"kg^0.5/gmol^0.5"));
548 if (actData.hasKey(
"max-ionic-strength")) {
549 setMaxIonicStrength(actData[
"max-ionic-strength"].asDouble());
551 if (actData.hasKey(
"interactions")) {
552 for (
auto& item : actData[
"interactions"].asVector<
AnyMap>()) {
553 auto&
species = item[
"species"].asVector<
string>(1, 3);
558 if (nsp == 2 && q0 * q1 < 0) {
560 vector<double> beta0 = getSizedVector(item,
"beta0", nCoeffs);
561 vector<double> beta1 = getSizedVector(item,
"beta1", nCoeffs);
562 vector<double> beta2 = getSizedVector(item,
"beta2", nCoeffs);
563 vector<double> Cphi = getSizedVector(item,
"Cphi", nCoeffs);
564 if (beta0.size() != beta1.size() || beta0.size() != beta2.size()
565 || beta0.size() != Cphi.size()) {
567 "Inconsistent binary salt array sizes ({}, {}, {}, {})",
568 beta0.size(), beta1.size(), beta2.size(), Cphi.size());
570 double alpha1 = item[
"alpha1"].asDouble();
571 double alpha2 = item.getDouble(
"alpha2", 0.0);
573 beta0, beta1, beta2, Cphi, alpha1, alpha2);
574 }
else if (nsp == 2 && q0 * q1 > 0) {
576 vector<double> theta = getSizedVector(item,
"theta", nCoeffs);
578 }
else if (nsp == 2 && q0 * q1 == 0) {
580 vector<double> lambda = getSizedVector(item,
"lambda", nCoeffs);
582 }
else if (nsp == 3 && q0 * q1 * q2 != 0) {
584 vector<double> psi = getSizedVector(item,
"psi", nCoeffs);
586 }
else if (nsp == 3 && q0 * q1 * q2 == 0) {
588 vector<double> zeta = getSizedVector(item,
"zeta", nCoeffs);
590 }
else if (nsp == 1) {
592 vector<double> mu = getSizedVector(item,
"mu", nCoeffs);
597 if (actData.hasKey(
"cropping-coefficients")) {
598 auto& crop = actData[
"cropping-coefficients"].as<
AnyMap>();
599 setCroppingCoefficients(
600 crop.getDouble(
"ln_gamma_k_min", crop_ln_gamma_k_min_default),
601 crop.getDouble(
"ln_gamma_k_max", crop_ln_gamma_k_max_default),
602 crop.getDouble(
"ln_gamma_o_min", crop_ln_gamma_o_min_default),
603 crop.getDouble(
"ln_gamma_o_max", crop_ln_gamma_o_max_default));
609 for (
int i = 0; i < 17; i++) {
623 vector<double> mf(
m_kk, 0.0);
631 for (
size_t k = 0; k <
m_kk; k++) {
633 if (fabs(mf[k] *
charge(k)) > MaxC) {
640 if (fabs(sum) > 1.0E-30) {
642 if (mf[kHp] > sum * 1.1) {
656 if (mf[kOHm] > -sum * 1.1) {
668 if (notDone && kMaxC !=
npos) {
669 if (mf[kMaxC] > (1.1 * sum /
charge(kMaxC))) {
670 mf[kMaxC] -= sum /
charge(kMaxC);
671 mf[0] += sum /
charge(kMaxC);
690void assignTrimmed(
AnyMap& interaction,
const string& key, vector<double>& values) {
691 while (values.size() > 1 && values.back() == 0) {
694 if (values.size() == 1) {
695 interaction[key] = values[0];
697 interaction[key] = values;
707 activityNode[
"temperature-model"] =
"linear";
710 activityNode[
"temperature-model"] =
"complex";
715 activityNode[
"A_Debye"] =
"variable";
716 }
else if (
m_A_Debye != A_Debye_default) {
717 activityNode[
"A_Debye"].setQuantity(
m_A_Debye,
"kg^0.5/gmol^0.5");
723 vector<AnyMap> interactions;
726 for (
size_t i = 1; i <
m_kk; i++) {
727 for (
size_t j = 1; j <
m_kk; j++) {
728 size_t c = i*
m_kk + j;
730 bool lambda_found =
false;
731 for (
size_t n = 0; n < nParams; n++) {
739 interaction[
"species"] = vector<string>{
741 vector<double> lambda(nParams);
742 for (
size_t n = 0; n < nParams; n++) {
745 assignTrimmed(interaction,
"lambda", lambda);
746 interactions.push_back(std::move(interaction));
751 if (c == 0 || i > j) {
756 bool salt_found =
false;
757 for (
size_t n = 0; n < nParams; n++) {
767 interaction[
"species"] = vector<string>{
769 vector<double> beta0(nParams), beta1(nParams), beta2(nParams), Cphi(nParams);
770 size_t last_nonzero = 0;
771 for (
size_t n = 0; n < nParams; n++) {
776 if (beta0[n] || beta1[n] || beta2[n] || Cphi[n]) {
780 if (last_nonzero == 0) {
781 interaction[
"beta0"] = beta0[0];
782 interaction[
"beta1"] = beta1[0];
783 interaction[
"beta2"] = beta2[0];
784 interaction[
"Cphi"] = Cphi[0];
786 beta0.resize(1 + last_nonzero);
787 beta1.resize(1 + last_nonzero);
788 beta2.resize(1 + last_nonzero);
789 Cphi.resize(1 + last_nonzero);
790 interaction[
"beta0"] = beta0;
791 interaction[
"beta1"] = beta1;
792 interaction[
"beta2"] = beta2;
793 interaction[
"Cphi"] = Cphi;
795 interaction[
"alpha1"] = m_Alpha1MX_ij[c];
799 interactions.push_back(std::move(interaction));
804 bool theta_found =
false;
805 for (
size_t n = 0; n < nParams; n++) {
813 interaction[
"species"] = vector<string>{
815 vector<double> theta(nParams);
816 for (
size_t n = 0; n < nParams; n++) {
819 assignTrimmed(interaction,
"theta", theta);
820 interactions.push_back(std::move(interaction));
829 for (
size_t i = 1; i <
m_kk; i++) {
833 for (
size_t j = i + 1; j <
m_kk; j++) {
837 for (
size_t k = j + 1; k <
m_kk; k++) {
842 for (
size_t n = 0; n < nParams; n++) {
845 interaction[
"species"] = vector<string>{
847 vector<double> psi(nParams);
848 for (
size_t m = 0; m < nParams; m++) {
851 assignTrimmed(interaction,
"psi", psi);
852 interactions.push_back(std::move(interaction));
861 for (
size_t i = 1; i <
m_kk; i++) {
865 for (
size_t j = 1; j <
m_kk; j++) {
869 for (
size_t k = 1; k <
m_kk; k++) {
874 for (
size_t n = 0; n < nParams; n++) {
877 interaction[
"species"] = vector<string>{
879 vector<double> zeta(nParams);
880 for (
size_t m = 0; m < nParams; m++) {
883 assignTrimmed(interaction,
"zeta", zeta);
884 interactions.push_back(std::move(interaction));
893 for (
size_t i = 1; i <
m_kk; i++) {
894 for (
size_t n = 0; n < nParams; n++) {
897 interaction[
"species"] = vector<string>{
speciesName(i)};
898 vector<double> mu(nParams);
899 for (
size_t m = 0; m < nParams; m++) {
902 assignTrimmed(interaction,
"mu", mu);
903 interactions.push_back(std::move(interaction));
909 activityNode[
"interactions"] = std::move(interactions);
912 if (CROP_ln_gamma_k_min != crop_ln_gamma_k_min_default) {
913 croppingCoeffs[
"ln_gamma_k_min"] = CROP_ln_gamma_k_min;
915 if (CROP_ln_gamma_k_max != crop_ln_gamma_k_max_default) {
916 croppingCoeffs[
"ln_gamma_k_max"] = CROP_ln_gamma_k_max;
918 if (CROP_ln_gamma_o_min != crop_ln_gamma_o_min_default) {
919 croppingCoeffs[
"ln_gamma_o_min"] = CROP_ln_gamma_o_min;
921 if (CROP_ln_gamma_o_max != crop_ln_gamma_o_max_default) {
922 croppingCoeffs[
"ln_gamma_o_max"] = CROP_ln_gamma_o_max;
924 if (croppingCoeffs.
size()) {
925 activityNode[
"cropping-coefficients"] = std::move(croppingCoeffs);
928 phaseNode[
"activity-data"] = std::move(activityNode);
935 if (tempArg != -1.0) {
939 if (presArg != -1.0) {
958 throw CanteraError(
"HMWSoln::A_Debye_TP",
"shouldn't be here");
966 if (tempArg != -1.0) {
970 if (presArg != -1.0) {
982 throw CanteraError(
"HMWSoln::dA_DebyedT_TP",
"shouldn't be here");
990 if (tempArg != -1.0) {
994 if (presArg != -1.0) {
1007 dAdP = cached.
value;
1010 cached.
value = dAdP;
1014 throw CanteraError(
"HMWSoln::dA_DebyedP_TP",
"shouldn't be here");
1022 double dAphidT = dAdT /3.0;
1024 if (tempArg != -1.0) {
1033 double dAphidP = dAdP /3.0;
1035 if (tempArg != -1.0) {
1044 if (tempArg != -1.0) {
1049 double d2Aphi = d2 / 3.0;
1050 return 2.0 * A_L / T + 4.0 *
GasConstant * T * T *d2Aphi;
1056 if (tempArg != -1.0) {
1060 if (presArg != -1.0) {
1072 throw CanteraError(
"HMWSoln::d2A_DebyedT2_TP",
"shouldn't be here");
1086 size_t maxCounterIJlen = 1 + (
m_kk-1) * (
m_kk-2) / 2;
1089 int TCoeffLength = 1;
1120 m_Alpha1MX_ij.resize(maxCounterIJlen, 2.0);
1161 m_BMX_IJ.resize(maxCounterIJlen, 0.0);
1173 m_Phi_IJ.resize(maxCounterIJlen, 0.0);
1182 m_CMX_IJ.resize(maxCounterIJlen, 0.0);
1222 double lnActCoeffMolal0 = - log(xx) + (xx - 1.0)/xx;
1223 double lnxs = log(xx);
1225 for (
size_t k = 1; k <
m_kk; k++) {
1263 for (
size_t k = 0; k <
m_kk; k++) {
1269 if (cropMethod == 0) {
1276 for (
size_t i = 1; i < (
m_kk - 1); i++) {
1277 double charge_i =
charge(i);
1278 double abs_charge_i = fabs(charge_i);
1279 if (charge_i == 0.0) {
1282 for (
size_t j = (i+1); j <
m_kk; j++) {
1283 double charge_j =
charge(j);
1284 double abs_charge_j = fabs(charge_j);
1287 if (charge_i * charge_j < 0) {
1292 if (Imax > Iac_max) {
1296 if (Imax > Iac_max) {
1301 if (Imax > Iac_max) {
1305 if (Imax > Iac_max) {
1315 for (
int times = 0; times< 10; times++) {
1316 double anion_charge = 0.0;
1317 double cation_charge = 0.0;
1318 size_t anion_contrib_max_i =
npos;
1319 double anion_contrib_max = -1.0;
1320 size_t cation_contrib_max_i =
npos;
1321 double cation_contrib_max = -1.0;
1322 for (
size_t i = 0; i <
m_kk; i++) {
1323 double charge_i =
charge(i);
1324 if (charge_i < 0.0) {
1326 anion_charge += anion_contrib;
1327 if (anion_contrib > anion_contrib_max) {
1328 anion_contrib_max = anion_contrib;
1329 anion_contrib_max_i = i;
1331 }
else if (charge_i > 0.0) {
1333 cation_charge += cation_contrib;
1334 if (cation_contrib > cation_contrib_max) {
1335 cation_contrib_max = cation_contrib;
1336 cation_contrib_max_i = i;
1340 double total_charge = cation_charge - anion_charge;
1341 if (total_charge > 1.0E-8) {
1342 double desiredCrop = total_charge/
charge(cation_contrib_max_i);
1344 if (desiredCrop < maxCrop) {
1350 }
else if (total_charge < -1.0E-8) {
1351 double desiredCrop = total_charge/
charge(anion_contrib_max_i);
1353 if (desiredCrop < maxCrop) {
1365 if (cropMethod == 1) {
1368 double xmolSolvent = molF[0];
1374 double poly = MC_apCut_ + MC_bpCut_ * xmolSolvent + MC_dpCut_* xmolSolvent * xmolSolvent;
1375 double p = xmolSolvent + MC_epCut_ + exp(- xmolSolvent/ MC_cpCut_) * poly;
1377 for (
size_t k = 0; k <
m_kk; k++) {
1385 for (
size_t k = 0; k <
m_kk; k++) {
1390 for (
size_t k = 0; k <
m_kk; k++) {
1403 for (
size_t i = 0; i <
m_kk; i++) {
1405 size_t nc =
m_kk * i;
1409 for (
size_t i = 1; i < (
m_kk - 1); i++) {
1410 size_t n =
m_kk * i + i;
1412 for (
size_t j = (i+1); j <
m_kk; j++) {
1414 size_t nc =
m_kk * i + j;
1424 double IMS_gamma_o_min_ = 1.0E-5;
1425 double IMS_gamma_k_min_ = 10.0;
1426 double IMS_slopefCut_ = 0.6;
1428 IMS_afCut_ = 1.0 / (std::exp(1.0) * IMS_gamma_k_min_);
1430 bool converged =
false;
1432 for (
int its = 0; its < 100 && !converged; its++) {
1434 IMS_afCut_ = 1.0 / (std::exp(1.0) * IMS_gamma_k_min_) -IMS_efCut_;
1435 IMS_bfCut_ = IMS_afCut_ /
IMS_cCut_ + IMS_slopefCut_ - 1.0;
1441 IMS_efCut_ = - eterm * tmp;
1442 if (fabs(IMS_efCut_ - oldV) < 1.0E-14) {
1448 " failed to converge on the f polynomial");
1451 double f_0 = IMS_afCut_ + IMS_efCut_;
1452 double f_prime_0 = 1.0 - IMS_afCut_ /
IMS_cCut_ + IMS_bfCut_;
1454 for (
int its = 0; its < 100 && !converged; its++) {
1456 double lng_0 = -log(IMS_gamma_o_min_) - f_prime_0 / f_0;
1457 IMS_agCut_ = exp(lng_0) - IMS_egCut_;
1464 IMS_egCut_ = - eterm * tmp;
1465 if (fabs(IMS_egCut_ - oldV) < 1.0E-14) {
1471 " failed to converge on the g polynomial");
1477 double MC_X_o_min_ = 0.35;
1479 double MC_slopepCut_ = 0.02;
1483 MC_apCut_ = MC_X_o_min_;
1485 bool converged =
false;
1488 for (
int its = 0; its < 500 && !converged; its++) {
1490 MC_apCut_ = damp *(MC_X_o_min_ - MC_epCut_) + (1-damp) * MC_apCut_;
1491 double MC_bpCutNew = MC_apCut_ / MC_cpCut_ + MC_slopepCut_ - 1.0;
1492 MC_bpCut_ = damp * MC_bpCutNew + (1-damp) * MC_bpCut_;
1493 double MC_dpCutNew = ((- MC_apCut_/MC_cpCut_ + MC_bpCut_ - MC_bpCut_ *
MC_X_o_cutoff_/MC_cpCut_)
1496 MC_dpCut_ = damp * MC_dpCutNew + (1-damp) * MC_dpCut_;
1499 MC_epCut_ = - eterm * tmp;
1500 double diff = MC_epCut_ - oldV;
1501 if (fabs(diff) < 1.0E-14) {
1507 " failed to converge on the p polynomial");
1514 const double twoT = 2.0 * T;
1515 const double invT = 1.0 / T;
1516 const double invT2 = invT * invT;
1517 const double twoinvT3 = 2.0 * invT * invT2;
1518 double tinv = 0.0, tln = 0.0, tlin = 0.0, tquad = 0.0;
1528 for (
size_t i = 1; i < (
m_kk - 1); i++) {
1529 for (
size_t j = (i+1); j <
m_kk; j++) {
1531 size_t n =
m_kk*i + j;
1541 case PITZER_TEMP_CONSTANT:
1543 case PITZER_TEMP_LINEAR:
1546 + beta0MX_coeff[1]*tlin;
1550 + beta1MX_coeff[1]*tlin;
1554 + beta2MX_coeff[1]*tlin;
1558 + CphiMX_coeff[1]*tlin;
1561 m_Theta_ij[counterIJ] = Theta_coeff[0] + Theta_coeff[1]*tlin;
1566 case PITZER_TEMP_COMPLEX1:
1568 + beta0MX_coeff[1]*tlin
1569 + beta0MX_coeff[2]*tquad
1570 + beta0MX_coeff[3]*tinv
1571 + beta0MX_coeff[4]*tln;
1573 + beta1MX_coeff[1]*tlin
1574 + beta1MX_coeff[2]*tquad
1575 + beta1MX_coeff[3]*tinv
1576 + beta1MX_coeff[4]*tln;
1578 + beta2MX_coeff[1]*tlin
1579 + beta2MX_coeff[2]*tquad
1580 + beta2MX_coeff[3]*tinv
1581 + beta2MX_coeff[4]*tln;
1583 + CphiMX_coeff[1]*tlin
1584 + CphiMX_coeff[2]*tquad
1585 + CphiMX_coeff[3]*tinv
1586 + CphiMX_coeff[4]*tln;
1588 + Theta_coeff[1]*tlin
1589 + Theta_coeff[2]*tquad
1590 + Theta_coeff[3]*tinv
1591 + Theta_coeff[4]*tln;
1593 + beta0MX_coeff[2]*twoT
1594 - beta0MX_coeff[3]*invT2
1595 + beta0MX_coeff[4]*invT;
1597 + beta1MX_coeff[2]*twoT
1598 - beta1MX_coeff[3]*invT2
1599 + beta1MX_coeff[4]*invT;
1601 + beta2MX_coeff[2]*twoT
1602 - beta2MX_coeff[3]*invT2
1603 + beta2MX_coeff[4]*invT;
1605 + CphiMX_coeff[2]*twoT
1606 - CphiMX_coeff[3]*invT2
1607 + CphiMX_coeff[4]*invT;
1609 + Theta_coeff[2]*twoT
1610 - Theta_coeff[3]*invT2
1611 + Theta_coeff[4]*invT;
1615 + beta0MX_coeff[2]*2.0
1616 + beta0MX_coeff[3]*twoinvT3
1617 - beta0MX_coeff[4]*invT2;
1619 + beta1MX_coeff[2]*2.0
1620 + beta1MX_coeff[3]*twoinvT3
1621 - beta1MX_coeff[4]*invT2;
1623 + beta2MX_coeff[2]*2.0
1624 + beta2MX_coeff[3]*twoinvT3
1625 - beta2MX_coeff[4]*invT2;
1627 + CphiMX_coeff[2]*2.0
1628 + CphiMX_coeff[3]*twoinvT3
1629 - CphiMX_coeff[4]*invT2;
1631 + Theta_coeff[2]*2.0
1632 + Theta_coeff[3]*twoinvT3
1633 - Theta_coeff[4]*invT2;
1643 for (
size_t i = 1; i <
m_kk; i++) {
1645 for (
size_t j = 1; j <
m_kk; j++) {
1646 size_t n = i *
m_kk + j;
1649 case PITZER_TEMP_CONSTANT:
1652 case PITZER_TEMP_LINEAR:
1653 m_Lambda_nj(i,j) = Lambda_coeff[0] + Lambda_coeff[1]*tlin;
1657 case PITZER_TEMP_COMPLEX1:
1659 + Lambda_coeff[1]*tlin
1660 + Lambda_coeff[2]*tquad
1661 + Lambda_coeff[3]*tinv
1662 + Lambda_coeff[4]*tln;
1665 + Lambda_coeff[2]*twoT
1666 - Lambda_coeff[3]*invT2
1667 + Lambda_coeff[4]*invT;
1671 + Lambda_coeff[3]*twoinvT3
1672 - Lambda_coeff[4]*invT2;
1678 case PITZER_TEMP_CONSTANT:
1681 case PITZER_TEMP_LINEAR:
1682 m_Mu_nnn[i] = Mu_coeff[0] + Mu_coeff[1]*tlin;
1686 case PITZER_TEMP_COMPLEX1:
1698 + Mu_coeff[3]*twoinvT3
1699 - Mu_coeff[4]*invT2;
1707 case PITZER_TEMP_CONSTANT:
1708 for (
size_t i = 1; i <
m_kk; i++) {
1709 for (
size_t j = 1; j <
m_kk; j++) {
1710 for (
size_t k = 1; k <
m_kk; k++) {
1718 case PITZER_TEMP_LINEAR:
1719 for (
size_t i = 1; i <
m_kk; i++) {
1720 for (
size_t j = 1; j <
m_kk; j++) {
1721 for (
size_t k = 1; k <
m_kk; k++) {
1724 m_Psi_ijk[n] = Psi_coeff[0] + Psi_coeff[1]*tlin;
1731 case PITZER_TEMP_COMPLEX1:
1732 for (
size_t i = 1; i <
m_kk; i++) {
1733 for (
size_t j = 1; j <
m_kk; j++) {
1734 for (
size_t k = 1; k <
m_kk; k++) {
1739 + Psi_coeff[2]*tquad
1744 - Psi_coeff[3]*invT2
1745 + Psi_coeff[4]*invT;
1748 + Psi_coeff[3]*twoinvT3
1749 - Psi_coeff[4]*invT2;
1767 double etheta[5][5], etheta_prime[5][5], sqrtIs;
1774 double molarcharge = 0.0;
1778 double molalitysumUncropped = 0.0;
1784 for (
size_t n = 1; n <
m_kk; n++) {
1788 molarcharge += fabs(
charge(n)) * molality[n];
1803 for (
int z1 = 1; z1 <=4; z1++) {
1804 for (
int z2 =1; z2 <=4; z2++) {
1805 calc_thetas(z1, z2, etheta[z1][z2], etheta_prime[z1][z2]);
1812 for (
size_t i = 1; i < (
m_kk - 1); i++) {
1813 for (
size_t j = (i+1); j <
m_kk; j++) {
1815 size_t n =
m_kk*i + j;
1821 double x1 = sqrtIs * m_Alpha1MX_ij[counterIJ];
1822 if (x1 > 1.0E-100) {
1823 m_gfunc_IJ[counterIJ] = 2.0*(1.0-(1.0 + x1) * exp(-x1)) / (x1 * x1);
1825 (1.0-(1.0 + x1 + 0.5 * x1 * x1) * exp(-x1)) / (x1 * x1);
1833 if (x2 > 1.0E-100) {
1834 m_g2func_IJ[counterIJ] = 2.0*(1.0-(1.0 + x2) * exp(-x2)) / (x2 * x2);
1836 (1.0-(1.0 + x2 + 0.5 * x2 * x2) * exp(-x2)) / (x2 * x2);
1851 for (
size_t i = 1; i <
m_kk - 1; i++) {
1852 for (
size_t j = i+1; j <
m_kk; j++) {
1854 size_t n =
m_kk*i + j;
1864 if (Is > 1.0E-150) {
1881 for (
size_t i = 1; i <
m_kk-1; i++) {
1882 for (
size_t j = i+1; j <
m_kk; j++) {
1884 size_t n =
m_kk*i + j;
1900 for (
size_t i = 1; i <
m_kk-1; i++) {
1901 for (
size_t j = i+1; j <
m_kk; j++) {
1903 size_t n =
m_kk*i + j;
1909 int z1 = (int) fabs(
charge(i));
1910 int z2 = (int) fabs(
charge(j));
1925 double F = -Aphi * (sqrt(Is) / (1.0 + 1.2*sqrt(Is))
1926 + (2.0/1.2) * log(1.0+1.2*(sqrtIs)));
1927 for (
size_t i = 1; i <
m_kk-1; i++) {
1928 for (
size_t j = i+1; j <
m_kk; j++) {
1930 size_t n =
m_kk*i + j;
1947 for (
size_t i = 1; i <
m_kk; i++) {
1960 for (
size_t j = 1; j <
m_kk; j++) {
1962 size_t n =
m_kk*i + j;
1967 sum1 += molality[j] *
1973 for (
size_t k = j+1; k <
m_kk; k++) {
1977 sum3 += molality[j]*molality[k]*
m_Psi_ijk[n];
1986 sum2 += molality[j]*(2.0*
m_Phi_IJ[counterIJ]);
1988 for (
size_t k = 1; k <
m_kk; k++) {
1992 sum2 += molality[j]*molality[k]*
m_Psi_ijk[n];
1997 sum4 += (fabs(
charge(i))*
1998 molality[j]*molality[k]*
m_CMX_IJ[counterIJ2]);
2008 for (
size_t k = 1; k <
m_kk; k++) {
2015 sum5 += molality[j]*molality[k]*zeta;
2039 for (
size_t j = 1; j <
m_kk; j++) {
2041 size_t n =
m_kk*i + j;
2046 sum1 += molality[j]*
2049 for (
size_t k = j+1; k <
m_kk; k++) {
2053 sum3 += molality[j]*molality[k]*
m_Psi_ijk[n];
2063 sum2 += molality[j]*(2.0*
m_Phi_IJ[counterIJ]);
2065 for (
size_t k = 1; k <
m_kk; k++) {
2069 sum2 += molality[j]*molality[k]*
m_Psi_ijk[n];
2074 molality[j]*molality[k]*
m_CMX_IJ[counterIJ2];
2083 for (
size_t k = 1; k <
m_kk; k++) {
2091 sum5 += molality[j]*molality[k]*zeta;
2107 for (
size_t j = 1; j <
m_kk; j++) {
2111 for (
size_t k = 1; k <
m_kk; k++) {
2114 sum3 += molality[j]*molality[k]*
m_Psi_ijk[n];
2119 double sum2 = 3.0 * molality[i]* molality[i] *
m_Mu_nnn[i];
2141 double term1 = -Aphi * pow(Is,1.5) / (1.0 + 1.2 * sqrt(Is));
2143 for (
size_t j = 1; j <
m_kk; j++) {
2146 for (
size_t k = 1; k <
m_kk; k++) {
2149 size_t n =
m_kk*j + k;
2152 sum1 += molality[j]*molality[k]*
2157 for (
size_t k = j+1; k <
m_kk; k++) {
2158 if (j == (
m_kk-1)) {
2160 throw CanteraError(
"HMWSoln::s_updatePitzer_lnMolalityActCoeff",
2161 "logic error 1 in Step 9 of hmw_act");
2166 size_t n =
m_kk*j + k;
2168 sum2 += molality[j]*molality[k]*
m_PhiPhi_IJ[counterIJ];
2169 for (
size_t m = 1; m <
m_kk; m++) {
2173 sum2 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk[n];
2182 for (
size_t k = j+1; k <
m_kk; k++) {
2185 throw CanteraError(
"HMWSoln::s_updatePitzer_lnMolalityActCoeff",
2186 "logic error 2 in Step 9 of hmw_act");
2191 size_t n =
m_kk*j + k;
2193 sum3 += molality[j]*molality[k]*
m_PhiPhi_IJ[counterIJ];
2194 for (
size_t m = 1; m <
m_kk; m++) {
2197 sum3 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk[n];
2206 for (
size_t k = 1; k <
m_kk; k++) {
2216 }
else if (k == j) {
2217 sum6 += 0.5 * molality[j]*molality[k]*
m_Lambda_nj(j,k);
2222 for (
size_t m = 1; m <
m_kk; m++) {
2228 sum7 += molality[izeta]*molality[jzeta]*molality[k]*zeta;
2234 sum7 += molality[j]*molality[j]*molality[j]*
m_Mu_nnn[j];
2237 double sum_m_phi_minus_1 = 2.0 *
2238 (term1 + sum1 + sum2 + sum3 + sum4 + sum5 + sum6 + sum7);
2241 double osmotic_coef;
2242 if (molalitysumUncropped > 1.0E-150) {
2243 osmotic_coef = 1.0 + (sum_m_phi_minus_1 / molalitysumUncropped);
2247 double lnwateract = -(
m_weightSolvent/1000.0) * molalitysumUncropped * osmotic_coef;
2274 for (
size_t k = 1; k <
m_kk; k++) {
2298 double etheta[5][5], etheta_prime[5][5], sqrtIs;
2305 double molarcharge = 0.0;
2309 double molalitysum = 0.0;
2315 for (
size_t n = 1; n <
m_kk; n++) {
2319 molarcharge += fabs(
charge(n)) * molality[n];
2320 molalitysum += molality[n];
2334 for (
int z1 = 1; z1 <=4; z1++) {
2335 for (
int z2 =1; z2 <=4; z2++) {
2336 calc_thetas(z1, z2, etheta[z1][z2], etheta_prime[z1][z2]);
2343 for (
size_t i = 1; i < (
m_kk - 1); i++) {
2344 for (
size_t j = (i+1); j <
m_kk; j++) {
2346 size_t n =
m_kk*i + j;
2352 double x1 = sqrtIs * m_Alpha1MX_ij[counterIJ];
2353 if (x1 > 1.0E-100) {
2354 m_gfunc_IJ[counterIJ] = 2.0*(1.0-(1.0 + x1) * exp(-x1)) / (x1 * x1);
2356 (1.0-(1.0 + x1 + 0.5 * x1 *x1) * exp(-x1)) / (x1 * x1);
2364 if (x2 > 1.0E-100) {
2365 m_g2func_IJ[counterIJ] = 2.0*(1.0-(1.0 + x2) * exp(-x2)) / (x2 * x2);
2367 (1.0-(1.0 + x2 + 0.5 * x2 * x2) * exp(-x2)) / (x2 * x2);
2383 for (
size_t i = 1; i <
m_kk - 1; i++) {
2384 for (
size_t j = i+1; j <
m_kk; j++) {
2386 size_t n =
m_kk*i + j;
2395 if (Is > 1.0E-150) {
2411 for (
size_t i = 1; i <
m_kk-1; i++) {
2412 for (
size_t j = i+1; j <
m_kk; j++) {
2414 size_t n =
m_kk*i + j;
2429 for (
size_t i = 1; i <
m_kk-1; i++) {
2430 for (
size_t j = i+1; j <
m_kk; j++) {
2432 size_t n =
m_kk*i + j;
2451 double dAphidT = dA_DebyedT /3.0;
2452 double dFdT = -dAphidT * (sqrt(Is) / (1.0 + 1.2*sqrt(Is))
2453 + (2.0/1.2) * log(1.0+1.2*(sqrtIs)));
2454 for (
size_t i = 1; i <
m_kk-1; i++) {
2455 for (
size_t j = i+1; j <
m_kk; j++) {
2457 size_t n =
m_kk*i + j;
2474 for (
size_t i = 1; i <
m_kk; i++) {
2484 for (
size_t j = 1; j <
m_kk; j++) {
2486 size_t n =
m_kk*i + j;
2491 sum1 += molality[j]*
2497 for (
size_t k = j+1; k <
m_kk; k++) {
2510 sum2 += molality[j]*(2.0*
m_Phi_IJ_L[counterIJ]);
2512 for (
size_t k = 1; k <
m_kk; k++) {
2522 molality[j]*molality[k]*
m_CMX_IJ_L[counterIJ2];
2533 for (
size_t k = 1; k <
m_kk; k++) {
2539 if (zeta_L != 0.0) {
2540 sum5 += molality[j]*molality[k]*zeta_L;
2549 zsqdFdT + sum1 + sum2 + sum3 + sum4 + sum5;
2562 for (
size_t j = 1; j <
m_kk; j++) {
2564 size_t n =
m_kk*i + j;
2569 sum1 += molality[j]*
2572 for (
size_t k = j+1; k <
m_kk; k++) {
2586 sum2 += molality[j]*(2.0*
m_Phi_IJ_L[counterIJ]);
2588 for (
size_t k = 1; k <
m_kk; k++) {
2596 sum4 += fabs(
charge(i)) *
2597 molality[j]*molality[k]*
m_CMX_IJ_L[counterIJ2];
2605 for (
size_t k = 1; k <
m_kk; k++) {
2612 if (zeta_L != 0.0) {
2613 sum5 += molality[j]*molality[k]*zeta_L;
2620 zsqdFdT + sum1 + sum2 + sum3 + sum4 + sum5;
2630 for (
size_t j = 1; j <
m_kk; j++) {
2634 for (
size_t k = 1; k <
m_kk; k++) {
2642 double sum2 = 3.0 * molality[i] * molality[i] *
m_Mu_nnn_L[i];
2662 double term1 = -dAphidT * Is * sqrt(Is) / (1.0 + 1.2 * sqrt(Is));
2664 for (
size_t j = 1; j <
m_kk; j++) {
2667 for (
size_t k = 1; k <
m_kk; k++) {
2670 size_t n =
m_kk*j + k;
2672 sum1 += molality[j]*molality[k]*
2677 for (
size_t k = j+1; k <
m_kk; k++) {
2678 if (j == (
m_kk-1)) {
2680 throw CanteraError(
"HMWSoln::s_updatePitzer_dlnMolalityActCoeff_dT",
2681 "logic error 1 in Step 9 of hmw_act");
2686 size_t n =
m_kk*j + k;
2689 for (
size_t m = 1; m <
m_kk; m++) {
2693 sum2 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk_L[n];
2702 for (
size_t k = j+1; k <
m_kk; k++) {
2705 throw CanteraError(
"HMWSoln::s_updatePitzer_dlnMolalityActCoeff_dT",
2706 "logic error 2 in Step 9 of hmw_act");
2711 size_t n =
m_kk*j + k;
2714 for (
size_t m = 1; m <
m_kk; m++) {
2717 sum3 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk_L[n];
2726 for (
size_t k = 1; k <
m_kk; k++) {
2736 }
else if (k == j) {
2742 for (
size_t m = 1; m <
m_kk; m++) {
2747 if (zeta_L != 0.0) {
2748 sum7 += molality[izeta]*molality[jzeta]*molality[k]*zeta_L;
2754 sum7 += molality[j]*molality[j]*molality[j]*
m_Mu_nnn_L[j];
2757 double sum_m_phi_minus_1 = 2.0 *
2758 (term1 + sum1 + sum2 + sum3 + sum4 + sum5 + sum6 + sum7);
2761 double d_osmotic_coef_dT;
2762 if (molalitysum > 1.0E-150) {
2763 d_osmotic_coef_dT = 0.0 + (sum_m_phi_minus_1 / molalitysum);
2765 d_osmotic_coef_dT = 0.0;
2768 double d_lnwateract_dT = -(
m_weightSolvent/1000.0) * molalitysum * d_osmotic_coef_dT;
2793 for (
size_t k = 1; k <
m_kk; k++) {
2812 double etheta[5][5], etheta_prime[5][5], sqrtIs;
2819 double molarcharge = 0.0;
2823 double molalitysum = 0.0;
2829 for (
size_t n = 1; n <
m_kk; n++) {
2833 molarcharge += fabs(
charge(n)) * molality[n];
2834 molalitysum += molality[n];
2848 for (
int z1 = 1; z1 <=4; z1++) {
2849 for (
int z2 =1; z2 <=4; z2++) {
2850 calc_thetas(z1, z2, etheta[z1][z2], etheta_prime[z1][z2]);
2857 for (
size_t i = 1; i < (
m_kk - 1); i++) {
2858 for (
size_t j = (i+1); j <
m_kk; j++) {
2860 size_t n =
m_kk*i + j;
2866 double x1 = sqrtIs * m_Alpha1MX_ij[counterIJ];
2867 if (x1 > 1.0E-100) {
2868 m_gfunc_IJ[counterIJ] = 2.0*(1.0-(1.0 + x1) * exp(-x1)) / (x1 *x1);
2870 (1.0-(1.0 + x1 + 0.5*x1 * x1) * exp(-x1)) / (x1 * x1);
2878 if (x2 > 1.0E-100) {
2879 m_g2func_IJ[counterIJ] = 2.0*(1.0-(1.0 + x2) * exp(-x2)) / (x2 * x2);
2881 (1.0-(1.0 + x2 + 0.5 * x2 * x2) * exp(-x2)) / (x2 * x2);
2897 for (
size_t i = 1; i <
m_kk - 1; i++) {
2898 for (
size_t j = i+1; j <
m_kk; j++) {
2900 size_t n =
m_kk*i + j;
2909 if (Is > 1.0E-150) {
2925 for (
size_t i = 1; i <
m_kk-1; i++) {
2926 for (
size_t j = i+1; j <
m_kk; j++) {
2928 size_t n =
m_kk*i + j;
2943 for (
size_t i = 1; i <
m_kk-1; i++) {
2944 for (
size_t j = i+1; j <
m_kk; j++) {
2946 size_t n =
m_kk*i + j;
2965 double d2FdT2 = -d2AphidT2 * (sqrt(Is) / (1.0 + 1.2*sqrt(Is))
2966 + (2.0/1.2) * log(1.0+1.2*(sqrtIs)));
2967 for (
size_t i = 1; i <
m_kk-1; i++) {
2968 for (
size_t j = i+1; j <
m_kk; j++) {
2970 size_t n =
m_kk*i + j;
2982 d2FdT2 += molality[i]*molality[j] *
m_Phiprime_IJ[counterIJ];
2987 for (
size_t i = 1; i <
m_kk; i++) {
2997 for (
size_t j = 1; j <
m_kk; j++) {
2999 size_t n =
m_kk*i + j;
3004 sum1 += molality[j]*
3010 for (
size_t k = j+1; k <
m_kk; k++) {
3025 for (
size_t k = 1; k <
m_kk; k++) {
3034 sum4 += fabs(
charge(i)) *
3044 for (
size_t k = 1; k <
m_kk; k++) {
3050 if (zeta_LL != 0.0) {
3051 sum5 += molality[j]*molality[k]*zeta_LL;
3060 zsqd2FdT2 + sum1 + sum2 + sum3 + sum4 + sum5;
3072 for (
size_t j = 1; j <
m_kk; j++) {
3074 size_t n =
m_kk*i + j;
3079 sum1 += molality[j]*
3082 for (
size_t k = j+1; k <
m_kk; k++) {
3098 for (
size_t k = 1; k <
m_kk; k++) {
3106 sum4 += fabs(
charge(i)) *
3116 for (
size_t k = 1; k <
m_kk; k++) {
3123 if (zeta_LL != 0.0) {
3124 sum5 += molality[j]*molality[k]*zeta_LL;
3131 zsqd2FdT2 + sum1 + sum2 + sum3 + sum4 + sum5;
3140 for (
size_t j = 1; j <
m_kk; j++) {
3144 for (
size_t k = 1; k <
m_kk; k++) {
3152 double sum2 = 3.0 * molality[i] * molality[i] *
m_Mu_nnn_LL[i];
3171 double term1 = -d2AphidT2 * Is * sqrt(Is) / (1.0 + 1.2 * sqrt(Is));
3173 for (
size_t j = 1; j <
m_kk; j++) {
3176 for (
size_t k = 1; k <
m_kk; k++) {
3179 size_t n =
m_kk*j + k;
3182 sum1 += molality[j]*molality[k] *
3187 for (
size_t k = j+1; k <
m_kk; k++) {
3188 if (j == (
m_kk-1)) {
3190 throw CanteraError(
"HMWSoln::s_updatePitzer_d2lnMolalityActCoeff_dT2",
3191 "logic error 1 in Step 9 of hmw_act");
3196 size_t n =
m_kk*j + k;
3199 for (
size_t m = 1; m <
m_kk; m++) {
3203 sum2 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk_LL[n];
3212 for (
size_t k = j+1; k <
m_kk; k++) {
3215 throw CanteraError(
"HMWSoln::s_updatePitzer_d2lnMolalityActCoeff_dT2",
3216 "logic error 2 in Step 9 of hmw_act");
3221 size_t n =
m_kk*j + k;
3225 for (
size_t m = 1; m <
m_kk; m++) {
3228 sum3 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk_LL[n];
3237 for (
size_t k = 1; k <
m_kk; k++) {
3247 }
else if (k == j) {
3253 for (
size_t m = 1; m <
m_kk; m++) {
3258 if (zeta_LL != 0.0) {
3259 sum7 += molality[izeta]*molality[jzeta]*molality[k]*zeta_LL;
3266 sum7 += molality[j] * molality[j] * molality[j] *
m_Mu_nnn_LL[j];
3269 double sum_m_phi_minus_1 = 2.0 *
3270 (term1 + sum1 + sum2 + sum3 + sum4 + sum5 + sum6 + sum7);
3273 double d2_osmotic_coef_dT2;
3274 if (molalitysum > 1.0E-150) {
3275 d2_osmotic_coef_dT2 = 0.0 + (sum_m_phi_minus_1 / molalitysum);
3277 d2_osmotic_coef_dT2 = 0.0;
3279 double d2_lnwateract_dT2 = -(
m_weightSolvent/1000.0) * molalitysum * d2_osmotic_coef_dT2;
3301 for (
size_t k = 1; k <
m_kk; k++) {
3319 double etheta[5][5], etheta_prime[5][5], sqrtIs;
3326 double molarcharge = 0.0;
3330 double molalitysum = 0.0;
3338 for (
size_t n = 1; n <
m_kk; n++) {
3342 molarcharge += fabs(
charge(n)) * molality[n];
3343 molalitysum += molality[n];
3357 for (
int z1 = 1; z1 <=4; z1++) {
3358 for (
int z2 =1; z2 <=4; z2++) {
3359 calc_thetas(z1, z2, etheta[z1][z2], etheta_prime[z1][z2]);
3366 for (
size_t i = 1; i < (
m_kk - 1); i++) {
3367 for (
size_t j = (i+1); j <
m_kk; j++) {
3369 size_t n =
m_kk*i + j;
3375 double x1 = sqrtIs * m_Alpha1MX_ij[counterIJ];
3376 if (x1 > 1.0E-100) {
3377 m_gfunc_IJ[counterIJ] = 2.0*(1.0-(1.0 + x1) * exp(-x1)) / (x1 * x1);
3379 (1.0-(1.0 + x1 + 0.5 * x1 * x1) * exp(-x1)) / (x1 * x1);
3387 if (x2 > 1.0E-100) {
3388 m_g2func_IJ[counterIJ] = 2.0*(1.0-(1.0 + x2) * exp(-x2)) / (x2 * x2);
3390 (1.0-(1.0 + x2 + 0.5 * x2 * x2) * exp(-x2)) / (x2 * x2);
3406 for (
size_t i = 1; i <
m_kk - 1; i++) {
3407 for (
size_t j = i+1; j <
m_kk; j++) {
3409 size_t n =
m_kk*i + j;
3418 if (Is > 1.0E-150) {
3434 for (
size_t i = 1; i <
m_kk-1; i++) {
3435 for (
size_t j = i+1; j <
m_kk; j++) {
3437 size_t n =
m_kk*i + j;
3452 for (
size_t i = 1; i <
m_kk-1; i++) {
3453 for (
size_t j = i+1; j <
m_kk; j++) {
3455 size_t n =
m_kk*i + j;
3474 double dAphidP = dA_DebyedP /3.0;
3475 double dFdP = -dAphidP * (sqrt(Is) / (1.0 + 1.2*sqrt(Is))
3476 + (2.0/1.2) * log(1.0+1.2*(sqrtIs)));
3477 for (
size_t i = 1; i <
m_kk-1; i++) {
3478 for (
size_t j = i+1; j <
m_kk; j++) {
3480 size_t n =
m_kk*i + j;
3497 for (
size_t i = 1; i <
m_kk; i++) {
3507 for (
size_t j = 1; j <
m_kk; j++) {
3509 size_t n =
m_kk*i + j;
3514 sum1 += molality[j]*
3520 for (
size_t k = j+1; k <
m_kk; k++) {
3533 sum2 += molality[j]*(2.0*
m_Phi_IJ_P[counterIJ]);
3535 for (
size_t k = 1; k <
m_kk; k++) {
3544 sum4 += fabs(
charge(i)) *
3545 molality[j]*molality[k]*
m_CMX_IJ_P[counterIJ2];
3554 for (
size_t k = 1; k <
m_kk; k++) {
3560 if (zeta_P != 0.0) {
3561 sum5 += molality[j]*molality[k]*zeta_P;
3571 zsqdFdP + sum1 + sum2 + sum3 + sum4 + sum5;
3583 for (
size_t j = 1; j <
m_kk; j++) {
3585 size_t n =
m_kk*i + j;
3590 sum1 += molality[j] *
3593 for (
size_t k = j+1; k <
m_kk; k++) {
3607 sum2 += molality[j]*(2.0*
m_Phi_IJ_P[counterIJ]);
3609 for (
size_t k = 1; k <
m_kk; k++) {
3618 molality[j]*molality[k]*
m_CMX_IJ_P[counterIJ2];
3627 for (
size_t k = 1; k <
m_kk; k++) {
3634 if (zeta_P != 0.0) {
3635 sum5 += molality[j]*molality[k]*zeta_P;
3642 zsqdFdP + sum1 + sum2 + sum3 + sum4 + sum5;
3649 for (
size_t j = 1; j <
m_kk; j++) {
3653 for (
size_t k = 1; k <
m_kk; k++) {
3661 double sum2 = 3.0 * molality[i] * molality[i] *
m_Mu_nnn_P[i];
3680 double term1 = -dAphidP * Is * sqrt(Is) / (1.0 + 1.2 * sqrt(Is));
3682 for (
size_t j = 1; j <
m_kk; j++) {
3685 for (
size_t k = 1; k <
m_kk; k++) {
3688 size_t n =
m_kk*j + k;
3690 sum1 += molality[j]*molality[k]*
3695 for (
size_t k = j+1; k <
m_kk; k++) {
3696 if (j == (
m_kk-1)) {
3698 throw CanteraError(
"HMWSoln::s_updatePitzer_dlnMolalityActCoeff_dP",
3699 "logic error 1 in Step 9 of hmw_act");
3704 size_t n =
m_kk*j + k;
3707 for (
size_t m = 1; m <
m_kk; m++) {
3711 sum2 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk_P[n];
3720 for (
size_t k = j+1; k <
m_kk; k++) {
3723 throw CanteraError(
"HMWSoln::s_updatePitzer_dlnMolalityActCoeff_dP",
3724 "logic error 2 in Step 9 of hmw_act");
3729 size_t n =
m_kk*j + k;
3733 for (
size_t m = 1; m <
m_kk; m++) {
3736 sum3 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk_P[n];
3745 for (
size_t k = 1; k <
m_kk; k++) {
3755 }
else if (k == j) {
3761 for (
size_t m = 1; m <
m_kk; m++) {
3766 if (zeta_P != 0.0) {
3767 sum7 += molality[izeta]*molality[jzeta]*molality[k]*zeta_P;
3774 sum7 += molality[j] * molality[j] * molality[j] *
m_Mu_nnn_P[j];
3777 double sum_m_phi_minus_1 = 2.0 *
3778 (term1 + sum1 + sum2 + sum3 + sum4 + sum5 + sum6 + sum7);
3782 double d_osmotic_coef_dP;
3783 if (molalitysum > 1.0E-150) {
3784 d_osmotic_coef_dP = 0.0 + (sum_m_phi_minus_1 / molalitysum);
3786 d_osmotic_coef_dP = 0.0;
3788 double d_lnwateract_dP = -(
m_weightSolvent/1000.0) * molalitysum * d_osmotic_coef_dP;
3801 if( m_last_is == is ) {
3808 double c1 = 4.581, c2 = 0.7237, c3 = 0.0120, c4 = 0.528;
3809 double aphi = 0.392;
3810 if (is < 1.0E-150) {
3811 for (
int i = 0; i < 17; i++) {
3820 for (
int i=1; i<=4; i++) {
3821 for (
int j=i; j<=4; j++) {
3825 double zprod = (double)ij;
3828 double x = 6.0* zprod * aphi * sqrt(is);
3830 double jfunc = x / (4.0 + c1*pow(x,-c2)*exp(-c3*pow(x,c4)));
3832 double t = c3 * c4 * pow(x,c4);
3833 double dj = c1* pow(x,(-c2-1.0)) * (c2+t) * exp(-c3*pow(x,c4));
3834 double jprime = (jfunc/x)*(1.0 + jfunc*dj);
3836 elambda[ij] = zprod*jfunc / (4.0*is);
3837 elambda1[ij] = (3.0*zprod*zprod*aphi*jprime/(4.0*sqrt(is))
3844 double& etheta,
double& etheta_prime)
const
3851 "we shouldn't be here");
3853 "called with one species being neutral");
3862 double f1 = (double)i / (2.0 * j);
3863 double f2 = (double)j / (2.0 * i);
3878 for (
size_t k = 1; k <
m_kk; k++) {
3885 double eterm = std::exp(-xoverc);
3887 double fptmp = IMS_bfCut_ - IMS_afCut_ /
IMS_cCut_ - IMS_bfCut_*xoverc
3888 + 2.0*IMS_dfCut_*xmolSolvent - IMS_dfCut_*xmolSolvent*xoverc;
3889 double f_prime = 1.0 + eterm*fptmp;
3890 double f = xmolSolvent + IMS_efCut_
3891 + eterm * (IMS_afCut_ + xmolSolvent * (IMS_bfCut_ + IMS_dfCut_*xmolSolvent));
3893 double gptmp = IMS_bgCut_ - IMS_agCut_ /
IMS_cCut_ - IMS_bgCut_*xoverc
3894 + 2.0*IMS_dgCut_*xmolSolvent - IMS_dgCut_*xmolSolvent*xoverc;
3895 double g_prime = 1.0 + eterm*gptmp;
3896 double g = xmolSolvent + IMS_egCut_
3897 + eterm * (IMS_agCut_ + xmolSolvent * (IMS_bgCut_ + IMS_dgCut_*xmolSolvent));
3899 double tmp = (xmolSolvent / g * g_prime + (1.0 - xmolSolvent) / f * f_prime);
3900 double lngammak = -1.0 - log(f) + tmp * xmolSolvent;
3901 double lngammao =-log(g) - tmp * (1.0-xmolSolvent);
3903 tmp = log(xx) + lngammak;
3904 for (
size_t k = 1; k <
m_kk; k++) {
3915 vector<double>& moleF =
m_workS;
3921 writelog(
"Index Name MoleF MolalityCropped Charge\n");
3922 for (
size_t k = 0; k <
m_kk; k++) {
3923 writelogf(
"%2d %-16s %14.7le %14.7le %5.1f \n",
3927 writelog(
"\n Species Species beta0MX "
3928 "beta1MX beta2MX CphiMX alphaMX thetaij\n");
3929 for (
size_t i = 1; i <
m_kk - 1; i++) {
3930 for (
size_t j = i+1; j <
m_kk; j++) {
3931 size_t n = i *
m_kk + j;
3933 writelogf(
" %-16s %-16s %9.5f %9.5f %9.5f %9.5f %9.5f %9.5f \n",
3941 writelog(
"\n Species Species Species psi \n");
3942 for (
size_t i = 1; i <
m_kk; i++) {
3943 for (
size_t j = 1; j <
m_kk; j++) {
3944 for (
size_t k = 1; k <
m_kk; k++) {
3947 writelogf(
" %-16s %-16s %-16s %9.5f \n",
3965 double afac = -1.0 *(lnGammaClMs2 - lnGammaCLMs1);
3966 for (
size_t k = 0; k <
m_kk; k++) {
3967 acMolality[k] *= exp(
charge(k) * afac);
3980 double afac = -1.0 *(lnGammaClMs2 - lnGammaCLMs1);
3981 for (
size_t k = 0; k <
m_kk; k++) {
3995 double afac = -1.0 *(dlnGammaClM_dT_s2 - dlnGammaCLM_dT_s1);
3996 for (
size_t k = 0; k <
m_kk; k++) {
4010 double afac = -1.0 *(d2lnGammaClM_dT2_s2 - d2lnGammaCLM_dT2_s1);
4011 for (
size_t k = 0; k <
m_kk; k++) {
4025 double afac = -1.0 *(dlnGammaClM_dP_s2 - dlnGammaCLM_dP_s1);
4026 for (
size_t k = 0; k <
m_kk; k++) {
4035 double lnGammaClMs2 = - A * sqrtIs /(1.0 + 1.5 * sqrtIs);
4036 return lnGammaClMs2;
4043 return - dAdT * sqrtIs /(1.0 + 1.5 * sqrtIs);
4050 return - d2AdT2 * sqrtIs /(1.0 + 1.5 * sqrtIs);
4057 return - dAdP * sqrtIs /(1.0 + 1.5 * sqrtIs);
Headers for the HMWSoln ThermoPhase object, which models concentrated electrolyte solutions (see Ther...
Implementation of a pressure dependent standard state virtual function for a Pure Water Phase (see Sp...
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.
size_t size() const
Returns the number of elements in this map.
bool hasKey(const string &key) const
Returns true if the map contains an item named key.
span< double > col(size_t j)
Return a writable span over column j.
virtual void resize(size_t n, size_t m, double v=0.0)
Resize the array, and fill the new entries with 'v'.
Base class for exceptions thrown by Cantera classes.
void calcIMSCutoffParams_()
Precalculate the IMS Cutoff parameters for typeCutoff = 2.
vector< double > m_d2lnActCoeffMolaldT2_Unscaled
Derivative of the Logarithm of the activity coefficients on the molality scale wrt TT.
Array2D m_Theta_ij_coeff
Array of coefficients for Theta_ij[i][j] in the Pitzer/HMW formulation.
vector< double > m_Mu_nnn_L
Mu coefficient temperature derivative for the self-ternary neutral coefficient.
vector< double > m_Beta1MX_ij
Array of 2D data used in the Pitzer/HMW formulation.
unique_ptr< WaterProps > m_waterProps
Pointer to the water property calculator.
Array2D m_Beta0MX_ij_coeff
Array of coefficients for Beta0, a variable in Pitzer's papers.
double m_A_Debye
A_Debye: this expression appears on the top of the ln actCoeff term in the general Debye-Huckel expre...
virtual double d2A_DebyedT2_TP(double temperature=-1.0, double pressure=-1.0) const
Value of the 2nd derivative of the Debye Huckel constant with respect to temperature as a function of...
vector< double > m_h2func_IJ
hfunc2, was called gprime in Pitzer's paper.
vector< double > m_Phi_IJ_LL
Derivative of m_Phi_IJ wrt TT. Vector index is counterIJ.
vector< double > m_Beta0MX_ij
Array of 2D data used in the Pitzer/HMW formulation.
double IMS_slopegCut_
Parameter in the polyExp cutoff treatment.
Array2D m_Lambda_nj_P
Derivative of Lambda_nj[i][j] wrt P.
void s_updateScaling_pHScaling_dT() const
Apply the current phScale to a set of derivatives of the activity Coefficients wrt temperature.
vector< double > m_gfunc_IJ
Various temporary arrays used in the calculation of the Pitzer activity coefficients.
double m_IionicMolality
Current value of the ionic strength on the molality scale Associated Salts, if present in the mechani...
void getPartialMolarEnthalpies(span< double > hbar) const override
Returns an array of partial molar enthalpies for the species in the mixture.
void calcMCCutoffParams_()
Calculate molality cut-off parameters.
Array2D m_Beta2MX_ij_coeff
Array of coefficients for Beta2, a variable in Pitzer's papers.
void s_update_d2lnMolalityActCoeff_dT2() const
This function calculates the temperature second derivative of the natural logarithm of the molality a...
vector< double > m_Beta2MX_ij_P
Derivative of Beta2_ij[i][j] wrt P. Vector index is counterIJ.
vector< double > m_Beta0MX_ij_LL
Derivative of Beta0_ij[i][j] wrt TT. Vector index is counterIJ.
int m_form_A_Debye
Form of the constant outside the Debye-Huckel term called A.
vector< double > m_molalitiesCropped
Cropped and modified values of the molalities used in activity coefficient calculations.
HMWSoln(const string &inputFile="", const string &id="")
Construct and initialize an HMWSoln ThermoPhase object directly from an input file.
vector< double > m_lnActCoeffMolal_Scaled
Logarithm of the activity coefficients on the molality scale.
vector< double > m_CphiMX_ij_P
Derivative of Cphi_ij[i][j] wrt P. Vector index is counterIJ.
vector< double > m_PhiPhi_IJ_L
Derivative of m_PhiPhi_IJ wrt T. Vector index is counterIJ.
vector< double > m_Theta_ij_LL
Derivative of Theta_ij[i][j] wrt TT. Vector index is counterIJ.
vector< double > m_Theta_ij_L
Derivative of Theta_ij[i][j] wrt T. Vector index is counterIJ.
void getPartialMolarCp(span< double > cpbar) const override
Return an array of partial molar heat capacities for the species in the mixture.
vector< double > m_CphiMX_ij_LL
Derivative of Cphi_ij[i][j] wrt TT. Vector index is counterIJ.
vector< double > m_PhiPhi_IJ_LL
Derivative of m_PhiPhi_IJ wrt TT. Vector index is counterIJ.
Array2D m_Lambda_nj_L
Derivative of Lambda_nj[i][j] wrt T. see m_Lambda_ij.
double s_NBS_CLM_dlnMolalityActCoeff_dT() const
Calculate the temperature derivative of the Chlorine activity coefficient on the NBS scale.
vector< double > m_Psi_ijk_L
Derivative of Psi_ijk[n] wrt T.
void getParameters(AnyMap &phaseNode) const override
Store the parameters of a ThermoPhase object such that an identical one could be reconstructed using ...
void initThermo() override
Initialize the ThermoPhase object after all species have been set up.
void s_updateScaling_pHScaling_dP() const
Apply the current phScale to a set of derivatives of the activity Coefficients wrt pressure.
void printCoeffs() const
Print out all of the input Pitzer coefficients.
vector< double > m_Psi_ijk
Array of 3D data used in the Pitzer/HMW formulation.
vector< double > m_hfunc_IJ
hfunc, was called gprime in Pitzer's paper.
void s_update_dlnMolalityActCoeff_dT() const
This function calculates the temperature derivative of the natural logarithm of the molality activity...
void s_update_lnMolalityActCoeff() const
This function will be called to update the internally stored natural logarithm of the molality activi...
void applyphScale(span< double > acMolality) const override
Apply the current phScale to a set of activity Coefficients or activities.
vector< double > m_Beta1MX_ij_P
Derivative of Beta1_ij[i][j] wrt P. Vector index is counterIJ.
vector< int > CROP_speciesCropped_
This is a boolean-type vector indicating whether a species's activity coefficient is in the cropped r...
vector< double > m_Alpha2MX_ij
Array of 2D data used in the Pitzer/HMW formulation.
double ADebye_V(double temperature=-1.0, double pressure=-1.0) const
Return Pitzer's definition of A_V.
vector< double > m_BphiMX_IJ_L
Derivative of BphiMX_IJ wrt T. Vector index is counterIJ.
vector< double > m_Phi_IJ_P
Derivative of m_Phi_IJ wrt P. Vector index is counterIJ.
vector< double > m_BphiMX_IJ_P
Derivative of BphiMX_IJ wrt P. Vector index is counterIJ.
void counterIJ_setup() const
Set up a counter variable for keeping track of symmetric binary interactions amongst the solute speci...
vector< double > m_BMX_IJ
Intermediate variable called BMX in Pitzer's paper.
vector< double > m_dlnActCoeffMolaldP_Unscaled
Derivative of the Logarithm of the activity coefficients on the molality scale wrt P.
vector< double > m_CMX_IJ_LL
Derivative of m_CMX_IJ wrt TT. Vector index is counterIJ.
vector< double > m_BMX_IJ_P
Derivative of BMX_IJ wrt P. Vector index is counterIJ.
double cv_mole() const override
Molar heat capacity at constant volume and composition [J/kmol/K].
vector< double > m_Mu_nnn_P
Mu coefficient pressure derivative for the self-ternary neutral coefficient.
Array2D m_Psi_ijk_coeff
Array of coefficients for Psi_ijk[n] in the Pitzer/HMW formulation.
void getActivities(span< double > ac) const override
Get the array of non-dimensional activities at the current solution temperature, pressure,...
void setA_Debye(double A)
Set the A_Debye parameter.
vector< double > IMS_lnActCoeffMolal_
Logarithm of the molal activity coefficients.
int m_formPitzerTemp
This is the form of the temperature dependence of Pitzer parameterization used in the model.
vector< double > m_dlnActCoeffMolaldT_Unscaled
Derivative of the Logarithm of the activity coefficients on the molality scale wrt T.
vector< double > m_BMX_IJ_L
Derivative of BMX_IJ wrt T. Vector index is counterIJ.
virtual double relative_enthalpy() const
Excess molar enthalpy of the solution from the mixing process.
vector< double > m_Beta0MX_ij_L
Derivative of Beta0_ij[i][j] wrt T. Vector index is counterIJ.
vector< double > m_Beta0MX_ij_P
Derivative of Beta0_ij[i][j] wrt P. Vector index is counterIJ.
void s_updatePitzer_CoeffWRTemp(int doDerivs=2) const
Calculates the Pitzer coefficients' dependence on the temperature.
double s_NBS_CLM_lnMolalityActCoeff() const
Calculate the Chlorine activity coefficient on the NBS scale.
vector< double > m_Theta_ij
Array of 2D data for Theta_ij[i][j] in the Pitzer/HMW formulation.
vector< double > m_Beta2MX_ij_L
Derivative of Beta2_ij[i][j] wrt T. Vector index is counterIJ.
vector< double > m_Mu_nnn_LL
Mu coefficient 2nd temperature derivative for the self-ternary neutral coefficient.
void s_updatePitzer_dlnMolalityActCoeff_dP() const
Calculates the Pressure derivative of the natural logarithm of the molality activity coefficients.
vector< double > m_BphiMX_IJ
Intermediate variable called BphiMX in Pitzer's paper.
Array2D m_Lambda_nj
Lambda coefficient for the ij interaction.
vector< double > m_BprimeMX_IJ
Intermediate variable called BprimeMX in Pitzer's paper.
vector< double > m_Theta_ij_P
Derivative of Theta_ij[i][j] wrt P. Vector index is counterIJ.
vector< double > m_PhiPhi_IJ
Intermediate variable called PhiPhi in Pitzer's paper.
vector< int > m_CounterIJ
a counter variable for keeping track of symmetric binary interactions amongst the solute species.
Array2D m_Mu_nnn_coeff
Array of coefficients form_Mu_nnn term.
virtual double relative_molal_enthalpy() const
Excess molar enthalpy of the solution from the mixing process on a molality basis.
double ADebye_L(double temperature=-1.0, double pressure=-1.0) const
Return Pitzer's definition of A_L.
PDSS * m_waterSS
Water standard state calculator.
void calcDensity() override
Calculate the density of the mixture using the partial molar volumes and mole fractions as input.
void calc_lambdas(double is) const
Calculate the lambda interactions.
double elambda1[17]
This is elambda1, MEC.
vector< double > m_Beta1MX_ij_LL
Derivative of Beta1_ij[i][j] wrt TT. Vector index is counterIJ.
vector< double > m_lnActCoeffMolal_Unscaled
Logarithm of the activity coefficients on the molality scale.
double s_NBS_CLM_dlnMolalityActCoeff_dP() const
Calculate the pressure derivative of the Chlorine activity coefficient.
double m_maxIionicStrength
Maximum value of the ionic strength allowed in the calculation of the activity coefficients.
vector< double > m_dlnActCoeffMolaldT_Scaled
Derivative of the Logarithm of the activity coefficients on the molality scale wrt T.
vector< double > m_Beta2MX_ij
Array of 2D data used in the Pitzer/HMW formulation.
void getUnscaledMolalityActivityCoefficients(span< double > acMolality) const override
Get the array of unscaled non-dimensional molality based activity coefficients at the current solutio...
vector< double > m_BprimeMX_IJ_LL
Derivative of BprimeMX wrt TT. Vector index is counterIJ.
vector< double > m_Phiprime_IJ
Intermediate variable called Phiprime in Pitzer's paper.
void s_updatePitzer_dlnMolalityActCoeff_dT() const
Calculates the temperature derivative of the natural logarithm of the molality activity coefficients.
void s_updatePitzer_lnMolalityActCoeff() const
Calculate the Pitzer portion of the activity coefficients.
vector< double > m_PhiPhi_IJ_P
Derivative of m_PhiPhi_IJ wrt P. Vector index is counterIJ.
virtual double dA_DebyedT_TP(double temperature=-1.0, double pressure=-1.0) const
Value of the derivative of the Debye Huckel constant with respect to temperature as a function of tem...
vector< double > m_BprimeMX_IJ_L
Derivative of BprimeMX wrt T. Vector index is counterIJ.
vector< double > m_Phi_IJ
Intermediate variable called Phi in Pitzer's paper.
vector< double > m_BMX_IJ_LL
Derivative of BMX_IJ wrt TT. Vector index is counterIJ.
vector< double > m_d2lnActCoeffMolaldT2_Scaled
Derivative of the Logarithm of the activity coefficients on the molality scale wrt TT.
Array2D m_Lambda_nj_LL
Derivative of Lambda_nj[i][j] wrt TT.
double IMS_X_o_cutoff_
value of the solute mole fraction that centers the cutoff polynomials for the cutoff =1 process;
double IMS_cCut_
Parameter in the polyExp cutoff treatment having to do with rate of exp decay.
void getPartialMolarVolumes(span< double > vbar) const override
Return an array of partial molar volumes for the species in the mixture.
vector< double > m_BphiMX_IJ_LL
Derivative of BphiMX_IJ wrt TT. Vector index is counterIJ.
void s_updatePitzer_d2lnMolalityActCoeff_dT2() const
This function calculates the temperature second derivative of the natural logarithm of the molality a...
vector< double > m_CMX_IJ_L
Derivative of m_CMX_IJ wrt T. Vector index is counterIJ.
Array2D m_Lambda_nj_coeff
Array of coefficients for Lambda_nj[i][j] in the Pitzer/HMW formulation.
vector< double > m_Psi_ijk_LL
Derivative of Psi_ijk[n] wrt TT.
void initLengths()
Initialize all of the species-dependent lengths in the object.
vector< double > m_g2func_IJ
This is the value of g2(x2) in Pitzer's papers. Vector index is counterIJ.
void getPartialMolarEntropies(span< double > sbar) const override
Returns an array of partial molar entropies of the species in the solution.
double standardConcentration(size_t k=0) const override
Return the standard concentration for the kth species.
vector< double > m_CphiMX_ij
Array of 2D data used in the Pitzer/HMW formulation.
vector< double > m_BprimeMX_IJ_P
Derivative of BprimeMX wrt P. Vector index is counterIJ.
vector< double > m_CMX_IJ
Intermediate variable called CMX in Pitzer's paper.
void s_update_dlnMolalityActCoeff_dP() const
This function calculates the pressure derivative of the natural logarithm of the molality activity co...
double MC_X_o_cutoff_
value of the solvent mole fraction that centers the cutoff polynomials for the cutoff =1 process;
double satPressure(double T) override
Get the saturation pressure for a given temperature.
double m_TempPitzerRef
Reference Temperature for the Pitzer formulations.
void calc_thetas(int z1, int z2, double ðeta, double ðeta_prime) const
Calculate etheta and etheta_prime.
void getChemPotentials(span< double > mu) const override
Get the species chemical potentials. Units: J/kmol.
vector< double > m_Beta2MX_ij_LL
Derivative of Beta2_ij[i][j] wrt TT. Vector index is counterIJ.
double elambda[17]
This is elambda, MEC.
void getActivityConcentrations(span< double > c) const override
This method returns an array of generalized activity concentrations.
vector< double > m_dlnActCoeffMolaldP_Scaled
Derivative of the Logarithm of the activity coefficients on the molality scale wrt P.
vector< double > m_Mu_nnn
Mu coefficient for the self-ternary neutral coefficient.
vector< double > m_Psi_ijk_P
Derivative of Psi_ijk[n] wrt P.
void s_updateIMS_lnMolalityActCoeff() const
This function will be called to update the internally stored natural logarithm of the molality activi...
void calcMolalitiesCropped() const
Calculate the cropped molalities.
vector< double > m_CphiMX_ij_L
Derivative of Cphi_ij[i][j] wrt T. Vector index is counterIJ.
double ADebye_J(double temperature=-1.0, double pressure=-1.0) const
Return Pitzer's definition of A_J.
void s_updateScaling_pHScaling_dT2() const
Apply the current phScale to a set of 2nd derivatives of the activity Coefficients wrt temperature.
Array2D m_Beta1MX_ij_coeff
Array of coefficients for Beta1, a variable in Pitzer's papers.
vector< double > m_CMX_IJ_P
Derivative of m_CMX_IJ wrt P. Vector index is counterIJ.
void s_updateScaling_pHScaling() const
Apply the current phScale to a set of activity Coefficients.
vector< double > m_Beta1MX_ij_L
Derivative of Beta1_ij[i][j] wrt T. Vector index is counterIJ.
Array2D m_CphiMX_ij_coeff
Array of coefficients for CphiMX, a parameter in the activity coefficient formulation.
virtual double A_Debye_TP(double temperature=-1.0, double pressure=-1.0) const
Value of the Debye Huckel constant as a function of temperature and pressure.
virtual double dA_DebyedP_TP(double temperature=-1.0, double pressure=-1.0) const
Value of the derivative of the Debye Huckel constant with respect to pressure, as a function of tempe...
bool m_molalitiesAreCropped
Boolean indicating whether the molalities are cropped or are modified.
vector< double > m_Phi_IJ_L
Derivative of m_Phi_IJ wrt T. Vector index is counterIJ.
vector< double > m_gamma_tmp
Intermediate storage of the activity coefficient itself.
double s_NBS_CLM_d2lnMolalityActCoeff_dT2() const
Calculate the second temperature derivative of the Chlorine activity coefficient on the NBS scale.
double m_Mnaught
This is the multiplication factor that goes inside log expressions involving the molalities of specie...
size_t m_indexCLM
Index of the phScale species.
void initThermo() override
Initialize the ThermoPhase object after all species have been set up.
double m_xmolSolventMIN
In any molality implementation, it makes sense to have a minimum solvent mole fraction requirement,...
vector< double > m_molalities
Current value of the molalities of the species in the phase.
int m_pHScalingType
Scaling to be used for output of single-ion species activity coefficients.
void setMoleFSolventMin(double xmolSolventMIN)
Sets the minimum mole fraction in the molality formulation.
void calcMolalities() const
Calculates the molality of all species and stores the result internally.
double m_weightSolvent
Molecular weight of the Solvent.
Class for the liquid water pressure dependent standard state.
virtual double satPressure(double T)
saturation pressure
virtual void setState_TP(double temp, double pres)
Set the internal temperature and pressure.
void getMoleFractions(span< double > x) const
Get the species mole fraction vector.
vector< double > m_workS
Vector of size m_kk, used as a temporary holding area.
ValueCache m_cache
Cached for saved calculations within each ThermoPhase.
size_t m_kk
Number of species in the phase.
size_t speciesIndex(const string &name, bool raise=true) const
Returns the index of a species named 'name' within the Phase object.
double temperature() const
Temperature (K).
string speciesName(size_t k) const
Name of the species with index k.
double mean_X(span< const double > Q) const
Evaluate the mole-fraction-weighted mean of an array Q.
double moleFraction(size_t k) const
Return the mole fraction of a single species.
int stateMFNumber() const
Return the State Mole Fraction Number.
virtual void setMoleFractions(span< const double > x)
Set the mole fractions to the specified values.
shared_ptr< Species > species(const string &name) const
Return the Species object for the named species.
virtual double molarVolume() const
Molar volume (m^3/kmol).
double charge(size_t k) const
Dimensionless electrical charge of a single molecule of species k The charge is normalized by the the...
virtual double cp_mole() const
Molar heat capacity at constant pressure and composition [J/kmol/K].
virtual double thermalExpansionCoeff() const
Return the volumetric thermal expansion coefficient. Units: 1/K.
virtual void getParameters(AnyMap &phaseNode) const
Store the parameters of a ThermoPhase object such that an identical one could be reconstructed using ...
double RT() const
Return the Gas Constant multiplied by the current temperature.
virtual double isothermalCompressibility() const
Returns the isothermal compressibility. Units: 1/Pa.
void initThermoFile(const string &inputFile, const string &id)
Initialize a ThermoPhase object using an input file.
AnyMap m_input
Data supplied via setParameters.
void getCp_R(span< double > cpr) const override
Get the nondimensional Heat Capacities at constant pressure for the species standard states at the cu...
double pressure() const override
Returns the current pressure of the phase.
void getStandardChemPotentials(span< double > mu) const override
Get the array of chemical potentials at unit activity for the species at their standard states at the...
void getEnthalpy_RT(span< double > hrt) const override
Get the nondimensional Enthalpy functions for the species at their standard states at the current T a...
void getEntropy_R(span< double > sr) const override
Get the array of nondimensional Entropy functions for the standard state species at the current T and...
void getStandardVolumes(span< double > vol) const override
Get the molar volumes of the species standard states at the current T and P of the solution.
virtual void updateStandardStateThermo() const
Updates the standard state thermodynamic functions at the current T and P of the solution.
virtual void calcDensity()
Calculate the density of the mixture using the partial molar volumes and mole fractions as input.
CachedScalar getScalar(int id)
Get a reference to a CachedValue object representing a scalar (double) with the given id.
int getId()
Get a unique id for a cached value.
Header file for a common definitions used in electrolytes thermodynamics.
bool caseInsensitiveEquals(const string &input, const string &test)
Case insensitive equality predicate.
#define AssertTrace(expr)
Assertion must be true or an error is thrown.
#define AssertThrowMsg(expr, procedure,...)
Assertion must be true or an error is thrown.
void writelogf(const char *fmt, const Args &... args)
Write a formatted message to the screen.
void writelog(const string &fmt, const Args &... args)
Write a formatted message to the screen.
int sign(T x)
Sign of a number.
const double GasConstant
Universal Gas Constant [J/kmol/K].
Namespace for the Cantera kernel.
const size_t npos
index returned by functions to indicate "no position"
const int PHSCALE_PITZER
Scale to be used for the output of single-ion activity coefficients is that used by Pitzer.
const double SmallNumber
smallest number to compare to zero.
const int PHSCALE_NBS
Scale to be used for evaluation of single-ion activity coefficients is that used by the NBS standard ...
void checkArraySize(const char *procedure, size_t available, size_t required)
Wrapper for throwing ArraySizeError.
Contains declarations for string manipulation functions within Cantera.
A cached property value and the state at which it was evaluated.
T value
The value of the cached property.
bool validate(double state1New)
Check whether the currently cached value is valid based on a single state variable.