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)
323 throw CanteraError(
"HMWSoln::setBinarySalt",
"Species '{}' not found", sp1);
324 }
else if (k2 ==
npos) {
325 throw CanteraError(
"HMWSoln::setBinarySalt",
"Species '{}' not found", sp2);
330 throw CanteraError(
"HMWSoln::setBinarySalt",
"Species '{}' and '{}' "
331 "do not have opposite charges ({}, {})", sp1, sp2,
341 for (
size_t n = 0; n < nParams; n++) {
347 m_Alpha1MX_ij[c] = alpha1;
351void HMWSoln::setTheta(
const string& sp1,
const string& sp2,
352 size_t nParams,
double* theta)
357 throw CanteraError(
"HMWSoln::setTheta",
"Species '{}' not found", sp1);
358 }
else if (k2 ==
npos) {
359 throw CanteraError(
"HMWSoln::setTheta",
"Species '{}' not found", sp2);
362 throw CanteraError(
"HMWSoln::setTheta",
"Species '{}' and '{}' "
363 "should both have the same (non-zero) charge ({}, {})", sp1, sp2,
369 for (
size_t n = 0; n < nParams; n++) {
374void HMWSoln::setPsi(
const string& sp1,
const string& sp2,
375 const string& sp3,
size_t nParams,
double* psi)
381 throw CanteraError(
"HMWSoln::setPsi",
"Species '{}' not found", sp1);
382 }
else if (k2 ==
npos) {
383 throw CanteraError(
"HMWSoln::setPsi",
"Species '{}' not found", sp2);
384 }
else if (k3 ==
npos) {
385 throw CanteraError(
"HMWSoln::setPsi",
"Species '{}' not found", sp3);
390 throw CanteraError(
"HMWSoln::setPsi",
"All species must be ions and"
391 " must include at least one cation and one anion, but given species"
392 " (charges) were: {} ({}), {} ({}), and {} ({}).",
403 for (
size_t n = 0; n < nParams; n++) {
410void HMWSoln::setLambda(
const string& sp1,
const string& sp2,
411 size_t nParams,
double* lambda)
416 throw CanteraError(
"HMWSoln::setLambda",
"Species '{}' not found", sp1);
417 }
else if (k2 ==
npos) {
418 throw CanteraError(
"HMWSoln::setLambda",
"Species '{}' not found", sp2);
422 throw CanteraError(
"HMWSoln::setLambda",
"Expected at least one neutral"
423 " species, but given species (charges) were: {} ({}) and {} ({}).",
430 size_t c = k1*
m_kk + k2;
431 for (
size_t n = 0; n < nParams; n++) {
437void HMWSoln::setMunnn(
const string& sp,
size_t nParams,
double* munnn)
441 throw CanteraError(
"HMWSoln::setMunnn",
"Species '{}' not found", sp);
445 throw CanteraError(
"HMWSoln::setMunnn",
"Expected a neutral species,"
446 " got {} ({}).", sp,
charge(k));
449 for (
size_t n = 0; n < nParams; n++) {
455void HMWSoln::setZeta(
const string& sp1,
const string& sp2,
456 const string& sp3,
size_t nParams,
double* psi)
462 throw CanteraError(
"HMWSoln::setZeta",
"Species '{}' not found", sp1);
463 }
else if (k2 ==
npos) {
464 throw CanteraError(
"HMWSoln::setZeta",
"Species '{}' not found", sp2);
465 }
else if (k3 ==
npos) {
466 throw CanteraError(
"HMWSoln::setZeta",
"Species '{}' not found", sp3);
471 throw CanteraError(
"HMWSoln::setZeta",
"Requires one neutral species, "
472 "one cation, and one anion, but given species (charges) were: "
473 "{} ({}), {} ({}), and {} ({}).",
480 }
else if (
charge(k3) == 0) {
492 for (
size_t n = 0; n < nParams; n++) {
498void HMWSoln::setPitzerTempModel(
const string& model)
507 throw CanteraError(
"HMWSoln::setPitzerTempModel",
508 "Unknown Pitzer ActivityCoeff Temp model: {}", model);
522void HMWSoln::setCroppingCoefficients(
double ln_gamma_k_min,
523 double ln_gamma_k_max,
double ln_gamma_o_min,
double ln_gamma_o_max)
525 CROP_ln_gamma_k_min = ln_gamma_k_min;
526 CROP_ln_gamma_k_max = ln_gamma_k_max;
527 CROP_ln_gamma_o_min = ln_gamma_o_min;
528 CROP_ln_gamma_o_max = ln_gamma_o_max;
531vector<double> getSizedVector(
const AnyMap& item,
const string& key,
size_t nCoeffs)
534 if (item[key].is<double>()) {
537 v.push_back(item[key].asDouble());
539 v = item[key].asVector<
double>(1, nCoeffs);
541 if (v.size() == 1 && nCoeffs == 5) {
554 setPitzerTempModel(actData[
"temperature-model"].asString());
562 if (actData.hasKey(
"A_Debye")) {
563 if (actData[
"A_Debye"] ==
"variable") {
566 setA_Debye(actData.convert(
"A_Debye",
"kg^0.5/gmol^0.5"));
569 if (actData.hasKey(
"max-ionic-strength")) {
570 setMaxIonicStrength(actData[
"max-ionic-strength"].asDouble());
572 if (actData.hasKey(
"interactions")) {
573 for (
auto& item : actData[
"interactions"].asVector<
AnyMap>()) {
574 auto&
species = item[
"species"].asVector<
string>(1, 3);
579 if (nsp == 2 && q0 * q1 < 0) {
581 vector<double> beta0 = getSizedVector(item,
"beta0", nCoeffs);
582 vector<double> beta1 = getSizedVector(item,
"beta1", nCoeffs);
583 vector<double> beta2 = getSizedVector(item,
"beta2", nCoeffs);
584 vector<double> Cphi = getSizedVector(item,
"Cphi", nCoeffs);
585 if (beta0.size() != beta1.size() || beta0.size() != beta2.size()
586 || beta0.size() != Cphi.size()) {
588 "Inconsistent binary salt array sizes ({}, {}, {}, {})",
589 beta0.size(), beta1.size(), beta2.size(), Cphi.size());
591 double alpha1 = item[
"alpha1"].asDouble();
592 double alpha2 = item.getDouble(
"alpha2", 0.0);
594 beta0.data(), beta1.data(), beta2.data(), Cphi.data(),
596 }
else if (nsp == 2 && q0 * q1 > 0) {
598 vector<double> theta = getSizedVector(item,
"theta", nCoeffs);
600 }
else if (nsp == 2 && q0 * q1 == 0) {
602 vector<double> lambda = getSizedVector(item,
"lambda", nCoeffs);
604 }
else if (nsp == 3 && q0 * q1 * q2 != 0) {
606 vector<double> psi = getSizedVector(item,
"psi", nCoeffs);
608 psi.size(), psi.data());
609 }
else if (nsp == 3 && q0 * q1 * q2 == 0) {
611 vector<double> zeta = getSizedVector(item,
"zeta", nCoeffs);
613 zeta.size(), zeta.data());
614 }
else if (nsp == 1) {
616 vector<double> mu = getSizedVector(item,
"mu", nCoeffs);
617 setMunnn(
species[0], mu.size(), mu.data());
621 if (actData.hasKey(
"cropping-coefficients")) {
622 auto& crop = actData[
"cropping-coefficients"].as<
AnyMap>();
623 setCroppingCoefficients(
624 crop.getDouble(
"ln_gamma_k_min", crop_ln_gamma_k_min_default),
625 crop.getDouble(
"ln_gamma_k_max", crop_ln_gamma_k_max_default),
626 crop.getDouble(
"ln_gamma_o_min", crop_ln_gamma_o_min_default),
627 crop.getDouble(
"ln_gamma_o_max", crop_ln_gamma_o_max_default));
633 for (
int i = 0; i < 17; i++) {
647 vector<double> mf(
m_kk, 0.0);
655 for (
size_t k = 0; k <
m_kk; k++) {
657 if (fabs(mf[k] *
charge(k)) > MaxC) {
664 if (fabs(sum) > 1.0E-30) {
666 if (mf[kHp] > sum * 1.1) {
680 if (mf[kOHm] > -sum * 1.1) {
692 if (notDone && kMaxC !=
npos) {
693 if (mf[kMaxC] > (1.1 * sum /
charge(kMaxC))) {
694 mf[kMaxC] -= sum /
charge(kMaxC);
695 mf[0] += sum /
charge(kMaxC);
714void assignTrimmed(
AnyMap& interaction,
const string& key, vector<double>& values) {
715 while (values.size() > 1 && values.back() == 0) {
718 if (values.size() == 1) {
719 interaction[key] = values[0];
721 interaction[key] = values;
731 activityNode[
"temperature-model"] =
"linear";
734 activityNode[
"temperature-model"] =
"complex";
739 activityNode[
"A_Debye"] =
"variable";
740 }
else if (
m_A_Debye != A_Debye_default) {
741 activityNode[
"A_Debye"].setQuantity(
m_A_Debye,
"kg^0.5/gmol^0.5");
747 vector<AnyMap> interactions;
750 for (
size_t i = 1; i <
m_kk; i++) {
751 for (
size_t j = 1; j <
m_kk; j++) {
752 size_t c = i*
m_kk + j;
754 bool lambda_found =
false;
755 for (
size_t n = 0; n < nParams; n++) {
763 interaction[
"species"] = vector<string>{
765 vector<double> lambda(nParams);
766 for (
size_t n = 0; n < nParams; n++) {
769 assignTrimmed(interaction,
"lambda", lambda);
770 interactions.push_back(std::move(interaction));
775 if (c == 0 || i > j) {
780 bool salt_found =
false;
781 for (
size_t n = 0; n < nParams; n++) {
791 interaction[
"species"] = vector<string>{
793 vector<double> beta0(nParams), beta1(nParams), beta2(nParams), Cphi(nParams);
794 size_t last_nonzero = 0;
795 for (
size_t n = 0; n < nParams; n++) {
800 if (beta0[n] || beta1[n] || beta2[n] || Cphi[n]) {
804 if (last_nonzero == 0) {
805 interaction[
"beta0"] = beta0[0];
806 interaction[
"beta1"] = beta1[0];
807 interaction[
"beta2"] = beta2[0];
808 interaction[
"Cphi"] = Cphi[0];
810 beta0.resize(1 + last_nonzero);
811 beta1.resize(1 + last_nonzero);
812 beta2.resize(1 + last_nonzero);
813 Cphi.resize(1 + last_nonzero);
814 interaction[
"beta0"] = beta0;
815 interaction[
"beta1"] = beta1;
816 interaction[
"beta2"] = beta2;
817 interaction[
"Cphi"] = Cphi;
819 interaction[
"alpha1"] = m_Alpha1MX_ij[c];
823 interactions.push_back(std::move(interaction));
828 bool theta_found =
false;
829 for (
size_t n = 0; n < nParams; n++) {
837 interaction[
"species"] = vector<string>{
839 vector<double> theta(nParams);
840 for (
size_t n = 0; n < nParams; n++) {
843 assignTrimmed(interaction,
"theta", theta);
844 interactions.push_back(std::move(interaction));
853 for (
size_t i = 1; i <
m_kk; i++) {
857 for (
size_t j = i + 1; j <
m_kk; j++) {
861 for (
size_t k = j + 1; k <
m_kk; k++) {
866 for (
size_t n = 0; n < nParams; n++) {
869 interaction[
"species"] = vector<string>{
871 vector<double> psi(nParams);
872 for (
size_t m = 0; m < nParams; m++) {
875 assignTrimmed(interaction,
"psi", psi);
876 interactions.push_back(std::move(interaction));
885 for (
size_t i = 1; i <
m_kk; i++) {
889 for (
size_t j = 1; j <
m_kk; j++) {
893 for (
size_t k = 1; k <
m_kk; k++) {
898 for (
size_t n = 0; n < nParams; n++) {
901 interaction[
"species"] = vector<string>{
903 vector<double> zeta(nParams);
904 for (
size_t m = 0; m < nParams; m++) {
907 assignTrimmed(interaction,
"zeta", zeta);
908 interactions.push_back(std::move(interaction));
917 for (
size_t i = 1; i <
m_kk; i++) {
918 for (
size_t n = 0; n < nParams; n++) {
921 interaction[
"species"] = vector<string>{
speciesName(i)};
922 vector<double> mu(nParams);
923 for (
size_t m = 0; m < nParams; m++) {
926 assignTrimmed(interaction,
"mu", mu);
927 interactions.push_back(std::move(interaction));
933 activityNode[
"interactions"] = std::move(interactions);
936 if (CROP_ln_gamma_k_min != crop_ln_gamma_k_min_default) {
937 croppingCoeffs[
"ln_gamma_k_min"] = CROP_ln_gamma_k_min;
939 if (CROP_ln_gamma_k_max != crop_ln_gamma_k_max_default) {
940 croppingCoeffs[
"ln_gamma_k_max"] = CROP_ln_gamma_k_max;
942 if (CROP_ln_gamma_o_min != crop_ln_gamma_o_min_default) {
943 croppingCoeffs[
"ln_gamma_o_min"] = CROP_ln_gamma_o_min;
945 if (CROP_ln_gamma_o_max != crop_ln_gamma_o_max_default) {
946 croppingCoeffs[
"ln_gamma_o_max"] = CROP_ln_gamma_o_max;
948 if (croppingCoeffs.
size()) {
949 activityNode[
"cropping-coefficients"] = std::move(croppingCoeffs);
952 phaseNode[
"activity-data"] = std::move(activityNode);
959 if (tempArg != -1.0) {
963 if (presArg != -1.0) {
982 throw CanteraError(
"HMWSoln::A_Debye_TP",
"shouldn't be here");
990 if (tempArg != -1.0) {
994 if (presArg != -1.0) {
1006 throw CanteraError(
"HMWSoln::dA_DebyedT_TP",
"shouldn't be here");
1014 if (tempArg != -1.0) {
1018 if (presArg != -1.0) {
1031 dAdP = cached.
value;
1034 cached.
value = dAdP;
1038 throw CanteraError(
"HMWSoln::dA_DebyedP_TP",
"shouldn't be here");
1046 double dAphidT = dAdT /3.0;
1048 if (tempArg != -1.0) {
1057 double dAphidP = dAdP /3.0;
1059 if (tempArg != -1.0) {
1068 if (tempArg != -1.0) {
1073 double d2Aphi = d2 / 3.0;
1074 return 2.0 * A_L / T + 4.0 *
GasConstant * T * T *d2Aphi;
1080 if (tempArg != -1.0) {
1084 if (presArg != -1.0) {
1096 throw CanteraError(
"HMWSoln::d2A_DebyedT2_TP",
"shouldn't be here");
1110 size_t maxCounterIJlen = 1 + (
m_kk-1) * (
m_kk-2) / 2;
1113 int TCoeffLength = 1;
1144 m_Alpha1MX_ij.resize(maxCounterIJlen, 2.0);
1185 m_BMX_IJ.resize(maxCounterIJlen, 0.0);
1197 m_Phi_IJ.resize(maxCounterIJlen, 0.0);
1206 m_CMX_IJ.resize(maxCounterIJlen, 0.0);
1246 double lnActCoeffMolal0 = - log(xx) + (xx - 1.0)/xx;
1247 double lnxs = log(xx);
1249 for (
size_t k = 1; k <
m_kk; k++) {
1287 for (
size_t k = 0; k <
m_kk; k++) {
1293 if (cropMethod == 0) {
1300 for (
size_t i = 1; i < (
m_kk - 1); i++) {
1301 double charge_i =
charge(i);
1302 double abs_charge_i = fabs(charge_i);
1303 if (charge_i == 0.0) {
1306 for (
size_t j = (i+1); j <
m_kk; j++) {
1307 double charge_j =
charge(j);
1308 double abs_charge_j = fabs(charge_j);
1311 if (charge_i * charge_j < 0) {
1316 if (Imax > Iac_max) {
1320 if (Imax > Iac_max) {
1325 if (Imax > Iac_max) {
1329 if (Imax > Iac_max) {
1339 for (
int times = 0; times< 10; times++) {
1340 double anion_charge = 0.0;
1341 double cation_charge = 0.0;
1342 size_t anion_contrib_max_i =
npos;
1343 double anion_contrib_max = -1.0;
1344 size_t cation_contrib_max_i =
npos;
1345 double cation_contrib_max = -1.0;
1346 for (
size_t i = 0; i <
m_kk; i++) {
1347 double charge_i =
charge(i);
1348 if (charge_i < 0.0) {
1350 anion_charge += anion_contrib;
1351 if (anion_contrib > anion_contrib_max) {
1352 anion_contrib_max = anion_contrib;
1353 anion_contrib_max_i = i;
1355 }
else if (charge_i > 0.0) {
1357 cation_charge += cation_contrib;
1358 if (cation_contrib > cation_contrib_max) {
1359 cation_contrib_max = cation_contrib;
1360 cation_contrib_max_i = i;
1364 double total_charge = cation_charge - anion_charge;
1365 if (total_charge > 1.0E-8) {
1366 double desiredCrop = total_charge/
charge(cation_contrib_max_i);
1368 if (desiredCrop < maxCrop) {
1374 }
else if (total_charge < -1.0E-8) {
1375 double desiredCrop = total_charge/
charge(anion_contrib_max_i);
1377 if (desiredCrop < maxCrop) {
1389 if (cropMethod == 1) {
1392 double xmolSolvent = molF[0];
1398 double poly = MC_apCut_ + MC_bpCut_ * xmolSolvent + MC_dpCut_* xmolSolvent * xmolSolvent;
1399 double p = xmolSolvent + MC_epCut_ + exp(- xmolSolvent/ MC_cpCut_) * poly;
1401 for (
size_t k = 0; k <
m_kk; k++) {
1409 for (
size_t k = 0; k <
m_kk; k++) {
1414 for (
size_t k = 0; k <
m_kk; k++) {
1427 for (
size_t i = 0; i <
m_kk; i++) {
1429 size_t nc =
m_kk * i;
1433 for (
size_t i = 1; i < (
m_kk - 1); i++) {
1434 size_t n =
m_kk * i + i;
1436 for (
size_t j = (i+1); j <
m_kk; j++) {
1438 size_t nc =
m_kk * i + j;
1448 double IMS_gamma_o_min_ = 1.0E-5;
1449 double IMS_gamma_k_min_ = 10.0;
1450 double IMS_slopefCut_ = 0.6;
1452 IMS_afCut_ = 1.0 / (std::exp(1.0) * IMS_gamma_k_min_);
1454 bool converged =
false;
1456 for (
int its = 0; its < 100 && !converged; its++) {
1458 IMS_afCut_ = 1.0 / (std::exp(1.0) * IMS_gamma_k_min_) -IMS_efCut_;
1459 IMS_bfCut_ = IMS_afCut_ /
IMS_cCut_ + IMS_slopefCut_ - 1.0;
1465 IMS_efCut_ = - eterm * tmp;
1466 if (fabs(IMS_efCut_ - oldV) < 1.0E-14) {
1472 " failed to converge on the f polynomial");
1475 double f_0 = IMS_afCut_ + IMS_efCut_;
1476 double f_prime_0 = 1.0 - IMS_afCut_ /
IMS_cCut_ + IMS_bfCut_;
1478 for (
int its = 0; its < 100 && !converged; its++) {
1480 double lng_0 = -log(IMS_gamma_o_min_) - f_prime_0 / f_0;
1481 IMS_agCut_ = exp(lng_0) - IMS_egCut_;
1488 IMS_egCut_ = - eterm * tmp;
1489 if (fabs(IMS_egCut_ - oldV) < 1.0E-14) {
1495 " failed to converge on the g polynomial");
1501 double MC_X_o_min_ = 0.35;
1503 double MC_slopepCut_ = 0.02;
1507 MC_apCut_ = MC_X_o_min_;
1509 bool converged =
false;
1512 for (
int its = 0; its < 500 && !converged; its++) {
1514 MC_apCut_ = damp *(MC_X_o_min_ - MC_epCut_) + (1-damp) * MC_apCut_;
1515 double MC_bpCutNew = MC_apCut_ / MC_cpCut_ + MC_slopepCut_ - 1.0;
1516 MC_bpCut_ = damp * MC_bpCutNew + (1-damp) * MC_bpCut_;
1517 double MC_dpCutNew = ((- MC_apCut_/MC_cpCut_ + MC_bpCut_ - MC_bpCut_ *
MC_X_o_cutoff_/MC_cpCut_)
1520 MC_dpCut_ = damp * MC_dpCutNew + (1-damp) * MC_dpCut_;
1523 MC_epCut_ = - eterm * tmp;
1524 double diff = MC_epCut_ - oldV;
1525 if (fabs(diff) < 1.0E-14) {
1531 " failed to converge on the p polynomial");
1538 const double twoT = 2.0 * T;
1539 const double invT = 1.0 / T;
1540 const double invT2 = invT * invT;
1541 const double twoinvT3 = 2.0 * invT * invT2;
1542 double tinv = 0.0, tln = 0.0, tlin = 0.0, tquad = 0.0;
1552 for (
size_t i = 1; i < (
m_kk - 1); i++) {
1553 for (
size_t j = (i+1); j <
m_kk; j++) {
1555 size_t n =
m_kk*i + j;
1565 case PITZER_TEMP_CONSTANT:
1567 case PITZER_TEMP_LINEAR:
1570 + beta0MX_coeff[1]*tlin;
1574 + beta1MX_coeff[1]*tlin;
1578 + beta2MX_coeff[1]*tlin;
1582 + CphiMX_coeff[1]*tlin;
1585 m_Theta_ij[counterIJ] = Theta_coeff[0] + Theta_coeff[1]*tlin;
1590 case PITZER_TEMP_COMPLEX1:
1592 + beta0MX_coeff[1]*tlin
1593 + beta0MX_coeff[2]*tquad
1594 + beta0MX_coeff[3]*tinv
1595 + beta0MX_coeff[4]*tln;
1597 + beta1MX_coeff[1]*tlin
1598 + beta1MX_coeff[2]*tquad
1599 + beta1MX_coeff[3]*tinv
1600 + beta1MX_coeff[4]*tln;
1602 + beta2MX_coeff[1]*tlin
1603 + beta2MX_coeff[2]*tquad
1604 + beta2MX_coeff[3]*tinv
1605 + beta2MX_coeff[4]*tln;
1607 + CphiMX_coeff[1]*tlin
1608 + CphiMX_coeff[2]*tquad
1609 + CphiMX_coeff[3]*tinv
1610 + CphiMX_coeff[4]*tln;
1612 + Theta_coeff[1]*tlin
1613 + Theta_coeff[2]*tquad
1614 + Theta_coeff[3]*tinv
1615 + Theta_coeff[4]*tln;
1617 + beta0MX_coeff[2]*twoT
1618 - beta0MX_coeff[3]*invT2
1619 + beta0MX_coeff[4]*invT;
1621 + beta1MX_coeff[2]*twoT
1622 - beta1MX_coeff[3]*invT2
1623 + beta1MX_coeff[4]*invT;
1625 + beta2MX_coeff[2]*twoT
1626 - beta2MX_coeff[3]*invT2
1627 + beta2MX_coeff[4]*invT;
1629 + CphiMX_coeff[2]*twoT
1630 - CphiMX_coeff[3]*invT2
1631 + CphiMX_coeff[4]*invT;
1633 + Theta_coeff[2]*twoT
1634 - Theta_coeff[3]*invT2
1635 + Theta_coeff[4]*invT;
1639 + beta0MX_coeff[2]*2.0
1640 + beta0MX_coeff[3]*twoinvT3
1641 - beta0MX_coeff[4]*invT2;
1643 + beta1MX_coeff[2]*2.0
1644 + beta1MX_coeff[3]*twoinvT3
1645 - beta1MX_coeff[4]*invT2;
1647 + beta2MX_coeff[2]*2.0
1648 + beta2MX_coeff[3]*twoinvT3
1649 - beta2MX_coeff[4]*invT2;
1651 + CphiMX_coeff[2]*2.0
1652 + CphiMX_coeff[3]*twoinvT3
1653 - CphiMX_coeff[4]*invT2;
1655 + Theta_coeff[2]*2.0
1656 + Theta_coeff[3]*twoinvT3
1657 - Theta_coeff[4]*invT2;
1667 for (
size_t i = 1; i <
m_kk; i++) {
1669 for (
size_t j = 1; j <
m_kk; j++) {
1670 size_t n = i *
m_kk + j;
1673 case PITZER_TEMP_CONSTANT:
1676 case PITZER_TEMP_LINEAR:
1677 m_Lambda_nj(i,j) = Lambda_coeff[0] + Lambda_coeff[1]*tlin;
1681 case PITZER_TEMP_COMPLEX1:
1683 + Lambda_coeff[1]*tlin
1684 + Lambda_coeff[2]*tquad
1685 + Lambda_coeff[3]*tinv
1686 + Lambda_coeff[4]*tln;
1689 + Lambda_coeff[2]*twoT
1690 - Lambda_coeff[3]*invT2
1691 + Lambda_coeff[4]*invT;
1695 + Lambda_coeff[3]*twoinvT3
1696 - Lambda_coeff[4]*invT2;
1702 case PITZER_TEMP_CONSTANT:
1705 case PITZER_TEMP_LINEAR:
1706 m_Mu_nnn[i] = Mu_coeff[0] + Mu_coeff[1]*tlin;
1710 case PITZER_TEMP_COMPLEX1:
1722 + Mu_coeff[3]*twoinvT3
1723 - Mu_coeff[4]*invT2;
1731 case PITZER_TEMP_CONSTANT:
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++) {
1742 case PITZER_TEMP_LINEAR:
1743 for (
size_t i = 1; i <
m_kk; i++) {
1744 for (
size_t j = 1; j <
m_kk; j++) {
1745 for (
size_t k = 1; k <
m_kk; k++) {
1748 m_Psi_ijk[n] = Psi_coeff[0] + Psi_coeff[1]*tlin;
1755 case PITZER_TEMP_COMPLEX1:
1756 for (
size_t i = 1; i <
m_kk; i++) {
1757 for (
size_t j = 1; j <
m_kk; j++) {
1758 for (
size_t k = 1; k <
m_kk; k++) {
1763 + Psi_coeff[2]*tquad
1768 - Psi_coeff[3]*invT2
1769 + Psi_coeff[4]*invT;
1772 + Psi_coeff[3]*twoinvT3
1773 - Psi_coeff[4]*invT2;
1791 double etheta[5][5], etheta_prime[5][5], sqrtIs;
1798 double molarcharge = 0.0;
1802 double molalitysumUncropped = 0.0;
1808 for (
size_t n = 1; n <
m_kk; n++) {
1812 molarcharge += fabs(
charge(n)) * molality[n];
1827 for (
int z1 = 1; z1 <=4; z1++) {
1828 for (
int z2 =1; z2 <=4; z2++) {
1829 calc_thetas(z1, z2, ðeta[z1][z2], ðeta_prime[z1][z2]);
1836 for (
size_t i = 1; i < (
m_kk - 1); i++) {
1837 for (
size_t j = (i+1); j <
m_kk; j++) {
1839 size_t n =
m_kk*i + j;
1845 double x1 = sqrtIs * m_Alpha1MX_ij[counterIJ];
1846 if (x1 > 1.0E-100) {
1847 m_gfunc_IJ[counterIJ] = 2.0*(1.0-(1.0 + x1) * exp(-x1)) / (x1 * x1);
1849 (1.0-(1.0 + x1 + 0.5 * x1 * x1) * exp(-x1)) / (x1 * x1);
1857 if (x2 > 1.0E-100) {
1858 m_g2func_IJ[counterIJ] = 2.0*(1.0-(1.0 + x2) * exp(-x2)) / (x2 * x2);
1860 (1.0-(1.0 + x2 + 0.5 * x2 * x2) * exp(-x2)) / (x2 * x2);
1875 for (
size_t i = 1; i <
m_kk - 1; i++) {
1876 for (
size_t j = i+1; j <
m_kk; j++) {
1878 size_t n =
m_kk*i + j;
1888 if (Is > 1.0E-150) {
1905 for (
size_t i = 1; i <
m_kk-1; i++) {
1906 for (
size_t j = i+1; j <
m_kk; j++) {
1908 size_t n =
m_kk*i + j;
1924 for (
size_t i = 1; i <
m_kk-1; i++) {
1925 for (
size_t j = i+1; j <
m_kk; j++) {
1927 size_t n =
m_kk*i + j;
1933 int z1 = (int) fabs(
charge(i));
1934 int z2 = (int) fabs(
charge(j));
1949 double F = -Aphi * (sqrt(Is) / (1.0 + 1.2*sqrt(Is))
1950 + (2.0/1.2) * log(1.0+1.2*(sqrtIs)));
1951 for (
size_t i = 1; i <
m_kk-1; i++) {
1952 for (
size_t j = i+1; j <
m_kk; j++) {
1954 size_t n =
m_kk*i + j;
1971 for (
size_t i = 1; i <
m_kk; i++) {
1984 for (
size_t j = 1; j <
m_kk; j++) {
1986 size_t n =
m_kk*i + j;
1991 sum1 += molality[j] *
1997 for (
size_t k = j+1; k <
m_kk; k++) {
2001 sum3 += molality[j]*molality[k]*
m_Psi_ijk[n];
2010 sum2 += molality[j]*(2.0*
m_Phi_IJ[counterIJ]);
2012 for (
size_t k = 1; k <
m_kk; k++) {
2016 sum2 += molality[j]*molality[k]*
m_Psi_ijk[n];
2021 sum4 += (fabs(
charge(i))*
2022 molality[j]*molality[k]*
m_CMX_IJ[counterIJ2]);
2032 for (
size_t k = 1; k <
m_kk; k++) {
2039 sum5 += molality[j]*molality[k]*zeta;
2063 for (
size_t j = 1; j <
m_kk; j++) {
2065 size_t n =
m_kk*i + j;
2070 sum1 += molality[j]*
2073 for (
size_t k = j+1; k <
m_kk; k++) {
2077 sum3 += molality[j]*molality[k]*
m_Psi_ijk[n];
2087 sum2 += molality[j]*(2.0*
m_Phi_IJ[counterIJ]);
2089 for (
size_t k = 1; k <
m_kk; k++) {
2093 sum2 += molality[j]*molality[k]*
m_Psi_ijk[n];
2098 molality[j]*molality[k]*
m_CMX_IJ[counterIJ2];
2107 for (
size_t k = 1; k <
m_kk; k++) {
2115 sum5 += molality[j]*molality[k]*zeta;
2131 for (
size_t j = 1; j <
m_kk; j++) {
2135 for (
size_t k = 1; k <
m_kk; k++) {
2138 sum3 += molality[j]*molality[k]*
m_Psi_ijk[n];
2143 double sum2 = 3.0 * molality[i]* molality[i] *
m_Mu_nnn[i];
2165 double term1 = -Aphi * pow(Is,1.5) / (1.0 + 1.2 * sqrt(Is));
2167 for (
size_t j = 1; j <
m_kk; j++) {
2170 for (
size_t k = 1; k <
m_kk; k++) {
2173 size_t n =
m_kk*j + k;
2176 sum1 += molality[j]*molality[k]*
2181 for (
size_t k = j+1; k <
m_kk; k++) {
2182 if (j == (
m_kk-1)) {
2184 throw CanteraError(
"HMWSoln::s_updatePitzer_lnMolalityActCoeff",
2185 "logic error 1 in Step 9 of hmw_act");
2190 size_t n =
m_kk*j + k;
2192 sum2 += molality[j]*molality[k]*
m_PhiPhi_IJ[counterIJ];
2193 for (
size_t m = 1; m <
m_kk; m++) {
2197 sum2 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk[n];
2206 for (
size_t k = j+1; k <
m_kk; k++) {
2209 throw CanteraError(
"HMWSoln::s_updatePitzer_lnMolalityActCoeff",
2210 "logic error 2 in Step 9 of hmw_act");
2215 size_t n =
m_kk*j + k;
2217 sum3 += molality[j]*molality[k]*
m_PhiPhi_IJ[counterIJ];
2218 for (
size_t m = 1; m <
m_kk; m++) {
2221 sum3 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk[n];
2230 for (
size_t k = 1; k <
m_kk; k++) {
2240 }
else if (k == j) {
2241 sum6 += 0.5 * molality[j]*molality[k]*
m_Lambda_nj(j,k);
2246 for (
size_t m = 1; m <
m_kk; m++) {
2252 sum7 += molality[izeta]*molality[jzeta]*molality[k]*zeta;
2258 sum7 += molality[j]*molality[j]*molality[j]*
m_Mu_nnn[j];
2261 double sum_m_phi_minus_1 = 2.0 *
2262 (term1 + sum1 + sum2 + sum3 + sum4 + sum5 + sum6 + sum7);
2265 double osmotic_coef;
2266 if (molalitysumUncropped > 1.0E-150) {
2267 osmotic_coef = 1.0 + (sum_m_phi_minus_1 / molalitysumUncropped);
2271 double lnwateract = -(
m_weightSolvent/1000.0) * molalitysumUncropped * osmotic_coef;
2298 for (
size_t k = 1; k <
m_kk; k++) {
2322 double etheta[5][5], etheta_prime[5][5], sqrtIs;
2329 double molarcharge = 0.0;
2333 double molalitysum = 0.0;
2339 for (
size_t n = 1; n <
m_kk; n++) {
2343 molarcharge += fabs(
charge(n)) * molality[n];
2344 molalitysum += molality[n];
2358 for (
int z1 = 1; z1 <=4; z1++) {
2359 for (
int z2 =1; z2 <=4; z2++) {
2360 calc_thetas(z1, z2, ðeta[z1][z2], ðeta_prime[z1][z2]);
2367 for (
size_t i = 1; i < (
m_kk - 1); i++) {
2368 for (
size_t j = (i+1); j <
m_kk; j++) {
2370 size_t n =
m_kk*i + j;
2376 double x1 = sqrtIs * m_Alpha1MX_ij[counterIJ];
2377 if (x1 > 1.0E-100) {
2378 m_gfunc_IJ[counterIJ] = 2.0*(1.0-(1.0 + x1) * exp(-x1)) / (x1 * x1);
2380 (1.0-(1.0 + x1 + 0.5 * x1 *x1) * exp(-x1)) / (x1 * x1);
2388 if (x2 > 1.0E-100) {
2389 m_g2func_IJ[counterIJ] = 2.0*(1.0-(1.0 + x2) * exp(-x2)) / (x2 * x2);
2391 (1.0-(1.0 + x2 + 0.5 * x2 * x2) * exp(-x2)) / (x2 * x2);
2407 for (
size_t i = 1; i <
m_kk - 1; i++) {
2408 for (
size_t j = i+1; j <
m_kk; j++) {
2410 size_t n =
m_kk*i + j;
2419 if (Is > 1.0E-150) {
2435 for (
size_t i = 1; i <
m_kk-1; i++) {
2436 for (
size_t j = i+1; j <
m_kk; j++) {
2438 size_t n =
m_kk*i + j;
2453 for (
size_t i = 1; i <
m_kk-1; i++) {
2454 for (
size_t j = i+1; j <
m_kk; j++) {
2456 size_t n =
m_kk*i + j;
2475 double dAphidT = dA_DebyedT /3.0;
2476 double dFdT = -dAphidT * (sqrt(Is) / (1.0 + 1.2*sqrt(Is))
2477 + (2.0/1.2) * log(1.0+1.2*(sqrtIs)));
2478 for (
size_t i = 1; i <
m_kk-1; i++) {
2479 for (
size_t j = i+1; j <
m_kk; j++) {
2481 size_t n =
m_kk*i + j;
2498 for (
size_t i = 1; i <
m_kk; i++) {
2508 for (
size_t j = 1; j <
m_kk; j++) {
2510 size_t n =
m_kk*i + j;
2515 sum1 += molality[j]*
2521 for (
size_t k = j+1; k <
m_kk; k++) {
2534 sum2 += molality[j]*(2.0*
m_Phi_IJ_L[counterIJ]);
2536 for (
size_t k = 1; k <
m_kk; k++) {
2546 molality[j]*molality[k]*
m_CMX_IJ_L[counterIJ2];
2557 for (
size_t k = 1; k <
m_kk; k++) {
2563 if (zeta_L != 0.0) {
2564 sum5 += molality[j]*molality[k]*zeta_L;
2573 zsqdFdT + sum1 + sum2 + sum3 + sum4 + sum5;
2586 for (
size_t j = 1; j <
m_kk; j++) {
2588 size_t n =
m_kk*i + j;
2593 sum1 += molality[j]*
2596 for (
size_t k = j+1; k <
m_kk; k++) {
2610 sum2 += molality[j]*(2.0*
m_Phi_IJ_L[counterIJ]);
2612 for (
size_t k = 1; k <
m_kk; k++) {
2620 sum4 += fabs(
charge(i)) *
2621 molality[j]*molality[k]*
m_CMX_IJ_L[counterIJ2];
2629 for (
size_t k = 1; k <
m_kk; k++) {
2636 if (zeta_L != 0.0) {
2637 sum5 += molality[j]*molality[k]*zeta_L;
2644 zsqdFdT + sum1 + sum2 + sum3 + sum4 + sum5;
2654 for (
size_t j = 1; j <
m_kk; j++) {
2658 for (
size_t k = 1; k <
m_kk; k++) {
2666 double sum2 = 3.0 * molality[i] * molality[i] *
m_Mu_nnn_L[i];
2686 double term1 = -dAphidT * Is * sqrt(Is) / (1.0 + 1.2 * sqrt(Is));
2688 for (
size_t j = 1; j <
m_kk; j++) {
2691 for (
size_t k = 1; k <
m_kk; k++) {
2694 size_t n =
m_kk*j + k;
2696 sum1 += molality[j]*molality[k]*
2701 for (
size_t k = j+1; k <
m_kk; k++) {
2702 if (j == (
m_kk-1)) {
2704 throw CanteraError(
"HMWSoln::s_updatePitzer_dlnMolalityActCoeff_dT",
2705 "logic error 1 in Step 9 of hmw_act");
2710 size_t n =
m_kk*j + k;
2713 for (
size_t m = 1; m <
m_kk; m++) {
2717 sum2 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk_L[n];
2726 for (
size_t k = j+1; k <
m_kk; k++) {
2729 throw CanteraError(
"HMWSoln::s_updatePitzer_dlnMolalityActCoeff_dT",
2730 "logic error 2 in Step 9 of hmw_act");
2735 size_t n =
m_kk*j + k;
2738 for (
size_t m = 1; m <
m_kk; m++) {
2741 sum3 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk_L[n];
2750 for (
size_t k = 1; k <
m_kk; k++) {
2760 }
else if (k == j) {
2766 for (
size_t m = 1; m <
m_kk; m++) {
2771 if (zeta_L != 0.0) {
2772 sum7 += molality[izeta]*molality[jzeta]*molality[k]*zeta_L;
2778 sum7 += molality[j]*molality[j]*molality[j]*
m_Mu_nnn_L[j];
2781 double sum_m_phi_minus_1 = 2.0 *
2782 (term1 + sum1 + sum2 + sum3 + sum4 + sum5 + sum6 + sum7);
2785 double d_osmotic_coef_dT;
2786 if (molalitysum > 1.0E-150) {
2787 d_osmotic_coef_dT = 0.0 + (sum_m_phi_minus_1 / molalitysum);
2789 d_osmotic_coef_dT = 0.0;
2792 double d_lnwateract_dT = -(
m_weightSolvent/1000.0) * molalitysum * d_osmotic_coef_dT;
2817 for (
size_t k = 1; k <
m_kk; k++) {
2836 double etheta[5][5], etheta_prime[5][5], sqrtIs;
2843 double molarcharge = 0.0;
2847 double molalitysum = 0.0;
2853 for (
size_t n = 1; n <
m_kk; n++) {
2857 molarcharge += fabs(
charge(n)) * molality[n];
2858 molalitysum += molality[n];
2872 for (
int z1 = 1; z1 <=4; z1++) {
2873 for (
int z2 =1; z2 <=4; z2++) {
2874 calc_thetas(z1, z2, ðeta[z1][z2], ðeta_prime[z1][z2]);
2881 for (
size_t i = 1; i < (
m_kk - 1); i++) {
2882 for (
size_t j = (i+1); j <
m_kk; j++) {
2884 size_t n =
m_kk*i + j;
2890 double x1 = sqrtIs * m_Alpha1MX_ij[counterIJ];
2891 if (x1 > 1.0E-100) {
2892 m_gfunc_IJ[counterIJ] = 2.0*(1.0-(1.0 + x1) * exp(-x1)) / (x1 *x1);
2894 (1.0-(1.0 + x1 + 0.5*x1 * x1) * exp(-x1)) / (x1 * x1);
2902 if (x2 > 1.0E-100) {
2903 m_g2func_IJ[counterIJ] = 2.0*(1.0-(1.0 + x2) * exp(-x2)) / (x2 * x2);
2905 (1.0-(1.0 + x2 + 0.5 * x2 * x2) * exp(-x2)) / (x2 * x2);
2921 for (
size_t i = 1; i <
m_kk - 1; i++) {
2922 for (
size_t j = i+1; j <
m_kk; j++) {
2924 size_t n =
m_kk*i + j;
2933 if (Is > 1.0E-150) {
2949 for (
size_t i = 1; i <
m_kk-1; i++) {
2950 for (
size_t j = i+1; j <
m_kk; j++) {
2952 size_t n =
m_kk*i + j;
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;
2989 double d2FdT2 = -d2AphidT2 * (sqrt(Is) / (1.0 + 1.2*sqrt(Is))
2990 + (2.0/1.2) * log(1.0+1.2*(sqrtIs)));
2991 for (
size_t i = 1; i <
m_kk-1; i++) {
2992 for (
size_t j = i+1; j <
m_kk; j++) {
2994 size_t n =
m_kk*i + j;
3006 d2FdT2 += molality[i]*molality[j] *
m_Phiprime_IJ[counterIJ];
3011 for (
size_t i = 1; i <
m_kk; i++) {
3021 for (
size_t j = 1; j <
m_kk; j++) {
3023 size_t n =
m_kk*i + j;
3028 sum1 += molality[j]*
3034 for (
size_t k = j+1; k <
m_kk; k++) {
3049 for (
size_t k = 1; k <
m_kk; k++) {
3058 sum4 += fabs(
charge(i)) *
3068 for (
size_t k = 1; k <
m_kk; k++) {
3074 if (zeta_LL != 0.0) {
3075 sum5 += molality[j]*molality[k]*zeta_LL;
3084 zsqd2FdT2 + sum1 + sum2 + sum3 + sum4 + sum5;
3096 for (
size_t j = 1; j <
m_kk; j++) {
3098 size_t n =
m_kk*i + j;
3103 sum1 += molality[j]*
3106 for (
size_t k = j+1; k <
m_kk; k++) {
3122 for (
size_t k = 1; k <
m_kk; k++) {
3130 sum4 += fabs(
charge(i)) *
3140 for (
size_t k = 1; k <
m_kk; k++) {
3147 if (zeta_LL != 0.0) {
3148 sum5 += molality[j]*molality[k]*zeta_LL;
3155 zsqd2FdT2 + sum1 + sum2 + sum3 + sum4 + sum5;
3164 for (
size_t j = 1; j <
m_kk; j++) {
3168 for (
size_t k = 1; k <
m_kk; k++) {
3176 double sum2 = 3.0 * molality[i] * molality[i] *
m_Mu_nnn_LL[i];
3195 double term1 = -d2AphidT2 * Is * sqrt(Is) / (1.0 + 1.2 * sqrt(Is));
3197 for (
size_t j = 1; j <
m_kk; j++) {
3200 for (
size_t k = 1; k <
m_kk; k++) {
3203 size_t n =
m_kk*j + k;
3206 sum1 += molality[j]*molality[k] *
3211 for (
size_t k = j+1; k <
m_kk; k++) {
3212 if (j == (
m_kk-1)) {
3214 throw CanteraError(
"HMWSoln::s_updatePitzer_d2lnMolalityActCoeff_dT2",
3215 "logic error 1 in Step 9 of hmw_act");
3220 size_t n =
m_kk*j + k;
3223 for (
size_t m = 1; m <
m_kk; m++) {
3227 sum2 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk_LL[n];
3236 for (
size_t k = j+1; k <
m_kk; k++) {
3239 throw CanteraError(
"HMWSoln::s_updatePitzer_d2lnMolalityActCoeff_dT2",
3240 "logic error 2 in Step 9 of hmw_act");
3245 size_t n =
m_kk*j + k;
3249 for (
size_t m = 1; m <
m_kk; m++) {
3252 sum3 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk_LL[n];
3261 for (
size_t k = 1; k <
m_kk; k++) {
3271 }
else if (k == j) {
3277 for (
size_t m = 1; m <
m_kk; m++) {
3282 if (zeta_LL != 0.0) {
3283 sum7 += molality[izeta]*molality[jzeta]*molality[k]*zeta_LL;
3290 sum7 += molality[j] * molality[j] * molality[j] *
m_Mu_nnn_LL[j];
3293 double sum_m_phi_minus_1 = 2.0 *
3294 (term1 + sum1 + sum2 + sum3 + sum4 + sum5 + sum6 + sum7);
3297 double d2_osmotic_coef_dT2;
3298 if (molalitysum > 1.0E-150) {
3299 d2_osmotic_coef_dT2 = 0.0 + (sum_m_phi_minus_1 / molalitysum);
3301 d2_osmotic_coef_dT2 = 0.0;
3303 double d2_lnwateract_dT2 = -(
m_weightSolvent/1000.0) * molalitysum * d2_osmotic_coef_dT2;
3325 for (
size_t k = 1; k <
m_kk; k++) {
3343 double etheta[5][5], etheta_prime[5][5], sqrtIs;
3350 double molarcharge = 0.0;
3354 double molalitysum = 0.0;
3362 for (
size_t n = 1; n <
m_kk; n++) {
3366 molarcharge += fabs(
charge(n)) * molality[n];
3367 molalitysum += molality[n];
3381 for (
int z1 = 1; z1 <=4; z1++) {
3382 for (
int z2 =1; z2 <=4; z2++) {
3383 calc_thetas(z1, z2, ðeta[z1][z2], ðeta_prime[z1][z2]);
3390 for (
size_t i = 1; i < (
m_kk - 1); i++) {
3391 for (
size_t j = (i+1); j <
m_kk; j++) {
3393 size_t n =
m_kk*i + j;
3399 double x1 = sqrtIs * m_Alpha1MX_ij[counterIJ];
3400 if (x1 > 1.0E-100) {
3401 m_gfunc_IJ[counterIJ] = 2.0*(1.0-(1.0 + x1) * exp(-x1)) / (x1 * x1);
3403 (1.0-(1.0 + x1 + 0.5 * x1 * x1) * exp(-x1)) / (x1 * x1);
3411 if (x2 > 1.0E-100) {
3412 m_g2func_IJ[counterIJ] = 2.0*(1.0-(1.0 + x2) * exp(-x2)) / (x2 * x2);
3414 (1.0-(1.0 + x2 + 0.5 * x2 * x2) * exp(-x2)) / (x2 * x2);
3430 for (
size_t i = 1; i <
m_kk - 1; i++) {
3431 for (
size_t j = i+1; j <
m_kk; j++) {
3433 size_t n =
m_kk*i + j;
3442 if (Is > 1.0E-150) {
3458 for (
size_t i = 1; i <
m_kk-1; i++) {
3459 for (
size_t j = i+1; j <
m_kk; j++) {
3461 size_t n =
m_kk*i + j;
3476 for (
size_t i = 1; i <
m_kk-1; i++) {
3477 for (
size_t j = i+1; j <
m_kk; j++) {
3479 size_t n =
m_kk*i + j;
3498 double dAphidP = dA_DebyedP /3.0;
3499 double dFdP = -dAphidP * (sqrt(Is) / (1.0 + 1.2*sqrt(Is))
3500 + (2.0/1.2) * log(1.0+1.2*(sqrtIs)));
3501 for (
size_t i = 1; i <
m_kk-1; i++) {
3502 for (
size_t j = i+1; j <
m_kk; j++) {
3504 size_t n =
m_kk*i + j;
3521 for (
size_t i = 1; i <
m_kk; i++) {
3531 for (
size_t j = 1; j <
m_kk; j++) {
3533 size_t n =
m_kk*i + j;
3538 sum1 += molality[j]*
3544 for (
size_t k = j+1; k <
m_kk; k++) {
3557 sum2 += molality[j]*(2.0*
m_Phi_IJ_P[counterIJ]);
3559 for (
size_t k = 1; k <
m_kk; k++) {
3568 sum4 += fabs(
charge(i)) *
3569 molality[j]*molality[k]*
m_CMX_IJ_P[counterIJ2];
3578 for (
size_t k = 1; k <
m_kk; k++) {
3584 if (zeta_P != 0.0) {
3585 sum5 += molality[j]*molality[k]*zeta_P;
3595 zsqdFdP + sum1 + sum2 + sum3 + sum4 + sum5;
3607 for (
size_t j = 1; j <
m_kk; j++) {
3609 size_t n =
m_kk*i + j;
3614 sum1 += molality[j] *
3617 for (
size_t k = j+1; k <
m_kk; k++) {
3631 sum2 += molality[j]*(2.0*
m_Phi_IJ_P[counterIJ]);
3633 for (
size_t k = 1; k <
m_kk; k++) {
3642 molality[j]*molality[k]*
m_CMX_IJ_P[counterIJ2];
3651 for (
size_t k = 1; k <
m_kk; k++) {
3658 if (zeta_P != 0.0) {
3659 sum5 += molality[j]*molality[k]*zeta_P;
3666 zsqdFdP + sum1 + sum2 + sum3 + sum4 + sum5;
3673 for (
size_t j = 1; j <
m_kk; j++) {
3677 for (
size_t k = 1; k <
m_kk; k++) {
3685 double sum2 = 3.0 * molality[i] * molality[i] *
m_Mu_nnn_P[i];
3704 double term1 = -dAphidP * Is * sqrt(Is) / (1.0 + 1.2 * sqrt(Is));
3706 for (
size_t j = 1; j <
m_kk; j++) {
3709 for (
size_t k = 1; k <
m_kk; k++) {
3712 size_t n =
m_kk*j + k;
3714 sum1 += molality[j]*molality[k]*
3719 for (
size_t k = j+1; k <
m_kk; k++) {
3720 if (j == (
m_kk-1)) {
3722 throw CanteraError(
"HMWSoln::s_updatePitzer_dlnMolalityActCoeff_dP",
3723 "logic error 1 in Step 9 of hmw_act");
3728 size_t n =
m_kk*j + k;
3731 for (
size_t m = 1; m <
m_kk; m++) {
3735 sum2 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk_P[n];
3744 for (
size_t k = j+1; k <
m_kk; k++) {
3747 throw CanteraError(
"HMWSoln::s_updatePitzer_dlnMolalityActCoeff_dP",
3748 "logic error 2 in Step 9 of hmw_act");
3753 size_t n =
m_kk*j + k;
3757 for (
size_t m = 1; m <
m_kk; m++) {
3760 sum3 += molality[j]*molality[k]*molality[m]*
m_Psi_ijk_P[n];
3769 for (
size_t k = 1; k <
m_kk; k++) {
3779 }
else if (k == j) {
3785 for (
size_t m = 1; m <
m_kk; m++) {
3790 if (zeta_P != 0.0) {
3791 sum7 += molality[izeta]*molality[jzeta]*molality[k]*zeta_P;
3798 sum7 += molality[j] * molality[j] * molality[j] *
m_Mu_nnn_P[j];
3801 double sum_m_phi_minus_1 = 2.0 *
3802 (term1 + sum1 + sum2 + sum3 + sum4 + sum5 + sum6 + sum7);
3806 double d_osmotic_coef_dP;
3807 if (molalitysum > 1.0E-150) {
3808 d_osmotic_coef_dP = 0.0 + (sum_m_phi_minus_1 / molalitysum);
3810 d_osmotic_coef_dP = 0.0;
3812 double d_lnwateract_dP = -(
m_weightSolvent/1000.0) * molalitysum * d_osmotic_coef_dP;
3825 if( m_last_is == is ) {
3832 double c1 = 4.581, c2 = 0.7237, c3 = 0.0120, c4 = 0.528;
3833 double aphi = 0.392;
3834 if (is < 1.0E-150) {
3835 for (
int i = 0; i < 17; i++) {
3844 for (
int i=1; i<=4; i++) {
3845 for (
int j=i; j<=4; j++) {
3849 double zprod = (double)ij;
3852 double x = 6.0* zprod * aphi * sqrt(is);
3854 double jfunc = x / (4.0 + c1*pow(x,-c2)*exp(-c3*pow(x,c4)));
3856 double t = c3 * c4 * pow(x,c4);
3857 double dj = c1* pow(x,(-c2-1.0)) * (c2+t) * exp(-c3*pow(x,c4));
3858 double jprime = (jfunc/x)*(1.0 + jfunc*dj);
3860 elambda[ij] = zprod*jfunc / (4.0*is);
3861 elambda1[ij] = (3.0*zprod*zprod*aphi*jprime/(4.0*sqrt(is))
3868 double* etheta,
double* etheta_prime)
const
3875 "we shouldn't be here");
3877 "called with one species being neutral");
3883 *etheta_prime = 0.0;
3886 double f1 = (double)i / (2.0 * j);
3887 double f2 = (double)j / (2.0 * i);
3902 for (
size_t k = 1; k <
m_kk; k++) {
3909 double eterm = std::exp(-xoverc);
3911 double fptmp = IMS_bfCut_ - IMS_afCut_ /
IMS_cCut_ - IMS_bfCut_*xoverc
3912 + 2.0*IMS_dfCut_*xmolSolvent - IMS_dfCut_*xmolSolvent*xoverc;
3913 double f_prime = 1.0 + eterm*fptmp;
3914 double f = xmolSolvent + IMS_efCut_
3915 + eterm * (IMS_afCut_ + xmolSolvent * (IMS_bfCut_ + IMS_dfCut_*xmolSolvent));
3917 double gptmp = IMS_bgCut_ - IMS_agCut_ /
IMS_cCut_ - IMS_bgCut_*xoverc
3918 + 2.0*IMS_dgCut_*xmolSolvent - IMS_dgCut_*xmolSolvent*xoverc;
3919 double g_prime = 1.0 + eterm*gptmp;
3920 double g = xmolSolvent + IMS_egCut_
3921 + eterm * (IMS_agCut_ + xmolSolvent * (IMS_bgCut_ + IMS_dgCut_*xmolSolvent));
3923 double tmp = (xmolSolvent / g * g_prime + (1.0 - xmolSolvent) / f * f_prime);
3924 double lngammak = -1.0 - log(f) + tmp * xmolSolvent;
3925 double lngammao =-log(g) - tmp * (1.0-xmolSolvent);
3927 tmp = log(xx) + lngammak;
3928 for (
size_t k = 1; k <
m_kk; k++) {
3939 vector<double>& moleF =
m_workS;
3945 writelog(
"Index Name MoleF MolalityCropped Charge\n");
3946 for (
size_t k = 0; k <
m_kk; k++) {
3947 writelogf(
"%2d %-16s %14.7le %14.7le %5.1f \n",
3951 writelog(
"\n Species Species beta0MX "
3952 "beta1MX beta2MX CphiMX alphaMX thetaij\n");
3953 for (
size_t i = 1; i <
m_kk - 1; i++) {
3954 for (
size_t j = i+1; j <
m_kk; j++) {
3955 size_t n = i *
m_kk + j;
3957 writelogf(
" %-16s %-16s %9.5f %9.5f %9.5f %9.5f %9.5f %9.5f \n",
3965 writelog(
"\n Species Species Species psi \n");
3966 for (
size_t i = 1; i <
m_kk; i++) {
3967 for (
size_t j = 1; j <
m_kk; j++) {
3968 for (
size_t k = 1; k <
m_kk; k++) {
3971 writelogf(
" %-16s %-16s %-16s %9.5f \n",
3988 double afac = -1.0 *(lnGammaClMs2 - lnGammaCLMs1);
3989 for (
size_t k = 0; k <
m_kk; k++) {
3990 acMolality[k] *= exp(
charge(k) * afac);
4003 double afac = -1.0 *(lnGammaClMs2 - lnGammaCLMs1);
4004 for (
size_t k = 0; k <
m_kk; k++) {
4018 double afac = -1.0 *(dlnGammaClM_dT_s2 - dlnGammaCLM_dT_s1);
4019 for (
size_t k = 0; k <
m_kk; k++) {
4033 double afac = -1.0 *(d2lnGammaClM_dT2_s2 - d2lnGammaCLM_dT2_s1);
4034 for (
size_t k = 0; k <
m_kk; k++) {
4048 double afac = -1.0 *(dlnGammaClM_dP_s2 - dlnGammaCLM_dP_s1);
4049 for (
size_t k = 0; k <
m_kk; k++) {
4058 double lnGammaClMs2 = - A * sqrtIs /(1.0 + 1.5 * sqrtIs);
4059 return lnGammaClMs2;
4066 return - dAdT * sqrtIs /(1.0 + 1.5 * sqrtIs);
4073 return - d2AdT2 * sqrtIs /(1.0 + 1.5 * sqrtIs);
4080 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.