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;
164 for (
size_t k = 1; k <
m_kk; k++) {
177 for (
size_t k = 0; k <
m_kk; k++) {
178 acMolality[k] = exp(acMolality[k]);
196 for (
size_t k = 1; k <
m_kk; k++) {
210 for (
size_t k = 0; k <
m_kk; k++) {
218 for (
size_t k = 0; k <
m_kk; k++) {
230 for (
size_t k = 0; k <
m_kk; k++) {
241 for (
size_t k = 1; k <
m_kk; k++) {
253 for (
size_t k = 0; k <
m_kk; k++) {
266 for (
size_t k = 0; k <
m_kk; k++) {
274 for (
size_t k = 0; k <
m_kk; k++) {
283 for (
size_t k = 0; k <
m_kk; k++) {
301static void check_nParams(
const string& method,
size_t nParams,
size_t m_formPitzerTemp)
303 if (m_formPitzerTemp == PITZER_TEMP_CONSTANT && nParams != 1) {
304 throw CanteraError(method,
"'constant' temperature model requires one"
305 " coefficient for each of parameter, but {} were given", nParams);
306 }
else if (m_formPitzerTemp == PITZER_TEMP_LINEAR && nParams != 2) {
307 throw CanteraError(method,
"'linear' temperature model requires two"
308 " coefficients for each parameter, but {} were given", nParams);
310 if (m_formPitzerTemp == PITZER_TEMP_COMPLEX1 && nParams != 5) {
311 throw CanteraError(method,
"'complex' temperature model requires five"
312 " coefficients for each parameter, but {} were given", nParams);
316void HMWSoln::setBinarySalt(
const string& sp1,
const string& sp2,
317 size_t nParams,
double* beta0,
double* beta1,
double* beta2,
318 double* Cphi,
double alpha1,
double alpha2)
325 throw CanteraError(
"HMWSoln::setBinarySalt",
"Species '{}' and '{}' "
326 "do not have opposite charges ({}, {})", sp1, sp2,
336 for (
size_t n = 0; n < nParams; n++) {
342 m_Alpha1MX_ij[c] = alpha1;
346void HMWSoln::setTheta(
const string& sp1,
const string& sp2,
347 size_t nParams,
double* theta)
352 throw CanteraError(
"HMWSoln::setTheta",
"Species '{}' and '{}' "
353 "should both have the same (non-zero) charge ({}, {})", sp1, sp2,
359 for (
size_t n = 0; n < nParams; n++) {
364void HMWSoln::setPsi(
const string& sp1,
const string& sp2,
365 const string& sp3,
size_t nParams,
double* psi)
373 throw CanteraError(
"HMWSoln::setPsi",
"All species must be ions and"
374 " must include at least one cation and one anion, but given species"
375 " (charges) were: {} ({}), {} ({}), and {} ({}).",
386 for (
size_t n = 0; n < nParams; n++) {
393void HMWSoln::setLambda(
const string& sp1,
const string& sp2,
394 size_t nParams,
double* lambda)
400 throw CanteraError(
"HMWSoln::setLambda",
"Expected at least one neutral"
401 " species, but given species (charges) were: {} ({}) and {} ({}).",
408 size_t c = k1*
m_kk + k2;
409 for (
size_t n = 0; n < nParams; n++) {
415void HMWSoln::setMunnn(
const string& sp,
size_t nParams,
double* munnn)
420 throw CanteraError(
"HMWSoln::setMunnn",
"Expected a neutral species,"
421 " got {} ({}).", sp,
charge(k));
424 for (
size_t n = 0; n < nParams; n++) {
430void HMWSoln::setZeta(
const string& sp1,
const string& sp2,
431 const string& sp3,
size_t nParams,
double* psi)
439 throw CanteraError(
"HMWSoln::setZeta",
"Requires one neutral species, "
440 "one cation, and one anion, but given species (charges) were: "
441 "{} ({}), {} ({}), and {} ({}).",
448 }
else if (
charge(k3) == 0) {
460 for (
size_t n = 0; n < nParams; n++) {
466void HMWSoln::setPitzerTempModel(
const string& model)
475 throw CanteraError(
"HMWSoln::setPitzerTempModel",
476 "Unknown Pitzer ActivityCoeff Temp model: {}", model);
490void HMWSoln::setCroppingCoefficients(
double ln_gamma_k_min,
491 double ln_gamma_k_max,
double ln_gamma_o_min,
double ln_gamma_o_max)
493 CROP_ln_gamma_k_min = ln_gamma_k_min;
494 CROP_ln_gamma_k_max = ln_gamma_k_max;
495 CROP_ln_gamma_o_min = ln_gamma_o_min;
496 CROP_ln_gamma_o_max = ln_gamma_o_max;
499vector<double> getSizedVector(
const AnyMap& item,
const string& key,
size_t nCoeffs)
502 if (item[key].is<double>()) {
505 v.push_back(item[key].asDouble());
507 v = item[key].asVector<
double>(1, nCoeffs);
509 if (v.size() == 1 && nCoeffs == 5) {
522 setPitzerTempModel(actData[
"temperature-model"].asString());
530 if (actData.hasKey(
"A_Debye")) {
531 if (actData[
"A_Debye"] ==
"variable") {
534 setA_Debye(actData.convert(
"A_Debye",
"kg^0.5/gmol^0.5"));
537 if (actData.hasKey(
"max-ionic-strength")) {
538 setMaxIonicStrength(actData[
"max-ionic-strength"].asDouble());
540 if (actData.hasKey(
"interactions")) {
541 for (
auto& item : actData[
"interactions"].asVector<
AnyMap>()) {
542 auto&
species = item[
"species"].asVector<
string>(1, 3);
547 if (nsp == 2 && q0 * q1 < 0) {
549 vector<double> beta0 = getSizedVector(item,
"beta0", nCoeffs);
550 vector<double> beta1 = getSizedVector(item,
"beta1", nCoeffs);
551 vector<double> beta2 = getSizedVector(item,
"beta2", nCoeffs);
552 vector<double> Cphi = getSizedVector(item,
"Cphi", nCoeffs);
553 if (beta0.size() != beta1.size() || beta0.size() != beta2.size()
554 || beta0.size() != Cphi.size()) {
556 "Inconsistent binary salt array sizes ({}, {}, {}, {})",
557 beta0.size(), beta1.size(), beta2.size(), Cphi.size());
559 double alpha1 = item[
"alpha1"].asDouble();
560 double alpha2 = item.getDouble(
"alpha2", 0.0);
562 beta0.data(), beta1.data(), beta2.data(), Cphi.data(),
564 }
else if (nsp == 2 && q0 * q1 > 0) {
566 vector<double> theta = getSizedVector(item,
"theta", nCoeffs);
568 }
else if (nsp == 2 && q0 * q1 == 0) {
570 vector<double> lambda = getSizedVector(item,
"lambda", nCoeffs);
572 }
else if (nsp == 3 && q0 * q1 * q2 != 0) {
574 vector<double> psi = getSizedVector(item,
"psi", nCoeffs);
576 psi.size(), psi.data());
577 }
else if (nsp == 3 && q0 * q1 * q2 == 0) {
579 vector<double> zeta = getSizedVector(item,
"zeta", nCoeffs);
581 zeta.size(), zeta.data());
582 }
else if (nsp == 1) {
584 vector<double> mu = getSizedVector(item,
"mu", nCoeffs);
585 setMunnn(
species[0], mu.size(), mu.data());
589 if (actData.hasKey(
"cropping-coefficients")) {
590 auto& crop = actData[
"cropping-coefficients"].as<
AnyMap>();
591 setCroppingCoefficients(
592 crop.getDouble(
"ln_gamma_k_min", crop_ln_gamma_k_min_default),
593 crop.getDouble(
"ln_gamma_k_max", crop_ln_gamma_k_max_default),
594 crop.getDouble(
"ln_gamma_o_min", crop_ln_gamma_o_min_default),
595 crop.getDouble(
"ln_gamma_o_max", crop_ln_gamma_o_max_default));
601 for (
int i = 0; i < 17; i++) {
615 vector<double> mf(
m_kk, 0.0);
623 for (
size_t k = 0; k <
m_kk; k++) {
625 if (fabs(mf[k] *
charge(k)) > MaxC) {
632 if (fabs(sum) > 1.0E-30) {
634 if (mf[kHp] > sum * 1.1) {
648 if (mf[kOHm] > -sum * 1.1) {
660 if (notDone && kMaxC !=
npos) {
661 if (mf[kMaxC] > (1.1 * sum /
charge(kMaxC))) {
662 mf[kMaxC] -= sum /
charge(kMaxC);
663 mf[0] += sum /
charge(kMaxC);
682void assignTrimmed(
AnyMap& interaction,
const string& key, vector<double>& values) {
683 while (values.size() > 1 && values.back() == 0) {
686 if (values.size() == 1) {
687 interaction[key] = values[0];
689 interaction[key] = values;
699 activityNode[
"temperature-model"] =
"linear";
702 activityNode[
"temperature-model"] =
"complex";
707 activityNode[
"A_Debye"] =
"variable";
708 }
else if (
m_A_Debye != A_Debye_default) {
709 activityNode[
"A_Debye"].setQuantity(
m_A_Debye,
"kg^0.5/gmol^0.5");
715 vector<AnyMap> interactions;
718 for (
size_t i = 1; i <
m_kk; i++) {
719 for (
size_t j = 1; j <
m_kk; j++) {
720 size_t c = i*
m_kk + j;
722 bool lambda_found =
false;
723 for (
size_t n = 0; n < nParams; n++) {
731 interaction[
"species"] = vector<string>{
733 vector<double> lambda(nParams);
734 for (
size_t n = 0; n < nParams; n++) {
737 assignTrimmed(interaction,
"lambda", lambda);
738 interactions.push_back(std::move(interaction));
743 if (c == 0 || i > j) {
748 bool salt_found =
false;
749 for (
size_t n = 0; n < nParams; n++) {
759 interaction[
"species"] = vector<string>{
761 vector<double> beta0(nParams), beta1(nParams), beta2(nParams), Cphi(nParams);
762 size_t last_nonzero = 0;
763 for (
size_t n = 0; n < nParams; n++) {
768 if (beta0[n] || beta1[n] || beta2[n] || Cphi[n]) {
772 if (last_nonzero == 0) {
773 interaction[
"beta0"] = beta0[0];
774 interaction[
"beta1"] = beta1[0];
775 interaction[
"beta2"] = beta2[0];
776 interaction[
"Cphi"] = Cphi[0];
778 beta0.resize(1 + last_nonzero);
779 beta1.resize(1 + last_nonzero);
780 beta2.resize(1 + last_nonzero);
781 Cphi.resize(1 + last_nonzero);
782 interaction[
"beta0"] = beta0;
783 interaction[
"beta1"] = beta1;
784 interaction[
"beta2"] = beta2;
785 interaction[
"Cphi"] = Cphi;
787 interaction[
"alpha1"] = m_Alpha1MX_ij[c];
791 interactions.push_back(std::move(interaction));
796 bool theta_found =
false;
797 for (
size_t n = 0; n < nParams; n++) {
805 interaction[
"species"] = vector<string>{
807 vector<double> theta(nParams);
808 for (
size_t n = 0; n < nParams; n++) {
811 assignTrimmed(interaction,
"theta", theta);
812 interactions.push_back(std::move(interaction));
821 for (
size_t i = 1; i <
m_kk; i++) {
825 for (
size_t j = i + 1; j <
m_kk; j++) {
829 for (
size_t k = j + 1; k <
m_kk; k++) {
834 for (
size_t n = 0; n < nParams; n++) {
837 interaction[
"species"] = vector<string>{
839 vector<double> psi(nParams);
840 for (
size_t m = 0; m < nParams; m++) {
843 assignTrimmed(interaction,
"psi", psi);
844 interactions.push_back(std::move(interaction));
853 for (
size_t i = 1; i <
m_kk; i++) {
857 for (
size_t j = 1; j <
m_kk; j++) {
861 for (
size_t k = 1; k <
m_kk; k++) {
866 for (
size_t n = 0; n < nParams; n++) {
869 interaction[
"species"] = vector<string>{
871 vector<double> zeta(nParams);
872 for (
size_t m = 0; m < nParams; m++) {
875 assignTrimmed(interaction,
"zeta", zeta);
876 interactions.push_back(std::move(interaction));
885 for (
size_t i = 1; i <
m_kk; i++) {
886 for (
size_t n = 0; n < nParams; n++) {
889 interaction[
"species"] = vector<string>{
speciesName(i)};
890 vector<double> mu(nParams);
891 for (
size_t m = 0; m < nParams; m++) {
894 assignTrimmed(interaction,
"mu", mu);
895 interactions.push_back(std::move(interaction));
901 activityNode[
"interactions"] = std::move(interactions);
904 if (CROP_ln_gamma_k_min != crop_ln_gamma_k_min_default) {
905 croppingCoeffs[
"ln_gamma_k_min"] = CROP_ln_gamma_k_min;
907 if (CROP_ln_gamma_k_max != crop_ln_gamma_k_max_default) {
908 croppingCoeffs[
"ln_gamma_k_max"] = CROP_ln_gamma_k_max;
910 if (CROP_ln_gamma_o_min != crop_ln_gamma_o_min_default) {
911 croppingCoeffs[
"ln_gamma_o_min"] = CROP_ln_gamma_o_min;
913 if (CROP_ln_gamma_o_max != crop_ln_gamma_o_max_default) {
914 croppingCoeffs[
"ln_gamma_o_max"] = CROP_ln_gamma_o_max;
916 if (croppingCoeffs.
size()) {
917 activityNode[
"cropping-coefficients"] = std::move(croppingCoeffs);
920 phaseNode[
"activity-data"] = std::move(activityNode);
927 if (tempArg != -1.0) {
931 if (presArg != -1.0) {
950 throw CanteraError(
"HMWSoln::A_Debye_TP",
"shouldn't be here");
958 if (tempArg != -1.0) {
962 if (presArg != -1.0) {
974 throw CanteraError(
"HMWSoln::dA_DebyedT_TP",
"shouldn't be here");
982 if (tempArg != -1.0) {
986 if (presArg != -1.0) {
1002 cached.
value = dAdP;
1006 throw CanteraError(
"HMWSoln::dA_DebyedP_TP",
"shouldn't be here");
1014 double dAphidT = dAdT /3.0;
1016 if (tempArg != -1.0) {
1025 double dAphidP = dAdP /3.0;
1027 if (tempArg != -1.0) {
1036 if (tempArg != -1.0) {
1041 double d2Aphi = d2 / 3.0;
1042 return 2.0 * A_L / T + 4.0 *
GasConstant * T * T *d2Aphi;
1048 if (tempArg != -1.0) {
1052 if (presArg != -1.0) {
1064 throw CanteraError(
"HMWSoln::d2A_DebyedT2_TP",
"shouldn't be here");
1078 size_t maxCounterIJlen = 1 + (
m_kk-1) * (
m_kk-2) / 2;
1081 int TCoeffLength = 1;
1112 m_Alpha1MX_ij.resize(maxCounterIJlen, 2.0);
1153 m_BMX_IJ.resize(maxCounterIJlen, 0.0);
1165 m_Phi_IJ.resize(maxCounterIJlen, 0.0);
1174 m_CMX_IJ.resize(maxCounterIJlen, 0.0);
1214 double lnActCoeffMolal0 = - log(xx) + (xx - 1.0)/xx;
1215 double lnxs = log(xx);
1217 for (
size_t k = 1; k <
m_kk; k++) {
1255 for (
size_t k = 0; k <
m_kk; k++) {
1261 if (cropMethod == 0) {
1268 for (
size_t i = 1; i < (
m_kk - 1); i++) {
1269 double charge_i =
charge(i);
1270 double abs_charge_i = fabs(charge_i);
1271 if (charge_i == 0.0) {
1274 for (
size_t j = (i+1); j <
m_kk; j++) {
1275 double charge_j =
charge(j);
1276 double abs_charge_j = fabs(charge_j);
1279 if (charge_i * charge_j < 0) {
1284 if (Imax > Iac_max) {
1288 if (Imax > Iac_max) {
1293 if (Imax > Iac_max) {
1297 if (Imax > Iac_max) {
1307 for (
int times = 0; times< 10; times++) {
1308 double anion_charge = 0.0;
1309 double cation_charge = 0.0;
1310 size_t anion_contrib_max_i =
npos;
1311 double anion_contrib_max = -1.0;
1312 size_t cation_contrib_max_i =
npos;
1313 double cation_contrib_max = -1.0;
1314 for (
size_t i = 0; i <
m_kk; i++) {
1315 double charge_i =
charge(i);
1316 if (charge_i < 0.0) {
1318 anion_charge += anion_contrib;
1319 if (anion_contrib > anion_contrib_max) {
1320 anion_contrib_max = anion_contrib;
1321 anion_contrib_max_i = i;
1323 }
else if (charge_i > 0.0) {
1325 cation_charge += cation_contrib;
1326 if (cation_contrib > cation_contrib_max) {
1327 cation_contrib_max = cation_contrib;
1328 cation_contrib_max_i = i;
1332 double total_charge = cation_charge - anion_charge;
1333 if (total_charge > 1.0E-8) {
1334 double desiredCrop = total_charge/
charge(cation_contrib_max_i);
1336 if (desiredCrop < maxCrop) {
1342 }
else if (total_charge < -1.0E-8) {
1343 double desiredCrop = total_charge/
charge(anion_contrib_max_i);
1345 if (desiredCrop < maxCrop) {
1357 if (cropMethod == 1) {
1360 double xmolSolvent = molF[0];
1366 double poly = MC_apCut_ + MC_bpCut_ * xmolSolvent + MC_dpCut_* xmolSolvent * xmolSolvent;
1367 double p = xmolSolvent + MC_epCut_ + exp(- xmolSolvent/ MC_cpCut_) * poly;
1369 for (
size_t k = 0; k <
m_kk; k++) {
1377 for (
size_t k = 0; k <
m_kk; k++) {
1382 for (
size_t k = 0; k <
m_kk; k++) {
1395 for (
size_t i = 0; i <
m_kk; i++) {
1397 size_t nc =
m_kk * i;
1401 for (
size_t i = 1; i < (
m_kk - 1); i++) {
1402 size_t n =
m_kk * i + i;
1404 for (
size_t j = (i+1); j <
m_kk; j++) {
1406 size_t nc =
m_kk * i + j;
1416 double IMS_gamma_o_min_ = 1.0E-5;
1417 double IMS_gamma_k_min_ = 10.0;
1418 double IMS_slopefCut_ = 0.6;
1420 IMS_afCut_ = 1.0 / (std::exp(1.0) * IMS_gamma_k_min_);
1422 bool converged =
false;
1424 for (
int its = 0; its < 100 && !converged; its++) {
1426 IMS_afCut_ = 1.0 / (std::exp(1.0) * IMS_gamma_k_min_) -IMS_efCut_;
1427 IMS_bfCut_ = IMS_afCut_ /
IMS_cCut_ + IMS_slopefCut_ - 1.0;
1433 IMS_efCut_ = - eterm * tmp;
1434 if (fabs(IMS_efCut_ - oldV) < 1.0E-14) {
1440 " failed to converge on the f polynomial");
1443 double f_0 = IMS_afCut_ + IMS_efCut_;
1444 double f_prime_0 = 1.0 - IMS_afCut_ /
IMS_cCut_ + IMS_bfCut_;
1446 for (
int its = 0; its < 100 && !converged; its++) {
1448 double lng_0 = -log(IMS_gamma_o_min_) - f_prime_0 / f_0;
1449 IMS_agCut_ = exp(lng_0) - IMS_egCut_;
1456 IMS_egCut_ = - eterm * tmp;
1457 if (fabs(IMS_egCut_ - oldV) < 1.0E-14) {
1463 " failed to converge on the g polynomial");
1469 double MC_X_o_min_ = 0.35;
1471 double MC_slopepCut_ = 0.02;
1475 MC_apCut_ = MC_X_o_min_;
1477 bool converged =
false;
1480 for (
int its = 0; its < 500 && !converged; its++) {
1482 MC_apCut_ = damp *(MC_X_o_min_ - MC_epCut_) + (1-damp) * MC_apCut_;
1483 double MC_bpCutNew = MC_apCut_ / MC_cpCut_ + MC_slopepCut_ - 1.0;
1484 MC_bpCut_ = damp * MC_bpCutNew + (1-damp) * MC_bpCut_;
1485 double MC_dpCutNew = ((- MC_apCut_/MC_cpCut_ + MC_bpCut_ - MC_bpCut_ *
MC_X_o_cutoff_/MC_cpCut_)
1488 MC_dpCut_ = damp * MC_dpCutNew + (1-damp) * MC_dpCut_;
1491 MC_epCut_ = - eterm * tmp;
1492 double diff = MC_epCut_ - oldV;
1493 if (fabs(diff) < 1.0E-14) {
1499 " failed to converge on the p polynomial");
1506 const double twoT = 2.0 * T;
1507 const double invT = 1.0 / T;
1508 const double invT2 = invT * invT;
1509 const double twoinvT3 = 2.0 * invT * invT2;
1510 double tinv = 0.0, tln = 0.0, tlin = 0.0, tquad = 0.0;
1520 for (
size_t i = 1; i < (
m_kk - 1); i++) {
1521 for (
size_t j = (i+1); j <
m_kk; j++) {
1523 size_t n =
m_kk*i + j;
1533 case PITZER_TEMP_CONSTANT:
1535 case PITZER_TEMP_LINEAR:
1538 + beta0MX_coeff[1]*tlin;
1542 + beta1MX_coeff[1]*tlin;
1546 + beta2MX_coeff[1]*tlin;
1550 + CphiMX_coeff[1]*tlin;
1553 m_Theta_ij[counterIJ] = Theta_coeff[0] + Theta_coeff[1]*tlin;
1558 case PITZER_TEMP_COMPLEX1:
1560 + beta0MX_coeff[1]*tlin
1561 + beta0MX_coeff[2]*tquad
1562 + beta0MX_coeff[3]*tinv
1563 + beta0MX_coeff[4]*tln;
1565 + beta1MX_coeff[1]*tlin
1566 + beta1MX_coeff[2]*tquad
1567 + beta1MX_coeff[3]*tinv
1568 + beta1MX_coeff[4]*tln;
1570 + beta2MX_coeff[1]*tlin
1571 + beta2MX_coeff[2]*tquad
1572 + beta2MX_coeff[3]*tinv
1573 + beta2MX_coeff[4]*tln;
1575 + CphiMX_coeff[1]*tlin
1576 + CphiMX_coeff[2]*tquad
1577 + CphiMX_coeff[3]*tinv
1578 + CphiMX_coeff[4]*tln;
1580 + Theta_coeff[1]*tlin
1581 + Theta_coeff[2]*tquad
1582 + Theta_coeff[3]*tinv
1583 + Theta_coeff[4]*tln;
1585 + beta0MX_coeff[2]*twoT
1586 - beta0MX_coeff[3]*invT2
1587 + beta0MX_coeff[4]*invT;
1589 + beta1MX_coeff[2]*twoT
1590 - beta1MX_coeff[3]*invT2
1591 + beta1MX_coeff[4]*invT;
1593 + beta2MX_coeff[2]*twoT
1594 - beta2MX_coeff[3]*invT2
1595 + beta2MX_coeff[4]*invT;
1597 + CphiMX_coeff[2]*twoT
1598 - CphiMX_coeff[3]*invT2
1599 + CphiMX_coeff[4]*invT;
1601 + Theta_coeff[2]*twoT
1602 - Theta_coeff[3]*invT2
1603 + Theta_coeff[4]*invT;
1607 + beta0MX_coeff[2]*2.0
1608 + beta0MX_coeff[3]*twoinvT3
1609 - beta0MX_coeff[4]*invT2;
1611 + beta1MX_coeff[2]*2.0
1612 + beta1MX_coeff[3]*twoinvT3
1613 - beta1MX_coeff[4]*invT2;
1615 + beta2MX_coeff[2]*2.0
1616 + beta2MX_coeff[3]*twoinvT3
1617 - beta2MX_coeff[4]*invT2;
1619 + CphiMX_coeff[2]*2.0
1620 + CphiMX_coeff[3]*twoinvT3
1621 - CphiMX_coeff[4]*invT2;
1623 + Theta_coeff[2]*2.0
1624 + Theta_coeff[3]*twoinvT3
1625 - Theta_coeff[4]*invT2;
1635 for (
size_t i = 1; i <
m_kk; i++) {
1637 for (
size_t j = 1; j <
m_kk; j++) {
1638 size_t n = i *
m_kk + j;
1641 case PITZER_TEMP_CONSTANT:
1644 case PITZER_TEMP_LINEAR:
1645 m_Lambda_nj(i,j) = Lambda_coeff[0] + Lambda_coeff[1]*tlin;
1649 case PITZER_TEMP_COMPLEX1:
1651 + Lambda_coeff[1]*tlin
1652 + Lambda_coeff[2]*tquad
1653 + Lambda_coeff[3]*tinv
1654 + Lambda_coeff[4]*tln;
1657 + Lambda_coeff[2]*twoT
1658 - Lambda_coeff[3]*invT2
1659 + Lambda_coeff[4]*invT;
1663 + Lambda_coeff[3]*twoinvT3
1664 - Lambda_coeff[4]*invT2;
1670 case PITZER_TEMP_CONSTANT:
1673 case PITZER_TEMP_LINEAR:
1674 m_Mu_nnn[i] = Mu_coeff[0] + Mu_coeff[1]*tlin;
1678 case PITZER_TEMP_COMPLEX1:
1690 + Mu_coeff[3]*twoinvT3
1691 - Mu_coeff[4]*invT2;
1699 case PITZER_TEMP_CONSTANT:
1700 for (
size_t i = 1; i <
m_kk; i++) {
1701 for (
size_t j = 1; j <
m_kk; j++) {
1702 for (
size_t k = 1; k <
m_kk; k++) {
1710 case PITZER_TEMP_LINEAR:
1711 for (
size_t i = 1; i <
m_kk; i++) {
1712 for (
size_t j = 1; j <
m_kk; j++) {
1713 for (
size_t k = 1; k <
m_kk; k++) {
1716 m_Psi_ijk[n] = Psi_coeff[0] + Psi_coeff[1]*tlin;
1723 case PITZER_TEMP_COMPLEX1:
1724 for (
size_t i = 1; i <
m_kk; i++) {
1725 for (
size_t j = 1; j <
m_kk; j++) {
1726 for (
size_t k = 1; k <
m_kk; k++) {
1731 + Psi_coeff[2]*tquad
1736 - Psi_coeff[3]*invT2
1737 + Psi_coeff[4]*invT;
1740 + Psi_coeff[3]*twoinvT3
1741 - Psi_coeff[4]*invT2;
1759 double etheta[5][5], etheta_prime[5][5], sqrtIs;
1766 double molarcharge = 0.0;
1770 double molalitysumUncropped = 0.0;
1776 for (
size_t n = 1; n <
m_kk; n++) {
1780 molarcharge += fabs(
charge(n)) * molality[n];
1795 for (
int z1 = 1; z1 <=4; z1++) {
1796 for (
int z2 =1; z2 <=4; z2++) {
1797 calc_thetas(z1, z2, ðeta[z1][z2], ðeta_prime[z1][z2]);
1804 for (
size_t i = 1; i < (
m_kk - 1); i++) {
1805 for (
size_t j = (i+1); j <
m_kk; j++) {
1807 size_t n =
m_kk*i + j;
1813 double x1 = sqrtIs * m_Alpha1MX_ij[counterIJ];
1814 if (x1 > 1.0E-100) {
1815 m_gfunc_IJ[counterIJ] = 2.0*(1.0-(1.0 + x1) * exp(-x1)) / (x1 * x1);
1817 (1.0-(1.0 + x1 + 0.5 * x1 * x1) * exp(-x1)) / (x1 * x1);
1825 if (x2 > 1.0E-100) {
1826 m_g2func_IJ[counterIJ] = 2.0*(1.0-(1.0 + x2) * exp(-x2)) / (x2 * x2);
1828 (1.0-(1.0 + x2 + 0.5 * x2 * x2) * exp(-x2)) / (x2 * x2);
1843 for (
size_t i = 1; i <
m_kk - 1; i++) {
1844 for (
size_t j = i+1; j <
m_kk; j++) {
1846 size_t n =
m_kk*i + j;
1856 if (Is > 1.0E-150) {
1873 for (
size_t i = 1; i <
m_kk-1; i++) {
1874 for (
size_t j = i+1; j <
m_kk; j++) {
1876 size_t n =
m_kk*i + j;
1892 for (
size_t i = 1; i <
m_kk-1; i++) {
1893 for (
size_t j = i+1; j <
m_kk; j++) {
1895 size_t n =
m_kk*i + j;
1901 int z1 = (int) fabs(
charge(i));
1902 int z2 = (int) fabs(
charge(j));
1917 double F = -Aphi * (sqrt(Is) / (1.0 + 1.2*sqrt(Is))
1918 + (2.0/1.2) * log(1.0+1.2*(sqrtIs)));
1919 for (
size_t i = 1; i <
m_kk-1; i++) {
1920 for (
size_t j = i+1; j <
m_kk; j++) {
1922 size_t n =
m_kk*i + j;
1939 for (
size_t i = 1; i <
m_kk; i++) {
1952 for (
size_t j = 1; j <
m_kk; j++) {
1954 size_t n =
m_kk*i + j;
1959 sum1 += molality[j] *
1965 for (
size_t k = j+1; k <
m_kk; k++) {
1969 sum3 += molality[j]*molality[k]*
m_Psi_ijk[n];
1978 sum2 += molality[j]*(2.0*
m_Phi_IJ[counterIJ]);
1980 for (
size_t k = 1; k <
m_kk; k++) {
1984 sum2 += molality[j]*molality[k]*
m_Psi_ijk[n];
1989 sum4 += (fabs(
charge(i))*
1990 molality[j]*molality[k]*
m_CMX_IJ[counterIJ2]);
2000 for (
size_t k = 1; k <
m_kk; k++) {
2007 sum5 += molality[j]*molality[k]*zeta;
2031 for (
size_t j = 1; j <
m_kk; j++) {
2033 size_t n =
m_kk*i + j;
2038 sum1 += molality[j]*
2041 for (
size_t k = j+1; k <
m_kk; k++) {
2045 sum3 += molality[j]*molality[k]*
m_Psi_ijk[n];
2055 sum2 += molality[j]*(2.0*
m_Phi_IJ[counterIJ]);
2057 for (
size_t k = 1; k <
m_kk; k++) {
2061 sum2 += molality[j]*molality[k]*
m_Psi_ijk[n];
2066 molality[j]*molality[k]*
m_CMX_IJ[counterIJ2];
2075 for (
size_t k = 1; k <
m_kk; k++) {
2083 sum5 += molality[j]*molality[k]*zeta;
2099 for (
size_t j = 1; j <
m_kk; j++) {
2103 for (
size_t k = 1; k <
m_kk; k++) {
2106 sum3 += molality[j]*molality[k]*
m_Psi_ijk[n];
2111 double sum2 = 3.0 * molality[i]* molality[i] *
m_Mu_nnn[i];
2133 double term1 = -Aphi * pow(Is,1.5) / (1.0 + 1.2 * sqrt(Is));
2135 for (
size_t j = 1; j <
m_kk; j++) {
2138 for (
size_t k = 1; k <
m_kk; k++) {
2141 size_t n =
m_kk*j + k;
2144 sum1 += molality[j]*molality[k]*
2149 for (
size_t k = j+1; k <
m_kk; k++) {
2150 if (j == (
m_kk-1)) {
2152 throw CanteraError(
"HMWSoln::s_updatePitzer_lnMolalityActCoeff",
2153 "logic error 1 in Step 9 of hmw_act");
2158 size_t n =
m_kk*j + k;
2160 sum2 += molality[j]*molality[k]*
m_PhiPhi_IJ[counterIJ];
2161 for (
size_t m = 1; m <
m_kk; m++) {
2165 sum2 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk[n];
2174 for (
size_t k = j+1; k <
m_kk; k++) {
2177 throw CanteraError(
"HMWSoln::s_updatePitzer_lnMolalityActCoeff",
2178 "logic error 2 in Step 9 of hmw_act");
2183 size_t n =
m_kk*j + k;
2185 sum3 += molality[j]*molality[k]*
m_PhiPhi_IJ[counterIJ];
2186 for (
size_t m = 1; m <
m_kk; m++) {
2189 sum3 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk[n];
2198 for (
size_t k = 1; k <
m_kk; k++) {
2208 }
else if (k == j) {
2209 sum6 += 0.5 * molality[j]*molality[k]*
m_Lambda_nj(j,k);
2214 for (
size_t m = 1; m <
m_kk; m++) {
2220 sum7 += molality[izeta]*molality[jzeta]*molality[k]*zeta;
2226 sum7 += molality[j]*molality[j]*molality[j]*
m_Mu_nnn[j];
2229 double sum_m_phi_minus_1 = 2.0 *
2230 (term1 + sum1 + sum2 + sum3 + sum4 + sum5 + sum6 + sum7);
2233 double osmotic_coef;
2234 if (molalitysumUncropped > 1.0E-150) {
2235 osmotic_coef = 1.0 + (sum_m_phi_minus_1 / molalitysumUncropped);
2239 double lnwateract = -(
m_weightSolvent/1000.0) * molalitysumUncropped * osmotic_coef;
2266 for (
size_t k = 1; k <
m_kk; k++) {
2290 double etheta[5][5], etheta_prime[5][5], sqrtIs;
2297 double molarcharge = 0.0;
2301 double molalitysum = 0.0;
2307 for (
size_t n = 1; n <
m_kk; n++) {
2311 molarcharge += fabs(
charge(n)) * molality[n];
2312 molalitysum += molality[n];
2326 for (
int z1 = 1; z1 <=4; z1++) {
2327 for (
int z2 =1; z2 <=4; z2++) {
2328 calc_thetas(z1, z2, ðeta[z1][z2], ðeta_prime[z1][z2]);
2335 for (
size_t i = 1; i < (
m_kk - 1); i++) {
2336 for (
size_t j = (i+1); j <
m_kk; j++) {
2338 size_t n =
m_kk*i + j;
2344 double x1 = sqrtIs * m_Alpha1MX_ij[counterIJ];
2345 if (x1 > 1.0E-100) {
2346 m_gfunc_IJ[counterIJ] = 2.0*(1.0-(1.0 + x1) * exp(-x1)) / (x1 * x1);
2348 (1.0-(1.0 + x1 + 0.5 * x1 *x1) * exp(-x1)) / (x1 * x1);
2356 if (x2 > 1.0E-100) {
2357 m_g2func_IJ[counterIJ] = 2.0*(1.0-(1.0 + x2) * exp(-x2)) / (x2 * x2);
2359 (1.0-(1.0 + x2 + 0.5 * x2 * x2) * exp(-x2)) / (x2 * x2);
2375 for (
size_t i = 1; i <
m_kk - 1; i++) {
2376 for (
size_t j = i+1; j <
m_kk; j++) {
2378 size_t n =
m_kk*i + j;
2387 if (Is > 1.0E-150) {
2403 for (
size_t i = 1; i <
m_kk-1; i++) {
2404 for (
size_t j = i+1; j <
m_kk; j++) {
2406 size_t n =
m_kk*i + j;
2421 for (
size_t i = 1; i <
m_kk-1; i++) {
2422 for (
size_t j = i+1; j <
m_kk; j++) {
2424 size_t n =
m_kk*i + j;
2443 double dAphidT = dA_DebyedT /3.0;
2444 double dFdT = -dAphidT * (sqrt(Is) / (1.0 + 1.2*sqrt(Is))
2445 + (2.0/1.2) * log(1.0+1.2*(sqrtIs)));
2446 for (
size_t i = 1; i <
m_kk-1; i++) {
2447 for (
size_t j = i+1; j <
m_kk; j++) {
2449 size_t n =
m_kk*i + j;
2466 for (
size_t i = 1; i <
m_kk; i++) {
2476 for (
size_t j = 1; j <
m_kk; j++) {
2478 size_t n =
m_kk*i + j;
2483 sum1 += molality[j]*
2489 for (
size_t k = j+1; k <
m_kk; k++) {
2502 sum2 += molality[j]*(2.0*
m_Phi_IJ_L[counterIJ]);
2504 for (
size_t k = 1; k <
m_kk; k++) {
2514 molality[j]*molality[k]*
m_CMX_IJ_L[counterIJ2];
2525 for (
size_t k = 1; k <
m_kk; k++) {
2531 if (zeta_L != 0.0) {
2532 sum5 += molality[j]*molality[k]*zeta_L;
2541 zsqdFdT + sum1 + sum2 + sum3 + sum4 + sum5;
2554 for (
size_t j = 1; j <
m_kk; j++) {
2556 size_t n =
m_kk*i + j;
2561 sum1 += molality[j]*
2564 for (
size_t k = j+1; k <
m_kk; k++) {
2578 sum2 += molality[j]*(2.0*
m_Phi_IJ_L[counterIJ]);
2580 for (
size_t k = 1; k <
m_kk; k++) {
2588 sum4 += fabs(
charge(i)) *
2589 molality[j]*molality[k]*
m_CMX_IJ_L[counterIJ2];
2597 for (
size_t k = 1; k <
m_kk; k++) {
2604 if (zeta_L != 0.0) {
2605 sum5 += molality[j]*molality[k]*zeta_L;
2612 zsqdFdT + sum1 + sum2 + sum3 + sum4 + sum5;
2622 for (
size_t j = 1; j <
m_kk; j++) {
2626 for (
size_t k = 1; k <
m_kk; k++) {
2634 double sum2 = 3.0 * molality[i] * molality[i] *
m_Mu_nnn_L[i];
2654 double term1 = -dAphidT * Is * sqrt(Is) / (1.0 + 1.2 * sqrt(Is));
2656 for (
size_t j = 1; j <
m_kk; j++) {
2659 for (
size_t k = 1; k <
m_kk; k++) {
2662 size_t n =
m_kk*j + k;
2664 sum1 += molality[j]*molality[k]*
2669 for (
size_t k = j+1; k <
m_kk; k++) {
2670 if (j == (
m_kk-1)) {
2672 throw CanteraError(
"HMWSoln::s_updatePitzer_dlnMolalityActCoeff_dT",
2673 "logic error 1 in Step 9 of hmw_act");
2678 size_t n =
m_kk*j + k;
2681 for (
size_t m = 1; m <
m_kk; m++) {
2685 sum2 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk_L[n];
2694 for (
size_t k = j+1; k <
m_kk; k++) {
2697 throw CanteraError(
"HMWSoln::s_updatePitzer_dlnMolalityActCoeff_dT",
2698 "logic error 2 in Step 9 of hmw_act");
2703 size_t n =
m_kk*j + k;
2706 for (
size_t m = 1; m <
m_kk; m++) {
2709 sum3 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk_L[n];
2718 for (
size_t k = 1; k <
m_kk; k++) {
2728 }
else if (k == j) {
2734 for (
size_t m = 1; m <
m_kk; m++) {
2739 if (zeta_L != 0.0) {
2740 sum7 += molality[izeta]*molality[jzeta]*molality[k]*zeta_L;
2746 sum7 += molality[j]*molality[j]*molality[j]*
m_Mu_nnn_L[j];
2749 double sum_m_phi_minus_1 = 2.0 *
2750 (term1 + sum1 + sum2 + sum3 + sum4 + sum5 + sum6 + sum7);
2753 double d_osmotic_coef_dT;
2754 if (molalitysum > 1.0E-150) {
2755 d_osmotic_coef_dT = 0.0 + (sum_m_phi_minus_1 / molalitysum);
2757 d_osmotic_coef_dT = 0.0;
2760 double d_lnwateract_dT = -(
m_weightSolvent/1000.0) * molalitysum * d_osmotic_coef_dT;
2785 for (
size_t k = 1; k <
m_kk; k++) {
2804 double etheta[5][5], etheta_prime[5][5], sqrtIs;
2811 double molarcharge = 0.0;
2815 double molalitysum = 0.0;
2821 for (
size_t n = 1; n <
m_kk; n++) {
2825 molarcharge += fabs(
charge(n)) * molality[n];
2826 molalitysum += molality[n];
2840 for (
int z1 = 1; z1 <=4; z1++) {
2841 for (
int z2 =1; z2 <=4; z2++) {
2842 calc_thetas(z1, z2, ðeta[z1][z2], ðeta_prime[z1][z2]);
2849 for (
size_t i = 1; i < (
m_kk - 1); i++) {
2850 for (
size_t j = (i+1); j <
m_kk; j++) {
2852 size_t n =
m_kk*i + j;
2858 double x1 = sqrtIs * m_Alpha1MX_ij[counterIJ];
2859 if (x1 > 1.0E-100) {
2860 m_gfunc_IJ[counterIJ] = 2.0*(1.0-(1.0 + x1) * exp(-x1)) / (x1 *x1);
2862 (1.0-(1.0 + x1 + 0.5*x1 * x1) * exp(-x1)) / (x1 * x1);
2870 if (x2 > 1.0E-100) {
2871 m_g2func_IJ[counterIJ] = 2.0*(1.0-(1.0 + x2) * exp(-x2)) / (x2 * x2);
2873 (1.0-(1.0 + x2 + 0.5 * x2 * x2) * exp(-x2)) / (x2 * x2);
2889 for (
size_t i = 1; i <
m_kk - 1; i++) {
2890 for (
size_t j = i+1; j <
m_kk; j++) {
2892 size_t n =
m_kk*i + j;
2901 if (Is > 1.0E-150) {
2917 for (
size_t i = 1; i <
m_kk-1; i++) {
2918 for (
size_t j = i+1; j <
m_kk; j++) {
2920 size_t n =
m_kk*i + j;
2935 for (
size_t i = 1; i <
m_kk-1; i++) {
2936 for (
size_t j = i+1; j <
m_kk; j++) {
2938 size_t n =
m_kk*i + j;
2957 double d2FdT2 = -d2AphidT2 * (sqrt(Is) / (1.0 + 1.2*sqrt(Is))
2958 + (2.0/1.2) * log(1.0+1.2*(sqrtIs)));
2959 for (
size_t i = 1; i <
m_kk-1; i++) {
2960 for (
size_t j = i+1; j <
m_kk; j++) {
2962 size_t n =
m_kk*i + j;
2974 d2FdT2 += molality[i]*molality[j] *
m_Phiprime_IJ[counterIJ];
2979 for (
size_t i = 1; i <
m_kk; i++) {
2989 for (
size_t j = 1; j <
m_kk; j++) {
2991 size_t n =
m_kk*i + j;
2996 sum1 += molality[j]*
3002 for (
size_t k = j+1; k <
m_kk; k++) {
3017 for (
size_t k = 1; k <
m_kk; k++) {
3026 sum4 += fabs(
charge(i)) *
3036 for (
size_t k = 1; k <
m_kk; k++) {
3042 if (zeta_LL != 0.0) {
3043 sum5 += molality[j]*molality[k]*zeta_LL;
3052 zsqd2FdT2 + sum1 + sum2 + sum3 + sum4 + sum5;
3064 for (
size_t j = 1; j <
m_kk; j++) {
3066 size_t n =
m_kk*i + j;
3071 sum1 += molality[j]*
3074 for (
size_t k = j+1; k <
m_kk; k++) {
3090 for (
size_t k = 1; k <
m_kk; k++) {
3098 sum4 += fabs(
charge(i)) *
3108 for (
size_t k = 1; k <
m_kk; k++) {
3115 if (zeta_LL != 0.0) {
3116 sum5 += molality[j]*molality[k]*zeta_LL;
3123 zsqd2FdT2 + sum1 + sum2 + sum3 + sum4 + sum5;
3132 for (
size_t j = 1; j <
m_kk; j++) {
3136 for (
size_t k = 1; k <
m_kk; k++) {
3144 double sum2 = 3.0 * molality[i] * molality[i] *
m_Mu_nnn_LL[i];
3163 double term1 = -d2AphidT2 * Is * sqrt(Is) / (1.0 + 1.2 * sqrt(Is));
3165 for (
size_t j = 1; j <
m_kk; j++) {
3168 for (
size_t k = 1; k <
m_kk; k++) {
3171 size_t n =
m_kk*j + k;
3174 sum1 += molality[j]*molality[k] *
3179 for (
size_t k = j+1; k <
m_kk; k++) {
3180 if (j == (
m_kk-1)) {
3182 throw CanteraError(
"HMWSoln::s_updatePitzer_d2lnMolalityActCoeff_dT2",
3183 "logic error 1 in Step 9 of hmw_act");
3188 size_t n =
m_kk*j + k;
3191 for (
size_t m = 1; m <
m_kk; m++) {
3195 sum2 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk_LL[n];
3204 for (
size_t k = j+1; k <
m_kk; k++) {
3207 throw CanteraError(
"HMWSoln::s_updatePitzer_d2lnMolalityActCoeff_dT2",
3208 "logic error 2 in Step 9 of hmw_act");
3213 size_t n =
m_kk*j + k;
3217 for (
size_t m = 1; m <
m_kk; m++) {
3220 sum3 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk_LL[n];
3229 for (
size_t k = 1; k <
m_kk; k++) {
3239 }
else if (k == j) {
3245 for (
size_t m = 1; m <
m_kk; m++) {
3250 if (zeta_LL != 0.0) {
3251 sum7 += molality[izeta]*molality[jzeta]*molality[k]*zeta_LL;
3258 sum7 += molality[j] * molality[j] * molality[j] *
m_Mu_nnn_LL[j];
3261 double sum_m_phi_minus_1 = 2.0 *
3262 (term1 + sum1 + sum2 + sum3 + sum4 + sum5 + sum6 + sum7);
3265 double d2_osmotic_coef_dT2;
3266 if (molalitysum > 1.0E-150) {
3267 d2_osmotic_coef_dT2 = 0.0 + (sum_m_phi_minus_1 / molalitysum);
3269 d2_osmotic_coef_dT2 = 0.0;
3271 double d2_lnwateract_dT2 = -(
m_weightSolvent/1000.0) * molalitysum * d2_osmotic_coef_dT2;
3293 for (
size_t k = 1; k <
m_kk; k++) {
3311 double etheta[5][5], etheta_prime[5][5], sqrtIs;
3318 double molarcharge = 0.0;
3322 double molalitysum = 0.0;
3330 for (
size_t n = 1; n <
m_kk; n++) {
3334 molarcharge += fabs(
charge(n)) * molality[n];
3335 molalitysum += molality[n];
3349 for (
int z1 = 1; z1 <=4; z1++) {
3350 for (
int z2 =1; z2 <=4; z2++) {
3351 calc_thetas(z1, z2, ðeta[z1][z2], ðeta_prime[z1][z2]);
3358 for (
size_t i = 1; i < (
m_kk - 1); i++) {
3359 for (
size_t j = (i+1); j <
m_kk; j++) {
3361 size_t n =
m_kk*i + j;
3367 double x1 = sqrtIs * m_Alpha1MX_ij[counterIJ];
3368 if (x1 > 1.0E-100) {
3369 m_gfunc_IJ[counterIJ] = 2.0*(1.0-(1.0 + x1) * exp(-x1)) / (x1 * x1);
3371 (1.0-(1.0 + x1 + 0.5 * x1 * x1) * exp(-x1)) / (x1 * x1);
3379 if (x2 > 1.0E-100) {
3380 m_g2func_IJ[counterIJ] = 2.0*(1.0-(1.0 + x2) * exp(-x2)) / (x2 * x2);
3382 (1.0-(1.0 + x2 + 0.5 * x2 * x2) * exp(-x2)) / (x2 * x2);
3398 for (
size_t i = 1; i <
m_kk - 1; i++) {
3399 for (
size_t j = i+1; j <
m_kk; j++) {
3401 size_t n =
m_kk*i + j;
3410 if (Is > 1.0E-150) {
3426 for (
size_t i = 1; i <
m_kk-1; i++) {
3427 for (
size_t j = i+1; j <
m_kk; j++) {
3429 size_t n =
m_kk*i + j;
3444 for (
size_t i = 1; i <
m_kk-1; i++) {
3445 for (
size_t j = i+1; j <
m_kk; j++) {
3447 size_t n =
m_kk*i + j;
3466 double dAphidP = dA_DebyedP /3.0;
3467 double dFdP = -dAphidP * (sqrt(Is) / (1.0 + 1.2*sqrt(Is))
3468 + (2.0/1.2) * log(1.0+1.2*(sqrtIs)));
3469 for (
size_t i = 1; i <
m_kk-1; i++) {
3470 for (
size_t j = i+1; j <
m_kk; j++) {
3472 size_t n =
m_kk*i + j;
3489 for (
size_t i = 1; i <
m_kk; i++) {
3499 for (
size_t j = 1; j <
m_kk; j++) {
3501 size_t n =
m_kk*i + j;
3506 sum1 += molality[j]*
3512 for (
size_t k = j+1; k <
m_kk; k++) {
3525 sum2 += molality[j]*(2.0*
m_Phi_IJ_P[counterIJ]);
3527 for (
size_t k = 1; k <
m_kk; k++) {
3536 sum4 += fabs(
charge(i)) *
3537 molality[j]*molality[k]*
m_CMX_IJ_P[counterIJ2];
3546 for (
size_t k = 1; k <
m_kk; k++) {
3552 if (zeta_P != 0.0) {
3553 sum5 += molality[j]*molality[k]*zeta_P;
3563 zsqdFdP + sum1 + sum2 + sum3 + sum4 + sum5;
3575 for (
size_t j = 1; j <
m_kk; j++) {
3577 size_t n =
m_kk*i + j;
3582 sum1 += molality[j] *
3585 for (
size_t k = j+1; k <
m_kk; k++) {
3599 sum2 += molality[j]*(2.0*
m_Phi_IJ_P[counterIJ]);
3601 for (
size_t k = 1; k <
m_kk; k++) {
3610 molality[j]*molality[k]*
m_CMX_IJ_P[counterIJ2];
3619 for (
size_t k = 1; k <
m_kk; k++) {
3626 if (zeta_P != 0.0) {
3627 sum5 += molality[j]*molality[k]*zeta_P;
3634 zsqdFdP + sum1 + sum2 + sum3 + sum4 + sum5;
3641 for (
size_t j = 1; j <
m_kk; j++) {
3645 for (
size_t k = 1; k <
m_kk; k++) {
3653 double sum2 = 3.0 * molality[i] * molality[i] *
m_Mu_nnn_P[i];
3672 double term1 = -dAphidP * Is * sqrt(Is) / (1.0 + 1.2 * sqrt(Is));
3674 for (
size_t j = 1; j <
m_kk; j++) {
3677 for (
size_t k = 1; k <
m_kk; k++) {
3680 size_t n =
m_kk*j + k;
3682 sum1 += molality[j]*molality[k]*
3687 for (
size_t k = j+1; k <
m_kk; k++) {
3688 if (j == (
m_kk-1)) {
3690 throw CanteraError(
"HMWSoln::s_updatePitzer_dlnMolalityActCoeff_dP",
3691 "logic error 1 in Step 9 of hmw_act");
3696 size_t n =
m_kk*j + k;
3699 for (
size_t m = 1; m <
m_kk; m++) {
3703 sum2 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk_P[n];
3712 for (
size_t k = j+1; k <
m_kk; k++) {
3715 throw CanteraError(
"HMWSoln::s_updatePitzer_dlnMolalityActCoeff_dP",
3716 "logic error 2 in Step 9 of hmw_act");
3721 size_t n =
m_kk*j + k;
3725 for (
size_t m = 1; m <
m_kk; m++) {
3728 sum3 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk_P[n];
3737 for (
size_t k = 1; k <
m_kk; k++) {
3747 }
else if (k == j) {
3753 for (
size_t m = 1; m <
m_kk; m++) {
3758 if (zeta_P != 0.0) {
3759 sum7 += molality[izeta]*molality[jzeta]*molality[k]*zeta_P;
3766 sum7 += molality[j] * molality[j] * molality[j] *
m_Mu_nnn_P[j];
3769 double sum_m_phi_minus_1 = 2.0 *
3770 (term1 + sum1 + sum2 + sum3 + sum4 + sum5 + sum6 + sum7);
3774 double d_osmotic_coef_dP;
3775 if (molalitysum > 1.0E-150) {
3776 d_osmotic_coef_dP = 0.0 + (sum_m_phi_minus_1 / molalitysum);
3778 d_osmotic_coef_dP = 0.0;
3780 double d_lnwateract_dP = -(
m_weightSolvent/1000.0) * molalitysum * d_osmotic_coef_dP;
3793 if( m_last_is == is ) {
3800 double c1 = 4.581, c2 = 0.7237, c3 = 0.0120, c4 = 0.528;
3801 double aphi = 0.392;
3802 if (is < 1.0E-150) {
3803 for (
int i = 0; i < 17; i++) {
3812 for (
int i=1; i<=4; i++) {
3813 for (
int j=i; j<=4; j++) {
3817 double zprod = (double)ij;
3820 double x = 6.0* zprod * aphi * sqrt(is);
3822 double jfunc = x / (4.0 + c1*pow(x,-c2)*exp(-c3*pow(x,c4)));
3824 double t = c3 * c4 * pow(x,c4);
3825 double dj = c1* pow(x,(-c2-1.0)) * (c2+t) * exp(-c3*pow(x,c4));
3826 double jprime = (jfunc/x)*(1.0 + jfunc*dj);
3828 elambda[ij] = zprod*jfunc / (4.0*is);
3829 elambda1[ij] = (3.0*zprod*zprod*aphi*jprime/(4.0*sqrt(is))
3836 double* etheta,
double* etheta_prime)
const
3843 "we shouldn't be here");
3845 "called with one species being neutral");
3851 *etheta_prime = 0.0;
3854 double f1 = (double)i / (2.0 * j);
3855 double f2 = (double)j / (2.0 * i);
3870 for (
size_t k = 1; k <
m_kk; k++) {
3877 double eterm = std::exp(-xoverc);
3879 double fptmp = IMS_bfCut_ - IMS_afCut_ /
IMS_cCut_ - IMS_bfCut_*xoverc
3880 + 2.0*IMS_dfCut_*xmolSolvent - IMS_dfCut_*xmolSolvent*xoverc;
3881 double f_prime = 1.0 + eterm*fptmp;
3882 double f = xmolSolvent + IMS_efCut_
3883 + eterm * (IMS_afCut_ + xmolSolvent * (IMS_bfCut_ + IMS_dfCut_*xmolSolvent));
3885 double gptmp = IMS_bgCut_ - IMS_agCut_ /
IMS_cCut_ - IMS_bgCut_*xoverc
3886 + 2.0*IMS_dgCut_*xmolSolvent - IMS_dgCut_*xmolSolvent*xoverc;
3887 double g_prime = 1.0 + eterm*gptmp;
3888 double g = xmolSolvent + IMS_egCut_
3889 + eterm * (IMS_agCut_ + xmolSolvent * (IMS_bgCut_ + IMS_dgCut_*xmolSolvent));
3891 double tmp = (xmolSolvent / g * g_prime + (1.0 - xmolSolvent) / f * f_prime);
3892 double lngammak = -1.0 - log(f) + tmp * xmolSolvent;
3893 double lngammao =-log(g) - tmp * (1.0-xmolSolvent);
3895 tmp = log(xx) + lngammak;
3896 for (
size_t k = 1; k <
m_kk; k++) {
3907 vector<double>& moleF =
m_workS;
3913 writelog(
"Index Name MoleF MolalityCropped Charge\n");
3914 for (
size_t k = 0; k <
m_kk; k++) {
3915 writelogf(
"%2d %-16s %14.7le %14.7le %5.1f \n",
3919 writelog(
"\n Species Species beta0MX "
3920 "beta1MX beta2MX CphiMX alphaMX thetaij\n");
3921 for (
size_t i = 1; i <
m_kk - 1; i++) {
3922 for (
size_t j = i+1; j <
m_kk; j++) {
3923 size_t n = i *
m_kk + j;
3925 writelogf(
" %-16s %-16s %9.5f %9.5f %9.5f %9.5f %9.5f %9.5f \n",
3933 writelog(
"\n Species Species Species psi \n");
3934 for (
size_t i = 1; i <
m_kk; i++) {
3935 for (
size_t j = 1; j <
m_kk; j++) {
3936 for (
size_t k = 1; k <
m_kk; k++) {
3939 writelogf(
" %-16s %-16s %-16s %9.5f \n",
3956 double afac = -1.0 *(lnGammaClMs2 - lnGammaCLMs1);
3957 for (
size_t k = 0; k <
m_kk; k++) {
3958 acMolality[k] *= exp(
charge(k) * afac);
3971 double afac = -1.0 *(lnGammaClMs2 - lnGammaCLMs1);
3972 for (
size_t k = 0; k <
m_kk; k++) {
3986 double afac = -1.0 *(dlnGammaClM_dT_s2 - dlnGammaCLM_dT_s1);
3987 for (
size_t k = 0; k <
m_kk; k++) {
4001 double afac = -1.0 *(d2lnGammaClM_dT2_s2 - d2lnGammaCLM_dT2_s1);
4002 for (
size_t k = 0; k <
m_kk; k++) {
4016 double afac = -1.0 *(dlnGammaClM_dP_s2 - dlnGammaCLM_dP_s1);
4017 for (
size_t k = 0; k <
m_kk; k++) {
4026 double lnGammaClMs2 = - A * sqrtIs /(1.0 + 1.5 * sqrtIs);
4027 return lnGammaClMs2;
4034 return - dAdT * sqrtIs /(1.0 + 1.5 * sqrtIs);
4041 return - d2AdT2 * sqrtIs /(1.0 + 1.5 * sqrtIs);
4048 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.
double * ptrColumn(size_t j)
Return a pointer to the top of column j, columns are contiguous in memory.
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.
void applyphScale(double *acMolality) const override
Apply the current phScale to a set of activity Coefficients or activities.
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.
void getPartialMolarEnthalpies(double *hbar) const override
Returns an array of partial molar enthalpies for the species in the mixture.
vector< double > m_Beta0MX_ij
Array of 2D data used in the Pitzer/HMW formulation.
void getChemPotentials(double *mu) const override
Get the species chemical potentials. Units: J/kmol.
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 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.
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.
void getActivityConcentrations(double *c) const override
This method returns an array of generalized activity concentrations.
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...
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.
void getPartialMolarVolumes(double *vbar) const override
Return an array of partial molar volumes for the species in the mixture.
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. Units: 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 getUnscaledMolalityActivityCoefficients(double *acMolality) const override
Get the array of unscaled non-dimensional molality based activity coefficients at the current solutio...
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.
void calc_thetas(int z1, int z2, double *etheta, double *etheta_prime) const
Calculate etheta and etheta_prime.
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.
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.
void getActivities(double *ac) const override
Get the array of non-dimensional activities at the current solution temperature, pressure,...
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.
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.
void getPartialMolarCp(double *cpbar) const override
Return an array of partial molar heat capacities for the species in the mixture.
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.
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.
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.
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.
void getPartialMolarEntropies(double *sbar) const override
Returns an array of partial molar entropies of the species in the solution.
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.
virtual void setMoleFractions(const double *const x)
Set the mole fractions to the specified values.
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.
double temperature() const
Temperature (K).
string speciesName(size_t k) const
Name of the species with index k.
void getMoleFractions(double *const x) const
Get the species mole fraction vector.
size_t speciesIndex(const string &name) const
Returns the index of a species named 'name' within the Phase object.
double moleFraction(size_t k) const
Return the mole fraction of a single species.
int stateMFNumber() const
Return the State Mole Fraction Number.
double mean_X(const double *const Q) const
Evaluate the mole-fraction-weighted mean of an array Q.
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. Units: 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.
double pressure() const override
Returns the current pressure of the phase.
void getEntropy_R(double *sr) const override
Get the array of nondimensional Entropy functions for the standard state species at the current T and...
void getStandardChemPotentials(double *mu) const override
Get the array of chemical potentials at unit activity for the species at their standard states at the...
void getCp_R(double *cpr) const override
Get the nondimensional Heat Capacities at constant pressure for the species standard states at the cu...
void getEnthalpy_RT(double *hrt) const override
Get the nondimensional Enthalpy functions for the species at their standard states at the current T a...
void getStandardVolumes(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 ...
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.