58 : N(component_names.size()), ion_term(false), polar_term(false), assoc_term(false), water_present(false), water_idx(0) {
62 for (
unsigned int i = 0; i <
N; ++i) {
89 std::string kij_string;
90 std::string kijT_string;
96 for (
unsigned int i = 0; i <
N; ++i) {
97 for (
unsigned int j = 0; j <
N; ++j) {
101 k_ij[i *
N + j] = atof(kij_string.c_str());
102 k_ijT[i *
N + j] = atof(kijT_string.c_str());
108 if (generate_SatL_and_SatV) {
109 bool SatLSatV =
false;
126 : components(components_in), N(components.size()), ion_term(false), polar_term(false), assoc_term(false), water_present(false), water_idx(0) {
130 for (
unsigned int i = 0; i <
N; ++i) {
155 std::string kij_string;
156 std::string kijT_string;
162 for (
unsigned int i = 0; i <
N; ++i) {
163 for (
unsigned int j = 0; j <
N; ++j) {
167 k_ij[i *
N + j] = atof(kij_string.c_str());
168 k_ijT[i *
N + j] = atof(kijT_string.c_str());
174 if (generate_SatL_and_SatV) {
175 bool SatLSatV =
false;
203 if (mass_fractions.size() !=
N) {
204 throw ValueError(
format(
"size of mass fraction vector [%d] does not equal that of component vector [%d]", mass_fractions.size(),
N));
206 std::vector<CoolPropDbl> moles;
209 for (
unsigned int i = 0; i <
components.size(); ++i) {
210 tmp = mass_fractions[i] /
components[i].molar_mass();
211 moles.push_back(tmp);
215 for (
const auto& mole : moles) {
249 vector<double> d(ncomp);
250 for (
auto i = 0U; i < ncomp; i++) {
254 for (
auto i = 0U; i < ncomp; i++) {
264 vector<double> zeta(4, 0);
266 for (
int i = 0; i < 4; i++) {
268 for (
size_t j = 0; j < ncomp; j++) {
271 zeta[i] = PI / 6 * den * summ;
274 double eta = zeta[3];
276 for (
size_t i = 0; i < ncomp; i++) {
280 vector<double> ghs(ncomp * ncomp, 0);
281 vector<double> e_ij(ncomp * ncomp, 0);
282 vector<double> s_ij(ncomp * ncomp, 0);
286 for (
size_t i = 0; i < ncomp; i++) {
287 for (
size_t j = 0; j < ncomp; j++) {
310 ghs[idx] = 1 / (1 - zeta[3]) + (d[i] * d[j] / (d[i] + d[j])) * 3 * zeta[2] / (1 - zeta[3]) / (1 - zeta[3])
311 + pow(d[i] * d[j] / (d[i] + d[j]), 2) * 2 * zeta[2] * zeta[2] / pow(1 - zeta[3], 3);
315 double ares_hs = 1 / zeta[0]
316 * (3 * zeta[1] * zeta[2] / (1 - zeta[3]) + pow(zeta[2], 3.) / (zeta[3] * pow(1 - zeta[3], 2))
317 + (pow(zeta[2], 3.) / pow(zeta[3], 2.) - zeta[0]) * log(1 - zeta[3]));
319 static double a0[7] = {0.9105631445, 0.6361281449, 2.6861347891, -26.547362491, 97.759208784, -159.59154087, 91.297774084};
320 static double a1[7] = {-0.3084016918, 0.1860531159, -2.5030047259, 21.419793629, -65.255885330, 83.318680481, -33.746922930};
321 static double a2[7] = {-0.0906148351, 0.4527842806, 0.5962700728, -1.7241829131, -4.1302112531, 13.776631870, -8.6728470368};
322 static double b0[7] = {0.7240946941, 2.2382791861, -4.0025849485, -21.003576815, 26.855641363, 206.55133841, -355.60235612};
323 static double b1[7] = {-0.5755498075, 0.6995095521, 3.8925673390, -17.215471648, 192.67226447, -161.82646165, -165.20769346};
324 static double b2[7] = {0.0976883116, -0.2557574982, -9.1558561530, 20.642075974, -38.804430052, 93.626774077, -29.666905585};
326 vector<double> a(7, 0);
327 vector<double> b(7, 0);
328 for (
int i = 0; i < 7; i++) {
329 a[i] = a0[i] + (m_avg - 1.) / m_avg * a1[i] + (m_avg - 1.) / m_avg * (m_avg - 2.) / m_avg * a2[i];
330 b[i] = b0[i] + (m_avg - 1.) / m_avg * b1[i] + (m_avg - 1.) / m_avg * (m_avg - 2.) / m_avg * b2[i];
335 for (
int i = 0; i < 7; i++) {
336 I1 += a[i] * pow(eta, i);
337 I2 += b[i] * pow(eta, i);
340 / (1. + m_avg * (8 * eta - 2 * eta * eta) / pow(1 - eta, 4)
341 + (1 - m_avg) * (20 * eta - 27 * eta * eta + 12 * pow(eta, 3) - 2 * pow(eta, 4)) / pow((1 - eta) * (2 - eta), 2.0));
344 for (
size_t i = 0; i < ncomp; i++) {
348 double ares_hc = m_avg * ares_hs - summ;
349 double ares_disp = -2 * PI * den * I1 * m2es3 - PI * den * m_avg * C1 * I2 * m2e2s3;
352 double ares_polar = 0.;
356 vector<double> dipmSQ(ncomp, 0);
358 static double a0dip[5] = {0.3043504, -0.1358588, 1.4493329, 0.3556977, -2.0653308};
359 static double a1dip[5] = {0.9534641, -1.8396383, 2.0131180, -7.3724958, 8.2374135};
360 static double a2dip[5] = {-1.1610080, 4.5258607, 0.9751222, -12.281038, 5.9397575};
361 static double b0dip[5] = {0.2187939, -1.1896431, 1.1626889, 0, 0};
362 static double b1dip[5] = {-0.5873164, 1.2489132, -0.5085280, 0, 0};
363 static double b2dip[5] = {3.4869576, -14.915974, 15.372022, 0, 0};
364 static double c0dip[5] = {-0.0646774, 0.1975882, -0.8087562, 0.6902849, 0};
365 static double c1dip[5] = {-0.9520876, 2.9924258, -2.3802636, -0.2701261, 0};
366 static double c2dip[5] = {-0.6260979, 1.2924686, 1.6542783, -3.4396744, 0};
368 const static double conv = 7242.702976750923;
370 for (
size_t i = 0; i < ncomp; i++) {
374 vector<double> adip(5, 0);
375 vector<double> bdip(5, 0);
376 vector<double> cdip(5, 0);
377 double J2 = NAN, J3 = NAN;
380 for (
size_t i = 0; i < ncomp; i++) {
381 for (
size_t j = 0; j < ncomp; j++) {
387 for (
int l = 0; l < 5; l++) {
388 adip[l] = a0dip[l] + (m_ij - 1) / m_ij * a1dip[l] + (m_ij - 1) / m_ij * (m_ij - 2) / m_ij * a2dip[l];
389 bdip[l] = b0dip[l] + (m_ij - 1) / m_ij * b1dip[l] + (m_ij - 1) / m_ij * (m_ij - 2) / m_ij * b2dip[l];
390 J2 += (adip[l] + bdip[l] * e_ij[i * ncomp + j] /
_T)
394 * pow(s_ij[j * ncomp + j], 3) / pow(s_ij[i * ncomp + j], 3) *
components[i].getDipnum() *
components[j].getDipnum() * dipmSQ[i]
397 for (
size_t k = 0; k < ncomp; k++) {
403 for (
int l = 0; l < 5; l++) {
404 cdip[l] = c0dip[l] + (m_ijk - 1) / m_ijk * c1dip[l] + (m_ijk - 1) / m_ijk * (m_ijk - 2) / m_ijk * c2dip[l];
405 J3 += cdip[l] * pow(eta, l);
408 * e_ij[k * ncomp + k] /
_T * pow(s_ij[i * ncomp + i], 3) * pow(s_ij[j * ncomp + j], 3) * pow(s_ij[k * ncomp + k], 3)
409 / s_ij[i * ncomp + j] / s_ij[i * ncomp + k] / s_ij[j * ncomp + k] *
components[i].getDipnum() *
components[j].getDipnum()
410 *
components[k].getDipnum() * dipmSQ[i] * dipmSQ[j] * dipmSQ[k] * J3;
416 A3 = -4 / 3. * PI * PI * den * den * A3;
419 ares_polar = A2 / (1 - A3 / A2);
424 double ares_assoc = 0.;
430 for (
int i = 0; i < *it; i++) {
431 iA.push_back(
static_cast<int>(it -
assoc_num.begin()));
435 vector<double> x_assoc(num_sites);
436 for (
int i = 0; i < num_sites; i++) {
441 vector<double> XA(num_sites, 0);
442 vector<double> delta_ij(
static_cast<std::size_t
>(num_sites) * num_sites, 0);
446 for (
auto i = 0; i < num_sites; i++) {
447 idxi = iA[i] * ncomp + iA[i];
448 for (
int j = 0; j < num_sites; j++) {
449 idxj = iA[j] * ncomp + iA[j];
453 * pow(sqrt(s_ij[idxi] * s_ij[idxj]) / (0.5 * (s_ij[idxi] + s_ij[idxj])), 3);
454 delta_ij[idxa] = ghs[iA[i] * ncomp + iA[j]] * (exp(eABij /
_T) - 1) * pow(s_ij[iA[i] * ncomp + iA[j]], 3) * volABij;
458 XA[i] = (-1 + sqrt(1 + 8 * den * delta_ij[i * num_sites + i])) / (4 * den * delta_ij[i * num_sites + i]);
459 if (!std::isfinite(XA[i])) {
466 vector<double> XA_old = XA;
467 while ((ctr < 100) && (dif > 1e-15)) {
469 XA =
XA_find(XA_old, delta_ij, den, x_assoc);
471 for (
int i = 0; i < num_sites; i++) {
472 dif += abs(XA[i] - XA_old[i]);
474 for (
int i = 0; i < num_sites; i++) {
475 XA_old[i] = (XA[i] + XA_old[i]) / 2.0;
480 for (
int i = 0; i < num_sites; i++) {
481 ares_assoc +=
mole_fractions[iA[i]] * (log(XA[i]) - 0.5 * XA[i] + 0.5);
486 double ares_ion = 0.;
488 vector<double> q(ncomp);
489 for (
size_t i = 0; i < ncomp; i++) {
494 for (
size_t i = 0; i < ncomp; i++) {
498 sqrt(den * E_CHRG * E_CHRG / kb /
_T / (
dielc * perm_vac) * summ);
501 vector<double> chi(ncomp);
502 vector<double> sigma_k(ncomp);
504 for (
size_t i = 0; i < ncomp; i++) {
505 chi[i] = 3 / pow(kappa * d[i], 3) * (1.5 + log(1 + kappa * d[i]) - 2 * (1 + kappa * d[i]) + 0.5 * pow(1 + kappa * d[i], 2));
509 ares_ion = -1 / 12. / PI / kb /
_T / (
dielc * perm_vac) * summ;
513 CoolPropDbl ares = ares_hc + ares_disp + ares_polar + ares_assoc + ares_ion;
519 vector<double> d(ncomp), dd_dt(ncomp);
520 for (
auto i = 0U; i < ncomp; i++) {
525 for (
auto i = 0U; i < ncomp; i++) {
536 vector<double> zeta(4, 0);
538 for (
int i = 0; i < 4; i++) {
540 for (
size_t j = 0; j < ncomp; j++) {
543 zeta[i] = PI / 6 * den * summ;
546 vector<double> dzeta_dt(4, 0);
547 for (
int i = 1; i < 4; i++) {
549 for (
size_t j = 0; j < ncomp; j++) {
552 dzeta_dt[i] = PI / 6 * den * summ;
555 double eta = zeta[3];
557 for (
size_t i = 0; i < ncomp; i++) {
561 vector<double> ghs(ncomp * ncomp, 0);
562 vector<double> dghs_dt(ncomp * ncomp, 0);
563 vector<double> e_ij(ncomp * ncomp, 0);
564 vector<double> s_ij(ncomp * ncomp, 0);
567 double ddij_dt = NAN;
569 for (
size_t i = 0; i < ncomp; i++) {
570 for (
size_t j = 0; j < ncomp; j++) {
593 ghs[idx] = 1 / (1 - zeta[3]) + (d[i] * d[j] / (d[i] + d[j])) * 3 * zeta[2] / (1 - zeta[3]) / (1 - zeta[3])
594 + pow(d[i] * d[j] / (d[i] + d[j]), 2) * 2 * zeta[2] * zeta[2] / pow(1 - zeta[3], 3);
595 ddij_dt = (d[i] * d[j] / (d[i] + d[j])) * (dd_dt[i] / d[i] + dd_dt[j] / d[j] - (dd_dt[i] + dd_dt[j]) / (d[i] + d[j]));
596 dghs_dt[idx] = dzeta_dt[3] / pow(1 - zeta[3], 2.)
597 + 3 * (ddij_dt * zeta[2] + (d[i] * d[j] / (d[i] + d[j])) * dzeta_dt[2]) / pow(1 - zeta[3], 2.)
598 + 4 * (d[i] * d[j] / (d[i] + d[j])) * zeta[2]
599 * (1.5 * dzeta_dt[3] + ddij_dt * zeta[2] + (d[i] * d[j] / (d[i] + d[j])) * dzeta_dt[2]) / pow(1 - zeta[3], 3.)
600 + 6 * pow((d[i] * d[j] / (d[i] + d[j])) * zeta[2], 2.) * dzeta_dt[3] / pow(1 - zeta[3], 4.);
606 * (3 * (dzeta_dt[1] * zeta[2] + zeta[1] * dzeta_dt[2]) / (1 - zeta[3]) + 3 * zeta[1] * zeta[2] * dzeta_dt[3] / pow(1 - zeta[3], 2.)
607 + 3 * pow(zeta[2], 2.) * dzeta_dt[2] / zeta[3] / pow(1 - zeta[3], 2.)
608 + pow(zeta[2], 3.) * dzeta_dt[3] * (3 * zeta[3] - 1) / pow(zeta[3], 2.) / pow(1 - zeta[3], 3.)
609 + (3 * pow(zeta[2], 2.) * dzeta_dt[2] * zeta[3] - 2 * pow(zeta[2], 3.) * dzeta_dt[3]) / pow(zeta[3], 3.) * log(1 - zeta[3])
610 + (zeta[0] - pow(zeta[2], 3) / pow(zeta[3], 2.)) * dzeta_dt[3] / (1 - zeta[3]));
612 static double a0[7] = {0.9105631445, 0.6361281449, 2.6861347891, -26.547362491, 97.759208784, -159.59154087, 91.297774084};
613 static double a1[7] = {-0.3084016918, 0.1860531159, -2.5030047259, 21.419793629, -65.255885330, 83.318680481, -33.746922930};
614 static double a2[7] = {-0.0906148351, 0.4527842806, 0.5962700728, -1.7241829131, -4.1302112531, 13.776631870, -8.6728470368};
615 static double b0[7] = {0.7240946941, 2.2382791861, -4.0025849485, -21.003576815, 26.855641363, 206.55133841, -355.60235612};
616 static double b1[7] = {-0.5755498075, 0.6995095521, 3.8925673390, -17.215471648, 192.67226447, -161.82646165, -165.20769346};
617 static double b2[7] = {0.0976883116, -0.2557574982, -9.1558561530, 20.642075974, -38.804430052, 93.626774077, -29.666905585};
619 vector<double> a(7, 0);
620 vector<double> b(7, 0);
621 for (
int i = 0; i < 7; i++) {
622 a[i] = a0[i] + (m_avg - 1.) / m_avg * a1[i] + (m_avg - 1.) / m_avg * (m_avg - 2.) / m_avg * a2[i];
623 b[i] = b0[i] + (m_avg - 1.) / m_avg * b1[i] + (m_avg - 1.) / m_avg * (m_avg - 2.) / m_avg * b2[i];
628 double dI1_dt = 0.0, dI2_dt = 0.;
629 for (
int i = 0; i < 7; i++) {
630 I1 += a[i] * pow(eta, i);
631 I2 += b[i] * pow(eta, i);
632 dI1_dt += a[i] * dzeta_dt[3] * i * pow(eta, i - 1);
633 dI2_dt += b[i] * dzeta_dt[3] * i * pow(eta, i - 1);
636 / (1. + m_avg * (8 * eta - 2 * eta * eta) / pow(1 - eta, 4)
637 + (1 - m_avg) * (20 * eta - 27 * eta * eta + 12 * pow(eta, 3) - 2 * pow(eta, 4)) / pow((1 - eta) * (2 - eta), 2.0));
638 double C2 = -1 * C1 * C1
639 * (m_avg * (-4 * eta * eta + 20 * eta + 8) / pow(1 - eta, 5.)
640 + (1 - m_avg) * (2 * pow(eta, 3) + 12 * eta * eta - 48 * eta + 40) / pow((1 - eta) * (2 - eta), 3));
641 double dC1_dt = C2 * dzeta_dt[3];
644 for (
size_t i = 0; i < ncomp; i++) {
648 double dadt_hc = m_avg * dadt_hs - summ;
649 double dadt_disp = -2 * PI * den * (dI1_dt - I1 /
_T) * m2es3 - PI * den * m_avg * (dC1_dt * I2 + C1 * dI2_dt - 2 * C1 * I2 /
_T) * m2e2s3;
652 double dadt_polar = 0.;
658 vector<double> dipmSQ(ncomp, 0);
660 static double a0dip[5] = {0.3043504, -0.1358588, 1.4493329, 0.3556977, -2.0653308};
661 static double a1dip[5] = {0.9534641, -1.8396383, 2.0131180, -7.3724958, 8.2374135};
662 static double a2dip[5] = {-1.1610080, 4.5258607, 0.9751222, -12.281038, 5.9397575};
663 static double b0dip[5] = {0.2187939, -1.1896431, 1.1626889, 0, 0};
664 static double b1dip[5] = {-0.5873164, 1.2489132, -0.5085280, 0, 0};
665 static double b2dip[5] = {3.4869576, -14.915974, 15.372022, 0, 0};
666 static double c0dip[5] = {-0.0646774, 0.1975882, -0.8087562, 0.6902849, 0};
667 static double c1dip[5] = {-0.9520876, 2.9924258, -2.3802636, -0.2701261, 0};
668 static double c2dip[5] = {-0.6260979, 1.2924686, 1.6542783, -3.4396744, 0};
670 const static double conv = 7242.702976750923;
672 for (
size_t i = 0; i < ncomp; i++) {
676 vector<double> adip(5, 0);
677 vector<double> bdip(5, 0);
678 vector<double> cdip(5, 0);
679 double J2 = NAN, J3 = NAN, dJ2_dt = NAN, dJ3_dt = NAN;
682 for (
size_t i = 0; i < ncomp; i++) {
683 for (
size_t j = 0; j < ncomp; j++) {
690 for (
int l = 0; l < 5; l++) {
691 adip[l] = a0dip[l] + (m_ij - 1) / m_ij * a1dip[l] + (m_ij - 1) / m_ij * (m_ij - 2) / m_ij * a2dip[l];
692 bdip[l] = b0dip[l] + (m_ij - 1) / m_ij * b1dip[l] + (m_ij - 1) / m_ij * (m_ij - 2) / m_ij * b2dip[l];
693 J2 += (adip[l] + bdip[l] * e_ij[i * ncomp + j] /
_T)
695 dJ2_dt += adip[l] * l * pow(eta, l - 1) * dzeta_dt[3]
696 + bdip[l] * e_ij[j * ncomp + j] * (1 /
_T * l * pow(eta, l - 1) * dzeta_dt[3] - 1 / pow(
_T, 2.) * pow(eta, l));
699 * pow(s_ij[j * ncomp + j], 3) / pow(s_ij[i * ncomp + j], 3) *
components[i].getDipnum() *
components[j].getDipnum() * dipmSQ[i]
702 * pow(s_ij[j * ncomp + j], 3) / pow(s_ij[i * ncomp + j], 3) *
components[i].getDipnum() *
components[j].getDipnum()
703 * dipmSQ[i] * dipmSQ[j] * (dJ2_dt / pow(
_T, 2) - 2 * J2 / pow(
_T, 3));
705 for (
size_t k = 0; k < ncomp; k++) {
712 for (
int l = 0; l < 5; l++) {
713 cdip[l] = c0dip[l] + (m_ijk - 1) / m_ijk * c1dip[l] + (m_ijk - 1) / m_ijk * (m_ijk - 2) / m_ijk * c2dip[l];
714 J3 += cdip[l] * pow(eta, l);
715 dJ3_dt += cdip[l] * l * pow(eta, l - 1) * dzeta_dt[3];
718 * e_ij[k * ncomp + k] /
_T * pow(s_ij[i * ncomp + i], 3) * pow(s_ij[j * ncomp + j], 3) * pow(s_ij[k * ncomp + k], 3)
719 / s_ij[i * ncomp + j] / s_ij[i * ncomp + k] / s_ij[j * ncomp + k] *
components[i].getDipnum() *
components[j].getDipnum()
720 *
components[k].getDipnum() * dipmSQ[i] * dipmSQ[j] * dipmSQ[k] * J3;
722 * e_ij[k * ncomp + k] * pow(s_ij[i * ncomp + i], 3) * pow(s_ij[j * ncomp + j], 3) * pow(s_ij[k * ncomp + k], 3)
723 / s_ij[i * ncomp + j] / s_ij[i * ncomp + k] / s_ij[j * ncomp + k] *
components[i].getDipnum()
725 * (-3 * J3 / pow(
_T, 4) + dJ3_dt / pow(
_T, 3));
731 A3 = -4 / 3. * PI * PI * den * den * A3;
732 dA2_dt = -PI * den * dA2_dt;
733 dA3_dt = -4 / 3. * PI * PI * den * den * dA3_dt;
736 dadt_polar = (dA2_dt - 2 * A3 / A2 * dA2_dt + dA3_dt) / pow(1 - A3 / A2, 2.);
741 double dadt_assoc = 0.;
747 for (
int i = 0; i < *it; i++) {
748 iA.push_back(
static_cast<int>(it -
assoc_num.begin()));
752 vector<double> x_assoc(num_sites);
753 for (
int i = 0; i < num_sites; i++) {
758 vector<double> XA(num_sites, 0);
759 vector<double> delta_ij(
static_cast<std::size_t
>(num_sites) * num_sites, 0);
760 vector<double> ddelta_dt(
static_cast<std::size_t
>(num_sites) * num_sites, 0);
761 std::size_t idxa = 0UL;
762 std::size_t idxi = 0UL;
763 std::size_t idxj = 0UL;
764 for (
auto i = 0; i < num_sites; i++) {
765 idxi = iA[i] * ncomp + iA[i];
766 for (
auto j = 0; j < num_sites; j++) {
767 idxj = iA[j] * ncomp + iA[j];
771 * pow(sqrt(s_ij[idxi] * s_ij[idxj]) / (0.5 * (s_ij[idxi] + s_ij[idxj])), 3);
772 delta_ij[idxa] = ghs[iA[i] * ncomp + iA[j]] * (exp(eABij /
_T) - 1) * pow(s_ij[iA[i] * ncomp + iA[j]], 3) * volABij;
774 pow(s_ij[idxj], 3) * volABij
775 * (-eABij / pow(
_T, 2) * exp(eABij /
_T) * ghs[iA[i] * ncomp + iA[j]] + dghs_dt[iA[i] * ncomp + iA[j]] * (exp(eABij /
_T) - 1));
779 XA[i] = (-1 + sqrt(1 + 8 * den * delta_ij[i * num_sites + i])) / (4 * den * delta_ij[i * num_sites + i]);
780 if (!std::isfinite(XA[i])) {
787 vector<double> XA_old = XA;
788 while ((ctr < 100) && (dif > 1e-15)) {
790 XA =
XA_find(XA_old, delta_ij, den, x_assoc);
792 for (
int i = 0; i < num_sites; i++) {
793 dif += abs(XA[i] - XA_old[i]);
795 for (
int i = 0; i < num_sites; i++) {
796 XA_old[i] = (XA[i] + XA_old[i]) / 2.0;
800 vector<double> dXA_dt(num_sites, 0);
801 dXA_dt =
dXAdt_find(delta_ij, den, XA, ddelta_dt, x_assoc);
803 for (
int i = 0; i < num_sites; i++) {
804 dadt_assoc +=
mole_fractions[iA[i]] * (1 / XA[i] - 0.5) * dXA_dt[i];
809 double dadt_ion = 0.;
811 vector<double> q(ncomp);
812 for (
size_t i = 0; i < ncomp; i++) {
817 for (
size_t i = 0; i < ncomp; i++) {
821 sqrt(den * E_CHRG * E_CHRG / kb /
_T / (
dielc * perm_vac) * summ);
823 double dkappa_dt = NAN;
825 vector<double> chi(ncomp);
826 vector<double> dchikap_dk(ncomp);
828 for (
size_t i = 0; i < ncomp; i++) {
829 chi[i] = 3 / pow(kappa * d[i], 3) * (1.5 + log(1 + kappa * d[i]) - 2 * (1 + kappa * d[i]) + 0.5 * pow(1 + kappa * d[i], 2));
830 dchikap_dk[i] = -2 * chi[i] + 3 / (1 + kappa * d[i]);
833 dkappa_dt = -0.5 * den * E_CHRG * E_CHRG / kb /
_T /
_T / (
dielc * perm_vac) * summ / kappa;
836 for (
size_t i = 0; i < ncomp; i++) {
837 summ +=
mole_fractions[i] * q[i] * q[i] * (dchikap_dk[i] * dkappa_dt /
_T - kappa * chi[i] /
_T /
_T);
839 dadt_ion = -1 / 12. / PI / kb / (
dielc * perm_vac) * summ;
843 double dadt = dadt_hc + dadt_disp + dadt_assoc + dadt_polar + dadt_ion;
865 vector<double> d(ncomp);
866 for (
auto i = 0U; i < ncomp; i++) {
870 for (
auto i = 0U; i < ncomp; i++) {
880 vector<double> zeta(4, 0);
882 for (
int i = 0; i < 4; i++) {
884 for (
size_t j = 0; j < ncomp; j++) {
887 zeta[i] = PI / 6 * den * summ;
890 double eta = zeta[3];
892 for (
size_t i = 0; i < ncomp; i++) {
896 vector<double> ghs(ncomp * ncomp, 0);
897 vector<double> denghs(ncomp * ncomp, 0);
898 vector<double> e_ij(ncomp * ncomp, 0);
899 vector<double> s_ij(ncomp * ncomp, 0);
903 for (
size_t i = 0; i < ncomp; i++) {
904 for (
size_t j = 0; j < ncomp; j++) {
927 ghs[idx] = 1 / (1 - zeta[3]) + (d[i] * d[j] / (d[i] + d[j])) * 3 * zeta[2] / (1 - zeta[3]) / (1 - zeta[3])
928 + pow(d[i] * d[j] / (d[i] + d[j]), 2) * 2 * zeta[2] * zeta[2] / pow(1 - zeta[3], 3);
930 zeta[3] / (1 - zeta[3]) / (1 - zeta[3])
931 + (d[i] * d[j] / (d[i] + d[j])) * (3 * zeta[2] / (1 - zeta[3]) / (1 - zeta[3]) + 6 * zeta[2] * zeta[3] / pow(1 - zeta[3], 3))
932 + pow(d[i] * d[j] / (d[i] + d[j]), 2)
933 * (4 * zeta[2] * zeta[2] / pow(1 - zeta[3], 3) + 6 * zeta[2] * zeta[2] * zeta[3] / pow(1 - zeta[3], 4));
937 double ares_hs = 1 / zeta[0]
938 * (3 * zeta[1] * zeta[2] / (1 - zeta[3]) + pow(zeta[2], 3.) / (zeta[3] * pow(1 - zeta[3], 2))
939 + (pow(zeta[2], 3.) / pow(zeta[3], 2.) - zeta[0]) * log(1 - zeta[3]));
940 double Zhs = zeta[3] / (1 - zeta[3]) + 3. * zeta[1] * zeta[2] / zeta[0] / (1. - zeta[3]) / (1. - zeta[3])
941 + (3. * pow(zeta[2], 3.) - zeta[3] * pow(zeta[2], 3.)) / zeta[0] / pow(1. - zeta[3], 3.);
943 static double a0[7] = {0.9105631445, 0.6361281449, 2.6861347891, -26.547362491, 97.759208784, -159.59154087, 91.297774084};
944 static double a1[7] = {-0.3084016918, 0.1860531159, -2.5030047259, 21.419793629, -65.255885330, 83.318680481, -33.746922930};
945 static double a2[7] = {-0.0906148351, 0.4527842806, 0.5962700728, -1.7241829131, -4.1302112531, 13.776631870, -8.6728470368};
946 static double b0[7] = {0.7240946941, 2.2382791861, -4.0025849485, -21.003576815, 26.855641363, 206.55133841, -355.60235612};
947 static double b1[7] = {-0.5755498075, 0.6995095521, 3.8925673390, -17.215471648, 192.67226447, -161.82646165, -165.20769346};
948 static double b2[7] = {0.0976883116, -0.2557574982, -9.1558561530, 20.642075974, -38.804430052, 93.626774077, -29.666905585};
950 vector<double> a(7, 0);
951 vector<double> b(7, 0);
952 for (
int i = 0; i < 7; i++) {
953 a[i] = a0[i] + (m_avg - 1.) / m_avg * a1[i] + (m_avg - 1.) / m_avg * (m_avg - 2.) / m_avg * a2[i];
954 b[i] = b0[i] + (m_avg - 1.) / m_avg * b1[i] + (m_avg - 1.) / m_avg * (m_avg - 2.) / m_avg * b2[i];
957 double detI1_det = 0.0;
958 double detI2_det = 0.0;
961 for (
int i = 0; i < 7; i++) {
962 detI1_det += a[i] * (i + 1) * pow(eta, i);
963 detI2_det += b[i] * (i + 1) * pow(eta, i);
964 I2 += b[i] * pow(eta, i);
965 I1 += a[i] * pow(eta, i);
968 / (1. + m_avg * (8 * eta - 2 * eta * eta) / pow(1 - eta, 4)
969 + (1 - m_avg) * (20 * eta - 27 * eta * eta + 12 * pow(eta, 3) - 2 * pow(eta, 4)) / pow((1 - eta) * (2 - eta), 2.0));
970 double C2 = -1. * C1 * C1
971 * (m_avg * (-4 * eta * eta + 20 * eta + 8) / pow(1 - eta, 5)
972 + (1 - m_avg) * (2 * pow(eta, 3) + 12 * eta * eta - 48 * eta + 40) / pow((1 - eta) * (2 - eta), 3.0));
975 for (
size_t i = 0; i < ncomp; i++) {
979 double ares_hc = m_avg * ares_hs - summ;
980 double ares_disp = -2 * PI * den * I1 * m2es3 - PI * den * m_avg * C1 * I2 * m2e2s3;
983 for (
size_t i = 0; i < ncomp; i++) {
987 double Zhc = m_avg * Zhs - summ;
988 double Zdisp = -2 * PI * den * detI1_det * m2es3 - PI * den * m_avg * (C1 * detI2_det + C2 * eta * I2) * m2e2s3;
990 vector<double> dghsii_dx(ncomp * ncomp, 0);
991 vector<double> dahs_dx(ncomp, 0);
992 vector<double> dzeta_dx(4, 0);
994 for (
size_t i = 0; i < ncomp; i++) {
995 for (
int l = 0; l < 4; l++) {
996 dzeta_dx[l] = PI / 6. * den *
components[i].getM() * pow(d[i], l);
998 for (
size_t j = 0; j < ncomp; j++) {
1001 dzeta_dx[3] / (1 - zeta[3]) / (1 - zeta[3])
1002 + (d[j] * d[j] / (d[j] + d[j])) * (3 * dzeta_dx[2] / (1 - zeta[3]) / (1 - zeta[3]) + 6 * zeta[2] * dzeta_dx[3] / pow(1 - zeta[3], 3))
1003 + pow(d[j] * d[j] / (d[j] + d[j]), 2)
1004 * (4 * zeta[2] * dzeta_dx[2] / pow(1 - zeta[3], 3) + 6 * zeta[2] * zeta[2] * dzeta_dx[3] / pow(1 - zeta[3], 4));
1007 -dzeta_dx[0] / zeta[0] * ares_hs
1009 * (3 * (dzeta_dx[1] * zeta[2] + zeta[1] * dzeta_dx[2]) / (1 - zeta[3])
1010 + 3 * zeta[1] * zeta[2] * dzeta_dx[3] / (1 - zeta[3]) / (1 - zeta[3])
1011 + 3 * zeta[2] * zeta[2] * dzeta_dx[2] / zeta[3] / (1 - zeta[3]) / (1 - zeta[3])
1012 + pow(zeta[2], 3) * dzeta_dx[3] * (3 * zeta[3] - 1) / zeta[3] / zeta[3] / pow(1 - zeta[3], 3)
1014 * ((3 * zeta[2] * zeta[2] * dzeta_dx[2] * zeta[3] - 2 * pow(zeta[2], 3) * dzeta_dx[3]) / pow(zeta[3], 3) - dzeta_dx[0])
1015 + (zeta[0] - pow(zeta[2], 3) / zeta[3] / zeta[3]) * dzeta_dx[3] / (1 - zeta[3]));
1018 vector<double> dadisp_dx(ncomp, 0);
1019 vector<double> dahc_dx(ncomp, 0);
1020 double dzeta3_dx = NAN, daa_dx = NAN, db_dx = NAN, dI1_dx = NAN, dI2_dx = NAN, dm2es3_dx = NAN, dm2e2s3_dx = NAN, dC1_dx = NAN;
1021 for (
size_t i = 0; i < ncomp; i++) {
1022 dzeta3_dx = PI / 6. * den *
components[i].getM() * pow(d[i], 3);
1027 for (
int l = 0; l < 7; l++) {
1028 daa_dx =
components[i].getM() / m_avg / m_avg * a1[l] +
components[i].getM() / m_avg / m_avg * (3 - 4 / m_avg) * a2[l];
1029 db_dx =
components[i].getM() / m_avg / m_avg * b1[l] +
components[i].getM() / m_avg / m_avg * (3 - 4 / m_avg) * b2[l];
1030 dI1_dx += a[l] * l * dzeta3_dx * pow(eta, l - 1) + daa_dx * pow(eta, l);
1031 dI2_dx += b[l] * l * dzeta3_dx * pow(eta, l - 1) + db_dx * pow(eta, l);
1033 for (
size_t j = 0; j < ncomp; j++) {
1038 dm2es3_dx = dm2es3_dx * 2 *
components[i].getM();
1039 dm2e2s3_dx = dm2e2s3_dx * 2 *
components[i].getM();
1040 dahc_dx[i] =
components[i].getM() * ares_hs + m_avg * dahs_dx[i] - dahc_dx[i] - (
components[i].getM() - 1) * log(ghs[i * ncomp + i]);
1041 dC1_dx = C2 * dzeta3_dx
1043 * (
components[i].getM() * (8 * eta - 2 * eta * eta) / pow(1 - eta, 4)
1044 -
components[i].getM() * (20 * eta - 27 * eta * eta + 12 * pow(eta, 3) - 2 * pow(eta, 4)) / pow((1 - eta) * (2 - eta), 2));
1047 -2 * PI * den * (dI1_dx * m2es3 + I1 * dm2es3_dx)
1048 - PI * den * ((
components[i].getM() * C1 * I2 + m_avg * dC1_dx * I2 + m_avg * C1 * dI2_dx) * m2e2s3 + m_avg * C1 * I2 * dm2e2s3_dx);
1051 vector<double> mu_hc(ncomp, 0);
1052 vector<double> mu_disp(ncomp, 0);
1053 for (
size_t i = 0; i < ncomp; i++) {
1054 for (
size_t j = 0; j < ncomp; j++) {
1058 mu_hc[i] = ares_hc + Zhc + dahc_dx[i] - mu_hc[i];
1059 mu_disp[i] = ares_disp + Zdisp + dadisp_dx[i] - mu_disp[i];
1063 vector<double> mu_polar(ncomp, 0);
1067 double dA2_det = 0.;
1068 double dA3_det = 0.;
1069 vector<double> dA2_dx(ncomp, 0);
1070 vector<double> dA3_dx(ncomp, 0);
1072 static double a0dip[5] = {0.3043504, -0.1358588, 1.4493329, 0.3556977, -2.0653308};
1073 static double a1dip[5] = {0.9534641, -1.8396383, 2.0131180, -7.3724958, 8.2374135};
1074 static double a2dip[5] = {-1.1610080, 4.5258607, 0.9751222, -12.281038, 5.9397575};
1075 static double b0dip[5] = {0.2187939, -1.1896431, 1.1626889, 0, 0};
1076 static double b1dip[5] = {-0.5873164, 1.2489132, -0.5085280, 0, 0};
1077 static double b2dip[5] = {3.4869576, -14.915974, 15.372022, 0, 0};
1078 static double c0dip[5] = {-0.0646774, 0.1975882, -0.8087562, 0.6902849, 0};
1079 static double c1dip[5] = {-0.9520876, 2.9924258, -2.3802636, -0.2701261, 0};
1080 static double c2dip[5] = {-0.6260979, 1.2924686, 1.6542783, -3.4396744, 0};
1082 const static double conv = 7242.702976750923;
1084 vector<double> dipmSQ(ncomp, 0);
1085 for (
size_t i = 0; i < ncomp; i++) {
1089 vector<double> adip(5, 0);
1090 vector<double> bdip(5, 0);
1091 vector<double> cdip(5, 0);
1092 double J2 = NAN, dJ2_det = NAN, detJ2_det = NAN, J3 = NAN, dJ3_det = NAN, detJ3_det = NAN;
1095 for (
size_t i = 0; i < ncomp; i++) {
1096 for (
size_t j = 0; j < ncomp; j++) {
1104 for (
int l = 0; l < 5; l++) {
1105 adip[l] = a0dip[l] + (m_ij - 1) / m_ij * a1dip[l] + (m_ij - 1) / m_ij * (m_ij - 2) / m_ij * a2dip[l];
1106 bdip[l] = b0dip[l] + (m_ij - 1) / m_ij * b1dip[l] + (m_ij - 1) / m_ij * (m_ij - 2) / m_ij * b2dip[l];
1107 J2 += (adip[l] + bdip[l] * e_ij[i * ncomp + j] /
_T)
1109 dJ2_det += (adip[l] + bdip[l] * e_ij[i * ncomp + j] /
_T) * l * pow(eta, l - 1);
1110 detJ2_det += (adip[l] + bdip[l] * e_ij[i * ncomp + j] /
_T) * (l + 1) * pow(eta, l);
1113 * pow(s_ij[j * ncomp + j], 3) / pow(s_ij[i * ncomp + j], 3) *
components[i].getDipnum() *
components[j].getDipnum() * dipmSQ[i]
1116 * pow(s_ij[j * ncomp + j], 3) / pow(s_ij[i * ncomp + j], 3) *
components[i].getDipnum() *
components[j].getDipnum()
1117 * dipmSQ[i] * dipmSQ[j] * detJ2_det;
1119 dA2_dx[i] += e_ij[i * ncomp + i] /
_T * e_ij[j * ncomp + j] /
_T * pow(s_ij[i * ncomp + i], 3) * pow(s_ij[j * ncomp + j], 3)
1120 / pow(s_ij[i * ncomp + j], 3) *
components[i].getDipnum() *
components[j].getDipnum() * dipmSQ[i] * dipmSQ[j]
1124 dA2_dx[i] += e_ij[i * ncomp + i] /
_T * e_ij[j * ncomp + j] /
_T * pow(s_ij[i * ncomp + i], 3) * pow(s_ij[j * ncomp + j], 3)
1125 / pow(s_ij[i * ncomp + j], 3) *
components[i].getDipnum() *
components[j].getDipnum() * dipmSQ[i] * dipmSQ[j]
1130 for (
size_t k = 0; k < ncomp; k++) {
1138 for (
int l = 0; l < 5; l++) {
1139 cdip[l] = c0dip[l] + (m_ijk - 1) / m_ijk * c1dip[l] + (m_ijk - 1) / m_ijk * (m_ijk - 2) / m_ijk * c2dip[l];
1140 J3 += cdip[l] * pow(eta, l);
1141 dJ3_det += cdip[l] * l * pow(eta, (l - 1));
1142 detJ3_det += cdip[l] * (l + 2) * pow(eta, (l + 1));
1145 * e_ij[k * ncomp + k] /
_T * pow(s_ij[i * ncomp + i], 3) * pow(s_ij[j * ncomp + j], 3) * pow(s_ij[k * ncomp + k], 3)
1146 / s_ij[i * ncomp + j] / s_ij[i * ncomp + k] / s_ij[j * ncomp + k] *
components[i].getDipnum() *
components[j].getDipnum()
1147 *
components[k].getDipnum() * dipmSQ[i] * dipmSQ[j] * dipmSQ[k] * J3;
1149 * e_ij[k * ncomp + k] /
_T * pow(s_ij[i * ncomp + i], 3) * pow(s_ij[j * ncomp + j], 3) * pow(s_ij[k * ncomp + k], 3)
1150 / s_ij[i * ncomp + j] / s_ij[i * ncomp + k] / s_ij[j * ncomp + k] *
components[i].getDipnum()
1151 *
components[j].getDipnum() *
components[k].getDipnum() * dipmSQ[i] * dipmSQ[j] * dipmSQ[k] * detJ3_det;
1152 if ((i == j) && (i == k)) {
1154 e_ij[i * ncomp + i] /
_T * e_ij[j * ncomp + j] /
_T * e_ij[k * ncomp + k] /
_T * pow(s_ij[i * ncomp + i], 3)
1155 * pow(s_ij[j * ncomp + j], 3) * pow(s_ij[k * ncomp + k], 3) / s_ij[i * ncomp + j] / s_ij[i * ncomp + k]
1157 * dipmSQ[j] * dipmSQ[k]
1160 }
else if ((i == j) || (i == k)) {
1162 e_ij[i * ncomp + i] /
_T * e_ij[j * ncomp + j] /
_T * e_ij[k * ncomp + k] /
_T * pow(s_ij[i * ncomp + i], 3)
1163 * pow(s_ij[j * ncomp + j], 3) * pow(s_ij[k * ncomp + k], 3) / s_ij[i * ncomp + j] / s_ij[i * ncomp + k]
1165 * dipmSQ[j] * dipmSQ[k]
1170 e_ij[i * ncomp + i] /
_T * e_ij[j * ncomp + j] /
_T * e_ij[k * ncomp + k] /
_T * pow(s_ij[i * ncomp + i], 3)
1171 * pow(s_ij[j * ncomp + j], 3) * pow(s_ij[k * ncomp + k], 3) / s_ij[i * ncomp + j] / s_ij[i * ncomp + k]
1173 * dipmSQ[j] * dipmSQ[k]
1181 A2 = -PI * den * A2;
1182 A3 = -4 / 3. * PI * PI * den * den * A3;
1183 dA2_det = -PI * den / eta * dA2_det;
1184 dA3_det = -4 / 3. * PI * PI * den / eta * den / eta * dA3_det;
1185 for (
size_t i = 0; i < ncomp; i++) {
1186 dA2_dx[i] = -PI * den * dA2_dx[i];
1187 dA3_dx[i] = -4 / 3. * PI * PI * den * den * dA3_dx[i];
1190 vector<double> dapolar_dx(ncomp);
1191 for (
size_t i = 0; i < ncomp; i++) {
1192 dapolar_dx[i] = (dA2_dx[i] * (1 - A3 / A2) + (dA3_dx[i] * A2 - A3 * dA2_dx[i]) / A2) / pow(1 - A3 / A2, 2);
1196 double ares_polar = A2 / (1 - A3 / A2);
1197 double Zpolar = eta * ((dA2_det * (1 - A3 / A2) + (dA3_det * A2 - A3 * dA2_det) / A2) / (1 - A3 / A2) / (1 - A3 / A2));
1198 for (
size_t i = 0; i < ncomp; i++) {
1199 for (
size_t j = 0; j < ncomp; j++) {
1202 mu_polar[i] = ares_polar + Zpolar + dapolar_dx[i] - mu_polar[i];
1208 vector<double> mu_assoc(ncomp, 0);
1214 for (
int i = 0; i < *it; i++) {
1215 iA.push_back(
static_cast<int>(it -
assoc_num.begin()));
1219 vector<double> x_assoc(num_sites);
1220 for (
int i = 0; i < num_sites; i++) {
1225 vector<double> XA(num_sites, 0);
1226 vector<double> delta_ij(
static_cast<std::size_t
>(num_sites) * num_sites, 0);
1227 std::size_t idxa = 0UL;
1228 std::size_t idxi = 0UL;
1229 std::size_t idxj = 0UL;
1230 for (
auto i = 0UL; i < static_cast<std::size_t>(num_sites); i++) {
1231 idxi = iA[i] * ncomp + iA[i];
1232 for (
auto j = 0UL; j < static_cast<std::size_t>(num_sites); j++) {
1233 idxj = iA[j] * ncomp + iA[j];
1237 * pow(sqrt(s_ij[idxi] * s_ij[idxj]) / (0.5 * (s_ij[idxi] + s_ij[idxj])), 3);
1238 delta_ij[idxa] = ghs[iA[i] * ncomp + iA[j]] * (exp(eABij /
_T) - 1) * pow(s_ij[iA[i] * ncomp + iA[j]], 3) * volABij;
1242 XA[i] = (-1 + sqrt(1 + 8 * den * delta_ij[i * num_sites + i])) / (4 * den * delta_ij[i * num_sites + i]);
1243 if (!std::isfinite(XA[i])) {
1248 vector<double> ddelta_dx(
static_cast<std::size_t
>(num_sites) * num_sites * ncomp, 0);
1250 for (
size_t k = 0; k < ncomp; k++) {
1251 std::size_t idxi = 0UL;
1252 std::size_t idxj = 0UL;
1254 for (
auto i = 0UL; i < static_cast<std::size_t>(num_sites); i++) {
1255 idxi = iA[i] * ncomp + iA[i];
1256 for (
auto j = 0UL; j < static_cast<std::size_t>(num_sites); j++) {
1257 idxj = iA[j] * ncomp + iA[j];
1261 * pow(sqrt(s_ij[idxi] * s_ij[idxj]) / (0.5 * (s_ij[idxi] + s_ij[idxj])), 3);
1264 * (pow(d[k], 3) / (1 - zeta[3]) / (1 - zeta[3])
1265 + 3 * d[iA[i]] * d[iA[j]] / (d[iA[i]] + d[iA[j]])
1266 * (d[k] * d[k] / (1 - zeta[3]) / (1 - zeta[3]) + 2 * pow(d[k], 3) * zeta[2] / pow(1 - zeta[3], 3))
1267 + 2 * pow((d[iA[i]] * d[iA[j]] / (d[iA[i]] + d[iA[j]])), 2)
1268 * (2 * d[k] * d[k] * zeta[2] / pow(1 - zeta[3], 3) + 3 * (pow(d[k], 3) * zeta[2] * zeta[2] / pow(1 - zeta[3], 4))));
1269 ddelta_dx[idx_ddelta] = dghsd_dx * (exp(eABij /
_T) - 1) * pow(s_ij[iA[i] * ncomp + iA[j]], 3) * volABij;
1279 vector<double> XA_old = XA;
1280 while ((ctr < 100) && (dif > 1e-15)) {
1282 XA =
XA_find(XA_old, delta_ij, den, x_assoc);
1284 for (
int i = 0; i < num_sites; i++) {
1285 dif += abs(XA[i] - XA_old[i]);
1287 for (
int i = 0; i < num_sites; i++) {
1288 XA_old[i] = (XA[i] + XA_old[i]) / 2.0;
1292 vector<double> dXA_dx(num_sites * ncomp, 0);
1296 for (
size_t i = 0; i < ncomp; i++) {
1297 for (
int j = 0; j < num_sites; j++) {
1298 mu_assoc[i] +=
mole_fractions[iA[j]] * den * dXA_dx[ij] * (1 / XA[j] - 0.5);
1303 for (
int i = 0; i < num_sites; i++) {
1304 mu_assoc[iA[i]] += log(XA[i]) - 0.5 * XA[i] + 0.5;
1309 vector<double> mu_ion(ncomp, 0);
1311 vector<double> q(ncomp);
1312 for (
size_t i = 0; i < ncomp; i++) {
1317 for (
size_t i = 0; i < ncomp; i++) {
1321 sqrt(den * E_CHRG * E_CHRG / kb /
_T / (
dielc * perm_vac) * summ);
1324 vector<double> chi(ncomp);
1325 vector<double> sigma_k(ncomp);
1328 for (
size_t i = 0; i < ncomp; i++) {
1329 chi[i] = 3 / pow(kappa * d[i], 3) * (1.5 + log(1 + kappa * d[i]) - 2 * (1 + kappa * d[i]) + 0.5 * pow(1 + kappa * d[i], 2));
1330 sigma_k[i] = -2 * chi[i] + 3 / (1 + kappa * d[i]);
1335 for (
size_t i = 0; i < ncomp; i++) {
1336 mu_ion[i] = -q[i] * q[i] * kappa / 24. / PI / kb /
_T / (
dielc * perm_vac) * (2 * chi[i] + summ1 / summ2);
1343 vector<double> mu(ncomp, 0);
1344 vector<CoolPropDbl> fugcoef(ncomp, 0);
1345 for (
size_t i = 0; i < ncomp; i++) {
1346 mu[i] = mu_hc[i] + mu_disp[i] + mu_polar[i] + mu_assoc[i] + mu_ion[i];
1347 fugcoef[i] = exp(mu[i] - log(Z));
1369 vector<double> d(ncomp);
1370 for (
auto i = 0UL; i < ncomp; i++) {
1374 for (
auto i = 0UL; i < ncomp; i++) {
1384 vector<double> zeta(4, 0);
1386 for (
int i = 0; i < 4; i++) {
1388 for (
size_t j = 0; j < ncomp; j++) {
1391 zeta[i] = PI / 6 * den * summ;
1394 double eta = zeta[3];
1396 for (
size_t i = 0; i < ncomp; i++) {
1400 vector<double> ghs(ncomp * ncomp, 0);
1401 vector<double> denghs(ncomp * ncomp, 0);
1402 vector<double> e_ij(ncomp * ncomp, 0);
1403 vector<double> s_ij(ncomp * ncomp, 0);
1407 for (
size_t i = 0; i < ncomp; i++) {
1408 for (
size_t j = 0; j < ncomp; j++) {
1431 ghs[idx] = 1 / (1 - zeta[3]) + (d[i] * d[j] / (d[i] + d[j])) * 3 * zeta[2] / (1 - zeta[3]) / (1 - zeta[3])
1432 + pow(d[i] * d[j] / (d[i] + d[j]), 2) * 2 * zeta[2] * zeta[2] / pow(1 - zeta[3], 3);
1434 zeta[3] / (1 - zeta[3]) / (1 - zeta[3])
1435 + (d[i] * d[j] / (d[i] + d[j])) * (3 * zeta[2] / (1 - zeta[3]) / (1 - zeta[3]) + 6 * zeta[2] * zeta[3] / pow(1 - zeta[3], 3))
1436 + pow(d[i] * d[j] / (d[i] + d[j]), 2)
1437 * (4 * zeta[2] * zeta[2] / pow(1 - zeta[3], 3) + 6 * zeta[2] * zeta[2] * zeta[3] / pow(1 - zeta[3], 4));
1441 double Zhs = zeta[3] / (1 - zeta[3]) + 3. * zeta[1] * zeta[2] / zeta[0] / (1. - zeta[3]) / (1. - zeta[3])
1442 + (3. * pow(zeta[2], 3.) - zeta[3] * pow(zeta[2], 3.)) / zeta[0] / pow(1. - zeta[3], 3.);
1444 static double a0[7] = {0.9105631445, 0.6361281449, 2.6861347891, -26.547362491, 97.759208784, -159.59154087, 91.297774084};
1445 static double a1[7] = {-0.3084016918, 0.1860531159, -2.5030047259, 21.419793629, -65.255885330, 83.318680481, -33.746922930};
1446 static double a2[7] = {-0.0906148351, 0.4527842806, 0.5962700728, -1.7241829131, -4.1302112531, 13.776631870, -8.6728470368};
1447 static double b0[7] = {0.7240946941, 2.2382791861, -4.0025849485, -21.003576815, 26.855641363, 206.55133841, -355.60235612};
1448 static double b1[7] = {-0.5755498075, 0.6995095521, 3.8925673390, -17.215471648, 192.67226447, -161.82646165, -165.20769346};
1449 static double b2[7] = {0.0976883116, -0.2557574982, -9.1558561530, 20.642075974, -38.804430052, 93.626774077, -29.666905585};
1451 vector<double> a(7, 0);
1452 vector<double> b(7, 0);
1453 for (
int i = 0; i < 7; i++) {
1454 a[i] = a0[i] + (m_avg - 1.) / m_avg * a1[i] + (m_avg - 1.) / m_avg * (m_avg - 2.) / m_avg * a2[i];
1455 b[i] = b0[i] + (m_avg - 1.) / m_avg * b1[i] + (m_avg - 1.) / m_avg * (m_avg - 2.) / m_avg * b2[i];
1458 double detI1_det = 0.0;
1459 double detI2_det = 0.0;
1461 for (
int i = 0; i < 7; i++) {
1462 detI1_det += a[i] * (i + 1) * pow(eta, i);
1463 detI2_det += b[i] * (i + 1) * pow(eta, i);
1464 I2 += b[i] * pow(eta, i);
1467 / (1. + m_avg * (8 * eta - 2 * eta * eta) / pow(1 - eta, 4)
1468 + (1 - m_avg) * (20 * eta - 27 * eta * eta + 12 * pow(eta, 3) - 2 * pow(eta, 4)) / pow((1 - eta) * (2 - eta), 2.0));
1469 double C2 = -1. * C1 * C1
1470 * (m_avg * (-4 * eta * eta + 20 * eta + 8) / pow(1 - eta, 5)
1471 + (1 - m_avg) * (2 * pow(eta, 3) + 12 * eta * eta - 48 * eta + 40) / pow((1 - eta) * (2 - eta), 3.0));
1474 for (
size_t i = 0; i < ncomp; i++) {
1479 double Zhc = m_avg * Zhs - summ;
1480 double Zdisp = -2 * PI * den * detI1_det * m2es3 - PI * den * m_avg * (C1 * detI2_det + C2 * eta * I2) * m2e2s3;
1487 double dA2_det = 0.;
1488 double dA3_det = 0.;
1489 vector<double> adip(5, 0);
1490 vector<double> bdip(5, 0);
1491 vector<double> cdip(5, 0);
1492 vector<double> dipmSQ(ncomp, 0);
1493 double J2 = NAN, detJ2_det = NAN, J3 = NAN, detJ3_det = NAN;
1495 static double a0dip[5] = {0.3043504, -0.1358588, 1.4493329, 0.3556977, -2.0653308};
1496 static double a1dip[5] = {0.9534641, -1.8396383, 2.0131180, -7.3724958, 8.2374135};
1497 static double a2dip[5] = {-1.1610080, 4.5258607, 0.9751222, -12.281038, 5.9397575};
1498 static double b0dip[5] = {0.2187939, -1.1896431, 1.1626889, 0, 0};
1499 static double b1dip[5] = {-0.5873164, 1.2489132, -0.5085280, 0, 0};
1500 static double b2dip[5] = {3.4869576, -14.915974, 15.372022, 0, 0};
1501 static double c0dip[5] = {-0.0646774, 0.1975882, -0.8087562, 0.6902849, 0};
1502 static double c1dip[5] = {-0.9520876, 2.9924258, -2.3802636, -0.2701261, 0};
1503 static double c2dip[5] = {-0.6260979, 1.2924686, 1.6542783, -3.4396744, 0};
1505 const static double conv = 7242.702976750923;
1507 for (
size_t i = 0; i < ncomp; i++) {
1512 for (
size_t i = 0; i < ncomp; i++) {
1513 for (
size_t j = 0; j < ncomp; j++) {
1520 for (
int l = 0; l < 5; l++) {
1521 adip[l] = a0dip[l] + (m_ij - 1) / m_ij * a1dip[l] + (m_ij - 1) / m_ij * (m_ij - 2) / m_ij * a2dip[l];
1522 bdip[l] = b0dip[l] + (m_ij - 1) / m_ij * b1dip[l] + (m_ij - 1) / m_ij * (m_ij - 2) / m_ij * b2dip[l];
1523 J2 += (adip[l] + bdip[l] * e_ij[i * ncomp + j] /
_T)
1525 detJ2_det += (adip[l] + bdip[l] * e_ij[i * ncomp + j] /
_T) * (l + 1) * pow(eta, l);
1528 * pow(s_ij[j * ncomp + j], 3) / pow(s_ij[i * ncomp + j], 3) *
components[i].getDipnum() *
components[j].getDipnum() * dipmSQ[i]
1531 * pow(s_ij[j * ncomp + j], 3) / pow(s_ij[i * ncomp + j], 3) *
components[i].getDipnum() *
components[j].getDipnum()
1532 * dipmSQ[i] * dipmSQ[j] * detJ2_det;
1537 for (
size_t i = 0; i < ncomp; i++) {
1538 for (
size_t j = 0; j < ncomp; j++) {
1539 for (
size_t k = 0; k < ncomp; k++) {
1546 for (
int l = 0; l < 5; l++) {
1547 cdip[l] = c0dip[l] + (m_ijk - 1) / m_ijk * c1dip[l] + (m_ijk - 1) / m_ijk * (m_ijk - 2) / m_ijk * c2dip[l];
1548 J3 += cdip[l] * pow(eta, l);
1549 detJ3_det += cdip[l] * (l + 2) * pow(eta, (l + 1));
1552 * e_ij[k * ncomp + k] /
_T * pow(s_ij[i * ncomp + i], 3) * pow(s_ij[j * ncomp + j], 3) * pow(s_ij[k * ncomp + k], 3)
1553 / s_ij[i * ncomp + j] / s_ij[i * ncomp + k] / s_ij[j * ncomp + k] *
components[i].getDipnum() *
components[j].getDipnum()
1554 *
components[k].getDipnum() * dipmSQ[i] * dipmSQ[j] * dipmSQ[k] * J3;
1556 * e_ij[k * ncomp + k] /
_T * pow(s_ij[i * ncomp + i], 3) * pow(s_ij[j * ncomp + j], 3) * pow(s_ij[k * ncomp + k], 3)
1557 / s_ij[i * ncomp + j] / s_ij[i * ncomp + k] / s_ij[j * ncomp + k] *
components[i].getDipnum()
1558 *
components[j].getDipnum() *
components[k].getDipnum() * dipmSQ[i] * dipmSQ[j] * dipmSQ[k] * detJ3_det;
1563 A2 = -PI * den * A2;
1564 A3 = -4 / 3. * PI * PI * den * den * A3;
1565 dA2_det = -PI * den / eta * dA2_det;
1566 dA3_det = -4 / 3. * PI * PI * den / eta * den / eta * dA3_det;
1569 Zpolar = eta * ((dA2_det * (1 - A3 / A2) + (dA3_det * A2 - A3 * dA2_det) / A2) / (1 - A3 / A2) / (1 - A3 / A2));
1580 for (
int i = 0; i < *it; i++) {
1581 iA.push_back(
static_cast<int>(it -
assoc_num.begin()));
1585 vector<double> x_assoc(num_sites);
1586 for (
int i = 0; i < num_sites; i++) {
1591 vector<double> XA(num_sites, 0);
1592 vector<double> delta_ij(
static_cast<std::size_t
>(num_sites) * num_sites, 0);
1593 std::size_t idxa = 0UL;
1594 std::size_t idxi = 0UL;
1595 std::size_t idxj = 0UL;
1596 for (
auto i = 0UL; i < static_cast<std::size_t>(num_sites); i++) {
1597 idxi = iA[i] * ncomp + iA[i];
1598 for (
auto j = 0UL; j < static_cast<std::size_t>(num_sites); j++) {
1599 idxj = iA[j] * ncomp + iA[j];
1603 * pow(sqrt(s_ij[idxi] * s_ij[idxj]) / (0.5 * (s_ij[idxi] + s_ij[idxj])), 3);
1604 delta_ij[idxa] = ghs[iA[i] * ncomp + iA[j]] * (exp(eABij /
_T) - 1) * pow(s_ij[iA[i] * ncomp + iA[j]], 3) * volABij;
1608 XA[i] = (-1 + sqrt(1 + 8 * den * delta_ij[i * num_sites + i])) / (4 * den * delta_ij[i * num_sites + i]);
1609 if (!std::isfinite(XA[i])) {
1614 vector<double> ddelta_dx(
static_cast<std::size_t
>(num_sites) * num_sites * ncomp, 0);
1616 for (
size_t k = 0; k < ncomp; k++) {
1617 std::size_t idxi = 0UL;
1618 std::size_t idxj = 0UL;
1620 for (
auto i = 0UL; i < static_cast<std::size_t>(num_sites); i++) {
1621 idxi = iA[i] * ncomp + iA[i];
1622 for (
auto j = 0UL; j < static_cast<std::size_t>(num_sites); j++) {
1623 idxj = iA[j] * ncomp + iA[j];
1627 * pow(sqrt(s_ij[idxi] * s_ij[idxj]) / (0.5 * (s_ij[idxi] + s_ij[idxj])), 3);
1630 * (pow(d[k], 3) / (1 - zeta[3]) / (1 - zeta[3])
1631 + 3 * d[iA[i]] * d[iA[j]] / (d[iA[i]] + d[iA[j]])
1632 * (d[k] * d[k] / (1 - zeta[3]) / (1 - zeta[3]) + 2 * pow(d[k], 3) * zeta[2] / pow(1 - zeta[3], 3))
1633 + 2 * pow((d[iA[i]] * d[iA[j]] / (d[iA[i]] + d[iA[j]])), 2)
1634 * (2 * d[k] * d[k] * zeta[2] / pow(1 - zeta[3], 3) + 3 * (pow(d[k], 3) * zeta[2] * zeta[2] / pow(1 - zeta[3], 4))));
1635 ddelta_dx[idx_ddelta] = dghsd_dx * (exp(eABij /
_T) - 1) * pow(s_ij[iA[i] * ncomp + iA[j]], 3) * volABij;
1645 vector<double> XA_old = XA;
1646 while ((ctr < 100) && (dif > 1e-14)) {
1648 XA =
XA_find(XA_old, delta_ij, den, x_assoc);
1650 for (
int i = 0; i < num_sites; i++) {
1651 dif += abs(XA[i] - XA_old[i]);
1653 for (
int i = 0; i < num_sites; i++) {
1654 XA_old[i] = (XA[i] + XA_old[i]) / 2.0;
1658 vector<double> dXA_dx(num_sites * ncomp, 0);
1663 for (
size_t i = 0; i < ncomp; i++) {
1664 for (
int j = 0; j < num_sites; j++) {
1676 vector<double> q(ncomp);
1677 for (
size_t i = 0; i < ncomp; i++) {
1682 for (
size_t i = 0; i < ncomp; i++) {
1687 sqrt(den * E_CHRG * E_CHRG / kb /
_T / (
dielc * perm_vac) * summ);
1690 double chi = NAN, sigma_k = NAN;
1692 for (
size_t i = 0; i < ncomp; i++) {
1693 chi = 3 / pow(kappa * d[i], 3) * (1.5 + log(1 + kappa * d[i]) - 2 * (1 + kappa * d[i]) + 0.5 * pow(1 + kappa * d[i], 2));
1694 sigma_k = -2 * chi + 3 / (1 + kappa * d[i]);
1697 Zion = -1 * kappa / 24. / PI / kb /
_T / (
dielc * perm_vac) * summ;
1701 double Z = Zid + Zhc + Zdisp + Zpolar + Zassoc + Zion;
1717 throw ValueError(
"rhomolar is less than zero");
1720 throw ValueError(
"rhomolar is not a valid number");
1723 if (optional_checks) {
1735 std::cout <<
format(
"%s (%d): update called with (%d: (%s), %g, %g)", __FILE__, __LINE__, input_pair,
1749 CoolPropDbl ld_value1 = value1, ld_value2 = value2;
1757 throw ValueError(
"Mole fractions must be set");
1760 if (
SatL->mole_fractions.empty()) {
1763 if (
SatV->mole_fractions.empty()) {
1766 for (
size_t i = 0; i <
N; i++) {
1767 if (
SatV->components[i].getZ() != 0) {
1768 SatV->mole_fractions[i] = 0;
1770 summ +=
SatV->mole_fractions[i];
1773 for (
size_t i = 0; i <
N; i++) {
1774 SatV->mole_fractions[i] =
SatV->mole_fractions[i] / summ;
1781 switch (input_pair) {
1827 if ((
_Q < 0) || (
_Q > 1)) {
1835 SatL->_rhomolar = value1;
1836 SatV->_rhomolar = value1;
1889 double p_input = NAN, rho_input = NAN;
1890 double p_bub = NAN, p_dew = NAN, p_equil = NAN;
1891 switch (input_pair) {
1902 if (p_input > 1.6 * p_equil) {
1904 }
else if (p_input < 0.5 * p_equil) {
1924 }
else if (
_p == p_bub) {
1936 }
else if ((
_p <= p_bub) && (
_p >= p_dew)) {
1945 double rho_bub = NAN, rho_dew = NAN;
1997 bool solution_found =
false;
2003 solution_found =
true;
2011 if (!solution_found) {
2012 double p_lbound = -6;
2013 double p_ubound = 9;
2014 double p_step = 0.1;
2016 while (p_guess < p_ubound && !solution_found) {
2018 p =
outerTQ(pow(10, p_guess), PCSAFT);
2019 solution_found =
true;
2028 if (!solution_found) {
2029 throw SolutionError(
"solution could not be found for TQ flash");
2034 PCSAFT.
_rhomolar = 1 / (PCSAFT.
_Q / PCSAFT.
SatV->_rhomolar + (1 - PCSAFT.
_Q) / PCSAFT.
SatL->_rhomolar);
2039 bool solution_found =
false;
2045 solution_found =
true;
2053 if (!solution_found) {
2054 double t_lbound = 1;
2055 double t_ubound = 800;
2062 while (t_guess > t_lbound && !solution_found) {
2065 solution_found =
true;
2074 if (!solution_found) {
2075 throw SolutionError(
"solution could not be found for PQ flash");
2080 PCSAFT.
_rhomolar = 1 / (PCSAFT.
_Q / PCSAFT.
SatV->_rhomolar + (1 - PCSAFT.
_Q) / PCSAFT.
SatL->_rhomolar);
2096 vector<CoolPropDbl> u;
2098 SolverInnerResid(
PCSAFTBackend& PCSAFT,
CoolPropDbl kb0, vector<CoolPropDbl> u) : PCSAFT(PCSAFT), kb0(kb0), u(std::move(u)) {}
2103 vector<double> pp(ncomp, 0);
2105 for (
auto i = 0U; i < ncomp; i++) {
2107 pp[i] = PCSAFT.
mole_fractions[i] / (1 - R + kb0 * R * exp(u[i]));
2115 error = pow((L + PCSAFT.
_Q - 1), 2.);
2121 for (
size_t i = 0; i < ncomp; i++) {
2128 vector<double> k(ncomp, 0), u(ncomp, 0), kprime(ncomp, 0), uprime(ncomp, 0);
2129 double Tref = t_guess - 1;
2130 double Tprime = t_guess + 1;
2133 PCSAFT.
SatL->_T = t;
2134 PCSAFT.
SatV->_T = t;
2150 if ((PCSAFT.
SatL->_rhomolar - PCSAFT.
SatV->_rhomolar) < 1e-4) {
2151 throw SolutionError(
"liquid and vapor densities are the same.");
2153 vector<double> fugcoef_l = PCSAFT.
SatL->calc_fugacity_coefficients();
2154 vector<double> fugcoef_v = PCSAFT.
SatV->calc_fugacity_coefficients();
2158 for (
size_t i = 0; i < ncomp; i++) {
2160 k[i] = fugcoef_l[i] / fugcoef_v[i];
2165 xl_sum += PCSAFT.
SatL->mole_fractions[i];
2166 PCSAFT.
SatV->mole_fractions[i] = k[i] * PCSAFT.
mole_fractions[i] / (1 + PCSAFT.
_Q * (k[i] - 1));
2167 xv_sum += PCSAFT.
SatV->mole_fractions[i];
2171 for (
size_t i = 0; i < ncomp; i++) {
2172 PCSAFT.
SatV->mole_fractions[i] = PCSAFT.
SatV->mole_fractions[i] / xv_sum;
2177 for (
size_t i = 0; i < ncomp; i++) {
2178 PCSAFT.
SatL->mole_fractions[i] = PCSAFT.
SatL->mole_fractions[i] / xl_sum;
2183 fugcoef_l = PCSAFT.
SatL->calc_fugacity_coefficients();
2185 fugcoef_v = PCSAFT.
SatV->calc_fugacity_coefficients();
2186 for (
size_t i = 0; i < ncomp; i++) {
2187 k[i] = fugcoef_l[i] / fugcoef_v[i];
2190 PCSAFT.
SatL->_T = Tprime;
2191 PCSAFT.
SatV->_T = Tprime;
2195 PCSAFT.
SatL->components[
water_idx].calc_water_sigma(Tprime);
2196 PCSAFT.
SatV->components[
water_idx].calc_water_sigma(Tprime);
2203 fugcoef_l = PCSAFT.
SatL->calc_fugacity_coefficients();
2205 fugcoef_v = PCSAFT.
SatV->calc_fugacity_coefficients();
2206 for (
size_t i = 0; i < ncomp; i++) {
2207 kprime[i] = fugcoef_l[i] / fugcoef_v[i];
2210 vector<double> t_weight(ncomp);
2212 for (
size_t i = 0; i < ncomp; i++) {
2213 double dlnk_dt = (kprime[i] - k[i]) / (Tprime - t);
2214 t_weight[i] = PCSAFT.
SatV->mole_fractions[i] * dlnk_dt / (1 + PCSAFT.
_Q * (k[i] - 1));
2215 t_sum += t_weight[i];
2219 for (
size_t i = 0; i < ncomp; i++) {
2220 double wi = t_weight[i] / t_sum;
2222 kb += wi * std::log(k[i]);
2228 for (
size_t i = 0; i < ncomp; i++) {
2229 double dlnk_dt = (kprime[i] - k[i]) / (Tprime - t);
2230 t_weight[i] = PCSAFT.
SatV->mole_fractions[i] * dlnk_dt / (1 + PCSAFT.
_Q * (kprime[i] - 1));
2231 t_sum += t_weight[i];
2235 for (
size_t i = 0; i < ncomp; i++) {
2236 double wi = t_weight[i] / t_sum;
2238 kbprime += wi * std::log(kprime[i]);
2241 kbprime = std::exp(kbprime);
2242 double kb0 = kbprime;
2244 for (
size_t i = 0; i < ncomp; i++) {
2245 u[i] = std::log(k[i] / kb);
2246 uprime[i] = std::log(kprime[i] / kbprime);
2249 double B = std::log(kbprime / kb) / (1 / Tprime - 1 / t);
2250 double A = std::log(kb) - B * (1 / t - 1 / Tref);
2253 SolverInnerResid resid(*
this, kb0, u);
2255 vector<double> pp(ncomp, 0);
2256 double maxdif = 1e10 * TOL;
2258 double Rmin = 0, Rmax = 1;
2259 while (maxdif > TOL && itr < MAXITER) {
2261 vector<double> u_old = u;
2265 double R0 = kb * PCSAFT.
_Q / (kb * PCSAFT.
_Q + kb0 * (1 - PCSAFT.
_Q));
2267 if (resid.call(R) > TOL) {
2272 double eupp_sum = 0;
2273 for (
size_t i = 0; i < ncomp; i++) {
2274 pp[i] = PCSAFT.
mole_fractions[i] / (1 - R + kb0 * R * std::exp(u[i]));
2277 eupp_sum += std::exp(u[i]) * pp[i];
2280 kb = pp_sum / eupp_sum;
2282 t = 1 / (1 / Tref + (std::log(kb) - A) / B);
2283 for (
size_t i = 0; i < ncomp; i++) {
2285 PCSAFT.
SatL->mole_fractions[i] = pp[i] / pp_sum;
2286 PCSAFT.
SatV->mole_fractions[i] = std::exp(u[i]) * pp[i] / eupp_sum;
2288 PCSAFT.
SatL->mole_fractions[i] = pp[i] / pp_sum * (1 - x_ions / (1 - PCSAFT.
_Q));
2289 PCSAFT.
SatV->mole_fractions[i] = std::exp(u[i]) * pp[i] / eupp_sum;
2292 PCSAFT.
SatV->mole_fractions[i] = 0;
2296 PCSAFT.
SatL->_T = t;
2297 PCSAFT.
SatV->_T = t;
2309 vector<CoolPropDbl> fugcoef_l = PCSAFT.
SatL->calc_fugacity_coefficients();
2311 vector<CoolPropDbl> fugcoef_v = PCSAFT.
SatV->calc_fugacity_coefficients();
2312 for (
size_t i = 0; i < ncomp; i++) {
2313 k[i] = fugcoef_l[i] / fugcoef_v[i];
2314 u[i] = std::log(k[i] / kb);
2318 B = std::log(kbprime / kb) / (1 / Tprime - 1 / t);
2323 A = std::log(kb) - B * (1 / t - 1 / Tref);
2325 maxdif = std::abs(A - A_old);
2326 for (
size_t i = 0; i < ncomp; i++) {
2328 double dif = std::abs(u[i] - u_old[i]);
2338 if (!std::isfinite(t) || maxdif > 1e-3 || t < 0) {
2339 throw SolutionError(
"outerPQ did not converge to a solution");
2357 vector<CoolPropDbl> u;
2359 SolverInnerResid(
PCSAFTBackend& PCSAFT,
CoolPropDbl kb0, vector<CoolPropDbl> u) : PCSAFT(PCSAFT), kb0(kb0), u(std::move(u)) {}
2364 vector<double> pp(ncomp, 0);
2367 for (
size_t i = 0; i < ncomp; i++) {
2369 pp[i] = PCSAFT.
mole_fractions[i] / (1 - R + kb0 * R * exp(u[i]));
2377 error = pow((L + PCSAFT.
_Q - 1), 2.);
2383 for (
size_t i = 0; i < ncomp; i++) {
2390 vector<double> k(ncomp, 0), u(ncomp, 0), kprime(ncomp, 0), uprime(ncomp, 0);
2391 double Pref = p_guess - 0.01 * p_guess;
2392 double Pprime = p_guess + 0.01 * p_guess;
2393 if (p_guess > 1e6) {
2394 Pprime = p_guess - 0.005 * p_guess;
2401 if ((PCSAFT.
SatL->_rhomolar - PCSAFT.
SatV->_rhomolar) < 1e-4) {
2402 throw SolutionError(
"liquid and vapor densities are the same.");
2404 vector<double> fugcoef_l = PCSAFT.
SatL->calc_fugacity_coefficients();
2405 vector<double> fugcoef_v = PCSAFT.
SatV->calc_fugacity_coefficients();
2409 for (
size_t i = 0; i < ncomp; i++) {
2411 k[i] = fugcoef_l[i] / fugcoef_v[i];
2416 xl_sum += PCSAFT.
SatL->mole_fractions[i];
2417 PCSAFT.
SatV->mole_fractions[i] = k[i] * PCSAFT.
mole_fractions[i] / (1 + PCSAFT.
_Q * (k[i] - 1));
2418 xv_sum += PCSAFT.
SatV->mole_fractions[i];
2422 for (
size_t i = 0; i < ncomp; i++) {
2423 PCSAFT.
SatV->mole_fractions[i] = PCSAFT.
SatV->mole_fractions[i] / xv_sum;
2428 for (
size_t i = 0; i < ncomp; i++) {
2429 PCSAFT.
SatL->mole_fractions[i] = PCSAFT.
SatL->mole_fractions[i] / xl_sum;
2434 fugcoef_l = PCSAFT.
SatL->calc_fugacity_coefficients();
2436 fugcoef_v = PCSAFT.
SatV->calc_fugacity_coefficients();
2437 for (
size_t i = 0; i < ncomp; i++) {
2438 k[i] = fugcoef_l[i] / fugcoef_v[i];
2439 u[i] = std::log(k[i] / kb);
2443 fugcoef_l = PCSAFT.
SatL->calc_fugacity_coefficients();
2445 fugcoef_v = PCSAFT.
SatV->calc_fugacity_coefficients();
2446 for (
size_t i = 0; i < ncomp; i++) {
2447 kprime[i] = fugcoef_l[i] / fugcoef_v[i];
2450 vector<double> t_weight(ncomp);
2452 for (
size_t i = 0; i < ncomp; i++) {
2453 double dlnk_dt = (kprime[i] - k[i]) / (Pprime -
p);
2454 t_weight[i] = PCSAFT.
SatV->mole_fractions[i] * dlnk_dt / (1 + PCSAFT.
_Q * (k[i] - 1));
2455 t_sum += t_weight[i];
2459 for (
size_t i = 0; i < ncomp; i++) {
2460 double wi = t_weight[i] / t_sum;
2462 kb += wi * std::log(k[i]);
2468 for (
size_t i = 0; i < ncomp; i++) {
2469 double dlnk_dt = (kprime[i] - k[i]) / (Pprime -
p);
2470 t_weight[i] = PCSAFT.
SatV->mole_fractions[i] * dlnk_dt / (1 + PCSAFT.
_Q * (kprime[i] - 1));
2471 t_sum += t_weight[i];
2475 for (
size_t i = 0; i < ncomp; i++) {
2476 double wi = t_weight[i] / t_sum;
2478 kbprime += wi * std::log(kprime[i]);
2481 kbprime = std::exp(kbprime);
2482 double kb0 = kbprime;
2484 for (
size_t i = 0; i < ncomp; i++) {
2485 u[i] = std::log(k[i] / kb);
2486 uprime[i] = std::log(kprime[i] / kbprime);
2489 double B = std::log(kbprime / kb) / (1 / Pprime - 1 /
p);
2490 double A = std::log(kb) - B * (1 /
p - 1 / Pref);
2497 SolverInnerResid resid(*
this, kb0, u);
2499 vector<double> pp(ncomp, 0);
2500 double maxdif = 1e10 * TOL;
2502 double Rmin = 0, Rmax = 1;
2503 while (maxdif > TOL && itr < MAXITER) {
2505 vector<double> u_old = u;
2508 double R0 = kb * PCSAFT.
_Q / (kb * PCSAFT.
_Q + kb0 * (1 - PCSAFT.
_Q));
2511 if (resid.call(R) > TOL) {
2516 double eupp_sum = 0;
2517 for (
size_t i = 0; i < ncomp; i++) {
2518 pp[i] = PCSAFT.
mole_fractions[i] / (1 - R + kb0 * R * std::exp(u[i]));
2521 eupp_sum += std::exp(u[i]) * pp[i];
2524 kb = pp_sum / eupp_sum;
2526 p = 1 / (1 / Pref + (std::log(kb) - A) / B);
2527 for (
size_t i = 0; i < ncomp; i++) {
2529 PCSAFT.
SatL->mole_fractions[i] = pp[i] / pp_sum;
2530 PCSAFT.
SatV->mole_fractions[i] = std::exp(u[i]) * pp[i] / eupp_sum;
2532 PCSAFT.
SatL->mole_fractions[i] = pp[i] / pp_sum * (1 - x_ions / (1 - PCSAFT.
_Q));
2533 PCSAFT.
SatV->mole_fractions[i] = std::exp(u[i]) * pp[i] / eupp_sum;
2536 PCSAFT.
SatV->mole_fractions[i] = 0;
2541 vector<CoolPropDbl> fugcoef_l = PCSAFT.
SatL->calc_fugacity_coefficients();
2543 vector<CoolPropDbl> fugcoef_v = PCSAFT.
SatV->calc_fugacity_coefficients();
2544 for (
size_t i = 0; i < ncomp; i++) {
2545 k[i] = fugcoef_l[i] / fugcoef_v[i];
2546 u[i] = std::log(k[i] / kb);
2550 B = std::log(kbprime / kb) / (1 / Pprime - 1 /
p);
2552 A = std::log(kb) - B * (1 /
p - 1 / Pref);
2554 maxdif = std::abs(A - A_old);
2555 for (
size_t i = 0; i < ncomp; i++) {
2557 double dif = std::abs(u[i] - u_old[i]);
2560 }
else if (!std::isfinite(dif)) {
2568 if (!std::isfinite(
p) || !std::isfinite(maxdif) || maxdif > 0.1 ||
p < 0) {
2569 throw SolutionError(
"outerTQ did not converge to a solution");
2579 double t_guess = _HUGE;
2583 for (
size_t i = 0; i < ncomp; i++) {
2589 bool guess_found =
false;
2591 double t_start = 571;
2592 double t_lbound = 1;
2598 while (!guess_found && t_start > t_lbound) {
2600 double Tprime = t_start - 50;
2603 PCSAFT.
SatL->_T = t;
2604 PCSAFT.
SatV->_T = t;
2619 PCSAFT.
SatL->_T = Tprime;
2620 PCSAFT.
SatV->_T = Tprime;
2622 PCSAFT.
SatL->_T = t;
2623 PCSAFT.
SatV->_T = t;
2625 double slope = (std::log10(p1) - std::log10(p2)) / (1 / t - 1 / Tprime);
2626 double intercept = std::log10(p1) - slope * (1 / t);
2627 t_guess = slope / (std::log10(PCSAFT.
_p) - intercept);
2635 throw SolutionError(
"an estimate for the VLE temperature could not be found");
2645 double p_guess = _HUGE;
2649 for (
auto i = 0U; i < ncomp; i++) {
2655 bool guess_found =
false;
2656 double p_start = 10000;
2657 while (!guess_found && p_start < 1e7) {
2659 vector<double> k(ncomp, 0), u(ncomp, 0), kprime(ncomp, 0), uprime(ncomp, 0);
2660 double Pprime = 0.99 * p_start;
2666 if ((PCSAFT.
SatL->_rhomolar - PCSAFT.
SatV->_rhomolar) < 1e-4) {
2667 p_start = p_start + 2e5;
2670 vector<double> fugcoef_l = PCSAFT.
SatL->calc_fugacity_coefficients();
2671 vector<double> fugcoef_v = PCSAFT.
SatV->calc_fugacity_coefficients();
2675 for (
size_t i = 0; i < ncomp; i++) {
2677 k[i] = fugcoef_l[i] / fugcoef_v[i];
2682 xl_sum += PCSAFT.
SatL->mole_fractions[i];
2683 PCSAFT.
SatV->mole_fractions[i] = k[i] * PCSAFT.
mole_fractions[i] / (1 + PCSAFT.
_Q * (k[i] - 1));
2684 xv_sum += PCSAFT.
SatV->mole_fractions[i];
2688 for (
size_t i = 0; i < ncomp; i++) {
2689 PCSAFT.
SatV->mole_fractions[i] = PCSAFT.
SatV->mole_fractions[i] / xv_sum;
2694 for (
size_t i = 0; i < ncomp; i++) {
2695 PCSAFT.
SatL->mole_fractions[i] = PCSAFT.
SatL->mole_fractions[i] / xl_sum;
2701 if ((PCSAFT.
SatL->_rhomolar - PCSAFT.
SatV->_rhomolar) < 1e-4) {
2702 p_start = p_start + 2e5;
2705 fugcoef_l = PCSAFT.
SatL->calc_fugacity_coefficients();
2706 fugcoef_v = PCSAFT.
SatV->calc_fugacity_coefficients();
2709 for (
size_t i = 0; i < ncomp; i++) {
2711 numer += PCSAFT.
SatL->mole_fractions[i] * fugcoef_l[i];
2712 denom += PCSAFT.
SatV->mole_fractions[i] * fugcoef_v[i];
2715 double ratio = numer / denom;
2719 if ((PCSAFT.
SatL->_rhomolar - PCSAFT.
SatV->_rhomolar) < 1e-4) {
2720 p_start = p_start + 2e5;
2723 fugcoef_l = PCSAFT.
SatL->calc_fugacity_coefficients();
2724 fugcoef_v = PCSAFT.
SatV->calc_fugacity_coefficients();
2727 for (
size_t i = 0; i < ncomp; i++) {
2729 numer += PCSAFT.
SatL->mole_fractions[i] * fugcoef_l[i];
2730 denom += PCSAFT.
SatV->mole_fractions[i] * fugcoef_v[i];
2733 double ratio_prime = numer / denom;
2735 double slope = (std::log10(ratio) - std::log10(ratio_prime)) / (std::log10(
p) - std::log10(Pprime));
2736 double intercept = std::log10(ratio) - slope * std::log10(
p);
2737 p_guess = std::pow(10, -intercept / slope);
2743 throw SolutionError(
"an estimate for the VLE pressure could not be found");
2760 double cost = (peos -
p) /
p;
2769 SolverRhoResid resid(*
this,
T,
p);
2772 vector<double> x_lo, x_hi;
2774 double limit_lower = -8;
2775 double limit_upper = -1;
2776 double rho_guess = 1e-13;
2777 double rho_guess_prev = rho_guess;
2779 for (
int i = 0; i < num_pts; i++) {
2780 rho_guess = pow(10, (limit_upper - limit_lower) / (
double)num_pts * i + limit_lower);
2782 if (err * err_prev < 0) {
2783 x_lo.push_back(rho_guess_prev);
2784 x_hi.push_back(rho_guess);
2787 rho_guess_prev = rho_guess;
2791 limit_upper = 0.7405;
2792 for (
int i = 0; i < num_pts; i++) {
2793 rho_guess = (limit_upper - limit_lower) / (
double)num_pts * i + limit_lower;
2795 if (err * err_prev < 0) {
2796 x_lo.push_back(rho_guess_prev);
2797 x_hi.push_back(rho_guess);
2800 rho_guess_prev = rho_guess;
2805 double x_lo_molar = 1e-8, x_hi_molar = 1e7;
2807 if (x_lo.size() == 1) {
2812 }
else if (x_lo.size() <= 3 && !x_lo.empty()) {
2824 }
else if (x_lo.size() > 3) {
2826 double g_min = 1e60;
2827 for (
size_t i = 0; i < x_lo.size(); i++) {
2830 double rho_i =
Brent(resid, x_lo_molar, x_hi_molar,
DBL_EPSILON, 1e-8, 200);
2849 double err_min = 1e40;
2850 double rho_min = NAN;
2851 for (
int i = 0; i < num_pts; i++) {
2852 double rho_guess = (0.7405 - 1e-8) / (
double)num_pts * i + 1e-8;
2854 if (abs(err) < err_min) {
2866 vector<CoolPropDbl> d(
N);
2868 for (
int i = 0; i <
N; i++) {
2872 return 6 / PI * nu / summ * 1.0e30 / N_AV;
2877 for (
unsigned int i = 0; i <
N; ++i) {
2890 for (std::size_t i = 0; i <
N; ++i) {
2891 const double mm_i =
components[i].molar_mass();
2892 MM_l +=
static_cast<double>(
SatL->mole_fractions[i]) * mm_i;
2893 MM_v +=
static_cast<double>(
SatV->mole_fractions[i]) * mm_i;
2895 return {MM_l, MM_v};
2900 auto num_sites = XA_guess.size();
2901 vector<double> XA = XA_guess;
2904 for (
auto i = 0U; i < num_sites; i++) {
2906 for (
int j = 0; j < num_sites; j++) {
2908 summ += den * x[j] * XA_guess[j] * delta_ij[idxij];
2910 XA[i] = 1. / (1. + summ);
2916vector<double>
PCSAFTBackend::dXAdt_find(vector<double> delta_ij,
double den, vector<double> XA, vector<double> ddelta_dt, vector<double> x) {
2918 auto num_sites = XA.size();
2919 Eigen::MatrixXd B = Eigen::MatrixXd::Zero(num_sites, 1);
2920 Eigen::MatrixXd A = Eigen::MatrixXd::Zero(num_sites, num_sites);
2924 for (
auto i = 0U; i < num_sites; i++) {
2926 for (
int j = 0; j < num_sites; j++) {
2927 B(i) -= x[j] * XA[j] * ddelta_dt[ij];
2928 A(i, j) = x[j] * delta_ij[ij];
2929 summ += x[j] * XA[j] * delta_ij[ij];
2932 A(i, i) = pow(1 + den * summ, 2.) / den;
2935 Eigen::MatrixXd solution = A.lu().solve(B);
2936 vector<double> dXA_dt(num_sites);
2937 for (
int i = 0; i < num_sites; i++) {
2938 dXA_dt[i] = solution(i);
2943vector<double>
PCSAFTBackend::dXAdx_find(vector<int> assoc_num, vector<double> delta_ij,
double den, vector<double> XA, vector<double> ddelta_dx,
2947 auto num_sites = XA.size();
2949 Eigen::MatrixXd B(num_sites * ncomp, 1);
2950 Eigen::MatrixXd A = Eigen::MatrixXd::Zero(num_sites * ncomp, num_sites * ncomp);
2952 double sum1 = NAN, sum2 = NAN;
2955 for (
auto i = 0U; i < ncomp; i++) {
2956 for (
auto j = 0U; j < num_sites; j++) {
2958 for (
int k = 0; k < num_sites; k++) {
2959 sum1 = sum1 + den * x[k] * (XA[k] * ddelta_dx[i * num_sites * num_sites + j * num_sites + k]);
2960 A(ij, i * num_sites + k) = XA[j] * XA[j] * den * x[k] * delta_ij[j * num_sites + k];
2964 for (
int l = 0; l <
assoc_num[i]; l++) {
2965 sum2 = sum2 + XA[idx1 + l] * delta_ij[idx1 * num_sites + l * num_sites + j];
2968 A(ij, ij) = A(ij, ij) + 1;
2969 B(ij) = -1 * XA[j] * XA[j] * (sum1 + sum2);
2975 Eigen::MatrixXd solution = A.lu().solve(B);
2976 vector<double> dXA_dx(num_sites * ncomp);
2977 for (
int i = 0; i < num_sites * ncomp; i++) {
2978 dXA_dx[i] = solution(i);
2987 for (
int i = 0; i <
N; i++) {
2988 vector<std::string> assoc_scheme =
components[i].getAssocScheme();
2990 auto num = assoc_scheme.size();
2991 for (
auto j = 0U; j < num; j++) {
2994 charge.push_back(0);
2999 vector<int> tmp{0, 0};
3000 charge.insert(charge.end(), tmp.begin(), tmp.end());
3005 vector<int> tmp{-1, 1};
3006 charge.insert(charge.end(), tmp.begin(), tmp.end());
3011 vector<int> tmp{0, 0, 0};
3012 charge.insert(charge.end(), tmp.begin(), tmp.end());
3017 vector<int> tmp{-1, -1, 1};
3018 charge.insert(charge.end(), tmp.begin(), tmp.end());
3023 vector<int> tmp{0, 0, 0, 0};
3024 charge.insert(charge.end(), tmp.begin(), tmp.end());
3029 vector<int> tmp{1, 1, 1, -1};
3030 charge.insert(charge.end(), tmp.begin(), tmp.end());
3035 vector<int> tmp{-1, -1, 1, 1};
3036 charge.insert(charge.end(), tmp.begin(), tmp.end());
3041 throw ValueError(
format(
"%s is not a valid association type.", assoc_scheme[j]));
3048 for (
auto i1 = charge.begin();
i1 != charge.end();
i1++) {
3049 for (
int& i2 : charge) {
3050 if (*
i1 == 0 || i2 == 0) {
3052 }
else if (*
i1 == 1 && i2 == -1) {
3054 }
else if (*
i1 == -1 && i2 == 1) {
3081 throw ValueError(
"The current function for the dielectric constant for water is only valid for temperatures above 263.15 K.");
3082 }
else if (t <= 368.15) {
3083 dielc = 7.6555618295E-04 *
_T *
_T - 8.1783881423E-01 *
_T + 2.5419616803E+02;
3084 }
else if (t <= 443.15) {
3085 dielc = 0.0005003272124 *
_T *
_T - 0.6285556029 *
_T + 220.4467027;
3087 throw ValueError(
"The current function for the dielectric constant for water is only valid for temperatures less than 443.15 K.");