18 double B = 1 + m * (1 -
sqrt_Tr_Tci * sqrt(1 / tau));
43 double dDi_dtau = (itau >= 1) ? (1.0 / 2.0) *
sqrt_Tr_Tci / (pow(tau, 1.5)) : 0;
44 double d2Di_dtau2 = (itau >= 2) ? -(3.0 / 4.0) *
sqrt_Tr_Tci / (pow(tau, 2.5)) : 0;
45 double d3Di_dtau3 = (itau >= 3) ? (15.0 / 8.0) *
sqrt_Tr_Tci / (pow(tau, 3.5)) : 0;
46 double d4Di_dtau4 = (itau >= 4) ? -(105.0 / 16.0) *
sqrt_Tr_Tci / (pow(tau, 4.5)) : 0;
48 double Bi = 1, dBi_dtau = 0, d2Bi_dtau2 = 0, d3Bi_dtau3 = 0, d4Bi_dtau4 = 0;
49 for (
int n = 1; n <= 3; ++n) {
50 Bi +=
c[n - 1] * pow(Di, n);
51 dBi_dtau += (itau < 1) ? 0 : (n *
c[n - 1] * pow(Di, n - 1) * dDi_dtau);
52 d2Bi_dtau2 += (itau < 2) ? 0 : n *
c[n - 1] * ((n - 1) * pow(dDi_dtau, 2) + Di * d2Di_dtau2) * pow(Di, n - 2);
53 d3Bi_dtau3 += (itau < 3)
55 : n *
c[n - 1] * (3 * (n - 1) * Di * dDi_dtau * d2Di_dtau2 + (n * n - 3 * n + 2) * pow(dDi_dtau, 3) + pow(Di, 2) * d3Di_dtau3)
61 * (6 * (n * n - 3 * n + 2) * Di * pow(dDi_dtau, 2) * d2Di_dtau2 + (n * n * n - 6 * n * n + 11 * n - 6) * pow(dDi_dtau, 4)
62 + (4 * n * dDi_dtau * d3Di_dtau3 + 3 * n * pow(d2Di_dtau2, 2) - 4 * dDi_dtau * d3Di_dtau3 - 3 * pow(d2Di_dtau2, 2)) * pow(Di, 2)
63 + pow(Di, 3) * d4Di_dtau4)
70 return 2 *
a0 * Bi * dBi_dtau;
72 return 2 *
a0 * (Bi * d2Bi_dtau2 + dBi_dtau * dBi_dtau);
74 return 2 *
a0 * (Bi * d3Bi_dtau3 + 3 * dBi_dtau * d2Bi_dtau2);
76 return 2 *
a0 * (Bi * d4Bi_dtau4 + 4 * dBi_dtau * d3Bi_dtau3 + 3 * pow(d2Bi_dtau2, 2));
89 const double L =
c[0], M =
c[1], N =
c[2];
91 double B1 = (itau < 1) ? 0 : N / tau * (L * M * A - M + 1);
92 double dB1_dtau = (itau < 2) ? 0 : N /
powInt(tau, 2) * (-L * M * M * N * A - L * M * A + M - 1);
93 double d2B1_dtau2 = (itau < 3) ? 0 : N /
powInt(tau, 3) * (L * M * M * M * N * N * A + 3 * L * M * M * N * A + 2 * L * M * A - 2 * M + 2);
97 * (L *
powInt(M, 4) *
powInt(N, 3) * A + 6 * L * M * M * M * N * N * A + 11 * L * M * M * N * A + 6 * L * M * A - 6 * M + 6);
99 double dam_dtau = NAN, d2am_dtau2 = NAN, d3am_dtau3 = NAN, d4am_dtau4 = NAN;
100 double am =
a0 * pow(
Tr_over_Tci / tau, N * (M - 1)) * exp(L * (1 - A));
107 d2am_dtau2 = (itau < 2) ? 0 : B1 * dam_dtau + am * dB1_dtau;
108 d3am_dtau3 = (itau < 3) ? 0 : B1 * d2am_dtau2 + am * d2B1_dtau2 + 2 * dB1_dtau * dam_dtau;
109 d4am_dtau4 = (itau < 4) ? 0 : B1 * d3am_dtau3 + am * d3B1_dtau3 + 3 * dB1_dtau * d2am_dtau2 + 3 * d2B1_dtau2 * dam_dtau;
128 const double B = 1.0 + m * (1.0 - sq);
129 const double t15 =
sqrt_Tr_Tci / (tau * sqrt(tau));
130 const double t25 = t15 / tau;
131 const double t35 = t25 / tau;
132 const double t45 = t35 / tau;
134 const double t4 = t3 / tau;
135 const double t5 = t4 / tau;
136 terms[0] =
a0 * B * B;
137 terms[1] =
a0 * m * B * t15;
138 terms[2] =
a0 * m * 0.5 * (m * t3 - 3.0 * B * t25);
139 terms[3] = (3.0 / 4.0) *
a0 * m * (-3.0 * m * t4 + 5.0 * B * t35);
140 terms[4] = (3.0 / 8.0) *
a0 * m * (29.0 * m * t5 - 35.0 * B * t45);
144 const double L =
c[0], M =
c[1], N =
c[2];
147 const double am =
a0 * pow(
Tr_over_Tci / tau, N * (M - 1)) * exp(L * (1.0 - A));
149 const double B1 = N / tau * (L * M * A - M + 1.0);
150 const double dam = am * B1;
152 const double dB1 = N /
powInt(tau, 2) * (-L * M * M * N * A - L * M * A + M - 1.0);
153 const double d2am = B1 * dam + am * dB1;
155 const double d2B1 = N /
powInt(tau, 3) * (L * M * M * M * N * N * A + 3.0 * L * M * M * N * A + 2.0 * L * M * A - 2.0 * M + 2.0);
156 const double d3am = B1 * d2am + am * d2B1 + 2.0 * dB1 * dam;
160 * (L *
powInt(M, 4) *
powInt(N, 3) * A + 6.0 * L * M * M * M * N * N * A + 11.0 * L * M * M * N * A + 6.0 * L * M * A - 6.0 * M + 6.0);
161 terms[4] = B1 * d3am + am * d3B1 + 3.0 * dB1 * d2am + 3.0 * d2B1 * dam;
168 const double Di = 1.0 - sq;
169 const double p = sq / tau;
170 const double d1Di = 0.5 * p;
171 const double d2Di = -0.75 * p / tau;
172 const double d3Di = 1.875 * p / (tau * tau);
173 const double d4Di = -6.5625 * p / (tau * tau * tau);
175 const double Di2 = Di * Di;
176 const double Di3 = Di2 * Di;
177 const double c0 =
c[0], c1 =
c[1], c2 =
c[2];
181 const double Bi = 1.0 + c0 * Di + c1 * Di2 + c2 * Di3;
182 const double dBi = d1Di * (c0 + 2.0 * c1 * Di + 3.0 * c2 * Di2);
183 const double d2Bi = c0 * d2Di + 2.0 * c1 * (d1Di * d1Di + Di * d2Di) + 3.0 * c2 * Di * (2.0 * d1Di * d1Di + Di * d2Di);
185 c0 * d3Di + 2.0 * c1 * (3.0 * d1Di * d2Di + Di * d3Di) + 3.0 * c2 * (6.0 * Di * d1Di * d2Di + 2.0 * d1Di * d1Di * d1Di + Di2 * d3Di);
186 const double d4Bi = c0 * d4Di + 2.0 * c1 * (4.0 * d1Di * d3Di + 3.0 * d2Di * d2Di + Di * d4Di)
187 + 3.0 * c2 * (12.0 * d1Di * d1Di * d2Di + Di * (8.0 * d1Di * d3Di + 6.0 * d2Di * d2Di) + Di2 * d4Di);
189 terms[0] =
a0 * Bi * Bi;
190 terms[1] = 2.0 *
a0 * Bi * dBi;
191 terms[2] = 2.0 *
a0 * (Bi * d2Bi + dBi * dBi);
192 terms[3] = 2.0 *
a0 * (Bi * d3Bi + 3.0 * dBi * d2Bi);
193 terms[4] = 2.0 *
a0 * (Bi * d4Bi + 4.0 * dBi * d3Bi + 3.0 * d2Bi * d2Bi);
197 double Delta_2,
const std::vector<double>& C1,
const std::vector<double>& C2,
const std::vector<double>& C3)
202 acentric(std::move(acentric)),
206 N(static_cast<int>(Tc.size())),
209 k.resize(
N, std::vector<double>(
N, 0));
212 m_tau_cache = std::numeric_limits<double>::quiet_NaN();
218 m_tau_cache = std::numeric_limits<double>::quiet_NaN();
220 if (C1.empty() && C2.empty() && C3.empty()) {
221 for (std::size_t i = 0; i <
Tc.size(); ++i) {
222 alpha[i] = std::make_shared<BasicMathiasCopemanAlphaFunction>(
a0_ii(i),
m_ii(i),
T_r /
Tc[i]);
226 for (std::size_t i = 0; i <
Tc.size(); ++i) {
227 alpha[i] = std::make_shared<MathiasCopemanAlphaFunction>(
a0_ii(i), C1[i], C2[i], C3[i],
T_r /
Tc[i]);
239 for (
int i =
N - 1; i >= 0; --i) {
240 for (
int j =
N - 1; j >= 0; --j) {
241 summer += x[i] * x[j] *
aij_term(tau, i, j, itau);
248 if (xN_independent) {
250 for (
int j =
N - 1; j >= 0; --j) {
251 summer += x[j] *
aij_term(tau, i, j, itau);
256 for (
int k =
N - 2;
k >= 0; --
k) {
259 return 2 * (summer + x[
N - 1] * (
aij_term(tau,
N - 1, i, itau) -
aij_term(tau,
N - 1,
N - 1, itau)));
263 bool xN_independent) {
265 if (xN_independent) {
266 return 2 *
aij_term(tau, i, j, itau);
268 return 2 * (
aij_term(tau, i, j, itau) -
aij_term(tau, j,
N - 1, itau) -
aij_term(tau,
N - 1, i, itau) +
aij_term(tau,
N - 1,
N - 1, itau));
273 bool xN_independent) {
283 for (
int i = 0; i <
N; ++i) {
288 for (
int i =
N - 1; i >= 0; --i) {
294 if (xN_independent) {
324 assert(std::memcmp(&tau, &
m_tau_cache,
sizeof(
double)) == 0 &&
"u_term: aii cache not populated for this tau");
328 const double aii = ai[0], ajj = aj[0];
333 return aii * aj[1] + ajj * ai[1];
335 return (aii * aj[2] + 2 * ai[1] * aj[1] + ajj * ai[2]);
337 return (aii * aj[3] + 3 * ai[1] * aj[2] + 3 * ai[2] * aj[1] + ajj * ai[3]);
339 return (aii * aj[4] + 4 * ai[1] * aj[3] + 6 * ai[2] * aj[2] + 4 * ai[3] * aj[1] + ajj * ai[4]);
349 const double u =
u_term(tau, i, j, 0);
350 const double su = sqrt(u);
351 const double kf = 1 -
k[i][j];
357 return kf / (2.0 * su) *
u_term(tau, i, j, 1);
359 const double u1 =
u_term(tau, i, j, 1);
360 return kf / (4.0 * u * su) * (2 * u *
u_term(tau, i, j, 2) - u1 * u1);
363 const double u1 =
u_term(tau, i, j, 1), u2 =
u_term(tau, i, j, 2);
364 return kf / (8.0 * u * u * su) * (4 * u * u *
u_term(tau, i, j, 3) - 6 * u * u1 * u2 + 3 * u1 * u1 * u1);
367 const double u1 =
u_term(tau, i, j, 1), u2 =
u_term(tau, i, j, 2);
368 return kf / (16.0 * u * u * u * su)
369 * (-4 * u * u * (4 * u1 *
u_term(tau, i, j, 3) + 3 * u2 * u2) + 8 * u * u * u *
u_term(tau, i, j, 4) + 36 * u * u1 * u1 * u2
370 - 15 * u1 * u1 * u1 * u1);
377 if (itau > 0)
return 0.0;
379 double bracket = 1 - bmc * delta *
rho_r;
383 return -log(bracket);
385 return bmc *
rho_r / bracket;
387 const double r = bmc *
rho_r / bracket;
391 const double r = bmc *
rho_r / bracket;
392 return 2 * r * r * r;
395 const double r = bmc *
rho_r / bracket;
396 return 6 * r * r * r * r;
403 bool xN_independent) {
404 if (itau > 0)
return 0.0;
407 double bracket = 1 - bmc * delta *
rho_r;
411 return delta *
rho_r * db_dxi / bracket;
413 return rho_r * db_dxi / pow(bracket, 2);
415 return 2 * pow(
rho_r, 2) * bmc * db_dxi / pow(bracket, 3);
417 return 6 * pow(
rho_r, 3) * pow(bmc, 2) * db_dxi / pow(bracket, 4);
419 return 24 * pow(
rho_r, 4) * pow(bmc, 3) * db_dxi / pow(bracket, 5);
425 std::size_t j,
bool xN_independent) {
426 if (itau > 0)
return 0.0;
430 double bracket = 1 - bmc * delta *
rho_r;
434 return pow(delta *
rho_r, 2) * db_dxi * db_dxj / pow(bracket, 2) + delta *
rho_r * d2b_dxidxj / bracket;
436 return 2 * delta * pow(
rho_r, 2) * db_dxi * db_dxj / pow(bracket, 3) +
rho_r * d2b_dxidxj / pow(bracket, 2);
438 return 2 * pow(
rho_r, 2) * db_dxi * db_dxj / pow(bracket, 4) * (2 * delta *
rho_r * bmc + 1)
439 + 2 * pow(
rho_r, 2) * bmc * d2b_dxidxj / pow(bracket, 3);
441 return 12 * pow(
rho_r, 3) * bmc * db_dxi * db_dxj / pow(bracket, 5) * (delta *
rho_r * bmc + 1)
442 + 6 * pow(
rho_r, 3) * pow(bmc, 2) * d2b_dxidxj / pow(bracket, 4);
444 return 24 * pow(
rho_r, 4) * pow(bmc, 2) * db_dxi * db_dxj / pow(bracket, 6) * (2 * delta *
rho_r * bmc + 3)
445 + 24 * pow(
rho_r, 4) * pow(bmc, 3) * d2b_dxidxj / pow(bracket, 5);
451 std::size_t j, std::size_t k,
bool xN_independent) {
452 if (itau > 0)
return 0.0;
457 double bracket = 1 - bmc * delta *
rho_r;
461 return delta *
rho_r * d3b_dxidxjdxk / bracket + 2 * pow(delta *
rho_r, 3) * db_dxi * db_dxj * db_dxk / pow(bracket, 3)
462 + pow(delta *
rho_r, 2) / pow(bracket, 2) * (db_dxi * d2b_dxjdxk + db_dxj * d2b_dxidxk + db_dxk * d2b_dxidxj);
464 return rho_r * d3b_dxidxjdxk / pow(bracket, 2) + 6 * pow(delta, 2) * pow(
rho_r, 3) * db_dxi * db_dxj * db_dxk / pow(bracket, 4)
465 + 2 * delta * pow(
rho_r, 2) / pow(bracket, 3) * (db_dxi * d2b_dxjdxk + db_dxj * d2b_dxidxk + db_dxk * d2b_dxidxj);
508 bool xN_independent) {
523 return 2 * pow(
rho_r, 2)
534 bool xN_independent) {
544 + 2 *
Delta_1 *
Delta_2 * delta *
rho_r * (db_dxi * d2b_dxjdxk + db_dxj * d2b_dxidxk + db_dxk * d2b_dxidxj));
548 + 4 *
Delta_1 *
Delta_2 * delta *
rho_r * (db_dxi * d2b_dxjdxk + db_dxj * d2b_dxidxk + db_dxk * d2b_dxidxj));
560 const double p0 =
PI_12(delta, x, 0), p1 =
PI_12(delta, x, 1);
561 return -
rho_r / (p0 * p0) * p1;
564 const double p0 =
PI_12(delta, x, 0), p1 =
PI_12(delta, x, 1), p2 =
PI_12(delta, x, 2);
565 return rho_r * (-p0 * p2 + 2 * p1 * p1) / (p0 * p0 * p0);
569 const double p0 =
PI_12(delta, x, 0), p1 =
PI_12(delta, x, 1), p2 =
PI_12(delta, x, 2);
570 return rho_r * (6 * p0 * p1 * p2 - 6 * p1 * p1 * p1) / (p0 * p0 * p0 * p0);
585 bracket =
d_PI_12_dxi(delta, x, 0, i, xN_independent);
588 bracket = (
d_PI_12_dxi(delta, x, 1, i, xN_independent)
594 + 2 /
rho_r * (pow(
PI_12(delta, x, 1), 2) +
PI_12(delta, x, 0) *
PI_12(delta, x, 2)) *
d_psi_plus_dxi(delta, x, 1, i, xN_independent)
602 + 6 /
rho_r * (pow(
PI_12(delta, x, 1), 2) +
PI_12(delta, x, 0) *
PI_12(delta, x, 2)) *
d_psi_plus_dxi(delta, x, 2, i, xN_independent)
608 return -
rho_r / pow(
PI_12(delta, x, 0), 2) * bracket;
611 bool xN_independent) {
613 double PI12 =
PI_12(delta, x, 0);
629 + 2 * (PI12 *
d_PI_12_dxi(delta, x, 1, j, xN_independent) +
PI_12(delta, x, 1) *
d_PI_12_dxi(delta, x, 0, j, xN_independent))
637 + 2 * (PI12 *
PI_12(delta, x, 2) + pow(
PI_12(delta, x, 1), 2)) *
d2_psi_plus_dxidxj(delta, x, 1, i, j, xN_independent)
638 + 4 * (PI12 *
d_PI_12_dxi(delta, x, 1, j, xN_independent) +
PI_12(delta, x, 1) *
d_PI_12_dxi(delta, x, 0, j, xN_independent))
641 * (PI12 *
d_PI_12_dxi(delta, x, 2, j, xN_independent) + 2 *
PI_12(delta, x, 1) *
d_PI_12_dxi(delta, x, 1, j, xN_independent)
654 (+6 * (PI12 *
PI_12(delta, x, 2) + pow(
PI_12(delta, x, 1), 2)) *
d2_psi_plus_dxidxj(delta, x, 2, i, j, xN_independent)
656 + 6 * (PI12 *
d_PI_12_dxi(delta, x, 1, j, xN_independent) +
PI_12(delta, x, 1) *
d_PI_12_dxi(delta, x, 0, j, xN_independent))
659 * (PI12 *
d_PI_12_dxi(delta, x, 2, j, xN_independent) + 2 *
PI_12(delta, x, 1) *
d_PI_12_dxi(delta, x, 1, j, xN_independent)
672 return -1 / pow(PI12, 2) * bracket;
675 std::size_t k,
bool xN_independent) {
676 double PI12 =
PI_12(delta, x, 0);
689 return -1 / pow(PI12, 2)
704 return tau *
am_term(tau, x, 0);
706 return tau *
am_term(tau, x, itau) + itau *
am_term(tau, x, itau - 1);
717 bool xN_independent) {
721 return tau *
d2_am_term_dxidxj(tau, x, itau, i, j, xN_independent) + itau *
d2_am_term_dxidxj(tau, x, itau - 1, i, j, xN_independent);
725 std::size_t k,
bool xN_independent) {
733double AbstractCubic::alphar(
double tau,
double delta,
const std::vector<double>& x, std::size_t itau, std::size_t idelta) {
737 bool xN_independent) {
744 std::size_t j,
bool xN_independent) {
753 std::size_t j, std::size_t k,
bool xN_independent) {
771 double a = 0.42748023335403414043900347952220 *
R_u *
R_u *
Tc[i] *
Tc[i] /
pc[i];
776 double b = 0.08664034999649577215890158147700 *
R_u *
Tc[i] /
pc[i];
782 double m = 0.480 + 1.574 * omega - 0.176 * omega * omega;
788 double a = 0.45723552892138218938000849856422 *
R_u *
R_u *
Tc[i] *
Tc[i] /
pc[i];
793 double b = 0.07779607390388455972148597969400 *
R_u *
Tc[i] /
pc[i];
798 double m = 0.37464 + 1.54226 * omega - 0.26992 * omega * omega;